Basic get/put test

Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/75521268
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/75521268
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/75521268

Branch: refs/heads/feature/e2e-testing
Commit: 75521268a535c1cc9fff3b0245e5cd1af84665cc
Parents: 2cec7a6
Author: Jens Deppe <jde...@pivotal.io>
Authored: Tue Oct 4 10:02:50 2016 -0700
Committer: Jens Deppe <jde...@pivotal.io>
Committed: Tue Oct 4 10:02:50 2016 -0700

----------------------------------------------------------------------
 .../java/org/apache/geode/e2e/DockerTest.java   |  8 +-
 .../test/java/org/apache/geode/e2e/GetPut.java  | 32 +++++++
 .../java/org/apache/geode/e2e/GetPutSteps.java  | 71 ++++++++++++++
 .../java/org/apache/geode/e2e/StoryRunner.java  | 47 ++++++++++
 .../geode/e2e/container/DockerCluster.java      | 97 ++++++++++++++++----
 .../geode/e2e/container/ResultCallback.java     |  6 ++
 .../org/apache/geode/e2e/get_put.story          |  5 +
 gradle/test.gradle                              |  1 +
 8 files changed, 245 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/75521268/geode-core/src/test/java/org/apache/geode/e2e/DockerTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/e2e/DockerTest.java 
