You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2017/04/07 19:34:14 UTC
[15/19] geode git commit: Create ClientCachePutBench
Create ClientCachePutBench
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/0c168582
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/0c168582
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/0c168582
Branch: refs/heads/feature/GEODE-2632
Commit: 0c1685828e9717c52bf96b881fd006d8a92f4cbc
Parents: 39c72b2
Author: Kirk Lund <kl...@apache.org>
Authored: Mon Apr 3 14:52:28 2017 -0700
Committer: Kirk Lund <kl...@apache.org>
Committed: Wed Apr 5 12:49:37 2017 -0700
----------------------------------------------------------------------
geode-core/build.gradle | 5 +
.../sockets/command/ClientCachePutBench.java | 174 +++++++++++++++++++
.../cache/tier/sockets/command/Put65Bench.java | 120 +++++++++++++
.../command/ClientCachePutBench-server.xml | 29 ++++
.../internal/ClusterConfigurationService.java | 20 ++-
.../cache/tier/sockets/BaseCommand.java | 35 ++--
.../tier/sockets/ClientProxyMembershipID.java | 5 +-
.../geode/distributed/ServerLauncherUtils.java | 30 ++++
.../cache/tier/sockets/CacheServerUtils.java | 55 ++++++
.../command/ExperimentIntegrationTest.java | 80 +++++++++
.../tier/sockets/command/ExperimentTest.java | 121 +++++++++++++
11 files changed, 646 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/build.gradle
----------------------------------------------------------------------
diff --git a/geode-core/build.gradle b/geode-core/build.gradle
index 757599a..fd56fe1 100755
--- a/geode-core/build.gradle
+++ b/geode-core/build.gradle
@@ -17,6 +17,7 @@
apply plugin: 'antlr'
+apply plugin: 'me.champeau.gradle.jmh'
sourceSets {
jca {
@@ -220,5 +221,9 @@ dependencies {
classesOutput sourceSets.main.output
}
+jmh {
+ duplicateClassesStrategy = 'warn'
+}
+
tasks.eclipse.dependsOn(generateGrammarSource)
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/src/jmh/java/org/apache/geode/internal/cache/tier/sockets/command/ClientCachePutBench.java
----------------------------------------------------------------------
diff --git a/geode-core/src/jmh/java/org/apache/geode/internal/cache/tier/sockets/command/ClientCachePutBench.java b/geode-core/src/jmh/java/org/apache/geode/internal/cache/tier/sockets/command/ClientCachePutBench.java
new file mode 100644
index 0000000..a1cbd81
--- /dev/null
+++ b/geode-core/src/jmh/java/org/apache/geode/internal/cache/tier/sockets/command/ClientCachePutBench.java
@@ -0,0 +1,174 @@
+/*
+ * 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.geode.internal.cache.tier.sockets.command;
+
+import static org.apache.commons.io.FileUtils.*;
+import static org.apache.geode.test.dunit.NetworkUtils.getIPLiteral;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+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.distributed.ConfigurationProperties;
+import org.apache.geode.distributed.ServerLauncher;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.internal.AvailablePort;
+import org.apache.geode.internal.net.SocketCreator;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@Measurement(iterations = 5)
+@Warmup(iterations = 5)
+@Fork(1)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@State(Scope.Thread)
+@SuppressWarnings("unused")
+public class ClientCachePutBench {
+
+ @Test
+ public void tempTest() throws Exception {
+ String SERVER_XML_FILE_NAME =
+ "/" + StringUtils.replace(ClientCachePutBench.class.getPackage().getName(), ".", "/")
+ + "/ClientCachePutBench-server.xml";
+ assertThat(new File(getClass().getResource(SERVER_XML_FILE_NAME).getFile())).exists();
+ }
+
+ @State(Scope.Benchmark)
+ public static class ClientState {
+ // public static final String SERVER_XML_FILE_NAME =
+ // "/" + StringUtils.replace(ClientCachePutBench.class.getPackage().getName(), ".", "/")
+ // + "/ClientCachePutBench-server.xml";
+ public static final String REGION_NAME = "clientCachePutBench-region";
+
+ public Random random;
+
+ public int serverPort;
+ public Process process;
+ public ServerLauncher launcher;
+ public File serverDirectory;
+
+ public ClientCache clientCache;
+ public Region<String, String> region;
+
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Setup(Level.Trial)
+ public void startServer() throws Exception {
+ this.random = new Random(System.nanoTime());
+
+ this.temporaryFolder.create();
+ this.serverDirectory = this.temporaryFolder.getRoot();
+
+ String SERVER_XML_FILE_NAME =
+ "/" + StringUtils.replace(ClientCachePutBench.class.getPackage().getName(), ".", "/")
+ + "/ClientCachePutBench-server.xml";
+
+ URL srcServerXml = getClass().getResource(SERVER_XML_FILE_NAME);
+ assertThat(srcServerXml).isNotNull();
+ File destServerXml = new File(this.serverDirectory, SERVER_XML_FILE_NAME);
+ copyURLToFile(srcServerXml, destServerXml);
+
+ this.serverPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+
+ List<String> jvmArguments = getJvmArguments();
+
+ List<String> command = new ArrayList<>();
+ command.add(
+ new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
+ for (String jvmArgument : jvmArguments) {
+ command.add(jvmArgument);
+ }
+ command.add("-Dgemfire.cache-xml-file=" + destServerXml.getAbsolutePath());
+ command.add("-cp");
+ command.add(System.getProperty("java.class.path"));
+ command.add(ServerLauncher.class.getName());
+ command.add(ServerLauncher.Command.START.getName());
+ command.add("server1");
+ command.add("--server-port=" + this.serverPort);
+ // command.add("--redirect-output");
+
+ this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
+
+ boolean forever = true;
+ while (forever) {
+ assertThat(this.process.isAlive()).isTrue();
+ Thread.sleep(10000);
+ }
+
+ this.clientCache =
+ new ClientCacheFactory().addPoolServer(getIPLiteral(), this.serverPort).create();
+ this.region =
+ this.clientCache.<String, String>createClientRegionFactory(ClientRegionShortcut.PROXY)
+ .create(REGION_NAME);
+ }
+
+ @TearDown(Level.Trial)
+ public void stopServer() throws Exception {
+ try {
+ this.clientCache.close(false);
+ new ServerLauncher.Builder().setWorkingDirectory(this.serverDirectory.getAbsolutePath())
+ .build().stop();
+ } finally {
+ if (this.process != null) {
+ this.process.destroyForcibly();
+ }
+ this.temporaryFolder.delete();
+ }
+ }
+
+ private List<String> getJvmArguments() {
+ List<String> jvmArguments = new ArrayList<>();
+ jvmArguments.add(
+ "-D" + DistributionConfig.GEMFIRE_PREFIX + ConfigurationProperties.MCAST_PORT + "=0");
+ jvmArguments.add(
+ "-D" + DistributionConfig.GEMFIRE_PREFIX + ConfigurationProperties.LOCATORS + "\"\"");
+ return jvmArguments;
+ }
+ }
+
+ @Benchmark
+ public void test(ClientState state, Blackhole blackhole) throws Exception {
+ String key = "key-" + state.random.nextInt();
+ String value = "value-" + state.random.nextInt();
+ String oldValue = state.region.put(key, value);
+ blackhole.consume(new Object[] {key, value, oldValue});
+ blackhole.consume(oldValue);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/src/jmh/java/org/apache/geode/internal/cache/tier/sockets/command/Put65Bench.java
----------------------------------------------------------------------
diff --git a/geode-core/src/jmh/java/org/apache/geode/internal/cache/tier/sockets/command/Put65Bench.java b/geode-core/src/jmh/java/org/apache/geode/internal/cache/tier/sockets/command/Put65Bench.java
new file mode 100644
index 0000000..6ccd8c3
--- /dev/null
+++ b/geode-core/src/jmh/java/org/apache/geode/internal/cache/tier/sockets/command/Put65Bench.java
@@ -0,0 +1,120 @@
+/*
+ * 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.geode.internal.cache.tier.sockets.command;
+
+import static org.apache.geode.SystemFailure.loadEmergencyClasses;
+import static org.apache.geode.internal.cache.TXManagerImpl.NOTX;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.geode.SystemFailure;
+import org.apache.geode.cache.Operation;
+import org.apache.geode.internal.Version;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.cache.TXManagerImpl;
+import org.apache.geode.internal.cache.tier.Command;
+import org.apache.geode.internal.cache.tier.sockets.CacheServerStats;
+import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
+import org.apache.geode.internal.cache.tier.sockets.Message;
+import org.apache.geode.internal.cache.tier.sockets.Part;
+import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.Blackhole;
+
+public class Put65Bench {
+
+ @State(Scope.Benchmark)
+ public static class ServerConnectionState {
+ public Command command;
+ public ServerConnection mockServerConnection;
+ public Message message;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ loadEmergencyClasses();
+
+ this.command = Put65.getCommand();
+
+ this.mockServerConnection = mock(ServerConnection.class);
+ when(this.mockServerConnection.getClientVersion()).thenReturn(Version.CURRENT);
+
+ TXManagerImpl txManager = mock(TXManagerImpl.class);
+ GemFireCacheImpl cache = mock(GemFireCacheImpl.class);
+ when(cache.getTxManager()).thenReturn(txManager);
+
+ when(this.mockServerConnection.getCache()).thenReturn(cache);
+
+ CacheServerStats cacheServerStats = mock(CacheServerStats.class);
+ when(this.mockServerConnection.getCacheServerStats()).thenReturn(cacheServerStats);
+
+ // .getDistributedMember()
+ ClientProxyMembershipID mockProxyId = mock(ClientProxyMembershipID.class);
+ when(this.mockServerConnection.getProxyID()).thenReturn(mockProxyId);
+
+ Message errorResponseMessage = mock(Message.class);
+ when(this.mockServerConnection.getErrorResponseMessage()).thenReturn(errorResponseMessage);
+
+ Part regionNamePart = mock(Part.class);
+ when(regionNamePart.getString()).thenReturn("regionNamePart");
+
+ Part operationPart = mock(Part.class);
+ when(operationPart.getObject()).thenReturn(Operation.UPDATE);
+
+ Part flagsPart = mock(Part.class);
+ when(flagsPart.getInt()).thenReturn(0);
+
+ Part keyPart = mock(Part.class);
+ when(keyPart.getObject()).thenReturn("keyPart");
+ when(keyPart.getStringOrObject()).thenReturn("keyPart");
+
+ Part isDeltaPart = mock(Part.class);
+ when(isDeltaPart.getObject()).thenReturn(Boolean.FALSE);
+
+ Part valuePart = mock(Part.class);
+ when(valuePart.getObject()).thenReturn("valuePart");
+
+ Part eventPart = mock(Part.class);
+ when(eventPart.getObject()).thenReturn("eventPart");
+
+ Part callbackArgPart = mock(Part.class);
+ when(callbackArgPart.getObject()).thenReturn("callbackArgPart");
+
+ message = mock(Message.class);
+
+ when(message.getTransactionId()).thenReturn(NOTX);
+
+ when(message.getPart(0)).thenReturn(regionNamePart);
+ when(message.getPart(1)).thenReturn(operationPart);
+ when(message.getPart(2)).thenReturn(flagsPart);
+ when(message.getPart(3)).thenReturn(keyPart);
+ when(message.getPart(4)).thenReturn(isDeltaPart);
+ when(message.getPart(5)).thenReturn(valuePart);
+ when(message.getPart(6)).thenReturn(eventPart);
+ when(message.getPart(7)).thenReturn(callbackArgPart);
+ }
+ }
+
+ // @Benchmark
+ public void benchmark(ServerConnectionState state, Blackhole blackhole) {
+ state.command.execute(state.message, state.mockServerConnection);
+ // Message replyMessage = state.mockServerConnection.getReplyMessage();
+ // blackhole.consume(replyMessage);
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/src/jmh/resources/org/apache/geode/internal/cache/tier/sockets/command/ClientCachePutBench-server.xml
----------------------------------------------------------------------
diff --git a/geode-core/src/jmh/resources/org/apache/geode/internal/cache/tier/sockets/command/ClientCachePutBench-server.xml b/geode-core/src/jmh/resources/org/apache/geode/internal/cache/tier/sockets/command/ClientCachePutBench-server.xml
new file mode 100644
index 0000000..2013b37
--- /dev/null
+++ b/geode-core/src/jmh/resources/org/apache/geode/internal/cache/tier/sockets/command/ClientCachePutBench-server.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<cache
+ xmlns="http://geode.apache.org/schema/cache"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd"
+ version="1.0">
+ <region name="clientCachePutBench-region" refid="REPLICATE">
+ <region-attributes>
+ <key-constraint>java.lang.String</key-constraint>
+ <value-constraint>java.lang.String</value-constraint>
+ </region-attributes>
+ </region>
+</cache>
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterConfigurationService.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterConfigurationService.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterConfigurationService.java
index 95d1a5b..74df19c 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterConfigurationService.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterConfigurationService.java
@@ -386,10 +386,22 @@ public class ClusterConfigurationService {
createConfigDirIfNecessary(groupName);
- byte[] jarBytes = locators.stream()
- .map((DistributedMember locator) -> downloadJarFromLocator(locator, groupName, jarName))
- .filter(Objects::nonNull).findFirst().orElseThrow(() -> new IllegalStateException(
- "No locators have a deployed jar named " + jarName + " in " + groupName));
+ byte[] jarBytes = null;
+ for (DistributedMember locator : locators) {
+ jarBytes = downloadJarFromLocator(locator, groupName, jarName);
+ if (jarBytes != null) {
+ break;
+ }
+ }
+ if (jarBytes == null) {
+ throw new IllegalStateException(
+ "No locators have a deployed jar named " + jarName + " in " + groupName);
+ }
+
+ // byte[] jarBytes = locators.stream()
+ // .map((DistributedMember locator) -> downloadJarFromLocator(locator, groupName, jarName))
+ // .filter(Objects::nonNull).findFirst().orElseThrow(() -> new IllegalStateException(
+ // "No locators have a deployed jar named " + jarName + " in " + groupName));
File jarToWrite = getPathToJarOnThisLocator(groupName, jarName).toFile();
FileUtils.writeByteArrayToFile(jarToWrite, jarBytes);
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommand.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommand.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommand.java
index d217672..ff9daca 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommand.java
@@ -91,31 +91,26 @@ public abstract class BaseCommand implements Command {
private static final int MAX_INCOMING_MSGS =
Integer.getInteger("BridgeServer.MAX_INCOMING_MSGS", -1).intValue();
- private static final Semaphore incomingDataLimiter;
-
- private static final Semaphore incomingMsgLimiter;
- static {
- Semaphore tmp;
- if (MAX_INCOMING_DATA > 0) {
- // backport requires that this is fair since we inc by values > 1
- tmp = new Semaphore(MAX_INCOMING_DATA, true);
- } else {
- tmp = null;
- }
- incomingDataLimiter = tmp;
- if (MAX_INCOMING_MSGS > 0) {
- tmp = new Semaphore(MAX_INCOMING_MSGS, false); // unfair for best
- // performance
- } else {
- tmp = null;
- }
- incomingMsgLimiter = tmp;
+ // backport requires that this is fair since we inc by values > 1
+ private static final Semaphore incomingDataLimiter =
+ createIncomingLimiterSemaphore(MAX_INCOMING_DATA, true);
+
+ // unfair for best performance
+ private static final Semaphore incomingMsgLimiter =
+ createIncomingLimiterSemaphore(MAX_INCOMING_MSGS, false);
+ private static Semaphore createIncomingLimiterSemaphore(final int maximum, final boolean fair) {
+ Semaphore semaphore = null;
+ if (maximum > 0) {
+ semaphore = new Semaphore(maximum, fair);
+ }
+ return semaphore;
}
protected SecurityService securityService = IntegratedSecurityService.getSecurityService();
- final public void execute(Message msg, ServerConnection servConn) {
+ @Override
+ public void execute(final Message msg, final ServerConnection servConn) {
// Read the request and update the statistics
long start = DistributionStats.getStatTime();
// servConn.resetTransientData();
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipID.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipID.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipID.java
index 2cbf63b..46e43c5 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipID.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientProxyMembershipID.java
@@ -34,11 +34,8 @@ import static org.apache.geode.distributed.ConfigurationProperties.*;
/**
* This class represents a ConnectionProxy of the CacheClient
- *
- *
- *
*/
-public final class ClientProxyMembershipID
+public class ClientProxyMembershipID
implements DataSerializableFixedID, Serializable, Externalizable {
private static final Logger logger = LogService.getLogger();
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherUtils.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherUtils.java b/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherUtils.java
new file mode 100644
index 0000000..017e0f5
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherUtils.java
@@ -0,0 +1,30 @@
+/*
+ * 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.geode.distributed;
+
+import org.apache.geode.cache.Cache;
+
+/**
+ * Provides tests a way to access non-public state in ServerLauncher
+ */
+public class ServerLauncherUtils {
+
+ /**
+ * Returns the Cache from an online in-process ServerLauncher instance
+ */
+ public static Cache getCache(final ServerLauncher serverLauncher) {
+ return serverLauncher.getCache();
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/CacheServerUtils.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/CacheServerUtils.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/CacheServerUtils.java
new file mode 100644
index 0000000..8cd7622
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/CacheServerUtils.java
@@ -0,0 +1,55 @@
+/*
+ * 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.geode.internal.cache.tier.sockets;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.server.CacheServer;
+import org.apache.geode.internal.cache.CacheServerImpl;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Provides tests a way to access CacheServer, AcceptorImpl and ServerConnection
+ */
+public class CacheServerUtils {
+
+ /**
+ * Returns single CacheServer for the specified Cache instance
+ */
+ public static CacheServer getCacheServer(final Cache cache) {
+ List<CacheServer> cacheServers = cache.getCacheServers();
+ CacheServer cacheServer = cacheServers.get(0);
+ return cacheServer;
+ }
+
+ /**
+ * Returns AcceptorImpl for the specified CacheServer instance
+ */
+ public static AcceptorImpl getAcceptorImpl(final CacheServer cacheServer) {
+ AcceptorImpl acceptor = ((CacheServerImpl) cacheServer).getAcceptor();
+ return acceptor;
+ }
+
+ /**
+ * Returns single ServerConnection for the specified CacheServer instance
+ */
+ public static ServerConnection getServerConnection(final CacheServer cacheServer) {
+ AcceptorImpl acceptor = ((CacheServerImpl) cacheServer).getAcceptor();
+ Set<ServerConnection> serverConnections = acceptor.getAllServerConnections();
+ ServerConnection serverConnection = serverConnections.iterator().next(); // null
+ return serverConnection;
+ }
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExperimentIntegrationTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExperimentIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExperimentIntegrationTest.java
new file mode 100644
index 0000000..2d900dc
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExperimentIntegrationTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.geode.internal.cache.tier.sockets.command;
+
+import static org.apache.geode.distributed.AbstractLauncher.Status.ONLINE;
+import static org.apache.geode.distributed.ServerLauncherUtils.*;
+import static org.apache.geode.internal.cache.tier.sockets.AcceptorImpl.DEFAULT_HANDSHAKE_TIMEOUT_MS;
+import static org.apache.geode.internal.cache.tier.sockets.CacheServerUtils.*;
+import static org.apache.geode.internal.AvailablePort.*;
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.server.CacheServer;
+import org.apache.geode.distributed.ServerLauncher;
+import org.apache.geode.internal.cache.tier.Acceptor;
+import org.apache.geode.internal.cache.tier.Command;
+import org.apache.geode.internal.cache.tier.sockets.AcceptorImpl;
+import org.apache.geode.internal.cache.tier.sockets.Message;
+import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
+import org.apache.geode.internal.net.SocketCreator;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.net.Socket;
+
+@Category(IntegrationTest.class)
+public class ExperimentIntegrationTest {
+
+ private ServerLauncher serverLauncher;
+ private ServerConnection serverConnection;
+
+ @Before
+ public void before() throws Exception {
+ int serverPort = getRandomAvailablePort(SOCKET);
+
+ this.serverLauncher =
+ new ServerLauncher.Builder().setMemberName("server").setServerPort(serverPort).build();
+ this.serverLauncher.start();
+
+ Cache cache = getCache(this.serverLauncher);
+ CacheServer cacheServer = getCacheServer(cache);
+ AcceptorImpl acceptor = getAcceptorImpl(cacheServer);
+
+ Socket mockSocket = mock(Socket.class);
+ when(mockSocket.getInetAddress()).thenReturn(SocketCreator.getLocalHost());
+
+ this.serverConnection =
+ new ServerConnection(mockSocket, cache, null, null, DEFAULT_HANDSHAKE_TIMEOUT_MS,
+ CacheServer.DEFAULT_SOCKET_BUFFER_SIZE, "client", Acceptor.CLIENT_TO_SERVER, acceptor);
+
+ preConditions();
+ }
+
+ public void preConditions() throws Exception {
+ assertThat(this.serverLauncher.status().getStatus()).isEqualTo(ONLINE);
+ }
+
+ @Test
+ public void handlePutFromFakeClient() throws Exception {
+ Message message = mock(Message.class);
+ Command command = mock(Command.class);
+ command.execute(message, this.serverConnection);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/0c168582/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExperimentTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExperimentTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExperimentTest.java
new file mode 100644
index 0000000..b52e81d
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/command/ExperimentTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.geode.internal.cache.tier.sockets.command;
+
+import static org.apache.geode.internal.cache.TXManagerImpl.NOTX;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.*;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.Operation;
+import org.apache.geode.internal.Version;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.cache.TXManagerImpl;
+import org.apache.geode.internal.cache.tier.Command;
+import org.apache.geode.internal.cache.tier.sockets.CacheServerStats;
+import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
+import org.apache.geode.internal.cache.tier.sockets.Message;
+import org.apache.geode.internal.cache.tier.sockets.Part;
+import org.apache.geode.internal.cache.tier.sockets.ServerConnection;
+import org.apache.geode.test.junit.categories.UnitTest;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+
+@Category(UnitTest.class)
+public class ExperimentTest {
+
+ private ServerConnection mockServerConnection;
+
+ @Rule
+ public TestName testName = new TestName();
+
+ @Before
+ public void before() throws Exception {
+ this.mockServerConnection = mock(ServerConnection.class);
+ when(this.mockServerConnection.getClientVersion()).thenReturn(Version.CURRENT);
+
+ TXManagerImpl txManager = mock(TXManagerImpl.class);
+ GemFireCacheImpl cache = mock(GemFireCacheImpl.class);
+ when(cache.getTxManager()).thenReturn(txManager);
+
+ when(this.mockServerConnection.getCache()).thenReturn(cache);
+
+ CacheServerStats cacheServerStats = mock(CacheServerStats.class);
+ when(this.mockServerConnection.getCacheServerStats()).thenReturn(cacheServerStats);
+
+ // .getDistributedMember()
+ ClientProxyMembershipID mockProxyId = mock(ClientProxyMembershipID.class);
+ when(this.mockServerConnection.getProxyID()).thenReturn(mockProxyId);
+
+ Message errorResponseMessage = mock(Message.class);
+ when(this.mockServerConnection.getErrorResponseMessage()).thenReturn(errorResponseMessage);
+ }
+
+ @Test
+ public void handlePutFromFakeClient() throws Exception {
+ Part regionNamePart = mock(Part.class);
+ when(regionNamePart.getString()).thenReturn("regionNamePart");
+
+ Part operationPart = mock(Part.class);
+ when(operationPart.getObject()).thenReturn(Operation.UPDATE);
+
+ Part flagsPart = mock(Part.class);
+ when(flagsPart.getInt()).thenReturn(0);
+
+ Part keyPart = mock(Part.class);
+ when(keyPart.getObject()).thenReturn("keyPart");
+ when(keyPart.getStringOrObject()).thenReturn("keyPart");
+
+ Part isDeltaPart = mock(Part.class);
+ when(isDeltaPart.getObject()).thenReturn(Boolean.FALSE);
+
+ Part valuePart = mock(Part.class);
+ when(valuePart.getObject()).thenReturn("valuePart");
+
+ Part eventPart = mock(Part.class);
+ when(eventPart.getObject()).thenReturn("eventPart");
+
+ Part callbackArgPart = mock(Part.class);
+ when(callbackArgPart.getObject()).thenReturn("callbackArgPart");
+
+ Message message = mock(Message.class);
+
+ when(message.getTransactionId()).thenReturn(NOTX);
+
+ when(message.getPart(0)).thenReturn(regionNamePart);
+ when(message.getPart(1)).thenReturn(operationPart);
+ when(message.getPart(2)).thenReturn(flagsPart);
+ when(message.getPart(3)).thenReturn(keyPart);
+ when(message.getPart(4)).thenReturn(isDeltaPart);
+ when(message.getPart(5)).thenReturn(valuePart);
+ when(message.getPart(6)).thenReturn(eventPart);
+ when(message.getPart(7)).thenReturn(callbackArgPart);
+
+ assertThat(message.getPart(0)).isSameAs(regionNamePart);
+ assertThat(message.getPart(1)).isSameAs(operationPart);
+ assertThat(message.getPart(2)).isSameAs(flagsPart);
+ assertThat(message.getPart(3)).isSameAs(keyPart);
+ assertThat(message.getPart(4)).isSameAs(isDeltaPart);
+ assertThat(message.getPart(5)).isSameAs(valuePart);
+ assertThat(message.getPart(6)).isSameAs(eventPart);
+ assertThat(message.getPart(7)).isSameAs(callbackArgPart);
+
+ Command command = Put65.getCommand();
+ command.execute(message, this.mockServerConnection);
+ }
+}