JUnit使用嵌入式服务器测试Cassandra

时间:2011-07-07 14:20:27

标签: unit-testing testing junit cassandra hector

为将数据保存到nosql数据存储的代码编写单元测试的最佳方法是什么,在我们的例子中是cassandra?

=>我们使用嵌入式服务器方法,使用来自git hub(https://github.com/hector-client/hector/blob/master/test/src/main/java/me/prettyprint/hector/testutils/EmbeddedServerHelper.java)的实用程序。但是我一直在看这个问题。 1)它将数据保存在多个测试用例中,这使得我们很难确保测试类的测试用例中的数据不同。我尝试在每个测试用例之后调用cleanUp @Ahech,但这似乎并没有清理数据。 2)当我们添加更多测试时,我们的内存不足,这可能是因为1,但我还不确定。我目前有1G堆大小来运行我的构建。

=>我一直在想的另一种方法是模拟cassandra存储。但是这可能会泄漏cassandra架构中的一些问题,因为我们经常发现上述方法可以解决数据存储到cassandra中的问题。

如果有人使用过EmbeddedServerHelper并且熟悉我提到的问题,请告诉我您的想法。


只是一个更新。通过在测试嵌入式服务器使用的cassandra.yaml中将in_memory_compaction_limit_in_mb参数更改为32,我能够解决2)运行构建时用尽Java堆空间问题。以下链接帮助了我http://www.datastax.com/docs/0.7/configuration/storage_configuration#in-memory-compaction-limit-in-mb。它是64,并且在压实过程中始终失败。

6 个答案:

答案 0 :(得分:9)

我们使用嵌入式cassandra服务器,我认为这是测试cassandra的最佳方法,模拟cassandra API太容易出错。

EmbeddedServerHelper.cleanup()只删除文件系统中的文件,但数据可能仍存在于内存中。

teardown()中有一个EmbeddedServerHelper方法,但我不确定它的效果如何,因为cassandra有很多静态单例,其状态未被teardown() <清除/ p>

我们所做的是在测试之间有一个在每个列族上调用truncate的方法。这将删除所有数据。

答案 1 :(得分:7)

我想你可以看看cassandra-unit:https://github.com/jsevellec/cassandra-unit/wiki

答案 2 :(得分:3)

我使用Mojo Cassandra maven plugin

这是一个示例插件配置,用于启动Cassandra服务器以供我的单元测试使用:

 <build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>cassandra-maven-plugin</artifactId>
            <version>1.1.0-1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>start</goal>
                        <goal>flush</goal>
                        <goal>cleanup</goal>
                    </goals>
                    <phase>compile</phase>
                </execution>
            </executions>
        </plugin>
     <plugins>
  <build>

我确实设法使Hector的嵌入式服务器助手类工作非常有用,但由于this bug我遇到了类加载器冲突。

答案 3 :(得分:2)

你无法在一个虚拟机中重启Cassandra实例 - 由于他们正在使用的singeltons,Cassandra已经“关闭每个杀死策略”。

您也不需要重新启动Casandra,只需删除所有列族(CF)。为了删除CF,你首先需要刷新数据,压缩数据,然后最后你可以删除它。

此代码将连接到嵌入式Cassandra并执行必需的cleaup:

private void cleanAndCompact() throws Exception {
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    ObjectName ssn = new ObjectName("org.apache.cassandra.db:type=StorageService");
    StorageServiceMBean ssmb = JMX.newMBeanProxy(mbs, ssn, StorageServiceMBean.class);

    List<String> keyspaces = ssmb.getKeyspaces();
    if (keyspaces == null) {
        LOG.info("No keysaces to cleanup");
        return;
    }

    for (String keyspace : keyspaces) {
        if (keyspace.equalsIgnoreCase("system")) {
            continue;
        }
        execCleanup(ssmb, keyspace);
    }

}

private void execCleanup(StorageServiceMBean ssmb, String keyspace) throws Exception {
    LOG.info("Cleaning up keyspace: " + keyspace);

    ssmb.invalidateKeyCaches(keyspace, new String[0]);
    ssmb.invalidateRowCaches(keyspace, new String[0]);
    ssmb.forceTableFlush(keyspace, new String[0]);
    ssmb.forceTableCompaction(keyspace, new String[0]);
    ssmb.forceTableCleanup(keyspace, new String[0]);
}

现在执行CLI drop CF脚本:

CliMain.main(new String[] { "-host", host, "-port", Integer.toString(rpcPort), "-f", "/my/script/path/script.txt","-username", "myUser", "-password", "123456" });

和script.txt可以有:

use ExampleTestSpace;
drop column family ExampleCF;

答案 4 :(得分:0)

通过“似乎没有清理数据”究竟是什么意思?你还在数据库中看到你的数据吗?

这个问题可能是由于Cassandra没有立即删除“值”,而是仅在gc_grace_seconds秒后通过(通常默认为10天)。 Cassandra标记要删除的值。

答案 5 :(得分:0)

除了发布的内容之外,还有一些情况需要测试错误处理 - 当Cassandra查询失败时,您的应用如何表现。

有一些图书馆可以帮助您解决这个问题:

我是cassandra-spy的作者并写信帮助我测试这些案例。