You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2012/01/25 21:32:53 UTC

svn commit: r1235919 [12/12] - in /lucene/dev/branches/lucene3661: ./ dev-tools/eclipse/ dev-tools/idea/lucene/contrib/ dev-tools/maven/ dev-tools/maven/solr/core/ dev-tools/maven/solr/solrj/ lucene/ lucene/contrib/ lucene/contrib/sandbox/src/test/org/...

Modified: lucene/dev/branches/lucene3661/solr/solrj/src/java/org/apache/solr/common/util/Hash.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/solrj/src/java/org/apache/solr/common/util/Hash.java?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/solrj/src/java/org/apache/solr/common/util/Hash.java (original)
+++ lucene/dev/branches/lucene3661/solr/solrj/src/java/org/apache/solr/common/util/Hash.java Wed Jan 25 20:32:44 2012
@@ -239,4 +239,59 @@ public class Hash {
     return c + (((long)b) << 32);
   }
 
+
+  /** Returns the MurmurHash3_x86_32 hash.
+   * Original source/tests at https://github.com/yonik/java_util/
+   */
+  public static int murmurhash3_x86_32(byte[] data, int offset, int len, int seed) {
+
+    final int c1 = 0xcc9e2d51;
+    final int c2 = 0x1b873593;
+
+    int h1 = seed;
+    int roundedEnd = offset + (len & 0xfffffffc);  // round down to 4 byte block
+
+    for (int i=offset; i<roundedEnd; i+=4) {
+      // little endian load order
+      int k1 = (data[i] & 0xff) | ((data[i+1] & 0xff) << 8) | ((data[i+2] & 0xff) << 16) | (data[i+3] << 24);
+      k1 *= c1;
+      k1 = (k1 << 15) | (k1 >>> 17);  // ROTL32(k1,15);
+      k1 *= c2;
+
+      h1 ^= k1;
+      h1 = (h1 << 13) | (h1 >>> 19);  // ROTL32(h1,13);
+      h1 = h1*5+0xe6546b64;
+    }
+
+    // tail
+    int k1 = 0;
+
+    switch(len & 0x03) {
+      case 3:
+        k1 = (data[roundedEnd + 2] & 0xff) << 16;
+        // fallthrough
+      case 2:
+        k1 |= (data[roundedEnd + 1] & 0xff) << 8;
+        // fallthrough
+      case 1:
+        k1 |= (data[roundedEnd] & 0xff);
+        k1 *= c1;
+        k1 = (k1 << 15) | (k1 >>> 17);  // ROTL32(k1,15);
+        k1 *= c2;
+        h1 ^= k1;
+    }
+
+    // finalization
+    h1 ^= len;
+
+    // fmix(h1);
+    h1 ^= h1 >>> 16;
+    h1 *= 0x85ebca6b;
+    h1 ^= h1 >>> 13;
+    h1 *= 0xc2b2ae35;
+    h1 ^= h1 >>> 16;
+
+    return h1;
+  }
+
 }

Modified: lucene/dev/branches/lucene3661/solr/solrj/src/java/org/apache/solr/common/util/StrUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/solrj/src/java/org/apache/solr/common/util/StrUtils.java?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/solrj/src/java/org/apache/solr/common/util/StrUtils.java (original)
+++ lucene/dev/branches/lucene3661/solr/solrj/src/java/org/apache/solr/common/util/StrUtils.java Wed Jan 25 20:32:44 2012
@@ -144,10 +144,11 @@ public class StrUtils {
   }
 
   /** Creates a backslash escaped string, joining all the items. */
