You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2015/09/03 18:39:54 UTC

svn commit: r1701066 - in /lucene/dev/trunk/solr/core/src/test/org/apache/solr: cloud/TestMiniSolrCloudCluster.java cloud/TestMiniSolrCloudClusterBase.java security/BasicAuthIntegrationTest.java

Author: noble
Date: Thu Sep  3 16:39:53 2015
New Revision: 1701066

URL: http://svn.apache.org/r1701066
Log:
SOLR-8006: Test failures in BasicAuthIntegrationTest

Added:
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterBase.java   (with props)
Modified:
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudCluster.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudCluster.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudCluster.java?rev=1701066&r1=1701065&r2=1701066&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudCluster.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudCluster.java Thu Sep  3 16:39:53 2015
@@ -205,7 +205,6 @@ public class TestMiniSolrCloudCluster ex
           assertTrue(e.code() >= 500 && e.code() < 600);
         }
 
-        doExtraTests(miniCluster, zkClient, zkStateReader,cloudSolrClient, collectionName);
         // delete the collection we created earlier
         miniCluster.deleteCollection(collectionName);
         AbstractDistribZkTestBase.waitForCollectionToDisappear(collectionName, zkStateReader, true, true, 330);
@@ -216,9 +215,6 @@ public class TestMiniSolrCloudCluster ex
     }
   }
 
