You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ro...@apache.org on 2014/12/31 15:05:50 UTC

svn commit: r1648697 [12/13] - in /lucene/dev/trunk/solr: ./ contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/ contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/ contrib/map-reduce/src/java/org/apache/solr/hadoo...

Modified: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java?rev=1648697&r1=1648696&r2=1648697&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java (original)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java Wed Dec 31 14:05:48 2014
@@ -17,12 +17,6 @@
 
 package org.apache.solr.client.solrj.embedded;
 
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Map;
-
-import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpPost;
@@ -30,15 +24,17 @@ import org.apache.http.entity.InputStrea
 import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
 import org.apache.solr.client.solrj.SolrExampleTests;
 import org.apache.solr.client.solrj.SolrQuery;
-import org.apache.solr.client.solrj.impl.HttpSolrServer;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.common.SolrDocument;
-import org.apache.solr.util.ExternalPaths;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.noggit.ObjectBuilder;
 
+import java.io.ByteArrayInputStream;
+import java.util.Map;
+
 /**
  * TODO? perhaps use:
  *  http://docs.codehaus.org/display/JETTY/ServletTester
@@ -59,8 +55,8 @@ public class SolrExampleJettyTest extend
     try {
       // setup the server...
       String url = "http" + (isSSLMode() ? "s" : "") +  "://127.0.0.1/?core=xxx";
-      HttpSolrServer s = new HttpSolrServer( url );
-      Assert.fail("HttpSolrServer should not allow a path with a parameter: "+s.getBaseURL() );
+      HttpSolrClient client = new HttpSolrClient(url);
+      Assert.fail("HttpSolrServer should not allow a path with a parameter: " + client.getBaseURL());
     }
     catch( Exception ex ) {
       // expected
@@ -69,21 +65,21 @@ public class SolrExampleJettyTest extend
 
   @Test
   public void testArbitraryJsonIndexing() throws Exception  {
-    HttpSolrServer server = (HttpSolrServer) getSolrServer();
-    server.deleteByQuery("*:*");
-    server.commit();
+    HttpSolrClient client = (HttpSolrClient) getSolrClient();
+    client.deleteByQuery("*:*");
+    client.commit();
     assertNumFound("*:*", 0); // make sure it got in
 
     // two docs, one with uniqueKey, another without it
     String json = "{\"id\":\"abc1\", \"name\": \"name1\"} {\"name\" : \"name2\"}";
-    HttpClient httpClient = server.getHttpClient();
-    HttpPost post = new HttpPost(server.getBaseURL() + "/update/json/docs");
+    HttpClient httpClient = client.getHttpClient();
+    HttpPost post = new HttpPost(client.getBaseURL() + "/update/json/docs");
     post.setHeader("Content-Type", "application/json");
     post.setEntity(new InputStreamEntity(new ByteArrayInputStream(json.getBytes("UTF-8")), -1));
     HttpResponse response = httpClient.execute(post);
     assertEquals(200, response.getStatusLine().getStatusCode());
-    server.commit();
-    QueryResponse rsp = getSolrServer().query(new SolrQuery("*:*"));
+    client.commit();
+    QueryResponse rsp = getSolrClient().query(new SolrQuery("*:*"));
     assertEquals(2,rsp.getResults().getNumFound());
 
     SolrDocument doc = rsp.getResults().get(0);

Modified: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryTest.java?rev=1648697&r1=1648696&r2=1648697&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryTest.java (original)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryTest.java Wed Dec 31 14:05:48 2014
@@ -19,20 +19,20 @@ package org.apache.solr.client.solrj.emb
 
 import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
 import org.apache.lucene.util.LuceneTestCase.Slow;
-import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.impl.BinaryRequestWriter;
 import org.apache.solr.client.solrj.impl.BinaryResponseParser;
-import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer;
+import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient;
 
 @Slow
 @SuppressSSL(bugUrl = "https://issues.apache.org/jira/browse/SOLR-5776")
 public class SolrExampleStreamingBinaryTest extends SolrExampleStreamingTest {
 
   @Override
-  public SolrServer createNewSolrServer() {
-    ConcurrentUpdateSolrServer s = (ConcurrentUpdateSolrServer)super.createNewSolrServer();
-    s.setParser(new BinaryResponseParser());
-    s.setRequestWriter(new BinaryRequestWriter());
-    return s;
+  public SolrClient createNewSolrClient() {
+    ConcurrentUpdateSolrClient client = (ConcurrentUpdateSolrClient)super.createNewSolrClient();
+    client.setParser(new BinaryResponseParser());
+    client.setRequestWriter(new BinaryRequestWriter());
+    return client;
   }
 }

Modified: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingTest.java?rev=1648697&r1=1648696&r2=1648697&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingTest.java (original)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingTest.java Wed Dec 31 14:05:48 2014
@@ -18,22 +18,19 @@
 package org.apache.solr.client.solrj.embedded;
 
 import org.apache.lucene.util.LuceneTestCase.Slow;
+import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrExampleTests;
-import org.apache.solr.client.solrj.SolrServer;
-import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer;
+import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient;
 import org.apache.solr.client.solrj.impl.XMLResponseParser;
 import org.apache.solr.client.solrj.request.RequestWriter;
 import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.common.SolrInputDocument;
-import org.apache.solr.util.ExternalPaths;
+import org.junit.BeforeClass;
 
-import java.util.EnumSet;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.EnumSet;
 import java.util.List;
-import java.util.ArrayList;
-
-import org.junit.BeforeClass;
-import org.junit.After;
 
 /**
  * 
@@ -51,13 +48,13 @@ public class SolrExampleStreamingTest ex
   }
 
   @Override
-  public SolrServer createNewSolrServer()
+  public SolrClient createNewSolrClient()
   {
     try {
       // setup the server...
       String url = jetty.getBaseUrl().toString() + "/collection1";
       // smaller queue size hits locks more often
-      ConcurrentUpdateSolrServer s = new ConcurrentUpdateSolrServer( url, 2, 5 ) {
+      ConcurrentUpdateSolrClient concurrentClient = new ConcurrentUpdateSolrClient( url, 2, 5 ) {
         
         public Throwable lastError = null;
         @Override
@@ -66,9 +63,9 @@ public class SolrExampleStreamingTest ex
         }
       };
 
-      s.setParser(new XMLResponseParser());
-      s.setRequestWriter(new RequestWriter());
-      return s;
+      concurrentClient.setParser(new XMLResponseParser());
+      concurrentClient.setRequestWriter(new RequestWriter());
+      return concurrentClient;
     }
     
     catch( Exception ex ) {
@@ -79,7 +76,7 @@ public class SolrExampleStreamingTest ex
   public void testWaitOptions() throws Exception {
     // SOLR-3903
     final List<Throwable> failures = new ArrayList<>();
-    ConcurrentUpdateSolrServer s = new ConcurrentUpdateSolrServer
+    ConcurrentUpdateSolrClient concurrentClient = new ConcurrentUpdateSolrClient
       (jetty.getBaseUrl().toString() + "/collection1", 2, 2) {
         @Override
         public void handleError(Throwable ex) {
@@ -96,13 +93,13 @@ public class SolrExampleStreamingTest ex
           document.addField("id", docId++ );
           updateRequest.add(document);
           updateRequest.setAction(action, waitSearch, waitFlush);
-          s.request(updateRequest);
+          concurrentClient.request(updateRequest);
         }
       }
     }
-    s.commit();
-    s.blockUntilFinished();
-    s.shutdown();
+    concurrentClient.commit();
+    concurrentClient.blockUntilFinished();
+    concurrentClient.shutdown();
 
     if (0 != failures.size()) {
       assertEquals(failures.size() + " Unexpected Exception, starting with...", 

Modified: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/TestSolrProperties.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/TestSolrProperties.java?rev=1648697&r1=1648696&r2=1648697&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/TestSolrProperties.java (original)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/TestSolrProperties.java Wed Dec 31 14:05:48 2014
@@ -20,7 +20,7 @@ package org.apache.solr.client.solrj.emb
 import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.client.solrj.SolrQuery;
-import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.request.AbstractUpdateRequest.ACTION;
 import org.apache.solr.client.solrj.request.CoreAdminRequest;
 import org.apache.solr.client.solrj.request.QueryRequest;
@@ -56,11 +56,11 @@ public class TestSolrProperties extends
     return new File(SOLR_HOME, SOLR_XML);
   }
 
-  protected SolrServer getSolrAdmin() {
+  protected SolrClient getSolrAdmin() {
     return new EmbeddedSolrServer(cores, "core0");
   }
   
-  protected SolrServer getRenamedSolrAdmin() {
+  protected SolrClient getRenamedSolrAdmin() {
     return new EmbeddedSolrServer(cores, "renamed_core");
   }
 
@@ -130,7 +130,7 @@ public class TestSolrProperties extends
 
     // Now test reloading it should have a newer open time
     String name = "core0";
-    SolrServer coreadmin = getSolrAdmin();
+    SolrClient coreadmin = getSolrAdmin();
     CoreAdminResponse mcr = CoreAdminRequest.getStatus(name, coreadmin);
     long before = mcr.getStartTime(name).getTime();
     CoreAdminRequest.reloadCore(name, coreadmin);

Added: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java?rev=1648697&view=auto
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java (added)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java Wed Dec 31 14:05:48 2014
@@ -0,0 +1,651 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.client.solrj.impl;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.solr.SolrJettyTestBase;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.SolrRequest.METHOD;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.request.QueryRequest;
+import org.apache.solr.client.solrj.request.UpdateRequest;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.util.SSLTestConfig;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class BasicHttpSolrClientTest extends SolrJettyTestBase {
+  
+  public static class RedirectServlet extends HttpServlet {
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+        throws ServletException, IOException {
+      resp.sendRedirect("/solr/collection1/select?" + req.getQueryString());
+    }
+  }
+  
+  public static class SlowServlet extends HttpServlet {
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+        throws ServletException, IOException {
+      try {
+        Thread.sleep(5000);
+      } catch (InterruptedException e) {}
+    }
+  }
+  
+  public static class DebugServlet extends HttpServlet {
+    public static void clear() {
+      lastMethod = null;
+      headers = null;
+      parameters = null;
+      errorCode = null;
+      queryString = null;
+    }
+    
+    public static Integer errorCode = null;
+    public static String lastMethod = null;
+    public static HashMap<String,String> headers = null;
+    public static Map<String,String[]> parameters = null;
+    public static String queryString = null;
+    
+    public static void setErrorCode(Integer code) {
+      errorCode = code;
+    }
+    
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+        throws ServletException, IOException {
+      lastMethod = "get";
+      recordRequest(req, resp);
+    }
+    
+    private void setHeaders(HttpServletRequest req) {
+      Enumeration<String> headerNames = req.getHeaderNames();
+      headers = new HashMap<>();
+      while (headerNames.hasMoreElements()) {
+        final String name = headerNames.nextElement();
+        headers.put(name, req.getHeader(name));
+      }
+    }
+
+    private void setParameters(HttpServletRequest req) {
+      parameters = req.getParameterMap();
+    }
+
+    private void setQueryString(HttpServletRequest req) {
+      queryString = req.getQueryString();
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+        throws ServletException, IOException {
+      lastMethod = "post";
+      recordRequest(req, resp);
+    }
+
+    @Override
+    protected void doPut(HttpServletRequest req, HttpServletResponse resp)
+        throws ServletException, IOException {
+      lastMethod = "put";
+      recordRequest(req, resp);
+    }
+    
+    private void recordRequest(HttpServletRequest req, HttpServletResponse resp) {
+      setHeaders(req);
+      setParameters(req);
+      setQueryString(req);
+      if (null != errorCode) {
+        try { 
+          resp.sendError(errorCode); 
+        } catch (IOException e) {
+          throw new RuntimeException("sendError IO fail in DebugServlet", e);
+        }
+      }
+    }
+  }
+  
+  @BeforeClass
+  public static void beforeTest() throws Exception {
+    createJetty(legacyExampleCollection1SolrHome(), null, null);
+    jetty.getDispatchFilter().getServletHandler()
+        .addServletWithMapping(RedirectServlet.class, "/redirect/*");
+    jetty.getDispatchFilter().getServletHandler()
+        .addServletWithMapping(SlowServlet.class, "/slow/*");
+    jetty.getDispatchFilter().getServletHandler()
+        .addServletWithMapping(DebugServlet.class, "/debug/*");
+  }
+  
+  @Test
+  public void testTimeout() throws Exception {
+    HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() +
+                                               "/slow/foo");
+    SolrQuery q = new SolrQuery("*:*");
+    client.setSoTimeout(2000);
+    try {
+      QueryResponse response = client.query(q, METHOD.GET);
+      fail("No exception thrown.");
+    } catch (SolrServerException e) {
+      assertTrue(e.getMessage().contains("Timeout"));
+    }
+    client.shutdown();
+  }
+  
+  /**
+   * test that SolrExceptions thrown by HttpSolrClient can
+   * correctly encapsulate http status codes even when not on the list of
+   * ErrorCodes solr may return.
+   */
+  public void testSolrExceptionCodeNotFromSolr() throws IOException, SolrServerException {
+    final int status = 527;
+    assertEquals(status + " didn't generate an UNKNOWN error code, someone modified the list of valid ErrorCode's w/o changing this test to work a different way",
+                 ErrorCode.UNKNOWN, ErrorCode.getErrorCode(status));
+
+    HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() +
+                                               "/debug/foo");
+    try {
+      DebugServlet.setErrorCode(status);
+      try {
+        SolrQuery q = new SolrQuery("foo");
+        client.query(q, METHOD.GET);
+        fail("Didn't get excepted exception from oversided request");
+      } catch (SolrException e) {
+        System.out.println(e);
+        assertEquals("Unexpected exception status code", status, e.code());
+      }
+    } finally {
+      client.shutdown();
+      DebugServlet.clear();
+    }
+  }
+
+  @Test
+  public void testQuery(){
+    DebugServlet.clear();
+    HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo");
+    SolrQuery q = new SolrQuery("foo");
+    q.setParam("a", "\u1234");
+    try {
+      client.query(q, METHOD.GET);
+    } catch (Throwable t) {}
+    
+    //default method
+    assertEquals("get", DebugServlet.lastMethod);
+    //agent
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    //default wt
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    //default version
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    //agent
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    //keepalive
+    assertEquals("keep-alive", DebugServlet.headers.get("Connection"));
+    //content-type
+    assertEquals(null, DebugServlet.headers.get("Content-Type"));
+    //param encoding
+    assertEquals(1, DebugServlet.parameters.get("a").length);
+    assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
+
+    //POST
+    DebugServlet.clear();
+    try {
+      client.query(q, METHOD.POST);
+    } catch (Throwable t) {}
+    assertEquals("post", DebugServlet.lastMethod);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    assertEquals(1, DebugServlet.parameters.get("a").length);
+    assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals("keep-alive", DebugServlet.headers.get("Connection"));
+    assertEquals("application/x-www-form-urlencoded; charset=UTF-8", DebugServlet.headers.get("Content-Type"));
+
+    //PUT
+    DebugServlet.clear();
+    try {
+      client.query(q, METHOD.PUT);
+    } catch (Throwable t) {}
+    assertEquals("put", DebugServlet.lastMethod);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    assertEquals(1, DebugServlet.parameters.get("a").length);
+    assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals("keep-alive", DebugServlet.headers.get("Connection"));
+    assertEquals("application/x-www-form-urlencoded; charset=UTF-8", DebugServlet.headers.get("Content-Type"));
+
+    //XML/GET
+    client.setParser(new XMLResponseParser());
+    DebugServlet.clear();
+    try {
+      client.query(q, METHOD.GET);
+    } catch (Throwable t) {}
+    assertEquals("get", DebugServlet.lastMethod);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("xml", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    assertEquals(1, DebugServlet.parameters.get("a").length);
+    assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals("keep-alive", DebugServlet.headers.get("Connection"));
+
+    //XML/POST
+    client.setParser(new XMLResponseParser());
+    DebugServlet.clear();
+    try {
+      client.query(q, METHOD.POST);
+    } catch (Throwable t) {}
+    assertEquals("post", DebugServlet.lastMethod);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("xml", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    assertEquals(1, DebugServlet.parameters.get("a").length);
+    assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals("keep-alive", DebugServlet.headers.get("Connection"));
+    assertEquals("application/x-www-form-urlencoded; charset=UTF-8", DebugServlet.headers.get("Content-Type"));
+
+    client.setParser(new XMLResponseParser());
+    DebugServlet.clear();
+    try {
+      client.query(q, METHOD.PUT);
+    } catch (Throwable t) {}
+    assertEquals("put", DebugServlet.lastMethod);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("xml", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    assertEquals(1, DebugServlet.parameters.get("a").length);
+    assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals("keep-alive", DebugServlet.headers.get("Connection"));
+    assertEquals("application/x-www-form-urlencoded; charset=UTF-8", DebugServlet.headers.get("Content-Type"));
+    client.shutdown();
+  }
+
+  @Test
+  public void testDelete(){
+    DebugServlet.clear();
+    HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo");
+    try {
+      client.deleteById("id");
+    } catch (Throwable t) {}
+    
+    //default method
+    assertEquals("post", DebugServlet.lastMethod);
+    //agent
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    //default wt
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    //default version
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    //agent
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    //keepalive
+    assertEquals("keep-alive", DebugServlet.headers.get("Connection"));
+
+    //XML
+    client.setParser(new XMLResponseParser());
+    try {
+      client.deleteByQuery("*:*");
+    } catch (Throwable t) {}
+    
+    assertEquals("post", DebugServlet.lastMethod);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("xml", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals("keep-alive", DebugServlet.headers.get("Connection"));
+    client.shutdown();
+  }
+  
+  @Test
+  public void testUpdate(){
+    DebugServlet.clear();
+    HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo");
+    UpdateRequest req = new UpdateRequest();
+    req.add(new SolrInputDocument());
+    req.setParam("a", "\u1234");
+    try {
+      client.request(req);
+    } catch (Throwable t) {}
+    
+    //default method
+    assertEquals("post", DebugServlet.lastMethod);
+    //agent
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    //default wt
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    //default version
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    //content type
+    assertEquals("application/xml; charset=UTF-8", DebugServlet.headers.get("Content-Type"));
+    //parameter encoding
+    assertEquals(1, DebugServlet.parameters.get("a").length);
+    assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
+
+    //XML response
+    client.setParser(new XMLResponseParser());
+    try {
+      client.request(req);
+    } catch (Throwable t) {}
+    assertEquals("post", DebugServlet.lastMethod);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("xml", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    assertEquals("application/xml; charset=UTF-8", DebugServlet.headers.get("Content-Type"));
+    assertEquals(1, DebugServlet.parameters.get("a").length);
+    assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
+    
+    //javabin request
+    client.setParser(new BinaryResponseParser());
+    client.setRequestWriter(new BinaryRequestWriter());
+    DebugServlet.clear();
+    try {
+      client.request(req);
+    } catch (Throwable t) {}
+    assertEquals("post", DebugServlet.lastMethod);
+    assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.WT).length);
+    assertEquals("javabin", DebugServlet.parameters.get(CommonParams.WT)[0]);
+    assertEquals(1, DebugServlet.parameters.get(CommonParams.VERSION).length);
+    assertEquals(client.getParser().getVersion(), DebugServlet.parameters.get(CommonParams.VERSION)[0]);
+    assertEquals("application/javabin", DebugServlet.headers.get("Content-Type"));
+    assertEquals(1, DebugServlet.parameters.get("a").length);
+    assertEquals("\u1234", DebugServlet.parameters.get("a")[0]);
+    client.shutdown();
+  }
+  
+  @Test
+  public void testRedirect() throws Exception {
+    HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/redirect/foo");
+    SolrQuery q = new SolrQuery("*:*");
+    // default = false
+    try {
+      QueryResponse response = client.query(q);
+      fail("Should have thrown an exception.");
+    } catch (SolrServerException e) {
+      assertTrue(e.getMessage().contains("redirect"));
+    }
+    client.setFollowRedirects(true);
+    try {
+      QueryResponse response = client.query(q);
+    } catch (Throwable t) {
+      fail("Exception was thrown:" + t);
+    }
+    //And back again:
+    client.setFollowRedirects(false);
+    try {
+      QueryResponse response = client.query(q);
+      fail("Should have thrown an exception.");
+    } catch (SolrServerException e) {
+      assertTrue(e.getMessage().contains("redirect"));
+    }
+    client.shutdown();
+  }
+  
+  @Test
+  public void testCompression() throws Exception {
+    HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo");
+    SolrQuery q = new SolrQuery("*:*");
+    
+    // verify request header gets set
+    DebugServlet.clear();
+    try {
+      client.query(q);
+    } catch (Throwable t) {}
+    assertNull(DebugServlet.headers.get("Accept-Encoding"));
+    client.setAllowCompression(true);
+    try {
+      client.query(q);
+    } catch (Throwable t) {}
+    assertNotNull(DebugServlet.headers.get("Accept-Encoding"));
+    client.setAllowCompression(false);
+    try {
+      client.query(q);
+    } catch (Throwable t) {}
+    assertNull(DebugServlet.headers.get("Accept-Encoding"));
+    
+    // verify server compresses output
+    HttpGet get = new HttpGet(jetty.getBaseUrl().toString() + "/collection1" +
+                              "/select?q=foo&wt=xml");
+    get.setHeader("Accept-Encoding", "gzip");
+    HttpClient httpclient = HttpClientUtil.createClient(null);
+    HttpEntity entity = null;
+    try {
+      HttpResponse response = httpclient.execute(get);
+      entity = response.getEntity();
+      Header ceheader = entity.getContentEncoding();
+      assertEquals("gzip", ceheader.getValue());
+      
+    } finally {
+      if(entity!=null) {
+        entity.getContent().close();
+      }
+      httpclient.getConnectionManager().shutdown();
+    }
+    
+    // verify compressed response can be handled
+    client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/collection1");
+    client.setAllowCompression(true);
+    q = new SolrQuery("foo");
+    QueryResponse response = client.query(q);
+    assertEquals(0, response.getStatus());
+    client.shutdown();
+  }
+  
+  @Test
+  public void testSetParametersExternalClient(){
+    HttpClient httpClient = HttpClientUtil.createClient(null);
+    HttpSolrClient solrClient = new HttpSolrClient(jetty.getBaseUrl().toString(),
+                                               httpClient);
+    try {
+      solrClient.setMaxTotalConnections(1);
+      fail("Operation should not succeed.");
+    } catch (UnsupportedOperationException e) {}
+    try {
+      solrClient.setDefaultMaxConnectionsPerHost(1);
+      fail("Operation should not succeed.");
+    } catch (UnsupportedOperationException e) {}
+    solrClient.shutdown();
+    httpClient.getConnectionManager().shutdown();
+  }
+
+  @Test
+  public void testGetRawStream() throws SolrServerException, IOException{
+    HttpClient client = HttpClientUtil.createClient(null);
+    HttpSolrClient solrClient = new HttpSolrClient(jetty.getBaseUrl().toString() + "/collection1",
+                                               client, null);
+    QueryRequest req = new QueryRequest();
+    NamedList response = solrClient.request(req);
+    InputStream stream = (InputStream)response.get("stream");
+    assertNotNull(stream);
+    stream.close();
+    client.getConnectionManager().shutdown();
+  }
+
+  /**
+   * A trivial test that verifies the example keystore used for SSL testing can be 
+   * found using the base class. this helps future-proof against the possibility of 
+   * something moving/breaking the keystore path in a way that results in the SSL 
+   * randomization logic being forced to silently never use SSL.  (We can't enforce 
+   * this type of check in the base class because then it would not be usable by client 
+   * code depending on the test framework
+   */
+  public void testExampleKeystorePath() {
+    assertNotNull("Example keystore is null, meaning that something has changed in the " +
+                  "structure of the example configs and/or ExternalPaths.java - " + 
+                  "SSL randomization is broken",
+                  SSLTestConfig.TEST_KEYSTORE);
+  }
+
+
+  private int findUnusedPort() {
+    for (int port = 0; port < 65535; port++) {
+      Socket s = new Socket();
+      try {
+        s.bind(null);
+        int availablePort = s.getLocalPort();
+        s.close();
+        return availablePort;
+      } catch (IOException e) {
+        e.printStackTrace();
+      }
+    }
+    throw new RuntimeException("Could not find unused TCP port.");
+  }
+
+  private Set<String> setOf(String... keys) {
+    Set<String> set = new TreeSet<String>();
+    if (keys != null) {
+      for (String k : keys) {
+        set.add(k);
+      }
+    }
+    return set;
+  }
+
+  private void setReqParamsOf(UpdateRequest req, String... keys) {
+    if (keys != null) {
+      for (String k : keys) {
+        req.setParam(k, k+"Value");
+      }
+    }
+  }
+
+  private void verifyServletState(HttpSolrClient client, SolrRequest request) {
+    // check query String
+    Iterator<String> paramNames = request.getParams().getParameterNamesIterator();
+    while (paramNames.hasNext()) {
+      String name = paramNames.next();
+      String [] values = request.getParams().getParams(name);
+      if (values != null) {
+        for (String value : values) {
+          boolean shouldBeInQueryString = client.getQueryParams().contains(name)
+            || (request.getQueryParams() != null && request.getQueryParams().contains(name));
+          assertEquals(shouldBeInQueryString, DebugServlet.queryString.contains(name + "=" + value));
+          // in either case, it should be in the parameters
+          assertNotNull(DebugServlet.parameters.get(name));
+          assertEquals(1, DebugServlet.parameters.get(name).length);
+          assertEquals(value, DebugServlet.parameters.get(name)[0]);
+        }
+      }
+    }
+  }
+
+  @Test
+  public void testQueryString() throws Exception {
+    HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() +
+                                               "/debug/foo");
+
+    // test without request query params
+    DebugServlet.clear();
+    client.setQueryParams(setOf("serverOnly"));
+    UpdateRequest req = new UpdateRequest();
+    setReqParamsOf(req, "serverOnly", "notServer");
+    try {
+      client.request(req);
+    } catch (Throwable t) {}
+    verifyServletState(client, req);
+
+    // test without server query params
+    DebugServlet.clear();
+    client.setQueryParams(setOf());
+    req = new UpdateRequest();
+    req.setQueryParams(setOf("requestOnly"));
+    setReqParamsOf(req, "requestOnly", "notRequest");
+    try {
+      client.request(req);
+    } catch (Throwable t) {}
+    verifyServletState(client, req);
+
+    // test with both request and server query params
+    DebugServlet.clear();
+    req = new UpdateRequest();
+    client.setQueryParams(setOf("serverOnly", "both"));
+    req.setQueryParams(setOf("requestOnly", "both"));
+    setReqParamsOf(req, "serverOnly", "requestOnly", "both", "neither");
+     try {
+      client.request(req);
+    } catch (Throwable t) {}
+    verifyServletState(client, req);
+
+    // test with both request and server query params with single stream
+    DebugServlet.clear();
+    req = new UpdateRequest();
+    req.add(new SolrInputDocument());
+    client.setQueryParams(setOf("serverOnly", "both"));
+    req.setQueryParams(setOf("requestOnly", "both"));
+    setReqParamsOf(req, "serverOnly", "requestOnly", "both", "neither");
+     try {
+      client.request(req);
+    } catch (Throwable t) {}
+    // NOTE: single stream requests send all the params
+    // as part of the query string.  So add "neither" to the request
+    // so it passes the verification step.
+    req.setQueryParams(setOf("requestOnly", "both", "neither"));
+    verifyServletState(client, req);
+  }
+}

Added: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientMultiConstructorTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientMultiConstructorTest.java?rev=1648697&view=auto
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientMultiConstructorTest.java (added)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientMultiConstructorTest.java Wed Dec 31 14:05:48 2014
@@ -0,0 +1,82 @@
+package org.apache.solr.client.solrj.impl;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.TestUtil;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class CloudSolrClientMultiConstructorTest extends LuceneTestCase {
+  
+  /*
+   * NOTE: If you only include one String argument, it will NOT use the
+   * constructor with the variable argument list, which is the one that
+   * we are testing here.
+   */
+  Collection<String> hosts;
+
+  @Test
+  public void testWithChroot() {
+    boolean setOrList = random().nextBoolean();
+    int numOfZKServers = TestUtil.nextInt(random(), 1, 5);
+    boolean withChroot = random().nextBoolean();
+
+    final String chroot = "/mychroot";
+
+    StringBuilder sb = new StringBuilder();
+    CloudSolrClient client;
+
+    if(setOrList) {
+      /*
+        A LinkedHashSet is required here for testing, or we can't guarantee
+        the order of entries in the final string.
+       */
+      hosts = new LinkedHashSet<>();
+    } else {
+      hosts = new ArrayList<>();
+    }
+
+    for(int i=0; i<numOfZKServers; i++) {
+      String ZKString = "host" + i + ":2181";
+      hosts.add(ZKString);
+      sb.append(ZKString);
+      if(i<numOfZKServers -1) sb.append(",");
+    }
+
+    if(withChroot) {
+      sb.append(chroot);
+      client = new CloudSolrClient(hosts, "/mychroot");
+    } else {
+      client = new CloudSolrClient(hosts, null);
+    }
+
+    assertEquals(sb.toString(), client.getZkHost());
+    client.shutdown();
+  }
+  
+  @Test(expected = IllegalArgumentException.class)
+  public void testBadChroot() {
+    hosts = new ArrayList<>();
+    hosts.add("host1:2181");
+    new CloudSolrClient(hosts, "foo");
+  }
+}

Added: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java?rev=1648697&view=auto
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java (added)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java Wed Dec 31 14:05:48 2014
@@ -0,0 +1,459 @@
+package org.apache.solr.client.solrj.impl;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.apache.http.client.HttpClient;
+import org.apache.lucene.util.LuceneTestCase.Slow;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
+import org.apache.solr.client.solrj.request.QueryRequest;
+import org.apache.solr.client.solrj.request.UpdateRequest;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
+import org.apache.solr.cloud.AbstractZkTestCase;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.cloud.ClusterState;
+import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.DocRouter;
+import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.ShardParams;
+import org.apache.solr.common.util.NamedList;
+import org.apache.zookeeper.KeeperException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeoutException;
+
+
+/**
+ * This test would be faster if we simulated the zk state instead.
+ */
+@Slow
+public class CloudSolrClientTest extends AbstractFullDistribZkTestBase {
+  static Logger log = LoggerFactory.getLogger(CloudSolrClientTest.class);
+
+  private static final String SOLR_HOME = getFile("solrj" + File.separator + "solr").getAbsolutePath();
+
+  @BeforeClass
+  public static void beforeSuperClass() {
+      AbstractZkTestCase.SOLRHOME = new File(SOLR_HOME());
+  }
+  
+  @AfterClass
+  public static void afterSuperClass() {
+    
+  }
+  
+  protected String getCloudSolrConfig() {
+    return "solrconfig.xml";
+  }
+  
+  @Override
+  public String getSolrHome() {
+    return SOLR_HOME;
+  }
+  
+  public static String SOLR_HOME() {
+    return SOLR_HOME;
+  }
+  
+  @Before
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    // we expect this time of exception as shards go up and down...
+    //ignoreException(".*");
+    
+    System.setProperty("numShards", Integer.toString(sliceCount));
+  }
+  
+  @Override
+  @After
+  public void tearDown() throws Exception {
+    super.tearDown();
+    resetExceptionIgnores();
+  }
+  
+  public CloudSolrClientTest() {
+    super();
+    sliceCount = 2;
+    shardCount = 3;
+  }
+
+  @Override
+  public void doTest() throws Exception {
+    allTests();
+    stateVersionParamTest();
+    customHttpClientTest();
+  }
+
+  private void allTests() throws Exception {
+
+    String collectionName = "clientTestExternColl";
+    createCollection(collectionName, controlClientCloud, 2, 2);
+    waitForRecoveriesToFinish(collectionName, false);
+    CloudSolrClient cloudClient = createCloudClient(collectionName);
+
+    assertNotNull(cloudClient);
+    
+    handle.clear();
+    handle.put("timestamp", SKIPVAL);
+    
+    waitForThingsToLevelOut(30);
+
+    controlClient.deleteByQuery("*:*");
+    cloudClient.deleteByQuery("*:*");
+
+
+    controlClient.commit();
+    this.cloudClient.commit();
+
+    SolrInputDocument doc1 = new SolrInputDocument();
+    doc1.addField(id, "0");
+    doc1.addField("a_t", "hello1");
+    SolrInputDocument doc2 = new SolrInputDocument();
+    doc2.addField(id, "2");
+    doc2.addField("a_t", "hello2");
+    
+    UpdateRequest request = new UpdateRequest();
+    request.add(doc1);
+    request.add(doc2);
+    request.setAction(AbstractUpdateRequest.ACTION.COMMIT, false, false);
+    
+    // Test single threaded routed updates for UpdateRequest
+    NamedList<Object> response = cloudClient.request(request);
+    CloudSolrClient.RouteResponse rr = (CloudSolrClient.RouteResponse) response;
+    Map<String,LBHttpSolrClient.Req> routes = rr.getRoutes();
+    Iterator<Map.Entry<String,LBHttpSolrClient.Req>> it = routes.entrySet()
+        .iterator();
+    while (it.hasNext()) {
+      Map.Entry<String,LBHttpSolrClient.Req> entry = it.next();
+      String url = entry.getKey();
+      UpdateRequest updateRequest = (UpdateRequest) entry.getValue()
+          .getRequest();
+      SolrInputDocument doc = updateRequest.getDocuments().get(0);
+      String id = doc.getField("id").getValue().toString();
+      ModifiableSolrParams params = new ModifiableSolrParams();
+      params.add("q", "id:" + id);
+      params.add("distrib", "false");
+      QueryRequest queryRequest = new QueryRequest(params);
+      HttpSolrClient solrClient = new HttpSolrClient(url);
+      QueryResponse queryResponse = queryRequest.process(solrClient);
+      SolrDocumentList docList = queryResponse.getResults();
+      assertTrue(docList.getNumFound() == 1);
+    }
+    
+    // Test the deleteById routing for UpdateRequest
+    
+    UpdateRequest delRequest = new UpdateRequest();
+    delRequest.deleteById("0");
+    delRequest.deleteById("2");
+    delRequest.setAction(AbstractUpdateRequest.ACTION.COMMIT, false, false);
+    cloudClient.request(delRequest);
+    ModifiableSolrParams qParams = new ModifiableSolrParams();
+    qParams.add("q", "*:*");
+    QueryRequest qRequest = new QueryRequest(qParams);
+    QueryResponse qResponse = qRequest.process(cloudClient);
+    SolrDocumentList docs = qResponse.getResults();
+    assertTrue(docs.getNumFound() == 0);
+    
+    // Test Multi-Threaded routed updates for UpdateRequest
+    
+    CloudSolrClient threadedClient = null;
+    try {
+      threadedClient = new CloudSolrClient(zkServer.getZkAddress());
+      threadedClient.setParallelUpdates(true);
+      threadedClient.setDefaultCollection(collectionName);
+      response = threadedClient.request(request);
+      rr = (CloudSolrClient.RouteResponse) response;
+      routes = rr.getRoutes();
+      it = routes.entrySet()
+          .iterator();
+      while (it.hasNext()) {
+        Map.Entry<String,LBHttpSolrClient.Req> entry = it.next();
+        String url = entry.getKey();
+        UpdateRequest updateRequest = (UpdateRequest) entry.getValue()
+            .getRequest();
+        SolrInputDocument doc = updateRequest.getDocuments().get(0);
+        String id = doc.getField("id").getValue().toString();
+        ModifiableSolrParams params = new ModifiableSolrParams();
+        params.add("q", "id:" + id);
+        params.add("distrib", "false");
+        QueryRequest queryRequest = new QueryRequest(params);
+        HttpSolrClient solrClient = new HttpSolrClient(url);
+        QueryResponse queryResponse = queryRequest.process(solrClient);
+        SolrDocumentList docList = queryResponse.getResults();
+        assertTrue(docList.getNumFound() == 1);
+      }
+    } finally {
+      threadedClient.shutdown();
+    }
+
+    // Test that queries with _route_ params are routed by the client
+
+    // Track request counts on each node before query calls
+    ClusterState clusterState = cloudClient.getZkStateReader().getClusterState();
+    DocCollection col = clusterState.getCollection(collectionName);
+    Map<String, Long> requestCountsMap = Maps.newHashMap();
+    for (Slice slice : col.getSlices()) {
+      for (Replica replica : slice.getReplicas()) {
+        String baseURL = (String) replica.get(ZkStateReader.BASE_URL_PROP);
+        requestCountsMap.put(baseURL, getNumRequests(baseURL,collectionName));
+      }
+    }
+
+    // Collect the base URLs of the replicas of shard that's expected to be hit
+    DocRouter router = col.getRouter();
+    Collection<Slice> expectedSlices = router.getSearchSlicesSingle("0", null, col);
+    Set<String> expectedBaseURLs = Sets.newHashSet();
+    for (Slice expectedSlice : expectedSlices) {
+      for (Replica replica : expectedSlice.getReplicas()) {
+        String baseURL = (String) replica.get(ZkStateReader.BASE_URL_PROP);
+        expectedBaseURLs.add(baseURL);
+      }
+    }
+
+    assertTrue("expected urls is not fewer than all urls! expected=" + expectedBaseURLs
+        + "; all=" + requestCountsMap.keySet(),
+        expectedBaseURLs.size() < requestCountsMap.size());
+
+    // Calculate a number of shard keys that route to the same shard.
+    int n;
+    if (TEST_NIGHTLY) {
+      n = random().nextInt(999) + 2;
+    } else {
+      n = random().nextInt(9) + 2;
+    }
+    
+    List<String> sameShardRoutes = Lists.newArrayList();
+    sameShardRoutes.add("0");
+    for (int i = 1; i < n; i++) {
+      String shardKey = Integer.toString(i);
+      Collection<Slice> slices = router.getSearchSlicesSingle(shardKey, null, col);
+      log.info("Expected Slices {}", slices);
+      if (expectedSlices.equals(slices)) {
+        sameShardRoutes.add(shardKey);
+      }
+    }
+
+    assertTrue(sameShardRoutes.size() > 1);
+
+    // Do N queries with _route_ parameter to the same shard
+    for (int i = 0; i < n; i++) {
+      ModifiableSolrParams solrParams = new ModifiableSolrParams();
+      solrParams.set(CommonParams.Q, "*:*");
+      solrParams.set(ShardParams._ROUTE_, sameShardRoutes.get(random().nextInt(sameShardRoutes.size())));
+      log.info("output  : {}" ,cloudClient.query(solrParams));
+    }
+
+    // Request counts increase from expected nodes should aggregate to 1000, while there should be
+    // no increase in unexpected nodes.
+    int increaseFromExpectedUrls = 0;
+    int increaseFromUnexpectedUrls = 0;
+    Map<String, Long> numRequestsToUnexpectedUrls = Maps.newHashMap();
+    for (Slice slice : col.getSlices()) {
+      for (Replica replica : slice.getReplicas()) {
+        String baseURL = (String) replica.get(ZkStateReader.BASE_URL_PROP);
+
+        Long prevNumRequests = requestCountsMap.get(baseURL);
+        Long curNumRequests = getNumRequests(baseURL, collectionName);
+
+        long delta = curNumRequests - prevNumRequests;
+        if (expectedBaseURLs.contains(baseURL)) {
+          increaseFromExpectedUrls += delta;
+        } else {
+          increaseFromUnexpectedUrls += delta;
+          numRequestsToUnexpectedUrls.put(baseURL, delta);
+        }
+      }
+    }
+
+    assertEquals("Unexpected number of requests to expected URLs", n, increaseFromExpectedUrls);
+    assertEquals("Unexpected number of requests to unexpected URLs: " + numRequestsToUnexpectedUrls,
+        0, increaseFromUnexpectedUrls);
+
+    controlClient.deleteByQuery("*:*");
+    cloudClient.deleteByQuery("*:*");
+
+    controlClient.commit();
+    cloudClient.commit();
+    cloudClient.shutdown();
+  }
+
+  private Long getNumRequests(String baseUrl, String collectionName) throws
+      SolrServerException, IOException {
+    HttpSolrClient client = new HttpSolrClient(baseUrl + "/"+ collectionName);
+    client.setConnectionTimeout(15000);
+    client.setSoTimeout(60000);
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.set("qt", "/admin/mbeans");
+    params.set("stats", "true");
+    params.set("key", "standard");
+    params.set("cat", "QUERYHANDLER");
+    // use generic request to avoid extra processing of queries
+    QueryRequest req = new QueryRequest(params);
+    NamedList<Object> resp = client.request(req);
+    return (Long) resp.findRecursive("solr-mbeans", "QUERYHANDLER",
+        "standard", "stats", "requests");
+  }
+  
+  @Override
+  protected void indexr(Object... fields) throws Exception {
+    SolrInputDocument doc = getDoc(fields);
+    indexDoc(doc);
+  }
+
+  private void stateVersionParamTest() throws Exception {
+    CloudSolrClient client = createCloudClient(null);
+    try {
+      String collectionName = "checkStateVerCol";
+      createCollection(collectionName, client, 2, 2);
+      waitForRecoveriesToFinish(collectionName, false);
+      DocCollection coll = client.getZkStateReader().getClusterState().getCollection(collectionName);
+      Replica r = coll.getSlices().iterator().next().getReplicas().iterator().next();
+
+      HttpSolrClient solrClient = new HttpSolrClient(r.getStr(ZkStateReader.BASE_URL_PROP) + "/"+collectionName);
+
+
+      SolrQuery q = new SolrQuery().setQuery("*:*");
+
+      log.info("should work query, result {}", solrClient.query(q));
+      //no problem
+      q.setParam(CloudSolrClient.STATE_VERSION, collectionName + ":" + coll.getZNodeVersion());
+      log.info("2nd query , result {}", solrClient.query(q));
+      //no error yet good
+
+      q.setParam(CloudSolrClient.STATE_VERSION, collectionName+":"+ (coll.getZNodeVersion() -1)); //an older version expect error
+
+      HttpSolrClient.RemoteSolrException sse = null;
+      try {
+        solrClient.query(q);
+        log.info("expected query error");
+      } catch (HttpSolrClient.RemoteSolrException e) {
+        sse = e;
+      }
+      solrClient.shutdown();
+      assertNotNull(sse);
+      assertEquals(" Error code should be ", sse.code(), SolrException.ErrorCode.INVALID_STATE.code);
+
+      //now send the request to another node that does n ot serve the collection
+
+      Set<String> allNodesOfColl = new HashSet<>();
+      for (Slice slice : coll.getSlices()) {
+        for (Replica replica : slice.getReplicas()) {
+          allNodesOfColl.add(replica.getStr(ZkStateReader.BASE_URL_PROP));
+        }
+      }
+      String theNode = null;
+      for (String s : client.getZkStateReader().getClusterState().getLiveNodes()) {
+        String n = client.getZkStateReader().getBaseUrlForNodeName(s);
+        if(!allNodesOfColl.contains(s)){
+          theNode = n;
+          break;
+        }
+      }
+      log.info("thenode which does not serve this collection{} ",theNode);
+      assertNotNull(theNode);
+      solrClient = new HttpSolrClient(theNode + "/"+collectionName);
+
+      q.setParam(CloudSolrClient.STATE_VERSION, collectionName+":"+coll.getZNodeVersion());
+
+      try {
+        solrClient.query(q);
+        log.info("error was expected");
+      } catch (HttpSolrClient.RemoteSolrException e) {
+        sse = e;
+      }
+      solrClient.shutdown();
+      assertNotNull(sse);
+      assertEquals(" Error code should be ",  sse.code() , SolrException.ErrorCode.INVALID_STATE.code);
+    } finally {
+      client.shutdown();
+    }
+
+  }
+
+  public void testShutdown() throws MalformedURLException {
+    CloudSolrClient client = new CloudSolrClient("[ff01::114]:33332");
+    try {
+      client.setZkConnectTimeout(100);
+      client.connect();
+      fail("Expected exception");
+    } catch (SolrException e) {
+      assertTrue(e.getCause() instanceof TimeoutException);
+    } finally {
+      client.shutdown();
+    }
+  }
+
+  public void testWrongZkChrootTest() throws MalformedURLException {
+    CloudSolrClient client = null;
+    try {
+      client = new CloudSolrClient(zkServer.getZkAddress() + "/xyz/foo");
+      client.setDefaultCollection(DEFAULT_COLLECTION);
+      client.setZkClientTimeout(1000 * 60);
+      client.connect();
+      fail("Expected exception");
+    } catch(SolrException e) {
+      assertTrue(e.getCause() instanceof KeeperException);
+    } finally {
+      client.shutdown();
+    }
+    // see SOLR-6146 - this test will fail by virtue of the zkClient tracking performed
+    // in the afterClass method of the base class
+  }
+
+  public void customHttpClientTest() {
+    CloudSolrClient solrClient = null;
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.set(HttpClientUtil.PROP_SO_TIMEOUT, 1000);
+    HttpClient client = null;
+
+    try {
+      client = HttpClientUtil.createClient(params);
+      solrClient = new CloudSolrClient(zkServer.getZkAddress(), client);
+      assertTrue(solrClient.getLbClient().getHttpClient() == client);
+    } finally {
+      solrClient.shutdown();
+      client.getConnectionManager().shutdown();
+    }
+  }
+}