-  public static String join(List<String> items, char separator) {
+  public static String join(List<?> items, char separator) {
     StringBuilder sb = new StringBuilder(items.size() << 3);
     boolean first=true;
-    for (String item : items) {
+    for (Object o : items) {
+      String item = o.toString();
       if (first) {
         first = false;
       } else {

Modified: lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java (original)
+++ lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java Wed Jan 25 20:32:44 2012
@@ -343,7 +343,7 @@ abstract public class SolrExampleTests e
    * query the example
    */
  @Test
- public void testCommitWithin() throws Exception
+ public void testCommitWithinOnAdd() throws Exception
   {    
     // make sure it is empty...
     SolrServer server = getSolrServer();
@@ -388,7 +388,6 @@ abstract public class SolrExampleTests e
     
     Assert.assertEquals( 1, rsp.getResults().getNumFound() );
     
-
     // Now test the new convenience parameter on the add() for commitWithin
     SolrInputDocument doc4 = new SolrInputDocument();
     doc4.addField( "id", "id4", 1.0f );
@@ -416,7 +415,52 @@ abstract public class SolrExampleTests e
     }
     
     Assert.assertEquals( 1, rsp.getResults().getNumFound() );
+  }
+ 
+ @Test
+ public void testCommitWithinOnDelete() throws Exception
+  {    
+    // make sure it is empty...
+    SolrServer server = getSolrServer();
+    server.deleteByQuery( "*:*" );// delete everything!
+    server.commit();
+    QueryResponse rsp = server.query( new SolrQuery( "*:*") );
+    Assert.assertEquals( 0, rsp.getResults().getNumFound() );
 
+    // Now add one document...
+    SolrInputDocument doc3 = new SolrInputDocument();
+    doc3.addField( "id", "id3", 1.0f );
+    doc3.addField( "name", "doc3", 1.0f );
+    doc3.addField( "price", 10 );
+    server.add(doc3);
+    server.commit();
+
+    // now check that it comes out...
+    rsp = server.query( new SolrQuery( "id:id3") );    
+    Assert.assertEquals( 1, rsp.getResults().getNumFound() );
+    
+    // now test commitWithin on a delete
+    UpdateRequest up = new UpdateRequest();
+    up.setCommitWithin(1000);
+    up.deleteById("id3");
+    up.process( server );
+    
+    // the document should still be there
+    rsp = server.query( new SolrQuery( "id:id3") );
+    Assert.assertEquals( 1, rsp.getResults().getNumFound() );
+    
+    // check if the doc has been deleted every 250 ms for 30 seconds
+    long timeout = System.currentTimeMillis() + 30000;
+    do {
+      Thread.sleep( 250 ); // wait 250 ms
+      
+      rsp = server.query( new SolrQuery( "id:id3") );
+      if(rsp.getResults().getNumFound()==0) {
+        return;
+      }
+    } while(System.currentTimeMillis()<timeout);
+    
+    Assert.fail("commitWithin failed to commit");
   }
 
 

Modified: lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrServer.java?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrServer.java (original)
+++ lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrServer.java Wed Jan 25 20:32:44 2012
@@ -276,8 +276,7 @@ public class TestLBHttpSolrServer extend
     }
 
     public void startJetty() throws Exception {
-      jetty = new JettySolrRunner("/solr", port);
-      System.setProperty("solr.solr.home", getHomeDir());
+      jetty = new JettySolrRunner(getHomeDir(), "/solr", port, "bad_solrconfig.xml", null);
       System.setProperty("solr.data.dir", getDataDir());
       jetty.start();
       int newPort = jetty.getLocalPort();

Modified: lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/MultiCoreExampleJettyTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/MultiCoreExampleJettyTest.java?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/MultiCoreExampleJettyTest.java (original)
+++ lucene/dev/branches/lucene3661/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/MultiCoreExampleJettyTest.java Wed Jan 25 20:32:44 2012
@@ -53,7 +53,7 @@ public class MultiCoreExampleJettyTest e
     System.clearProperty("solr.directoryFactory");
     super.setUp();
 
-    jetty = new JettySolrRunner( context, 0 );
+    jetty = new JettySolrRunner(getSolrHome(), context, 0 );
     jetty.start(false);
     port = jetty.getLocalPort();
 

Modified: lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java (original)
+++ lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java Wed Jan 25 20:32:44 2012
@@ -36,11 +36,14 @@ import org.apache.solr.client.solrj.Solr
 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.request.UpdateRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.client.solrj.response.UpdateResponse;
 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.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.schema.TrieDateField;
 import org.apache.solr.util.AbstractSolrTestCase;
@@ -69,6 +72,7 @@ public abstract class BaseDistributedSea
   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 String[] shardsArr;
@@ -159,7 +163,6 @@ public abstract class BaseDistributedSea
     super.setUp();
     System.setProperty("solr.test.sys.prop1", "propone");
     System.setProperty("solr.test.sys.prop2", "proptwo");
-    System.setProperty("solr.solr.home", getSolrHome());
     testDir = new File(TEMP_DIR,
             getClass().getName() + "-" + System.currentTimeMillis());
     testDir.mkdirs();
@@ -175,14 +178,17 @@ public abstract class BaseDistributedSea
   }
 
   protected void createServers(int numShards) throws Exception {
-    controlJetty = createJetty(testDir, testDir + "/control/data");
+    controlJetty = createJetty(testDir, testDir + "/control/data", null, getSolrConfigFile(), getSchemaFile());
+
     controlClient = createNewSolrServer(controlJetty.getLocalPort());
 
     shardsArr = new String[numShards];
     StringBuilder sb = new StringBuilder();
     for (int i = 0; i < numShards; i++) {
       if (sb.length() > 0) sb.append(',');
-      JettySolrRunner j = createJetty(testDir, testDir + "/shard" + i + "/data");
+      JettySolrRunner j = createJetty(testDir,
+          testDir + "/shard" + i + "/data", null, getSolrConfigFile(),
+          getSchemaFile());
       jettys.add(j);
       clients.add(createNewSolrServer(j.getLocalPort()));
       String shardStr = "localhost:" + j.getLocalPort() + context;
@@ -223,27 +229,28 @@ public abstract class BaseDistributedSea
 
   protected void destroyServers() throws Exception {
     controlJetty.stop();
+    ((CommonsHttpSolrServer) controlClient).shutdown();
     for (JettySolrRunner jetty : jettys) jetty.stop();
+    for (SolrServer client : clients) ((CommonsHttpSolrServer) client).shutdown();
     clients.clear();
     jettys.clear();
   }
   
   public JettySolrRunner createJetty(File baseDir, String dataDir) throws Exception {
-    return createJetty(baseDir, dataDir, null, null);
+    return createJetty(baseDir, dataDir, null, null, null);
   }
 
   public JettySolrRunner createJetty(File baseDir, String dataDir, String shardId) throws Exception {
-    return createJetty(baseDir, dataDir, shardId, null);
+    return createJetty(baseDir, dataDir, shardId, null, null);
   }
   
-  public JettySolrRunner createJetty(File baseDir, String dataDir, String shardList, String solrConfigOverride) throws Exception {
-    System.setProperty("solr.data.dir", dataDir);
-    JettySolrRunner jetty = new JettySolrRunner("/solr", 0, solrConfigOverride);
-    if(shardList != null) {
-      System.setProperty("shard", shardList);
-    }
+  public JettySolrRunner createJetty(File baseDir, String dataDir, String shardList, String solrConfigOverride, String schemaOverride) throws Exception {
+
+    JettySolrRunner jetty = new JettySolrRunner(getSolrHome(), "/solr", 0, solrConfigOverride, schemaOverride);
+    jetty.setShards(shardList);
+    jetty.setDataDir(dataDir);
     jetty.start();
-    System.clearProperty("shard");
+
     return jetty;
   }
   
@@ -272,9 +279,14 @@ public abstract class BaseDistributedSea
     SolrInputDocument doc = new SolrInputDocument();
     addFields(doc, fields);
     addFields(doc, "rnd_b", true);
-    addFields(doc, getRandFields(getFieldNames(), getRandValues()));
+    addRandFields(doc);
     indexDoc(doc);
   }
+  
+  protected SolrInputDocument addRandFields(SolrInputDocument sdoc) {
+    addFields(sdoc, getRandFields(getFieldNames(), getRandValues()));
+    return sdoc;
+  }
 
   protected void index(Object... fields) throws Exception {
     SolrInputDocument doc = new SolrInputDocument();
@@ -289,6 +301,33 @@ public abstract class BaseDistributedSea
     SolrServer client = clients.get(which);
     client.add(doc);
   }
+  
+  protected UpdateResponse add(SolrServer server, SolrParams params, SolrInputDocument... sdocs) throws IOException, SolrServerException {
+    UpdateRequest ureq = new UpdateRequest();
+    ureq.setParams(new ModifiableSolrParams(params));
+    for (SolrInputDocument sdoc : sdocs) {
+      ureq.add(sdoc);
+    }
+    return ureq.process(server);
+  }
+
+  protected UpdateResponse del(SolrServer server, SolrParams params, Object... ids) throws IOException, SolrServerException {
+    UpdateRequest ureq = new UpdateRequest();
+    ureq.setParams(new ModifiableSolrParams(params));
+    for (Object id: ids) {
+      ureq.deleteById(id.toString());
+    }
+    return ureq.process(server);
+  }
+
+  protected UpdateResponse delQ(SolrServer server, SolrParams params, String... queries) throws IOException, SolrServerException {
+    UpdateRequest ureq = new UpdateRequest();
+    ureq.setParams(new ModifiableSolrParams(params));
+    for (String q: queries) {
+      ureq.deleteByQuery(q);
+    }
+    return ureq.process(server);
+  }
 
   protected void index_specific(int serverNumber, Object... fields) throws Exception {
     SolrInputDocument doc = new SolrInputDocument();
@@ -310,7 +349,9 @@ public abstract class BaseDistributedSea
 
   protected void commit() throws Exception {
     controlClient.commit();
-    for (SolrServer client : clients) client.commit();
+    for (SolrServer client : clients) {
+      client.commit();
+    }
   }
 
   protected QueryResponse queryServer(ModifiableSolrParams params) throws SolrServerException {
@@ -322,14 +363,17 @@ public abstract class BaseDistributedSea
   }
 
   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());
     }
-
+    // TODO: look into why passing true causes fails
+    params.set("distrib", "false");
     final QueryResponse controlRsp = controlClient.query(params);
 
+    params.remove("distrib");
     setDistributedParams(params);
 
     QueryResponse rsp = queryServer(params);
@@ -365,6 +409,20 @@ public abstract class BaseDistributedSea
       }
     }
   }
+  
+  public QueryResponse queryAndCompare(SolrParams params, SolrServer... servers) throws SolrServerException {
+    QueryResponse first = null;
+    for (SolrServer server : servers) {
+      QueryResponse rsp = server.query(new ModifiableSolrParams(params));
+      if (first == null) {
+        first = rsp;
+      } else {
+        compareResponses(first, rsp);
+      }
+    }
+
+    return first;
+  }
 
   public static boolean eq(String a, String b) {
     return a == b || (a != null && a.equals(b));
@@ -377,6 +435,8 @@ public abstract class BaseDistributedSea
   }
 
   public static String compare(NamedList a, NamedList b, int flags, Map<String, Integer> handle) {
+//    System.out.println("resp a:" + a);
+//    System.out.println("resp b:" + b);
     boolean ordered = (flags & UNORDERED) == 0;
 
     int posa = 0, posb = 0;
@@ -578,9 +638,19 @@ public abstract class BaseDistributedSea
 
   protected void compareResponses(QueryResponse a, QueryResponse b) {
     String cmp;
+    if (System.getProperty("remove.version.field") != null) {
+      // we don't care if one has a version and the other doesnt -
+      // control vs distrib
+      for (SolrDocument doc : a.getResults()) {
+        doc.removeFields("_version_");
+      }
+      for (SolrDocument doc : b.getResults()) {
+        doc.removeFields("_version_");
+      }
+    }
     cmp = compare(a.getResponse(), b.getResponse(), flags, handle);
     if (cmp != null) {
-      log.info("Mismatched responses:\n" + a + "\n" + b);
+      log.error("Mismatched responses:\n" + a + "\n" + b);
       TestCase.fail(cmp);
     }
   }

Modified: lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/SolrJettyTestBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/SolrJettyTestBase.java?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/SolrJettyTestBase.java (original)
+++ lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/SolrJettyTestBase.java Wed Jan 25 20:32:44 2012
@@ -44,12 +44,11 @@ abstract public class SolrJettyTestBase 
     ignoreException("maxWarmingSearchers");
 
     // this sets the property for jetty starting SolrDispatchFilter
-    System.setProperty( "solr.solr.home", solrHome);
     System.setProperty( "solr.data.dir", dataDir.getCanonicalPath() );
 
     context = context==null ? "/solr" : context;
     SolrJettyTestBase.context = context;
-    jetty = new JettySolrRunner( context, 0, configFile );
+    jetty = new JettySolrRunner(solrHome, context, 0, configFile, null);
 
     jetty.start();
     port = jetty.getLocalPort();

Modified: lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java (original)
+++ lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java Wed Jan 25 20:32:44 2012
@@ -27,6 +27,7 @@ import org.apache.noggit.ObjectBuilder;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.SolrInputField;
+import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
@@ -64,6 +65,7 @@ public abstract class SolrTestCaseJ4 ext
   @BeforeClass
   public static void beforeClassSolrTestCase() throws Exception {
     startTrackingSearchers();
+    startTrackingZkClients();
     ignoreException("ignore_exception");
   }
 
@@ -72,6 +74,7 @@ public abstract class SolrTestCaseJ4 ext
     deleteCore();
     resetExceptionIgnores();
     endTrackingSearchers();
+    endTrackingZkClients();
   }
 
   @Override
@@ -110,6 +113,12 @@ public abstract class SolrTestCaseJ4 ext
     numOpens = SolrIndexSearcher.numOpens.get();
     numCloses = SolrIndexSearcher.numCloses.get();
   }
