package org.cloudname.backends.consul; import org.junit.BeforeClass; import org.junit.Test; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertFalse; import static org.junit.Assume.assumeTrue; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertThat; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.fail; /** * Simple tests for the Consul interface. Needs a running Consul Agent to execute so requires a * system property to execute (consul.endpoint). Tests aren't exhaustive. * * @author Ståle Dahl <stalehd@gmail.com> */ public class ConsulTest { public static final String EP_PROPERTY = "consul.endpoint"; private final Random random = new Random(); private String getSessionName() { return "test/consul/session/" + Long.toOctalString(random.nextLong()); } @BeforeClass public static void checkIfTestShouldRun() { assumeTrue("The system property consul.endpoint isn't set", System.getProperty(EP_PROPERTY) != null); } @Test public void testIsValid() { final Consul consul = new Consul(System.getProperty(EP_PROPERTY)); assertTrue(consul.isValid()); final Consul unavailable = new Consul("http://localhost/"); assertFalse(unavailable.isValid()); } @Test public void createSession() { final Consul consul = new Consul(System.getProperty(EP_PROPERTY)); assertTrue(consul.isValid()); final ConsulSession session = consul.createSession(getSessionName(), 10, 0); assertThat(session, is(notNullValue())); assertThat(session.getId(), is(not(""))); session.close(); } @Test public void writeSessionData() throws Exception { final Consul consul = new Consul(System.getProperty(EP_PROPERTY)); assertTrue(consul.isValid()); final ConsulSession session = consul.createSession(getSessionName(), 10, 0); System.out.println(session.getId()); assertThat(session, is(notNullValue())); assertTrue(consul.writeSessionData("TheKey", "TheValue", session.getId())); assertThat(consul.readData("TheKey"), is("TheValue")); assertTrue(consul.writeSessionData("TheKey", "TheNewValue", session.getId())); assertThat(consul.readData("TheKey"), is("TheNewValue")); session.close(); } @Test public void createPermanentData() { final Consul consul = new Consul(System.getProperty(EP_PROPERTY)); assertTrue(consul.isValid()); final String keyName = "thepermanentone"; consul.removePermanentData(keyName); assertTrue(consul.createPermanentData(keyName, "SomeValue")); assertFalse(consul.createPermanentData(keyName, "AlreadyExists")); assertThat(consul.readData(keyName), is("SomeValue")); assertTrue(consul.writePermanentData(keyName, "OtherValue")); assertThat(consul.readData(keyName), is("OtherValue")); assertTrue(consul.removePermanentData(keyName)); } /** * Create a session, write a value once, wait a bit, then write again, wait close */ private void createSessionAndWrite(final CountDownLatch readyLatch, final CountDownLatch createLatch, final CountDownLatch changeLatch, final Consul consul, final String path, final String value) { try { readyLatch.await(); final ConsulSession session = consul.createSession(getSessionName(), 10, 0); assertTrue(consul.writeSessionData(path, value, session.getId())); createLatch.await(); assertTrue(consul.writeSessionData(path, value + "_1", session.getId())); changeLatch.await(); session.close(); } catch (final InterruptedException ie) { fail(ie.getMessage()); } } /** * Do a simple test with the ConsulWatch class. */ @Test public void watches() throws Exception { final Consul consul = new Consul(System.getProperty(EP_PROPERTY)); assertTrue(consul.isValid()); final ConsulWatch watch = consul.createWatch("some/random/path"); assertThat(watch, is(notNullValue())); final AtomicInteger changeCount = new AtomicInteger(0); final String[] values = new String[] { "first", "second", "third", "fourth", "fifth" }; final CountDownLatch readyLatch = new CountDownLatch(1); final CountDownLatch createLatch = new CountDownLatch(values.length); final CountDownLatch changeLatch = new CountDownLatch(values.length); final CountDownLatch removeLatch = new CountDownLatch(values.length); watch.startWatching(new ConsulWatch.ConsulWatchListener() { @Override public void created(String valueName, String value) { createLatch.countDown(); } @Override public void changed(String valueName, String value) { changeLatch.countDown(); } @Override public void removed(String valueName) { removeLatch.countDown(); } }); final Executor executor = Executors.newCachedThreadPool(); for (final String str : values) { executor.execute(() -> createSessionAndWrite(readyLatch, createLatch, changeLatch, consul, "some/random/path/" + str, str)); } readyLatch.countDown(); final int waitTime = 1000; // N elements should be created assertTrue(createLatch.await(waitTime * 10, TimeUnit.MILLISECONDS)); // ...changed assertTrue(changeLatch.await(waitTime * 10, TimeUnit.MILLISECONDS)); // ...and removed assertTrue(removeLatch.await(waitTime * 10, TimeUnit.MILLISECONDS)); } }