2011-11-22 38 views
4

在处理最终一致的数据存储(如MongoDB)时编写测试用例的最佳做法是什么?最终一致性和测试用例

我目前的设置是Mongodb,它有一个3节点主/从/从设置,slave-ok设置为true。这意味着主节点用于只写,而两个从节点用于只读。

数据在从站上一致的时间相对较短,并且取决于操作和数据大小。例如,对于1000个对象,删除操作的时间约为3毫秒,批量插入的时间约为200毫秒。

我的目标是测试我的道操作。它们可能很简单,比如getById,删除,插入,或者像findByExample这样的复杂类。我需要验证它们是否正常工作,最终一致性可以接受。

这是我目前的测试删除操作,例如:

@Test 
    public void deleteTest() throws InstantiationException, 
       IllegalAccessException { 
     MyObject obj = new MyObject(); 
     obj.setName("test object"); 
     obj.save(obj); 
     MyObject found = dao.findById(obj.getId()); 
     logger.info ("before: " + found); 
     Assert.assertEquals(obj, found); 

     dao.delete(obj.getId()); 
     MyObject deleted = null; 
     long start = System.nanoTime(); 
     do { 
       //TBD: need to add escape condition/timeout, else may be infinite loop.... 
       deleted = dao.findById(obj.getId()); 
       logger.info ("While: " + deleted); 
     } while (deleted!=null); 
     logger.info("It took " + ((System.nanoTime()-start)/1000000.00) + " ms for delete to be consistent"); 
     Assert.assertEquals(null, d1); 
    } 
+0

你想测试什么?您的应用程序如何处理“陈旧”数据?或者您的MongoDB安装需要多长时间才能传播更改? – Thilo

+1

我正在测试我的Dao上的操作。它们可能很简单,比如getById,删除,插入,或者像findByExample这样的复杂类。我需要验证它们是否正常工作,最终一致性可以接受。 – ltfishie

+0

在这种情况下,让他们在查询奴隶之前让他们睡在可接受的限度内(如果这样做不必要的时间过长,让他们每秒钟醒来)。 – Thilo

回答

1

一对夫妇的想法浮现在脑海

  1. 在生产中,如果你是从从准备,你永远不知道你是否获得最新的数据。这是MongoDB中读取从机的权衡。我的经验是,在正常的工作条件下,奴隶是最新的。如果您必须获取最新的数据,请查询主数据。
  2. 我肯定会开始使用mms来追踪您的副本滞后。这将告诉你,你的奴隶背后有多远,以便你能感觉到数据有多快可用
  3. 至于最初的测试问题,它取决于你的目标。无论是复制还是独立,您的DAO都应该能够读写它们。您只需确保您的应用程序了解它所查询的数据可能不是最新的数据。
1

对于你正在做的事情,你可以依靠这样一个事实:对于一个副本集,mongo将始终写入主节点。因此,我想删除测试改变这样的事情:

/* 
* get this from the DAO, 
* or use the instance injected into the DAO, etc. 
*/ 
DBCollection collection = something(); 
DBCursor itemsRemaining = collection.find(); //find everything 
itemsRemaining.setReadPreference(ReadPreference.PRIMARY); //force query to the master 
Assert.assertEquals(0, itemsRemaining.count()); 

通过DBCollection做测试允许用户直接强制测试查询使用主。我会测试findById(anyOldId)将返回null,当项目不在一个单独的测试集合中。