Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   package org.apache.solr.cloud;
   
   /*
    * 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 static org.apache.solr.cloud.OverseerCollectionProcessor.CREATE_NODE_SET;
  import static org.apache.solr.cloud.OverseerCollectionProcessor.NUM_SLICES;
  import static org.apache.solr.cloud.OverseerCollectionProcessor.SHARDS_PROP;
  import static org.apache.solr.common.cloud.ZkStateReader.MAX_SHARDS_PER_NODE;
  import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR;
  
  import java.io.File;
  import java.net.URI;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Random;
  import java.util.Set;
  
  import org.junit.After;
  import org.junit.Before;
  import org.slf4j.Logger;
TODO: we should still test this works as a custom update chain as well as what we test now - the default update chain
  
  @Slow
  public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTestBase {
    static Logger log = LoggerFactory.getLogger(AbstractFullDistribZkTestBase.class);
    
    @BeforeClass
    public static void beforeFullSolrCloudTest() {
      // shorten the log output more for this test type
      if ( != null.setShorterFormat();
    }
    
    public static final String SHARD1 = "shard1";
    public static final String SHARD2 = "shard2";
    
    protected boolean printLayoutOnTearDown = false;
    
    String t1 = "a_t";
    String i1 = "a_si";
    String nint = "n_i";
    String tint = "n_ti";
   String nfloat = "n_f";
   String tfloat = "n_tf";
   String ndouble = "n_d";
   String tdouble = "n_td";
   String nlong = "n_l";
   String tlong = "other_tl1";
   String ndate = "n_dt";
   String tdate = "n_tdt";
   
   String oddField = "oddField_s";
   String missingField = "ignore_exception__missing_but_valid_field_t";
   String invalidField = "ignore_exception__invalid_field_not_in_schema";
   protected int sliceCount;
 
   protected CloudSolrServer controlClientCloud;  // cloud version of the control client
   protected volatile CloudSolrServer cloudClient;
   
   private AtomicInteger jettyIntCntr = new AtomicInteger(0);
   protected ChaosMonkey chaosMonkey;
   
   private boolean cloudInit;
   protected boolean checkCreatedVsState;
   protected boolean useJettyDataDir = true;
   
   public static class CloudJettyRunner {
     public JettySolrRunner jetty;
     public String nodeName;
     public String coreNodeName;
     public String url;
     public CloudSolrServerClient client;
     public ZkNodeProps info;
     @Override
     public int hashCode() {
       final int prime = 31;
       int result = 1;
       result = prime * result + (( == null) ? 0 : .hashCode());
       return result;
     }
     @Override
     public boolean equals(Object obj) {
       if (this == objreturn true;
       if (obj == nullreturn false;
       if (getClass() != obj.getClass()) return false;
       CloudJettyRunner other = (CloudJettyRunnerobj;
       if ( == null) {
         if (other.url != nullreturn false;
       } else if (!.equals(other.url)) return false;
       return true;
     }
     @Override
     public String toString() {
       return "CloudJettyRunner [url=" +  + "]";
     }
   }
   
   static class CloudSolrServerClient {
     String shardName;
     int port;
     public ZkNodeProps info;
     
     public CloudSolrServerClient() {}
     
     public CloudSolrServerClient(SolrServer client) {
       this. = client;
     }
     
     @Override
     public int hashCode() {
       final int prime = 31;
       int result = 1;
       result = prime * result + (( == null) ? 0 : .hashCode());
       return result;
     }
     
     @Override
     public boolean equals(Object obj) {
       if (this == objreturn true;
       if (obj == nullreturn false;
       if (getClass() != obj.getClass()) return false;
       CloudSolrServerClient other = (CloudSolrServerClientobj;
       if ( == null) {
         if (other.solrClient != nullreturn false;
       } else if (!.equals(other.solrClient)) return false;
       return true;
     }
     
   }
   
   @Before
   public void setUp() throws Exception {
     super.setUp();
     // ignoreException(".*");
     if ( > 0) {
       System.setProperty("numShards", Integer.toString());
     } else {
       System.clearProperty("numShards");
     }
   }
   
   public static void beforeClass() {
     System.setProperty("solrcloud.update.delay""0");
   }
   
   public static void afterClass() {
     System.clearProperty("solrcloud.update.delay");
     System.clearProperty("genericCoreNodeNames");
   }
   
      = true;
     
      = 4;
      = 2;
     // TODO: for now, turn off stress because it uses regular clients, and we
     // need the cloud client because we kill servers
      = 0;
     
   }
   
   protected String getDataDir(String dataDirthrows IOException {
     return dataDir;
   }
   
   protected void initCloud() throws Exception {
     assert( == false);
      = true;
     try {
       
       .connect();
     } catch (MalformedURLException e) {
       throw new RuntimeException(e);
     }
     
     ZkStateReader zkStateReader = .getZkStateReader();
     
      = new ChaosMonkey(zkStateReader,
         );
   }
   
   protected CloudSolrServer createCloudClient(String defaultCollection)
       throws MalformedURLException {
     if (defaultCollection != nullserver.setDefaultCollection(defaultCollection);
     server.getLbServer().getHttpClient().getParams()
     server.getLbServer().getHttpClient().getParams()
         .setParameter(., 30000);
     return server;
   }
   
   protected void createServers(int numServersthrows Exception {
     
     System.setProperty("collection""control_collection");
 
     // we want hashes by default for the control, so set to 1 shard as opposed to leaving unset
     String oldNumShards = System.getProperty(.);
     
     try {
       
     File controlJettyDir = new File(,
             getClass().getName() + "-controljetty-" + System.currentTimeMillis());
       setupJettySolrHome(controlJettyDir);
       
        = createJetty(controlJettyDir,getDataDir( + "/control/data")); // don't pass shard name... let it default to "shard1"
 
       
       if ( <= 0) {
         // for now, just create the cloud client for the control if we don't
         // create the normal cloud client.
         // this can change if more tests need it.
          = createCloudClient("control_collection");
         .connect();
             "control_collection", 0);
         // NOTE: we are skipping creation of the chaos monkey by returning here
          = // temporary - some code needs/uses
                                           // cloudClient
         return;
       }
       
     } finally {
       System.clearProperty("collection");
       if (oldNumShards != null) {
         System.setProperty(.oldNumShards);
       } else {
       }
     }
 
 
     initCloud();
     
     createJettys(numServers).size();
     
     int cnt = getTotalReplicas();
     if (cnt > 0) {
     }
 
   }
 
 
   protected void waitForCollection(ZkStateReader readerString collectionint slicesthrows Exception {
     // wait until shards have started registering...
     int cnt = 30;
     while (!reader.getClusterState().getCollections().contains(collection)) {
       if (cnt == 0) {
         throw new RuntimeException("timeout waiting for collection in cluster state: collection=" + collection);
       }
       cnt--;
       Thread.sleep(500);
     }
     cnt = 30;
     while (reader.getClusterState().getSlices(collection).size() < slices) {
       if (cnt == 0) {
         throw new RuntimeException("timeout waiting for collection shards to come up: collection="+collection
             + ", slices.expected="+slices" slices.actual= " + reader.getClusterState().getSlices(collection).size()
             + " slices : "reader.getClusterState().getSlices(collection) );
       }
       cnt--;
       Thread.sleep(500);
     }
   }
   
   protected List<JettySolrRunnercreateJettys(int numJettysthrows Exception {
     return createJettys(numJettysfalse);
   }
  

  

Parameters:
checkCreatedVsState if true, make sure the number created (numJettys) matches the number in the cluster state - if you add more jetties this may not be the case
 
   protected List<JettySolrRunnercreateJettys(int numJettysboolean checkCreatedVsStatethrows Exception {
     List<JettySolrRunnerjettys = new ArrayList<JettySolrRunner>();
     List<SolrServerclients = new ArrayList<SolrServer>();
     StringBuilder sb = new StringBuilder();
     for (int i = 1; i <= numJettysi++) {
       if (sb.length() > 0) sb.append(',');
       int cnt = this..incrementAndGet();
       File jettyDir = new File(,
           getClass().getName() + "-jetty" + cnt + "-" + System.currentTimeMillis());
       jettyDir.mkdirs();
       setupJettySolrHome(jettyDir);
       JettySolrRunner j = createJetty(jettyDir ? getDataDir( + "/jetty"
           + cnt) : nullnull"solrconfig.xml"null);
       jettys.add(j);
       SolrServer client = createNewSolrServer(j.getLocalPort());
       clients.add(client);
     }
   
     this..addAll(jettys);
     this..addAll(clients);
     
     int numShards = getTotalReplicas();
     if (checkCreatedVsState) {
       // now wait until we see that the number of shards in the cluster state
       // matches what we expect
       int retries = 0;
       while (numShards != ) {
         numShards = getTotalReplicas();
         if (numShards == break;
         if (retries++ == 60) {
            = true;
           fail("Shards in the state does not match what we set:" + numShards
               + " vs " + );
         }
         Thread.sleep(500);
       }
 
       ZkStateReader zkStateReader = .getZkStateReader();
       // also make sure we have a leader for each shard
       for (int i = 1; i <= i++) {
         zkStateReader.getLeaderRetry("shard" + i, 10000);
       }
     }
 
     if (numShards > 0) {
       updateMappingsFromZk(this.this.);
     }
     
     // build the shard string
     for (int i = 1; i <= numJettys / 2; i++) {
       JettySolrRunner j = this..get(i);
       JettySolrRunner j2 = this..get(i + (numJettys / 2 - 1));
       if (sb.length() > 0) sb.append(',');
       sb.append("127.0.0.1:").append(j.getLocalPort()).append();
       sb.append("|127.0.0.1:").append(j2.getLocalPort()).append();
     }
      = sb.toString();
     
     return jettys;
   }
 
 
   protected SolrServer startCloudJetty(String collectionString shardthrows Exception {
 
     // TODO: use the collection string!!!!
     collection = ;
 
     int totalReplicas = getTotalReplicas(collection);
 
 
     int cnt = this..incrementAndGet();
       File jettyDir = new File(,
           getClass().getName() + "-jetty" + cnt + "-" + System.currentTimeMillis());
       jettyDir.mkdirs();
       org.apache.commons.io.FileUtils.copyDirectory(new File(getSolrHome()), jettyDir);
       JettySolrRunner j = createJetty(jettyDir + "/jetty" + cntshard"solrconfig.xml"null);
       .add(j);
       SolrServer client = createNewSolrServer(j.getLocalPort());
       .add(client);
 
     int retries = 60;
     while (--retries >= 0) {
       // total replicas changed.. assume it was us
       if (getTotalReplicas(collection) != totalReplicas) {
        break;
       }
       Thread.sleep(500);
     }
 
     if (retries <= 0) {
       fail("Timeout waiting for " + j + " to appear in clusterstate");
       printLayout();
     }
 
     updateMappingsFromZk(this.this.);
     return client;
   }
 
 
   /* Total number of replicas (number of cores serving an index to the collection) shown by the cluster state */
   protected int getTotalReplicas(String collection) {
     ZkStateReader zkStateReader = .getZkStateReader();
     DocCollection coll = zkStateReader.getClusterState().getCollectionStates().get(collection);
     if (coll == nullreturn 0;  // support for when collection hasn't been created yet
     int cnt = 0;
     for (Slice slices : coll.getSlices()) {
       cnt += slices.getReplicas().size();
     }
     return cnt;
   }
   
   public JettySolrRunner createJetty(String dataDirString ulogDirString shardList,
       String solrConfigOverridethrows Exception {
     
     JettySolrRunner jetty = new JettySolrRunner(getSolrHome(), , 0,
         solrConfigOverridenullfalsegetExtraServlets(), nullgetExtraRequestFilters());
     jetty.setShards(shardList);
     jetty.setDataDir(getDataDir(dataDir));
     jetty.start();
     
     return jetty;
   }
   
   public JettySolrRunner createJetty(File solrHomeString dataDirString shardListString solrConfigOverrideString schemaOverridethrows Exception {
 
     JettySolrRunner jetty = new JettySolrRunner(solrHome.getAbsolutePath(), , 0, solrConfigOverrideschemaOverridefalsegetExtraServlets(), nullgetExtraRequestFilters());
     jetty.setShards(shardList);
     jetty.setDataDir(getDataDir(dataDir));
     jetty.start();
     
     return jetty;
   }
   
   protected void updateMappingsFromZk(List<JettySolrRunnerjettys,
       List<SolrServerclientsthrows Exception {
     ZkStateReader zkStateReader = .getZkStateReader();
     zkStateReader.updateClusterState(true);
     .clear();
     .clear();
     
     ClusterState clusterState = zkStateReader.getClusterState();
     DocCollection coll = clusterState.getCollection();
 
     List<CloudSolrServerClienttheClients = new ArrayList<CloudSolrServerClient>();
     for (SolrServer client : clients) {
       // find info for this client in zk 
       nextClient:
       // we find out state by simply matching ports...
       for (Slice slice : coll.getSlices()) {
         for (Replica replica : slice.getReplicas()) {
           int port = new URI(((HttpSolrServerclient).getBaseURL())
               .getPort();
           
           if (replica.getNodeName().contains(":" + port + "_")) {
             CloudSolrServerClient csc = new CloudSolrServerClient();
             csc.solrClient = client;
             csc.port = port;
             csc.shardName = replica.getStr(.);
             csc.info = replica;
             
             theClients .add(csc);
             
             break nextClient;
           }
         }
       }
     }
  
     for (JettySolrRunner jetty : jettys) {
       int port = jetty.getLocalPort();
       if (port == -1) {
         throw new RuntimeException("Cannot find the port for jetty");
       }
       
       nextJetty:
       for (Slice slice : coll.getSlices()) {
         Set<Entry<String,Replica>> entries = slice.getReplicasMap().entrySet();
         for (Entry<String,Replicaentry : entries) {
           Replica replica = entry.getValue();
           if (replica.getStr(.).contains(":" + port)) {
             List<CloudJettyRunnerlist = .get(slice.getName());
             if (list == null) {
               list = new ArrayList<CloudJettyRunner>();
               .put(slice.getName(), list);
             }
             boolean isLeader = slice.getLeader() == replica;
             CloudJettyRunner cjr = new CloudJettyRunner();
             cjr.jetty = jetty;
             cjr.info = replica;
             cjr.nodeName = replica.getStr(.);
             cjr.coreNodeName = entry.getKey();
             cjr.url = replica.getStr(.) + "/" + replica.getStr(.);
             cjr.client = findClientByPort(porttheClients);
             list.add(cjr);
             if (isLeader) {
               .put(slice.getName(), cjr);
             }
             .add(cjr);
             break nextJetty;
           }
         }
       }
     }
     
     // # of jetties may not match replicas in shard here, because we don't map
     // jetties that are not running - every shard should have at least one
     // running jetty though
     for (Slice slice : coll.getSlices()) {
       // check that things look right
       List<CloudJettyRunnerjetties = .get(slice.getName());
       assertNotNull("Test setup problem: We found no jetties for shard: " + slice.getName()
           + " just:" + .keySet(), jetties);
       assertEquals("slice:" + slice.getName(), slice.getReplicas().size(), jetties.size());
     }
   }
   
   private CloudSolrServerClient findClientByPort(int portList<CloudSolrServerClienttheClients) {
     for (CloudSolrServerClient client : theClients) {
       if (client.port == port) {
         return client;
       }
     }
     throw new IllegalArgumentException("Client with the given port does not exist:" + port);
   }
 
   protected void setDistributedParams(ModifiableSolrParams params) {
     
     if (.nextBoolean()) {
       // don't set shards, let that be figured out from the cloud state
     } else {
       // use shard ids rather than physical locations
       StringBuilder sb = new StringBuilder();
       for (int i = 0; i < i++) {
         if (i > 0) sb.append(',');
         sb.append("shard" + (i + 1));
       }
       params.set("shards"sb.toString());
     }
   }
   
   protected void indexDoc(SolrInputDocument docthrows IOException,
       SolrServerException {
     .add(doc);
     
     // if we wanted to randomly pick a client - but sometimes they may be
     // down...
     
     // boolean pick = random.nextBoolean();
     //
     // int which = (doc.getField(id).toString().hashCode() & 0x7fffffff) %
     // sliceCount;
     //
     // if (pick && sliceCount > 1) {
     // which = which + ((shardCount / sliceCount) *
     // random.nextInt(sliceCount-1));
     // }
     //
     // CommonsHttpSolrServer client = (CommonsHttpSolrServer)
     // clients.get(which);
     
     UpdateRequest ureq = new UpdateRequest();
     ureq.add(doc);
     // ureq.setParam(UpdateParams.UPDATE_CHAIN, DISTRIB_UPDATE_CHAIN);
     ureq.process();
   }
   
   protected void index_specific(int serverNumberObject... fields)
       throws Exception {
     SolrInputDocument doc = new SolrInputDocument();
     for (int i = 0; i < fields.lengthi += 2) {
       doc.addField((String) (fields[i]), fields[i + 1]);
     }
     .add(doc);
     
     HttpSolrServer client = (HttpSolrServer
         .get(serverNumber);
     
     UpdateRequest ureq = new UpdateRequest();
     ureq.add(doc);
     // ureq.setParam("update.chain", DISTRIB_UPDATE_CHAIN);
     ureq.process(client);
   }
   
   protected void index_specific(SolrServer clientObject... fields)
       throws Exception {
     SolrInputDocument doc = new SolrInputDocument();
     for (int i = 0; i < fields.lengthi += 2) {
       doc.addField((String) (fields[i]), fields[i + 1]);
     }
     
     UpdateRequest ureq = new UpdateRequest();
     ureq.add(doc);
     // ureq.setParam("update.chain", DISTRIB_UPDATE_CHAIN);
     ureq.process(client);
     
     // add to control second in case adding to shards fails
     .add(doc);
   }
   
   protected void del(String qthrows Exception {
     .deleteByQuery(q);

    
for (SolrServer client : clients) { UpdateRequest ureq = new UpdateRequest(); // ureq.setParam("update.chain", DISTRIB_UPDATE_CHAIN); ureq.deleteByQuery(q).process(client); }
 
   }// serial commit...
   
   protected void waitForRecoveriesToFinish(boolean verbose)
       throws Exception {
     ZkStateReader zkStateReader = .getZkStateReader();
     super.waitForRecoveriesToFinish(zkStateReaderverbose);
   }
   
   protected void waitForRecoveriesToFinish(String collectionboolean verbose)
       throws Exception {
     ZkStateReader zkStateReader = .getZkStateReader();
     super.waitForRecoveriesToFinish(collectionzkStateReaderverbose);
   }
   
   protected void waitForRecoveriesToFinish(boolean verboseint timeoutSeconds)
       throws Exception {
     ZkStateReader zkStateReader = .getZkStateReader();
     super.waitForRecoveriesToFinish(zkStateReaderverbosetruetimeoutSeconds);
   }
   
   protected void checkQueries() throws Exception {
 
     .put("_version_");
 
     query("q""*:*""sort""n_tl1 desc");
 
     .put("response");  // get?ids=a,b,c requests are unordered
     String ids = "987654";
     for (int i=0; i<20; i++) {
       query("qt","/get""id",Integer.toString(i));
       query("qt","/get""ids",Integer.toString(i));
       ids = ids + ',' + Integer.toString(i);
       query("qt","/get""ids",ids);
     }
     .remove("response");
 
 
 
     // random value sort
     for (String f : ) {
       query("q""*:*""sort"f + " desc");
       query("q""*:*""sort"f + " asc");
     }
     
     // these queries should be exactly ordered and scores should exactly match
     query("q""*:*""sort" + " desc");
     query("q""*:*""sort" + " asc");
     query("q""*:*""sort" + " desc""fl""*,score");
     query("q""*:*""sort""n_tl1 asc""fl""score"); // test legacy
                                                            // behavior -
                                                            // "score"=="*,score"
     query("q""*:*""sort""n_tl1 desc");
     .put("maxScore");
     query("q""{!func}" + );// does not expect maxScore. So if it comes
                                // ,ignore it.
                                // JavaBinCodec.writeSolrDocumentList()
     // is agnostic of request params.
     .remove("maxScore");
     query("q""{!func}" + "fl""*,score"); // even scores should match
                                                  // exactly here
     
     .put("highlighting");
     .put("response");
     
     .put("maxScore");
     query("q""quick");
     query("q""all""fl""id""start""0");
     query("q""all""fl""foofoofoo""start""0"); // no fields in returned
                                                         // docs
     query("q""all""fl""id""start""100");
     
     .put("score");
     query("q""quick""fl""*,score");
     query("q""all""fl""*,score""start""1");
     query("q""all""fl""*,score""start""100");
     
     query("q""now their fox sat had put""fl""*,score""hl""true",
         "hl.fl");
     
     query("q""now their fox sat had put""fl""foofoofoo""hl""true",
         "hl.fl");
     
     query("q""matchesnothing""fl""*,score");
     
     query("q""*:*""rows", 100, "facet""true""facet.field");
     query("q""*:*""rows", 100, "facet""true""facet.field",
         "facet.limit", -1, "facet.sort""count");
     query("q""*:*""rows", 100, "facet""true""facet.field",
         "facet.limit", -1, "facet.sort""count""facet.mincount", 2);
     query("q""*:*""rows", 100, "facet""true""facet.field",
         "facet.limit", -1, "facet.sort""index");
     query("q""*:*""rows", 100, "facet""true""facet.field",
         "facet.limit", -1, "facet.sort""index""facet.mincount", 2);
     query("q""*:*""rows", 100, "facet""true""facet.field",
         "facet.limit", 1);
     query("q""*:*""rows", 100, "facet""true""facet.query""quick",
         "facet.query""all""facet.query""*:*");
     query("q""*:*""rows", 100, "facet""true""facet.field",
         "facet.offset", 1);
     query("q""*:*""rows", 100, "facet""true""facet.field",
         "facet.mincount", 2);
     
     // test faceting multiple things at once
     query("q""*:*""rows", 100, "facet""true""facet.query""quick",
         "facet.query""all""facet.query""*:*""facet.field");
     
     // test filter tagging, facet exclusion, and naming (multi-select facet
     // support)
     query("q""*:*""rows", 100, "facet""true""facet.query",
         "{!key=myquick}quick""facet.query""{!key=myall ex=a}all",
         "facet.query""*:*""facet.field""{!key=mykey ex=a}" + ,
         "facet.field""{!key=other ex=b}" + "facet.field",
         "{!key=again ex=a,b}" + "facet.field""fq",
         "{!tag=a}id:[1 TO 7]""fq""{!tag=b}id:[3 TO 9]");
     query("q""*:*""facet""true""facet.field",
         "{!ex=t1}SubjectTerms_mfacet""fq",
         "{!tag=t1}SubjectTerms_mfacet:(test 1)""facet.limit""10",
         "facet.mincount""1");
     
     // test field that is valid in schema but missing in all shards
     query("q""*:*""rows", 100, "facet""true""facet.field",
         "facet.mincount", 2);
     // test field that is valid in schema and missing in some shards
     query("q""*:*""rows", 100, "facet""true""facet.field",
         "facet.mincount", 2);
     
     query("q""*:*""sort" + " desc""stats""true""stats.field");
     
     // Try to get better coverage for refinement queries by turning off over
     // requesting.
     // This makes it much more likely that we may not get the top facet values
     // and hence
     // we turn of that checking.
     .put("facet_fields");
     query("q""*:*""rows", 0, "facet""true""facet.field",
         "facet.limit", 5, "facet.shard.limit", 5);
     // check a complex key name
     query("q""*:*""rows", 0, "facet""true""facet.field",
         "{!key='a b/c \\' \\} foo'}" + "facet.limit", 5,
         "facet.shard.limit", 5);
     .remove("facet_fields");
     
     query("q""*:*""sort""n_tl1 desc");
     
     // index the same document to two shards and make sure things
     // don't blow up.
     // assumes first n clients are first n shards
     if (.size() >= 2) {
       index(, 100, , 107, "oh no, a duplicate!");
       for (int i = 0; i < i++) {
         index_specific(i, 100, , 107, "oh no, a duplicate!");
       }
       commit();
       query("q""duplicate""hl""true""hl.fl");
       query("q""fox duplicate horses""hl""true""hl.fl");
       query("q""*:*""rows", 100);
     }
   }
   
   protected void indexAbunchOfDocs() throws Exception {
     indexr(, 2, , 50, , 50, "to come to the aid of their country.");
     indexr(, 3, , 2, , 2, "how now brown cow");
     indexr(, 4, , -100, , 101, ,
         "the quick fox jumped over the lazy dog");
     indexr(, 5, , 500, , 500, ,
         "the quick fox jumped way over the lazy dog");
     indexr(, 6, , -600, , 600, "humpty dumpy sat on a wall");
     indexr(, 7, , 123, , 123, "humpty dumpy had a great fall");
     indexr(, 8, , 876, , 876, ,
         "all the kings horses and all the kings men");
     indexr(, 9, , 7, , 7, "couldn't put humpty together again");
     indexr(, 10, , 4321, , 4321, "this too shall pass");
     indexr(, 11, , -987, , 987, ,
         "An eye for eye only ends up making the whole world blind.");
     indexr(, 12, , 379, , 379, ,
         "Great works are performed, not by strength, but by perseverance.");
     indexr(, 13, , 232, , 232, "no eggs on wall, lesson learned",
         "odd man out");
     
     indexr(, 14, "SubjectTerms_mfacet"new String[] {"mathematical models",
         "mathematical analysis"});
     indexr(, 15, "SubjectTerms_mfacet"new String[] {"test 1""test 2",
         "test3"});
     indexr(, 16, "SubjectTerms_mfacet"new String[] {"test 1""test 2",
         "test3"});
     String[] vals = new String[100];
     for (int i = 0; i < 100; i++) {
       vals[i] = "test " + i;
     }
     indexr(, 17, "SubjectTerms_mfacet"vals);
     
     for (int i = 100; i < 150; i++) {
       indexr(i);
     }
   }
  
  
Executes a query against each live and active replica of the specified shard and aserts that the results are identical.

 
   public QueryResponse queryAndCompareReplicas(SolrParams paramsString shard
     throws Exception {
 
     ArrayList<SolrServershardClients = new ArrayList<SolrServer>(7);
 
     ZkStateReader zkStateReader = .getZkStateReader();
     List<CloudJettyRunnersolrJetties = .get(shard);
     assertNotNull("no jetties found for shard: " + shardsolrJetties);
 
 
     for (CloudJettyRunner cjetty : solrJetties) {
       ZkNodeProps props = cjetty.info;
       String nodeName = props.getStr(.);
       boolean active = props.getStr(.).equals(.);
       boolean live = zkStateReader.getClusterState().liveNodesContain(nodeName);
       if (active && live) {
         shardClients.add(cjetty.client.solrClient);
       }
     }
     return queryAndCompare(paramsshardClients);
   }

  
For each Shard, executes a query against each live and active replica of that shard and asserts that the results are identical for each replica of the same shard. Because results are not compared between replicas of different shards, this method should be safe for comparing the results of any query, even if it contains "distrib=false", because the replicas should all be identical.

 
   public void queryAndCompareShards(SolrParams paramsthrows Exception {
 
     List<Stringshards = new ArrayList<String>(.keySet());
     for (String shard : shards) {
       queryAndCompareReplicas(paramsshard);
     }
   }

  
Returns a non-null string if replicas within the same shard do not have a consistent number of documents.
 
   protected void checkShardConsistency(String shardthrows Exception {
     checkShardConsistency(shardfalsefalse);
   }

  
Returns a non-null string if replicas within the same shard do not have a consistent number of documents. If expectFailure==false, the exact differences found will be logged since this would be an unexpected failure. verbose causes extra debugging into to be displayed, even if everything is consistent.
 
   protected String checkShardConsistency(String shardboolean expectFailureboolean verbose)
       throws Exception {
     
     List<CloudJettyRunnersolrJetties = .get(shard);
     if (solrJetties == null) {
       throw new RuntimeException("shard not found:" + shard + " keys:"
           + .keySet());
     }
     long num = -1;
     long lastNum = -1;
     String failMessage = null;
     if (verbose..println("check const of " + shard);
     int cnt = 0;
     ZkStateReader zkStateReader = .getZkStateReader();
     assertEquals(
         "The client count does not match up with the shard count for slice:"
             + shard,
         zkStateReader.getClusterState().getSlice(shard)
             .getReplicasMap().size(), solrJetties.size());
 
     CloudJettyRunner lastJetty = null;
     for (CloudJettyRunner cjetty : solrJetties) {
       ZkNodeProps props = cjetty.info;
       if (verbose..println("client" + cnt++);
       if (verbose..println("PROPS:" + props);
 
       try {
         SolrParams query = params("q","*:*""rows","0""distrib","false""tests","checkShardConsistency"); // "tests" is just a tag that won't do anything except be echoed in logs
         num = cjetty.client.solrClient.query(query).getResults().getNumFound();
       } catch (SolrServerException e) {
         if (verbose..println("error contacting client: "
             + e.getMessage() + "\n");
         continue;
       } catch (SolrException e) {
         if (verbose..println("error contacting client: "
             + e.getMessage() + "\n");
         continue;
       }
       
       boolean live = false;
       String nodeName = props.getStr(.);
       if (zkStateReader.getClusterState().liveNodesContain(nodeName)) {
         live = true;
       }
       if (verbose..println(" live:" + live);
       if (verbose..println(" num:" + num + "\n");
 
       boolean active = props.getStr(.).equals(
           .);
       if (active && live) {
         if (lastNum > -1 && lastNum != num && failMessage == null) {
           failMessage = shard + " is not consistent.  Got " + lastNum + " from " + lastJetty.url + "lastClient"
               + " and got " + num + " from " + cjetty.url;
 
           if (!expectFailure || verbose) {
             ..println("######" + failMessage);
             SolrQuery query = new SolrQuery("*:*");
             query.set("distrib"false);
             query.set("fl","id,_version_");
             query.set("rows","100000");
             query.set("sort","id asc");
             query.set("tests","checkShardConsistency/showDiff");
 
             SolrDocumentList lst1 = lastJetty.client.solrClient.query(query).getResults();
             SolrDocumentList lst2 = cjetty.client.solrClient.query(query).getResults();
 
             CloudInspectUtil.logDiff(lst1lst2lastJetty.urlcjetty.url);
           }
 
         }
         lastNum = num;
         lastJetty = cjetty;