+  static long zkClientNumOpens;
+  static long zkClientNumCloses;
+  public static void startTrackingZkClients() {
+    zkClientNumOpens = SolrZkClient.numOpens.get();
+    zkClientNumCloses = SolrZkClient.numCloses.get();
+  }
 
   public static void endTrackingSearchers() {
      long endNumOpens = SolrIndexSearcher.numOpens.get();
@@ -118,6 +127,18 @@ public abstract class SolrTestCaseJ4 ext
      SolrIndexSearcher.numOpens.getAndSet(0);
      SolrIndexSearcher.numCloses.getAndSet(0);
 
+     // wait a bit in case any ending threads have anything to release
+     int retries = 0;
+     while (endNumOpens - numOpens != endNumCloses - numCloses) {
+       if (retries++ > 15) {
+         break;
+       }
+       try {
+         Thread.sleep(1000);
+       } catch (InterruptedException e) {}
+       endNumOpens = SolrIndexSearcher.numOpens.get();
+       endNumCloses = SolrIndexSearcher.numCloses.get();
+     }
      
      if (endNumOpens-numOpens != endNumCloses-numCloses) {
        String msg = "ERROR: SolrIndexSearcher opens=" + (endNumOpens-numOpens) + " closes=" + (endNumCloses-numCloses);
@@ -127,6 +148,22 @@ public abstract class SolrTestCaseJ4 ext
      }
   }
   