-  protected void doExtraTests(MiniSolrCloudCluster miniCluster, SolrZkClient zkClient, ZkStateReader zkStateReader, CloudSolrClient cloudSolrClient,
-                            String defaultCollName) throws Exception { /*do nothing*/ }
-
   @Test
   public void testErrorsInStartup() throws Exception {
 

Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterBase.java?rev=1701066&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterBase.java (added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterBase.java Thu Sep  3 16:39:53 2015
@@ -0,0 +1,209 @@
+package org.apache.solr.cloud;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import java.io.File;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.embedded.JettyConfig;
+import org.apache.solr.client.solrj.embedded.JettySolrRunner;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.cloud.ClusterState;
+import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.core.CoreDescriptor;
+import org.apache.solr.util.RevertDefaultThreadHandlerRule;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@LuceneTestCase.SuppressSysoutChecks(bugUrl = "Solr logs to JUL")
+public class TestMiniSolrCloudClusterBase extends LuceneTestCase {
+
+  private static Logger log = LoggerFactory.getLogger(MiniSolrCloudCluster.class);
+  protected int NUM_SERVERS = 5;
+  protected int NUM_SHARDS = 2;
+  protected int REPLICATION_FACTOR = 2;
+
+  public TestMiniSolrCloudClusterBase () {
+    NUM_SERVERS = 5;
+    NUM_SHARDS = 2;
+    REPLICATION_FACTOR = 2;
+  }
+
+  @Rule
+  public TestRule solrTestRules = RuleChain
+      .outerRule(new SystemPropertiesRestoreRule());
+
+  @ClassRule
+  public static TestRule solrClassRules = RuleChain.outerRule(
+      new SystemPropertiesRestoreRule()).around(
+      new RevertDefaultThreadHandlerRule());
+
+  @Test
+  public void testBasics() throws Exception {
+    final String collectionName = "testSolrCloudCollection";
+    testCollectionCreateSearchDelete(collectionName);
+  }
+
+  private MiniSolrCloudCluster createMiniSolrCloudCluster() throws Exception {
+
+    File solrXml = new File(SolrTestCaseJ4.TEST_HOME(), "solr-no-core.xml");
+    JettyConfig.Builder jettyConfig = JettyConfig.builder();
+    jettyConfig.waitForLoadingCoresToFinish(null);
+    MiniSolrCloudCluster miniCluster = new MiniSolrCloudCluster(NUM_SERVERS, createTempDir().toFile(), solrXml, jettyConfig.build());
+    return miniCluster;
+  }
+
+  private void createCollection(MiniSolrCloudCluster miniCluster, String collectionName, String createNodeSet, String asyncId) throws Exception {
+    String configName = "solrCloudCollectionConfig";
+    File configDir = new File(SolrTestCaseJ4.TEST_HOME() + File.separator + "collection1" + File.separator + "conf");
+    miniCluster.uploadConfigDir(configDir, configName);
+
+    Map<String, String> collectionProperties = new HashMap<>();
+    collectionProperties.put(CoreDescriptor.CORE_CONFIG, "solrconfig-tlog.xml");
+    collectionProperties.put("solr.tests.maxBufferedDocs", "100000");
+    collectionProperties.put("solr.tests.ramBufferSizeMB", "100");
+    // use non-test classes so RandomizedRunner isn't necessary
+    collectionProperties.put("solr.tests.mergePolicy", "org.apache.lucene.index.TieredMergePolicy");
+    collectionProperties.put("solr.tests.mergeScheduler", "org.apache.lucene.index.ConcurrentMergeScheduler");
+    collectionProperties.put("solr.directoryFactory", "solr.RAMDirectoryFactory");
+
+    miniCluster.createCollection(collectionName, NUM_SHARDS, REPLICATION_FACTOR, configName, createNodeSet, asyncId, collectionProperties);
+  }
+
+  protected void testCollectionCreateSearchDelete(String collectionName) throws Exception {
+
+    MiniSolrCloudCluster miniCluster = createMiniSolrCloudCluster();
+
+    final CloudSolrClient cloudSolrClient = miniCluster.getSolrClient();
+
+    try {
+      assertNotNull(miniCluster.getZkServer());
+      List<JettySolrRunner> jettys = miniCluster.getJettySolrRunners();
+      assertEquals(NUM_SERVERS, jettys.size());
+      for (JettySolrRunner jetty : jettys) {
+        assertTrue(jetty.isRunning());
+      }
+
+      // shut down a server
+      JettySolrRunner stoppedServer = miniCluster.stopJettySolrRunner(0);
+      assertTrue(stoppedServer.isStopped());
+      assertEquals(NUM_SERVERS - 1, miniCluster.getJettySolrRunners().size());
+
+      // create a server
+      JettySolrRunner startedServer = miniCluster.startJettySolrRunner();
+      assertTrue(startedServer.isRunning());
+      assertEquals(NUM_SERVERS, miniCluster.getJettySolrRunners().size());
+
+      // create collection
+      final String asyncId = (random().nextBoolean() ? null : "asyncId("+collectionName+".create)="+random().nextInt());
+      createCollection(miniCluster, collectionName, null, asyncId);
+      if (asyncId != null) {
+        assertEquals("did not see async createCollection completion", "completed", AbstractFullDistribZkTestBase.getRequestStateAfterCompletion(asyncId, 330, cloudSolrClient));
+      }
+
+      try (SolrZkClient zkClient = new SolrZkClient
+          (miniCluster.getZkServer().getZkAddress(), AbstractZkTestCase.TIMEOUT, 45000, null);
+           ZkStateReader zkStateReader = new ZkStateReader(zkClient)) {
+        AbstractDistribZkTestBase.waitForRecoveriesToFinish(collectionName, zkStateReader, true, true, 330);
+
+        // modify/query collection
+        cloudSolrClient.setDefaultCollection(collectionName);
+        SolrInputDocument doc = new SolrInputDocument();
+        doc.setField("id", "1");
+        cloudSolrClient.add(doc);
+        cloudSolrClient.commit();
+        SolrQuery query = new SolrQuery();
+        query.setQuery("*:*");
+        QueryResponse rsp = cloudSolrClient.query(query);
+        assertEquals(1, rsp.getResults().getNumFound());
+
+        // remove a server not hosting any replicas
+        zkStateReader.updateClusterState();
+        ClusterState clusterState = zkStateReader.getClusterState();
+        HashMap<String, JettySolrRunner> jettyMap = new HashMap<String, JettySolrRunner>();
+        for (JettySolrRunner jetty : miniCluster.getJettySolrRunners()) {
+          String key = jetty.getBaseUrl().toString().substring((jetty.getBaseUrl().getProtocol() + "://").length());
+          jettyMap.put(key, jetty);
+        }
+        Collection<Slice> slices = clusterState.getSlices(collectionName);
+        // track the servers not host repliacs
+        for (Slice slice : slices) {
+          jettyMap.remove(slice.getLeader().getNodeName().replace("_solr", "/solr"));
+          for (Replica replica : slice.getReplicas()) {
+            jettyMap.remove(replica.getNodeName().replace("_solr", "/solr"));
+          }
+        }
+        assertTrue("Expected to find a node without a replica", jettyMap.size() > 0);
+        JettySolrRunner jettyToStop = jettyMap.entrySet().iterator().next().getValue();
+        jettys = miniCluster.getJettySolrRunners();
+        for (int i = 0; i < jettys.size(); ++i) {
+          if (jettys.get(i).equals(jettyToStop)) {
+            miniCluster.stopJettySolrRunner(i);
+            assertEquals(NUM_SERVERS - 1, miniCluster.getJettySolrRunners().size());
+          }
+        }
+
+        // now restore the original state so that this function could be called multiple times
+
+        // re-create a server (to restore original NUM_SERVERS count)
+        startedServer = miniCluster.startJettySolrRunner();
+        assertTrue(startedServer.isRunning());
+        assertEquals(NUM_SERVERS, miniCluster.getJettySolrRunners().size());
+        Thread.sleep(15000);
+        try {
+          cloudSolrClient.query(query);
+          fail("Expected exception on query because collection should not be ready - we have turned on async core loading");
+        } catch (SolrServerException e) {
+          SolrException rc = (SolrException) e.getRootCause();
+          assertTrue(rc.code() >= 500 && rc.code() < 600);
+        } catch (SolrException e) {
+          assertTrue(e.code() >= 500 && e.code() < 600);
+        }
+
+        doExtraTests(miniCluster, zkClient, zkStateReader,cloudSolrClient, collectionName);
+      }
+    }
+    finally {
+      miniCluster.shutdown();
+    }
+  }
+
+  protected void doExtraTests(MiniSolrCloudCluster miniCluster, SolrZkClient zkClient, ZkStateReader zkStateReader, CloudSolrClient cloudSolrClient,
+                              String defaultCollName) throws Exception { /*do nothing*/ }
+
+}

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java?rev=1701066&r1=1701065&r2=1701066&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java Thu Sep  3 16:39:53 2015
@@ -41,7 +41,7 @@ import org.apache.solr.client.solrj.impl
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.request.GenericSolrRequest;
 import org.apache.solr.cloud.MiniSolrCloudCluster;
-import org.apache.solr.cloud.TestMiniSolrCloudCluster;
+import org.apache.solr.cloud.TestMiniSolrCloudClusterBase;
 import org.apache.solr.common.cloud.DocCollection;
 import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.common.cloud.Slice;
@@ -62,7 +62,7 @@ import static java.util.Collections.sing
 import static org.apache.solr.common.cloud.ZkStateReader.BASE_URL_PROP;
 
 
-public class BasicAuthIntegrationTest extends TestMiniSolrCloudCluster {
+public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
 
   private static final Logger log = LoggerFactory.getLogger(BasicAuthIntegrationTest.class);
 
@@ -164,11 +164,18 @@ public class BasicAuthIntegrationTest ex
 
     }
 
-    httpPost = new HttpPost(baseUrl + "/admin/authorization");
+   /* httpPost = new HttpPost(baseUrl + "/admin/authorization");
     setBasicAuthHeader(httpPost, "harry", "HarryIsUberCool");
     httpPost.setEntity(new ByteArrayEntity(Utils.toJSON(singletonMap("delete-permission", "collection-admin-edit"))));
-    r = cl.execute(httpPost);//cleanup so that the super class does not need to pass on credentials
+    r = cl.execute(httpPost); //cleanup so that the super class does not need to pass on credentials
 
+    for (Slice  slice : zkStateReader.getClusterState().getCollection(defaultCollName).getSlices()) {
+      //ensure that all nodes have removed the collection-admin-edit permission
+      for (Replica replica : slice.getReplicas()) {
+        baseUrl = replica.getStr(BASE_URL_PROP);
+        verifySecurityStatus(cl, baseUrl + "/admin/authorization", "authorization/permissions[2]/name", null, 20);
+      }
+    }*/
   }
 
   public static void verifySecurityStatus(HttpClient cl, String url, String objPath, Object expected, int count) throws Exception {
@@ -187,7 +194,7 @@ public class BasicAuthIntegrationTest ex
           success = true;
           break;
         }
-      } else if (Objects.equals(String.valueOf(actual), expected)) {
+      } else if (Objects.equals(actual == null ? null : String.valueOf(actual), expected)) {
         success = true;
         break;
       }
@@ -223,21 +230,6 @@ public class BasicAuthIntegrationTest ex
     }
   };
 
-
-  @Override
-  public void testErrorsInStartup() throws Exception {
-    //don't do anything
-  }
-
-  @Override
-  public void testErrorsInShutdown() throws Exception {
-  }
-
-
-  @Override
-  public void testCollectionCreateWithoutCoresThenDelete() throws Exception {
-  }
-
   //the password is 'SolrRocks'
   //this could be generated everytime. But , then we will not know if there is any regression
   private static final String STD_CONF = "{\n" +