lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From m...@apache.org
Subject lucene-solr:branch_6x: SOLR-9554: adding a test for concurrent schema upgrade in cloud.
Date Sun, 02 Oct 2016 18:45:25 GMT
Repository: lucene-solr
Updated Branches:
  refs/heads/branch_6x a2e24d1fc -> cc1841cbb


SOLR-9554: adding a test for concurrent schema upgrade in cloud.



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

Branch: refs/heads/branch_6x
Commit: cc1841cbb73f1c5c54208549cb20cf8244fa5104
Parents: a2e24d1
Author: Mikhail Khludnev <mkhl@apache.org>
Authored: Wed Sep 28 12:33:15 2016 +0300
Committer: Mikhail Khludnev <mkhl@apache.org>
Committed: Sun Oct 2 21:33:01 2016 +0300

----------------------------------------------------------------------
 .../cloud-managed-upgrade/conf/schema.xml       |  27 ++++
 .../cloud-managed-upgrade/conf/solrconfig.xml   |  50 ++++++
 .../schema/TestManagedSchemaThreadSafety.java   | 162 +++++++++++++++++++
 .../java/org/apache/solr/SolrTestCaseJ4.java    |   4 +
 .../apache/solr/cloud/SolrCloudTestCase.java    |   4 -
 5 files changed, 243 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cc1841cb/solr/core/src/test-files/solr/configsets/cloud-managed-upgrade/conf/schema.xml