Added: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTest.java?rev=1648697&view=auto
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTest.java (added)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTest.java Wed Dec 31 14:05:48 2014
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.client.solrj.impl;
+
+import org.apache.http.HttpResponse;
+import org.apache.solr.SolrJettyTestBase;
+import org.apache.solr.client.solrj.request.JavaBinUpdateRequestCodec;
+import org.apache.solr.client.solrj.request.UpdateRequest;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.util.SolrjNamedThreadFactory;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class ConcurrentUpdateSolrClientTest extends SolrJettyTestBase {
+
+  /**
+   * Mock endpoint where the CUSS being tested in this class sends requests.
+   */
+  public static class TestServlet extends HttpServlet 
+    implements JavaBinUpdateRequestCodec.StreamingUpdateHandler
+  {   
+    private static final long serialVersionUID = 1L;
+
+    public static void clear() {
+      lastMethod = null;
+      headers = null;
+      parameters = null;
+      errorCode = null;
+      numReqsRcvd.set(0);
+      numDocsRcvd.set(0);
+    }
+    
+    public static Integer errorCode = null;
+    public static String lastMethod = null;
+    public static HashMap<String,String> headers = null;
+    public static Map<String,String[]> parameters = null;
+    public static AtomicInteger numReqsRcvd = new AtomicInteger(0);
+    public static AtomicInteger numDocsRcvd = new AtomicInteger(0);
+    
+    public static void setErrorCode(Integer code) {
+      errorCode = code;
+    }
+        
+    private void setHeaders(HttpServletRequest req) {
+      Enumeration<String> headerNames = req.getHeaderNames();
+      headers = new HashMap<>();
+      while (headerNames.hasMoreElements()) {
+        final String name = headerNames.nextElement();
+        headers.put(name, req.getHeader(name));
+      }
+    }
+
+    private void setParameters(HttpServletRequest req) {
+      //parameters = req.getParameterMap();
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+        throws ServletException, IOException {
+      
+      numReqsRcvd.incrementAndGet();
+      lastMethod = "post";
+      recordRequest(req, resp);
+            
+      InputStream reqIn = req.getInputStream();
+      JavaBinUpdateRequestCodec javabin = new JavaBinUpdateRequestCodec();
+      for (;;) {
+        try {
+          javabin.unmarshal(reqIn, this);
+        } catch (EOFException e) {
+          break; // this is expected
+        }
+      }      
+    }
+    
+    private void recordRequest(HttpServletRequest req, HttpServletResponse resp) {
+      setHeaders(req);
+      setParameters(req);
+      if (null != errorCode) {
+        try { 
+          resp.sendError(errorCode); 
+        } catch (IOException e) {
+          throw new RuntimeException("sendError IO fail in TestServlet", e);
+        }
+      }
+    }
+
+    @Override
+    public void update(SolrInputDocument document, UpdateRequest req, Integer commitWithin, Boolean override) {
+      numDocsRcvd.incrementAndGet();
+    }
+  } // end TestServlet
+  
+  @BeforeClass
+  public static void beforeTest() throws Exception {
+    createJetty(legacyExampleCollection1SolrHome(), null, null);
+    jetty.getDispatchFilter().getServletHandler()
+        .addServletWithMapping(TestServlet.class, "/cuss/*");
+  }
+  
+  @Test
+  public void testConcurrentUpdate() throws Exception {
+    TestServlet.clear();
+    
+    String serverUrl = jetty.getBaseUrl().toString() + "/cuss/foo";
+        
+    int cussThreadCount = 2;
+    int cussQueueSize = 100;
+    
+    // for tracking callbacks from CUSS
+    final AtomicInteger successCounter = new AtomicInteger(0);
+    final AtomicInteger errorCounter = new AtomicInteger(0);    
+    final StringBuilder errors = new StringBuilder();     
+    
+    @SuppressWarnings("serial")
+    ConcurrentUpdateSolrClient concurrentClient = new ConcurrentUpdateSolrClient(serverUrl, cussQueueSize, cussThreadCount) {
+      @Override
+      public void handleError(Throwable ex) {
+        errorCounter.incrementAndGet();
+        errors.append(" "+ex);
+      }
+      @Override
+      public void onSuccess(HttpResponse resp) {
+        successCounter.incrementAndGet();
+      }
+    };
+    
+    concurrentClient.setParser(new BinaryResponseParser());
+    concurrentClient.setRequestWriter(new BinaryRequestWriter());
+    concurrentClient.setPollQueueTime(0);
+    
+    // ensure it doesn't block where there's nothing to do yet
+    concurrentClient.blockUntilFinished();
+    
+    int poolSize = 5;
+    ExecutorService threadPool = Executors.newFixedThreadPool(poolSize, new SolrjNamedThreadFactory("testCUSS"));
+
+    int numDocs = 100;
+    int numRunnables = 5;
+    for (int r=0; r < numRunnables; r++)
+      threadPool.execute(new SendDocsRunnable(String.valueOf(r), numDocs, concurrentClient));
+    
+    // ensure all docs are sent
+    threadPool.awaitTermination(5, TimeUnit.SECONDS);
+    threadPool.shutdown();
+    
+    // wait until all requests are processed by CUSS 
+    concurrentClient.blockUntilFinished();
+    concurrentClient.shutdownNow();
+    
+    assertEquals("post", TestServlet.lastMethod);
+        
+    // expect all requests to be successful
+    int expectedSuccesses = TestServlet.numReqsRcvd.get();
+    assertTrue(expectedSuccesses > 0); // at least one request must have been sent
+    
+    assertTrue("Expected no errors but got "+errorCounter.get()+
+        ", due to: "+errors.toString(), errorCounter.get() == 0);
+    assertTrue("Expected "+expectedSuccesses+" successes, but got "+successCounter.get(), 
+        successCounter.get() == expectedSuccesses);
+    
+    int expectedDocs = numDocs * numRunnables;
+    assertTrue("Expected CUSS to send "+expectedDocs+" but got "+TestServlet.numDocsRcvd.get(), 
+        TestServlet.numDocsRcvd.get() == expectedDocs);
+  }
+  
+  class SendDocsRunnable implements Runnable {
+    
+    private String id;
+    private int numDocs;
+    private ConcurrentUpdateSolrClient cuss;
+    
+    SendDocsRunnable(String id, int numDocs, ConcurrentUpdateSolrClient cuss) {
+      this.id = id;
+      this.numDocs = numDocs;
+      this.cuss = cuss;
+    }
+
+    @Override
+    public void run() {
+      for (int d=0; d < numDocs; d++) {
+        SolrInputDocument doc = new SolrInputDocument();
+        String docId = id+"_"+d;
+        doc.setField("id", docId);    
+        UpdateRequest req = new UpdateRequest();
+        req.add(doc);        
+        try {
+          cuss.request(req);
+        } catch (Throwable t) {
+          t.printStackTrace();
+        }
+      }      
+    }    
+  }
+}

Modified: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ExternalHttpClientTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ExternalHttpClientTest.java?rev=1648697&r1=1648696&r2=1648697&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ExternalHttpClientTest.java (original)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ExternalHttpClientTest.java Wed Dec 31 14:05:48 2014
@@ -26,7 +26,6 @@ import org.apache.solr.client.solrj.Solr
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.response.QueryResponse;
-import org.apache.solr.util.ExternalPaths;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -36,15 +35,15 @@ public class ExternalHttpClientTest exte
   public static void beforeTest() throws Exception {
     createJetty(legacyExampleCollection1SolrHome(), null, null);
     jetty.getDispatchFilter().getServletHandler()
-        .addServletWithMapping(BasicHttpSolrServerTest.SlowServlet.class, "/slow/*");
+        .addServletWithMapping(BasicHttpSolrClientTest.SlowServlet.class, "/slow/*");
   }
 
   /**
-   * The internal client created by HttpSolrServer is a SystemDefaultHttpClient
+   * The internal client created by HttpSolrClient is a SystemDefaultHttpClient
    * which takes care of merging request level params (such as timeout) with the
    * configured defaults.
    *
-   * However, if an external HttpClient is passed to HttpSolrServer,
+   * However, if an external HttpClient is passed to HttpSolrClient,
    * the logic in InternalHttpClient.executeMethod replaces the configured defaults
    * by request level params if they exist. That is why we must test a setting such
    * as timeout with an external client to assert that the defaults are indeed being
@@ -57,21 +56,21 @@ public class ExternalHttpClientTest exte
     HttpClientBuilder builder = HttpClientBuilder.create();
     RequestConfig config = RequestConfig.custom().setSocketTimeout(2000).build();
     builder.setDefaultRequestConfig(config);
-    HttpSolrServer server = null;
+    HttpSolrClient solrClient = null;
     try (CloseableHttpClient httpClient = builder.build()) {
-      server = new HttpSolrServer(jetty.getBaseUrl().toString() +
+      solrClient = new HttpSolrClient(jetty.getBaseUrl().toString() +
           "/slow/foo", httpClient);
 
       SolrQuery q = new SolrQuery("*:*");
       try {
-        QueryResponse response = server.query(q, SolrRequest.METHOD.GET);
+        QueryResponse response = solrClient.query(q, SolrRequest.METHOD.GET);
         fail("No exception thrown.");
       } catch (SolrServerException e) {
         assertTrue(e.getMessage().contains("Timeout"));
       }
     } finally {
-      if (server != null) {
-        server.shutdown();
+      if (solrClient != null) {
+        solrClient.shutdown();
       }
     }
   }

Added: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBHttpSolrClientTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBHttpSolrClientTest.java?rev=1648697&view=auto
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBHttpSolrClientTest.java (added)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBHttpSolrClientTest.java Wed Dec 31 14:05:48 2014
@@ -0,0 +1,56 @@
+/**
+ * 
+ */
+package org.apache.solr.client.solrj.impl;
+
+import org.apache.solr.client.solrj.ResponseParser;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.junit.Test;
+
+import java.net.MalformedURLException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Test the LBHttpSolrClient.
+ */
+public class LBHttpSolrClientTest {
+  
+  /**
+   * Test method for {@link LBHttpSolrClient#LBHttpSolrClient(org.apache.http.client.HttpClient, org.apache.solr.client.solrj.ResponseParser, java.lang.String[])}.
+   * 
+   * Validate that the parser passed in is used in the <code>HttpSolrClient</code> instances created.
+   * 
+   * @throws MalformedURLException If URL is invalid, no URL passed, so won't happen.
+   */
+  @Test
+  public void testLBHttpSolrClientHttpClientResponseParserStringArray() throws MalformedURLException {
+    LBHttpSolrClient testClient = new LBHttpSolrClient(HttpClientUtil.createClient(new ModifiableSolrParams()), (ResponseParser) null);
+    HttpSolrClient httpSolrClient = testClient.makeSolrClient("http://127.0.0.1:8080");
+    assertNull("Generated server should have null parser.", httpSolrClient.getParser());
+
+    ResponseParser parser = new BinaryResponseParser();
+    testClient = new LBHttpSolrClient(HttpClientUtil.createClient(new ModifiableSolrParams()), parser);
+    httpSolrClient = testClient.makeSolrClient("http://127.0.0.1:8080");
+    assertEquals("Invalid parser passed to generated server.", parser, httpSolrClient.getParser());
+  }
+  
+}

Modified: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/SolrPingTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/SolrPingTest.java?rev=1648697&r1=1648696&r2=1648697&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/SolrPingTest.java (original)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/SolrPingTest.java Wed Dec 31 14:05:48 2014
@@ -52,8 +52,8 @@ public class SolrPingTest extends SolrJe
     SolrInputDocument doc = new SolrInputDocument();
     doc.setField("id", 1);
     doc.setField("terms_s", "samsung");
-    getSolrServer().add(doc);
-    getSolrServer().commit(true, true);
+    getSolrClient().add(doc);
+    getSolrClient().commit(true, true);
   }
   
   @Test
