From 92afaeb4a959ea5a6a072fe3ed7a01088d703e0b Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Tue, 31 Jan 2017 10:00:51 +0100 Subject: 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 Signed-off-by: Jan Srnicek --- infra/it/management/asciidoc/Readme.adoc | 35 ++++ infra/it/management/pom.xml | 50 ++++++ .../management/jmx/ConnectorServerProvider.java | 54 ++++++ .../management/jmx/HoneycombManagementConfig.java | 49 ++++++ .../management/jmx/HoneycombManagementModule.java | 58 +++++++ .../honeycomb/management/jmx/JMXBeanProvider.java | 51 ++++++ .../management/jmx/JMXServiceUrlProvider.java | 45 +++++ .../management/src/main/resources/management.json | 2 + infra/it/memory-benchmark-api/asciidoc/Readme.adoc | 5 + infra/it/memory-benchmark-api/pom.xml | 15 ++ .../src/main/yang/memory-benchmark.yang | 19 +++ infra/it/memory-benchmark-scripts/pom.xml | 72 ++++++++ .../MemoryBenchmarkStartupScriptGenerator.groovy | 38 +++++ .../src/main/resources/memoryBenchmarkScript | 2 + infra/it/memory-benchmark/asciidoc/Readme.adoc | 68 ++++++++ infra/it/memory-benchmark/pom.xml | 184 +++++++++++++++++++++ .../src/main/assembly/assembly.xml | 30 ++++ .../benchmark/memory/BenchmarkFilesProvider.java | 95 +++++++++++ .../benchmark/memory/MemoryFootprintBenchmark.java | 125 ++++++++++++++ .../fd/honeycomb/benchmark/memory/MemoryInfo.java | 87 ++++++++++ .../memory/config/BindableCfgAttrsModule.java | 38 +++++ .../config/StaticHoneycombConfiguration.java | 97 +++++++++++ .../config/StaticHoneycombManagementModule.java | 46 ++++++ .../benchmark/memory/write/NoopWriter.java | 54 ++++++ .../benchmark/memory/write/NoopWritersModule.java | 38 +++++ .../benchmark/memory/HoneycombFootprintTest.java | 64 +++++++ infra/it/pom.xml | 22 ++- 27 files changed, 1441 insertions(+), 2 deletions(-) create mode 100644 infra/it/management/asciidoc/Readme.adoc create mode 100644 infra/it/management/pom.xml create mode 100644 infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/ConnectorServerProvider.java create mode 100644 infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementConfig.java create mode 100644 infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementModule.java create mode 100644 infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXBeanProvider.java create mode 100644 infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXServiceUrlProvider.java create mode 100644 infra/it/management/src/main/resources/management.json create mode 100644 infra/it/memory-benchmark-api/asciidoc/Readme.adoc create mode 100644 infra/it/memory-benchmark-api/pom.xml create mode 100644 infra/it/memory-benchmark-api/src/main/yang/memory-benchmark.yang create mode 100644 infra/it/memory-benchmark-scripts/pom.xml create mode 100644 infra/it/memory-benchmark-scripts/src/main/groovy/io/fd/honeycomb/benchmark/script/MemoryBenchmarkStartupScriptGenerator.groovy create mode 100644 infra/it/memory-benchmark-scripts/src/main/resources/memoryBenchmarkScript create mode 100644 infra/it/memory-benchmark/asciidoc/Readme.adoc create mode 100644 infra/it/memory-benchmark/pom.xml create mode 100644 infra/it/memory-benchmark/src/main/assembly/assembly.xml create mode 100644 infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/BenchmarkFilesProvider.java create mode 100644 infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryFootprintBenchmark.java create mode 100644 infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryInfo.java create mode 100644 infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/BindableCfgAttrsModule.java create mode 100644 infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombConfiguration.java create mode 100644 infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombManagementModule.java create mode 100644 infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWriter.java create mode 100644 infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWritersModule.java create mode 100644 infra/it/memory-benchmark/src/test/java/io/fd/honeycomb/benchmark/memory/HoneycombFootprintTest.java (limited to 'infra/it') diff --git a/infra/it/management/asciidoc/Readme.adoc b/infra/it/management/asciidoc/Readme.adoc new file mode 100644 index 000000000..89bbf65d3 --- /dev/null +++ b/infra/it/management/asciidoc/Readme.adoc @@ -0,0 +1,35 @@ += management + +This modules is used to enable JMX monitoring on honeycomb Instance. + += Tutorial +== Configure +To build honeycomb with management module incldued + + mvn clean install -DskipTests -Pmanagement + +After this management module must be included to honeycomb module configuration. +In /minimal-distribution/modules , just include fully qualified name of management module like so + + io.fd.honeycomb.management.jmx.HoneycombManagementModule + +This will start all necessary beans to allow jmx connections to honeycomb instance. +Also in logs , you will see all available JMX beans + +== Use + +To get any available JMX bean, +use interface *JMXBeanProvider* that defines utility method to get *JMXConnector* + + // get configured instance of jxm connection url according to HoneycombManagementConfig + @Inject JMXServiceUrl url; + + // creates JMX connector + final JMXConnector connector = getConnector(url); + // to get any available bean + final String beanType = "java.lang:type=Memory"; + final String beanName = "HeapMemoryUsage"; + final Object jmxBean = getJMXAttribute(connector, beanType, beanName); + + + diff --git a/infra/it/management/pom.xml b/infra/it/management/pom.xml new file mode 100644 index 000000000..0a8e97200 --- /dev/null +++ b/infra/it/management/pom.xml @@ -0,0 +1,50 @@ + + + + + + io.fd.honeycomb.common + honeycomb-parent + 1.17.04-SNAPSHOT + ../../../common/honeycomb-parent + + 4.0.0 + + + 9.3.11.v20160721 + + + io.fd.honeycomb.it + management + 1.17.04-SNAPSHOT + + + + org.eclipse.jetty + jetty-jmx + ${jetty-jmx.version} + + + + io.fd.honeycomb + minimal-distribution + ${project.version} + + + \ No newline at end of file diff --git a/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/ConnectorServerProvider.java b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/ConnectorServerProvider.java new file mode 100644 index 000000000..625c63cb8 --- /dev/null +++ b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/ConnectorServerProvider.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.management.jmx; + +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import org.eclipse.jetty.jmx.ConnectorServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.management.remote.JMXServiceURL; + +/** + * Provides and start JMX connector server + * */ +public class ConnectorServerProvider extends ProviderTrait { + + private static final Logger LOG = LoggerFactory.getLogger(ConnectorServerProvider.class); + + @Inject + private HoneycombManagementConfig config; + + @Inject + private JMXServiceURL jmxServiceUrl; + + @Override + protected ConnectorServer create() { + try { + final ConnectorServer connectorServer = new ConnectorServer(jmxServiceUrl, + "org.eclipse.jetty.jmx:name="+HoneycombManagementConfig.JXM_CONNECTOR_SERVER_NAME); + + LOG.info("Starting connector server {}", connectorServer); + connectorServer.doStart(); + + return connectorServer; + } catch (Exception e) { + throw new IllegalStateException("Unable to create jmx connector server", e); + } + } +} diff --git a/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementConfig.java b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementConfig.java new file mode 100644 index 000000000..2362b6f43 --- /dev/null +++ b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementConfig.java @@ -0,0 +1,49 @@ +/* + * 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.management.jmx; + + +import net.jmob.guice.conf.core.BindConfig; +import net.jmob.guice.conf.core.InjectConfig; +import net.jmob.guice.conf.core.Syntax; + +import java.util.Optional; + +@BindConfig(value = "management", syntax = Syntax.JSON) +public class HoneycombManagementConfig { + + public static final String JMX_PROTOCOL = "rmi"; + public static final String JXM_CONNECTOR_SERVER_NAME = "rmi"; + + public static final String PROP_JMX_HOST = "jetty.jmxrmihost"; + public static final String PROP_JMX_PORT = "jetty.jmxrmiport"; + + + @InjectConfig(PROP_JMX_HOST) + private String jmxHost; + + @InjectConfig(PROP_JMX_PORT) + private String jmxPort; + + public String getJmxHost() { + return Optional.ofNullable(jmxHost).orElse("localhost"); + } + + public int getJmxPort() { + return Integer.parseInt(Optional.ofNullable(jmxPort).orElse("1099")); + } +} diff --git a/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementModule.java b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementModule.java new file mode 100644 index 000000000..bc75cd01f --- /dev/null +++ b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementModule.java @@ -0,0 +1,58 @@ +/* + * 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.management.jmx; + + +import com.google.inject.AbstractModule; +import net.jmob.guice.conf.core.ConfigurationModule; +import org.eclipse.jetty.jmx.ConnectorServer; +import org.eclipse.jetty.jmx.MBeanContainer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.management.ObjectInstance; +import javax.management.remote.JMXServiceURL; +import java.lang.management.ManagementFactory; + +public class HoneycombManagementModule extends AbstractModule { + + private static final Logger LOG = LoggerFactory.getLogger(HoneycombManagementModule.class); + + @Override + protected void configure() { + install(ConfigurationModule.create()); + requestInjection(HoneycombManagementConfig.class); + bind(MBeanContainer.class).toInstance(new MBeanContainer(ManagementFactory.getPlatformMBeanServer())); + bind(JMXServiceURL.class).toProvider(JMXServiceUrlProvider.class); + // .asEagerSingleton(); will cause also start defined in provider + bind(ConnectorServer.class).toProvider(ConnectorServerProvider.class).asEagerSingleton(); + + showAvailableBeans(); + } + + /** + * Prints all available JMX beans + */ + protected static void showAvailableBeans() { + for (final ObjectInstance instance : ManagementFactory.getPlatformMBeanServer().queryMBeans(null, null)) { + LOG.info("MBean Found:"); + LOG.info("Class Name:{}", instance.getClassName()); + LOG.info("Object Name:{}", instance.getObjectName()); + LOG.info("****************************************"); + } + } +} diff --git a/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXBeanProvider.java b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXBeanProvider.java new file mode 100644 index 000000000..557acb464 --- /dev/null +++ b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXBeanProvider.java @@ -0,0 +1,51 @@ +/* + * 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.management.jmx; + +import javax.annotation.Nonnull; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; +import java.io.IOException; + +public interface JMXBeanProvider { + + /** + * Provides JMX connector to specified url + */ + default JMXConnector getConnector(@Nonnull final JMXServiceURL url) { + try { + return JMXConnectorFactory.connect(url); + } catch (IOException e) { + throw new IllegalStateException("Unable to create JMX connector", e); + } + } + + /** + * Requests specified jxm bean from provided connector + */ + default Object getJMXAttribute(@Nonnull final JMXConnector connector, @Nonnull final String beanType, + @Nonnull final String beanName) { + try { + return connector.getMBeanServerConnection().getAttribute(new ObjectName(beanType), beanName); + } catch (Exception e) { + throw new IllegalStateException( + String.format("Unable to query mbean of type %s, name %s", beanType, beanName), e); + } + } +} diff --git a/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXServiceUrlProvider.java b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXServiceUrlProvider.java new file mode 100644 index 000000000..1b9136501 --- /dev/null +++ b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXServiceUrlProvider.java @@ -0,0 +1,45 @@ +/* + * 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.management.jmx; + +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; + +import javax.management.remote.JMXServiceURL; +import java.net.MalformedURLException; + +/** + * Provides properly binded {@link JMXServiceURL} + */ +public class JMXServiceUrlProvider extends ProviderTrait { + + @Inject + private HoneycombManagementConfig config; + + @Override + protected JMXServiceURL create() { + try { + return new JMXServiceURL( + HoneycombManagementConfig.JMX_PROTOCOL, + config.getJmxHost(), + config.getJmxPort(), + "/jndi/rmi://" + config.getJmxHost() + ":" + config.getJmxPort() + "/jmxrmi"); + } catch (MalformedURLException e) { + throw new IllegalStateException("Unable to create JXM Service url", e); + } + } +} diff --git a/infra/it/management/src/main/resources/management.json b/infra/it/management/src/main/resources/management.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/infra/it/management/src/main/resources/management.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/infra/it/memory-benchmark-api/asciidoc/Readme.adoc b/infra/it/memory-benchmark-api/asciidoc/Readme.adoc new file mode 100644 index 000000000..c63073613 --- /dev/null +++ b/infra/it/memory-benchmark-api/asciidoc/Readme.adoc @@ -0,0 +1,5 @@ += memory-benchmark-api + +Overview of memory-benchmark-api + +Provides test models for honeycomb memory benchmark. \ No newline at end of file diff --git a/infra/it/memory-benchmark-api/pom.xml b/infra/it/memory-benchmark-api/pom.xml new file mode 100644 index 000000000..8b92303ec --- /dev/null +++ b/infra/it/memory-benchmark-api/pom.xml @@ -0,0 +1,15 @@ + + + + api-parent + io.fd.honeycomb.common + 1.17.04-SNAPSHOT + + 4.0.0 + + io.fd.honeycomb.it + memory-benchmark-api + 1.17.04-SNAPSHOT + \ No newline at end of file diff --git a/infra/it/memory-benchmark-api/src/main/yang/memory-benchmark.yang b/infra/it/memory-benchmark-api/src/main/yang/memory-benchmark.yang new file mode 100644 index 000000000..e01550659 --- /dev/null +++ b/infra/it/memory-benchmark-api/src/main/yang/memory-benchmark.yang @@ -0,0 +1,19 @@ +module memory-benchmark { + + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:memory:benchmark"; + prefix "mm-bench"; + + revision "2016-12-04" { + description "Memory benchmark test api"; + } + + container config-data { + list config-list { + key name; + leaf name { + type string; + } + } + } +} \ No newline at end of file diff --git a/infra/it/memory-benchmark-scripts/pom.xml b/infra/it/memory-benchmark-scripts/pom.xml new file mode 100644 index 000000000..b6b29e5e2 --- /dev/null +++ b/infra/it/memory-benchmark-scripts/pom.xml @@ -0,0 +1,72 @@ + + + + + + + + 2.0 + 2.4.7 + 2.9.2-01 + 2.4.3-01 + + + 4.0.0 + io.fd.honeycomb.it + benchmark-scripts + 1.17.04-SNAPSHOT + jar + + + + + + org.apache.maven.plugins + maven-site-plugin + + true + true + + + + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler.version} + true + + + maven-compiler-plugin + + + groovy-eclipse-compiler + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler.version} + + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch.version} + + + + + + + + + org.codehaus.groovy + groovy-all + ${groovy.version} + + + \ No newline at end of file diff --git a/infra/it/memory-benchmark-scripts/src/main/groovy/io/fd/honeycomb/benchmark/script/MemoryBenchmarkStartupScriptGenerator.groovy b/infra/it/memory-benchmark-scripts/src/main/groovy/io/fd/honeycomb/benchmark/script/MemoryBenchmarkStartupScriptGenerator.groovy new file mode 100644 index 000000000..1db656aca --- /dev/null +++ b/infra/it/memory-benchmark-scripts/src/main/groovy/io/fd/honeycomb/benchmark/script/MemoryBenchmarkStartupScriptGenerator.groovy @@ -0,0 +1,38 @@ +package io.fd.honeycomb.benchmark.script + +import groovy.text.SimpleTemplateEngine + +import java.nio.file.Files +import java.nio.file.Paths + +class MemoryBenchmarkStartupScriptGenerator { + + static final def STARTUP_SCRIPT_ON_REST_TEMPLATE = MemoryBenchmarkStartupScriptGenerator.getResource("/memoryBenchmarkScript") + static final def STARTUP_SCRIPT_NAME_BASE = "honeycomb-memory-footprint-benchmark-" + + static final def FOOTPRINT_TEST_CLASS = "io.fd.honeycomb.benchmark.memory.HoneycombFootprintTest" + + static final def OUTPUT_PATH_PARAM = "-DoutPath=\$(dirname \$0)/" + static final def SAMPLE_SIZE_PARAM = "-DsampleSize=" + + /** + * Generate script to run io.fd.honeycomb.benchmark.memory.HoneycombWithDataTest with provided params + * */ + public static void generateWithDataScript(project, log, String outputFileName, dataSampleSize) { + log.info "Binding execution script for with-data benchmark[output=${outputFileName},sampleSize=${dataSampleSize}]" + def scriptContent = new SimpleTemplateEngine().createTemplate(STARTUP_SCRIPT_ON_REST_TEMPLATE).make( + [ + "testParams" : "${OUTPUT_PATH_PARAM}${outputFileName}-${dataSampleSize} ${SAMPLE_SIZE_PARAM}${dataSampleSize}", + "testClass" : FOOTPRINT_TEST_CLASS + ]).toString() + flushScript(Paths.get(project.build.directory, "${STARTUP_SCRIPT_NAME_BASE}${dataSampleSize}"), scriptContent, log) + } + + private static flushScript(filePath, content,log) { + log.info "Saving script to path ${filePath}" + def file = Files.createFile(filePath).toFile() + + file.text = content + file.setExecutable(true) + } +} diff --git a/infra/it/memory-benchmark-scripts/src/main/resources/memoryBenchmarkScript b/infra/it/memory-benchmark-scripts/src/main/resources/memoryBenchmarkScript new file mode 100644 index 000000000..120cb00e0 --- /dev/null +++ b/infra/it/memory-benchmark-scripts/src/main/resources/memoryBenchmarkScript @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +java -cp .:memory-benchmark-1.0.0-with-tests.jar ${testParams} org.junit.runner.JUnitCore ${testClass} \ No newline at end of file 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 @@ + + + + + + + io.fd.honeycomb.common + honeycomb-parent + 1.17.04-SNAPSHOT + ../../../common/honeycomb-parent + + 4.0.0 + + io.fd.honeycomb.it + memory-benchmark + + 1.0.0 + + 1.4 + 1.17.04-SNAPSHOT + 2.0 + 2.4.7 + 2.9.2-01 + 2.4.3-01 + + + jar + + + + io.fd.honeycomb.it + memory-benchmark-api + ${honeycomb.version} + + + + io.fd.honeycomb + minimal-distribution + ${honeycomb.version} + + + + io.fd.honeycomb.it + management + ${honeycomb.version} + + + + org.apache.commons + commons-csv + ${commons-csv.version} + + + + org.codehaus.groovy + groovy-all + ${groovy.version} + + + + junit + junit + test + + + org.mockito + mockito-core + test + + + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + true + + + + + + maven-assembly-plugin + 2.3 + + src/main/assembly/assembly.xml + + + + make-assembly + package + + single + + + + + + + + org.codehaus.gmaven + groovy-maven-plugin + + + + generate-on-rest-benchmark-script + package + + execute + + + + + io.fd.honeycomb.benchmark.script.MemoryBenchmarkStartupScriptGenerator.generateWithDataScript(project, log, "memory-benchmark-on-rest-out", 0) + + + + + + generate-with-data-1000-benchmark-script + package + + execute + + + + io.fd.honeycomb.benchmark.script.MemoryBenchmarkStartupScriptGenerator.generateWithDataScript(project, log, "memory-benchmark-with-data-out", 1000) + + + + + + generate-with-data-10000-benchmark-script + package + + execute + + + + io.fd.honeycomb.benchmark.script.MemoryBenchmarkStartupScriptGenerator.generateWithDataScript(project, log, "memory-benchmark-with-data-out", 10000) + + + + + + + io.fd.honeycomb.it + benchmark-scripts + 1.17.04-SNAPSHOT + + + + + + \ 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 @@ + + with-tests + + jar + + false + + + / + true + + true + true + test + + + + + ${project.build.directory}/test-classes + / + + **/*.class + + true + + + \ 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 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 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.builder() + .add(new BindableCfgAttrsModule(configuration)) + .addAll(BASE_MODULES).build()); + } + + /** + * Queries heap and non-heap memory usage + */ + private Set 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 implements Writer { + + private final InstanceIdentifier id; + + public NoopWriter(final InstanceIdentifier id) { + this.id = id; + } + + @Override + public void update(@Nonnull final InstanceIdentifier id, + @Nullable final DataObject dataBefore, + @Nullable final DataObject dataAfter, + @Nonnull final WriteContext ctx) throws WriteFailedException { + // NOOP + } + + @Nonnull + @Override + public InstanceIdentifier 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 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.
+ * Test must be triggered by separated scripts, not by Parametrized runner,
+ * because of classes like WebSocketServer that is internally a singleton, therefore it holds static reference
+ * 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(); + } +} diff --git a/infra/it/pom.xml b/infra/it/pom.xml index da6e3c2b8..cbf8eae62 100644 --- a/infra/it/pom.xml +++ b/infra/it/pom.xml @@ -34,15 +34,33 @@ it-test - - + benchmark benchmark + + + + management + + management + + + + + + memory-benchmark + + management + memory-benchmark-scripts + memory-benchmark + memory-benchmark-api + + -- cgit 1.2.3-korg