blob: 1a8002e3342ff0782b54bbd57d7e2bc5c52c0966 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.cloud;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.Properties;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.SolrTestCase;
import org.apache.solr.client.solrj.embedded.JettyConfig;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.core.SolrCore;
import org.apache.solr.util.RevertDefaultThreadHandlerRule;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
@LuceneTestCase.SuppressSysoutChecks(bugUrl = "Solr logs to JUL")
public class MiniSolrCloudClusterTest extends SolrTestCase {
@ClassRule
public static TestRule solrClassRules = RuleChain.outerRule(
new SystemPropertiesRestoreRule()).around(
new RevertDefaultThreadHandlerRule());
@Test
public void testErrorsInStartup() throws Exception {
AtomicInteger jettyIndex = new AtomicInteger();
MiniSolrCloudCluster cluster = null;
try {
cluster = new MiniSolrCloudCluster(3, createTempDir(), JettyConfig.builder().build()) {
@Override
public JettySolrRunner startJettySolrRunner(String name, String context, JettyConfig config) throws Exception {
if (jettyIndex.incrementAndGet() != 2)
return super.startJettySolrRunner(name, context, config);
throw new IOException("Fake exception on startup!");
}
};
fail("Expected an exception to be thrown from MiniSolrCloudCluster");
}
catch (Exception e) {
assertEquals("Error starting up MiniSolrCloudCluster", e.getMessage());
assertEquals("Expected one suppressed exception", 1, e.getSuppressed().length);
assertEquals("Fake exception on startup!", e.getSuppressed()[0].getMessage());
}
finally {
if (cluster != null)
cluster.shutdown();
}
}
@Test
public void testErrorsInShutdown() throws Exception {
AtomicInteger jettyIndex = new AtomicInteger();
MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(3, createTempDir(), JettyConfig.builder().build()) {
@Override
public JettySolrRunner stopJettySolrRunner(JettySolrRunner jetty) throws Exception {
JettySolrRunner j = super.stopJettySolrRunner(jetty);
if (jettyIndex.incrementAndGet() == 2)
throw new IOException("Fake IOException on shutdown!");
return j;
}
};
Exception ex = expectThrows(Exception.class, cluster::shutdown);
assertEquals("Error shutting down MiniSolrCloudCluster", ex.getMessage());
assertEquals("Expected one suppressed exception", 1, ex.getSuppressed().length);
assertEquals("Fake IOException on shutdown!", ex.getSuppressed()[0].getMessage());
}
@Test
public void testExtraFilters() throws Exception {
JettyConfig.Builder jettyConfig = JettyConfig.builder();
jettyConfig.waitForLoadingCoresToFinish(null);
jettyConfig.withFilter(JettySolrRunner.DebugFilter.class, "*");
MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(random().nextInt(3) + 1, createTempDir(), jettyConfig.build());
cluster.shutdown();
}
public void testSolrHomeAndResourceLoaders() throws Exception {
final String SOLR_HOME_PROP = "solr.solr.home";
// regardless of what sys prop may be set, everything in the cluster should use solr home dirs under the
// configured base dir -- and nothing in the call stack should be "setting" the sys prop to make that work...
final String fakeSolrHome = createTempDir().toAbsolutePath().toString();
System.setProperty(SOLR_HOME_PROP, fakeSolrHome);
// mock FS from createTempDir don't play nice using 'startsWith' when the solr stack reconsistutes the path from string
// so we have to go the string route here as well...
final Path workDir = Paths.get(createTempDir().toAbsolutePath().toString());
final MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(1, workDir, JettyConfig.builder().build());
try {
final JettySolrRunner jetty = cluster.getJettySolrRunners().get(0);
assertTrue(jetty.getCoreContainer().getSolrHome() + " vs " + workDir,
// mock dirs from createTempDir() don't play nice with startsWith, so we have to use the string value
Paths.get(jetty.getCoreContainer().getSolrHome()).startsWith(workDir));
assertEquals(jetty.getCoreContainer().getSolrHome(),
jetty.getCoreContainer().getResourceLoader().getInstancePath().toAbsolutePath().toString());
assertTrue(CollectionAdminRequest.createCollection("test", 1,1).process(cluster.getSolrClient()).isSuccess());
final SolrCore core = jetty.getCoreContainer().getCores().get(0);
assertTrue(core.getInstancePath() + " vs " + workDir,
core.getInstancePath().startsWith(workDir));
assertEquals(core.getInstancePath(),
core.getResourceLoader().getInstancePath());
} finally {
cluster.shutdown();
}
assertEquals("There is no reason why anything should have set this sysprop",
fakeSolrHome, System.getProperty(SOLR_HOME_PROP));
}
public void testMultipleClustersDiffZk() throws Exception {
final MiniSolrCloudCluster x = new MiniSolrCloudCluster(1, createTempDir(), JettyConfig.builder().build());
try {
final MiniSolrCloudCluster y = new MiniSolrCloudCluster(1, createTempDir(), JettyConfig.builder().build());
try {
// sanity check we're not talking to ourselves
assertNotSame(x.getZkServer(), y.getZkServer());
assertNotEquals(x.getZkServer().getZkAddress(), y.getZkServer().getZkAddress());
// baseline check
assertEquals(1, x.getJettySolrRunners().size());
assertZkHost("x", x.getZkServer().getZkAddress(), x.getJettySolrRunners().get(0));
assertEquals(1, y.getJettySolrRunners().size());
assertZkHost("y", y.getZkServer().getZkAddress(), y.getJettySolrRunners().get(0));
// adding nodes should be isolated
final JettySolrRunner j2x = x.startJettySolrRunner();
assertZkHost("x2", x.getZkServer().getZkAddress(), j2x);
assertEquals(2, x.getJettySolrRunners().size());
assertEquals(1, y.getJettySolrRunners().size());
final JettySolrRunner j2y = y.startJettySolrRunner();
assertZkHost("y2", y.getZkServer().getZkAddress(), j2y);
assertEquals(2, x.getJettySolrRunners().size());
assertEquals(2, y.getJettySolrRunners().size());
} finally {
y.shutdown();
}
} finally {
x.shutdown();
}
}
public void testJettyUsingSysProp() throws Exception {
try {
// this cluster will use a sysprop to communicate zkHost to it's nodes -- not node props in the servlet context
final MiniSolrCloudCluster x = new MiniSolrCloudCluster(1, createTempDir(), JettyConfig.builder().build()) {
@Override
public JettySolrRunner startJettySolrRunner(String name, String hostContext, JettyConfig config) throws Exception {
System.setProperty("zkHost", getZkServer().getZkAddress());
final Properties nodeProps = new Properties();
nodeProps.setProperty("test-from-sysprop", "yup");
Path runnerPath = createTempDir(name);
JettyConfig newConfig = JettyConfig.builder(config).setContext("/blarfh").build();
JettySolrRunner jetty = new JettySolrRunner(runnerPath.toString(), nodeProps, newConfig);
return super.startJettySolrRunner(jetty);
}
};
try {
// baseline check
assertEquals(1, x.getJettySolrRunners().size());
assertZkHost("x", x.getZkServer().getZkAddress(), x.getJettySolrRunners().get(0));
// verify MiniSolrCloudCluster's impl didn't change out from under us making test useless
assertEquals("yup", x.getJettySolrRunners().get(0).getNodeProperties().getProperty("test-from-sysprop"));
assertNull(x.getJettySolrRunners().get(0).getNodeProperties().getProperty("zkHost"));
} finally {
x.shutdown();
}
}finally {
System.clearProperty("zkHost");
}
}
private static void assertZkHost(final String msg, final String zkHost, final JettySolrRunner node) {
assertEquals(zkHost, node.getCoreContainer().getNodeConfig().getCloudConfig().getZkHost());
}
}