@@ -61,9 +61,9 @@ public class SolrPingTest extends SolrJe
     SolrPing ping = new SolrPing();
     SolrPingResponse rsp = null;
     ping.setActionEnable();
-    ping.process(getSolrServer());
+    ping.process(getSolrClient());
     ping.removeAction();
-    rsp = ping.process(getSolrServer());
+    rsp = ping.process(getSolrClient());
     Assert.assertNotNull(rsp);
   }
   
@@ -73,12 +73,12 @@ public class SolrPingTest extends SolrJe
     SolrPingResponse rsp = null;
     ping.setActionDisable();
     try {
-      ping.process(getSolrServer());
+      ping.process(getSolrClient());
     } catch (Exception e) {
       throw new Exception("disable action failed!");
     }
     ping.setActionPing();
-    rsp = ping.process(getSolrServer());
+    rsp = ping.process(getSolrClient());
     // the above line should fail with a 503 SolrException.
     Assert.assertNotNull(rsp);
   }

Modified: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java?rev=1648697&r1=1648696&r2=1648697&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java (original)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java Wed Dec 31 14:05:48 2014
@@ -17,16 +17,12 @@
 
 package org.apache.solr.client.solrj.request;
 
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.core.Is.is;
-
-import java.io.File;
-
+import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
+import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
 import org.apache.commons.io.FileUtils;
 import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.TestUtil;
 import org.apache.solr.SolrIgnoredThreadsFilter;
