From c7eea9a927157a6036288564c2138e4ecd604129 Mon Sep 17 00:00:00 2001 From: Reiner Jung <reiner.jung@email.uni-kiel.de> Date: Fri, 20 Nov 2020 15:55:41 +0100 Subject: [PATCH] Updated Moobench code. Refactored and working on support for Kieker 1.14 --- .gitignore | 6 + build.gradle | 36 +++ .../OverheadEvaluationMicrobenchmark}/LICENSE | 0 .../MooBench/benchmark.sh | 0 .../MooBench/collector-2.0/bin/collector | 0 .../MooBench/collector-2.0/bin/collector.bat | 0 .../collector-2.0/lib/collector-2.0.jar | Bin .../collector-2.0/lib/jcommander-1.72.jar | Bin .../collector-2.0/lib/log4j-1.2.17.jar | Bin .../collector-2.0/lib/slf4j-api-1.7.25.jar | Bin .../lib/slf4j-log4j12-1.7.25.jar | Bin .../MooBench/common-functions | 0 .../MooBench/config | 0 .../MooBench/lib/.gitignore | 0 .../MooBench/log4j.cfg | 0 .../MooBench/moobench-2.0-all.jar | Bin .../MooBench/r/stats.csv.r | 0 .../OverheadEvaluationMicrobenchmark}/README | 0 .../executeRemoteMicroBenchmark.sh | 0 .../rerun-benchmark.sh | 0 frameworks/Kieker/build.gradle | 12 + .../src/kieker/tcp/TestExperiment1.java | 266 ------------------ .../src/kieker/tcp/TestExperiment2.java | 83 ------ .../src/kieker/tcp/TestExperiment3.java | 86 ------ .../java/moobench}/kieker/Logger.java | 7 +- .../kieker/tcp/TestConfiguration1.java | 15 + .../kieker/tcp/TestConfiguration2.java | 45 +++ .../kieker/tcp/TestConfiguration3.java | 42 +++ .../moobench}/kieker/tcp/TestExperiment0.java | 2 +- .../moobench/kieker/tcp/TestExperiment1.java | 35 +++ .../moobench/kieker/tcp/TestExperiment2.java | 38 +++ .../moobench/kieker/tcp/TestExperiment3.java | 38 +++ frameworks/SPASSmeter/build.gradle | 8 + frameworks/inspectIT/build.gradle | 8 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 58910 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 185 ++++++++++++ gradlew.bat | 104 +++++++ lib/commons-cli-1.2.LICENSE | 207 -------------- lib/commons-cli-1.2.jar | Bin 41123 -> 0 bytes moobench/build.gradle | 12 + .../moobench/application}/MonitoredClass.java | 2 +- .../application}/MonitoredClassSimple.java | 2 +- .../application}/MonitoredClassThreaded.java | 2 +- .../moobench/benchmark/BenchmarkMain.java | 158 +++++++++++ .../benchmark/BenchmarkParameter.java | 91 ++++++ .../benchmark/BenchmarkingThread.java | 2 +- .../benchmark/BenchmarkingThreadMilli.java | 4 +- .../benchmark/BenchmarkingThreadNano.java | 4 +- settings.gradle | 16 ++ src/META-INF/.gitignore | 4 - src/mooBench/benchmark/Benchmark.java | 240 ---------------- 52 files changed, 866 insertions(+), 899 deletions(-) create mode 100644 build.gradle rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/LICENSE (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/benchmark.sh (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/collector-2.0/bin/collector (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/collector-2.0/bin/collector.bat (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/collector-2.0/lib/collector-2.0.jar (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/collector-2.0/lib/jcommander-1.72.jar (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/collector-2.0/lib/log4j-1.2.17.jar (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/collector-2.0/lib/slf4j-api-1.7.25.jar (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/collector-2.0/lib/slf4j-log4j12-1.7.25.jar (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/common-functions (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/config (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/lib/.gitignore (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/log4j.cfg (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/moobench-2.0-all.jar (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/MooBench/r/stats.csv.r (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/README (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/executeRemoteMicroBenchmark.sh (100%) rename {OverheadEvaluationMicrobenchmark => frameworks/Kieker/OverheadEvaluationMicrobenchmark}/rerun-benchmark.sh (100%) create mode 100644 frameworks/Kieker/build.gradle delete mode 100644 frameworks/Kieker/src/kieker/tcp/TestExperiment1.java delete mode 100644 frameworks/Kieker/src/kieker/tcp/TestExperiment2.java delete mode 100644 frameworks/Kieker/src/kieker/tcp/TestExperiment3.java rename frameworks/Kieker/src/{ => main/java/moobench}/kieker/Logger.java (87%) create mode 100644 frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration1.java create mode 100644 frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration2.java create mode 100644 frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration3.java rename frameworks/Kieker/src/{ => main/java/moobench}/kieker/tcp/TestExperiment0.java (99%) create mode 100644 frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment1.java create mode 100644 frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment2.java create mode 100644 frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment3.java create mode 100644 frameworks/SPASSmeter/build.gradle create mode 100644 frameworks/inspectIT/build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat delete mode 100644 lib/commons-cli-1.2.LICENSE delete mode 100644 lib/commons-cli-1.2.jar create mode 100644 moobench/build.gradle rename {src/mooBench/monitoredApplication => moobench/src/main/java/moobench/application}/MonitoredClass.java (95%) rename {src/mooBench/monitoredApplication => moobench/src/main/java/moobench/application}/MonitoredClassSimple.java (97%) rename {src/mooBench/monitoredApplication => moobench/src/main/java/moobench/application}/MonitoredClassThreaded.java (97%) create mode 100644 moobench/src/main/java/moobench/benchmark/BenchmarkMain.java create mode 100644 moobench/src/main/java/moobench/benchmark/BenchmarkParameter.java rename {src/mooBench => moobench/src/main/java/moobench}/benchmark/BenchmarkingThread.java (97%) rename {src/mooBench => moobench/src/main/java/moobench}/benchmark/BenchmarkingThreadMilli.java (96%) rename {src/mooBench => moobench/src/main/java/moobench}/benchmark/BenchmarkingThreadNano.java (97%) create mode 100644 settings.gradle delete mode 100644 src/META-INF/.gitignore delete mode 100644 src/mooBench/benchmark/Benchmark.java diff --git a/.gitignore b/.gitignore index 9119436..a543dc0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,9 @@ /build/ /dist/ /tmp/ + +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..041f1ac --- /dev/null +++ b/build.gradle @@ -0,0 +1,36 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This generated file contains a sample Java project to get you started. + * For more details take a look at the Java Quickstart chapter in the Gradle + * User Manual available at https://docs.gradle.org/6.5/userguide/tutorial_java_projects.html + */ + +plugins { + id 'java' +} + +repositories { + // Use jcenter for resolving dependencies. + // You can declare any Maven/Ivy/file repository here. + jcenter() + mavenCentral() +} + +dependencies { + // This dependency is used by the application. + implementation 'com.google.guava:guava:29.0-jre' + implementation 'com.beust:jcommander:1.72' + + // Use JUnit test framework + testImplementation 'junit:junit:4.13' +} + +subprojects { + repositories { + // Use jcenter for resolving dependencies. + // You can declare any Maven/Ivy/file repository here. + jcenter() + mavenCentral() +} +} diff --git a/OverheadEvaluationMicrobenchmark/LICENSE b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/LICENSE similarity index 100% rename from OverheadEvaluationMicrobenchmark/LICENSE rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/LICENSE diff --git a/OverheadEvaluationMicrobenchmark/MooBench/benchmark.sh b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/benchmark.sh similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/benchmark.sh rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/benchmark.sh diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector.bat b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector.bat similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector.bat rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector.bat diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/collector-2.0.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/collector-2.0.jar similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/collector-2.0.jar rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/collector-2.0.jar diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/jcommander-1.72.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/jcommander-1.72.jar similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/jcommander-1.72.jar rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/jcommander-1.72.jar diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/log4j-1.2.17.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/log4j-1.2.17.jar similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/log4j-1.2.17.jar rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/log4j-1.2.17.jar diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-api-1.7.25.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-api-1.7.25.jar similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-api-1.7.25.jar rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-api-1.7.25.jar diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-log4j12-1.7.25.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-log4j12-1.7.25.jar similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-log4j12-1.7.25.jar rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-log4j12-1.7.25.jar diff --git a/OverheadEvaluationMicrobenchmark/MooBench/common-functions b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/common-functions similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/common-functions rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/common-functions diff --git a/OverheadEvaluationMicrobenchmark/MooBench/config b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/config similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/config rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/config diff --git a/OverheadEvaluationMicrobenchmark/MooBench/lib/.gitignore b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/lib/.gitignore similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/lib/.gitignore rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/lib/.gitignore diff --git a/OverheadEvaluationMicrobenchmark/MooBench/log4j.cfg b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/log4j.cfg similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/log4j.cfg rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/log4j.cfg diff --git a/OverheadEvaluationMicrobenchmark/MooBench/moobench-2.0-all.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/moobench-2.0-all.jar similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/moobench-2.0-all.jar rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/moobench-2.0-all.jar diff --git a/OverheadEvaluationMicrobenchmark/MooBench/r/stats.csv.r b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/r/stats.csv.r similarity index 100% rename from OverheadEvaluationMicrobenchmark/MooBench/r/stats.csv.r rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/r/stats.csv.r diff --git a/OverheadEvaluationMicrobenchmark/README b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/README similarity index 100% rename from OverheadEvaluationMicrobenchmark/README rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/README diff --git a/OverheadEvaluationMicrobenchmark/executeRemoteMicroBenchmark.sh b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/executeRemoteMicroBenchmark.sh similarity index 100% rename from OverheadEvaluationMicrobenchmark/executeRemoteMicroBenchmark.sh rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/executeRemoteMicroBenchmark.sh diff --git a/OverheadEvaluationMicrobenchmark/rerun-benchmark.sh b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/rerun-benchmark.sh similarity index 100% rename from OverheadEvaluationMicrobenchmark/rerun-benchmark.sh rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/rerun-benchmark.sh diff --git a/frameworks/Kieker/build.gradle b/frameworks/Kieker/build.gradle new file mode 100644 index 0000000..7f69424 --- /dev/null +++ b/frameworks/Kieker/build.gradle @@ -0,0 +1,12 @@ +plugins { + id 'java' + id 'application' +} + +dependencies { + implementation project(':moobench') + implementation 'net.kieker-monitoring:kieker:1.14' + implementation 'net.sourceforge.teetime:teetime:3.0' + implementation 'org.slf4j:slf4j-api:1.7.+' + implementation 'ch.qos.logback:logback-classic:1.2.3' +} diff --git a/frameworks/Kieker/src/kieker/tcp/TestExperiment1.java b/frameworks/Kieker/src/kieker/tcp/TestExperiment1.java deleted file mode 100644 index 335259e..0000000 --- a/frameworks/Kieker/src/kieker/tcp/TestExperiment1.java +++ /dev/null @@ -1,266 +0,0 @@ -/*************************************************************************** - * Copyright 2014 Kieker Project (http://kieker-monitoring.net) - * - * 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 kieker.tcp; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import kieker.analysis.AnalysisController; -import kieker.analysis.IAnalysisController; -import kieker.analysis.IProjectContext; -import kieker.analysis.exception.AnalysisConfigurationException; -import kieker.analysis.plugin.annotation.OutputPort; -import kieker.analysis.plugin.annotation.Plugin; -import kieker.analysis.plugin.annotation.Property; -import kieker.analysis.plugin.reader.AbstractReaderPlugin; -import kieker.common.configuration.Configuration; -import kieker.common.exception.MonitoringRecordException; -import kieker.common.logging.Log; -import kieker.common.logging.LogFactory; -import kieker.common.record.AbstractMonitoringRecord; -import kieker.common.record.IMonitoringRecord; -import kieker.common.record.misc.RegistryRecord; -import kieker.common.util.registry.ILookup; -import kieker.common.util.registry.Lookup; - -// Command-Line: -// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000 -/** - * @author Jan Waller - */ -public final class TestExperiment1 { - private static final Log LOG = LogFactory.getLog(TestExperiment1.class); - - private TestExperiment1() {} - - public static void main(final String[] args) { - final IAnalysisController analysisController = new AnalysisController("TCPThroughput"); - TestExperiment1.createAndConnectPlugins(analysisController); - try { - analysisController.run(); - } catch (final AnalysisConfigurationException ex) { - TestExperiment1.LOG.error("Failed to start the example project.", ex); - } - } - - private static void createAndConnectPlugins(final IAnalysisController analysisController) { - final Configuration readerConfig = new Configuration(); - // readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT1, 10333); - // readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT2, 10334); - final TCPCountingReader reader = new TCPCountingReader(readerConfig, analysisController); - reader.getName(); // to remove unused warning - } -} - -/** - * - * @author Jan Waller - * - * @since 1.8 - */ -@Plugin(description = "A reader which reads records from a TCP port", - outputPorts = { - @OutputPort(name = TCPCountingReader.OUTPUT_PORT_NAME_RECORDS, eventTypes = { IMonitoringRecord.class }, description = "Output Port of the TCPReader") - }, - configuration = { - @Property(name = TCPCountingReader.CONFIG_PROPERTY_NAME_PORT1, defaultValue = "10133", - description = "The first port of the server used for the TCP connection."), - @Property(name = TCPCountingReader.CONFIG_PROPERTY_NAME_PORT2, defaultValue = "10134", - description = "The second port of the server used for the TCP connection.") - }) -final class TCPCountingReader extends AbstractReaderPlugin { - - /** The name of the output port delivering the received records. */ - public static final String OUTPUT_PORT_NAME_RECORDS = "monitoringRecords"; - - /** The name of the configuration determining the TCP port. */ - public static final String CONFIG_PROPERTY_NAME_PORT1 = "port1"; - /** The name of the configuration determining the TCP port. */ - public static final String CONFIG_PROPERTY_NAME_PORT2 = "port2"; - - private static final int MESSAGE_BUFFER_SIZE = 65535; - - static final Log LOG = LogFactory.getLog(TCPCountingReader.class); - - private final int port1; - private final int port2; - private final ILookup<String> stringRegistry = new Lookup<String>(); - - final AtomicInteger counter = new AtomicInteger(0); - final ScheduledExecutorService executorService; - - public TCPCountingReader(final Configuration configuration, final IProjectContext projectContext) { - super(configuration, projectContext); - this.port1 = this.configuration.getIntProperty(CONFIG_PROPERTY_NAME_PORT1); - this.port2 = this.configuration.getIntProperty(CONFIG_PROPERTY_NAME_PORT2); - this.executorService = new ScheduledThreadPoolExecutor(1); - } - - @Override - public boolean init() { - this.executorService.scheduleAtFixedRate(new Runnable() { - public void run() { - System.out.println("Records/s: " + TCPCountingReader.this.counter.getAndSet(0)); - } - }, 0, 1, TimeUnit.SECONDS); - - final TCPStringReader tcpStringReader = new TCPStringReader(this.port2, this.stringRegistry); - tcpStringReader.start(); - return super.init(); - } - - @Override - public Configuration getCurrentConfiguration() { - final Configuration configuration = new Configuration(); - configuration.setProperty(CONFIG_PROPERTY_NAME_PORT1, Integer.toString(this.port1)); - configuration.setProperty(CONFIG_PROPERTY_NAME_PORT2, Integer.toString(this.port2)); - return configuration; - } - - public boolean read() { - ServerSocketChannel serversocket = null; - try { - serversocket = ServerSocketChannel.open(); - serversocket.socket().bind(new InetSocketAddress(this.port1)); - if (LOG.isDebugEnabled()) { - LOG.debug("Listening on port " + this.port1); - } - // BEGIN also loop this one? - final SocketChannel socketChannel = serversocket.accept(); - final ByteBuffer buffer = ByteBuffer.allocateDirect(MESSAGE_BUFFER_SIZE); - while (socketChannel.read(buffer) != -1) { - buffer.flip(); - // System.out.println("Reading, remaining:" + buffer.remaining()); - try { - while (buffer.hasRemaining()) { - buffer.mark(); - final int clazzid = buffer.getInt(); - final long loggingTimestamp = buffer.getLong(); - final IMonitoringRecord record; - try { // NOCS (Nested try-catch) - record = AbstractMonitoringRecord.createFromByteBuffer(clazzid, buffer, this.stringRegistry); - record.setLoggingTimestamp(loggingTimestamp); - // super.deliver(OUTPUT_PORT_NAME_RECORDS, record); - this.counter.incrementAndGet(); - } catch (final MonitoringRecordException ex) { - LOG.error("Failed to create record.", ex); - } - } - buffer.clear(); - } catch (final BufferUnderflowException ex) { - buffer.reset(); - // System.out.println("Underflow, remaining:" + buffer.remaining()); - buffer.compact(); - } - } - // System.out.println("Channel closing..."); - socketChannel.close(); - // END also loop this one? - } catch (final IOException ex) { - LOG.error("Error while reading", ex); - return false; - } finally { - if (null != serversocket) { - try { - serversocket.close(); - } catch (final IOException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Failed to close TCP connection!", e); - } - } - } - } - return true; - } - - public void terminate(final boolean error) { - LOG.info("Shutdown of TCPReader requested."); - this.executorService.shutdown(); - } -} - -/** - * - * @author Jan Waller - * - * @since 1.8 - */ -class TCPStringReader extends Thread { - - private static final int MESSAGE_BUFFER_SIZE = 65535; - - private static final Log LOG = LogFactory.getLog(TCPStringReader.class); - - private final int port; - private final ILookup<String> stringRegistry; - - public TCPStringReader(final int port, final ILookup<String> stringRegistry) { - this.port = port; - this.stringRegistry = stringRegistry; - } - - @Override - public void run() { - ServerSocketChannel serversocket = null; - try { - serversocket = ServerSocketChannel.open(); - serversocket.socket().bind(new InetSocketAddress(this.port)); - if (LOG.isDebugEnabled()) { - LOG.debug("Listening on port " + this.port); - } - // BEGIN also loop this one? - final SocketChannel socketChannel = serversocket.accept(); - final ByteBuffer buffer = ByteBuffer.allocateDirect(MESSAGE_BUFFER_SIZE); - while (socketChannel.read(buffer) != -1) { - buffer.flip(); - try { - while (buffer.hasRemaining()) { - buffer.mark(); - RegistryRecord.registerRecordInRegistry(buffer, this.stringRegistry); - } - buffer.clear(); - } catch (final BufferUnderflowException ex) { - buffer.reset(); - buffer.compact(); - } - } - socketChannel.close(); - // END also loop this one? - } catch (final IOException ex) { - LOG.error("Error while reading", ex); - } finally { - if (null != serversocket) { - try { - serversocket.close(); - } catch (final IOException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Failed to close TCP connection!", e); - } - } - } - } - } - -} diff --git a/frameworks/Kieker/src/kieker/tcp/TestExperiment2.java b/frameworks/Kieker/src/kieker/tcp/TestExperiment2.java deleted file mode 100644 index 17ab72d..0000000 --- a/frameworks/Kieker/src/kieker/tcp/TestExperiment2.java +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************** - * Copyright 2014 Kieker Project (http://kieker-monitoring.net) - * - * 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 kieker.tcp; - -import java.util.concurrent.TimeUnit; - -import kieker.analysis.AnalysisController; -import kieker.analysis.IAnalysisController; -import kieker.analysis.exception.AnalysisConfigurationException; -import kieker.analysis.plugin.filter.flow.EventRecordTraceReconstructionFilter; -import kieker.analysis.plugin.filter.forward.AnalysisThroughputFilter; -import kieker.analysis.plugin.filter.forward.TeeFilter; -import kieker.analysis.plugin.reader.tcp.TCPReader; -import kieker.analysis.plugin.reader.timer.TimeReader; -import kieker.common.configuration.Configuration; -import kieker.common.logging.Log; -import kieker.common.logging.LogFactory; - -// Command-Line: -// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000 -/** - * @author Jan Waller - */ -public final class TestExperiment2 { - private static final Log LOG = LogFactory.getLog(TestExperiment2.class); - - private TestExperiment2() {} - - public static void main(final String[] args) throws IllegalStateException, AnalysisConfigurationException { - final IAnalysisController analysisController = new AnalysisController("TCPThroughput"); - TestExperiment2.createAndConnectPlugins(analysisController); - try { - analysisController.run(); - } catch (final AnalysisConfigurationException ex) { - TestExperiment2.LOG.error("Failed to start the example project.", ex); - } - } - - private static void createAndConnectPlugins(final IAnalysisController analysisController) throws IllegalStateException, AnalysisConfigurationException { - final Configuration readerConfig = new Configuration(); - // readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT1, 10333); - // readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT2, 10334); - final TCPReader reader = new TCPReader(readerConfig, analysisController); - - final Configuration timeConfig = new Configuration(); - final TimeReader timeReader = new TimeReader(timeConfig, analysisController); - - final Configuration configTraceRecon = new Configuration(); - configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name()); - configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_DURATION, "1"); - configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_TIMEOUT, "1"); - final EventRecordTraceReconstructionFilter traceRecon = new EventRecordTraceReconstructionFilter(configTraceRecon, analysisController); - - analysisController.connect(reader, TCPReader.OUTPUT_PORT_NAME_RECORDS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TRACE_RECORDS); - analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TIME_EVENT); - - final Configuration counterConfig = new Configuration(); - final AnalysisThroughputFilter through = new AnalysisThroughputFilter(counterConfig, analysisController); - analysisController.connect(traceRecon, EventRecordTraceReconstructionFilter.OUTPUT_PORT_NAME_TRACE_VALID, through, - AnalysisThroughputFilter.INPUT_PORT_NAME_OBJECTS); - analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, through, AnalysisThroughputFilter.INPUT_PORT_NAME_TIME); - - final Configuration confTeeFilter = new Configuration(); - confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_STDOUT); - // confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_NULL); - final TeeFilter teeFilter = new TeeFilter(confTeeFilter, analysisController); - analysisController.connect(through, AnalysisThroughputFilter.OUTPUT_PORT_NAME_THROUGHPUT, teeFilter, TeeFilter.INPUT_PORT_NAME_EVENTS); - } -} diff --git a/frameworks/Kieker/src/kieker/tcp/TestExperiment3.java b/frameworks/Kieker/src/kieker/tcp/TestExperiment3.java deleted file mode 100644 index fb0a031..0000000 --- a/frameworks/Kieker/src/kieker/tcp/TestExperiment3.java +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************** - * Copyright 2014 Kieker Project (http://kieker-monitoring.net) - * - * 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 kieker.tcp; - -import java.util.concurrent.TimeUnit; - -import kieker.analysis.AnalysisController; -import kieker.analysis.IAnalysisController; -import kieker.analysis.exception.AnalysisConfigurationException; -import kieker.analysis.plugin.filter.flow.EventRecordTraceReconstructionFilter; -import kieker.analysis.plugin.filter.flow.TraceAggregationFilter; -import kieker.analysis.plugin.filter.forward.TeeFilter; -import kieker.analysis.plugin.reader.tcp.TCPReader; -import kieker.analysis.plugin.reader.timer.TimeReader; -import kieker.common.configuration.Configuration; -import kieker.common.logging.Log; -import kieker.common.logging.LogFactory; - -// Command-Line: -// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000 -/** - * @author Jan Waller - */ -public final class TestExperiment3 { - private static final Log LOG = LogFactory.getLog(TestExperiment3.class); - - private TestExperiment3() {} - - public static void main(final String[] args) throws IllegalStateException, AnalysisConfigurationException { - final IAnalysisController analysisController = new AnalysisController("TCPThroughput"); - TestExperiment3.createAndConnectPlugins(analysisController); - try { - analysisController.run(); - } catch (final AnalysisConfigurationException ex) { - TestExperiment3.LOG.error("Failed to start the example project.", ex); - } - } - - private static void createAndConnectPlugins(final IAnalysisController analysisController) throws IllegalStateException, AnalysisConfigurationException { - final Configuration readerConfig = new Configuration(); - // readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT1, 10333); - // readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT2, 10334); - final TCPReader reader = new TCPReader(readerConfig, analysisController); - - final Configuration timeConfig = new Configuration(); - final TimeReader timeReader = new TimeReader(timeConfig, analysisController); - - final Configuration configTraceRecon = new Configuration(); - configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name()); - configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_DURATION, "1"); - configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_TIMEOUT, "1"); - final EventRecordTraceReconstructionFilter traceRecon = new EventRecordTraceReconstructionFilter(configTraceRecon, analysisController); - - analysisController.connect(reader, TCPReader.OUTPUT_PORT_NAME_RECORDS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TRACE_RECORDS); - analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TIME_EVENT); - - final Configuration configTraceAggr = new Configuration(); - configTraceAggr.setProperty(TraceAggregationFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name()); - configTraceAggr.setProperty(TraceAggregationFilter.CONFIG_PROPERTY_NAME_MAX_COLLECTION_DURATION, "1"); - final TraceAggregationFilter traceAggr = new TraceAggregationFilter(configTraceAggr, analysisController); - - analysisController.connect(traceRecon, EventRecordTraceReconstructionFilter.OUTPUT_PORT_NAME_TRACE_VALID, traceAggr, - TraceAggregationFilter.INPUT_PORT_NAME_TRACES); - analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceAggr, TraceAggregationFilter.INPUT_PORT_NAME_TIME_EVENT); - - final Configuration confTeeFilter = new Configuration(); - confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_STDOUT); - // confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_NULL); - final TeeFilter teeFilter = new TeeFilter(confTeeFilter, analysisController); - analysisController.connect(traceAggr, TraceAggregationFilter.OUTPUT_PORT_NAME_TRACES, teeFilter, TeeFilter.INPUT_PORT_NAME_EVENTS); - } -} diff --git a/frameworks/Kieker/src/kieker/Logger.java b/frameworks/Kieker/src/main/java/moobench/kieker/Logger.java similarity index 87% rename from frameworks/Kieker/src/kieker/Logger.java rename to frameworks/Kieker/src/main/java/moobench/kieker/Logger.java index 5502935..1ade793 100644 --- a/frameworks/Kieker/src/kieker/Logger.java +++ b/frameworks/Kieker/src/main/java/moobench/kieker/Logger.java @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ - -package kieker; +package moobench.kieker; import java.io.IOException; -import mooBench.benchmark.Benchmark; +import moobench.benchmark.BenchmarkMain; /** * @author Jan Waller @@ -28,7 +27,7 @@ public class Logger implements Runnable { public void run() { try { java.util.logging.LogManager.getLogManager().readConfiguration( - Benchmark.class.getClassLoader().getResourceAsStream("META-INF/kieker.logging.properties")); + BenchmarkMain.class.getClassLoader().getResourceAsStream("META-INF/kieker.logging.properties")); } catch (final IOException ex) { java.util.logging.Logger.getAnonymousLogger().log(java.util.logging.Level.SEVERE, "Could not load default logging.properties file", ex); } diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration1.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration1.java new file mode 100644 index 0000000..0729de7 --- /dev/null +++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration1.java @@ -0,0 +1,15 @@ +package moobench.kieker.tcp; + +import kieker.analysis.source.tcp.MultipleConnectionTcpSourceStage; +import kieker.analysisteetime.plugin.filter.forward.CountingFilter; +import teetime.framework.Configuration; + +public class TestConfiguration1 extends Configuration { + + public TestConfiguration1(int inputPort, int bufferSize) { + MultipleConnectionTcpSourceStage source = new MultipleConnectionTcpSourceStage(inputPort, bufferSize, null); + CountingFilter counting = new CountingFilter(); + + connectPorts(source.getOutputPort(), counting.getInputPort()); + } +} diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration2.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration2.java new file mode 100644 index 0000000..b553900 --- /dev/null +++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration2.java @@ -0,0 +1,45 @@ +/** + * + */ +package moobench.kieker.tcp; + +import java.util.concurrent.TimeUnit; + +import kieker.analysis.source.tcp.MultipleConnectionTcpSourceStage; +import teetime.framework.Configuration; + +/** + * @author reiner + * + */ +public class TestConfiguration2 extends Configuration { + + public TestConfiguration2(int inputPort, int bufferSize) { + MultipleConnectionTcpSourceStage reader = new MultipleConnectionTcpSourceStage(inputPort, bufferSize, null); +/* + final Configuration timeConfig = new Configuration(); + final TimeReader timeReader = new TimeReader(timeConfig, analysisController); + + final Configuration configTraceRecon = new Configuration(); + configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name()); + configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_DURATION, "1"); + configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_TIMEOUT, "1"); + final EventRecordTraceReconstructionFilter traceRecon = new EventRecordTraceReconstructionFilter(configTraceRecon, analysisController); + + analysisController.connect(reader, TCPReader.OUTPUT_PORT_NAME_RECORDS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TRACE_RECORDS); + analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TIME_EVENT); + + final Configuration counterConfig = new Configuration(); + final AnalysisThroughputFilter through = new AnalysisThroughputFilter(counterConfig, analysisController); + analysisController.connect(traceRecon, EventRecordTraceReconstructionFilter.OUTPUT_PORT_NAME_TRACE_VALID, through, + AnalysisThroughputFilter.INPUT_PORT_NAME_OBJECTS); + analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, through, AnalysisThroughputFilter.INPUT_PORT_NAME_TIME); + + final Configuration confTeeFilter = new Configuration(); + confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_STDOUT); + // confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_NULL); + final TeeFilter teeFilter = new TeeFilter(confTeeFilter, analysisController); + analysisController.connect(through, AnalysisThroughputFilter.OUTPUT_PORT_NAME_THROUGHPUT, teeFilter, TeeFilter.INPUT_PORT_NAME_EVENTS);*/ + + } +} diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration3.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration3.java new file mode 100644 index 0000000..a33a4d6 --- /dev/null +++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration3.java @@ -0,0 +1,42 @@ +package moobench.kieker.tcp; + +import java.util.concurrent.TimeUnit; + +import kieker.analysis.source.tcp.MultipleConnectionTcpSourceStage; +import teetime.framework.Configuration; + +public class TestConfiguration3 extends Configuration { + + public TestConfiguration3(int inputPort, int bufferSize) { + MultipleConnectionTcpSourceStage source = new MultipleConnectionTcpSourceStage(inputPort, bufferSize, null); + + /* + final Configuration timeConfig = new Configuration(); + final TimeReader timeReader = new TimeReader(timeConfig, analysisController); + + final Configuration configTraceRecon = new Configuration(); + configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name()); + configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_DURATION, "1"); + configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_TIMEOUT, "1"); + final EventRecordTraceReconstructionFilter traceRecon = new EventRecordTraceReconstructionFilter(configTraceRecon, analysisController); + + analysisController.connect(reader, TCPReader.OUTPUT_PORT_NAME_RECORDS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TRACE_RECORDS); + analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TIME_EVENT); + + final Configuration configTraceAggr = new Configuration(); + configTraceAggr.setProperty(TraceAggregationFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name()); + configTraceAggr.setProperty(TraceAggregationFilter.CONFIG_PROPERTY_NAME_MAX_COLLECTION_DURATION, "1"); + final TraceAggregationFilter traceAggr = new TraceAggregationFilter(configTraceAggr, analysisController); + + analysisController.connect(traceRecon, EventRecordTraceReconstructionFilter.OUTPUT_PORT_NAME_TRACE_VALID, traceAggr, + TraceAggregationFilter.INPUT_PORT_NAME_TRACES); + analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceAggr, TraceAggregationFilter.INPUT_PORT_NAME_TIME_EVENT); + + final Configuration confTeeFilter = new Configuration(); + confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_STDOUT); + // confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_NULL); + final TeeFilter teeFilter = new TeeFilter(confTeeFilter, analysisController); + analysisController.connect(traceAggr, TraceAggregationFilter.OUTPUT_PORT_NAME_TRACES, teeFilter, TeeFilter.INPUT_PORT_NAME_EVENTS); +*/ + } +} diff --git a/frameworks/Kieker/src/kieker/tcp/TestExperiment0.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment0.java similarity index 99% rename from frameworks/Kieker/src/kieker/tcp/TestExperiment0.java rename to frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment0.java index f4b174b..0460b57 100644 --- a/frameworks/Kieker/src/kieker/tcp/TestExperiment0.java +++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment0.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.tcp; +package moobench.kieker.tcp; import java.io.IOException; import java.net.InetSocketAddress; diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment1.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment1.java new file mode 100644 index 0000000..b4a09a8 --- /dev/null +++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment1.java @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright 2014 Kieker Project (http://kieker-monitoring.net) + * + * 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 moobench.kieker.tcp; + +import teetime.framework.Execution; + +// Command-Line: +// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000 +/** + * @author Jan Waller + */ +public final class TestExperiment1 { + + private TestExperiment1() {} + + public static void main(final String[] args) { + TestConfiguration1 config = new TestConfiguration1(Integer.parseInt(args[0]), 8192); + Execution<TestConfiguration1> execution = new Execution<TestConfiguration1>(config); + execution.executeBlocking(); + } +} diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment2.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment2.java new file mode 100644 index 0000000..663b038 --- /dev/null +++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment2.java @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright 2014 Kieker Project (http://kieker-monitoring.net) + * + * 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 moobench.kieker.tcp; + +import java.util.concurrent.TimeUnit; + +import teetime.framework.Execution; + +// Command-Line: +// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000 +/** + * @author Jan Waller + */ +public final class TestExperiment2 { + + private TestExperiment2() {} + + public static void main(final String[] args) { + TestConfiguration2 config = new TestConfiguration2(Integer.parseInt(args[0]), 8192); + Execution<TestConfiguration2> execution = new Execution<TestConfiguration2>(config); + execution.executeBlocking(); + } + +} diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment3.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment3.java new file mode 100644 index 0000000..7a854fd --- /dev/null +++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment3.java @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright 2014 Kieker Project (http://kieker-monitoring.net) + * + * 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 moobench.kieker.tcp; + +import java.util.concurrent.TimeUnit; + +import teetime.framework.Execution; + +// Command-Line: +// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000 +/** + * @author Jan Waller + */ +public final class TestExperiment3 { + + private TestExperiment3() {} + + public static void main(final String[] args) { + TestConfiguration3 config = new TestConfiguration3(Integer.parseInt(args[0]), 8192); + Execution<TestConfiguration3> execution = new Execution<TestConfiguration3>(config); + execution.executeBlocking(); + } + +} diff --git a/frameworks/SPASSmeter/build.gradle b/frameworks/SPASSmeter/build.gradle new file mode 100644 index 0000000..105b078 --- /dev/null +++ b/frameworks/SPASSmeter/build.gradle @@ -0,0 +1,8 @@ +plugins { + id 'java' + id 'java-library' +} + +dependencies { + +} diff --git a/frameworks/inspectIT/build.gradle b/frameworks/inspectIT/build.gradle new file mode 100644 index 0000000..105b078 --- /dev/null +++ b/frameworks/inspectIT/build.gradle @@ -0,0 +1,8 @@ +plugins { + id 'java' + id 'java-library' +} + +dependencies { + +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..62d4c053550b91381bbd28b1afc82d634bf73a8a GIT binary patch literal 58910 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 literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..622ab64 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..fbd7c51 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..5093609 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,104 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/lib/commons-cli-1.2.LICENSE b/lib/commons-cli-1.2.LICENSE deleted file mode 100644 index 9e1db3b..0000000 --- a/lib/commons-cli-1.2.LICENSE +++ /dev/null @@ -1,207 +0,0 @@ -The Apache Software License - ASL - v2.0 -Project: http://commons.apache.org/cli/ -Description: Apache Commons CLI provides a simple API for working with the command line arguments and options. -License: http://www.apache.org/licenses/LICENSE-2.0.txt - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. - diff --git a/lib/commons-cli-1.2.jar b/lib/commons-cli-1.2.jar deleted file mode 100644 index ce4b9fffe40c41669797cd806ac989471b2acd84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41123 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%0D2u^7bcx|ezvBT@`6 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 CNzF?D diff --git a/moobench/build.gradle b/moobench/build.gradle new file mode 100644 index 0000000..1dbd5d6 --- /dev/null +++ b/moobench/build.gradle @@ -0,0 +1,12 @@ +plugins { + id 'java' + id 'application' +} + +dependencies { + implementation 'com.beust:jcommander:1.72' +} + +application { + mainClass = 'moobench.benchmark.BenchmarkMain' +} diff --git a/src/mooBench/monitoredApplication/MonitoredClass.java b/moobench/src/main/java/moobench/application/MonitoredClass.java similarity index 95% rename from src/mooBench/monitoredApplication/MonitoredClass.java rename to moobench/src/main/java/moobench/application/MonitoredClass.java index db4be42..ce87df4 100644 --- a/src/mooBench/monitoredApplication/MonitoredClass.java +++ b/moobench/src/main/java/moobench/application/MonitoredClass.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package mooBench.monitoredApplication; +package moobench.application; /** * @author Jan Waller diff --git a/src/mooBench/monitoredApplication/MonitoredClassSimple.java b/moobench/src/main/java/moobench/application/MonitoredClassSimple.java similarity index 97% rename from src/mooBench/monitoredApplication/MonitoredClassSimple.java rename to moobench/src/main/java/moobench/application/MonitoredClassSimple.java index 3227e38..8ea21fa 100644 --- a/src/mooBench/monitoredApplication/MonitoredClassSimple.java +++ b/moobench/src/main/java/moobench/application/MonitoredClassSimple.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package mooBench.monitoredApplication; +package moobench.application; /** * @author Jan Waller diff --git a/src/mooBench/monitoredApplication/MonitoredClassThreaded.java b/moobench/src/main/java/moobench/application/MonitoredClassThreaded.java similarity index 97% rename from src/mooBench/monitoredApplication/MonitoredClassThreaded.java rename to moobench/src/main/java/moobench/application/MonitoredClassThreaded.java index 869e0d8..060fda2 100644 --- a/src/mooBench/monitoredApplication/MonitoredClassThreaded.java +++ b/moobench/src/main/java/moobench/application/MonitoredClassThreaded.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package mooBench.monitoredApplication; +package moobench.application; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; diff --git a/moobench/src/main/java/moobench/benchmark/BenchmarkMain.java b/moobench/src/main/java/moobench/benchmark/BenchmarkMain.java new file mode 100644 index 0000000..ff3eebb --- /dev/null +++ b/moobench/src/main/java/moobench/benchmark/BenchmarkMain.java @@ -0,0 +1,158 @@ +/*************************************************************************** + * Copyright 2014 Kieker Project (http://kieker-monitoring.net) + * + * 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 moobench.benchmark; + +import java.io.BufferedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.ParameterException; + +import moobench.application.MonitoredClass; +import moobench.application.MonitoredClassThreaded; + +/** + * @author Jan Waller + */ +public final class BenchmarkMain { + private static final String ENCODING = "UTF-8"; + + private static PrintStream ps = null; + private static String outputFn = null; + private static int totalThreads = 0; + private static int totalCalls = 0; + private static long methodTime = 0; + private static int recursionDepth = 0; + private static boolean quickstart = false; + private static boolean forceTerminate = false; + private static MonitoredClass mc = null; + + private static BenchmarkParameter parameter = new BenchmarkParameter(); + + private BenchmarkMain() { + } + + public static void main(final String[] args) throws InterruptedException { + + // 1. Preparations + BenchmarkMain.parseAndInitializeArguments(args); + + System.out.println(" # Experiment run configuration:"); // NOPMD (System.out) + System.out.println(" # 1. Output filename " + BenchmarkMain.outputFn); // NOPMD (System.out) + System.out.println(" # 2. Recursion Depth " + BenchmarkMain.recursionDepth); // NOPMD (System.out) + System.out.println(" # 3. Threads " + BenchmarkMain.totalThreads); // NOPMD (System.out) + System.out.println(" # 4. Total-Calls " + BenchmarkMain.totalCalls); // NOPMD (System.out) + System.out.println(" # 5. Method-Time " + BenchmarkMain.methodTime); // NOPMD (System.out) + + // 2. Initialize Threads and Classes + final CountDownLatch doneSignal = new CountDownLatch(BenchmarkMain.totalThreads); + final BenchmarkingThread[] benchmarkingThreads = new BenchmarkingThread[BenchmarkMain.totalThreads]; + final Thread[] threads = new Thread[BenchmarkMain.totalThreads]; + for (int i = 0; i < BenchmarkMain.totalThreads; i++) { + benchmarkingThreads[i] = new BenchmarkingThreadNano(BenchmarkMain.mc, BenchmarkMain.totalCalls, + BenchmarkMain.methodTime, BenchmarkMain.recursionDepth, doneSignal); + threads[i] = new Thread(benchmarkingThreads[i], String.valueOf(i + 1)); + } + if (!quickstart) { + for (int l = 0; l < 4; l++) { + { // NOCS (reserve mem only within the block) + final long freeMemChunks = Runtime.getRuntime().freeMemory() >> 27; + // System.out.println("Free-Mem: " + Runtime.getRuntime().freeMemory()); + final int memSize = 128 * 1024 * 128; // memSize * 8 = total Bytes -> 128MB + for (int j = 0; j < freeMemChunks; j++) { + final long[] grabMemory = new long[memSize]; + for (int i = 0; i < memSize; i++) { + grabMemory[i] = System.nanoTime(); + } + } + // System.out.println("done grabbing memory..."); + // System.out.println("Free-Mem: " + Runtime.getRuntime().freeMemory()); + } + Thread.sleep(5000); + } + } + final long startTime = System.currentTimeMillis(); + System.out.println(" # 6. Starting benchmark ..."); // NOPMD (System.out) + // 3. Starting Threads + for (int i = 0; i < BenchmarkMain.totalThreads; i++) { + threads[i].start(); + } + + // 4. Wait for all Threads + try { + doneSignal.await(); + } catch (final InterruptedException e) { + e.printStackTrace(); // NOPMD (Stacktrace) + System.exit(-1); + } + final long totalTime = System.currentTimeMillis() - startTime; + System.out.println(" # done (" + TimeUnit.MILLISECONDS.toSeconds(totalTime) + " s)"); // NOPMD + // (System.out) + + // 5. Print experiment statistics + System.out.print(" # 7. Writing results ... "); // NOPMD (System.out) + // CSV Format: configuration;order_index;Thread-ID;duration_nsec + for (int h = 0; h < BenchmarkMain.totalThreads; h++) { + final BenchmarkingThread thread = benchmarkingThreads[h]; + for (int i = 0; i < BenchmarkMain.totalCalls; i++) { + final String line = threads[h].getName() + ";" + thread.print(i, ";"); + BenchmarkMain.ps.println(line); + } + } + BenchmarkMain.ps.close(); + + System.out.println("done"); // NOPMD (System.out) + System.out.println(" # "); // NOPMD (System.out) + + if (forceTerminate) { + System.exit(0); + } + } + + public static void parseAndInitializeArguments(final String[] argv) { + JCommander commander = null; + try { + commander = JCommander.newBuilder().addObject(parameter).build(); + commander.parse(argv); + + BenchmarkMain.ps = new PrintStream( + new BufferedOutputStream(Files.newOutputStream(parameter.getOutputFile().toPath()), 8192 * 8), + false, BenchmarkMain.ENCODING); + if (null != parameter.getApplicationClassname()) { + mc = ((MonitoredClass) Class.forName(parameter.getApplicationClassname()).newInstance()); + } else { + mc = new MonitoredClassThreaded(); + } + if (null != parameter.getRunnableClassname()) { + ((Runnable) Class.forName(parameter.getRunnableClassname()).newInstance()).run(); + } + } catch (ParameterException ex) { + if (commander != null) + commander.usage(); + } catch (final Exception ex) { // NOCS (e.g., IOException, ParseException, + // NumberFormatException) + if (commander != null) { + commander.usage(); + } + System.out.println(ex.toString()); // NOPMD (Stacktrace) + System.exit(-1); + } + } +} diff --git a/moobench/src/main/java/moobench/benchmark/BenchmarkParameter.java b/moobench/src/main/java/moobench/benchmark/BenchmarkParameter.java new file mode 100644 index 0000000..5ffe44f --- /dev/null +++ b/moobench/src/main/java/moobench/benchmark/BenchmarkParameter.java @@ -0,0 +1,91 @@ +/** + * + */ +package moobench.benchmark; + +import java.io.File; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.converters.FileConverter; + +/** + * @author Reiner Jung + * + */ +public class BenchmarkParameter { + + @Parameter(names = { "--totalCalls", "-c" }, required = true, description = "Number of total method calls performed.") + long totalCalls; + + @Parameter(names = { "--methodtime", "-m" }, required = true, description = "Time a method call takes.") + long methodTime; + + @Parameter(names = { "--totalthreads", "-t" }, required = true, description = "Number of threads started.") + long totalThreads; + + @Parameter(names = { "--recursiondepth", "-d" }, required = true, description = "Depth of recursion performed.") + long recursionDepth; + + @Parameter(names = { "--output-filename", "-o" }, required = true, converter = FileConverter.class, + description = "Filename of results file. Output is appended if file exists.") + File outputFile; + + @Parameter(names = { "--quickstart", "-q" }, required = false, description = "Skips initial garbage collection.") + boolean quickstart; + + @Parameter(names = { "--forceTerminate", "-f" }, required = false, description = "Forces a termination at the end of the benchmark.") + boolean forceTerminate; + + @Parameter(names = { "--runnable", "-r" }, required = false, + description = "Class implementing the Runnable interface. run() method is executed before the benchmark starts.") + String runnableClassname; + + @Parameter(names = { "--application", "-a" }, required = false, description = "Class implementing the MonitoredClass interface.") + String applicationClassname; + + @Parameter(names = { "--benchmarkthread", "-b" }, required = false, description = "Class implementing the BenchmarkingThread interface.") + String benchmarkClassname; + + public long getTotalCalls() { + return totalCalls; + } + + public long getMethodTime() { + return methodTime; + } + + public long getTotalThreads() { + return totalThreads; + } + + public long getRecursionDepth() { + return recursionDepth; + } + + public File getOutputFile() { + return outputFile; + } + + public boolean isQuickstart() { + return quickstart; + } + + public boolean isForceTerminate() { + return forceTerminate; + } + + public String getRunnableClassname() { + return runnableClassname; + } + + public String getApplicationClassname() { + return applicationClassname; + } + + public String getBenchmarkClassname() { + return benchmarkClassname; + } + + + +} diff --git a/src/mooBench/benchmark/BenchmarkingThread.java b/moobench/src/main/java/moobench/benchmark/BenchmarkingThread.java similarity index 97% rename from src/mooBench/benchmark/BenchmarkingThread.java rename to moobench/src/main/java/moobench/benchmark/BenchmarkingThread.java index 043ad1a..97b1263 100644 --- a/src/mooBench/benchmark/BenchmarkingThread.java +++ b/moobench/src/main/java/moobench/benchmark/BenchmarkingThread.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package mooBench.benchmark; +package moobench.benchmark; /** * @author Jan Waller, Christian Wulf diff --git a/src/mooBench/benchmark/BenchmarkingThreadMilli.java b/moobench/src/main/java/moobench/benchmark/BenchmarkingThreadMilli.java similarity index 96% rename from src/mooBench/benchmark/BenchmarkingThreadMilli.java rename to moobench/src/main/java/moobench/benchmark/BenchmarkingThreadMilli.java index 9f5e249..6fe6dde 100644 --- a/src/mooBench/benchmark/BenchmarkingThreadMilli.java +++ b/moobench/src/main/java/moobench/benchmark/BenchmarkingThreadMilli.java @@ -14,11 +14,11 @@ * limitations under the License. ***************************************************************************/ -package mooBench.benchmark; +package moobench.benchmark; import java.util.concurrent.CountDownLatch; -import mooBench.monitoredApplication.MonitoredClass; +import moobench.application.MonitoredClass; /** * @author Jan Waller diff --git a/src/mooBench/benchmark/BenchmarkingThreadNano.java b/moobench/src/main/java/moobench/benchmark/BenchmarkingThreadNano.java similarity index 97% rename from src/mooBench/benchmark/BenchmarkingThreadNano.java rename to moobench/src/main/java/moobench/benchmark/BenchmarkingThreadNano.java index ad135b3..7baf0b6 100644 --- a/src/mooBench/benchmark/BenchmarkingThreadNano.java +++ b/moobench/src/main/java/moobench/benchmark/BenchmarkingThreadNano.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package mooBench.benchmark; +package moobench.benchmark; import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; @@ -22,7 +22,7 @@ import java.lang.management.MemoryMXBean; import java.util.List; import java.util.concurrent.CountDownLatch; -import mooBench.monitoredApplication.MonitoredClass; +import moobench.application.MonitoredClass; /** * @author Jan Waller, Aike Sass, Christian Wulf diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..e7d9c6a --- /dev/null +++ b/settings.gradle @@ -0,0 +1,16 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/6.5/userguide/multi_project_builds.html + */ + +rootProject.name = 'moobench' + +include 'moobench' +include 'frameworks:inspectIT' +include 'frameworks:Kieker' +include 'frameworks:SPASSmeter' + diff --git a/src/META-INF/.gitignore b/src/META-INF/.gitignore deleted file mode 100644 index 5e7d273..0000000 --- a/src/META-INF/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/src/mooBench/benchmark/Benchmark.java b/src/mooBench/benchmark/Benchmark.java deleted file mode 100644 index b3377ea..0000000 --- a/src/mooBench/benchmark/Benchmark.java +++ /dev/null @@ -1,240 +0,0 @@ -/*************************************************************************** - * Copyright 2014 Kieker Project (http://kieker-monitoring.net) - * - * 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 mooBench.benchmark; - -import java.io.BufferedOutputStream; -import java.io.FileOutputStream; -import java.io.PrintStream; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.cli.BasicParser; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.OptionBuilder; -import org.apache.commons.cli.Options; - -import mooBench.monitoredApplication.MonitoredClass; -import mooBench.monitoredApplication.MonitoredClassThreaded; - -/** - * @author Jan Waller - */ -public final class Benchmark { - private static final String ENCODING = "UTF-8"; - - private static PrintStream ps = null; - private static String outputFn = null; - private static int totalThreads = 0; - private static int totalCalls = 0; - private static long methodTime = 0; - private static int recursionDepth = 0; - private static boolean quickstart = false; - private static boolean forceTerminate = false; - private static MonitoredClass mc = null; - - private Benchmark() {} - - public static void main(final String[] args) throws InterruptedException { - - // 1. Preparations - Benchmark.parseAndInitializeArguments(args); - - System.out.println(" # Experiment run configuration:"); // NOPMD (System.out) - System.out.println(" # 1. Output filename " + Benchmark.outputFn); // NOPMD (System.out) - System.out.println(" # 2. Recursion Depth " + Benchmark.recursionDepth); // NOPMD (System.out) - System.out.println(" # 3. Threads " + Benchmark.totalThreads); // NOPMD (System.out) - System.out.println(" # 4. Total-Calls " + Benchmark.totalCalls); // NOPMD (System.out) - System.out.println(" # 5. Method-Time " + Benchmark.methodTime); // NOPMD (System.out) - - // 2. Initialize Threads and Classes - final CountDownLatch doneSignal = new CountDownLatch(Benchmark.totalThreads); - final BenchmarkingThread[] benchmarkingThreads = new BenchmarkingThread[Benchmark.totalThreads]; - final Thread[] threads = new Thread[Benchmark.totalThreads]; - for (int i = 0; i < Benchmark.totalThreads; i++) { - benchmarkingThreads[i] = new BenchmarkingThreadNano(Benchmark.mc, Benchmark.totalCalls, - Benchmark.methodTime, Benchmark.recursionDepth, doneSignal); - threads[i] = new Thread(benchmarkingThreads[i], String.valueOf(i + 1)); - } - if (!quickstart) { - for (int l = 0; l < 4; l++) { - { // NOCS (reserve mem only within the block) - final long freeMemChunks = Runtime.getRuntime().freeMemory() >> 27; - // System.out.println("Free-Mem: " + Runtime.getRuntime().freeMemory()); - final int memSize = 128 * 1024 * 128; // memSize * 8 = total Bytes -> 128MB - for (int j = 0; j < freeMemChunks; j++) { - final long[] grabMemory = new long[memSize]; - for (int i = 0; i < memSize; i++) { - grabMemory[i] = System.nanoTime(); - } - } - // System.out.println("done grabbing memory..."); - // System.out.println("Free-Mem: " + Runtime.getRuntime().freeMemory()); - } - Thread.sleep(5000); - } - } - final long startTime = System.currentTimeMillis(); - System.out.println(" # 6. Starting benchmark ..."); // NOPMD (System.out) - // 3. Starting Threads - for (int i = 0; i < Benchmark.totalThreads; i++) { - threads[i].start(); - } - - // 4. Wait for all Threads - try { - doneSignal.await(); - } catch (final InterruptedException e) { - e.printStackTrace(); // NOPMD (Stacktrace) - System.exit(-1); - } - final long totalTime = System.currentTimeMillis() - startTime; - System.out.println(" # done (" + TimeUnit.MILLISECONDS.toSeconds(totalTime) + " s)"); // NOPMD - // (System.out) - - // 5. Print experiment statistics - System.out.print(" # 7. Writing results ... "); // NOPMD (System.out) - // CSV Format: configuration;order_index;Thread-ID;duration_nsec - for (int h = 0; h < Benchmark.totalThreads; h++) { - final BenchmarkingThread thread = benchmarkingThreads[h]; - for (int i = 0; i < Benchmark.totalCalls; i++) { - final String line = threads[h].getName() + ";" + thread.print(i, ";"); - Benchmark.ps.println(line); - } - } - Benchmark.ps.close(); - - System.out.println("done"); // NOPMD (System.out) - System.out.println(" # "); // NOPMD (System.out) - - if (forceTerminate) { - System.exit(0); - } - } - - public static void parseAndInitializeArguments(final String[] args) { - final Options cmdlOpts = new Options(); - OptionBuilder.withLongOpt("totalcalls"); - OptionBuilder.withArgName("calls"); - OptionBuilder.hasArg(true); - OptionBuilder.isRequired(true); - OptionBuilder - .withDescription("Number of total method calls performed."); - OptionBuilder.withValueSeparator('='); - cmdlOpts.addOption(OptionBuilder.create("t")); - OptionBuilder.withLongOpt("methodtime"); - OptionBuilder.withArgName("time"); - OptionBuilder.hasArg(true); - OptionBuilder.isRequired(true); - OptionBuilder.withDescription("Time a method call takes."); - OptionBuilder - .withValueSeparator('='); - cmdlOpts.addOption(OptionBuilder.create("m")); - OptionBuilder.withLongOpt("totalthreads"); - OptionBuilder.withArgName("threads"); - OptionBuilder.hasArg(true); - OptionBuilder.isRequired(true); - OptionBuilder - .withDescription("Number of threads started."); - OptionBuilder.withValueSeparator('='); - cmdlOpts.addOption(OptionBuilder.create("h")); - OptionBuilder.withLongOpt("recursiondepth"); - OptionBuilder.withArgName("depth"); - OptionBuilder.hasArg(true); - OptionBuilder.isRequired(true); - OptionBuilder - .withDescription("Depth of recursion performed."); - OptionBuilder.withValueSeparator('='); - cmdlOpts.addOption(OptionBuilder.create("d")); - OptionBuilder.withLongOpt("output-filename"); - OptionBuilder.withArgName("filename"); - OptionBuilder.hasArg(true); - OptionBuilder.isRequired(true); - OptionBuilder - .withDescription("Filename of results file. Output is appended if file exists."); - OptionBuilder.withValueSeparator('='); - cmdlOpts.addOption(OptionBuilder.create("o")); - OptionBuilder.withLongOpt("quickstart"); - OptionBuilder.isRequired(false); - OptionBuilder.withDescription("Skips initial garbage collection."); - cmdlOpts.addOption(OptionBuilder.create("q")); - OptionBuilder.withLongOpt("forceTerminate"); - OptionBuilder.isRequired(false); - OptionBuilder.withDescription("Forces a termination at the end of the benchmark."); - cmdlOpts.addOption(OptionBuilder - .create("f")); - OptionBuilder.withLongOpt("runnable"); - OptionBuilder.withArgName("classname"); - OptionBuilder.hasArg(true); - OptionBuilder.isRequired(false); - OptionBuilder - .withDescription( - "Class implementing the Runnable interface. run() method is executed before the benchmark starts."); - OptionBuilder.withValueSeparator('='); - cmdlOpts.addOption(OptionBuilder - .create("r")); - OptionBuilder.withLongOpt("application"); - OptionBuilder.withArgName("classname"); - OptionBuilder.hasArg(true); - OptionBuilder.isRequired(false); - OptionBuilder - .withDescription("Class implementing the MonitoredClass interface."); - OptionBuilder.withValueSeparator('='); - cmdlOpts.addOption(OptionBuilder - .create("a")); - OptionBuilder.withLongOpt("benchmarkthread"); - OptionBuilder.withArgName("classname"); - OptionBuilder.hasArg(true); - OptionBuilder.isRequired(false); - OptionBuilder - .withDescription("Class implementing the BenchmarkingThread interface."); - OptionBuilder.withValueSeparator('='); - cmdlOpts.addOption(OptionBuilder - .create("b")); - try { - CommandLine cmdl = null; - final CommandLineParser cmdlParser = new BasicParser(); - cmdl = cmdlParser.parse(cmdlOpts, args); - Benchmark.outputFn = cmdl.getOptionValue("output-filename"); - Benchmark.totalCalls = Integer.parseInt(cmdl.getOptionValue("totalcalls")); - Benchmark.methodTime = Integer.parseInt(cmdl.getOptionValue("methodtime")); - Benchmark.totalThreads = Integer.parseInt(cmdl.getOptionValue("totalthreads")); - Benchmark.recursionDepth = Integer.parseInt(cmdl.getOptionValue("recursiondepth")); - Benchmark.quickstart = cmdl.hasOption("quickstart"); - Benchmark.forceTerminate = cmdl.hasOption("forceTerminate"); - Benchmark.ps = new PrintStream( - new BufferedOutputStream(new FileOutputStream(Benchmark.outputFn, true), 8192 * 8), false, - Benchmark.ENCODING); - final String application = cmdl.getOptionValue("application"); - if (null != application) { - mc = ((MonitoredClass) Class.forName(application).newInstance()); - } else { - mc = new MonitoredClassThreaded(); - } - final String clazzname = cmdl.getOptionValue("runnable"); - if (null != clazzname) { - ((Runnable) Class.forName(clazzname).newInstance()).run(); - } - } catch (final Exception ex) { // NOCS (e.g., IOException, ParseException, - // NumberFormatException) - new HelpFormatter().printHelp(Benchmark.class.getName(), cmdlOpts); - System.out.println(ex.toString()); // NOPMD (Stacktrace) - System.exit(-1); - } - } -} -- GitLab