You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by cp...@apache.org on 2018/04/10 20:25:33 UTC

lucene-solr:branch_7x: SOLR-12151: Add abstract MultiSolrCloudTestCase class.

Repository: lucene-solr
Updated Branches:
  refs/heads/branch_7x bce3925cd -> f59770b24


SOLR-12151: Add abstract MultiSolrCloudTestCase class.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/f59770b2
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/f59770b2
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/f59770b2

Branch: refs/heads/branch_7x
Commit: f59770b2402f1c1e77a3b53306ffae3761c8e0b3
Parents: bce3925
Author: Christine Poerschke <cp...@apache.org>
Authored: Tue Apr 10 21:09:06 2018 +0100
Committer: Christine Poerschke <cp...@apache.org>
Committed: Tue Apr 10 21:25:15 2018 +0100

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   2 +
 .../solr/cloud/MultiSolrCloudTestCaseTest.java  |  80 ++++++++++++++
 .../solr/cloud/MultiSolrCloudTestCase.java      | 107 +++++++++++++++++++
 .../apache/solr/cloud/SolrCloudTestCase.java    |  13 ++-
 4 files changed, 200 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f59770b2/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 0c88650..73866c6 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -61,6 +61,8 @@ New Features
 
 * SOLR-12036: Factor out DefaultStreamFactory solrj class. (Christine Poerschke)
 