-import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.embedded.AbstractEmbeddedSolrServerTestCase;
 import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
 import org.apache.solr.client.solrj.response.CoreAdminResponse;
@@ -43,8 +39,10 @@ import org.junit.rules.TestRule;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
-import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
+import java.io.File;
+
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.core.Is.is;
 
 @ThreadLeakFilters(defaultFilters = true, filters = {SolrIgnoredThreadsFilter.class})
 public class TestCoreAdmin extends AbstractEmbeddedSolrServerTestCase {
@@ -68,14 +66,14 @@ public class TestCoreAdmin extends Abstr
     return solrXml;
   }
   
-  protected SolrServer getSolrAdmin() {
+  protected SolrClient getSolrAdmin() {
     return new EmbeddedSolrServer(cores, "core0");
   }
 
   @Test
   public void testConfigSet() throws Exception {
 
-    SolrServer server = getSolrAdmin();
+    SolrClient client = getSolrAdmin();
     File testDir = createTempDir(LuceneTestCase.getTestClass().getSimpleName()).toFile();
 
     File newCoreInstanceDir = new File(testDir, "newcore");
@@ -85,7 +83,7 @@ public class TestCoreAdmin extends Abstr
     req.setInstanceDir(newCoreInstanceDir.getAbsolutePath());
     req.setConfigSet("configset-2");
 
-    CoreAdminResponse response = req.process(server);
+    CoreAdminResponse response = req.process(client);
     assertThat((String) response.getResponse().get("core"), is("corewithconfigset"));
 
     try (SolrCore core = cores.getCore("corewithconfigset")) {
@@ -97,7 +95,7 @@ public class TestCoreAdmin extends Abstr
   @Test
   public void testCustomUlogDir() throws Exception {
     
-    SolrServer server = getSolrAdmin();
+    SolrClient client = getSolrAdmin();
     
     File dataDir = createTempDir("data").toFile();
     
@@ -116,7 +114,7 @@ public class TestCoreAdmin extends Abstr
     // These should be the inverse of defaults.
     req.setIsLoadOnStartup(false);
     req.setIsTransient(true);
-    req.process(server);
+    req.process(client);
 
     // Show that the newly-created core has values for load on startup and transient different than defaults due to the
     // above.
@@ -134,7 +132,7 @@ public class TestCoreAdmin extends Abstr
     }
 
     assertEquals(new File(dataDir, "ulog" + File.separator + "tlog").getAbsolutePath(), logDir.getAbsolutePath());
-    server.shutdown();
+    client.shutdown();
     
   }
   

Modified: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/response/NoOpResponseParserTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/response/NoOpResponseParserTest.java?rev=1648697&r1=1648696&r2=1648697&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/response/NoOpResponseParserTest.java (original)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/response/NoOpResponseParserTest.java Wed Dec 31 14:05:48 2014
@@ -18,13 +18,12 @@ package org.apache.solr.client.solrj.res
  */
 
 import org.apache.commons.io.IOUtils;
-import org.apache.lucene.util.LuceneTestCase;
 import org.apache.solr.SolrJettyTestBase;
 import org.apache.solr.client.solrj.ResponseParser;
 import org.apache.solr.client.solrj.SolrQuery;
-import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.HttpSolrServer;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.impl.NoOpResponseParser;
 import org.apache.solr.client.solrj.impl.XMLResponseParser;
 import org.apache.solr.client.solrj.request.QueryRequest;
@@ -32,7 +31,6 @@ import org.apache.solr.common.SolrDocume
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.SolrResourceLoader;
-import org.apache.solr.util.ExternalPaths;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -63,11 +61,11 @@ public class NoOpResponseParserTest exte
   @Before
   public void doBefore() throws IOException, SolrServerException {
     //add document and commit, and ensure it's there
-    SolrServer server1 = getSolrServer();
+    SolrClient client = getSolrClient();
     SolrInputDocument doc = new SolrInputDocument();
     doc.addField("id", "1234");
-    server1.add(doc);
-    server1.commit();
+    client.add(doc);
+    client.commit();
   }
 
   /**
@@ -75,15 +73,15 @@ public class NoOpResponseParserTest exte
    */
   @Test
   public void testQueryParse() throws Exception {
-    HttpSolrServer server = (HttpSolrServer) createNewSolrServer();
+    HttpSolrClient client = (HttpSolrClient) createNewSolrClient();
     SolrQuery query = new SolrQuery("id:1234");
     QueryRequest req = new QueryRequest(query);
-    server.setParser(new NoOpResponseParser());
-    NamedList<Object> resp = server.request(req);
+    client.setParser(new NoOpResponseParser());
+    NamedList<Object> resp = client.request(req);
     String responseString = (String) resp.get("response");
 
     assertResponse(responseString);
-    server.shutdown();
+    client.shutdown();
   }
 
   private void assertResponse(String responseString) throws IOException {

Modified: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/response/TermsResponseTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/response/TermsResponseTest.java?rev=1648697&r1=1648696&r2=1648697&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/response/TermsResponseTest.java (original)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/response/TermsResponseTest.java Wed Dec 31 14:05:48 2014
@@ -24,7 +24,6 @@ import org.apache.solr.client.solrj.Solr
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.client.solrj.request.QueryRequest;
 import org.apache.solr.client.solrj.response.TermsResponse.Term;
-import org.apache.solr.util.ExternalPaths;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -53,8 +52,8 @@ public class TermsResponseTest extends S
     SolrInputDocument doc = new SolrInputDocument();
     doc.setField("id", 1);
     doc.setField("terms_s", "samsung");
-    getSolrServer().add(doc);
-    getSolrServer().commit(true, true);
+    getSolrClient().add(doc);
+    getSolrClient().commit(true, true);
 
     SolrQuery query = new SolrQuery();
     query.setRequestHandler("/terms");
@@ -66,7 +65,7 @@ public class TermsResponseTest extends S
     query.setTermsMinCount(1);
     
     QueryRequest request = new QueryRequest(query);
-    List<Term> terms = request.process(getSolrServer()).getTermsResponse().getTerms("terms_s");
+    List<Term> terms = request.process(getSolrClient()).getTermsResponse().getTerms("terms_s");
 
     Assert.assertNotNull(terms);
     Assert.assertEquals(terms.size(), 1);