b/geode-core/src/test/java/org/apache/geode/e2e/DockerTest.java
index e8e04f0..d8581f4 100644
--- a/geode-core/src/test/java/org/apache/geode/e2e/DockerTest.java
+++ b/geode-core/src/test/java/org/apache/geode/e2e/DockerTest.java
@@ -14,7 +14,9 @@ public class DockerTest {
 
   @Before
   public void setup() throws Exception {
-    cluster = new DockerCluster("testy", 1);
+    cluster = new DockerCluster("testy");
+    cluster.setLocatorCount(1);
+    cluster.setServerCount(2);
   }
 
   @After
@@ -25,11 +27,11 @@ public class DockerTest {
   @Test
   public void sanity() throws Exception {
     cluster.start();
-    assertNotNull("Locator address is null", cluster.getLocatorAddress());
+    assertNotNull("Locator host is null", cluster.getLocatorHost());
   }
 
   @Test
-  public void testInvalidGfshCommand() throws Exception {
+  public void testInvalidGfshCommandReturnsNonZero() throws Exception {
     String id = cluster.startContainer(0);
     int r = cluster.execCommand(id, false, null, new String[] { 
"/tmp/work/bin/gfsh", "startx" });
     assertEquals(1, r);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/75521268/geode-core/src/test/java/org/apache/geode/e2e/GetPut.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/e2e/GetPut.java 
b/geode-core/src/test/java/org/apache/geode/e2e/GetPut.java
new file mode 100644
index 0000000..e62194b
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/e2e/GetPut.java
@@ -0,0 +1,32 @@
+package org.apache.geode.e2e;
+
+import org.jbehave.core.configuration.Configuration;
+import org.jbehave.core.configuration.MostUsefulConfiguration;
+import org.jbehave.core.io.LoadFromClasspath;
+import org.jbehave.core.junit.JUnitStory;
+import org.jbehave.core.reporters.Format;
+import org.jbehave.core.reporters.StoryReporterBuilder;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+
+public class GetPut extends JUnitStory {
+
+  // Here we specify the configuration, starting from default 
MostUsefulConfiguration, and changing only what is need ed
+  @Override
+  public Configuration configuration() {
+    return new MostUsefulConfiguration()
+      // where to find the stories
+      .useStoryLoader(new LoadFromClasspath(this.getClass()))
+      // CONSOLE and TXT reporting
+      .useStoryReporterBuilder(new StoryReporterBuilder().withDefaultFormats()
+      .withFormats(Format.ANSI_CONSOLE, Format.TXT));
+  }
+
+  // Here we specify the steps classes
+  @Override
+  public InjectableStepsFactory stepsFactory() {
+    // varargs, can have more that one steps classes
+    return new InstanceStepsFactory(configuration(), new GetPutSteps());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/75521268/geode-core/src/test/java/org/apache/geode/e2e/GetPutSteps.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/e2e/GetPutSteps.java 
b/geode-core/src/test/java/org/apache/geode/e2e/GetPutSteps.java
new file mode 100644
index 0000000..bb4db31
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/e2e/GetPutSteps.java
@@ -0,0 +1,71 @@
+package org.apache.geode.e2e;
+
+import static org.junit.Assert.assertEquals;
+
+import com.spotify.docker.client.exceptions.DockerException;
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.client.ClientCache;
+import org.apache.geode.cache.client.ClientCacheFactory;
+import org.apache.geode.cache.client.ClientRegionShortcut;
+import org.apache.geode.e2e.container.DockerCluster;
+import org.jbehave.core.annotations.AfterScenario;
+import org.jbehave.core.annotations.BeforeScenario;
+import org.jbehave.core.annotations.BeforeStories;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Then;
+import org.jbehave.core.annotations.When;
+
+public class GetPutSteps {
+
+  private DockerCluster cluster;
+
+  @BeforeStories
+  public void teardownContainers() throws DockerException, 
InterruptedException {
+    DockerCluster.scorch();
+  }
+
+  @BeforeScenario
+  public void beforeScenario() {
+    cluster = new DockerCluster("test-cluster");
+  }
+
+  @AfterScenario
+  public void afterScenario() throws Exception {
+    cluster.stop();
+  }
+
+  @Given("cluster is started with $locators locators and $servers servers")
+  public void startCluster(int locatorCount, int serverCount) throws Exception 
{
+    cluster.setLocatorCount(locatorCount);
+    cluster.setServerCount(serverCount);
+    cluster.start();
+  }
+
+  @Given("region $name is created as $type")
+  public void createRegion(String name, String type) throws Exception {
+    cluster.gfshCommand(String.format("create region --name=%s --type=%s", 
name, type));
+  }
+
+  @When("I put $count entries into region $name")
+  public void when(int count, String name) throws Exception {
+    ClientCache cache = new ClientCacheFactory().
+      set("log-level", "warn").
+      addPoolLocator("localhost", cluster.getLocatorPort()).
+      create();
+    Region region = 
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(name);
+    for (int i = 0; i < count; i++) {
+      region.put("key_" + i, "value_" + i);
+    }
+  }
+
+  @Then("I can get $count entries from region $name")
+  public void then(int count, String name) throws Exception {
+    Region region = CacheFactory.getAnyInstance().getRegion(name);
+
+    for (int i = 0; i < count; i++) {
+      assertEquals("value_" + i, region.get("key_" + i));
+    }
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/75521268/geode-core/src/test/java/org/apache/geode/e2e/StoryRunner.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/e2e/StoryRunner.java 
b/geode-core/src/test/java/org/apache/geode/e2e/StoryRunner.java
new file mode 100644
index 0000000..21921cb
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/e2e/StoryRunner.java
@@ -0,0 +1,47 @@
+package org.apache.geode.e2e;
+
+import static org.jbehave.core.io.CodeLocations.codeLocationFromClass;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.jbehave.core.configuration.Configuration;
+import org.jbehave.core.configuration.MostUsefulConfiguration;
+import org.jbehave.core.io.LoadFromClasspath;
+import org.jbehave.core.io.StoryFinder;
+import org.jbehave.core.junit.JUnitStories;
+import org.jbehave.core.junit.JUnitStory;
+import org.jbehave.core.reporters.Format;
+import org.jbehave.core.reporters.StoryReporterBuilder;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+
+public class StoryRunner extends JUnitStories {
+
+  // Here we specify the configuration, starting from default 
MostUsefulConfiguration, and changing only what is need ed
+  @Override
+  public Configuration configuration() {
+    return new MostUsefulConfiguration()
+      // where to find the stories
+      .useStoryLoader(new LoadFromClasspath(this.getClass()))
+      // CONSOLE and TXT reporting
+      .useStoryReporterBuilder(new StoryReporterBuilder().withDefaultFormats()
+      .withFormats(Format.ANSI_CONSOLE, Format.TXT));
+  }
+
+  // Here we specify the steps classes
+  @Override
+  public InjectableStepsFactory stepsFactory() {
+    // varargs, can have more that one steps classes
+    return new InstanceStepsFactory(configuration(), new GetPutSteps());
+  }
+
+  @Override
+  protected List<String> storyPaths() {
+    String codeLocation = codeLocationFromClass(this.getClass()).getFile() + 
"../../resources/test";
+    List<String> stories = new ArrayList<>();
+    stories.add("**/*.story");
+    return new StoryFinder().findPaths(codeLocation, stories, 
Collections.EMPTY_LIST);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/75521268/geode-core/src/test/java/org/apache/geode/e2e/container/DockerCluster.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/e2e/container/DockerCluster.java 
b/geode-core/src/test/java/org/apache/geode/e2e/container/DockerCluster.java
index 3be2feb..c9a4478 100644
--- a/geode-core/src/test/java/org/apache/geode/e2e/container/DockerCluster.java
+++ b/geode-core/src/test/java/org/apache/geode/e2e/container/DockerCluster.java
@@ -4,15 +4,20 @@ import static com.google.common.base.Charsets.*;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import com.spotify.docker.client.DefaultDockerClient;
 import com.spotify.docker.client.DockerClient;
 import com.spotify.docker.client.LogStream;
 import com.spotify.docker.client.exceptions.DockerException;
+import com.spotify.docker.client.messages.Container;
 import com.spotify.docker.client.messages.ContainerConfig;
 import com.spotify.docker.client.messages.ContainerCreation;
 import com.spotify.docker.client.messages.HostConfig;
+import com.spotify.docker.client.messages.NetworkSettings;
+import com.spotify.docker.client.messages.PortBinding;
 
 public class DockerCluster {
 
@@ -21,39 +26,52 @@ public class DockerCluster {
   private int serverCount;
   private String name;
   private List<String> nodeIds;
-  private String locatorAddress;
+  private String locatorHost;
+  private int locatorPort;
 
-  public DockerCluster(String name, int serverCount) {
-    this(name, 1, serverCount);
-  }
-
-  public DockerCluster(String name, int locatorCount, int serverCount) {
+  public DockerCluster(String name) {
     docker = DefaultDockerClient.builder().
       uri("unix:///var/run/docker.sock").build();
 
     this.name = name;
-    this.locatorCount = locatorCount;
-    this.serverCount = serverCount;
     this.nodeIds = new ArrayList<>();
   }
 
+  public void setServerCount(int count) {
+    this.serverCount = count;
+  }
+
+  public void setLocatorCount(int count) {
+    this.locatorCount = count;
+  }
+
   public void start() throws Exception {
     startLocators();
     startServers();
   }
 
   public String startContainer(int index) throws DockerException, 
InterruptedException {
+    return startContainer(index, new HashMap<>());
+  }
+
+  public String startContainer(int index, Map<String, List<PortBinding>> 
portBindings) throws DockerException, InterruptedException {
     String geodeHome = System.getenv("GEODE_HOME");
+    if (geodeHome == null) {
+      throw new IllegalStateException("GEODE_HOME environment variable is not 
set");
+    }
+
     String vol = String.format("%s:/tmp/work", geodeHome);
 
     HostConfig hostConfig = HostConfig.
       builder().
+      portBindings(portBindings).
       appendBinds(vol).
       build();
 
     ContainerConfig config = ContainerConfig.builder().
       image("gemfire/ubuntu-gradle").
       openStdin(true).
+      exposedPorts(portBindings.keySet()).
       hostname(String.format("%s-%d", name, index)).
       hostConfig(hostConfig).
       workingDir("/tmp").
@@ -77,7 +95,12 @@ public class DockerCluster {
         String.format("--name=%s-locator-%d", name, i)
       };
 
-      String id = startContainer(i);
+      Map<String, List<PortBinding>> ports = new HashMap<>();
+      List<PortBinding> binding = new ArrayList<>();
+      binding.add(PortBinding.of("HostPort", (10334 + i) + ""));
+      ports.put((10334 + i) + "/tcp", binding);
+
+      String id = startContainer(i, ports);
       execCommand(id, true, null, command);
 
       while (gfshCommand(null, null) != 0) {
@@ -85,19 +108,28 @@ public class DockerCluster {
       }
     }
 
-    locatorAddress = String.format("%s[10334]", 
docker.inspectContainer(nodeIds.get(0)).networkSettings().ipAddress());
+    // Let's get the host port which is mapped to the container 10334 port
+    NetworkSettings networks = 
docker.inspectContainer(nodeIds.get(0)).networkSettings();
+    locatorPort = 
Integer.parseInt(networks.ports().get("10334/tcp").get(0).hostPort());
   }
 
   public void startServers() throws DockerException, InterruptedException {
-    for (int i = 0; i < serverCount+1; i++) {
+    String locatorAddress = String.format("%s[10334]", 
docker.inspectContainer(nodeIds.get(0)).networkSettings().ipAddress());
+    for (int i = 0; i < serverCount; i++) {
       String[] command = {
         "/tmp/work/bin/gfsh",
         "start server",
         String.format("--name=%s-server-%d", name, i),
-        String.format("--locators=%s", locatorAddress)
+        String.format("--locators=%s", locatorAddress),
+        "--hostname-for-clients=localhost"
       };
 
-      String id = startContainer(i);
+      Map<String, List<PortBinding>> ports = new HashMap<>();
+      List<PortBinding> binding = new ArrayList<>();
+      binding.add(PortBinding.of("HostPort", (40404 + i) + ""));
+      ports.put((40404 + i) + "/tcp", binding);
+
+      String id = startContainer(i, ports);
       execCommand(id, true, null, command);
     }
 
@@ -122,6 +154,10 @@ public class DockerCluster {
     }
   }
 
+  public int gfshCommand(String command) throws DockerException, 
InterruptedException {
+    return gfshCommand(command, null);
+  }
+
   public int gfshCommand(String command, ResultCallback callback) throws 
DockerException, InterruptedException {
     String locatorId = nodeIds.get(0);
     List<String> gfshCmd = new ArrayList<>();
@@ -137,14 +173,20 @@ public class DockerCluster {
   public int execCommand(String id, boolean startDetached,
                          ResultCallback callback, String... command) throws 
DockerException, InterruptedException {
     List<DockerClient.ExecCreateParam> execParams = new ArrayList<>();
-    execParams.add(DockerClient.ExecCreateParam.attachStdout());
-    execParams.add(DockerClient.ExecCreateParam.attachStderr());
-    execParams.add(DockerClient.ExecCreateParam.detach(startDetached));
+
+    if (startDetached) {
+      execParams.add(DockerClient.ExecCreateParam.detach(startDetached));
+    } else {
+      execParams.add(DockerClient.ExecCreateParam.attachStdout());
+      execParams.add(DockerClient.ExecCreateParam.attachStderr());
+    }
 
     String execId = docker.execCreate(id, command, execParams.toArray(new 
DockerClient.ExecCreateParam[]{}));
+
     LogStream output = docker.execStart(execId);
 
     if (startDetached) {
+      output.close();
       return 0;
     }
 
@@ -155,7 +197,7 @@ public class DockerCluster {
 
       if (buffer.indexOf("\n") >= 0) {
         int n;
-        while ((n = buffer.indexOf("\n")) >=0 ) {
+        while ((n = buffer.indexOf("\n")) >= 0) {
           System.out.println("[gfsh]: " + buffer.substring(0, n));
           if (callback != null) {
             callback.call(buffer.substring(0, n));
@@ -165,6 +207,8 @@ public class DockerCluster {
       }
     }
 
+    output.close();
+
     return docker.execInspect(execId).exitCode();
   }
 
@@ -176,7 +220,22 @@ public class DockerCluster {
     docker.close();
   }
 
-  public String getLocatorAddress() {
-    return locatorAddress;
+  public String getLocatorHost() {
+    return locatorHost;
+  }
+
+  public int getLocatorPort() {
+    return locatorPort;
+  }
+
+  public static void scorch() throws DockerException, InterruptedException {
+    DockerClient docker = DefaultDockerClient.builder().
+      uri("unix:///var/run/docker.sock").build();
+
+    List<Container> containers = docker.listContainers();
+    for (Container c : containers) {
+      docker.stopContainer(c.id(), 0);
+      docker.removeContainer(c.id());
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/75521268/geode-core/src/test/java/org/apache/geode/e2e/container/ResultCallback.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/e2e/container/ResultCallback.java 
b/geode-core/src/test/java/org/apache/geode/e2e/container/ResultCallback.java
new file mode 100644
index 0000000..03eefbf
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/e2e/container/ResultCallback.java
@@ -0,0 +1,6 @@
+package org.apache.geode.e2e.container;
+
+public interface ResultCallback {
+
+  void call(String output);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/75521268/geode-core/src/test/resources/org/apache/geode/e2e/get_put.story
----------------------------------------------------------------------
diff --git a/geode-core/src/test/resources/org/apache/geode/e2e/get_put.story 
b/geode-core/src/test/resources/org/apache/geode/e2e/get_put.story
new file mode 100644
index 0000000..b981023
--- /dev/null
+++ b/geode-core/src/test/resources/org/apache/geode/e2e/get_put.story
@@ -0,0 +1,5 @@
+Scenario: gfsh can start and manage a cluster
+Given cluster is started with 1 locators and 2 servers
+Given region FOO is created as REPLICATE
+When I put 100 entries into region FOO
+Then I can get 100 entries from region FOO

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/75521268/gradle/test.gradle
----------------------------------------------------------------------
diff --git a/gradle/test.gradle b/gradle/test.gradle
index 5b35db4..4b4e00d 100644
--- a/gradle/test.gradle
+++ b/gradle/test.gradle
@@ -72,6 +72,7 @@ subprojects {
     testCompile 'org.jmock:jmock-legacy:' + project.'jmock.version'
     testCompile 'pl.pragmatists:JUnitParams:' + project.'JUnitParams.version'
     testCompile 'com.spotify:docker-client:5.0.2'
+    testCompile 'org.jbehave:jbehave-core:4.0.5'
     
     testRuntime 'cglib:cglib:' + project.'cglib.version'
     testRuntime 'org.ow2.asm:asm:' + project.'asm.version'

Reply via email to