+  public static void endTrackingZkClients() {
+    long endNumOpens = SolrZkClient.numOpens.get();
+    long endNumCloses = SolrZkClient.numCloses.get();
+
+    SolrZkClient.numOpens.getAndSet(0);
+    SolrZkClient.numCloses.getAndSet(0);
+
+    
+    if (endNumOpens-zkClientNumOpens != endNumCloses-zkClientNumCloses) {
+      String msg = "ERROR: SolrZkClient opens=" + (endNumOpens-zkClientNumOpens) + " closes=" + (endNumCloses-zkClientNumCloses);
+      log.error(msg);
+      testsFailed = true;
+      fail(msg);
+    }
+ }
+  
   /** Causes an exception matching the regex pattern to not be logged. */
   public static void ignoreException(String pattern) {
     if (SolrException.ignorePatterns == null)
@@ -240,17 +277,20 @@ public abstract class SolrTestCaseJ4 ext
 
     String configFile = getSolrConfigFile();
     if (configFile != null) {
-
-      solrConfig = h.createConfig(getSolrConfigFile());
-      h = new TestHarness( dataDir.getAbsolutePath(),
-              solrConfig,
-              getSchemaFile());
-      lrf = h.getRequestFactory
-              ("standard",0,20,CommonParams.VERSION,"2.2");
+      createCore();
     }
     log.info("####initCore end");
   }
 
