You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by da...@apache.org on 2018/12/01 17:09:55 UTC

[07/32] lucene-solr:jira/http2: SOLR-12801: Make massive improvements to the tests.

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/ComputePlanActionTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/ComputePlanActionTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/ComputePlanActionTest.java
index 99eca6c..7227c8c 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/ComputePlanActionTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/ComputePlanActionTest.java
@@ -102,7 +102,8 @@ public class ComputePlanActionTest extends SolrCloudTestCase {
         for (int i1 = 0; i1 < jettySolrRunners.size(); i1++) {
           JettySolrRunner jettySolrRunner = jettySolrRunners.get(i1);
           if (jettySolrRunner == randomJetty) {
-            cluster.stopJettySolrRunner(i1);
+            JettySolrRunner j = cluster.stopJettySolrRunner(i1);
+            cluster.waitForJettyToStop(j);
             break;
           }
         }
@@ -168,8 +169,7 @@ public class ComputePlanActionTest extends SolrCloudTestCase {
   }
 
   @Test
-  //28-June-2018 @BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 21-May-2018
-  // commented 4-Sep-2018  @LuceneTestCase.BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 2-Aug-2018
+  @LuceneTestCase.AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") 
   public void testNodeLost() throws Exception  {
     // let's start a node so that we have at least two
     JettySolrRunner runner = cluster.startJettySolrRunner();
@@ -237,7 +237,8 @@ public class ComputePlanActionTest extends SolrCloudTestCase {
     for (int i = 0; i < cluster.getJettySolrRunners().size(); i++) {
       JettySolrRunner jettySolrRunner = cluster.getJettySolrRunners().get(i);
       if (jettySolrRunner == node2)  {
-        cluster.stopJettySolrRunner(i);
+        JettySolrRunner j = cluster.stopJettySolrRunner(i);
+        cluster.waitForJettyToStop(j);
         break;
       }
     }
@@ -275,12 +276,14 @@ public class ComputePlanActionTest extends SolrCloudTestCase {
     assertEquals(response.get("result").toString(), "success");
 
     CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection("testNodeWithMultipleReplicasLost",
-        "conf",2, 3);
+        "conf", 2, 3);
     create.setMaxShardsPerNode(2);
     create.process(solrClient);
+    
+    cluster.waitForActiveCollection("testNodeWithMultipleReplicasLost", 2, 6);
 
     waitForState("Timed out waiting for replicas of new collection to be active",
-        "testNodeWithMultipleReplicasLost", clusterShape(2, 3));
+        "testNodeWithMultipleReplicasLost", clusterShape(2, 6));
 
     ClusterState clusterState = cluster.getSolrClient().getZkStateReader().getClusterState();
     DocCollection docCollection = clusterState.getCollection("testNodeWithMultipleReplicasLost");
@@ -294,14 +297,14 @@ public class ComputePlanActionTest extends SolrCloudTestCase {
       if (replicas != null && replicas.size() == 2) {
         stoppedNodeName = jettySolrRunner.getNodeName();
         replicasToBeMoved = replicas;
-        cluster.stopJettySolrRunner(i);
+        JettySolrRunner j = cluster.stopJettySolrRunner(i);
+        cluster.waitForJettyToStop(j);
         break;
       }
     }
     assertNotNull(stoppedNodeName);
-    cluster.waitForAllNodes(30);
 
-    assertTrue("Trigger was not fired even after 5 seconds", triggerFiredLatch.await(5, TimeUnit.SECONDS));
+    assertTrue("Trigger was not fired even after 5 seconds", triggerFiredLatch.await(15, TimeUnit.SECONDS));
     assertTrue(fired.get());
 
     TriggerEvent triggerEvent = eventRef.get();
@@ -451,25 +454,29 @@ public class ComputePlanActionTest extends SolrCloudTestCase {
     assertEquals(response.get("result").toString(), "success");
 
     CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection("testSelected1",
-        "conf",2, 2);
+        "conf", 2, 2);
     create.process(solrClient);
 
     create = CollectionAdminRequest.createCollection("testSelected2",
-        "conf",2, 2);
+        "conf", 2, 2);
     create.process(solrClient);
 
     create = CollectionAdminRequest.createCollection("testSelected3",
-        "conf",2, 2);
+        "conf", 2, 2);
     create.process(solrClient);
-
+    
+    cluster.waitForActiveCollection("testSelected1", 2, 4);
+    cluster.waitForActiveCollection("testSelected2", 2, 4);
+    cluster.waitForActiveCollection("testSelected3", 2, 4);
+    
     waitForState("Timed out waiting for replicas of new collection to be active",
-        "testSelected1", clusterShape(2, 2));
+        "testSelected1", clusterShape(2, 4));
 
     waitForState("Timed out waiting for replicas of new collection to be active",
-        "testSelected2", clusterShape(2, 2));
+        "testSelected2", clusterShape(2, 4));
 
     waitForState("Timed out waiting for replicas of new collection to be active",
-        "testSelected3", clusterShape(2, 2));
+        "testSelected3", clusterShape(2, 4));
 
     // find a node that has replicas from all collections
     SolrCloudManager cloudManager = cluster.getJettySolrRunner(0).getCoreContainer().getZkController().getSolrCloudManager();
