截断Riak数据库



我正在编写一段使用Riak DB的代码,我想在每次测试开始时将数据库重置为已知状态。

有没有一种方法可以干净地截断riak数据库?那么在事务内部执行并在测试结束时回滚的方法呢?

目前我使用的代码如下:

riak.buckets.each do |bucket|
  bucket.keys.each do |key|
    bucket.delete(key)
  end
end

但我想在每次测试开始时这样做会很慢。

我认为每个面向测试的开发人员在使用Riak时都会面临这种困境。正如克里斯蒂安所提到的,在里亚克没有回滚的概念。而且,您不能发出单一的"truncate database"命令。

你有3种方法可供选择:

  1. 清除测试集群上的所有数据。这本质上意味着发出shell命令(假设测试服务器与测试套件在同一台机器上运行)。如果您使用的是内存后端,这意味着在每个测试之间发出riak restart。对于其他后端,您必须停止节点并删除整个数据目录,然后重新启动它:riak stop && rm -rf <...>/data/* && riak start。PROS:在每次测试之间清除集群数据。缺点:这很慢(当你考虑到关闭和重启时间时),从测试套件发出shell命令通常很尴尬。(旁注:虽然在每次测试之间进行操作可能会很慢,但在整个测试套件每次运行之前,您可以随时清除数据目录。)

  2. 循环遍历测试集群上的所有bucket和key并删除它们,正如您上面所建议的那样。PROS:易于理解和实施。缺点:也很慢(在每次测试之间运行)。

  3. 每次测试结束后都要进行清理。因此,如果您的测试创建了一个User对象,请确保在测试结束时为该对象发出DELETE命令。或者,在创建用户之前,测试用户最初是否存在。(以确保上一次测试已清理干净)。PROS:易于理解和实施。快速(肯定比在每次测试之间循环遍历所有bucket和key更快)。缺点:开发人员很容易忘记在每次插入后进行清理。

在讨论了这些方法之后,我决定使用#3(经常与在每次测试套件运行之前擦除测试服务器数据目录相结合)。

关于减轻"每次测试自行清理,手动"方法的CONS的一些想法:

使用以随机顺序运行测试的测试框架。许多框架,比如Ruby的Minitest,都是开箱即用的。这通常有助于捕获依赖于其他测试的测试,方便地忘记清理

测试运行后,定期检查测试集群(通过列表存储桶),以确保没有任何剩余内容。事实上,您可以在每个测试套件的末尾以编程方式执行此操作(简单到创建一个bucket列表并确保它为空)。

(一般来说,这是一个很好的测试实践,但与Riak特别相关)少写命中数据库的测试。在单元测试(在不影响数据库的情况下测试对象状态和行为)和集成或功能测试(确实影响数据库)之间保持严格的划分。确保前者比后者多得多。换句话说,您不必在每次单元测试中测试数据库是否工作。相信它(尽管很明显,在集成测试期间要验证)。

例如,如果您正在将Riak与RubyonRails一起使用,并且正在测试您的模型,那么不要调用test_user.save!来验证用户实例是否有效(就像我刚开始使用时所做的那样)。您可以简单地测试test_user.valid?,并了解在实际使用过程中,保存调用将相应地工作(或失败)。考虑使用Mockist风格的测试,它验证是否真的调用了save!函数,而不是真的保存到数据库中然后读回。等等。

这里几乎没有可能的答案。

  1. 您是否通过使用Riak的密钥查询来测试数据是否持久化?如果是这样,您可以设置一个测试服务器。文档就在这里,http://rubydoc.info/github/basho/riak-ruby-client/Riak/TestServer
  2. 您是否正在通过二级索引测试访问权限?如果是,为什么?你不信任Riak或Ruby司机吗
  3. 无论如何,您的测试都不应该耦合到数据存储。它会减慢速度
  4. 如果你坚持,并且TestServer不适合你,那么为每次测试运行设置一个新的bucket。每个bucket都有自己的名称空间,所以它几乎是清白的。根据Christian的回答,定期停止节点并清除数据目录

由于Riak中没有事务或回滚的概念,所以这是不可能的。然而,内存后端通常用于测试,因为它支持Bitask(自动过期)和LevelDB(二级索引)的功能。每当需要清除数据库时,只需重新启动节点即可。

如果在测试时使用Bitask或LevelDB,清除数据库的最有效方法是关闭节点并简单地删除数据目录。

最新更新