+* SOLR-12151: Add abstract MultiSolrCloudTestCase class. (Christine Poerschke)
+
 Bug Fixes
 ----------------------
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f59770b2/solr/core/src/test/org/apache/solr/cloud/MultiSolrCloudTestCaseTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/MultiSolrCloudTestCaseTest.java b/solr/core/src/test/org/apache/solr/cloud/MultiSolrCloudTestCaseTest.java
new file mode 100644
index 0000000..2e382f8
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/cloud/MultiSolrCloudTestCaseTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.cloud;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class MultiSolrCloudTestCaseTest extends MultiSolrCloudTestCase {
+
+  private static int numClouds;
+  private static int numCollectionsPerCloud;
+
+  private static int numShards;
+  private static int numReplicas;
+  private static int maxShardsPerNode;
+  private static int nodesPerCluster;
+
+  @BeforeClass
+  public static void setupClusters() throws Exception {
+
+    numClouds = random().nextInt(4); //  0..3
+    final String[] clusterIds = new String[numClouds];
+    for (int ii=0; ii<numClouds; ++ii) {
+      clusterIds[ii] = "cloud"+(ii+1);
+    }
+
+    numCollectionsPerCloud = random().nextInt(3); //  0..2
+    final String[] collections = new String[numCollectionsPerCloud];
+    for (int ii=0; ii<numCollectionsPerCloud; ++ii) {
+      collections[ii] = "collection"+(ii+1);
+    }
+
+    numShards = 1+random().nextInt(2);
+    numReplicas = 1+random().nextInt(2);
+    maxShardsPerNode = 1+random().nextInt(2);
+    nodesPerCluster = (numShards*numReplicas + (maxShardsPerNode-1))/maxShardsPerNode;
+
+    doSetupClusters(
+        clusterIds,
+        new DefaultClusterCreateFunction() {
+          @Override
+          protected int nodesPerCluster(String clusterId) {
+            return nodesPerCluster;
+          }
+        },
+        new DefaultClusterInitFunction(numShards, numReplicas, maxShardsPerNode) {
+          @Override
+          public void accept(String clusterId, MiniSolrCloudCluster cluster) {
+            for (final String collection : collections) {
+              if (random().nextBoolean()) {
+                doAccept(collection, cluster); // same collection name in different clouds
+              } else {
+                doAccept(collection+"_in_"+clusterId, cluster); // globally unique collection name
+              }
+            }
+          }
+        });
+  }
+
+  @Test
+  public void test() throws Exception {
+    assertEquals("numClouds", numClouds, clusterId2cluster.size());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f59770b2/solr/test-framework/src/java/org/apache/solr/cloud/MultiSolrCloudTestCase.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/MultiSolrCloudTestCase.java b/solr/test-framework/src/java/org/apache/solr/cloud/MultiSolrCloudTestCase.java
new file mode 100644
index 0000000..4562c3e
--- /dev/null
+++ b/solr/test-framework/src/java/org/apache/solr/cloud/MultiSolrCloudTestCase.java
@@ -0,0 +1,107 @@
+/*
+ * 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.cloud;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.junit.AfterClass;
+
+/**
+ * Base class for tests that require more than one SolrCloud
+ *
+ * Derived tests should call {@link #doSetupClusters(String[], Function, BiConsumer)} in a {@code BeforeClass}
+ * static method.  This configures and starts the {@link MiniSolrCloudCluster} instances, available
+ * via the {@code clusterId2cluster} variable.  The clusters' shutdown is handled automatically.
+ */
+public abstract class MultiSolrCloudTestCase extends SolrTestCaseJ4 {
+
+  protected static Map<String,MiniSolrCloudCluster> clusterId2cluster = new HashMap<String,MiniSolrCloudCluster>();
+
+  protected static abstract class DefaultClusterCreateFunction implements Function<String,MiniSolrCloudCluster> {
+
+    public DefaultClusterCreateFunction() {
+    }
+
+    protected abstract int nodesPerCluster(String clusterId);
+
+    @Override
+    public MiniSolrCloudCluster apply(String clusterId) {
+      try {
+        final MiniSolrCloudCluster cluster = new SolrCloudTestCase
+            .Builder(nodesPerCluster(clusterId), createTempDir())
+            .addConfig("conf", configset("cloud-dynamic"))
+            .build();
+        return cluster;
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+  }
+
+  protected static abstract class DefaultClusterInitFunction implements BiConsumer<String,MiniSolrCloudCluster> {
+
+    final private int numShards;
+    final private int numReplicas;
+    final private int maxShardsPerNode;
+
+    public DefaultClusterInitFunction(int numShards, int numReplicas, int maxShardsPerNode) {
+      this.numShards = numShards;
+      this.numReplicas = numReplicas;
+      this.maxShardsPerNode = maxShardsPerNode;
+    }
+
+    protected void doAccept(String collection, MiniSolrCloudCluster cluster) {
+      try {
+        CollectionAdminRequest
+        .createCollection(collection, "conf", numShards, numReplicas)
+        .setMaxShardsPerNode(maxShardsPerNode)
+        .processAndWait(cluster.getSolrClient(), SolrCloudTestCase.DEFAULT_TIMEOUT);
+
+        AbstractDistribZkTestBase.waitForRecoveriesToFinish(collection, cluster.getSolrClient().getZkStateReader(), false, true, SolrCloudTestCase.DEFAULT_TIMEOUT);
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+  }
+
+  protected static void doSetupClusters(final String[] clusterIds,
+      final Function<String,MiniSolrCloudCluster> createFunc,
+      final BiConsumer<String,MiniSolrCloudCluster> initFunc) throws Exception {
+
+    for (final String clusterId : clusterIds) {
+      assertFalse("duplicate clusterId "+clusterId, clusterId2cluster.containsKey(clusterId));
+      MiniSolrCloudCluster cluster = createFunc.apply(clusterId);
+      initFunc.accept(clusterId, cluster);
+      clusterId2cluster.put(clusterId, cluster);
+    }
+  }
+
+  @AfterClass
+  public static void shutdownCluster() throws Exception {
+    for (MiniSolrCloudCluster cluster : clusterId2cluster.values()) {
+      cluster.shutdown();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f59770b2/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java b/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
index b8bf1f4..e0f3d78 100644
--- a/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
+++ b/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
@@ -87,7 +87,7 @@ public class SolrCloudTestCase extends SolrTestCaseJ4 {
   /**
    * Builder class for a MiniSolrCloudCluster
    */
-  protected static class Builder {
+  public static class Builder {
 
     private final int nodeCount;
     private final Path baseDir;
@@ -187,7 +187,15 @@ public class SolrCloudTestCase extends SolrTestCaseJ4 {
      * @throws Exception if an error occurs on startup
      */
     public void configure() throws Exception {
-      cluster = new MiniSolrCloudCluster(nodeCount, baseDir, solrxml, jettyConfig, null, securityJson);
+      cluster = build();
+    }
+
+    /**
+     * Configure, run and return the {@link MiniSolrCloudCluster}
+     * @throws Exception if an error occurs on startup
+     */
+    public MiniSolrCloudCluster build() throws Exception {
+      MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(nodeCount, baseDir, solrxml, jettyConfig, null, securityJson);
       CloudSolrClient client = cluster.getSolrClient();
       for (Config config : configs) {
         ((ZkClientClusterStateProvider)client.getClusterStateProvider()).uploadConfig(config.path, config.name);
@@ -199,6 +207,7 @@ public class SolrCloudTestCase extends SolrTestCaseJ4 {
           props.setClusterProperty(entry.getKey(), entry.getValue());
         }
       }
+      return cluster;
     }
 
   }