2014-08-30 46 views
4

我开发了一个自定义Solr搜索组件,为此我需要编写单元测试。正如我在其他Solr组件的代码中看到的,在Solr中编写单元测试是通过扩展SolrTestCaseJ4类来完成的。不幸的是,SolrTestCaseJ4不适用于分布式设置中的测试,而我的自定义组件仅适用于这种设置。事实上,我的组件有意在没有分布式设置时返回空响应。测试Solr分布式组件

我在想方法来使用BaseDistributedSearchTestCase类来测试我的组件。 BaseDistributedSearchTestCase的问题是它如何工作并不能解决我的问题。在使用BaseDistributedSearchTestCase时,您可以定义一种单一的测试方法,您可以为所有文档建立索引并执行一些查询。运行测试会在分布式设置和单个核心设置上执行请求。然后比较每个设置的响应以验证它们的相等性。我无法在该流程中明确声明任何内容。

如何为Solr分布式组件编写单元测试?

回答

4

在Solr 4.7中添加了一个MiniSolrCloudCluster类,它可以在本地实际“部署”一个完整的solr集群,包括动物园管理员,分片和所有内容,以便进行测试。

你可以在这里找到JIRA:https://issues.apache.org/jira/browse/SOLR-5865

我已经成功地用它来完成对Solr的分布式组件的测试,同时从Solr的测试举例如下:

 
    private static MiniSolrCloudCluster miniCluster; 
    private static CloudSolrServer cloudSolrServer; 

    @BeforeClass 
    public static void setup() throws Exception { 
     miniCluster = new MiniSolrCloudCluster(2, null, new File("src/main/solr/solr.xml"), null, null); 
     uploadConfigToZk("src/main/solr/content/conf/", "content"); 

     // override settings in the solrconfig include 
     System.setProperty("solr.tests.maxBufferedDocs", "100000"); 
     System.setProperty("solr.tests.maxIndexingThreads", "-1"); 
     System.setProperty("solr.tests.ramBufferSizeMB", "100"); 
     // use non-test classes so RandomizedRunner isn't necessary 
     System.setProperty("solr.tests.mergeScheduler", "org.apache.lucene.index.ConcurrentMergeScheduler"); 
     System.setProperty("solr.directoryFactory", "solr.RAMDirectoryFactory");   

     cloudSolrServer = new CloudSolrServer(miniCluster.getZkServer().getZkAddress(), false); 
     cloudSolrServer.setRequestWriter(new RequestWriter()); 
     cloudSolrServer.setParser(new XMLResponseParser()); 
     cloudSolrServer.setDefaultCollection("content"); 
     cloudSolrServer.setParallelUpdates(false); 
     cloudSolrServer.connect(); 

     createCollection(cloudSolrServer, "content", 2, 1, "content"); 

    } 

    protected static void uploadConfigToZk(String configDir, String configName) throws Exception { 
     SolrZkClient zkClient = null; 
     try { 
      zkClient = new SolrZkClient(miniCluster.getZkServer().getZkAddress(), 10000, 45000, null); 
      uploadConfigFileToZk(zkClient, configName, "solrconfig.xml", new File(configDir, "solrconfig.xml")); 
      uploadConfigFileToZk(zkClient, configName, "schema.xml", new File(configDir, "schema.xml")); 
      uploadConfigFileToZk(zkClient, configName, "stopwords_en.txt", new File(configDir, "stopwords_en.txt")); 
      uploadConfigFileToZk(zkClient, configName, "stopwords_it.txt", new File(configDir, "stopwords_it.txt")); 

      System.out.println(zkClient.getChildren(ZkController.CONFIGS_ZKNODE + "/" + configName, null, true)); 
     } finally { 
      if (zkClient != null) 
       zkClient.close(); 
     } 
    } 

    protected static void uploadConfigFileToZk(SolrZkClient zkClient, String configName, String nameInZk, File file) throws Exception { 
     zkClient.makePath(ZkController.CONFIGS_ZKNODE + "/" + configName + "/" + nameInZk, file, false, true); 
    } 

    @AfterClass 
    public static void shutDown() throws Exception { 
     miniCluster.shutdown(); 
    } 

    protected static NamedList createCollection(CloudSolrServer server, String name, int numShards, int replicationFactor, String configName) throws Exception { 
     ModifiableSolrParams modParams = new ModifiableSolrParams(); 
     modParams.set(CoreAdminParams.ACTION, CollectionAction.CREATE.name()); 
     modParams.set("name", name); 
     modParams.set("numShards", numShards); 
     modParams.set("replicationFactor", replicationFactor); 
     modParams.set("collection.configName", configName); 
     QueryRequest request = new QueryRequest(modParams); 
     request.setPath("/admin/collections"); 
     return server.request(request); 
    } 

    @Test 
    public void test() throws Exception { 
     // Do you stuff here using cloudSolrServer as a normal solrServer 
    } 

+0

优秀的文章,但我相信这是首次与Solr 4.8.0一起发货。 – Ryan 2014-11-05 21:33:01