cassandra-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ran Tavory <ran...@gmail.com>
Subject Re: How to unit test my code calling Cassandra with Thift
Date Sun, 24 Jan 2010 10:02:30 GMT
Here's the code I've just written over the weekend and started using in
test:


package com.outbrain.data.cassandra.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.service.CassandraDaemon;
import org.apache.cassandra.utils.FileUtils;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * An in-memory cassandra storage service that listens to the thrift
interface.
 * Useful for unit testing,
 *
 * @author Ran Tavory (ran@outbain.com)
 *
 */
public class InProcessCassandraServer implements Runnable {

  private static final Logger log =
LoggerFactory.getLogger(InProcessCassandraServer.class);

  CassandraDaemon cassandraDaemon;

  public void init() {
    try {
      prepare();
    } catch (IOException e) {
      log.error("Cannot prepare cassandra.", e);
    }
    try {
      cassandraDaemon = new CassandraDaemon();
      cassandraDaemon.init(null);
    } catch (TTransportException e) {
      log.error("TTransportException", e);
    } catch (IOException e) {
      log.error("IOException", e);
    }
  }

  @Override
  public void run() {
    cassandraDaemon.start();
  }

  public void stop() {
    cassandraDaemon.stop();
    rmdir("tmp");
  }


  /**
   * Creates all files and directories needed
   * @throws IOException
   */
  private void prepare() throws IOException {
    // delete tmp dir first
    rmdir("tmp");
    // make a tmp dir and copy storag-conf.xml and log4j.properties to it
    copy("/cassandra/storage-conf.xml", "tmp");
    copy("/cassandra/log4j.properties", "tmp");
    System.setProperty("storage-config", "tmp");

    // make cassandra directories.
    for (String s: DatabaseDescriptor.getAllDataFileLocations()) {
      mkdir(s);
    }
    mkdir(DatabaseDescriptor.getBootstrapFileLocation());
    mkdir(DatabaseDescriptor.getLogFileLocation());
  }

  /**
   * Copies a resource from within the jar to a directory.
   *
   * @param resourceName
   * @param directory
   * @throws IOException
   */
  private void copy(String resource, String directory) throws IOException {
    mkdir(directory);
    InputStream is = getClass().getResourceAsStream(resource);
    String fileName = resource.substring(resource.lastIndexOf("/") + 1);
    File file = new File(directory + System.getProperty("file.separator") +
fileName);
    OutputStream out = new FileOutputStream(file);
    byte buf[] = new byte[1024];
    int len;
    while ((len = is.read(buf)) > 0) {
      out.write(buf, 0, len);
    }
    out.close();
    is.close();
  }

  /**
   * Creates a directory
   * @param dir
   * @throws IOException
   */
  private void mkdir(String dir) throws IOException {
    FileUtils.createDirectory(dir);
  }

  /**
   * Removes a directory from file system
   * @param dir
   */
  private void rmdir(String dir) {
    FileUtils.deleteDir(new File(dir));
  }
}


And in the test class:

public class XxxTest {

  private static InProcessCassandraServer cassandra;

  @BeforeClass
  public static void setup() throws TTransportException, IOException,
InterruptedException {
    cassandra = new InProcessCassandraServer();
    cassandra.init();
    Thread t = new Thread(cassandra);
    t.setDaemon(true);
    t.start();
  }

  @AfterClass
  public static void shutdown() {
    cassandra.stop();
  }
... test
}

Now you can connect to localhost:9160.

Assumptions:
The code assumes you have two files in your classpath:
/cassandra/stogage-config.xml and /cassandra/log4j.xml. This is convenient
if you use maven, just throw them at /src/test/resources/cassandra/
If you don't work with maven or would like to configure the configuration
files differently it should be fairly easy, just change the prepare()
method.



On Sun, Jan 24, 2010 at 10:54 AM, Richard Grossman <richiesgr@gmail.com>wrote:

> So Is there anybody ? Unit testing is important people ...
> Thanks
>
>
> On Thu, Jan 21, 2010 at 12:09 PM, Richard Grossman <richiesgr@gmail.com>wrote:
>
>> Here is the code I use
>>     class startServer implements Runnable {
>>
>>         @Override
>>         public void run() {
>>             try {
>>                 CassandraDaemon cassandraDaemon = new CassandraDaemon();
>>                 cassandraDaemon.init(null);
>>                 cassandraDaemon.start();
>>             } catch (TTransportException e) {
>>                 // TODO Auto-generated catch block
>>                 e.printStackTrace();
>>             } catch (IOException e) {
>>                 // TODO Auto-generated catch block
>>                 e.printStackTrace();
>>             }
>>         }
>>     }
>>
>>         Thread thread = new Thread(new startServer());
>>         thread.start();
>>
>> <the code to test here>
>>
>>
>>
>> On Thu, Jan 21, 2010 at 12:08 PM, Richard Grossman <richiesgr@gmail.com>wrote:
>>
>>> Yes I've seen this and also check it but if I start the server then it
>>> block the current thread I can continue the test in sequence.
>>> So I've tried to start into separate thread but no chance too it close
>>> the server even before I arrive to the code to test.
>>>
>>> If you've a trick to start the server in JVM thank
>>>
>>> Richard
>>>
>>> On Wed, Jan 20, 2010 at 3:47 PM, Jonathan Ellis <jbellis@gmail.com>wrote:
>>>
>>>> did you look at CassandraDaemon?
>>>>
>>>>
>>
>

Mime
View raw message