summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Gradzki <mgradzki@cisco.com>2018-05-29 16:54:49 +0200
committerMarek Gradzki <mgradzki@cisco.com>2018-05-29 17:22:18 +0200
commit5d077627a8d28c4853b7bb4ac4fd6e8938b7844b (patch)
tree7128a7ce603dadb3b0d38d050d471717e6c0a3e1
parent16e6594b9d258a1a6879eac1e270957ac3501428 (diff)
jvpp-benchmark: introduce abstract JVppBenchmark
Change-Id: I957edd6813b1be43232845d9bf6a4f13ed01ecfb Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
-rw-r--r--it/jvpp-benchmark/asciidoc/Readme.adoc6
-rw-r--r--it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclUpdateBenchmark.java187
-rw-r--r--it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableBenchmark.java59
-rw-r--r--it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/util/JVppBenchmark.java (renamed from it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableCreateBenchmark.java)79
4 files changed, 170 insertions, 161 deletions
diff --git a/it/jvpp-benchmark/asciidoc/Readme.adoc b/it/jvpp-benchmark/asciidoc/Readme.adoc
index 65aeff2c7..b50327e91 100644
--- a/it/jvpp-benchmark/asciidoc/Readme.adoc
+++ b/it/jvpp-benchmark/asciidoc/Readme.adoc
@@ -54,7 +54,7 @@ sudo java -jar ./target/jvpp-benchmark*executable.jar -p mode=L2 AclUpdateBenchm
---
-== ClassifyTableCreateBenchmark
+== ClassifyTableBenchmark
Synchronously creates classify tables using classifyAddDelTable operation.
By default 20x2s warmup and 100x2s measurement iterations are performed.
@@ -68,11 +68,11 @@ Tables from the set are used in round-robin fashion.
Run with:
[source,shell]
---
-sudo java -jar ./target/jvpp-benchmark*executable.jar ClassifyTableCreateBenchmark
+sudo java -jar ./target/jvpp-benchmark*executable.jar ClassifyTableBenchmark
---
To specify tableSetSize (default=100), use:
[source,shell]
---
-sudo java -jar ./target/jvpp-benchmark*executable.jar ClassifyTableCreateBenchmark -p aclSetSize=1000
+sudo java -jar ./target/jvpp-benchmark*executable.jar ClassifyTableBenchmark -p aclSetSize=1000
---
diff --git a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclUpdateBenchmark.java b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclUpdateBenchmark.java
index e8bf2a833..4042f8a73 100644
--- a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclUpdateBenchmark.java
+++ b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclUpdateBenchmark.java
@@ -19,8 +19,8 @@ package io.fd.hc2vpp.it.jvpp.benchmark.acl;
import static io.fd.hc2vpp.it.jvpp.benchmark.acl.AclUpdateBenchmark.InterfaceMode.L2;
import static io.fd.hc2vpp.it.jvpp.benchmark.acl.AclUpdateBenchmark.InterfaceMode.L3;
-import com.google.common.io.CharStreams;
-import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.hc2vpp.it.jvpp.benchmark.util.JVppBenchmark;
+import io.fd.vpp.jvpp.JVppRegistry;
import io.fd.vpp.jvpp.acl.JVppAclImpl;
import io.fd.vpp.jvpp.acl.dto.AclInterfaceSetAclList;
import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
@@ -32,41 +32,14 @@ import io.fd.vpp.jvpp.core.dto.SwInterfaceAddDelAddress;
import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlags;
import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Bridge;
import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
-import io.fd.vpp.jvpp.dto.JVppReply;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
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.Param;
-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.Threads;
-import org.openjdk.jmh.annotations.Timeout;
-import org.openjdk.jmh.annotations.Warmup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-@BenchmarkMode(Mode.AverageTime)
-@State(Scope.Thread)
-@Fork(1)
-@Threads(1)
-@Timeout(time = 5)
-@Warmup(iterations = 20, time = 2)
-@Measurement(iterations = 100, time = 2)
-@OutputTimeUnit(TimeUnit.MILLISECONDS)
-public class AclUpdateBenchmark {
+public class AclUpdateBenchmark extends JVppBenchmark {
private static final Logger LOG = LoggerFactory.getLogger(AclUpdateBenchmark.class);
@Param( {"100"})
@@ -79,84 +52,37 @@ public class AclUpdateBenchmark {
private InterfaceMode mode;
private AclProvider aclProvider;
- private JVppRegistryImpl registry;
private FutureJVppAclFacade jvppAcl;
private FutureJVppCoreFacade jvppCore;
@Benchmark
- public void testMethod() throws Exception {
- // In real application, reply may be ignored by the caller, so we ignore as well.
+ public void testUpdate() throws Exception {
+ // In a real application, reply may be ignored by the caller, so we ignore it as well.
jvppAcl.aclAddReplace(aclProvider.next()).toCompletableFuture().get();
}
- @Setup(Level.Iteration)
- public void setup() throws Exception {
- initAclProvider();
- startVpp();
- connect();
- initAcl();
- }
-
- @TearDown(Level.Iteration)
- public void tearDown() throws Exception {
- disconnect();
- stopVpp();
- }
-
- private void initAclProvider() {
+ /**
+ * Initializes loopback interface, creates ACL and assigns it to loop0.
+ */
+ @Override
+ protected void iterationSetup() throws Exception {
aclProvider = new AclProviderImpl(aclSetSize, aclSize);
- }
-
- private void startVpp() throws Exception {
- LOG.info("Starting VPP ...");
- final String[] cmd = {"/bin/sh", "-c", "sudo service vpp start"};
- exec(cmd);
- LOG.info("VPP started successfully");
- }
-
- private void stopVpp() throws Exception {
- LOG.info("Stopping VPP ...");
- final String[] cmd = {"/bin/sh", "-c", "sudo service vpp stop"};
- exec(cmd);
-
- // Wait to be sure VPP was stopped.
- // Prevents VPP start failure: "vpp.service: Start request repeated too quickly".
- Thread.sleep(1500);
- LOG.info("VPP stopped successfully");
- }
-
- private static void exec(String[] command) throws IOException, InterruptedException {
- Process process = Runtime.getRuntime().exec(command);
- process.waitFor();
- if (process.exitValue() != 0) {
- String error_msg = "Failed to execute " + Arrays.toString(command) + ": " +
- CharStreams.toString(new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8));
- throw new IllegalStateException(error_msg);
+ // Init loop0 interface
+ final int swIfIndex = initLoop0();
+ if (L3.equals(mode)) {
+ initL3(swIfIndex);
+ } else if (L2.equals(mode)) {
+ initL2(swIfIndex);
}
- }
-
- private void connect() throws IOException {
- LOG.info("Connecting to JVPP ...");
- registry = new JVppRegistryImpl("ACLUpdateBenchmark");
- jvppCore = new FutureJVppCoreFacade(registry, new JVppCoreImpl());
- jvppAcl = new FutureJVppAclFacade(registry, new JVppAclImpl());
- LOG.info("Successfully connected to JVPP");
- }
+ // Create ACL and assign to loop0
+ final int aclId = initAcl(swIfIndex);
- private void disconnect() throws Exception {
- LOG.info("Disconnecting ...");
- jvppAcl.close();
- jvppCore.close();
- registry.close();
- LOG.info("Successfully disconnected ...");
+ // Use ACL index in subsequent executions of aclProvider.next() method
+ aclProvider.setAclIndex(aclId);
}
- /**
- * Initializes loopback interface, creates ACL and assigns it to loop0.
- */
- private void initAcl()
- throws ExecutionException, InterruptedException {
+ private int initLoop0() throws ExecutionException, InterruptedException {
// Create loopback interface
final CreateLoopbackReply loop0 = invoke(jvppCore.createLoopback(new CreateLoopback()));
@@ -165,51 +91,62 @@ public class AclUpdateBenchmark {
flags.adminUpDown = 1;
flags.swIfIndex = loop0.swIfIndex;
invoke(jvppCore.swInterfaceSetFlags(flags));
+ return loop0.swIfIndex;
+ }
- if (L3.equals(mode)) {
- // Assign IP to loop0
- final SwInterfaceAddDelAddress address = new SwInterfaceAddDelAddress();
- address.address = new byte[]{1,0,0,0};
- address.addressLength = 8;
- address.isAdd = 1;
- address.swIfIndex = loop0.swIfIndex;
- invoke(jvppCore.swInterfaceAddDelAddress(address));
- } else if (L2.equals(mode)) {
- // Create bridge domain 1
- final BridgeDomainAddDel bd = new BridgeDomainAddDel();
- bd.bdId = 1;
- bd.isAdd = 1;
- invoke(jvppCore.bridgeDomainAddDel(bd));
-
- // Assign loop0 to BD1:
- final SwInterfaceSetL2Bridge loop0Bridge = new SwInterfaceSetL2Bridge();
- loop0Bridge.bdId = bd.bdId;
- loop0Bridge.rxSwIfIndex = loop0.swIfIndex;
- loop0Bridge.enable = 1; // set L2 mode
- invoke(jvppCore.swInterfaceSetL2Bridge(loop0Bridge));
- }
+ private void initL3(final int swIfIndex) throws ExecutionException, InterruptedException {
+ // Assign IP to loop0
+ final SwInterfaceAddDelAddress address = new SwInterfaceAddDelAddress();
+ address.address = new byte[] {1, 0, 0, 0};
+ address.addressLength = 8;
+ address.isAdd = 1;
+ address.swIfIndex = swIfIndex;
+ invoke(jvppCore.swInterfaceAddDelAddress(address));
+ }
+ private void initL2(final int swIfIndex) throws ExecutionException, InterruptedException {
+ // Create bridge domain with id=1
+ final BridgeDomainAddDel bd = new BridgeDomainAddDel();
+ bd.bdId = 1;
+ bd.isAdd = 1;
+ invoke(jvppCore.bridgeDomainAddDel(bd));
+
+ // Assign loop0 to BD1:
+ final SwInterfaceSetL2Bridge loop0Bridge = new SwInterfaceSetL2Bridge();
+ loop0Bridge.bdId = bd.bdId;
+ loop0Bridge.rxSwIfIndex = swIfIndex;
+ loop0Bridge.enable = 1; // set L2 mode
+ invoke(jvppCore.swInterfaceSetL2Bridge(loop0Bridge));
+ }
+
+ private int initAcl(final int swIfIndex) throws ExecutionException, InterruptedException {
// Create ACL
final int aclId = invoke(jvppAcl.aclAddReplace(aclProvider.next())).aclIndex;
// Assign the ACL to loop0 interface
final AclInterfaceSetAclList aclList = new AclInterfaceSetAclList();
- aclList.swIfIndex = loop0.swIfIndex;
+ aclList.swIfIndex = swIfIndex;
aclList.count = 1;
aclList.nInput = 1;
aclList.acls = new int[] {aclId};
invoke(jvppAcl.aclInterfaceSetAclList(aclList));
- // Use ACL index in subsequent executions of aclProvider.next() method
- aclProvider.setAclIndex(aclId);
+ return aclId;
}
- public enum InterfaceMode {
- L2, L3
+ @Override
+ protected void connect(final JVppRegistry registry) throws IOException {
+ jvppCore = new FutureJVppCoreFacade(registry, new JVppCoreImpl());
+ jvppAcl = new FutureJVppAclFacade(registry, new JVppAclImpl());
}
- private static <R extends JVppReply<?>> R invoke(final CompletionStage<R> completionStage)
- throws ExecutionException, InterruptedException {
- return completionStage.toCompletableFuture().get();
+ @Override
+ protected void disconnect() throws Exception {
+ jvppAcl.close();
+ jvppCore.close();
+ }
+
+ public enum InterfaceMode {
+ L2, L3
}
}
diff --git a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableBenchmark.java b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableBenchmark.java
new file mode 100644
index 000000000..ba234e44d
--- /dev/null
+++ b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableBenchmark.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.hc2vpp.it.jvpp.benchmark.classify;
+
+import io.fd.hc2vpp.it.jvpp.benchmark.util.JVppBenchmark;
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply;
+import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
+import java.io.IOException;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ClassifyTableBenchmark extends JVppBenchmark {
+ private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableBenchmark.class);
+
+ @Param( {"100"})
+ private int tableSetSize;
+
+ private FutureJVppCoreFacade jvppCore;
+ private ClassifyTableProvider classifyTableProvider;
+
+ @Benchmark
+ public ClassifyAddDelTableReply testCreate() throws Exception {
+ // Caller may want to process reply, so return it to prevent JVM from dead code elimination
+ return jvppCore.classifyAddDelTable(classifyTableProvider.next()).toCompletableFuture().get();
+ }
+
+ @Override
+ protected void iterationSetup() throws Exception {
+ classifyTableProvider = new ClassifyTableProviderImpl(tableSetSize);
+ }
+
+ @Override
+ protected void connect(final JVppRegistry registry) throws IOException {
+ jvppCore = new FutureJVppCoreFacade(registry, new JVppCoreImpl());
+ }
+
+ @Override
+ protected void disconnect() throws Exception {
+ jvppCore.close();
+ }
+}
diff --git a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableCreateBenchmark.java b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/util/JVppBenchmark.java
index 32700933e..9f422747e 100644
--- a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableCreateBenchmark.java
+++ b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/util/JVppBenchmark.java
@@ -14,26 +14,29 @@
* limitations under the License.
*/
-package io.fd.hc2vpp.it.jvpp.benchmark.classify;
+package io.fd.hc2vpp.it.jvpp.benchmark.util;
import com.google.common.io.CharStreams;
+import io.fd.vpp.jvpp.JVppRegistry;
import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.acl.JVppAclImpl;
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
import io.fd.vpp.jvpp.core.JVppCoreImpl;
-import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply;
import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
+import io.fd.vpp.jvpp.dto.JVppReply;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
-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.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
@@ -48,41 +51,34 @@ import org.slf4j.LoggerFactory;
@State(Scope.Thread)
@Fork(1)
@Threads(1)
-@Timeout(time = 5)
+@Timeout(time = 10)
@Warmup(iterations = 20, time = 2)
@Measurement(iterations = 100, time = 2)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
-public class ClassifyTableCreateBenchmark {
- private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableCreateBenchmark.class);
-
- @Param( {"100"})
- private int tableSetSize;
-
+public abstract class JVppBenchmark {
+ private static final Logger LOG = LoggerFactory.getLogger(JVppBenchmark.class);
private JVppRegistryImpl registry;
- private FutureJVppCoreFacade jvppCore;
- private ClassifyTableProvider classifyTableProvider;
-
- @Benchmark
- public ClassifyAddDelTableReply testMethod() throws Exception {
- // Caller may want to process reply, so return it to prevent JVM from dead code elimination
- return jvppCore.classifyAddDelTable(classifyTableProvider.next()).toCompletableFuture().get();
- }
@Setup(Level.Iteration)
- public void setup() throws Exception {
- initProvider();
+ public final void setup() throws Exception {
startVpp();
- connect();
+ jVppConnect();
+ iterationSetup();
+ }
+
+ protected void iterationSetup() throws Exception {
+ // NOOP
}
@TearDown(Level.Iteration)
- public void tearDown() throws Exception {
- disconnect();
+ public final void tearDown() throws Exception {
+ iterationTearDown();
+ jVppDisconnect();
stopVpp();
}
- private void initProvider() {
- classifyTableProvider = new ClassifyTableProviderImpl(tableSetSize);
+ protected void iterationTearDown() throws Exception {
+ // NOOP
}
private void startVpp() throws Exception {
@@ -101,10 +97,11 @@ public class ClassifyTableCreateBenchmark {
// Prevents VPP start failure: "vpp.service: Start request repeated too quickly".
Thread.sleep(1500);
LOG.info("VPP stopped successfully");
+
}
private static void exec(String[] command) throws IOException, InterruptedException {
- Process process = Runtime.getRuntime().exec(command);
+ final Process process = Runtime.getRuntime().exec(command);
process.waitFor();
if (process.exitValue() != 0) {
String error_msg = "Failed to execute " + Arrays.toString(command) + ": " +
@@ -113,17 +110,33 @@ public class ClassifyTableCreateBenchmark {
}
}
- private void connect() throws IOException {
- LOG.info("Connecting to JVPP ...");
+ private void jVppConnect() throws IOException {
+ LOG.info("Connecting JVpp ...");
registry = new JVppRegistryImpl("ACLUpdateBenchmark");
- jvppCore = new FutureJVppCoreFacade(registry, new JVppCoreImpl());
+ connect(registry);
LOG.info("Successfully connected to JVPP");
}
- private void disconnect() throws Exception {
- LOG.info("Disconnecting ...");
- jvppCore.close();
+ /**
+ * Connects JVpp plugins.
+ * @param registry manages JVpp connection
+ */
+ protected abstract void connect(final JVppRegistry registry) throws IOException;
+
+ private void jVppDisconnect() throws Exception {
+ LOG.info("Disconnecting JVpp...");
+ disconnect();
registry.close();
LOG.info("Successfully disconnected ...");
}
+
+ /**
+ * Disconnects JVpp plugins.
+ */
+ protected abstract void disconnect() throws Exception;
+
+ protected static <R extends JVppReply<?>> R invoke(final CompletionStage<R> completionStage)
+ throws ExecutionException, InterruptedException {
+ return completionStage.toCompletableFuture().get();
+ }
}