----------------------------------------------------------------------
diff --git a/solr/core/src/test-files/solr/configsets/cloud-managed-upgrade/conf/schema.xml
b/solr/core/src/test-files/solr/configsets/cloud-managed-upgrade/conf/schema.xml
new file mode 100644
index 0000000..b9f09f9
--- /dev/null
+++ b/solr/core/src/test-files/solr/configsets/cloud-managed-upgrade/conf/schema.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ 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.
+-->
+<schema name="minimal" version="1.1">
+  <fieldType name="string" class="solr.StrField"/>
+  <fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
+  <fieldType name="long" class="solr.TrieLongField" precisionStep="0" omitNorms="true"
positionIncrementGap="0"/>
+  <!-- for versioning -->
+  <field name="_version_" type="long" indexed="true" stored="true"/>
+  <field name="_root_" type="int" indexed="true" stored="true" multiValued="false" required="false"/>
+  <field name="id" type="string" indexed="true" stored="true"/>
+  <uniqueKey>id</uniqueKey>
+</schema>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cc1841cb/solr/core/src/test-files/solr/configsets/cloud-managed-upgrade/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/core/src/test-files/solr/configsets/cloud-managed-upgrade/conf/solrconfig.xml
b/solr/core/src/test-files/solr/configsets/cloud-managed-upgrade/conf/solrconfig.xml
new file mode 100644
index 0000000..fc4db3b
--- /dev/null
+++ b/solr/core/src/test-files/solr/configsets/cloud-managed-upgrade/conf/solrconfig.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" ?>
+
+<!--
+ 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.
+-->
+
+<!-- Minimal solrconfig.xml with /select, /admin and /update only -->
+
+<config>
+
+  <dataDir>${solr.data.dir:}</dataDir>
+
+  <directoryFactory name="DirectoryFactory"
+                    class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>
+
+  <schemaFactory class="ManagedIndexSchemaFactory">
+    <str name="managedSchemaResourceName">managed-schema</str>
+  </schemaFactory>
+
+  <luceneMatchVersion>${tests.luceneMatchVersion:LATEST}</luceneMatchVersion>
+
+  <updateHandler class="solr.DirectUpdateHandler2">
+    <commitWithin>
+      <softCommit>${solr.commitwithin.softcommit:true}</softCommit>
+    </commitWithin>
+    <updateLog></updateLog>
+  </updateHandler>
+
+  <requestHandler name="/select" class="solr.SearchHandler">
+    <lst name="defaults">
+      <str name="echoParams">explicit</str>
+      <str name="indent">true</str>
+      <str name="df">text</str>
+    </lst>
+
+  </requestHandler>
+</config>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cc1841cb/solr/core/src/test/org/apache/solr/schema/TestManagedSchemaThreadSafety.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/schema/TestManagedSchemaThreadSafety.java
b/solr/core/src/test/org/apache/solr/schema/TestManagedSchemaThreadSafety.java
new file mode 100644
index 0000000..043632e
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/schema/TestManagedSchemaThreadSafety.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.schema;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.cloud.ZkController;
+import org.apache.solr.cloud.ZkSolrResourceLoader;
+import org.apache.solr.cloud.ZkTestServer;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.util.ExecutorUtil;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.core.SolrConfig;
+import org.apache.solr.core.SolrResourceLoader;
+import org.apache.solr.util.LogLevel;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.NoNodeException;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.data.Stat;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+public class TestManagedSchemaThreadSafety extends SolrTestCaseJ4 {
+
+  private static final class SuspendingZkClient extends SolrZkClient {
+    AtomicReference<Thread> slowpoke = new AtomicReference<>();
+
+    private SuspendingZkClient(String zkServerAddress, int zkClientTimeout) {
+      super(zkServerAddress, zkClientTimeout);
+    }
+
+    boolean isSlowpoke(){
+      Thread youKnow;
+      if ((youKnow = slowpoke.get())!=null) {
+        return youKnow == Thread.currentThread();
+      } else {
+        return slowpoke.compareAndSet(null, Thread.currentThread());
+      }
+    }
+
+    @Override
+    public byte[] getData(String path, Watcher watcher, Stat stat, boolean retryOnConnLoss)
+        throws KeeperException, InterruptedException {
+      byte[] data;
+      try {
+        data = super.getData(path, watcher, stat, retryOnConnLoss);
+      } catch (NoNodeException e) {
+        if (isSlowpoke()) {
+          //System.out.println("suspending "+Thread.currentThread()+" on " + path);
+          Thread.sleep(500);
+        }
+        throw e;
+      }
+      return data;
+    }
+  }
+
+  private static ZkTestServer zkServer;
+  private static Path loaderPath;
+
+  @BeforeClass
+  public static void startZkServer() throws Exception {
+    zkServer = new ZkTestServer(createTempDir().toString());
+    zkServer.run();
+    loaderPath = createTempDir();
+  }
+
+  @AfterClass
+  public static void stopZkServer() throws Exception {
+    zkServer.shutdown();
+  }
+
+  @Test
+  @LogLevel("org.apache.solr.common.cloud.SolrZkClient=debug")
+  public void testThreadSafety() throws Exception {
+
+    final String configsetName = "managed-config";//
+
+    try (SolrZkClient client = new SuspendingZkClient(zkServer.getZkHost(), 30)) {
+      // we can pick any to load configs, I suppose, but here we check
+      client.upConfig(configset("cloud-managed-upgrade"), configsetName);
+    }
+
+    ExecutorService executor = ExecutorUtil.newMDCAwareCachedThreadPool("threadpool");
+    
+    try (SolrZkClient raceJudge = new SuspendingZkClient(zkServer.getZkHost(), 30)) {
+
+      ZkController zkController = createZkController(raceJudge);
+
+      List<Future<?>> futures = new ArrayList<>();
+      for (int i = 0; i < 2; i++) {
+        futures.add(executor.submit(indexSchemaLoader(configsetName, zkController)));
+      }
+
+      for (Future<?> future : futures) {
+        future.get();
+      }
+    }
+    finally {
+      ExecutorUtil.shutdownAndAwaitTermination(executor);
+    }
+  }
+
+  private ZkController createZkController(SolrZkClient client) throws KeeperException, InterruptedException
{
+    ZkController zkController = mock(ZkController.class,
+        Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS));
+
+    when(zkController.getZkClient()).thenReturn(client);
+    Mockito.doAnswer(new Answer<Boolean>() {
+      @Override
+      public Boolean answer(InvocationOnMock invocation) throws Throwable {
+        return client.exists((String) invocation.getArguments()[0], true);
+      }
+    }).when(zkController).pathExists(Mockito.anyString());
+    return zkController;
+  }
+
+  private Runnable indexSchemaLoader(String configsetName, final ZkController zkController)
{
+    return () -> {
+      try {
+        SolrResourceLoader loader = new ZkSolrResourceLoader(loaderPath, configsetName, zkController);
+        SolrConfig solrConfig = SolrConfig.readFromResourceLoader(loader, "solrconfig.xml");
+
+        ManagedIndexSchemaFactory factory = new ManagedIndexSchemaFactory();
+        factory.init(new NamedList());
+        factory.create("schema.xml", solrConfig);
+      }
+      catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    };
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cc1841cb/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
index 3659446..88ddc54 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
@@ -1804,6 +1804,10 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
 
   public static Path TEST_PATH() { return getFile("solr/collection1").getParentFile().toPath();
}
 
+  public static Path configset(String name) {
+    return TEST_PATH().resolve("configsets").resolve(name).resolve("conf");
+  }
+
   public static Throwable getRootCause(Throwable t) {
     Throwable result = t;
     for (Throwable cause = t; null != cause; cause = cause.getCause()) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cc1841cb/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java b/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
index 777e80a..02a4895 100644
--- a/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
+++ b/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
@@ -69,10 +69,6 @@ public class SolrCloudTestCase extends SolrTestCaseJ4 {
 
   public static final int DEFAULT_TIMEOUT = 30;
 
-  public static Path configset(String name) {
-    return TEST_PATH().resolve("configsets").resolve(name).resolve("conf");
-  }
-
   private static class Config {
     final String name;
     final Path path;


Mime
View raw message