19

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

=> 我们正在使用嵌入式服务器方法,使用来自 git hub 的实用程序(https://github.com/hector-client/hector/blob/master/test/src/main/java/me/prettyprint/hector/testutils/EmbeddedServerHelper .java )。但是,我已经看到了一些问题。1)它在多个测试用例中保留数据,这使我们很难确保测试类的测试用例中的数据不同。我尝试调用 cleanUp @After 每个测试用例,但这似乎并没有清理数据。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 并且在压缩期间开始持续失败。

4

6 回答 6

10

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

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

中有一个teardown()方法EmbeddedServerHelper,但我不确定它有多有效,因为 cassandra 有很多静态单例,它们的状态没有被清理teardown()

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

于 2011-07-09T14:31:00.353 回答
7

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

于 2011-10-13T18:39:08.560 回答
3

我使用Mojo Cassandra maven 插件

这是我用来启动 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 的嵌入式服务器助手类工作,这可能非常有用,但是由于这个错误,我遇到了类加载器冲突。

于 2012-12-01T16:10:20.573 回答
2

您无法在一个 VM 中重新启动 Cassandra 实例 - Cassandra 具有“每次杀死策略关闭”,因为他们正在使用单条。

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

此代码将连接到嵌入式 Cassandra 并执行所需的清理:

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;
于 2011-11-30T15:26:26.350 回答
0

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

该问题可能是由于 Cassandra 不会立即删除“值”,而是仅在经过gc_grace_seconds几秒钟之后(通常默认为 10 天)。Cassandra 标记要删除的值。

于 2011-07-08T12:55:33.480 回答
0

除了已发布的内容之外,在某些情况下,您还想测试错误处理——当 Cassandra 查询失败时,您的应用程序会如何表现。

有一些库可以帮助您解决这个问题:

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

于 2017-08-02T10:50:59.220 回答