+  public static void createCore() throws Exception {
+    solrConfig = h.createConfig(getSolrConfigFile());
+    h = new TestHarness( dataDir.getAbsolutePath(),
+            solrConfig,
+            getSchemaFile());
+    lrf = h.getRequestFactory
+            ("standard",0,20,CommonParams.VERSION,"2.2");
+  }
+
   /** Subclasses that override setUp can optionally call this method
    * to log the fact that their setUp process has ended.
    */
@@ -379,6 +419,30 @@ public abstract class SolrTestCaseJ4 ext
     }
   }
 
+  /** Makes a query request and returns the JSON string response */
+  public static String JQ(SolrQueryRequest req) throws Exception {
+    SolrParams params = req.getParams();
+    if (!"json".equals(params.get("wt","xml")) || params.get("indent")==null) {
+      ModifiableSolrParams newParams = new ModifiableSolrParams(params);
+      newParams.set("wt","json");
+      if (params.get("indent")==null) newParams.set("indent","true");
+      req.setParams(newParams);
+    }
+
+    String response;
+    boolean failed=true;
+    try {
+      response = h.query(req);
+      failed = false;
+    } finally {
+      if (failed) {
+        log.error("REQUEST FAILED: " + req.getParamString());
+      }
+    }
+
+    return response;
+  }
+
   /**
    * Validates a query matches some JSON test expressions using the default double delta tollerance.
    * @see JSONTestUtil#DEFAULT_DELTA
@@ -398,7 +462,7 @@ public abstract class SolrTestCaseJ4 ext
    * matching more than what you want to test.
    * </p>
    * @param req Solr request to execute
-   * @param delta tollerance allowed in comparing float/double values
+   * @param delta tolerance allowed in comparing float/double values
    * @param tests JSON path expression + '==' + expected value
    */
   public static void assertJQ(SolrQueryRequest req, double delta, String... tests) throws Exception {
@@ -647,6 +711,14 @@ public abstract class SolrTestCaseJ4 ext
   /** Send JSON update commands */
   public static String updateJ(String json, SolrParams args) throws Exception {
     SolrCore core = h.getCore();
+    if (args == null) {
+      args = params("wt","json","indent","true");
+    } else {
+      ModifiableSolrParams newArgs = new ModifiableSolrParams(args);
+      if (newArgs.get("wt") == null) newArgs.set("wt","json");
+      if (newArgs.get("indent") == null) newArgs.set("indent","true");
+      args = newArgs;
+    }
     DirectSolrConnection connection = new DirectSolrConnection(core);
     SolrRequestHandler handler = core.getRequestHandler("/update/json");
     if (handler == null) {
@@ -656,6 +728,128 @@ public abstract class SolrTestCaseJ4 ext
     return connection.request(handler, args, json);
   }
 
+  public static SolrInputDocument sdoc(Object... fieldsAndValues) {
+    SolrInputDocument sd = new SolrInputDocument();
+    for (int i=0; i<fieldsAndValues.length; i+=2) {
+      sd.addField((String)fieldsAndValues[i], fieldsAndValues[i+1]);
+    }
+    return sd;
+  }
+
+  /** Creates JSON from a SolrInputDocument.  Doesn't currently handle boosts. */
+  public static String json(SolrInputDocument doc) {
+     CharArr out = new CharArr();
+    try {
+      out.append('{');
+      boolean firstField = true;
+      for (SolrInputField sfield : doc) {
+        if (firstField) firstField=false;
+        else out.append(',');
+        JSONUtil.writeString(sfield.getName(), 0, sfield.getName().length(), out);
+        out.append(':');
+        if (sfield.getValueCount() > 1) {
+          out.append('[');
+        }
+        boolean firstVal = true;
+        for (Object val : sfield) {
+          if (firstVal) firstVal=false;
+          else out.append(',');
+          out.append(JSONUtil.toJSON(val));
+        }
+        if (sfield.getValueCount() > 1) {
+          out.append(']');
+        }
+      }
+      out.append('}');
+    } catch (IOException e) {
+      // should never happen
+    }
+    return out.toString();
+  }
+
+  /** Creates a JSON add command from a SolrInputDocument list.  Doesn't currently handle boosts. */
+  public static String jsonAdd(SolrInputDocument... docs) {
+    CharArr out = new CharArr();
+    try {
+      out.append('[');
+      boolean firstField = true;
+      for (SolrInputDocument doc : docs) {
+        if (firstField) firstField=false;
+        else out.append(',');
+        out.append(json(doc));
+      }
+      out.append(']');
+    } catch (IOException e) {
+      // should never happen
+    }
+    return out.toString();
+  }
+
+    /** Creates a JSON delete command from an id list */
+  public static String jsonDelId(Object... ids) {
+    CharArr out = new CharArr();
+    try {
+      out.append('{');
+      boolean first = true;
+      for (Object id : ids) {
+        if (first) first=false;
+        else out.append(',');
+        out.append("\"delete\":{\"id\":");
+        out.append(JSONUtil.toJSON(id));
+        out.append('}');
+      }
+      out.append('}');
+    } catch (IOException e) {
+      // should never happen
+    }
+    return out.toString();
+  }
+
+
+  /** Creates a JSON deleteByQuery command */
+  public static String jsonDelQ(String... queries) {
+    CharArr out = new CharArr();
+    try {
+      out.append('{');
+      boolean first = true;
+      for (Object q : queries) {
+        if (first) first=false;
+        else out.append(',');
+        out.append("\"delete\":{\"query\":");
+        out.append(JSONUtil.toJSON(q));
+        out.append('}');
+      }
+      out.append('}');
+    } catch (IOException e) {
+      // should never happen
+    }
+    return out.toString();
+  }
+
+
+  public static Long addAndGetVersion(SolrInputDocument sdoc, SolrParams params) throws Exception {
+    String response = updateJ(jsonAdd(sdoc), params);
+    Map rsp = (Map)ObjectBuilder.fromJSON(response);
+    List lst = (List)rsp.get("adds");
+    if (lst == null || lst.size() == 0) return null;
+    return (Long) lst.get(1);
+  }
+
+  public static Long deleteAndGetVersion(String id, SolrParams params) throws Exception {
+    String response = updateJ(jsonDelId(id), params);
+    Map rsp = (Map)ObjectBuilder.fromJSON(response);
+    List lst = (List)rsp.get("deletes");
+    if (lst == null || lst.size() == 0) return null;
+    return (Long) lst.get(1);
+  }
+
+  public static Long deleteByQueryAndGetVersion(String q, SolrParams params) throws Exception {
+    String response = updateJ(jsonDelQ(q), params);
+    Map rsp = (Map)ObjectBuilder.fromJSON(response);
+    List lst = (List)rsp.get("deleteByQuery");
+    if (lst == null || lst.size() == 0) return null;
+    return (Long) lst.get(1);
+  }
 
   /////////////////////////////////////////////////////////////////////////////////////
   //////////////////////////// random document / index creation ///////////////////////

Modified: lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/util/AbstractSolrTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/util/AbstractSolrTestCase.java?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/util/AbstractSolrTestCase.java (original)
+++ lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/util/AbstractSolrTestCase.java Wed Jan 25 20:32:44 2012
@@ -316,6 +316,20 @@ public abstract class AbstractSolrTestCa
     Doc d = doc(fieldsAndValues);
     return add(d);
   }
+  
+  /**
+   * Generates a simple &lt;add&gt;&lt;doc&gt;... XML String with the
+   * commitWithin attribute.
+   *
+   * @param commitWithin the value of the commitWithin attribute 
+   * @param fieldsAndValues 0th and Even numbered args are fields names odds are field values.
+   * @see #add
+   * @see #doc
+   */
+  public String adoc(int commitWithin, String... fieldsAndValues) {
+    Doc d = doc(fieldsAndValues);
+    return add(d, "commitWithin", String.valueOf(commitWithin));
+  }
 
   /**
    * Generates a simple &lt;add&gt;&lt;doc&gt;... XML String with no options
@@ -366,16 +380,17 @@ public abstract class AbstractSolrTestCa
    *
    * @see TestHarness#deleteById
    */
-  public String delI(String id) {
-    return h.deleteById(id);
+  public String delI(String id, String... args) {
+    return h.deleteById(id, args);
   }
+  
   /**
    * Generates a &lt;delete&gt;... XML string for an query
    *
    * @see TestHarness#deleteByQuery
    */
-  public String delQ(String q) {
-    return h.deleteByQuery(q);
+  public String delQ(String q, String... args) {
+    return h.deleteByQuery(q, args);
   }
   
   /**

Modified: lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java (original)
+++ lucene/dev/branches/lucene3661/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java Wed Jan 25 20:32:44 2012
@@ -216,6 +216,12 @@ public class TestHarness {
       SolrCore core = new SolrCore(coreName, dataDirectory, solrConfig, indexSchema, dcore);
       container.register(coreName, core, false);
 
+      // TODO: we should be exercising the *same* core container initialization code, not equivalent code!
+      if (container.getZkController() == null && core.getUpdateHandler().getUpdateLog() != null) {
+        // always kick off recovery if we are in standalone mode.
+        core.getUpdateHandler().getUpdateLog().recoverFromLog();
+      }
+      
       return container;
     }
   }
@@ -453,32 +459,46 @@ public class TestHarness {
   /**
    * Generates a delete by query xml string
    * @param q Query that has not already been xml escaped
+   * @param args The attributes of the delete tag
    */
-  public static String deleteByQuery(String q) {
-    return delete("query", q);
+  public static String deleteByQuery(String q, String... args) {
+    try {
+      StringWriter r = new StringWriter();
+      XML.writeXML(r, "query", q);
+      return delete(r.getBuffer().toString(), args);
+    } catch(IOException e) {
+      throw new RuntimeException
+        ("this should never happen with a StringWriter", e);
+    }
   }
+  
   /**
    * Generates a delete by id xml string
    * @param id ID that has not already been xml escaped
+   * @param args The attributes of the delete tag
    */
-  public static String deleteById(String id) {
-    return delete("id", id);
+  public static String deleteById(String id, String... args) {
+    try {
+      StringWriter r = new StringWriter();
+      XML.writeXML(r, "id", id);
+      return delete(r.getBuffer().toString(), args);
+    } catch(IOException e) {
+      throw new RuntimeException
+        ("this should never happen with a StringWriter", e);
+    }
   }
         
   /**
    * Generates a delete xml string
    * @param val text that has not already been xml escaped
+   * @param args 0 and Even numbered args are params, Odd numbered args are XML escaped values.
    */
-  private static String delete(String deltype, String val) {
+  private static String delete(String val, String... args) {
     try {
       StringWriter r = new StringWriter();
-            
-      r.write("<delete>");
-      XML.writeXML(r, deltype, val);
-      r.write("</delete>");
-            
+      XML.writeUnescapedXML(r, "delete", val, (Object[])args);
       return r.getBuffer().toString();
-    } catch (IOException e) {
+    } catch(IOException e) {
       throw new RuntimeException
         ("this should never happen with a StringWriter", e);
     }

Modified: lucene/dev/branches/lucene3661/solr/webapp/web/admin/zookeeper.jsp
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/webapp/web/admin/zookeeper.jsp?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/webapp/web/admin/zookeeper.jsp (original)
+++ lucene/dev/branches/lucene3661/solr/webapp/web/admin/zookeeper.jsp Wed Jan 25 20:32:44 2012
@@ -310,7 +310,7 @@
 
       Stat stat = new Stat();
       try {
-        byte[] data = zkClient.getData(path, null, stat);
+        byte[] data = zkClient.getData(path, null, stat, true);
 
         if (stat.getEphemeralOwner() != 0)
           out.print("ephemeral ");
@@ -362,7 +362,7 @@
 
       List<String> children = null;
       try {
-        children = zkClient.getChildren(path, null);
+        children = zkClient.getChildren(path, null, true);
       } catch (KeeperException e) {
         exception(e);
         return;
@@ -389,7 +389,7 @@
       try {
 
         Stat stat = new Stat();
-        byte[] data = zkClient.getData(path, null, stat);
+        byte[] data = zkClient.getData(path, null, stat, true);
 
         out.print("<h2>");
         xmlescape(path);

Modified: lucene/dev/branches/lucene3661/solr/webapp/web/zookeeper.jsp
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3661/solr/webapp/web/zookeeper.jsp?rev=1235919&r1=1235918&r2=1235919&view=diff
==============================================================================
--- lucene/dev/branches/lucene3661/solr/webapp/web/zookeeper.jsp (original)
+++ lucene/dev/branches/lucene3661/solr/webapp/web/zookeeper.jsp Wed Jan 25 20:32:44 2012
@@ -286,7 +286,7 @@ static class ZKPrinter
 		Stat stat = new Stat();
 		try
 		{
-			byte[] data = zkClient.getData(path, null, stat);
+			byte[] data = zkClient.getData(path, null, stat, true);
 
 			if( stat.getEphemeralOwner() != 0 )
 			{
@@ -361,7 +361,7 @@ static class ZKPrinter
 			List<String> children = null;
 			try
 			{
-				children = zkClient.getChildren(path, null);
+				children = zkClient.getChildren(path, null, true);
 			}
 			catch (KeeperException e)
 			{
@@ -407,7 +407,7 @@ static class ZKPrinter
 		try
 		{
 			Stat stat = new Stat();
-			byte[] data = zkClient.getData(path, null, stat);
+			byte[] data = zkClient.getData(path, null, stat, true);
 
 			out.println("\"znode\" : {");