@@ -486,7 +493,8 @@ public class ComputePlanActionTest extends SolrCloudTestCase {
     String node = nodes.get(0);
     for (int i = 0; i < cluster.getJettySolrRunners().size(); i++) {
       if (cluster.getJettySolrRunner(i).getNodeName().equals(node)) {
-        cluster.stopJettySolrRunner(i);
+        JettySolrRunner j = cluster.stopJettySolrRunner(i);
+        cluster.waitForJettyToStop(j);
         break;
       }
     }
@@ -563,6 +571,7 @@ public class ComputePlanActionTest extends SolrCloudTestCase {
             collectionState.getReplicas().stream().allMatch(replica -> replica.isActive(liveNodes)));
 
     JettySolrRunner newNode = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     assertTrue(triggerFiredLatch.await(30, TimeUnit.SECONDS));
     assertTrue(fired.get());
     Map actionContext = actionContextPropsRef.get();
@@ -674,6 +683,6 @@ public class ComputePlanActionTest extends SolrCloudTestCase {
     }
 
     waitForState("Timed out waiting for all shards to have only 1 replica",
-        collectionNamePrefix + "_0", clusterShape(numShards, 1));
+        collectionNamePrefix + "_0", clusterShape(numShards, numShards));
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/ExecutePlanActionTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/ExecutePlanActionTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/ExecutePlanActionTest.java
index c15bc53..cbd0bac 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/ExecutePlanActionTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/ExecutePlanActionTest.java
@@ -45,6 +45,7 @@ import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.util.LogLevel;
 import org.apache.solr.common.util.TimeSource;
 import org.apache.zookeeper.data.Stat;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -67,28 +68,29 @@ public class ExecutePlanActionTest extends SolrCloudTestCase {
 
   @BeforeClass
   public static void setupCluster() throws Exception {
-    configureCluster(NODE_COUNT)
-        .addConfig("conf", configset("cloud-minimal"))
-        .configure();
+
   }
 
   @Before
   public void setUp() throws Exception  {
     super.setUp();
+    
+    configureCluster(NODE_COUNT)
+    .addConfig("conf", configset("cloud-minimal"))
+    .configure();
+    
     // clear any persisted auto scaling configuration
     Stat stat = zkClient().setData(SOLR_AUTOSCALING_CONF_PATH, Utils.toJSON(new ZkNodeProps()), true);
 
-    if (cluster.getJettySolrRunners().size() < NODE_COUNT) {
-      // start some to get to original state
-      int numJetties = cluster.getJettySolrRunners().size();
-      for (int i = 0; i < NODE_COUNT - numJetties; i++) {
-        cluster.startJettySolrRunner();
-      }
-    }
-    cluster.waitForAllNodes(30);
-    loader = cluster.getJettySolrRunner(0).getCoreContainer().getResourceLoader();
+
     cloudManager = cluster.getJettySolrRunner(0).getCoreContainer().getZkController().getSolrCloudManager();
-    cluster.deleteAllCollections();
+  }
+  
+
+  @After
+  public void tearDown() throws Exception  {
+    shutdownCluster();
+    super.tearDown();
   }
 
   @Test
@@ -99,6 +101,8 @@ public class ExecutePlanActionTest extends SolrCloudTestCase {
         "conf", 1, 2);
     create.setMaxShardsPerNode(1);
     create.process(solrClient);
+    
+    cluster.waitForActiveCollection(collectionName, 1, 2);
 
     waitForState("Timed out waiting for replicas of new collection to be active",
         collectionName, clusterShape(1, 2));
@@ -189,6 +193,8 @@ public class ExecutePlanActionTest extends SolrCloudTestCase {
         "conf", 1, 2);
     create.setMaxShardsPerNode(1);
     create.process(solrClient);
+    
+    cluster.waitForActiveCollection(collectionName, 1, 2);
 
     waitForState("Timed out waiting for replicas of new collection to be active",
         collectionName, clusterShape(1, 2));
@@ -209,11 +215,13 @@ public class ExecutePlanActionTest extends SolrCloudTestCase {
     for (int i = 0; i < cluster.getJettySolrRunners().size(); i++) {
       JettySolrRunner runner = cluster.getJettySolrRunner(i);
       if (runner == sourceNode) {
-        cluster.stopJettySolrRunner(i);
+        JettySolrRunner j = cluster.stopJettySolrRunner(i);
+        cluster.waitForJettyToStop(j);
       }
     }
+    
+    Thread.sleep(1000);
 
-    cluster.waitForAllNodes(30);
     waitForState("Timed out waiting for replicas of collection to be 2 again",
         collectionName, clusterShape(1, 2));
 
@@ -221,6 +229,6 @@ public class ExecutePlanActionTest extends SolrCloudTestCase {
     docCollection = clusterState.getCollection(collectionName);
     List<Replica> replicasOnSurvivor = docCollection.getReplicas(survivor.getNodeName());
     assertNotNull(replicasOnSurvivor);
-    assertEquals(2, replicasOnSurvivor.size());
+    assertEquals(docCollection.toString(), 2, replicasOnSurvivor.size());
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/HdfsAutoAddReplicasIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/HdfsAutoAddReplicasIntegrationTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/HdfsAutoAddReplicasIntegrationTest.java
index cedf713..72d3c32 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/HdfsAutoAddReplicasIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/HdfsAutoAddReplicasIntegrationTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.solr.cloud.autoscaling;
 
+import com.carrotsearch.randomizedtesting.annotations.Nightly;
 import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
 import org.apache.hadoop.hdfs.MiniDFSCluster;
 import org.apache.lucene.util.LuceneTestCase;
@@ -33,6 +34,7 @@ import org.junit.BeforeClass;
     MoveReplicaHDFSTest.ForkJoinThreadsFilter.class
 })
 //commented 23-AUG-2018 @LuceneTestCase.BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // added 20-Jul-2018
+@Nightly
 public class HdfsAutoAddReplicasIntegrationTest extends AutoAddReplicasIntegrationTest {
 
   private static MiniDFSCluster dfsCluster;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/HttpTriggerListenerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/HttpTriggerListenerTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/HttpTriggerListenerTest.java
index eeb1a87..26c13b0 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/HttpTriggerListenerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/HttpTriggerListenerTest.java
@@ -114,6 +114,7 @@ public class HttpTriggerListenerTest extends SolrCloudTestCase {
     assertEquals(requests.toString(), 0, requests.size());
 
     cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     boolean await = triggerFiredLatch.await(20, TimeUnit.SECONDS);
     assertTrue("The trigger did not fire at all", await);
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/IndexSizeTriggerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/IndexSizeTriggerTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/IndexSizeTriggerTest.java
index ec2315d..ce22430 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/IndexSizeTriggerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/IndexSizeTriggerTest.java
@@ -142,14 +142,19 @@ public class IndexSizeTriggerTest extends SolrCloudTestCase {
   }
 
   @Test
-  //@BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 05-Jul-2018
+  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028")
   public void testTrigger() throws Exception {
     String collectionName = "testTrigger_collection";
     CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(collectionName,
         "conf", 2, 2).setMaxShardsPerNode(2);
     create.process(solrClient);
-    CloudTestUtils.waitForState(cloudManager, "failed to create " + collectionName, collectionName,
-        CloudTestUtils.clusterShape(2, 2, false, true));
+    
+    if (SPEED == 1) {
+      cluster.waitForActiveCollection(collectionName, 2, 4);
+    } else {
+      CloudTestUtils.waitForState(cloudManager, "failed to create " + collectionName, collectionName,
+          CloudTestUtils.clusterShape(2, 2, false, true));
+    }
 
     long waitForSeconds = 3 + random().nextInt(5);
     Map<String, Object> props = createTriggerProps(waitForSeconds);
@@ -243,16 +248,21 @@ public class IndexSizeTriggerTest extends SolrCloudTestCase {
   }
 
   @Test
-  //@BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 05-Jul-2018
+  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028")
   public void testSplitIntegration() throws Exception {
     String collectionName = "testSplitIntegration_collection";
     CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(collectionName,
         "conf", 2, 2).setMaxShardsPerNode(2);
     create.process(solrClient);
-    CloudTestUtils.waitForState(cloudManager, "failed to create " + collectionName, collectionName,
-        CloudTestUtils.clusterShape(2, 2, false, true));
+    
+    if (SPEED == 1) {
+      cluster.waitForActiveCollection(collectionName, 2, 4);
+    } else {
+      CloudTestUtils.waitForState(cloudManager, "failed to create " + collectionName, collectionName,
+          CloudTestUtils.clusterShape(2, 2, false, true));
+    }
 
-    long waitForSeconds = 3 + random().nextInt(5);
+    long waitForSeconds = 6 + random().nextInt(5);
     // add disabled trigger
     String setTriggerCommand = "{" +
         "'set-trigger' : {" +
@@ -316,7 +326,7 @@ public class IndexSizeTriggerTest extends SolrCloudTestCase {
 
     timeSource.sleep(TimeUnit.MILLISECONDS.convert(waitForSeconds + 1, TimeUnit.SECONDS));
 
-    boolean await = finished.await(60000 / SPEED, TimeUnit.MILLISECONDS);
+    boolean await = finished.await(60000, TimeUnit.MILLISECONDS);
     assertTrue("did not finish processing in time", await);
     CloudTestUtils.waitForState(cloudManager, collectionName, 20, TimeUnit.SECONDS, CloudTestUtils.clusterShape(6, 2, true, true));
     assertEquals(1, listenerEvents.size());
@@ -350,20 +360,31 @@ public class IndexSizeTriggerTest extends SolrCloudTestCase {
         fail("unexpected shard name " + p.second());
       }
     }
-    assertTrue("shard1 should be split", shard1);
-    assertTrue("shard2 should be split", shard2);
+
+    
+    if (events.size() == 6) {
+      assertTrue("shard1 should be split", shard1);
+      assertTrue("shard2 should be split", shard2);
+    } else {
+      assertTrue("shard1 or shard2 should be split", shard1 || shard2);
+    }
 
   }
 
   @Test
-  //@BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 05-Jul-2018
+  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028")
   public void testMergeIntegration() throws Exception {
     String collectionName = "testMergeIntegration_collection";
     CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(collectionName,
         "conf", 2, 2).setMaxShardsPerNode(2);
     create.process(solrClient);
-    CloudTestUtils.waitForState(cloudManager, "failed to create " + collectionName, collectionName,
-        CloudTestUtils.clusterShape(2, 2, false, true));
+    
+    if (SPEED == 1) {
+      cluster.waitForActiveCollection(collectionName, 2, 4);
+    } else {
+      CloudTestUtils.waitForState(cloudManager, "failed to create " + collectionName, collectionName,
+          CloudTestUtils.clusterShape(2, 2, false, true));
+    }
 
     for (int i = 0; i < 20; i++) {
       SolrInputDocument doc = new SolrInputDocument("id", "id-" + (i * 100));
@@ -467,6 +488,7 @@ public class IndexSizeTriggerTest extends SolrCloudTestCase {
 
   @Test
   //@BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 05-Jul-2018
+  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028")
   public void testMixedBounds() throws Exception {
 
     String collectionName = "testMixedBounds_collection";
@@ -686,14 +708,20 @@ public class IndexSizeTriggerTest extends SolrCloudTestCase {
   }
 
   @Test
+  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028")
   public void testMaxOps() throws Exception {
     String collectionName = "testMaxOps_collection";
     CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(collectionName,
         "conf", 5, 2).setMaxShardsPerNode(10);
     create.process(solrClient);
-    CloudTestUtils.waitForState(cloudManager, "failed to create " + collectionName, collectionName,
-        CloudTestUtils.clusterShape(5, 2, false, true));
-
+    
+    if (SPEED == 1) {
+      cluster.waitForActiveCollection(collectionName, 5, 10);
+    } else {
+      CloudTestUtils.waitForState(cloudManager, "failed to create " + collectionName, collectionName,
+          CloudTestUtils.clusterShape(5, 2, false, true));
+    }
+    
     long waitForSeconds = 3 + random().nextInt(5);
     // add disabled trigger
     String setTriggerCommand = "{" +

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/MetricTriggerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/MetricTriggerIntegrationTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/MetricTriggerIntegrationTest.java
index a9aac97..a562633 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/MetricTriggerIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/MetricTriggerIntegrationTest.java
@@ -84,8 +84,6 @@ public class MetricTriggerIntegrationTest extends SolrCloudTestCase {
   // commented 4-Sep-2018 @LuceneTestCase.BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 2-Aug-2018
   @BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 14-Oct-2018
   public void testMetricTrigger() throws Exception {
-    cluster.waitForAllNodes(5);
-
     String collectionName = "testMetricTrigger";
     CloudSolrClient solrClient = cluster.getSolrClient();
     CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(collectionName,
@@ -93,7 +91,7 @@ public class MetricTriggerIntegrationTest extends SolrCloudTestCase {
     create.process(solrClient);
     solrClient.setDefaultCollection(collectionName);
 
-    waitForState("Timed out waiting for collection:" + collectionName + " to become active", collectionName, clusterShape(2, 2));
+    cluster.waitForActiveCollection(collectionName, 2, 4);
 
     DocCollection docCollection = solrClient.getZkStateReader().getClusterState().getCollection(collectionName);
     String shardId = "shard1";

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/MetricTriggerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/MetricTriggerTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/MetricTriggerTest.java
index f0f9f07..2e195fb 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/MetricTriggerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/MetricTriggerTest.java
@@ -53,6 +53,7 @@ public class MetricTriggerTest extends SolrCloudTestCase {
     CloudSolrClient solrClient = cluster.getSolrClient();
     create.setMaxShardsPerNode(1);
     create.process(solrClient);
+    cluster.waitForActiveCollection(DEFAULT_TEST_COLLECTION_NAME, 1, 1);
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeAddedTriggerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeAddedTriggerIntegrationTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeAddedTriggerIntegrationTest.java
index ddc56ec..795c530 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeAddedTriggerIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeAddedTriggerIntegrationTest.java
@@ -40,6 +40,7 @@ import org.apache.solr.common.util.Utils;
 import org.apache.solr.util.LogLevel;
 import org.apache.solr.util.TimeOut;
 import org.apache.zookeeper.data.Stat;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -65,6 +66,20 @@ public class NodeAddedTriggerIntegrationTest extends SolrCloudTestCase {
 
   @BeforeClass
   public static void setupCluster() throws Exception {
+
+  }
+  
+  @After 
+  public void after() throws Exception {
+    shutdownCluster();
+  }
+
+  private static CountDownLatch getTriggerFiredLatch() {
+    return triggerFiredLatch;
+  }
+
+  @Before
+  public void setupTest() throws Exception {
     configureCluster(2)
         .addConfig("conf", configset("cloud-minimal"))
         .configure();
@@ -76,27 +91,6 @@ public class NodeAddedTriggerIntegrationTest extends SolrCloudTestCase {
     SolrClient solrClient = cluster.getSolrClient();
     NamedList<Object> response = solrClient.request(req);
     assertEquals(response.get("result").toString(), "success");
-  }
-
-  private static CountDownLatch getTriggerFiredLatch() {
-    return triggerFiredLatch;
-  }
-
-  @Before
-  public void setupTest() throws Exception {
-    // ensure that exactly 2 jetty nodes are running
-    int numJetties = cluster.getJettySolrRunners().size();
-    log.info("Found {} jetty instances running", numJetties);
-    for (int i = 2; i < numJetties; i++) {
-      int r = random().nextInt(cluster.getJettySolrRunners().size());
-      log.info("Shutdown extra jetty instance at port {}", cluster.getJettySolrRunner(r).getLocalPort());
-      cluster.stopJettySolrRunner(r);
-    }
-    for (int i = cluster.getJettySolrRunners().size(); i < 2; i++) {
-      // start jetty instances
-      cluster.startJettySolrRunner();
-    }
-    cluster.waitForAllNodes(5);
 
     NamedList<Object> overSeerStatus = cluster.getSolrClient().request(CollectionAdminRequest.getOverseerStatus());
     String overseerLeader = (String) overSeerStatus.get("leader");
@@ -117,14 +111,8 @@ public class NodeAddedTriggerIntegrationTest extends SolrCloudTestCase {
     Stat stat = zkClient().setData(SOLR_AUTOSCALING_CONF_PATH, Utils.toJSON(new ZkNodeProps()), true);
     log.info(SOLR_AUTOSCALING_CONF_PATH + " reset, new znode version {}", stat.getVersion());
 
-    cluster.deleteAllCollections();
     cluster.getSolrClient().setDefaultCollection(null);
 
-    // restart Overseer. Even though we reset the autoscaling config some already running
-    // trigger threads may still continue to execute and produce spurious events
-    cluster.stopJettySolrRunner(overseerLeaderIndex);
-    Thread.sleep(5000);
-
     waitForSeconds = 1 + random().nextInt(3);
     actionConstructorCalled = new CountDownLatch(1);
     actionInitCalled = new CountDownLatch(1);
@@ -132,12 +120,6 @@ public class NodeAddedTriggerIntegrationTest extends SolrCloudTestCase {
     triggerFired = new AtomicBoolean(false);
     events.clear();
 
-    while (cluster.getJettySolrRunners().size() < 2) {
-      // perhaps a test stopped a node but didn't start it back
-      // lets start a node
-      cluster.startJettySolrRunner();
-    }
-
     cloudManager = cluster.getJettySolrRunner(0).getCoreContainer().getZkController().getSolrCloudManager();
     // clear any events or markers
     // todo: consider the impact of such cleanup on regular cluster restarts
@@ -178,6 +160,8 @@ public class NodeAddedTriggerIntegrationTest extends SolrCloudTestCase {
 
     // start a new node
     JettySolrRunner newNode = cluster.startJettySolrRunner();
+    
+    cluster.waitForAllNodes(30);
 
     // ensure that the old trigger sees the new node, todo find a better way to do this
     Thread.sleep(500 + TimeUnit.SECONDS.toMillis(DEFAULT_SCHEDULED_TRIGGER_DELAY_SECONDS));
@@ -229,6 +213,7 @@ public class NodeAddedTriggerIntegrationTest extends SolrCloudTestCase {
     }
 
     JettySolrRunner newNode = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(15);
     boolean await = triggerFiredLatch.await(20, TimeUnit.SECONDS);
     assertTrue("The trigger did not fire at all", await);
     assertTrue(triggerFired.get());

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeAddedTriggerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeAddedTriggerTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeAddedTriggerTest.java
index a186a6c..8a78520 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeAddedTriggerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeAddedTriggerTest.java
@@ -33,6 +33,7 @@ import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.core.SolrResourceLoader;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -56,9 +57,7 @@ public class NodeAddedTriggerTest extends SolrCloudTestCase {
 
   @BeforeClass
   public static void setupCluster() throws Exception {
-    configureCluster(1)
-        .addConfig("conf", configset("cloud-minimal"))
-        .configure();
+
   }
 
   @Before
@@ -66,6 +65,14 @@ public class NodeAddedTriggerTest extends SolrCloudTestCase {
     actionConstructorCalled = new AtomicBoolean(false);
     actionInitCalled = new AtomicBoolean(false);
     actionCloseCalled = new AtomicBoolean(false);
+    configureCluster(1)
+    .addConfig("conf", configset("cloud-minimal"))
+    .configure();
+  }
+  
+  @After
+  public void afterTest() throws Exception {
+    shutdownCluster();
   }
 
   @Test
@@ -82,6 +89,9 @@ public class NodeAddedTriggerTest extends SolrCloudTestCase {
 
       JettySolrRunner newNode1 = cluster.startJettySolrRunner();
       JettySolrRunner newNode2 = cluster.startJettySolrRunner();
+      
+      cluster.waitForAllNodes(30);
+      
       AtomicBoolean fired = new AtomicBoolean(false);
       AtomicReference<TriggerEvent> eventRef = new AtomicReference<>();
       trigger.setProcessor(event -> {
@@ -254,6 +264,7 @@ public class NodeAddedTriggerTest extends SolrCloudTestCase {
     trigger.run();
 
     JettySolrRunner newNode = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     trigger.setProcessor(null); // the processor may get called for old nodes
     trigger.run(); // this run should detect the new node
     trigger.close(); // close the old trigger

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeLostTriggerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeLostTriggerIntegrationTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeLostTriggerIntegrationTest.java
index b756dcd..744f1da 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeLostTriggerIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeLostTriggerIntegrationTest.java
@@ -40,6 +40,7 @@ import org.apache.solr.common.util.Utils;
 import org.apache.solr.util.LogLevel;
 import org.apache.solr.util.TimeOut;
 import org.apache.zookeeper.data.Stat;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -65,17 +66,7 @@ public class NodeLostTriggerIntegrationTest extends SolrCloudTestCase {
 
   @BeforeClass
   public static void setupCluster() throws Exception {
-    configureCluster(2)
-        .addConfig("conf", configset("cloud-minimal"))
-        .configure();
-    // disable .scheduled_maintenance
-    String suspendTriggerCommand = "{" +
-        "'suspend-trigger' : {'name' : '.scheduled_maintenance'}" +
-        "}";
-    SolrRequest req = createAutoScalingRequest(SolrRequest.METHOD.POST, suspendTriggerCommand);
-    SolrClient solrClient = cluster.getSolrClient();
-    NamedList<Object> response = solrClient.request(req);
-    assertEquals(response.get("result").toString(), "success");
+ 
   }
 
   private static CountDownLatch getTriggerFiredLatch() {
@@ -84,19 +75,19 @@ public class NodeLostTriggerIntegrationTest extends SolrCloudTestCase {
 
   @Before
   public void setupTest() throws Exception {
-    // ensure that exactly 2 jetty nodes are running
-    int numJetties = cluster.getJettySolrRunners().size();
-    log.info("Found {} jetty instances running", numJetties);
-    for (int i = 2; i < numJetties; i++) {
-      int r = random().nextInt(cluster.getJettySolrRunners().size());
-      log.info("Shutdown extra jetty instance at port {}", cluster.getJettySolrRunner(r).getLocalPort());
-      cluster.stopJettySolrRunner(r);
-    }
-    for (int i = cluster.getJettySolrRunners().size(); i < 2; i++) {
-      // start jetty instances
-      cluster.startJettySolrRunner();
-    }
-    cluster.waitForAllNodes(5);
+    
+    configureCluster(4)
+    .addConfig("conf", configset("cloud-minimal"))
+    .configure();
+    
+    // disable .scheduled_maintenance
+    String suspendTriggerCommand = "{" +
+        "'suspend-trigger' : {'name' : '.scheduled_maintenance'}" +
+        "}";
+    SolrRequest req = createAutoScalingRequest(SolrRequest.METHOD.POST, suspendTriggerCommand);
+    SolrClient solrClient = cluster.getSolrClient();
+    NamedList<Object> response = solrClient.request(req);
+    assertEquals(response.get("result").toString(), "success");
 
     NamedList<Object> overSeerStatus = cluster.getSolrClient().request(CollectionAdminRequest.getOverseerStatus());
     String overseerLeader = (String) overSeerStatus.get("leader");
@@ -117,13 +108,9 @@ public class NodeLostTriggerIntegrationTest extends SolrCloudTestCase {
     Stat stat = zkClient().setData(SOLR_AUTOSCALING_CONF_PATH, Utils.toJSON(new ZkNodeProps()), true);
     log.info(SOLR_AUTOSCALING_CONF_PATH + " reset, new znode version {}", stat.getVersion());
 
-    cluster.deleteAllCollections();
+
     cluster.getSolrClient().setDefaultCollection(null);
 
-    // restart Overseer. Even though we reset the autoscaling config some already running
-    // trigger threads may still continue to execute and produce spurious events
-    cluster.stopJettySolrRunner(overseerLeaderIndex);
-    Thread.sleep(5000);
 
     waitForSeconds = 1 + random().nextInt(3);
     actionConstructorCalled = new CountDownLatch(1);
@@ -132,12 +119,6 @@ public class NodeLostTriggerIntegrationTest extends SolrCloudTestCase {
     triggerFired = new AtomicBoolean(false);
     events.clear();
 
-    while (cluster.getJettySolrRunners().size() < 2) {
-      // perhaps a test stopped a node but didn't start it back
-      // lets start a node
-      cluster.startJettySolrRunner();
-    }
-
     cloudManager = cluster.getJettySolrRunner(0).getCoreContainer().getZkController().getSolrCloudManager();
     // clear any events or markers
     // todo: consider the impact of such cleanup on regular cluster restarts
@@ -146,6 +127,11 @@ public class NodeLostTriggerIntegrationTest extends SolrCloudTestCase {
     deleteChildrenRecursively(ZkStateReader.SOLR_AUTOSCALING_NODE_LOST_PATH);
     deleteChildrenRecursively(ZkStateReader.SOLR_AUTOSCALING_NODE_ADDED_PATH);
   }
+  
+  @After
+  public void cleanUpTest() throws Exception {
+    shutdownCluster();
+  }
 
   private void deleteChildrenRecursively(String path) throws Exception {
     cloudManager.getDistribStateManager().removeRecursively(path, true, false);
@@ -187,7 +173,8 @@ public class NodeLostTriggerIntegrationTest extends SolrCloudTestCase {
       if (runner == newNode) index = i;
     }
     assertFalse(index == -1);
-    cluster.stopJettySolrRunner(index);
+    JettySolrRunner j = cluster.stopJettySolrRunner(index);
+    cluster.waitForJettyToStop(j);
 
     // ensure that the old trigger sees the stopped node, todo find a better way to do this
     Thread.sleep(500 + TimeUnit.SECONDS.toMillis(DEFAULT_SCHEDULED_TRIGGER_DELAY_SECONDS));
@@ -250,7 +237,8 @@ public class NodeLostTriggerIntegrationTest extends SolrCloudTestCase {
     triggerFired.set(false);
     triggerFiredLatch = new CountDownLatch(1);
     String lostNodeName = cluster.getJettySolrRunner(nonOverseerLeaderIndex).getNodeName();
-    cluster.stopJettySolrRunner(nonOverseerLeaderIndex);
+    JettySolrRunner j = cluster.stopJettySolrRunner(nonOverseerLeaderIndex);
+    cluster.waitForJettyToStop(j);
     boolean await = triggerFiredLatch.await(20, TimeUnit.SECONDS);
     assertTrue("The trigger did not fire at all", await);
     assertTrue(triggerFired.get());

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeLostTriggerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeLostTriggerTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeLostTriggerTest.java
index 0f9a348..ebe5081 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeLostTriggerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeLostTriggerTest.java
@@ -30,11 +30,12 @@ import java.util.concurrent.atomic.AtomicReference;
 import org.apache.solr.client.solrj.cloud.SolrCloudManager;
 import org.apache.solr.client.solrj.embedded.JettySolrRunner;
 import org.apache.solr.cloud.SolrCloudTestCase;
-import org.apache.solr.core.CoreContainer;
 import org.apache.solr.common.util.TimeSource;
+import org.apache.solr.core.CoreContainer;
 import org.apache.solr.core.SolrResourceLoader;
+import org.apache.solr.util.TimeOut;
+import org.junit.After;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
@@ -55,11 +56,9 @@ public class NodeLostTriggerTest extends SolrCloudTestCase {
   // currentTimeMillis is not as precise so to avoid false positives while comparing time of fire, we add some delta
   private static final long WAIT_FOR_DELTA_NANOS = TimeUnit.MILLISECONDS.toNanos(5);
 
-  @BeforeClass
-  public static void setupCluster() throws Exception {
-    configureCluster(5)
-        .addConfig("conf", configset("cloud-minimal"))
-        .configure();
+  @After
+  public void tearDownCluster() throws Exception {
+    shutdownCluster();
   }
 
   @Before
@@ -67,10 +66,17 @@ public class NodeLostTriggerTest extends SolrCloudTestCase {
     actionConstructorCalled = new AtomicBoolean(false);
     actionInitCalled = new AtomicBoolean(false);
     actionCloseCalled = new AtomicBoolean(false);
+    
+    configureCluster(3)
+    .addConfig("conf", configset("cloud-minimal"))
+    .configure();
   }
 
   @Test
   public void testTrigger() throws Exception {
+    cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
+    
     CoreContainer container = cluster.getJettySolrRunners().get(0).getCoreContainer();
     long waitForSeconds = 1 + random().nextInt(5);
     Map<String, Object> props = createTriggerProps(waitForSeconds);
@@ -81,9 +87,11 @@ public class NodeLostTriggerTest extends SolrCloudTestCase {
       trigger.setProcessor(noFirstRunProcessor);
       trigger.run();
       String lostNodeName1 = cluster.getJettySolrRunner(1).getNodeName();
-      cluster.stopJettySolrRunner(1);
+      JettySolrRunner j = cluster.stopJettySolrRunner(1);
+      cluster.waitForJettyToStop(j);
       String lostNodeName2 = cluster.getJettySolrRunner(1).getNodeName();
-      cluster.stopJettySolrRunner(1);
+      j = cluster.stopJettySolrRunner(1);
+      cluster.waitForJettyToStop(j);
       Thread.sleep(1000);
 
       AtomicBoolean fired = new AtomicBoolean(false);
@@ -130,6 +138,7 @@ public class NodeLostTriggerTest extends SolrCloudTestCase {
       trigger.run();
 
       JettySolrRunner lostNode = cluster.getJettySolrRunner(1);
+      String lostNodeName = lostNode.getNodeName();
       lostNode.stop();
       AtomicBoolean fired = new AtomicBoolean(false);
       trigger.setProcessor(event -> {
@@ -148,7 +157,7 @@ public class NodeLostTriggerTest extends SolrCloudTestCase {
       trigger.run(); // first run should detect the lost node
       int counter = 0;
       do {
-        if (container.getZkController().getZkStateReader().getClusterState().getLiveNodes().size() == 2) {
+        if (!container.getZkController().getZkStateReader().getClusterState().getLiveNodes().contains(lostNodeName)) {
           break;
         }
         Thread.sleep(100);
@@ -226,28 +235,24 @@ public class NodeLostTriggerTest extends SolrCloudTestCase {
   @Test
   //28-June-2018 @BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 16-Apr-2018
   public void testListenerAcceptance() throws Exception {
+
     CoreContainer container = cluster.getJettySolrRunners().get(0).getCoreContainer();
     Map<String, Object> props = createTriggerProps(0);
+
     try (NodeLostTrigger trigger = new NodeLostTrigger("node_added_trigger")) {
       trigger.configure(container.getResourceLoader(), container.getZkController().getSolrCloudManager(), props);
       trigger.init();
       trigger.setProcessor(noFirstRunProcessor);
 
       JettySolrRunner newNode = cluster.startJettySolrRunner();
-      cluster.waitForAllNodes(5);
 
+      cluster.waitForAllNodes(30);
+      
       trigger.run(); // starts tracking live nodes
-
+      
       // stop the newly created node
-      List<JettySolrRunner> jettySolrRunners = cluster.getJettySolrRunners();
-      for (int i = 0; i < jettySolrRunners.size(); i++) {
-        JettySolrRunner jettySolrRunner = jettySolrRunners.get(i);
-        if (newNode == jettySolrRunner) {
-          cluster.stopJettySolrRunner(i);
-          break;
-        }
-      }
-      cluster.waitForAllNodes(5);
+      newNode.stop();
+      cluster.waitForJettyToStop(newNode);
 
       AtomicInteger callCount = new AtomicInteger(0);
       AtomicBoolean fired = new AtomicBoolean(false);
@@ -261,10 +266,17 @@ public class NodeLostTriggerTest extends SolrCloudTestCase {
         }
       });
 
+      Thread.sleep(1000);
+      
       trigger.run(); // first run should detect the lost node and fire immediately but listener isn't ready
+      
+      TimeOut timeout = new TimeOut(5, TimeUnit.SECONDS, TimeSource.NANO_TIME);
+      timeout.waitFor("Timeout waiting for callCount to hit at least 1", () -> callCount.get() >= 1);
       assertEquals(1, callCount.get());
       assertFalse(fired.get());
       trigger.run(); // second run should again fire
+      timeout = new TimeOut(5, TimeUnit.SECONDS, TimeSource.NANO_TIME);
+      timeout.waitFor("Timeout waiting for callCount to hit at least 2", () -> callCount.get() >= 2);
       assertEquals(2, callCount.get());
       assertTrue(fired.get());
       trigger.run(); // should not fire
@@ -279,6 +291,7 @@ public class NodeLostTriggerTest extends SolrCloudTestCase {
     Map<String, Object> props = createTriggerProps(waitForSeconds);
 
     JettySolrRunner newNode = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     String lostNodeName = newNode.getNodeName();
 
     // remove a node but update the trigger before the waitFor period expires
@@ -295,7 +308,8 @@ public class NodeLostTriggerTest extends SolrCloudTestCase {
     for (int i = 0; i < jettySolrRunners.size(); i++) {
       JettySolrRunner jettySolrRunner = jettySolrRunners.get(i);
       if (newNode == jettySolrRunner) {
-        cluster.stopJettySolrRunner(i);
+        JettySolrRunner j = cluster.stopJettySolrRunner(i);
+        cluster.waitForJettyToStop(j);
         break;
       }
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeMarkersRegistrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeMarkersRegistrationTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeMarkersRegistrationTest.java
index b4ad3d5..7a8fa53 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeMarkersRegistrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/NodeMarkersRegistrationTest.java
@@ -17,6 +17,8 @@
 
 package org.apache.solr.cloud.autoscaling;
 
+import static org.apache.solr.cloud.autoscaling.AutoScalingHandlerTest.createAutoScalingRequest;
+
 import java.lang.invoke.MethodHandles;
 import java.util.HashSet;
 import java.util.List;
@@ -25,6 +27,7 @@ import java.util.SortedSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.solr.client.solrj.SolrClient;
@@ -38,26 +41,28 @@ import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.common.cloud.LiveNodesListener;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.util.LogLevel;
-import org.junit.BeforeClass;
+import org.apache.solr.util.TimeOut;
+import org.apache.zookeeper.KeeperException;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.solr.cloud.autoscaling.AutoScalingHandlerTest.createAutoScalingRequest;
-
 @LogLevel("org.apache.solr.cloud.autoscaling=DEBUG;org.apache.solr.client.solrj.cloud.autoscaling=DEBUG")
 public class NodeMarkersRegistrationTest extends SolrCloudTestCase {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  private static CountDownLatch triggerFiredLatch;
-  private static CountDownLatch listenerEventLatch;
+  private static volatile CountDownLatch triggerFiredLatch;
+  private static volatile CountDownLatch listenerEventLatch;
   private static Set<TriggerEvent> events = ConcurrentHashMap.newKeySet();
-  private static ZkStateReader zkStateReader;
-  private static ReentrantLock lock = new ReentrantLock();
+  private volatile ZkStateReader zkStateReader;
+  private static final ReentrantLock lock = new ReentrantLock();
 
-  @BeforeClass
-  public static void setupCluster() throws Exception {
+  @Before
+  public void setupCluster() throws Exception {
     configureCluster(2)
         .addConfig("conf", configset("cloud-minimal"))
         .configure();
@@ -71,6 +76,11 @@ public class NodeMarkersRegistrationTest extends SolrCloudTestCase {
     NamedList<Object> response = solrClient.request(req);
     assertEquals(response.get("result").toString(), "success");
   }
+  
+  @After
+  public void teardownCluster() throws Exception {
+    shutdownCluster();
+  }
 
   private static CountDownLatch getTriggerFiredLatch() {
     return triggerFiredLatch;
@@ -94,6 +104,7 @@ public class NodeMarkersRegistrationTest extends SolrCloudTestCase {
     }
     // add a node
     JettySolrRunner node = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     if (!listener.onChangeLatch.await(10, TimeUnit.SECONDS)) {
       fail("onChange listener didn't execute on cluster change");
     }
@@ -105,18 +116,39 @@ public class NodeMarkersRegistrationTest extends SolrCloudTestCase {
     listener.reset();
     // stop overseer
     log.info("====== KILL OVERSEER 1");
-    cluster.stopJettySolrRunner(overseerLeaderIndex);
+    JettySolrRunner j = cluster.stopJettySolrRunner(overseerLeaderIndex);
+    cluster.waitForJettyToStop(j);
     if (!listener.onChangeLatch.await(10, TimeUnit.SECONDS)) {
       fail("onChange listener didn't execute on cluster change");
     }
-    assertEquals(1, listener.lostNodes.size());
-    assertEquals(overseerLeader, listener.lostNodes.iterator().next());
+
     assertEquals(0, listener.addedNodes.size());
     // wait until the new overseer is up
     Thread.sleep(5000);
+    
+    assertEquals(1, listener.lostNodes.size());
+    assertEquals(overseerLeader, listener.lostNodes.iterator().next());
+    
+    
+    String pathLost = ZkStateReader.SOLR_AUTOSCALING_NODE_LOST_PATH + "/" + overseerLeader;
+    
+    TimeOut timeout = new TimeOut(30, TimeUnit.SECONDS, TimeSource.NANO_TIME);
+    try {
+      timeout.waitFor("zk path to go away", () -> {
+        try {
+          return !zkClient().exists(pathLost, true);
+        } catch (KeeperException e) {
+          throw new RuntimeException(e);
+        } catch (InterruptedException e) {
+          return false;
+        }
+      });
+    } catch (TimeoutException e) {
+      // okay
+    }
+
     // verify that a znode does NOT exist - there's no nodeLost trigger,
     // so the new overseer cleaned up existing nodeLost markers
-    String pathLost = ZkStateReader.SOLR_AUTOSCALING_NODE_LOST_PATH + "/" + overseerLeader;
     assertFalse("Path " + pathLost + " exists", zkClient().exists(pathLost, true));
 
     listener.reset();
@@ -175,6 +207,7 @@ public class NodeMarkersRegistrationTest extends SolrCloudTestCase {
     // create another node
     log.info("====== ADD NODE 1");
     JettySolrRunner node1 = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     if (!listener.onChangeLatch.await(10, TimeUnit.SECONDS)) {
       fail("onChange listener didn't execute on cluster change");
     }
@@ -219,8 +252,8 @@ public class NodeMarkersRegistrationTest extends SolrCloudTestCase {
   }
 
   private static class TestLiveNodesListener implements LiveNodesListener {
-    Set<String> lostNodes = new HashSet<>();
-    Set<String> addedNodes = new HashSet<>();
+    Set<String> lostNodes = ConcurrentHashMap.newKeySet();
+    Set<String> addedNodes = ConcurrentHashMap.newKeySet();
     CountDownLatch onChangeLatch = new CountDownLatch(1);
 
     public void reset() {
@@ -230,7 +263,7 @@ public class NodeMarkersRegistrationTest extends SolrCloudTestCase {
     }
 
     @Override
-    public void onChange(SortedSet<String> oldLiveNodes, SortedSet<String> newLiveNodes) {
+    public boolean onChange(SortedSet<String> oldLiveNodes, SortedSet<String> newLiveNodes) {
       onChangeLatch.countDown();
       Set<String> old = new HashSet<>(oldLiveNodes);
       old.removeAll(newLiveNodes);
@@ -241,6 +274,7 @@ public class NodeMarkersRegistrationTest extends SolrCloudTestCase {
       if (!newLiveNodes.isEmpty()) {
         addedNodes.addAll(newLiveNodes);
       }
+      return false;
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/RestoreTriggerStateTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/RestoreTriggerStateTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/RestoreTriggerStateTest.java
index 4949e6f..3088424 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/RestoreTriggerStateTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/RestoreTriggerStateTest.java
@@ -111,6 +111,7 @@ public class RestoreTriggerStateTest extends SolrCloudTestCase {
     events.clear();
 
     JettySolrRunner newNode = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     boolean await = triggerFiredLatch.await(20, TimeUnit.SECONDS);
     assertTrue("The trigger did not fire at all", await);
     assertTrue(triggerFired.get());
@@ -125,7 +126,8 @@ public class RestoreTriggerStateTest extends SolrCloudTestCase {
     JettySolrRunner newNode2 = cluster.startJettySolrRunner();
     Thread.sleep(10000);
     // kill overseer leader
-    cluster.stopJettySolrRunner(overseerLeaderIndex);
+    JettySolrRunner j = cluster.stopJettySolrRunner(overseerLeaderIndex);
+    cluster.waitForJettyToStop(j);
     await = triggerFiredLatch.await(20, TimeUnit.SECONDS);
     assertTrue("The trigger did not fire at all", await);
     assertTrue(triggerFired.get());

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledMaintenanceTriggerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledMaintenanceTriggerTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledMaintenanceTriggerTest.java
index b51d216..75a0d3f 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledMaintenanceTriggerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledMaintenanceTriggerTest.java
@@ -161,7 +161,7 @@ public class ScheduledMaintenanceTriggerTest extends SolrCloudTestCase {
   }
 
   @Test
-  @BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 17-Mar-2018
+  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 17-Mar-2018
   public void testInactiveShardCleanup() throws Exception {
     String collection1 = getClass().getSimpleName() + "_collection1";
     CollectionAdminRequest.Create create1 = CollectionAdminRequest.createCollection(collection1,

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledTriggerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledTriggerIntegrationTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledTriggerIntegrationTest.java
index ff0223b..ff27dd3 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledTriggerIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledTriggerIntegrationTest.java
@@ -17,6 +17,8 @@
 
 package org.apache.solr.cloud.autoscaling;
 
+import static org.apache.solr.cloud.autoscaling.AutoScalingHandlerTest.createAutoScalingRequest;
+
 import java.lang.invoke.MethodHandles;
 import java.util.Date;
 import java.util.List;
@@ -36,13 +38,12 @@ import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.util.LogLevel;
-import org.junit.BeforeClass;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.solr.cloud.autoscaling.AutoScalingHandlerTest.createAutoScalingRequest;
-
 /**
  * Integration test for {@link ScheduledTrigger}
  */
@@ -55,8 +56,8 @@ public class ScheduledTriggerIntegrationTest extends SolrCloudTestCase {
   private static Set<TriggerEvent> events = ConcurrentHashMap.newKeySet();
   private static AtomicReference<Map<String, Object>> actionContextPropertiesRef = new AtomicReference<>();
 
-  @BeforeClass
-  public static void setupCluster() throws Exception {
+  @Before
+  public void setupCluster() throws Exception {
     configureCluster(2)
         .addConfig("conf", configset("cloud-minimal"))
         .configure();
@@ -70,6 +71,11 @@ public class ScheduledTriggerIntegrationTest extends SolrCloudTestCase {
     assertEquals(response.get("result").toString(), "success");
     triggerFiredLatch = new CountDownLatch(1);
   }
+  
+  @After
+  public void afterTest() throws Exception {
+    shutdownCluster();
+  }
 
   @Test
   // commented 15-Sep-2018 @LuceneTestCase.BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 2-Aug-2018
@@ -81,7 +87,8 @@ public class ScheduledTriggerIntegrationTest extends SolrCloudTestCase {
     String collectionName = "testScheduledTrigger";
     CollectionAdminRequest.createCollection(collectionName, 1, 3)
         .setMaxShardsPerNode(5).process(solrClient);
-    waitForState("", collectionName, clusterShape(1, 3));
+    
+    cluster.waitForActiveCollection(collectionName, 1, 3);
 
     // create a policy which allows only 1 core per node thereby creating a violation for the above collection
     String setClusterPolicy = "{\n" +
@@ -95,7 +102,7 @@ public class ScheduledTriggerIntegrationTest extends SolrCloudTestCase {
 
     // start a new node which can be used to balance the cluster as per policy
     JettySolrRunner newNode = cluster.startJettySolrRunner();
-    cluster.waitForAllNodes(10);
+    cluster.waitForAllNodes(30);
 
     String setTriggerCommand = "{" +
         "'set-trigger' : {" +
@@ -112,7 +119,7 @@ public class ScheduledTriggerIntegrationTest extends SolrCloudTestCase {
     response = solrClient.request(req);
     assertEquals(response.get("result").toString(), "success");
 
-    assertTrue("ScheduledTrigger did not fire within 20 seconds", triggerFiredLatch.await(20, TimeUnit.SECONDS));
+    assertTrue("ScheduledTrigger did not fire in time", triggerFiredLatch.await(45, TimeUnit.SECONDS));
     assertEquals(1, events.size());
     Map<String, Object> actionContextProps = actionContextPropertiesRef.get();
     assertNotNull(actionContextProps);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledTriggerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledTriggerTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledTriggerTest.java
index f4344cf..84c6df9 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledTriggerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/ScheduledTriggerTest.java
@@ -22,6 +22,7 @@ import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.temporal.ChronoField;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -56,9 +57,8 @@ public class ScheduledTriggerTest extends SolrCloudTestCase {
   }
 
   @Test
-//2018-06-18 (commented)   @BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 09-Apr-2018
-//commented 23-AUG-2018   @BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // added 20-Jul-2018
-  @BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // added 20-Sep-2018
+  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // added 20-Sep-2018
+  // this does not appear to be a good way to test this
   public void testTrigger() throws Exception {
     CoreContainer container = cluster.getJettySolrRunners().get(0).getCoreContainer();
 
@@ -77,6 +77,7 @@ public class ScheduledTriggerTest extends SolrCloudTestCase {
     scheduledTriggerTest(container, properties);
   }
 
+  @Test
   public void testIgnoredEvent() throws Exception {
     CoreContainer container = cluster.getJettySolrRunners().get(0).getCoreContainer();
     long threeDaysAgo = new Date().getTime() - TimeUnit.DAYS.toMillis(3);
@@ -102,7 +103,7 @@ public class ScheduledTriggerTest extends SolrCloudTestCase {
       scheduledTrigger.init();
       scheduledTrigger.setProcessor(noFirstRunProcessor);
       scheduledTrigger.run();
-      final List<Long> eventTimes = new ArrayList<>();
+      final List<Long> eventTimes = Collections.synchronizedList(new ArrayList<>());
       scheduledTrigger.setProcessor(event -> {
         eventTimes.add(event.getEventTime());
         return true;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/SearchRateTriggerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/SearchRateTriggerIntegrationTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/SearchRateTriggerIntegrationTest.java
index 6febdd3..76e4b83 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/SearchRateTriggerIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/SearchRateTriggerIntegrationTest.java
@@ -26,6 +26,7 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import com.carrotsearch.randomizedtesting.annotations.Nightly;
 import com.google.common.util.concurrent.AtomicDouble;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.solr.client.solrj.SolrClient;
@@ -66,6 +67,7 @@ import static org.apache.solr.common.cloud.ZkStateReader.SOLR_AUTOSCALING_CONF_P
  */
 @LogLevel("org.apache.solr.cloud.autoscaling=DEBUG;org.apache.solr.client.solrj.cloud.autoscaling=DEBUG")
 @LuceneTestCase.Slow
+@Nightly // this test is too long for non nightly right now
 public class SearchRateTriggerIntegrationTest extends SolrCloudTestCase {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/SearchRateTriggerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/SearchRateTriggerTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/SearchRateTriggerTest.java
index c39dec8..f750a5e 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/SearchRateTriggerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/SearchRateTriggerTest.java
@@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
 
 import com.codahale.metrics.MetricRegistry;
 import com.google.common.util.concurrent.AtomicDouble;
+
 import org.apache.solr.client.solrj.cloud.NodeStateProvider;
 import org.apache.solr.client.solrj.cloud.autoscaling.ReplicaInfo;
 import org.apache.solr.client.solrj.cloud.SolrCloudManager;
@@ -51,6 +52,7 @@ import org.apache.solr.core.CoreContainer;
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.util.TimeOut;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -70,21 +72,23 @@ public class SearchRateTriggerTest extends SolrCloudTestCase {
 
   @BeforeClass
   public static void setupCluster() throws Exception {
-    configureCluster(4)
-        .addConfig("conf", configset("cloud-minimal"))
-        .configure();
+
   }
 
   @Before
   public void removeCollections() throws Exception {
-    cluster.deleteAllCollections();
-    if (cluster.getJettySolrRunners().size() < 4) {
-      cluster.startJettySolrRunner();
-    }
+    configureCluster(4)
+    .addConfig("conf", configset("cloud-minimal"))
+    .configure();
+  }
+  
+  @After
+  public void after() throws Exception {
+    shutdownCluster();
   }
 
   @Test
-  // commented 4-Sep-2018 @LuceneTestCase.BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // 2018-06-18
+  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028")
   public void testTrigger() throws Exception {
     JettySolrRunner targetNode = cluster.getJettySolrRunner(0);
     SolrZkClient zkClient = cluster.getSolrClient().getZkStateReader().getZkClient();
@@ -123,7 +127,7 @@ public class SearchRateTriggerTest extends SolrCloudTestCase {
       String url = baseUrl.toString() + "/" + coreName;
       try (HttpSolrClient simpleClient = new HttpSolrClient.Builder(url).build()) {
         SolrParams query = params(CommonParams.Q, "*:*", CommonParams.DISTRIB, "false");
-        for (int i = 0; i < 500; i++) {
+        for (int i = 0; i < 130; i++) {
           simpleClient.query(query);
         }
         String registryCoreName = coreName.replaceFirst("_", ".").replaceFirst("_", ".");
@@ -149,10 +153,11 @@ public class SearchRateTriggerTest extends SolrCloudTestCase {
         assertTrue((Double)info.getVariable(AutoScalingParams.RATE) > rate);
       }
       // close that jetty to remove the violation - alternatively wait for 1 min...
-      cluster.stopJettySolrRunner(1);
+      JettySolrRunner j = cluster.stopJettySolrRunner(1);
+      cluster.waitForJettyToStop(j);
       events.clear();
       SolrParams query = params(CommonParams.Q, "*:*");
-      for (int i = 0; i < 500; i++) {
+      for (int i = 0; i < 130; i++) {
         solrClient.query(COLL1, query);
       }
       Thread.sleep(waitForSeconds * 1000);
@@ -167,7 +172,7 @@ public class SearchRateTriggerTest extends SolrCloudTestCase {
       assertTrue(Rate > rate);
       events.clear();
 
-      for (int i = 0; i < 1000; i++) {
+      for (int i = 0; i < 150; i++) {
         solrClient.query(COLL2, query);
         solrClient.query(COLL1, query);
       }
@@ -233,7 +238,7 @@ public class SearchRateTriggerTest extends SolrCloudTestCase {
         "conf", 2, 2);
     create.setMaxShardsPerNode(1);
     create.process(solrClient);
-    CloudTestUtils.waitForState(cloudManager, COLL1, 60, TimeUnit.SECONDS, clusterShape(2, 2));
+    CloudTestUtils.waitForState(cloudManager, COLL1, 60, TimeUnit.SECONDS, clusterShape(2, 4));
 
     long waitForSeconds = 5 + random().nextInt(5);
     Map<String, Object> props = createTriggerProps(Arrays.asList(COLL1, COLL2), waitForSeconds, 1.0, 0.1);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/SystemLogListenerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/SystemLogListenerTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/SystemLogListenerTest.java
index 979dc58..040a26f 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/SystemLogListenerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/SystemLogListenerTest.java
@@ -16,15 +16,21 @@
  */
 package org.apache.solr.cloud.autoscaling;
 
+import static org.apache.solr.cloud.autoscaling.AutoScalingHandlerTest.createAutoScalingRequest;
+
+import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
 
 import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.embedded.JettySolrRunner;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
@@ -36,14 +42,15 @@ import org.apache.solr.common.params.CollectionAdminParams;
 import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.util.LogLevel;
-import org.junit.BeforeClass;
+import org.apache.solr.util.TimeOut;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.solr.cloud.autoscaling.AutoScalingHandlerTest.createAutoScalingRequest;
-
 /**
  * Test for {@link SystemLogListener}
  */
@@ -75,15 +82,21 @@ public class SystemLogListenerTest extends SolrCloudTestCase {
     }
   }
 
-  @BeforeClass
-  public static void setupCluster() throws Exception {
+  @Before
+  public void setupCluster() throws Exception {
     configureCluster(NODE_COUNT)
         .addConfig("conf", configset("cloud-minimal"))
         .configure();
     CollectionAdminRequest.createCollection(CollectionAdminParams.SYSTEM_COLL, null, 1, 3)
         .process(cluster.getSolrClient());
+    cluster.waitForActiveCollection(CollectionAdminParams.SYSTEM_COLL,  1, 3);
   }
 
+  @After
+  public void teardownCluster() throws Exception {
+    shutdownCluster();
+  }
+  
   @Test
   public void test() throws Exception {
     CloudSolrClient solrClient = cluster.getSolrClient();
@@ -118,7 +131,7 @@ public class SystemLogListenerTest extends SolrCloudTestCase {
     create.process(solrClient);
 
     waitForState("Timed out waiting for replicas of new collection to be active",
-        "test", clusterShape(3, 2));
+        "test", clusterShape(3, 6));
 
     String setListenerCommand = "{" +
         "'set-listener' : " +
@@ -146,20 +159,43 @@ public class SystemLogListenerTest extends SolrCloudTestCase {
       }
     }
     log.info("Stopping node " + cluster.getJettySolrRunner(nonOverseerLeaderIndex).getNodeName());
-    cluster.stopJettySolrRunner(nonOverseerLeaderIndex);
-    cluster.waitForAllNodes(30);
-    assertTrue("Trigger was not fired ", triggerFiredLatch.await(30, TimeUnit.SECONDS));
+    JettySolrRunner j = cluster.stopJettySolrRunner(nonOverseerLeaderIndex);
+    cluster.waitForJettyToStop(j);
+    assertTrue("Trigger was not fired ", triggerFiredLatch.await(60, TimeUnit.SECONDS));
     assertTrue(fired.get());
     Map context = actionContextPropsRef.get();
     assertNotNull(context);
 
+    
+    
+    TimeOut timeout = new TimeOut(30, TimeUnit.SECONDS, TimeSource.NANO_TIME);
+    
+    ModifiableSolrParams query = new ModifiableSolrParams();
+    query.add(CommonParams.Q, "type:" + SystemLogListener.DOC_TYPE);
+    query.add(CommonParams.SORT, "id asc");
+    
+    try {
+      timeout.waitFor("", new Supplier<Boolean>() {
+
+        @Override
+        public Boolean get() {
+          try {
+            cluster.getSolrClient().commit(CollectionAdminParams.SYSTEM_COLL, true, true);
+
+            return cluster.getSolrClient().query(CollectionAdminParams.SYSTEM_COLL, query).getResults().size() == 9;
+          } catch (SolrServerException | IOException e) {
+            throw new RuntimeException(e);
+          }
+        }
+      });
+    } catch (TimeoutException e) {
+      // fine
+    }
     // make sure the event docs are replicated and committed
     Thread.sleep(5000);
     cluster.getSolrClient().commit(CollectionAdminParams.SYSTEM_COLL, true, true);
 
-    ModifiableSolrParams query = new ModifiableSolrParams();
-    query.add(CommonParams.Q, "type:" + SystemLogListener.DOC_TYPE);
-    query.add(CommonParams.SORT, "id asc");
+
     QueryResponse resp = cluster.getSolrClient().query(CollectionAdminParams.SYSTEM_COLL, query);
     SolrDocumentList docs = resp.getResults();
     assertNotNull(docs);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/TestPolicyCloud.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/TestPolicyCloud.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/TestPolicyCloud.java
index 4ff847d..ff0bdd1 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/TestPolicyCloud.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/TestPolicyCloud.java
@@ -127,7 +127,7 @@ public class TestPolicyCloud extends SolrCloudTestCase {
   public void testDataProviderPerReplicaDetails() throws Exception {
     CollectionAdminRequest.createCollection("perReplicaDataColl", "conf", 1, 5)
         .process(cluster.getSolrClient());
-
+    cluster.waitForActiveCollection("perReplicaDataColl", 1, 5);
     DocCollection coll = getCollectionState("perReplicaDataColl");
     String autoScaleJson = "{" +
         "  'cluster-preferences': [" +
@@ -220,7 +220,7 @@ public class TestPolicyCloud extends SolrCloudTestCase {
     CollectionAdminRequest.createCollection(collectionName, "conf", 1, 2)
         .setPolicy("c1")
         .process(cluster.getSolrClient());
-
+    cluster.waitForActiveCollection(collectionName, 1, 2);
     DocCollection docCollection = getCollectionState(collectionName);
     List<Replica> list = docCollection.getReplicas(firstNode.getNodeName());
     int replicasOnNode1 = list != null ? list.size() : 0;
@@ -327,6 +327,8 @@ public class TestPolicyCloud extends SolrCloudTestCase {
     CollectionAdminRequest.createCollectionWithImplicitRouter("policiesTest", "conf", "s1", 1, 1, 1)
         .setMaxShardsPerNode(-1)
         .process(cluster.getSolrClient());
+    
+    cluster.waitForActiveCollection("policiesTest", 1, 3);
 
     DocCollection coll = getCollectionState("policiesTest");
 
@@ -352,6 +354,9 @@ public class TestPolicyCloud extends SolrCloudTestCase {
 
     CollectionAdminRequest.createShard("policiesTest", "s3").
         process(cluster.getSolrClient());
+    
+    cluster.waitForActiveCollection("policiesTest", 2, 6);
+    
     coll = getCollectionState("policiesTest");
     assertEquals(3, coll.getSlice("s3").getReplicas().size());
     coll.forEachReplica(verifyReplicas);
@@ -383,6 +388,9 @@ public class TestPolicyCloud extends SolrCloudTestCase {
   public void testDataProvider() throws IOException, SolrServerException, KeeperException, InterruptedException {
     CollectionAdminRequest.createCollectionWithImplicitRouter("policiesTest", "conf", "shard1", 2)
         .process(cluster.getSolrClient());
+    
+    cluster.waitForActiveCollection("policiesTest", 1, 2);
+    
     DocCollection rulesCollection = getCollectionState("policiesTest");
 
     try (SolrCloudManager cloudManager = new SolrClientCloudManager(new ZkDistributedQueueFactory(cluster.getZkClient()), cluster.getSolrClient())) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/TriggerCooldownIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/TriggerCooldownIntegrationTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/TriggerCooldownIntegrationTest.java
index 6cf424a..5c9ae90 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/TriggerCooldownIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/TriggerCooldownIntegrationTest.java
@@ -113,6 +113,7 @@ public class TriggerCooldownIntegrationTest extends SolrCloudTestCase {
     listenerEvents.clear();
 
     JettySolrRunner newNode = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     boolean await = triggerFiredLatch.await(20, TimeUnit.SECONDS);
     assertTrue("The trigger did not fire at all", await);
     assertTrue(triggerFired.get());

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/TriggerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/TriggerIntegrationTest.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/TriggerIntegrationTest.java
index c42d1e8..2fe3b95 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/TriggerIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/TriggerIntegrationTest.java
@@ -142,7 +142,8 @@ public class TriggerIntegrationTest extends SolrCloudTestCase {
 
     // restart Overseer. Even though we reset the autoscaling config some already running
     // trigger threads may still continue to execute and produce spurious events
-    cluster.stopJettySolrRunner(overseerLeaderIndex);
+    JettySolrRunner j = cluster.stopJettySolrRunner(overseerLeaderIndex);
+    cluster.waitForJettyToStop(j);
     Thread.sleep(5000);
 
     throttlingDelayMs.set(TimeUnit.SECONDS.toMillis(ScheduledTriggers.DEFAULT_ACTION_THROTTLE_PERIOD_SECONDS));
@@ -163,6 +164,7 @@ public class TriggerIntegrationTest extends SolrCloudTestCase {
       // lets start a node
       cluster.startJettySolrRunner();
     }
+    cluster.waitForAllNodes(30);
     cloudManager = cluster.getJettySolrRunner(0).getCoreContainer().getZkController().getSolrCloudManager();
     // clear any events or markers
     // todo: consider the impact of such cleanup on regular cluster restarts
@@ -217,7 +219,7 @@ public class TriggerIntegrationTest extends SolrCloudTestCase {
     }
 
     JettySolrRunner newNode = cluster.startJettySolrRunner();
-
+    cluster.waitForAllNodes(30);
     if (!triggerFiredLatch.await(30, TimeUnit.SECONDS)) {
       fail("Both triggers should have fired by now");
     }
@@ -261,7 +263,8 @@ public class TriggerIntegrationTest extends SolrCloudTestCase {
     for (int i = 0; i < jettySolrRunners.size(); i++) {
       JettySolrRunner jettySolrRunner = jettySolrRunners.get(i);
       if (jettySolrRunner == newNode) {
-        cluster.stopJettySolrRunner(i);
+        JettySolrRunner j = cluster.stopJettySolrRunner(i);
+        cluster.waitForJettyToStop(j);
         break;
       }
     }
@@ -350,9 +353,11 @@ public class TriggerIntegrationTest extends SolrCloudTestCase {
     }
 
     // stop the overseer, somebody else will take over as the overseer
-    cluster.stopJettySolrRunner(index);
+    JettySolrRunner j = cluster.stopJettySolrRunner(index);
+    cluster.waitForJettyToStop(j);
     Thread.sleep(10000);
     JettySolrRunner newNode = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     boolean await = triggerFiredLatch.await(20, TimeUnit.SECONDS);
     assertTrue("The trigger did not fire at all", await);
     assertTrue(triggerFired.get());
@@ -461,6 +466,7 @@ public class TriggerIntegrationTest extends SolrCloudTestCase {
 
     // add node to generate the event
     JettySolrRunner newNode = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     boolean await = actionStarted.await(60, TimeUnit.SECONDS);
     assertTrue("action did not start", await);
     eventQueueActionWait = 1;
@@ -472,7 +478,8 @@ public class TriggerIntegrationTest extends SolrCloudTestCase {
     events.clear();
     actionStarted = new CountDownLatch(1);
     // kill overseer leader
-    cluster.stopJettySolrRunner(overseerLeaderIndex);
+    JettySolrRunner j = cluster.stopJettySolrRunner(overseerLeaderIndex);
+    cluster.waitForJettyToStop(j);
     Thread.sleep(5000);
     // new overseer leader should be elected and run triggers
     await = actionInterrupted.await(3, TimeUnit.SECONDS);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/LiveNodesSet.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/LiveNodesSet.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/LiveNodesSet.java
index 3f5d5f4..5f12004 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/LiveNodesSet.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/LiveNodesSet.java
@@ -49,6 +49,10 @@ public class LiveNodesSet implements Iterable<String> {
   public void removeLiveNodesListener(LiveNodesListener listener) {
     listeners.remove(listener);
   }
+  
+  public void removeAllLiveNodesListeners() {
+    listeners.clear();
+  }
 
   private void fireListeners(SortedSet<String> oldNodes, SortedSet<String> newNodes) {
     for (LiveNodesListener listener : listeners) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/SimClusterStateProvider.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/SimClusterStateProvider.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/SimClusterStateProvider.java
index a7471eb..930b761 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/SimClusterStateProvider.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/SimClusterStateProvider.java
@@ -145,7 +145,7 @@ public class SimClusterStateProvider implements ClusterStateProvider {
   private final Map<String, Map<String, ActionThrottle>> leaderThrottles = new ConcurrentHashMap<>();
 
   // default map of: operation -> delay
-  private final Map<String, Long> defaultOpDelays = new HashMap<>();
+  private final Map<String, Long> defaultOpDelays = new ConcurrentHashMap<>();
   // per-collection map of: collection -> op -> delay
   private final Map<String, Map<String, Long>> opDelays = new ConcurrentHashMap<>();
 
@@ -153,11 +153,11 @@ public class SimClusterStateProvider implements ClusterStateProvider {
   private volatile int clusterStateVersion = 0;
   private volatile String overseerLeader = null;
 
-  private Map<String, Object> lastSavedProperties = null;
+  private volatile Map<String, Object> lastSavedProperties = null;
 
-  private AtomicReference<Map<String, DocCollection>> collectionsStatesRef = new AtomicReference<>();
+  private final AtomicReference<Map<String, DocCollection>> collectionsStatesRef = new AtomicReference<>();
 
-  private Random bulkUpdateRandom = new Random(0);
+  private final Random bulkUpdateRandom = new Random(0);
 
   private transient boolean closed;
 
@@ -1354,20 +1354,22 @@ public class SimClusterStateProvider implements ClusterStateProvider {
     }
   }
 
-  public synchronized void createSystemCollection() throws IOException {
+  public void createSystemCollection() throws IOException {
     try {
-      if (colShardReplicaMap.containsKey(CollectionAdminParams.SYSTEM_COLL)) {
-        return;
+
+      synchronized (this) {
+        if (colShardReplicaMap.containsKey(CollectionAdminParams.SYSTEM_COLL)) {
+          return;
+        }
       }
       String repFactor = String.valueOf(Math.min(3, liveNodes.size()));
       ZkNodeProps props = new ZkNodeProps(
           NAME, CollectionAdminParams.SYSTEM_COLL,
           REPLICATION_FACTOR, repFactor,
           OverseerCollectionMessageHandler.NUM_SLICES, "1",
-          CommonAdminParams.WAIT_FOR_FINAL_STATE, "true"
-      );
+          CommonAdminParams.WAIT_FOR_FINAL_STATE, "true");
       simCreateCollection(props, new NamedList());
-      CloudTestUtils.waitForState(cloudManager, CollectionAdminParams.SYSTEM_COLL, 20, TimeUnit.SECONDS,
+      CloudTestUtils.waitForState(cloudManager, CollectionAdminParams.SYSTEM_COLL, 90, TimeUnit.SECONDS,
           CloudTestUtils.clusterShape(1, Integer.parseInt(repFactor), false, true));
     } catch (Exception e) {
       throw new IOException(e);
@@ -1398,16 +1400,8 @@ public class SimClusterStateProvider implements ClusterStateProvider {
     if (collection == null) {
       throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Collection not set");
     }
-    if (!colShardReplicaMap.containsKey(collection)) {
-      if (CollectionAdminParams.SYSTEM_COLL.equals(collection)) {
-        // auto-create
-        log.trace("-- auto-create .system when req=" + req);
-        createSystemCollection();
-      } else {
-        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Collection '" + collection + "' doesn't exist");
-      }
-    }
-
+    ensureSystemCollection(collection);
+    
     DocCollection coll = getClusterState().getCollection(collection);
     DocRouter router = coll.getRouter();
     List<String> deletes = req.getDeleteById();
@@ -1629,6 +1623,7 @@ public class SimClusterStateProvider implements ClusterStateProvider {
     if (collection == null) {
       throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Collection not set");
     }
+    ensureSystemCollection(collection);
     if (!colShardReplicaMap.containsKey(collection)) {
       throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Collection does not exist");
     }
@@ -1662,6 +1657,17 @@ public class SimClusterStateProvider implements ClusterStateProvider {
     return rsp;
   }
 
+  private void ensureSystemCollection(String collection) throws InterruptedException, IOException {
+    if (!simListCollections().contains(collection)) {
+      if (CollectionAdminParams.SYSTEM_COLL.equals(collection)) {
+        // auto-create
+        createSystemCollection();
+      } else {
+        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Collection '" + collection + "' doesn't exist");
+      }
+    }
+  }
+
   private static String createRegistryName(String collection, String shard, Replica r) {
     return SolrMetricManager.getRegistryName(SolrInfoBean.Group.core, collection, shard,
         Utils.parseMetricsReplicaName(collection, r.getCoreName()));
@@ -1679,7 +1685,7 @@ public class SimClusterStateProvider implements ClusterStateProvider {
     VersionedData oldData = stateManager.getData(ZkStateReader.CLUSTER_PROPS);
     int version = oldData != null ? oldData.getVersion() : -1;
     stateManager.setData(ZkStateReader.CLUSTER_PROPS, data, version);
-    lastSavedProperties = (Map)Utils.fromJSON(data);
+    lastSavedProperties = new ConcurrentHashMap<>((Map)Utils.fromJSON(data));
     return lastSavedProperties;
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/SimSolrCloudTestCase.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/SimSolrCloudTestCase.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/SimSolrCloudTestCase.java
index 3d41ea4..69954cd 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/SimSolrCloudTestCase.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/SimSolrCloudTestCase.java
@@ -16,15 +16,21 @@
  */
 package org.apache.solr.cloud.autoscaling.sim;
 
+import static org.apache.solr.common.cloud.ZkStateReader.SOLR_AUTOSCALING_CONF_PATH;
+
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Predicate;
 
 import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.client.solrj.cloud.autoscaling.BadVersionException;
+import org.apache.solr.client.solrj.cloud.autoscaling.NotEmptyException;
 import org.apache.solr.common.cloud.DocCollection;
 import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.common.cloud.Slice;
@@ -32,13 +38,13 @@ import org.apache.solr.common.cloud.ZkNodeProps;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.common.util.Utils;
+import org.apache.solr.util.TimeOut;
+import org.apache.zookeeper.KeeperException;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.solr.common.cloud.ZkStateReader.SOLR_AUTOSCALING_CONF_PATH;
-
 /**
  * Base class for simulated test cases. Tests that use this class should configure the simulated cluster
  * in <code>@BeforeClass</code> like this:
@@ -115,10 +121,27 @@ public class SimSolrCloudTestCase extends SolrTestCaseJ4 {
   }
 
   protected void removeChildren(String path) throws Exception {
-    if (!cluster.getDistribStateManager().hasData(path)) {
-      return;
+    
+    TimeOut timeOut = new TimeOut(10, TimeUnit.SECONDS, TimeSource.NANO_TIME);
+    timeOut.waitFor("Timed out waiting to see core4 as leader", () -> {    try {
+      cluster.getDistribStateManager().removeRecursively(path, true, false);
+      return true;
+    } catch (NotEmptyException e) {
+
+    } catch (NoSuchElementException e) {
+
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    } catch (KeeperException e) {
+      throw new RuntimeException(e);
+    } catch (InterruptedException e) {
+      throw new RuntimeException(e);
+    } catch (BadVersionException e) {
+      throw new RuntimeException(e);
     }
-    cluster.getDistribStateManager().removeRecursively(path, true, false);
+    return false;
+    });
+
   }
 
   /* Cluster helper methods ************************************/

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75b18319/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/TestSimClusterStateProvider.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/TestSimClusterStateProvider.java b/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/TestSimClusterStateProvider.java
index 40ca91b..800af6b 100644
--- a/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/TestSimClusterStateProvider.java
+++ b/solr/core/src/test/org/apache/solr/cloud/autoscaling/sim/TestSimClusterStateProvider.java
@@ -145,6 +145,7 @@ public class TestSimClusterStateProvider extends SolrCloudTestCase {
 
   private String addNode() throws Exception {
     JettySolrRunner solr = cluster.startJettySolrRunner();
+    cluster.waitForAllNodes(30);
     String nodeId = solr.getNodeName();
     if (simulated) {
       ((SimCloudManager) cloudManager).getSimClusterStateProvider().simAddNode(nodeId);
@@ -154,7 +155,8 @@ public class TestSimClusterStateProvider extends SolrCloudTestCase {
 
   private String deleteNode() throws Exception {
     String nodeId = cluster.getJettySolrRunner(0).getNodeName();
-    cluster.stopJettySolrRunner(0);
+    JettySolrRunner stoppedServer = cluster.stopJettySolrRunner(0);
+    cluster.waitForJettyToStop(stoppedServer);
     if (simulated) {
       ((SimCloudManager) cloudManager).getSimClusterStateProvider().simRemoveNode(nodeId);
     }