You are viewing a plain text version of this content. The canonical link for it is here.
Posted to solr-commits@lucene.apache.org by sh...@apache.org on 2009/12/07 21:13:21 UTC
svn commit: r888115 - in /lucene/solr/trunk: CHANGES.txt
src/test/org/apache/solr/BaseDistributedSearchTestCase.java
src/test/org/apache/solr/TestDistributedSearch.java
Author: shalin
Date: Mon Dec 7 20:13:20 2009
New Revision: 888115
URL: http://svn.apache.org/viewvc?rev=888115&view=rev
Log:
SOLR-1608 -- Extract base class from TestDistributedSearch to make it easy to write test cases for other distributed components
Added:
lucene/solr/trunk/src/test/org/apache/solr/BaseDistributedSearchTestCase.java (with props)
Modified:
lucene/solr/trunk/CHANGES.txt
lucene/solr/trunk/src/test/org/apache/solr/TestDistributedSearch.java
Modified: lucene/solr/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/CHANGES.txt?rev=888115&r1=888114&r2=888115&view=diff
==============================================================================
--- lucene/solr/trunk/CHANGES.txt (original)
+++ lucene/solr/trunk/CHANGES.txt Mon Dec 7 20:13:20 2009
@@ -130,6 +130,9 @@
* SOLR-1611: Added Lucene 2.9.1 collation contrib jar to lib (shalin)
+* SOLR-1608: Extract base class from TestDistributedSearch to make
+ it easy to write test cases for other distributed components. (shalin)
+
Build
----------------------
Added: lucene/solr/trunk/src/test/org/apache/solr/BaseDistributedSearchTestCase.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/org/apache/solr/BaseDistributedSearchTestCase.java?rev=888115&view=auto
==============================================================================
--- lucene/solr/trunk/src/test/org/apache/solr/BaseDistributedSearchTestCase.java (added)
+++ lucene/solr/trunk/src/test/org/apache/solr/BaseDistributedSearchTestCase.java Mon Dec 7 20:13:20 2009
@@ -0,0 +1,535 @@
+package org.apache.solr;
+
+import junit.framework.TestCase;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.embedded.JettySolrRunner;
+import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.schema.TrieDateField;
+import org.apache.solr.util.AbstractSolrTestCase;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Helper base class for distributed search test cases
+ *
+ * @since solr 1.5
+ */
+public abstract class BaseDistributedSearchTestCase extends AbstractSolrTestCase {
+ public static Random r = new Random(0);
+
+ protected JettySolrRunner controlJetty;
+ protected List<SolrServer> clients = new ArrayList<SolrServer>();
+ protected List<JettySolrRunner> jettys = new ArrayList<JettySolrRunner>();
+ protected String context = "/solr";
+ protected String shards;
+ protected File testDir;
+ protected SolrServer controlClient;
+
+ // to stress with higher thread counts and requests, make sure the junit
+ // xml formatter is not being used (all output will be buffered before
+ // transformation to xml and cause an OOM exception).
+ protected int stress = 2;
+ protected boolean verifyStress = true;
+ protected int nThreads = 3;
+
+
+ public static int ORDERED = 1;
+ public static int SKIP = 2;
+ public static int SKIPVAL = 4;
+ public static int UNORDERED = 8;
+
+ protected int flags;
+ protected Map<String, Integer> handle = new HashMap<String, Integer>();
+
+ protected String id = "id";
+
+ public static RandVal rint = new RandVal() {
+ public Object val() {
+ return r.nextInt();
+ }
+ };
+
+ public static RandVal rlong = new RandVal() {
+ public Object val() {
+ return r.nextLong();
+ }
+ };
+
+ public static RandVal rfloat = new RandVal() {
+ public Object val() {
+ return r.nextFloat();
+ }
+ };
+
+ public static RandVal rdouble = new RandVal() {
+ public Object val() {
+ return r.nextDouble();
+ }
+ };
+
+ public static RandVal rdate = new RandDate();
+
+ /**
+ * Perform the actual tests here
+ *
+ * @throws Exception on error
+ */
+ public abstract void doTest() throws Exception;
+
+ @Override
+ public String getSchemaFile() {
+ return null;
+ }
+
+ @Override
+ public String getSolrConfigFile() {
+ return null;
+ }
+
+ public static String[] fieldNames = new String[]{"n_ti", "n_f", "n_tf", "n_d", "n_td", "n_l", "n_tl", "n_dt", "n_tdt"};
+ public static RandVal[] randVals = new RandVal[]{rint, rfloat, rfloat, rdouble, rdouble, rlong, rlong, rdate, rdate};
+
+ protected String[] getFieldNames() {
+ return fieldNames;
+ }
+
+ protected RandVal[] getRandValues() {
+ return randVals;
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ System.setProperty("solr.test.sys.prop1", "propone");
+ System.setProperty("solr.test.sys.prop2", "proptwo");
+ testDir = new File(System.getProperty("java.io.tmpdir")
+ + System.getProperty("file.separator")
+ + getClass().getName() + "-" + System.currentTimeMillis());
+ testDir.mkdirs();
+ postSetUp();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ preTearDown();
+ destroyServers();
+ AbstractSolrTestCase.recurseDelete(testDir);
+ super.tearDown();
+ }
+
+ private void createServers(int numShards) throws Exception {
+ controlJetty = createJetty(testDir, "control");
+ controlClient = createNewSolrServer(controlJetty.getLocalPort());
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 1; i <= numShards; i++) {
+ if (sb.length() > 0) sb.append(',');
+ JettySolrRunner j = createJetty(testDir, "shard" + i);
+ jettys.add(j);
+ clients.add(createNewSolrServer(j.getLocalPort()));
+ sb.append("localhost:").append(j.getLocalPort()).append(context);
+ }
+
+ shards = sb.toString();
+ }
+
+ protected void destroyServers() throws Exception {
+ controlJetty.stop();
+ for (JettySolrRunner jetty : jettys) jetty.stop();
+ clients.clear();
+ jettys.clear();
+ }
+
+ public static JettySolrRunner createJetty(File baseDir, String dataDirName) throws Exception {
+ File subDir = new File(baseDir, dataDirName);
+ subDir.mkdirs();
+ System.setProperty("solr.data.dir", subDir.toString());
+
+ JettySolrRunner jetty = new JettySolrRunner("/solr", 0);
+
+ jetty.start();
+ return jetty;
+ }
+
+ protected SolrServer createNewSolrServer(int port) {
+ try {
+ // setup the server...
+ String url = "http://localhost:" + port + context;
+ CommonsHttpSolrServer s = new CommonsHttpSolrServer(url);
+ s.setConnectionTimeout(100); // 1/10th sec
+ s.setDefaultMaxConnectionsPerHost(100);
+ s.setMaxTotalConnections(100);
+ return s;
+ }
+ catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ protected void addFields(SolrInputDocument doc, Object... fields) {
+ for (int i = 0; i < fields.length; i += 2) {
+ doc.addField((String) (fields[i]), fields[i + 1]);
+ }
+ }// add random fields to the documet before indexing
+
+ protected void indexr(Object... fields) throws Exception {
+ SolrInputDocument doc = new SolrInputDocument();
+ addFields(doc, fields);
+ addFields(doc, "rnd_b", true);
+ addFields(doc, getRandFields(getFieldNames(), getRandValues()));
+ indexDoc(doc);
+ }
+
+ protected void index(Object... fields) throws Exception {
+ SolrInputDocument doc = new SolrInputDocument();
+ addFields(doc, fields);
+ indexDoc(doc);
+ }
+
+ protected void indexDoc(SolrInputDocument doc) throws IOException, SolrServerException {
+ controlClient.add(doc);
+
+ int which = (doc.getField(id).toString().hashCode() & 0x7fffffff) % clients.size();
+ SolrServer client = clients.get(which);
+ client.add(doc);
+ }
+
+ protected void index_specific(int serverNumber, Object... fields) throws Exception {
+ SolrInputDocument doc = new SolrInputDocument();
+ for (int i = 0; i < fields.length; i += 2) {
+ doc.addField((String) (fields[i]), fields[i + 1]);
+ }
+ controlClient.add(doc);
+
+ SolrServer client = clients.get(serverNumber);
+ client.add(doc);
+ }
+
+ protected void del(String q) throws Exception {
+ controlClient.deleteByQuery(q);
+ for (SolrServer client : clients) {
+ client.deleteByQuery(q);
+ }
+ }// serial commit...
+
+ protected void commit() throws Exception {
+ controlClient.commit();
+ for (SolrServer client : clients) client.commit();
+ }
+
+ protected void query(Object... q) throws Exception {
+ final ModifiableSolrParams params = new ModifiableSolrParams();
+
+ for (int i = 0; i < q.length; i += 2) {
+ params.add(q[i].toString(), q[i + 1].toString());
+ }
+
+ final QueryResponse controlRsp = controlClient.query(params);
+
+ // query a random server
+ params.set("shards", shards);
+ int which = r.nextInt(clients.size());
+ SolrServer client = clients.get(which);
+ QueryResponse rsp = client.query(params);
+
+ compareResponses(rsp, controlRsp);
+
+ if (stress > 0) {
+ log.info("starting stress...");
+ Thread[] threads = new Thread[nThreads];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new Thread() {
+ public void run() {
+ for (int j = 0; j < stress; j++) {
+ int which = r.nextInt(clients.size());
+ SolrServer client = clients.get(which);
+ try {
+ QueryResponse rsp = client.query(new ModifiableSolrParams(params));
+ if (verifyStress) {
+ compareResponses(rsp, controlRsp);
+ }
+ } catch (SolrServerException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ };
+ threads[i].start();
+ }
+
+ for (Thread thread : threads) {
+ thread.join();
+ }
+ }
+ }
+
+ public static boolean eq(String a, String b) {
+ return a == b || (a != null && a.equals(b));
+ }
+
+ public static int flags(Map<String, Integer> handle, Object key) {
+ if (handle == null) return 0;
+ Integer f = handle.get(key);
+ return f == null ? 0 : f;
+ }
+
+ public static String compare(NamedList a, NamedList b, int flags, Map<String, Integer> handle) {
+ boolean ordered = (flags & UNORDERED) == 0;
+
+ int posa = 0, posb = 0;
+ int aSkipped = 0, bSkipped = 0;
+
+ for (; ;) {
+ if (posa >= a.size() || posb >= b.size()) {
+ break;
+ }
+
+ String namea, nameb;
+ Object vala, valb = null;
+
+ int flagsa, flagsb;
+ for (; ;) {
+ namea = a.getName(posa);
+ vala = a.getVal(posa);
+ posa++;
+ flagsa = flags(handle, namea);
+ if ((flagsa & SKIP) != 0) {
+ aSkipped++;
+ continue;
+ }
+ break;
+ }
+
+ if (!ordered) posb = 0; // reset if not ordered
+
+ while (posb < b.size()) {
+ nameb = b.getName(posb);
+ valb = b.getVal(posb);
+ posb++;
+ flagsb = flags(handle, nameb);
+ if ((flagsb & SKIP) != 0) {
+ bSkipped++;
+ continue;
+ }
+ if (eq(namea, nameb)) {
+ break;
+ }
+ if (ordered) {
+ return "." + namea + "!=" + nameb + " (unordered or missing)";
+ }
+ // if unordered, continue until we find the right field.
+ }
+
+ // ok, namea and nameb should be equal here already.
+ if ((flagsa & SKIPVAL) != 0) continue; // keys matching is enough
+
+ String cmp = compare(vala, valb, flagsa, handle);
+ if (cmp != null) return "." + namea + cmp;
+ }
+
+
+ if (a.size() - aSkipped != b.size() - bSkipped) {
+ return ".size()==" + a.size() + "," + b.size() + "skipped=" + aSkipped + "," + bSkipped;
+ }
+
+ return null;
+ }
+
+ public static String compare1(Map a, Map b, int flags, Map<String, Integer> handle) {
+ String cmp;
+
+ for (Object keya : a.keySet()) {
+ Object vala = a.get(keya);
+ int flagsa = flags(handle, keya);
+ if ((flagsa & SKIP) != 0) continue;
+ if (!b.containsKey(keya)) {
+ return "[" + keya + "]==null";
+ }
+ if ((flagsa & SKIPVAL) != 0) continue;
+ Object valb = b.get(keya);
+ cmp = compare(vala, valb, flagsa, handle);
+ if (cmp != null) return "[" + keya + "]" + cmp;
+ }
+ return null;
+ }
+
+ public static String compare(Map a, Map b, int flags, Map<String, Integer> handle) {
+ String cmp;
+ cmp = compare1(a, b, flags, handle);
+ if (cmp != null) return cmp;
+ return compare1(b, a, flags, handle);
+ }
+
+ public static String compare(SolrDocument a, SolrDocument b, int flags, Map<String, Integer> handle) {
+ return compare(a.getFieldValuesMap(), b.getFieldValuesMap(), flags, handle);
+ }
+
+ public static String compare(SolrDocumentList a, SolrDocumentList b, int flags, Map<String, Integer> handle) {
+ boolean ordered = (flags & UNORDERED) == 0;
+
+ String cmp;
+ int f = flags(handle, "maxScore");
+ if ((f & SKIPVAL) == 0) {
+ cmp = compare(a.getMaxScore(), b.getMaxScore(), 0, handle);
+ if (cmp != null) return ".maxScore" + cmp;
+ } else {
+ if (b.getMaxScore() != null) {
+ if (a.getMaxScore() == null) {
+ return ".maxScore missing";
+ }
+ }
+ }
+
+ cmp = compare(a.getNumFound(), b.getNumFound(), 0, handle);
+ if (cmp != null) return ".numFound" + cmp;
+
+ cmp = compare(a.getStart(), b.getStart(), 0, handle);
+ if (cmp != null) return ".start" + cmp;
+
+ cmp = compare(a.size(), b.size(), 0, handle);
+ if (cmp != null) return ".size()" + cmp;
+
+ // only for completely ordered results (ties might be in a different order)
+ if (ordered) {
+ for (int i = 0; i < a.size(); i++) {
+ cmp = compare(a.get(i), b.get(i), 0, handle);
+ if (cmp != null) return "[" + i + "]" + cmp;
+ }
+ return null;
+ }
+
+ // unordered case
+ for (int i = 0; i < a.size(); i++) {
+ SolrDocument doc = a.get(i);
+ Object key = doc.getFirstValue("id");
+ SolrDocument docb = null;
+ if (key == null) {
+ // no id field to correlate... must compare ordered
+ docb = b.get(i);
+ } else {
+ for (int j = 0; j < b.size(); j++) {
+ docb = b.get(j);
+ if (key.equals(docb.getFirstValue("id"))) break;
+ }
+ }
+ // if (docb == null) return "[id="+key+"]";
+ cmp = compare(doc, docb, 0, handle);
+ if (cmp != null) return "[id=" + key + "]" + cmp;
+ }
+ return null;
+ }
+
+ public static String compare(Object[] a, Object[] b, int flags, Map<String, Integer> handle) {
+ if (a.length != b.length) {
+ return ".length:" + a.length + "!=" + b.length;
+ }
+ for (int i = 0; i < a.length; i++) {
+ String cmp = compare(a[i], b[i], flags, handle);
+ if (cmp != null) return "[" + i + "]" + cmp;
+ }
+ return null;
+ }
+
+ public static String compare(Object a, Object b, int flags, Map<String, Integer> handle) {
+ if (a == b) return null;
+ if (a == null || b == null) return ":" + a + "!=" + b;
+
+ if (a instanceof NamedList && b instanceof NamedList) {
+ return compare((NamedList) a, (NamedList) b, flags, handle);
+ }
+
+ if (a instanceof SolrDocumentList && b instanceof SolrDocumentList) {
+ return compare((SolrDocumentList) a, (SolrDocumentList) b, flags, handle);
+ }
+
+ if (a instanceof SolrDocument && b instanceof SolrDocument) {
+ return compare((SolrDocument) a, (SolrDocument) b, flags, handle);
+ }
+
+ if (a instanceof Map && b instanceof Map) {
+ return compare((Map) a, (Map) b, flags, handle);
+ }
+
+ if (a instanceof Object[] && b instanceof Object[]) {
+ return compare((Object[]) a, (Object[]) b, flags, handle);
+ }
+
+ if (a instanceof byte[] && b instanceof byte[]) {
+ if (!Arrays.equals((byte[]) a, (byte[]) b)) {
+ return ":" + a + "!=" + b;
+ }
+ return null;
+ }
+
+ if (a instanceof List && b instanceof List) {
+ return compare(((List) a).toArray(), ((List) b).toArray(), flags, handle);
+
+ }
+
+ if (!(a.equals(b))) {
+ return ":" + a + "!=" + b;
+ }
+
+ return null;
+ }
+
+ protected void compareResponses(QueryResponse a, QueryResponse b) {
+ String cmp;
+ cmp = compare(a.getResponse(), b.getResponse(), flags, handle);
+ if (cmp != null) {
+ log.info("Mismatched responses:\n" + a + "\n" + b);
+ TestCase.fail(cmp);
+ }
+ }
+
+ public void testDistribSearch() throws Exception {
+ for (int nServers = 1; nServers < 2; nServers++) {
+ createServers(nServers);
+ RandVal.uniqueValues = new HashSet(); //reset random values
+ doTest();
+ destroyServers();
+ }
+ }
+
+ public static Object[] getRandFields(String[] fields, RandVal[] randVals) {
+ Object[] o = new Object[fields.length * 2];
+ for (int i = 0; i < fields.length; i++) {
+ o[i * 2] = fields[i];
+ o[i * 2 + 1] = randVals[i].uval();
+ }
+ return o;
+ }
+
+ public static abstract class RandVal {
+ public static Random r = new Random();
+ public static Set uniqueValues = new HashSet();
+
+ public abstract Object val();
+
+ public Object uval() {
+ for (; ;) {
+ Object v = val();
+ if (uniqueValues.add(v)) return v;
+ }
+ }
+ }
+
+ public static class RandDate extends RandVal {
+ public static TrieDateField df = new TrieDateField();
+
+ public Object val() {
+ long v = r.nextLong();
+ Date d = new Date(v);
+ return df.toExternal(d);
+ }
+ }
+}
Propchange: lucene/solr/trunk/src/test/org/apache/solr/BaseDistributedSearchTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/solr/trunk/src/test/org/apache/solr/BaseDistributedSearchTestCase.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: lucene/solr/trunk/src/test/org/apache/solr/TestDistributedSearch.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/org/apache/solr/TestDistributedSearch.java?rev=888115&r1=888114&r2=888115&view=diff
==============================================================================
--- lucene/solr/trunk/src/test/org/apache/solr/TestDistributedSearch.java (original)
+++ lucene/solr/trunk/src/test/org/apache/solr/TestDistributedSearch.java Mon Dec 7 20:13:20 2009
@@ -17,24 +17,7 @@
package org.apache.solr;
-import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.response.QueryResponse;
-import org.apache.solr.client.solrj.embedded.JettySolrRunner;
-import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
-import org.apache.solr.common.SolrInputDocument;
-import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.common.SolrDocument;
-import org.apache.solr.common.util.NamedList;
-import org.apache.solr.common.params.ModifiableSolrParams;
-import org.apache.solr.util.AbstractSolrTestCase;
-import org.apache.solr.schema.TrieDateField;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-
-import junit.framework.TestCase;
/**
* TODO? perhaps use:
@@ -44,7 +27,7 @@
* @version $Id$
* @since solr 1.3
*/
-public class TestDistributedSearch extends AbstractSolrTestCase {
+public class TestDistributedSearch extends BaseDistributedSearchTestCase {
public String getSchemaFile() {
return null;
}
@@ -53,19 +36,6 @@
return null;
}
- static Random r = new Random(0);
- File testDir;
-
- SolrServer controlClient;
- JettySolrRunner controlJetty;
-
- private List<SolrServer> clients = new ArrayList<SolrServer>();
- private List<JettySolrRunner> jettys = new ArrayList<JettySolrRunner>();
- String context = "/solr";
- String shards;
-
-
- String id="id";
String t1="a_t";
String i1="a_si";
String nint = "n_i";
@@ -83,492 +53,8 @@
String missingField="missing_but_valid_field_t";
String invalidField="invalid_field_not_in_schema";
- @Override public void setUp() throws Exception
- {
- super.setUp();
- System.setProperty("solr.test.sys.prop1", "propone");
- System.setProperty("solr.test.sys.prop2", "proptwo");
- testDir = new File(System.getProperty("java.io.tmpdir")
- + System.getProperty("file.separator")
- + getClass().getName() + "-" + System.currentTimeMillis());
- testDir.mkdirs();
- super.postSetUp();
- }
-
- @Override public void tearDown() throws Exception
- {
- super.preTearDown();
- destroyServers();
- AbstractSolrTestCase.recurseDelete(testDir);
- super.tearDown();
- }
-
-
- private void createServers(int numShards) throws Exception {
- controlJetty = createJetty("control");
- controlClient = createNewSolrServer(controlJetty.getLocalPort());
-
- StringBuilder sb = new StringBuilder();
- for (int i = 1; i <= numShards; i++) {
- if (sb.length()>0) sb.append(',');
- JettySolrRunner j = createJetty("shard"+i);
- jettys.add(j);
- clients.add(createNewSolrServer(j.getLocalPort()));
- sb.append("localhost:"+j.getLocalPort()+context);
- }
-
- shards = sb.toString();
- }
-
- private void destroyServers() throws Exception {
- controlJetty.stop();
- for (JettySolrRunner jetty : jettys) jetty.stop();
- clients.clear();
- jettys.clear();
- }
-
- private JettySolrRunner createJetty(String dataDirName) throws Exception {
- File subDir = new File(testDir, dataDirName);
- subDir.mkdirs();
- System.setProperty("solr.data.dir", subDir.toString());
-
- JettySolrRunner jetty = new JettySolrRunner("/solr", 0);
-
- jetty.start();
- return jetty;
- }
-
- protected SolrServer createNewSolrServer(int port)
- {
- try {
- // setup the server...
- String url = "http://localhost:"+port+context;
- CommonsHttpSolrServer s = new CommonsHttpSolrServer( url );
- s.setConnectionTimeout(100); // 1/10th sec
- s.setDefaultMaxConnectionsPerHost(100);
- s.setMaxTotalConnections(100);
- return s;
- }
- catch( Exception ex ) {
- throw new RuntimeException( ex );
- }
- }
-
- void addFields(SolrInputDocument doc, Object... fields) {
- for (int i=0; i<fields.length; i+=2) {
- doc.addField((String)(fields[i]), fields[i+1]);
- }
- }
-
- // add random fields to the documet before indexing
- void indexr(Object ... fields) throws Exception {
- SolrInputDocument doc = new SolrInputDocument();
- addFields(doc, fields);
- addFields(doc, "rnd_b", true);
- addFields(doc, getRandFields(fieldNames, randVals));
- indexDoc(doc);
- }
-
- void index(Object... fields) throws Exception {
- SolrInputDocument doc = new SolrInputDocument();
- addFields(doc, fields);
- indexDoc(doc);
- }
-
- void indexDoc(SolrInputDocument doc) throws IOException, SolrServerException {
- controlClient.add(doc);
-
- int which = (doc.getField(id).toString().hashCode() &0x7fffffff) % clients.size();
- SolrServer client = clients.get(which);
- client.add(doc);
- }
-
-
-
- void index_specific(int serverNumber, Object... fields) throws Exception {
- SolrInputDocument doc = new SolrInputDocument();
- for (int i=0; i<fields.length; i+=2) {
- doc.addField((String)(fields[i]), fields[i+1]);
- }
- controlClient.add(doc);
-
- int which = serverNumber;
- SolrServer client = clients.get(which);
- client.add(doc);
- }
-
- void del(String q) throws Exception {
- controlClient.deleteByQuery(q);
- for (SolrServer client : clients) {
- client.deleteByQuery(q);
- }
- }
-
-
- // serial commit...
- void commit() throws Exception {
- controlClient.commit();
- for (SolrServer client : clients) client.commit();
- }
-
- // to stress with higher thread counts and requests, make sure the junit
- // xml formatter is not being used (all output will be buffered before
- // transformation to xml and cause an OOM exception).
- int stress = 2;
- boolean verifyStress = true;
- int nThreads = 3;
-
-
- void query(Object... q) throws Exception {
- final ModifiableSolrParams params = new ModifiableSolrParams();
-
- for (int i=0; i<q.length; i+=2) {
- params.add(q[i].toString(), q[i+1].toString());
- }
-
- final QueryResponse controlRsp = controlClient.query(params);
-
- // query a random server
- params.set("shards", shards);
- int which = r.nextInt(clients.size());
- SolrServer client = clients.get(which);
- QueryResponse rsp = client.query(params);
-
- compareResponses(rsp, controlRsp);
-
- if (stress>0) {
- log.info("starting stress...");
- Thread[] threads = new Thread[nThreads];
- for (int i=0; i<threads.length; i++) {
- threads[i] = new Thread() {
- public void run() {
- for (int j=0; j<stress; j++) {
- int which = r.nextInt(clients.size());
- SolrServer client = clients.get(which);
- try {
- QueryResponse rsp = client.query(new ModifiableSolrParams(params));
- if (verifyStress) {
- compareResponses(rsp, controlRsp);
- }
- } catch (SolrServerException e) {
- throw new RuntimeException(e);
- }
- }
- }
- };
- threads[i].start();
- }
-
- for (Thread thread : threads) {
- thread.join();
- }
- }
- }
-
-
- private static int ORDERED=1;
- private static int SKIP=2;
- private static int SKIPVAL=4;
- private static int UNORDERED=8;
-
-
- public static boolean eq(String a, String b) {
- return a==b || (a != null && a.equals(b));
- }
-
- public static int flags(Map<String,Integer> handle, Object key) {
- if (handle==null) return 0;
- Integer f = handle.get(key);
- return f == null ? 0 : f;
- }
-
- public static String compare(NamedList a, NamedList b, int flags, Map<String,Integer> handle) {
- boolean ordered = (flags&UNORDERED) == 0;
-
- int posa = 0, posb = 0;
- int aSkipped = 0, bSkipped = 0;
-
- for(;;) {
- if (posa >= a.size() || posb >= b.size()) {
- break;
- }
-
- String namea=null, nameb=null;
- Object vala=null, valb=null;
-
- int flagsa, flagsb;
- for (;;) {
- namea = a.getName(posa);
- vala = a.getVal(posa);
- posa++;
- flagsa = flags(handle, namea);
- if ((flagsa & SKIP) != 0) {
- aSkipped++;
- continue;
- }
- break;
- }
-
- if (!ordered) posb=0; // reset if not ordered
-
- while (posb<b.size()) {
- nameb = b.getName(posb);
- valb = b.getVal(posb);
- posb++;
- flagsb = flags(handle, nameb);
- if ((flagsb & SKIP) != 0) {
- bSkipped++;
- continue;
- }
- if (eq(namea, nameb)) {
- break;
- }
- if (ordered) {
- return "."+namea+"!="+nameb+" (unordered or missing)";
- }
- // if unordered, continue until we find the right field.
- }
-
- // ok, namea and nameb should be equal here already.
- if ((flagsa & SKIPVAL) != 0) continue; // keys matching is enough
-
- String cmp = compare(vala, valb, flagsa, handle);
- if (cmp != null) return "."+namea+cmp;
- }
-
-
- if (a.size()-aSkipped != b.size()-bSkipped) {
- return ".size()=="+a.size()+","+b.size()+"skipped="+aSkipped+","+bSkipped;
- }
-
- return null;
- }
-
- private static String compare1(Map a, Map b, int flags, Map<String,Integer> handle) {
- String cmp;
-
- for (Object keya : a.keySet()) {
- Object vala = a.get(keya);
- int flagsa = flags(handle, keya);
- if ((flagsa & SKIP) != 0) continue;
- if (!b.containsKey(keya)) {
- return "[" + keya + "]==null";
- }
- if ((flagsa & SKIPVAL) != 0) continue;
- Object valb = b.get(keya);
- cmp = compare(vala, valb, flagsa, handle);
- if (cmp != null) return "[" + keya + "]" + cmp;
- }
- return null;
- }
-
- public static String compare(Map a, Map b, int flags, Map<String,Integer> handle) {
- String cmp;
- cmp = compare1(a,b,flags,handle);
- if (cmp != null) return cmp;
- return compare1(b,a,flags,handle);
- }
-
- public static String compare(SolrDocument a, SolrDocument b, int flags, Map<String,Integer> handle) {
- return compare(a.getFieldValuesMap(), b.getFieldValuesMap(), flags, handle);
- }
-
- public static String compare(SolrDocumentList a, SolrDocumentList b, int flags, Map<String,Integer> handle) {
- boolean ordered = (flags & UNORDERED) == 0;
-
- String cmp;
- int f = flags(handle, "maxScore");
- if ((f & SKIPVAL) == 0) {
- cmp = compare(a.getMaxScore(), b.getMaxScore(), 0, handle);
- if (cmp != null) return ".maxScore" + cmp;
- } else {
- if (b.getMaxScore() != null) {
- if (a.getMaxScore() == null) {
- return ".maxScore missing";
- }
- }
- }
-
- cmp = compare(a.getNumFound(), b.getNumFound(), 0, handle);
- if (cmp != null) return ".numFound" + cmp;
-
- cmp = compare(a.getStart(), b.getStart(), 0, handle);
- if (cmp != null) return ".start" + cmp;
-
- cmp = compare(a.size(), b.size(), 0, handle);
- if (cmp != null) return ".size()" + cmp;
-
- // only for completely ordered results (ties might be in a different order)
- if (ordered) {
- for (int i=0; i<a.size(); i++) {
- cmp = compare(a.get(i), b.get(i), 0, handle);
- if (cmp != null) return "["+i+"]"+cmp;
- }
- return null;
- }
-
- // unordered case
- for (int i=0; i<a.size(); i++) {
- SolrDocument doc = a.get(i);
- Object key = doc.getFirstValue("id");
- SolrDocument docb=null;
- if (key==null) {
- // no id field to correlate... must compare ordered
- docb = b.get(i);
- } else {
- for (int j=0; j<b.size(); j++) {
- docb = b.get(j);
- if (key.equals(docb.getFirstValue("id"))) break;
- }
- }
- // if (docb == null) return "[id="+key+"]";
- cmp = compare(doc, docb, 0, handle);
- if (cmp != null) return "[id="+key+"]" + cmp;
- }
- return null;
- }
-
- public static String compare(Object[] a, Object[] b, int flags, Map<String,Integer> handle) {
- if (a.length != b.length) {
- return ".length:"+a.length+"!="+b.length;
- }
- for (int i=0; i<a.length; i++) {
- String cmp = compare(a[i], b[i], flags, handle);
- if (cmp != null) return "["+i+"]"+cmp;
- }
- return null;
- }
-
-
- static String compare(Object a, Object b, int flags, Map<String,Integer> handle) {
- if (a==b) return null;
- if (a==null || b==null) return ":" +a + "!=" + b;
-
- if (a instanceof NamedList && b instanceof NamedList) {
- return compare((NamedList)a, (NamedList)b, flags, handle);
- }
-
- if (a instanceof SolrDocumentList && b instanceof SolrDocumentList) {
- return compare((SolrDocumentList)a, (SolrDocumentList)b, flags, handle);
- }
-
- if (a instanceof SolrDocument && b instanceof SolrDocument) {
- return compare((SolrDocument)a, (SolrDocument)b, flags, handle);
- }
-
- if (a instanceof Map && b instanceof Map) {
- return compare((Map)a, (Map)b, flags, handle);
- }
-
- if (a instanceof Object[] && b instanceof Object[]) {
- return compare((Object[])a, (Object[])b, flags, handle);
- }
-
- if (a instanceof byte[] && b instanceof byte[]) {
- if (!Arrays.equals((byte[])a, (byte[])b)) {
- return ":" + a + "!=" + b;
- }
- return null;
- }
-
- if (a instanceof List && b instanceof List) {
- return compare(((List)a).toArray(), ((List)b).toArray(), flags, handle);
-
- }
-
- if (!(a.equals(b))) {
- return ":" + a + "!=" + b;
- }
-
- return null;
- }
-
-
- void compareResponses(QueryResponse a, QueryResponse b) {
- String cmp;
- cmp = compare(a.getResponse(), b.getResponse(), flags, handle);
- if (cmp != null) {
- log.info("Mismatched responses:\n"+a+"\n"+b);
- TestCase.fail(cmp);
- }
- }
-
- int flags;
- Map<String, Integer> handle = new HashMap<String,Integer>();
-
-
- public void testDistribSearch() throws Exception {
- for (int nServers=1; nServers<4; nServers++) {
- createServers(nServers);
- doTest();
- }
- }
-
-
-
- public static abstract class RandVal {
- public static Random r = new Random();
- public static Set uniqueValues = new HashSet();
- public abstract Object val();
- public Object uval() {
- for(;;) {
- Object v = val();
- if (uniqueValues.add(v)) return v;
- }
- }
- }
-
- public static RandVal rint = new RandVal() {
- public Object val() {
- return r.nextInt();
- }
- };
-
- public static RandVal rlong = new RandVal() {
- public Object val() {
- return r.nextLong();
- }
- };
-
- public static RandVal rfloat = new RandVal() {
- public Object val() {
- return r.nextFloat();
- }
- };
-
- public static RandVal rdouble = new RandVal() {
- public Object val() {
- return r.nextDouble();
- }
- };
-
- public static class RandDate extends RandVal {
- public static TrieDateField df = new TrieDateField();
-
- public Object val() {
- long v = r.nextLong();
- Date d = new Date(v);
- return df.toExternal(d);
- }
- }
-
- public static RandVal rdate = new RandDate();
-
- public static String[] fieldNames = new String[] {"n_ti", "n_f", "n_tf", "n_d", "n_td", "n_l", "n_tl", "n_dt", "n_tdt"};
- public static RandVal[] randVals = new RandVal[] {rint, rfloat,rfloat, rdouble,rdouble,rlong,rlong, rdate, rdate};
-
- public static Object[] getRandFields(String[] fields, RandVal[] randVals) {
- Object[] o = new Object[fields.length*2];
- for (int i=0; i<fields.length; i++) {
- o[i*2] = fields[i];
- o[i*2+1] = randVals[i].uval();
- }
- return o;
- }
-
+ @Override
public void doTest() throws Exception {
- RandVal.uniqueValues = new HashSet(); // reset unique random values
-
del("*:*");
indexr(id,1, i1, 100, tlong, 100,t1,"now is the time for all good men"
,"foo_f", 1.414f, "foo_b", "true", "foo_d", 1.414d);
@@ -716,8 +202,6 @@
}
// Thread.sleep(10000000000L);
-
- destroyServers();
}
}