summaryrefslogtreecommitdiffstats
path: root/zkfacade/src/test
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /zkfacade/src/test
Publish
Diffstat (limited to 'zkfacade/src/test')
-rw-r--r--zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorCompletionWaiterTest.java39
-rw-r--r--zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorCounterTest.java23
-rw-r--r--zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorLockTest.java51
-rw-r--r--zkfacade/src/test/java/com/yahoo/vespa/zookeeper/CuratorTest.java116
-rw-r--r--zkfacade/src/test/java/com/yahoo/vespa/zookeeper/ZooKeeperServerTest.java138
5 files changed, 367 insertions, 0 deletions
diff --git a/zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorCompletionWaiterTest.java b/zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorCompletionWaiterTest.java
new file mode 100644
index 00000000000..51d3a14ba9f
--- /dev/null
+++ b/zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorCompletionWaiterTest.java
@@ -0,0 +1,39 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.curator;
+
+import com.yahoo.path.Path;
+import com.yahoo.vespa.curator.mock.MockCurator;
+import org.junit.Test;
+
+import java.time.Duration;
+
+import static org.junit.Assert.fail;
+
+/**
+ * @author lulf
+ */
+public class CuratorCompletionWaiterTest {
+
+ @Test
+ public void testCompletionWaiter() throws InterruptedException {
+ Curator curator = new MockCurator();
+ Curator.CompletionWaiter waiter = CuratorCompletionWaiter.createAndInitialize(curator, Path.createRoot(), "foo", 1, "foo");
+ Curator.CompletionWaiter notifier = CuratorCompletionWaiter.create(curator.framework(), Path.fromString("/foo"), 1, "bar");
+ Thread t1 = new Thread(() -> {
+ try {
+ waiter.awaitCompletion(Duration.ofSeconds(120));
+ } catch (CompletionTimeoutException e) {
+ fail("Waiting failed due to timeout");
+ }
+ });
+ notifier.notifyCompletion();
+ t1.join();
+ }
+
+ @Test(expected = CompletionTimeoutException.class)
+ public void testCompletionWaiterFailure() {
+ Curator curator = new MockCurator();
+ Curator.CompletionWaiter waiter = CuratorCompletionWaiter.createAndInitialize(curator, Path.createRoot(), "foo", 1, "foo");
+ waiter.awaitCompletion(Duration.ofMillis(100));
+ }
+}
diff --git a/zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorCounterTest.java b/zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorCounterTest.java
new file mode 100644
index 00000000000..32208e8c5a8
--- /dev/null
+++ b/zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorCounterTest.java
@@ -0,0 +1,23 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.curator;
+
+import com.yahoo.vespa.curator.mock.MockCurator;
+import org.apache.curator.framework.recipes.atomic.DistributedAtomicLong;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author lulf
+ * @date 19.08.13
+ */
+public class CuratorCounterTest {
+
+ @Test
+ public void testCounter() throws Exception {
+ DistributedAtomicLong counter = new MockCurator().createAtomicCounter("/mycounter");
+ counter.initialize(4l);
+ assertEquals(4l, counter.get().postValue().longValue());
+ assertEquals(5l, counter.increment().postValue().longValue());
+ }
+
+}
diff --git a/zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorLockTest.java b/zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorLockTest.java
new file mode 100644
index 00000000000..b8c8b095655
--- /dev/null
+++ b/zkfacade/src/test/java/com/yahoo/vespa/curator/CuratorLockTest.java
@@ -0,0 +1,51 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.curator;
+
+import com.yahoo.vespa.curator.mock.MockCurator;
+import com.yahoo.vespa.curator.recipes.CuratorLock;
+import com.yahoo.vespa.curator.recipes.CuratorLockException;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.assertFalse;
+
+/**
+ * @author lulf
+ * @since 5.1
+ */
+public class CuratorLockTest {
+
+ private MockCurator curator;
+ private CuratorLock curatorLock;
+
+ @Before
+ public void setupLock() {
+ curator = new MockCurator();
+ curatorLock = new CuratorLock(curator, "/foo");
+ }
+
+ @Test
+ public void testAcquireNormal() {
+ curator.timeoutOnLock = false;
+ curator.throwExceptionOnLock = false;
+ curatorLock.lock();
+ curatorLock.unlock();
+ }
+
+ @Test
+ public void testLockTimeout() throws InterruptedException {
+ curator.timeoutOnLock = true;
+ assertFalse(curatorLock.tryLock(0, TimeUnit.MILLISECONDS));
+ curatorLock.unlock();
+ }
+
+ @Test(expected = CuratorLockException.class)
+ public void testLockError() {
+ curator.throwExceptionOnLock = true;
+ curatorLock.lock();
+ curatorLock.unlock();
+ }
+
+}
diff --git a/zkfacade/src/test/java/com/yahoo/vespa/zookeeper/CuratorTest.java b/zkfacade/src/test/java/com/yahoo/vespa/zookeeper/CuratorTest.java
new file mode 100644
index 00000000000..e4ca52a0257
--- /dev/null
+++ b/zkfacade/src/test/java/com/yahoo/vespa/zookeeper/CuratorTest.java
@@ -0,0 +1,116 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.zookeeper;
+
+import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.vespa.curator.Curator;
+import org.apache.curator.test.TestingServer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Sets up actual ZooKeeper servers and verifies we can talk to them.
+ *
+ * @author lulf
+ */
+public class CuratorTest {
+
+ private String spec1;
+ private String spec2;
+ private TestingServer test1;
+ private TestingServer test2;
+ private int port1;
+ private int port2;
+
+ @Before
+ public void setupServers() throws Exception {
+ port1 = allocatePort();
+ port2 = allocatePort();
+ test1 = new TestingServer(port1);
+ test2 = new TestingServer(port2);
+ spec1 = "localhost:" + port1;
+ spec2 = "localhost:" + port2;
+ }
+
+ private int allocatePort() {
+ return PortAllocator.findAvailablePort();
+ }
+
+ @After
+ public void teardownServers() throws IOException {
+ test1.stop();
+ test1.close();
+ test2.close();
+ test2.stop();
+ }
+
+ @Test
+ public void require_curator_is_created_from_config() {
+ Curator curator = createCurator(createTestConfig());
+ assertThat(curator.connectionSpec(), is(spec1 + "," + spec2));
+ }
+
+ @Test
+ public void require_that_curator_can_produce_spec() {
+ Curator curator = createCurator(createTestConfig());
+ assertThat(curator.connectionSpec(), is(spec1 + "," + spec2));
+ assertThat(curator.serverCount(), is(2));
+ }
+
+ @Test
+ public void require_that_server_count_is_correct() {
+ ConfigserverConfig.Builder builder = new ConfigserverConfig.Builder();
+ builder.zookeeperserver(createZKBuilder("localhost", port1));
+ Curator curator = createCurator(new ConfigserverConfig(builder));
+ assertThat(curator.serverCount(), is(1));
+ }
+
+ private ConfigserverConfig createTestConfig() {
+ ConfigserverConfig.Builder builder = new ConfigserverConfig.Builder();
+ builder.zookeeperserver(createZKBuilder("localhost", port1));
+ builder.zookeeperserver(createZKBuilder("localhost", port2));
+ return new ConfigserverConfig(builder);
+ }
+
+ private ConfigserverConfig.Zookeeperserver.Builder createZKBuilder(String hostname, int port) {
+ ConfigserverConfig.Zookeeperserver.Builder zkBuilder = new ConfigserverConfig.Zookeeperserver.Builder();
+ zkBuilder.hostname(hostname);
+ zkBuilder.port(port);
+ return zkBuilder;
+ }
+
+ private Curator createCurator(ConfigserverConfig configserverConfig) {
+ return new Curator(configserverConfig, null);
+ }
+
+ private static class PortAllocator {
+
+ private static class PortRange {
+ private int first = 18621;
+ private int last = 18630; // see: factory/doc/port-ranges
+ private int value = first;
+
+ synchronized int next() {
+ if (value > last) {
+ throw new RuntimeException("no port ports in range");
+ }
+ return value++;
+ }
+ }
+
+ private final static PortRange portRange = new PortRange();
+
+ // Get the next port from a pre-allocated range
+ public static int findAvailablePort() {
+ return portRange.next();
+ }
+
+ }
+
+}
diff --git a/zkfacade/src/test/java/com/yahoo/vespa/zookeeper/ZooKeeperServerTest.java b/zkfacade/src/test/java/com/yahoo/vespa/zookeeper/ZooKeeperServerTest.java
new file mode 100644
index 00000000000..4e231631f28
--- /dev/null
+++ b/zkfacade/src/test/java/com/yahoo/vespa/zookeeper/ZooKeeperServerTest.java
@@ -0,0 +1,138 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.zookeeper;
+
+import com.yahoo.cloud.config.ZookeeperServerConfig;
+import com.yahoo.io.IOUtils;
+import com.yahoo.vespa.curator.Curator;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import com.yahoo.vespa.defaults.Defaults;
+
+/**
+ * Tests the zookeeper server.
+ */
+public class ZooKeeperServerTest {
+
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ @Test
+ public void config_is_written_correctly_when_one_server() throws IOException {
+ File cfgFile = folder.newFile();
+ File idFile = folder.newFile();
+ ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder();
+ builder.zooKeeperConfigFile(cfgFile.getAbsolutePath());
+ builder.myidFile(idFile.getAbsolutePath());
+ builder.server(newServer(1, "foo", 123, 321));
+ builder.myid(1);
+ createServer(builder);
+ validateConfigFileSingleHost(cfgFile);
+ validateIdFile(idFile, "");
+ }
+
+ @Test
+ public void config_is_written_correctly_when_multiple_servers() throws IOException {
+ File cfgFile = folder.newFile();
+ File idFile = folder.newFile();
+ ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder();
+ builder.zooKeeperConfigFile(cfgFile.getAbsolutePath());
+ builder.server(newServer(1, "foo", 123, 321));
+ builder.server(newServer(2, "bar", 234, 432));
+ builder.server(newServer(3, "baz", 345, 543));
+ builder.myidFile(idFile.getAbsolutePath());
+ builder.myid(1);
+ createServer(builder);
+ validateConfigFileMultipleHosts(cfgFile);
+ validateIdFile(idFile, "1\n");
+ }
+
+ private void createServer(ZookeeperServerConfig.Builder builder) {
+ new ZooKeeperServer(new ZookeeperServerConfig(builder), false);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void require_that_this_id_must_be_present_amongst_servers() throws IOException {
+ ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder();
+ builder.server(newServer(2, "bar", 234, 432));
+ builder.server(newServer(3, "baz", 345, 543));
+ builder.myid(1);
+ createServer(builder);
+ }
+
+ @Test
+ public void juteMaxBufferCanBeSet() throws IOException {
+ ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder();
+ builder.myid(1);
+ File idFile = folder.newFile();
+ File cfgFile = folder.newFile();
+
+ builder.zooKeeperConfigFile(cfgFile.getAbsolutePath());
+ builder.myidFile(idFile.getAbsolutePath());
+
+ createServer(builder);
+ assertThat(System.getProperty(ZooKeeperServer.ZOOKEEPER_JUTE_MAX_BUFFER), is("" + new ZookeeperServerConfig(builder).juteMaxBuffer()));
+
+ final int max_buffer = 1;
+ builder.juteMaxBuffer(max_buffer);
+ createServer(builder);
+ assertThat(System.getProperty(ZooKeeperServer.ZOOKEEPER_JUTE_MAX_BUFFER), is("" + max_buffer));
+ }
+
+ private ZookeeperServerConfig.Server.Builder newServer(int id, String hostName, int electionPort, int quorumPort) {
+ ZookeeperServerConfig.Server.Builder builder = new ZookeeperServerConfig.Server.Builder();
+ builder.id(id);
+ builder.hostname(hostName);
+ builder.electionPort(electionPort);
+ builder.quorumPort(quorumPort);
+ return builder;
+ }
+
+ private void validateIdFile(File idFile, String expected) throws IOException {
+ String actual = IOUtils.readFile(idFile);
+ assertThat(actual, is(expected));
+ }
+
+ private void validateConfigFileSingleHost(File cfgFile) throws IOException {
+ String expected =
+ "tickTime=2000\n" +
+ "initLimit=20\n" +
+ "syncLimit=15\n" +
+ "maxClientCnxns=0\n" +
+ "snapCount=50000\n" +
+ "dataDir=" + Defaults.getDefaults().vespaHome() + "var/zookeeper\n" +
+ "clientPort=2181\n" +
+ "autopurge.purgeInterval=1\n" +
+ "autopurge.snapRetainCount=15\n";
+ validateConfigFile(cfgFile, expected);
+ }
+
+ private void validateConfigFileMultipleHosts(File cfgFile) throws IOException {
+ String expected =
+ "tickTime=2000\n" +
+ "initLimit=20\n" +
+ "syncLimit=15\n" +
+ "maxClientCnxns=0\n" +
+ "snapCount=50000\n" +
+ "dataDir=" + Defaults.getDefaults().vespaHome() + "var/zookeeper\n" +
+ "clientPort=2181\n" +
+ "autopurge.purgeInterval=1\n" +
+ "autopurge.snapRetainCount=15\n" +
+ "server.1=foo:321:123\n" +
+ "server.2=bar:432:234\n" +
+ "server.3=baz:543:345\n";
+ validateConfigFile(cfgFile, expected);
+ }
+
+ private void validateConfigFile(File cfgFile, String expected) throws IOException {
+ String actual = IOUtils.readFile(cfgFile);
+ assertThat(actual, is(expected));
+ }
+}