summaryrefslogtreecommitdiffstats
path: root/infra/it/memory-benchmark
diff options
context:
space:
mode:
authorJan Srnicek <jsrnicek@cisco.com>2017-01-31 10:00:51 +0100
committerJan Srnicek <jsrnicek@cisco.com>2017-01-31 10:00:51 +0100
commit92afaeb4a959ea5a6a072fe3ed7a01088d703e0b (patch)
treefc98660011e75ca71f97c25e641638dce37158bd /infra/it/memory-benchmark
parent60e463b17b05458c1f9a7fd72f9e99d71124eedf (diff)
HONEYCOMB-293 - Memory benchmarking
Contains configuration for benchmarks: - Honeycomb on rest(just infra, no data) - Honeycomb with 1000 data nodes - Honeycomb with 10000 data nodes Each benchmark outputs two files: - out_path_name-HeapMemoryUsage.csv - out_path_name-NonHeapMemoryUsage.csv Both files are in format : committed,init,max,used 109576192,109051904,1525153792,12194752 Data sample sizes can be easily adjusted, just by changing start parameter -DsampleSize Change-Id: If6f9919307574237689326b4a38d410ec563200a Signed-off-by: Marek Gradzki <mgradzki@cisco.com> Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
Diffstat (limited to 'infra/it/memory-benchmark')
-rw-r--r--infra/it/memory-benchmark/asciidoc/Readme.adoc68
-rw-r--r--infra/it/memory-benchmark/pom.xml184
-rw-r--r--infra/it/memory-benchmark/src/main/assembly/assembly.xml30
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/BenchmarkFilesProvider.java95
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryFootprintBenchmark.java125
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryInfo.java87
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/BindableCfgAttrsModule.java38
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombConfiguration.java97
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombManagementModule.java46
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWriter.java54
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWritersModule.java38
-rw-r--r--infra/it/memory-benchmark/src/test/java/io/fd/honeycomb/benchmark/memory/HoneycombFootprintTest.java64
12 files changed, 926 insertions, 0 deletions
diff --git a/infra/it/memory-benchmark/asciidoc/Readme.adoc b/infra/it/memory-benchmark/asciidoc/Readme.adoc
new file mode 100644
index 000000000..80e2ffb6f
--- /dev/null
+++ b/infra/it/memory-benchmark/asciidoc/Readme.adoc
@@ -0,0 +1,68 @@
+= memory-benchmark
+
+Overview of memory-benchmark
+
+= Tutorial
+= Configure
+
+To run honeycomb memory benchmark, use maven profile *memory-benchmark* like so
+
+ mvn clean install -DskipTests -Pmemory-benchmark
+
+This will add following modules to build
+
+* _management_ - Enable JMX for honeycomb
+* _memory-benchmark-scripts_ - Script generation for benchmarks
+* _memory-benchmark-api_ - Test models for benchmark
+* _memory-benchmark_ - Benchmark itself
+
+By default, 3 versions of run scripts are produces in project build folder
+
+* _honeycomb-memory-footprint-benchmark-0_ - Tests honeycomb memory footprint on rest without any config/context data
+* _honeycomb-memory-footprint-benchmark-1000_ - Tests honeycomb memory footprint while 1000 data nodes present in config data
+* _honeycomb-memory-footprint-benchmark-10000_ - Tests honeycomb memory footprint while 10000 data nodes present in config data
+
+Any other data sample size can be tested by modifying script parameter *-DsampleSize*
+
+== Run
+
+To run benchmark
+
+ ./honeycomb-memory-footprint-benchmark-0
+
+This will produce two output files.
+
+* memory-benchmark-on-rest-out-0-HeapMemoryUsage.csv
+* memory-benchmark-on-rest-out-0-NonHeapMemoryUsage.csv
+
+For further explanation look at
+
+ https://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html
+
+
+Each of these files contains values in following format
+
+ committed,init,max,used
+ 132644864,109051904,1525153792,12577144
+
+These values stands for
+
+
+* init - Represents the initial amount of memory (in bytes) that the Java virtual machine requests from the operating system for memory management during startup.
+The Java virtual machine may request additional memory from the operating system and may also release memory to the system over time.
+The value of init may be undefined(-1).
+* used - Represents the amount of memory currently used (in bytes).
+* committed - Represents the amount of memory (in bytes) that is guaranteed to be available for use by the Java virtual machine.
+The amount of committed memory may change over time (increase or decrease). The Java virtual machine may release memory to the system and committed could be less than init.
+Committed will always be greater than or equal to used.
+* max - Represents the maximum amount of memory (in bytes) that can be used for memory management. Its value may be undefined(-1).
+ The maximum amount of memory may change over time if defined.
+ The amount of used and committed memory will always be less than or equal to max if max is defined.
+ A memory allocation may fail if it attempts to increase the used memory
+ such that used > committed even if used <= max would still be true (for example, when the system is low on virtual memory).
+
+
+
+
+
+
diff --git a/infra/it/memory-benchmark/pom.xml b/infra/it/memory-benchmark/pom.xml
new file mode 100644
index 000000000..8c93c0bef
--- /dev/null
+++ b/infra/it/memory-benchmark/pom.xml
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2016 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <!-- Parent set as common script to use all groovy dependency versions, etc-->
+ <parent>
+ <groupId>io.fd.honeycomb.common</groupId>
+ <artifactId>honeycomb-parent</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+ <relativePath>../../../common/honeycomb-parent</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>memory-benchmark</artifactId>
+ <!-- Static version, we don't want it to be deployed anyway-->
+ <version>1.0.0</version>
+ <properties>
+ <commons-csv.version>1.4</commons-csv.version>
+ <honeycomb.version>1.17.04-SNAPSHOT</honeycomb.version>
+ <maven.groovy.version>2.0</maven.groovy.version>
+ <groovy.version>2.4.7</groovy.version>
+ <groovy.eclipse.compiler.version>2.9.2-01</groovy.eclipse.compiler.version>
+ <groovy.eclipse.batch.version>2.4.3-01</groovy.eclipse.batch.version>
+ </properties>
+ <!-- to be runnable from command line -->
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>memory-benchmark-api</artifactId>
+ <version>${honeycomb.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.fd.honeycomb</groupId>
+ <artifactId>minimal-distribution</artifactId>
+ <version>${honeycomb.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>management</artifactId>
+ <version>${honeycomb.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-csv</artifactId>
+ <version>${commons-csv.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-all</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <!-- Skip deploy -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+
+ <!-- skips test by default but compile them -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.19.1</version>
+ <configuration>
+ <skipTests>true</skipTests>
+ </configuration>
+ </plugin>
+
+ <!-- assemble jar with all dependencies and test classes -->
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <descriptor>src/main/assembly/assembly.xml</descriptor>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- generate scripts for benchmarks -->
+ <plugin>
+ <groupId>org.codehaus.gmaven</groupId>
+ <artifactId>groovy-maven-plugin</artifactId>
+ <executions>
+ <!-- script for on-rest memory benchmark -->
+ <execution>
+ <id>generate-on-rest-benchmark-script</id>
+ <phase>package</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <!-- 0 data samples == empty config file, therefore same as honeycomb on rest -->
+ <configuration>
+ <source>
+ io.fd.honeycomb.benchmark.script.MemoryBenchmarkStartupScriptGenerator.generateWithDataScript(project, log, "memory-benchmark-on-rest-out", 0)
+ </source>
+ </configuration>
+ </execution>
+ <!-- script for memory benchmark with 1000 nodes in config data-->
+ <execution>
+ <id>generate-with-data-1000-benchmark-script</id>
+ <phase>package</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <source>
+ io.fd.honeycomb.benchmark.script.MemoryBenchmarkStartupScriptGenerator.generateWithDataScript(project, log, "memory-benchmark-with-data-out", 1000)
+ </source>
+ </configuration>
+ </execution>
+ <!-- script for memory benchmark with 10000 nodes in config data-->
+ <execution>
+ <id>generate-with-data-10000-benchmark-script</id>
+ <phase>package</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <source>
+ io.fd.honeycomb.benchmark.script.MemoryBenchmarkStartupScriptGenerator.generateWithDataScript(project, log, "memory-benchmark-with-data-out", 10000)
+ </source>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>benchmark-scripts</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/infra/it/memory-benchmark/src/main/assembly/assembly.xml b/infra/it/memory-benchmark/src/main/assembly/assembly.xml
new file mode 100644
index 000000000..385d0dcb8
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/assembly/assembly.xml
@@ -0,0 +1,30 @@
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+ <id>with-tests</id>
+ <formats>
+ <format>jar</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <dependencySets>
+ <dependencySet>
+ <outputDirectory>/</outputDirectory>
+ <useProjectArtifact>true</useProjectArtifact>
+ <!-- Will include junit-->
+ <useProjectAttachments>true</useProjectAttachments>
+ <unpack>true</unpack>
+ <scope>test</scope>
+ </dependencySet>
+ </dependencySets>
+ <fileSets>
+ <fileSet>
+ <directory>${project.build.directory}/test-classes</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>**/*.class</include>
+ </includes>
+ <useDefaultExcludes>true</useDefaultExcludes>
+ </fileSet>
+ </fileSets>
+</assembly> \ No newline at end of file
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/BenchmarkFilesProvider.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/BenchmarkFilesProvider.java
new file mode 100644
index 000000000..c7717d593
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/BenchmarkFilesProvider.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 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.honeycomb.benchmark.memory;
+
+
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVPrinter;
+import org.slf4j.Logger;
+
+import javax.annotation.Nonnull;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.function.Supplier;
+
+public interface BenchmarkFilesProvider {
+
+ default void outputBenchmarkResult(@Nonnull final MemoryInfo benchmarkResult,
+ @Nonnull final String outputPath,
+ @Nonnull final Supplier<Logger> loggerSupplier) {
+ // specifies output file in form specified_name-memory_info_type.csv
+ final Path outPath = Paths.get(outputPath + "-" + benchmarkResult.getMemoryInfoTypeName() + ".csv");
+ final CSVFormat csvFormat = CSVFormat.RFC4180.withHeader(MemoryInfo.COMMITTED, MemoryInfo.INIT, MemoryInfo.MAX, MemoryInfo.USED);
+
+ try (final CSVPrinter csvPrinter = new CSVPrinter(new StringBuilder(), csvFormat)) {
+ // prints values in same order that header is
+ csvPrinter.printRecord(benchmarkResult.getCommitted(), benchmarkResult.getInit(), benchmarkResult.getMax(), benchmarkResult.getUsed());
+
+ loggerSupplier.get().info("Creating output file {}", outPath);
+ // writes output to separate file
+ Files.write(Files.createFile(outPath), Collections.singleton(csvPrinter.getOut().toString()));
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to output results of benchmark", e);
+ }
+ }
+
+
+ default String generateEmptyJsonFile(final String fileName) {
+ try {
+ Path tempFilePath = Files.createTempFile(fileName, ".json");
+
+ Files.write(tempFilePath, Arrays.asList("{}"));
+
+ return tempFilePath.normalize().toString();
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to create temp config data file");
+ }
+ }
+
+ /**
+ * Generate dummy data file to be provided for honeycomb as config data
+ */
+ default String generateNonEmptyConfigDataFile(final String fileName, final int dataSampleSize) {
+ try {
+ Path tempFilePath = Files.createTempFile(fileName, ".json");
+
+ StringBuilder dataBuilder = new StringBuilder();
+
+ dataBuilder.append("{\"mm-bench:config-data\":{\"config-list\":[");
+
+ for (int i = 0; i < dataSampleSize; i++) {
+ dataBuilder.append("{\"name\":\"")
+ .append(String.valueOf(i))
+ .append("\"}");
+ if (i != dataSampleSize - 1) {
+ dataBuilder.append(",");
+ }
+ }
+
+ dataBuilder.append("]}}");
+
+ Files.write(tempFilePath, Arrays.asList(dataBuilder.toString()));
+
+ return tempFilePath.normalize().toString();
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to create temp config data file");
+ }
+ }
+}
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryFootprintBenchmark.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryFootprintBenchmark.java
new file mode 100644
index 000000000..48d805975
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryFootprintBenchmark.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2017 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.honeycomb.benchmark.memory;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import io.fd.honeycomb.benchmark.memory.config.BindableCfgAttrsModule;
+import io.fd.honeycomb.benchmark.memory.config.StaticHoneycombManagementModule;
+import io.fd.honeycomb.benchmark.memory.write.NoopWritersModule;
+import io.fd.honeycomb.infra.distro.Main;
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+import io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule;
+import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule;
+import io.fd.honeycomb.infra.distro.initializer.InitializerPipelineModule;
+import io.fd.honeycomb.infra.distro.netconf.NetconfModule;
+import io.fd.honeycomb.infra.distro.netconf.NetconfReadersModule;
+import io.fd.honeycomb.infra.distro.restconf.RestconfModule;
+import io.fd.honeycomb.infra.distro.schema.SchemaModule;
+import io.fd.honeycomb.infra.distro.schema.YangBindingProviderModule;
+import io.fd.honeycomb.management.jmx.JMXBeanProvider;
+import org.eclipse.jetty.server.Server;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXServiceURL;
+import java.util.Set;
+
+/**
+ * Measure memory consumption of config data storage
+ */
+public class MemoryFootprintBenchmark implements JMXBeanProvider, BenchmarkFilesProvider {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MemoryFootprintBenchmark.class);
+
+ /**
+ * All modules from infra to load.Not static to not persist state
+ */
+ private final Set<Module> BASE_MODULES = ImmutableSet.of(
+ new YangBindingProviderModule(),
+ new SchemaModule(),
+ new ConfigAndOperationalPipelineModule(),
+ new ContextPipelineModule(),
+ new InitializerPipelineModule(),
+ new NetconfModule(),
+ new NetconfReadersModule(),
+ new RestconfModule(),
+ // to enable jmx
+ new StaticHoneycombManagementModule(),
+ //adds noop writers
+ new NoopWritersModule());
+
+ // configuration class used to run benchmark, allows us to switch between honeycomb with data, or on rest
+ private final HoneycombConfiguration configuration;
+
+ // output file path
+ private final String outputPath;
+
+ public MemoryFootprintBenchmark(@Nonnull final HoneycombConfiguration configuration, @Nonnull final String outputPath) {
+ this.configuration = configuration;
+ this.outputPath = outputPath;
+ }
+
+ public void run() throws Exception {
+ // start honeycomb with configuration of BASE_MODULES + configuration class
+ final Injector injector = startHoneycomb();
+
+ // query memory beans with JMX and output results on output path
+ queryMemoryBeans(injector.getInstance(JMXServiceURL.class))
+ .forEach(memoryInfo -> outputBenchmarkResult(memoryInfo, outputPath, () -> LOG));
+ // shutdowns server instance
+ injector.getInstance(Server.class).stop();
+ }
+
+ /**
+ * start honeycomb with basic modules + provided static configuration
+ */
+ private Injector startHoneycomb() {
+ LOG.info("Starting embedded server with configuration {}", configuration);
+ return Main.init(ImmutableSet.<Module>builder()
+ .add(new BindableCfgAttrsModule(configuration))
+ .addAll(BASE_MODULES).build());
+ }
+
+ /**
+ * Queries heap and non-heap memory usage
+ */
+ private Set<MemoryInfo> queryMemoryBeans(final JMXServiceURL url) {
+ LOG.info("Requesting memory bean on url {}", url);
+
+ try (final JMXConnector connector = getConnector(url)) {
+ MemoryInfo heapMemoryInfo = new MemoryInfo(
+ (CompositeDataSupport) getJMXAttribute(connector, MemoryInfo.MEMORY_MBEAN_TYPE,
+ MemoryInfo.HEAP_MEMORY), MemoryInfo.HEAP_MEMORY);
+ LOG.info("Heap memory usage {}", heapMemoryInfo);
+
+ MemoryInfo nonHeapMemoryInfo = new MemoryInfo(
+ (CompositeDataSupport) getJMXAttribute(connector, MemoryInfo.MEMORY_MBEAN_TYPE,
+ MemoryInfo.NON_HEAP_MEMORY), MemoryInfo.NON_HEAP_MEMORY);
+ LOG.info("NonHeap memory usage {}", nonHeapMemoryInfo);
+ return ImmutableSet.of(heapMemoryInfo, nonHeapMemoryInfo);
+ } catch (Exception e) {
+ throw new IllegalStateException("Unable to query memory beans", e);
+ }
+ }
+
+}
+
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryInfo.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryInfo.java
new file mode 100644
index 000000000..f79006f78
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryInfo.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 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.honeycomb.benchmark.memory;
+
+import javax.annotation.Nonnull;
+import javax.management.openmbean.CompositeDataSupport;
+import java.util.Arrays;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Wrapped from data extracted from JMX beans of type Memory
+ * */
+public final class MemoryInfo {
+
+ public static final String MEMORY_MBEAN_TYPE = "java.lang:type=Memory";
+ public static final String HEAP_MEMORY = "HeapMemoryUsage";
+ public static final String NON_HEAP_MEMORY = "NonHeapMemoryUsage";
+
+ public static final String COMMITTED = "committed";
+ public static final String INIT = "init";
+ public static final String MAX = "max";
+ public static final String USED = "used";
+
+ private final String memoryInfoTypeName;
+ private final long committed, init, max, used;
+
+ public MemoryInfo(@Nonnull final CompositeDataSupport compositeData, @Nonnull final String memoryInfoTypeName) {
+ checkArgument(compositeData.getCompositeType().keySet().containsAll(Arrays.asList(COMMITTED, INIT, MAX, USED)),
+ "Submitted composite data %s does not contains necessary attributes", compositeData);
+ this.memoryInfoTypeName = memoryInfoTypeName;
+ this.committed = compositeDataAttributeValue(compositeData.get(COMMITTED));
+ this.init = compositeDataAttributeValue(compositeData.get(INIT));
+ this.max = compositeDataAttributeValue(compositeData.get(MAX));
+ this.used = compositeDataAttributeValue(compositeData.get(USED));
+
+ }
+
+ public String getMemoryInfoTypeName() {
+ return memoryInfoTypeName;
+ }
+
+ public long getCommitted() {
+ return committed;
+ }
+
+ public long getInit() {
+ return init;
+ }
+
+ public long getMax() {
+ return max;
+ }
+
+ public long getUsed() {
+ return used;
+ }
+
+ @Override
+ public String toString() {
+ return memoryInfoTypeName + "[" +
+ "committed=" + committed +
+ ",init=" + init +
+ ",max=" + max +
+ ",used=" + used +
+ ']';
+ }
+
+ private static Long compositeDataAttributeValue(final Object commited) {
+ checkArgument(commited instanceof Long, "Unsupported memory attribute value %s", commited.getClass());
+ return Long.class.cast(commited);
+ }
+}
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/BindableCfgAttrsModule.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/BindableCfgAttrsModule.java
new file mode 100644
index 000000000..03e3774db
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/BindableCfgAttrsModule.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 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.honeycomb.benchmark.memory.config;
+
+
+import com.google.inject.AbstractModule;
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+
+/**
+ * Provides ability to bind specific instance of static configuration
+ * */
+public class BindableCfgAttrsModule extends AbstractModule {
+
+ private final HoneycombConfiguration configToBind;
+
+ public BindableCfgAttrsModule(HoneycombConfiguration configToBind) {
+ this.configToBind = configToBind;
+ }
+
+ @Override
+ protected void configure() {
+ // Inject non-dependency configuration
+ bind(HoneycombConfiguration.class).toInstance(configToBind);
+ }
+}
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombConfiguration.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombConfiguration.java
new file mode 100644
index 000000000..6bcf7ef68
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombConfiguration.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017 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.honeycomb.benchmark.memory.config;
+
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+
+import javax.annotation.Nonnull;
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Optional;
+
+/**
+ * Static configuration to prevent injecting of properties from json fles
+ */
+public class StaticHoneycombConfiguration extends HoneycombConfiguration implements Closeable {
+
+ public StaticHoneycombConfiguration(@Nonnull final String persistConfigPath, @Nonnull final String persistContextPath) {
+ this.peristConfigPath = persistConfigPath;
+ this.peristContextPath = persistContextPath;
+
+ this.username = "admin";
+ this.password = "admin";
+ this.notificationServiceQueueDepth = 1;
+ this.restconfBindingAddress = Optional.of("/restconf");
+ this.restconfPort = Optional.of(8187);
+ this.restconfBindingAddress = Optional.of("127.0.0.1");
+ this.persistedConfigRestorationType = "Merge";
+ this.persistedContextRestorationType = "Merge";
+ this.restconfWebsocketPort = Optional.of(7890);
+ }
+
+ @Override
+ public boolean isConfigPersistenceEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isRestconfHttpsEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isRestconfHttpEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isRestconfEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isNetconfTcpEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isContextPersistenceEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isNetconfEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isNetconfSshEnabled() {
+ return false;
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (Files.exists(Paths.get(peristConfigPath))) {
+ Files.delete(Paths.get(peristConfigPath));
+ }
+
+ if (Files.exists(Paths.get(peristContextPath))) {
+ Files.delete(Paths.get(peristContextPath));
+ }
+ }
+}
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombManagementModule.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombManagementModule.java
new file mode 100644
index 000000000..a91d6ba84
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombManagementModule.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 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.honeycomb.benchmark.memory.config;
+
+import io.fd.honeycomb.management.jmx.ConnectorServerProvider;
+import io.fd.honeycomb.management.jmx.HoneycombManagementConfig;
+import io.fd.honeycomb.management.jmx.HoneycombManagementModule;
+import io.fd.honeycomb.management.jmx.JMXServiceUrlProvider;
+import org.eclipse.jetty.jmx.ConnectorServer;
+import org.eclipse.jetty.jmx.MBeanContainer;
+
+import javax.management.remote.JMXServiceURL;
+import java.lang.management.ManagementFactory;
+
+/**
+ * In this case we need to override Honeycomb config, but if standard management module is active,
+ * configuration module injection will cause attempt to inject attributes in HoneycombConfiguration,
+ * even if static instance is provider. Therefore here we need to override configure to also provide
+ * static instance for HoneycombManagementConfig
+ */
+public class StaticHoneycombManagementModule extends HoneycombManagementModule {
+
+ @Override
+ protected void configure() {
+ // all values are wrapped in Optionals with default values
+ bind(HoneycombManagementConfig.class).toInstance(new HoneycombManagementConfig());
+ bind(MBeanContainer.class).toInstance(new MBeanContainer(ManagementFactory.getPlatformMBeanServer()));
+ bind(JMXServiceURL.class).toProvider(JMXServiceUrlProvider.class);
+ bind(ConnectorServer.class).toProvider(ConnectorServerProvider.class).asEagerSingleton();
+
+ showAvailableBeans();
+ }
+}
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWriter.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWriter.java
new file mode 100644
index 000000000..000a176df
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWriter.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 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.honeycomb.benchmark.memory.write;
+
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.honeycomb.translate.write.Writer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public final class NoopWriter<T extends DataObject> implements Writer<T> {
+
+ private final InstanceIdentifier<T> id;
+
+ public NoopWriter(final InstanceIdentifier<T> id) {
+ this.id = id;
+ }
+
+ @Override
+ public void update(@Nonnull final InstanceIdentifier<? extends DataObject> id,
+ @Nullable final DataObject dataBefore,
+ @Nullable final DataObject dataAfter,
+ @Nonnull final WriteContext ctx) throws WriteFailedException {
+ // NOOP
+ }
+
+ @Nonnull
+ @Override
+ public InstanceIdentifier<T> getManagedDataObjectType() {
+ return id;
+ }
+
+ @Override
+ public String toString() {
+ return "NoopWriter{" +
+ id.getTargetType().getSimpleName() + '}';
+ }
+} \ No newline at end of file
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWritersModule.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWritersModule.java
new file mode 100644
index 000000000..a88c514c4
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWritersModule.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 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.honeycomb.benchmark.memory.write;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.multibindings.Multibinder;
+import io.fd.honeycomb.translate.write.WriterFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.memory.benchmark.rev161204.ConfigData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.memory.benchmark.rev161204.config.data.ConfigList;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class NoopWritersModule extends AbstractModule {
+ @Override
+ protected void configure() {
+
+ final Multibinder<WriterFactory> writeBinder = Multibinder.newSetBinder(binder(), WriterFactory.class);
+ writeBinder.addBinding().toInstance(registry -> {
+ // Add noop writers for all data written in this benchmark
+
+ registry.add(new NoopWriter<>(InstanceIdentifier.create(ConfigData.class)));
+ registry.add(new NoopWriter<>(InstanceIdentifier.create(ConfigData.class).child(ConfigList.class)));
+ });
+ }
+
+}
diff --git a/infra/it/memory-benchmark/src/test/java/io/fd/honeycomb/benchmark/memory/HoneycombFootprintTest.java b/infra/it/memory-benchmark/src/test/java/io/fd/honeycomb/benchmark/memory/HoneycombFootprintTest.java
new file mode 100644
index 000000000..b8817f8f4
--- /dev/null
+++ b/infra/it/memory-benchmark/src/test/java/io/fd/honeycomb/benchmark/memory/HoneycombFootprintTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017 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.honeycomb.benchmark.memory;
+
+import io.fd.honeycomb.benchmark.memory.config.StaticHoneycombConfiguration;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * Test honeycomb memory footprint while containing amount of nodes specified by
+ * parameter sampleSize.<br>
+ * Test must be triggered by separated scripts, not by Parametrized runner,<br>
+ * because of classes like WebSocketServer that is internally a singleton, therefore it holds static reference<br>
+ * on itself and would fail on second run on precondition, because junit kills threads, but does not unload classes
+ */
+public class HoneycombFootprintTest implements BenchmarkFilesProvider {
+
+ private static final String SAMPLE_SIZE_PROP = "sampleSize";
+ private static final String OUTPUT_PROP = "outPath";
+
+ private StaticHoneycombConfiguration staticHoneycombConfiguration;
+ private String outputPath;
+
+ @Before
+ public void init() {
+ outputPath = Objects.requireNonNull(System.getProperty(OUTPUT_PROP),
+ "No output file path specified, make sure you've specified -D" + OUTPUT_PROP + " parameter");
+ }
+
+ @Test
+ public void testHoneycombMemoryFootprintWithData() throws Exception {
+ final int dataSampleSize = Integer.valueOf(Objects.requireNonNull(System.getProperty(SAMPLE_SIZE_PROP),
+ "No sample data size defined, make sure you've specified -D" + SAMPLE_SIZE_PROP + " parameter"));
+
+ staticHoneycombConfiguration = new StaticHoneycombConfiguration(
+ generateNonEmptyConfigDataFile("temp-config", dataSampleSize),
+ generateEmptyJsonFile("temp-empty-context"));
+
+ new MemoryFootprintBenchmark(staticHoneycombConfiguration, outputPath).run();
+ }
+
+ @After
+ public void destroyTest() throws IOException {
+ // removes temp files,etc
+ staticHoneycombConfiguration.close();
+ }
+}