package lux.solr; import java.io.File; import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.embedded.LuxJettySolrRunner; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.cloud.AbstractFullDistribZkTestBase; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.NamedList; import org.junit.Ignore; /** * Basic test of Lux operation in a distributed ("cloud") setup. Inserts some test * documents and performs basic queries: ordered (by docid), sorted by field, and * sorted by relevance. TODO: Test both query parsers (user-supplied lux:search(string)). * * Test is ignored by default because it's slow, and doesn't seem to work properly on * travis-ci.org */ @Ignore public class ZkCloudTest extends AbstractFullDistribZkTestBase { public ZkCloudTest () { // shard by hashing the uri id = "lux_uri"; // fixShardCount = true; // shardCount = 2; } /** * Subclasses can override this to change a test's solr home * TODO: understand why we need this, yet properties seem to come from solr/conf/solrconfig.xml?? */ @Override public String getSolrHome() { return "zk-solr"; } @Override protected String getCloudSolrConfig() { return "solrconfig-tlog.xml"; } @Override public void createServers (int n) throws Exception { super.createServers(n); } @Override protected void destroyServers() throws Exception { super.destroyServers(); } @Override public void doTest() throws Exception { del("*:*"); // exclude certain result components from comparisons: initComparisonRegime(); String addTen = "for $i in 1 to 10 " + "let $doc := <doc>{$i}</doc> " + "return lux:insert(concat('/doc/', $i), $doc)"; query("qt", "/xquery", "q", addTen); query("qt", "/xquery", "q", "count(collection())"); query("qt", "/xquery", "q", "lux:commit()"); //query("qt", "/update", "commit", "true"); query("qt", "/xquery", "q", "count(collection())"); verifyShardCounts(10); // delete query ("qt", "/xquery", "q", "(lux:delete('/doc/1'), lux:commit(), count(collection()))"); verifyShardCounts(9); // delete all query ("qt", "/xquery", "q", "(lux:delete('lux:/'), count(collection()))"); verifyShardCounts(9); query ("qt", "/xquery", "q", "(lux:commit(), count(collection()))"); verifyShardCounts(0); } private void verifyShardCounts(int expectedTotal) throws Exception { int total = 0; for (int i = 0; i < this.sliceCount; i++) { // query the leader of each slice (aka shard -- the nomenclature is all confused) String count = sliceQuery(i, "qt", "/xquery", "q", "count(collection())"); int c = Integer.valueOf (count); // LoggerFactory.getLogger(getClass()).info("shard " + i + " has " + c + " documents"); total += c; } // each "slice" has some of the documents, they are replicated into a total number of // indexes == shardCount. assertEquals (expectedTotal, total); } private void initComparisonRegime() { // set some fields to ignore when comparing query results handle.clear(); handle.put("QTime", SKIPVAL); handle.put("timestamp", SKIPVAL); handle.put("_version_", SKIPVAL); handle.put("shards", SKIP); // in cloud response only handle.put("distrib", SKIP); // in control only handle.put("maxScore", SKIPVAL); // in cloud only } protected void query (String ... queryParams) throws Exception { final ModifiableSolrParams params = params(queryParams); QueryResponse rsp = cloudClient.query(params); // compare with control response params.set("distrib", "false"); final QueryResponse controlRsp = controlClient.query(params); validateControlData(controlRsp); compareResponses(rsp, controlRsp); } protected String sliceQuery(int slice, String ... q) throws Exception { final ModifiableSolrParams params = new ModifiableSolrParams(); for (int i = 0; i < q.length; i += 2) { params.add(q[i], q[i + 1]); } params.set("distrib", "false"); CloudJettyRunner jetty = shardToLeaderJetty.get ("shard" + (slice + 1)); final QueryResponse rsp = getClient(jetty.coreNodeName).query(params); NamedList<?> xpathResults = (NamedList<?>) rsp.getResponse().get("xpath-results"); assertNotNull ("no xquery results in response: " + rsp.getResponse(), xpathResults); return xpathResults.getVal(0).toString(); } @Override public JettySolrRunner createJetty(File solrHome, String dir, String shardList, String solrConfigOverride, String schemaOverride) throws Exception { JettySolrRunner jetty = new LuxJettySolrRunner(solrHome.getAbsolutePath(), context, 0, solrConfigOverride, schemaOverride, false, getExtraServlets()); jetty.setShards(shardList); jetty.setDataDir(getDataDir(dir)); jetty.start(); return jetty; } } /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */