You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2016/10/04 17:03:44 UTC
[38/38] incubator-geode git commit: Basic get/put test
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 <jd...@pivotal.io>
Authored: Tue Oct 4 10:02:50 2016 -0700
Committer: Jens Deppe <jd...@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'