diff --git a/solr/core/src/test/org/apache/solr/cloud/DeleteReplicaTest.java b/solr/core/src/test/org/apache/solr/cloud/DeleteReplicaTest.java index 23f5737b3af..a996f81342f 100644 --- a/solr/core/src/test/org/apache/solr/cloud/DeleteReplicaTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/DeleteReplicaTest.java @@ -35,6 +35,7 @@ import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.response.CoreAdminResponse; +import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.DocCollection; import org.apache.solr.common.cloud.Replica; import org.apache.solr.common.cloud.Slice; @@ -119,6 +120,19 @@ public class DeleteReplicaTest extends AbstractFullDistribZkTestBase { } finally { replica1Server.shutdown(); } + try { + // Should not be able to delete a replica that is up if onlyIfDown=true. + tryToRemoveOnlyIfDown(collectionName, client, replica1, shard1.getName(), dataDir); + fail("Should have thrown an exception here because the replica is NOT down"); + } catch (SolrException se) { + assertEquals("Should see 400 here ", se.code(), 400); + assertTrue("Should have had a good message here", se.getMessage().contains("with onlyIfDown='true', but state is 'active'")); + // This bit is a little weak in that if we're screwing up and actually deleting the replica, we might get back + // here _before_ the datadir is deleted. But I'd rather not introduce a delay here. + assertTrue("dataDir for " + replica1.getName() + " should NOT have been deleted by deleteReplica API with onlyIfDown='true'", + new File(dataDir).exists()); + } + removeAndWaitForReplicaGone(collectionName, client, replica1, shard1.getName()); @@ -128,6 +142,18 @@ public class DeleteReplicaTest extends AbstractFullDistribZkTestBase { } } + protected void tryToRemoveOnlyIfDown(String collectionName, CloudSolrServer client, Replica replica, String shard, String dataDir) throws IOException, SolrServerException { + Map m = makeMap("collection", collectionName, + "action", DELETEREPLICA, + "shard", shard, + "replica", replica.getName(), + ZkStateReader.ONLY_IF_DOWN, "true"); + SolrParams params = new MapSolrParams(m); + SolrRequest request = new QueryRequest(params); + request.setPath("/admin/collections"); + NamedList resp = client.request(request); + } + protected void removeAndWaitForReplicaGone(String COLL_NAME, CloudSolrServer client, Replica replica, String shard) throws SolrServerException, IOException, InterruptedException { diff --git a/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudCluster.java b/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudCluster.java index 70e2ad12671..c61da707971 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudCluster.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudCluster.java @@ -217,7 +217,7 @@ public class TestMiniSolrCloudCluster extends LuceneTestCase { zkClient.makePath(ZkController.CONFIGS_ZKNODE + "/" + configName + "/" + nameInZk, file, false, true); } - protected NamedList createCollection(CloudSolrServer server, String name, int numShards, + protected NamedList createCollection(CloudSolrServer server, String name, int numShards, int replicationFactor, String configName) throws Exception { ModifiableSolrParams modParams = new ModifiableSolrParams(); modParams.set(CoreAdminParams.ACTION, CollectionAction.CREATE.name());