From 30616783057ef305a13523be1b09842b7143ff66 Mon Sep 17 00:00:00 2001 From: Rick Parker Date: Thu, 23 Nov 2017 12:17:10 +0000 Subject: [PATCH] JMeter tooling for performance cluster (#110) * First working version of RPC & JMeter * Remote JMeter working from single JAR. * Some clean up. Remote slave via capsule is working. * Full config of capsule launched JMeter server (was missing functions previously). * SSH tunnelling utility. Property files per remote host. * Rename jar to make easier to deploy with wildcard filters. * Easy all in one launch of UI + SSH tunnels. * Comment out parties. * Work around for notary. * Clean up, renaming etc * Add some comments and clean up. * Add some comments and clean up. * README and fixes. * Redirect search_paths into a file since it so long and doesn't work on the command line in Windows. * First working version of RPC & JMeter * Remote JMeter working from single JAR. * Some clean up. Remote slave via capsule is working. * Full config of capsule launched JMeter server (was missing functions previously). * SSH tunnelling utility. Property files per remote host. * Easy all in one launch of UI + SSH tunnels. * Comment out parties. * Work around for notary. * Clean up, renaming etc * Add some comments and clean up. * Add some comments and clean up. * README and fixes. * Reduce the dependencies of the JMeter project by copying (#118) one function and listing required explicit dependencies instead of depending on loadtest * Tidy up * Fix ssh for windows (#121) * Make ssh tunnels work with Pageant on windows and allow specifying explicit ssh remote user * Update comments --- .idea/compiler.xml | 2 + settings.gradle | 1 + tools/jmeter/README.md | 57 + tools/jmeter/build.gradle | 138 ++ .../com/r3/corda/jmeter/BaseFlowSampler.kt | 87 ++ .../kotlin/com/r3/corda/jmeter/JshHelper.kt | 63 + .../kotlin/com/r3/corda/jmeter/Launcher.kt | 83 ++ .../kotlin/com/r3/corda/jmeter/Samplers.kt | 51 + .../main/kotlin/com/r3/corda/jmeter/Ssh.kt | 135 ++ .../main/resources/Example Flow Request.jmx | 177 +++ .../main/resources/bin/saveservice.properties | 412 ++++++ .../src/main/resources/bin/upgrade.properties | 123 ++ .../src/main/resources/jmeter.properties | 1242 +++++++++++++++++ .../src/main/resources/lib/ext/readme.txt | 1 + .../src/main/resources/lib/junit/readme.txt | 1 + tools/jmeter/src/main/resources/log4j2.xml | 21 + .../src/main/resources/perf-node-1.properties | 1 + .../src/main/resources/perf-node-2.properties | 1 + .../src/main/resources/perf-node-3.properties | 1 + .../src/main/resources/perf-node-4.properties | 1 + .../src/main/resources/perf-notary.properties | 1 + 21 files changed, 2599 insertions(+) create mode 100644 tools/jmeter/README.md create mode 100644 tools/jmeter/build.gradle create mode 100644 tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/BaseFlowSampler.kt create mode 100644 tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/JshHelper.kt create mode 100644 tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Launcher.kt create mode 100644 tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Samplers.kt create mode 100644 tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt create mode 100644 tools/jmeter/src/main/resources/Example Flow Request.jmx create mode 100644 tools/jmeter/src/main/resources/bin/saveservice.properties create mode 100644 tools/jmeter/src/main/resources/bin/upgrade.properties create mode 100644 tools/jmeter/src/main/resources/jmeter.properties create mode 100644 tools/jmeter/src/main/resources/lib/ext/readme.txt create mode 100644 tools/jmeter/src/main/resources/lib/junit/readme.txt create mode 100644 tools/jmeter/src/main/resources/log4j2.xml create mode 100644 tools/jmeter/src/main/resources/perf-node-1.properties create mode 100644 tools/jmeter/src/main/resources/perf-node-2.properties create mode 100644 tools/jmeter/src/main/resources/perf-node-3.properties create mode 100644 tools/jmeter/src/main/resources/perf-node-4.properties create mode 100644 tools/jmeter/src/main/resources/perf-notary.properties diff --git a/.idea/compiler.xml b/.idea/compiler.xml index bafd46fea2..723b83cbb3 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -77,6 +77,8 @@ + + diff --git a/settings.gradle b/settings.gradle index e386b5bf3f..d9596e00a6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -34,6 +34,7 @@ include 'tools:explorer:capsule' include 'tools:demobench' include 'tools:loadtest' include 'tools:graphs' +include 'tools:jmeter' include 'example-code' project(':example-code').projectDir = file("$settingsDir/docs/source/example-code") include 'samples:attachment-demo' diff --git a/tools/jmeter/README.md b/tools/jmeter/README.md new file mode 100644 index 0000000000..6e67cce028 --- /dev/null +++ b/tools/jmeter/README.md @@ -0,0 +1,57 @@ +This module contains gradle tasks to make running the JMeter (http://jmeter.apache.org) +load generation tool against Corda nodes much easier and more useful. It does this by +providing a simple way to launch JMeter with the actual JMeter install coming +from downloaded dependencies, and by providing some Samplers that interact with +the Corda node via RPC. + +To run up the JMeter UI, using the jmeter.properties in the resources folder, +type the following: + +`./gradlew tools:jmeter:run` + +You can then open the example script in "Example Flow Properties.jmx" via the File -> Open menu option. You need to +configure the host, ports, user name and password in the Java Sampler that correspond to your chosen target Corda node. +Simply running from the UI will result in the RPC client running inside the UI JVM. + +If you wish to pass additional arguments to JMeter, you can do this: + +`./gradlew tools:jmeter:run -PjmeterArgs="['-n', '-Ljmeter.engine=DEBUG']"` + +The intention is to run against a remote Corda node or nodes, hosted on servers rather than desktops. To +this end, we leverage the JMeter ability to run remote agents that actually execute the tests, with these +reporting results back to the UI (or headless process if you so desire - e.g. for automated benchmarks). This is +supplemented with some additional convenience of automatically creating ssh tunnels to the remote nodes +(we don't want the JMeter ports open to the internet) in coordination with the jmeter.properties. +The remote agents then run close to the nodes, so the latency of RPC calls is minimised. + +A Capsule (http://www.capsule.io) based launchable JAR is created that can be run with the simple command line + +`java -jar jmeter-corda-.jar` + +Embedded in the JAR is all of the corda code for flows and RPC, as well as the jmeter.propeties. This +JAR will also include a properties file based on the hostname in the JMeter configuration, +so we allocate different SSH tunneled port numbers this way. + +To launch JMeter with the tunnels automatically created: + +`./gradlew tools:jmeter:run -PjmeterHosts="['hostname1', 'hostname2']"` + +The list of hostnames should be of at least length one, with a maximum equal to the length of the remote_hosts +option in jmeter.properties. We effectively "zip" together the hostnames and that list to build the SSH tunnels. +The remote_hosts property helps define the ports (the hosts should always be local) used +for each host listed in jmeterHosts. Some additional ports are also opened based on some other +parts of the configuration to access the RMI registry and to allow return traffic +from remote agents. + +The SSH tunnels can be started independently with: + +`./gradlew tools:jmeter:runSsh -PjmeterHosts="['hostname1', 'hostname2']"` + +For the ssh tunneling to work, an ssh agent must be running on your local machine with the +appropriate private key loaded. If the environment variable `SSH_AUTH_SOCK` is set, the code +assumes that a posix sshagent process is being used, if it is not set, it assumes that +[Pageant](https://www.ssh.com/ssh/putty/putty-manuals/0.68/Chapter9.html) is in use. If the +remote user name is different from the current user name, `-XsshUser ` +can be used to set this, or in the gradle call: + +`./gradlew tools:jmeter:runSsh -PjmeterHosts="['hostname1', 'hostname2']" -PsshUser="'username'"` diff --git a/tools/jmeter/build.gradle b/tools/jmeter/build.gradle new file mode 100644 index 0000000000..aa041346fc --- /dev/null +++ b/tools/jmeter/build.gradle @@ -0,0 +1,138 @@ +apply plugin: 'kotlin' +apply plugin: 'us.kirchmeier.capsule' +apply plugin: 'application' + +mainClassName = 'com.r3.corda.jmeter.Launcher' + +dependencies { + compile project(':client:rpc') + compile project(':finance') + + // https://mvnrepository.com/artifact/com.jcraft/jsch + compile group: 'com.jcraft', name: 'jsch', version: '0.1.54' + compile group: 'com.jcraft', name: 'jsch.agentproxy.core', version: '0.0.9' + compile group: 'com.jcraft', name: 'jsch.agentproxy.sshagent', version: '0.0.9' + compile group: 'com.jcraft', name: 'jsch.agentproxy.usocket-jna', version: '0.0.9' + compile group: 'com.jcraft', name: 'jsch.agentproxy.pageant', version: '0.0.9' + + // Log4J: logging framework (with SLF4J bindings) + compile "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version" + compile "org.apache.logging.log4j:log4j-core:$log4j_version" + + // JMeter + ext.jmVersion = "3.3" + + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_components', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_core', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_ftp', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_functions', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_http', version: "$jmVersion" + compile group: 'org.apache.jmeter', name: 'ApacheJMeter_java', version: "$jmVersion" // 'compile' because we extend Java sampler. + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_jdbc', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_jms', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_junit', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_ldap', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_mail', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_mongodb', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_native', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_tcp', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter_config', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'ApacheJMeter', version: "$jmVersion" + runtime group: 'org.apache.jmeter', name: 'jorphan', version: "$jmVersion" +} + +// Run JMeter as server process/agent on current host. +task(runServer, dependsOn: 'classes', type: JavaExec) { + classpath = sourceSets.main.runtimeClasspath + main = 'com.r3.corda.jmeter.Launcher' + def file = new File("$rootDir/build/search_paths.txt") + file.createNewFile() + file.text = "${project(':tools:jmeter').configurations.runtime.files.join(";")}" + systemProperty "search_paths_file", file.toString() + systemProperty "java.rmi.server.hostname", "0.0.0.0" + systemProperty "jmeter.home", sourceSets.main.resources.getSrcDirs().first().getPath() + // If you want to debug: jvmArgs += "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005" + args+= [ "-p", sourceSets.main.resources.getSrcDirs().first().getPath()+"/jmeter.properties", + "-d", sourceSets.main.resources.getSrcDirs().first().getPath(), + "-s" ] +} + +// Just start ssh tunnels, without JMeter. +task(runSsh, dependsOn: 'classes', type: JavaExec) { + classpath = sourceSets.main.runtimeClasspath + main = 'com.r3.corda.jmeter.Ssh' + if ( project.hasProperty("sshUser") ){ + args+= "-XsshUser" + args+= Eval.me(sshUser) + } + if ( project.hasProperty("jmeterHosts") ) { + args+= "-Xssh" + args+= Eval.me(jmeterHosts) + } + standardInput = System.in +} + +// Run JMeter (by default the UI). +// Extra args can be passed by setting jmeterArgs (e.g. -n to run in non-UI mode). +// e.g. ./gradlew tools:jmeter:run -PjmeterArgs="['-n']" +// ssh tunnels will be built from local host to remote hosts by specifying jmeterHosts +// e.g. ./gradlew tools:jmeter:run -PjmeterHosts="['perf-notary.corda.r3cev.com', 'perf-node-1.corda.r3cev.com']" +// Each host is paired with local host ports listed in remote_hosts of jmeter.properties +run { + def file = new File("$rootDir/build/search_paths.txt") + file.createNewFile() + file.text = "${project(':tools:jmeter').configurations.runtime.files.join(";")}" + systemProperty "search_paths_file", file.toString() + systemProperty "java.rmi.server.hostname", "localhost" + systemProperty "jmeter.home", sourceSets.main.resources.getSrcDirs().first().getPath() + // If you want to debug: jvmArgs += "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005" + args+= [ "-p", sourceSets.main.resources.getSrcDirs().first().getPath()+"/jmeter.properties", + "-d", sourceSets.main.resources.getSrcDirs().first().getPath() ] + if ( project.hasProperty("jmeterArgs") ) { + args+= Eval.me(jmeterHosts) + } + if ( project.hasProperty("sshUser") ){ + args+= "-XsshUser" + args+= Eval.me(sshUser) + } + if ( project.hasProperty("jmeterHosts") ) { + args+= "-Xssh" + args+= Eval.me(jmeterHosts) + } +} + +jar { + manifest { + attributes( + 'Automatic-Module-Name': 'net.corda.tools.jmeter', + 'Main-Class': mainClassName + ) + } + zip64 = true +} + +// For building a runnable jar with no other dependencies for remote JMeter slave server, that has Corda code on classpath. +// Run with: java -jar jmeter-corda-.jar +// No additional args required but will be passed if specified. +task buildJMeterJAR(type: FatCapsule, dependsOn: 'jar') { + applicationClass 'com.r3.corda.jmeter.Launcher' + archiveName "jmeter-corda-${corda_release_version}.jar" + applicationSource = files( + project(':tools:jmeter').jar + ) + from 'NOTICE' // Copy CDDL notice + from("$rootDir/tools/jmeter/build/resources/main") { + include "log4j2.xml" + include "*.properties" + } + + capsuleManifest { + applicationVersion = corda_release_version + systemProperties['java.rmi.server.hostname'] = 'localhost' + minJavaVersion = '1.8.0' + minUpdateVersion['1.8'] = java8_minUpdateVersion + + // JVM configuration. Can be overridden on java command line. + jvmArgs = ['-Xms512m', '-Xmx512m', '-XX:+UseG1GC'] + } +} diff --git a/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/BaseFlowSampler.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/BaseFlowSampler.kt new file mode 100644 index 0000000000..34b17e4901 --- /dev/null +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/BaseFlowSampler.kt @@ -0,0 +1,87 @@ +package com.r3.corda.jmeter + +import net.corda.client.rpc.CordaRPCClient +import net.corda.client.rpc.CordaRPCConnection +import net.corda.core.flows.FlowLogic +import net.corda.core.messaging.CordaRPCOps +import net.corda.core.utilities.NetworkHostAndPort +import org.apache.jmeter.config.Argument +import org.apache.jmeter.config.Arguments +import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient +import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext +import org.apache.jmeter.samplers.SampleResult + +/** + * Do most of the work for firing flow start requests via RPC at a Corda node. + */ +abstract class BaseFlowSampler() : AbstractJavaSamplerClient() { + companion object { + val host = Argument("host", "localhost", "", "The remote network address (hostname or IP address) to connect to for RPC.") + val port = Argument("port", "10000", "", "The remote port to connect to for RPC.") + val username = Argument("username", "corda", "", "The RPC user to connect to connect as.") + val password = Argument("password", "corda_is_awesome", "", "The password for the RPC user.") + + val allArgs = setOf(host, port, username, password) + } + + var rpcClient: CordaRPCClient? = null + var rpcConnection: CordaRPCConnection? = null + var rpcProxy: CordaRPCOps? = null + + override fun getDefaultParameters(): Arguments { + // Add copies of all args, since they seem to be mutable. + return Arguments().apply { + for (arg in allArgs) { + addArgument(arg.clone() as Argument) + } + for (arg in additionalArgs) { + addArgument(arg.clone() as Argument) + } + } + } + + override fun setupTest(context: JavaSamplerContext) { + super.setupTest(context) + rpcClient = CordaRPCClient(NetworkHostAndPort(context.getParameter(host.name), context.getIntParameter(port.name))) + rpcConnection = rpcClient!!.start(context.getParameter(username.name), context.getParameter(password.name)) + rpcProxy = rpcConnection!!.proxy + setupTest(rpcProxy!!, context) + } + + override fun runTest(context: JavaSamplerContext): SampleResult { + val flowInvoke = createFlowInvoke(rpcProxy!!, context) + val result = SampleResult() + result.sampleStart() + val handle = rpcProxy!!.startFlowDynamic(flowInvoke!!.flowLogicClass, *(flowInvoke!!.args)) + result.sampleLabel = handle.id.toString() + result.latencyEnd() + try { + val flowResult = handle.returnValue.get() + result.sampleEnd() + return result.apply { + isSuccessful = true + } + } catch (e: Exception) { + result.sampleEnd() + return result.apply { + isSuccessful = false + } + } + } + + override fun teardownTest(context: JavaSamplerContext) { + teardownTest(rpcProxy!!, context) + rpcProxy = null + rpcConnection!!.close() + rpcConnection = null + rpcClient = null + super.teardownTest(context) + } + + abstract val additionalArgs: Set + abstract fun setupTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) + abstract fun createFlowInvoke(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext): FlowInvoke<*> + abstract fun teardownTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) + + class FlowInvoke>(val flowLogicClass: Class, val args: Array) +} \ No newline at end of file diff --git a/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/JshHelper.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/JshHelper.kt new file mode 100644 index 0000000000..d92a965948 --- /dev/null +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/JshHelper.kt @@ -0,0 +1,63 @@ +package com.r3.corda.jmeter + +import com.jcraft.jsch.Buffer +import com.jcraft.jsch.Identity +import com.jcraft.jsch.IdentityRepository +import com.jcraft.jsch.JSch +import com.jcraft.jsch.agentproxy.AgentProxy +import com.jcraft.jsch.agentproxy.connector.PageantConnector +import com.jcraft.jsch.agentproxy.connector.SSHAgentConnector +import com.jcraft.jsch.agentproxy.usocket.JNAUSocketFactory +import org.slf4j.LoggerFactory +import java.util.* + +private val log = LoggerFactory.getLogger(Ssh::class.java) + +/** + * Creates a new [JSch] instance with identities loaded from the running SSH agent. + */ +fun setupJSchWithSshAgent(): JSch { + val connector = + if (System.getenv("SSH_AUTH_SOCK") == null) + PageantConnector() + else + SSHAgentConnector(JNAUSocketFactory()) + val agentProxy = AgentProxy(connector) + val identities = agentProxy.identities + require(identities.isNotEmpty()) { "No SSH identities found, please add one to the agent" } + require(identities.size == 1) { "Multiple SSH identities found, don't know which one to pick" } + val identity = identities[0] + log.info("Using SSH identity ${String(identity.comment)}") + + return JSch().apply { + identityRepository = object : IdentityRepository { + override fun getStatus(): Int { + if (connector.isAvailable) { + return IdentityRepository.RUNNING + } else { + return IdentityRepository.UNAVAILABLE + } + } + + override fun getName() = connector.name + override fun getIdentities(): Vector = Vector(listOf( + object : Identity { + override fun clear() {} + override fun getAlgName() = String(Buffer(identity.blob).string) + override fun getName() = String(identity.comment) + override fun isEncrypted() = false + override fun getSignature(data: ByteArray?) = agentProxy.sign(identity.blob, data) + @Suppress("OverridingDeprecatedMember") + override fun decrypt() = true + + override fun getPublicKeyBlob() = identity.blob + override fun setPassphrase(passphrase: ByteArray?) = true + } + )) + + override fun remove(blob: ByteArray?) = throw UnsupportedOperationException() + override fun removeAll() = throw UnsupportedOperationException() + override fun add(bytes: ByteArray?) = throw UnsupportedOperationException() + } + } +} diff --git a/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Launcher.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Launcher.kt new file mode 100644 index 0000000000..b11d1d9f0d --- /dev/null +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Launcher.kt @@ -0,0 +1,83 @@ +package com.r3.corda.jmeter + +import com.sun.javaws.exceptions.InvalidArgumentException +import net.corda.core.internal.div +import org.apache.jmeter.JMeter +import org.slf4j.LoggerFactory +import java.net.InetAddress +import java.nio.file.Files +import java.nio.file.Paths +import kotlin.streams.asSequence + +/** + * A wrapper around JMeter to make it run without having a JMeter download installed locally. One mode is used for + * running on a remote cluster using an all-in-one bundle JAR using Capsule. The other is just used to run based on current + * classpath, but with optional SSH tunnelling logic automatically invoked. + */ +class Launcher { + companion object { + @JvmStatic + fun main(args: Array) { + val logger = LoggerFactory.getLogger(this::class.java) + logger.info("Launcher called with ${args.toList()}") + val jmeter = JMeter() + val capsuleDir = System.getProperty("capsule.dir") + if (capsuleDir != null) { + // We are running under Capsule, so assume we want a JMeter slave server to be controlled from + // elsewhere. + logger.info("Starting JMeter in server mode from $capsuleDir") + val capsuleDirPath = Paths.get(capsuleDir) + // Add all JMeter and Corda jars onto the JMeter search_paths + val searchPath = Files.list(capsuleDirPath).asSequence().filter { + val filename = it.fileName.toString() + filename.endsWith(".jar") && (filename.contains("corda") || filename.contains("jmeter", true)) + }.joinToString(";") + logger.info("search_paths = $searchPath") + System.setProperty("search_paths", searchPath) + // Set the JMeter home as a property rather than command line arg, due to inconsistent code in JMeter. + System.setProperty("jmeter.home", capsuleDir) + // Create two dirs that JMeter expects, if they don't already exist. + Files.createDirectories(capsuleDirPath / "lib" / "ext") + Files.createDirectories(capsuleDirPath / "lib" / "junit") + // Now see if we have a hostname specific property file, and if so, add it. + val hostName = InetAddress.getLocalHost().hostName + val hostSpecificConfigFile = capsuleDirPath / "$hostName.properties" + logger.info("Attempting to use host-specific properties file $hostSpecificConfigFile") + val extraArgs = if (Files.exists(hostSpecificConfigFile)) { + logger.info("Found host-specific properties file") + arrayOf("-q", hostSpecificConfigFile.toString()) + } else { + emptyArray() + } + jmeter.start(arrayOf("-s", "-p", (capsuleDirPath / "jmeter.properties").toString()) + extraArgs + args) + } else { + jmeter.start(maybeOpenSshTunnels(args)) + } + } + + fun maybeOpenSshTunnels(args: Array): Array { + // We trim the args at the point "-Xssh" appears in the array of args. Anything after that is a host to + // SSH tunnel to. Also get and remove the "-XsshUser" argument if it appears. + var index = 0 + var userName = System.getProperty("user.name") + val returnArgs = mutableListOf() + while (index < args.size) { + if (args[index] == "-XsshUser") { + ++index + if (index == args.size || args[index].startsWith("-")) { + throw InvalidArgumentException(args) + } + userName = args[index] + } else if (args[index] == "-Xssh") { + // start ssh + Ssh.createSshTunnels(args.copyOfRange(index + 1, args.size), userName, false) + return returnArgs.toTypedArray() + } else { + returnArgs.add(args[index]) + } + index++ + } + return returnArgs.toTypedArray() + } + } +} \ No newline at end of file diff --git a/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Samplers.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Samplers.kt new file mode 100644 index 0000000000..e23cc399cc --- /dev/null +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Samplers.kt @@ -0,0 +1,51 @@ +package com.r3.corda.jmeter + +import net.corda.core.identity.CordaX500Name +import net.corda.core.identity.Party +import net.corda.core.messaging.CordaRPCOps +import net.corda.core.utilities.OpaqueBytes +import net.corda.finance.DOLLARS +import net.corda.finance.flows.CashIssueFlow +import org.apache.jmeter.config.Argument +import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext + +/** + * A base sampler that looks up identities via RPC ready for starting flows, to be extended and specialised as required. + */ +abstract class AbstractSampler : BaseFlowSampler() { + lateinit var notaryIdentity: Party + + companion object JMeterProperties { + val notary = Argument("notaryName", "", "", "The X500 name of the notary.") + } + + protected fun getIdentities(rpc: CordaRPCOps, testContext: JavaSamplerContext) { + if (!testContext.containsParameter(notary.name)) { + throw IllegalStateException("You must specify the '${notary.name}' property.") + } + val notaryName = CordaX500Name.parse(testContext.getParameter(notary.name)) + notaryIdentity = rpc.wellKnownPartyFromX500Name(notaryName) ?: throw IllegalStateException("Don't know $notaryName") + } +} + +/** + * A sampler for calling CashIssueFlow. + * + * TODO: add more configurable parameters (reference, amount etc) if there is a requirement. + */ +class CashIssueSampler : AbstractSampler() { + override val additionalArgs: Set = setOf(notary) + + override fun setupTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) { + getIdentities(rpcProxy, testContext) + } + + override fun teardownTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) { + } + + override fun createFlowInvoke(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext): FlowInvoke { + val amount = 1_100_000_000_000.DOLLARS + return FlowInvoke(CashIssueFlow::class.java, arrayOf(amount, OpaqueBytes.of(1), notaryIdentity)) + } + +} \ No newline at end of file diff --git a/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt new file mode 100644 index 0000000000..a01af325e5 --- /dev/null +++ b/tools/jmeter/src/main/kotlin/com/r3/corda/jmeter/Ssh.kt @@ -0,0 +1,135 @@ +package com.r3.corda.jmeter + +import com.jcraft.jsch.JSch +import com.jcraft.jsch.Session +import com.sun.javaws.exceptions.InvalidArgumentException +import net.corda.core.utilities.NetworkHostAndPort +import net.corda.nodeapi.internal.addShutdownHook +import org.slf4j.LoggerFactory +import java.io.BufferedReader +import java.io.InputStreamReader +import java.util.* + +/** + * Creates SSH tunnels for remote controlling SSH servers/agents from the local host (via UI or headless). + */ +class Ssh { + companion object { + val log = LoggerFactory.getLogger(this::class.java) + + @JvmStatic + fun main(args: Array) { + // parse the args and call createSshTunnels + // the only arguments recognised are "-XsshUser" for the remote user name + // and "-Xssh" - everything after this will be treated as a remote host name + var userName = System.getProperty("user.name") + var index = 0 + while (index < args.size) { + if (args[index] == "-XsshUser") { + ++index + if (index == args.size || args[index].startsWith("-")) { + throw InvalidArgumentException(args) + } + userName = args[index] + } else if (args[index] == "-Xssh") { + createSshTunnels(args.copyOfRange(index + 1, args.size), userName, true) + return + } + } + log.info("Nothing to be done - did you specify hosts to tunnel to with -Xssh?") + } + + + fun createSshTunnels(hosts: Array, userName: String, wait: Boolean) { + log.info("User name for ssh: ${userName}") + val jsch = setupJSchWithSshAgent() + val sessions = mutableListOf() + + // Read jmeter.properties + // For each host:port combo, map them to hosts from command line + + val jmeterProps = loadProps("/jmeter.properties") + // The port the JMeter remote agents call back to on this client host. + val clientRmiLocalPort = jmeterProps.getProperty("client.rmi.localport").toInt() + // Remote RMI registry port. + val serverRmiPort = jmeterProps.getProperty("server.rmi.port", "1099").toInt() + + // Where JMeter driver will try to connect for remote agents (should all be localhost so can ssh tunnel). + val localHostsAndPorts = jmeterProps.getProperty("remote_hosts", "").split(',').map { it.trim() } + hosts.zip(localHostsAndPorts) { remoteHost, localHostAndPortString -> + // Actual remote host and port we will tunnel to. + log.info("Creating tunnels for $remoteHost") + val localHostAndPort = NetworkHostAndPort.parse(localHostAndPortString) + + // For the remote host, load their specific property file, since it specifies remote RMI server port + val unqualifiedHostName = remoteHost.substringBefore('.') + val hostProps = loadProps("/$unqualifiedHostName.properties") + + val serverRmiLocalPort = hostProps.getProperty("server.rmi.localport", jmeterProps.getProperty("server.rmi.localport")).toInt() + + val session = connectToHost(jsch, remoteHost, userName) + sessions += session + + // For tunnelling the RMI registry on the remote agent + // ssh ${remoteHostAndPort.host} -L 0.0.0.0:${localHostAndPort.port}:localhost:$serverRmiPort -N + createOutboundTunnel(session, NetworkHostAndPort("0.0.0.0", localHostAndPort.port), NetworkHostAndPort("localhost", serverRmiPort)) + + // For tunnelling the actual connection to the remote agent + // ssh ${remoteHostAndPort.host} -L 0.0.0.0:$serverRmiLocalPort:localhost:$serverRmiLocalPort -N + createOutboundTunnel(session, NetworkHostAndPort("0.0.0.0", serverRmiLocalPort), NetworkHostAndPort("localhost", serverRmiLocalPort)) + + // For returning results to the client + // ssh ${remoteHostAndPort.host} -R 0.0.0.0:clientRmiLocalPort:localhost:clientRmiLocalPort -N + createInboundTunnel(session, NetworkHostAndPort("0.0.0.0", clientRmiLocalPort), NetworkHostAndPort("localhost", clientRmiLocalPort)) + } + + if (wait) { + val input = BufferedReader(InputStreamReader(System.`in`)) + do { + log.info("Type 'quit' to exit cleanly.") + } while (input.readLine() != "quit") + sessions.forEach { + log.info("Closing tunnels for ${it.host}") + it.disconnect() + } + } else { + addShutdownHook { + sessions.forEach { + log.info("Closing tunnels for ${it.host}") + it.disconnect() + } + } + } + } + + private fun loadProps(filename: String): Properties { + val props = Properties() + this::class.java.getResourceAsStream(filename).use { + props.load(it) + } + return props + } + + fun connectToHost(jSch: JSch, remoteHost: String, remoteUserName: String): Session { + val session = jSch.getSession(remoteUserName, remoteHost, 22) + // We don't check the host fingerprints because they may change often + session.setConfig("StrictHostKeyChecking", "no") + log.info("Connecting to $remoteHost...") + session.connect() + log.info("Connected to $remoteHost!") + return session + } + + fun createOutboundTunnel(session: Session, local: NetworkHostAndPort, remote: NetworkHostAndPort) { + log.info("Creating outbound tunnel from $local to $remote with ${session.host}...") + session.setPortForwardingL(local.host, local.port, remote.host, remote.port) + log.info("Tunnel created!") + } + + fun createInboundTunnel(session: Session, local: NetworkHostAndPort, remote: NetworkHostAndPort) { + log.info("Creating inbound tunnel from $remote to $local on ${session.host}...") + session.setPortForwardingR(remote.host, remote.port, local.host, local.port) + log.info("Tunnel created!") + } + } +} \ No newline at end of file diff --git a/tools/jmeter/src/main/resources/Example Flow Request.jmx b/tools/jmeter/src/main/resources/Example Flow Request.jmx new file mode 100644 index 0000000000..6a2d25cfcf --- /dev/null +++ b/tools/jmeter/src/main/resources/Example Flow Request.jmx @@ -0,0 +1,177 @@ + + + + + + false + false + + + + + + + + continue + + false + 1000 + + 3 + + 1509455820000 + 1509455820000 + false + + + + + + + + + host + localhost + = + + + port + 10003 + = + + + username + corda + = + + + password + Password Here + = + + + notaryName + O=Perf-10.155.0.4, OU=Corda, L=London, C=GB + = + + + + com.r3.corda.jmeter.CashIssueSampler + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + + + + + + + + true + + + + diff --git a/tools/jmeter/src/main/resources/bin/saveservice.properties b/tools/jmeter/src/main/resources/bin/saveservice.properties new file mode 100644 index 0000000000..3e2b5fb4e1 --- /dev/null +++ b/tools/jmeter/src/main/resources/bin/saveservice.properties @@ -0,0 +1,412 @@ +#--------------------------------------------------------- +# SAVESERVICE PROPERTIES - JMETER INTERNAL USE ONLY +#--------------------------------------------------------- + +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. + +# This file is used to define how XStream (de-)serializes classnames +# in JMX test plan files. + +# FOR JMETER INTERNAL USE ONLY + +#--------------------------------------------------------- + +# N.B. To ensure backward compatibility, please do NOT change or delete any entries + +# New entries can be added as necessary. +# +# Note that keys starting with an underscore are special, +# and are not used as aliases. +# +# Please keep the entries in alphabetical order within the sections +# to reduce the likelihood of duplicates +# +# version number of this file is now computed by a sha1 sum, so no need for +# an explicit _file_version property anymore. +# +# For this sha1 sum we ignore every newline character. It can be computed +# by the following command: +# +# cat bin/saveservice.properties | perl -ne 'chomp; print' | sha1sum +# +# Be aware, that every change in this file will change the sha1 sum! +# +# Conversion version (for JMX output files) +# Must be updated if the file has been changed since the previous release +# Format is: +# Save service version=JMeter version at which change occurred +# 1.7 = 2.1.1 +# 1.8 = 2.1.2 +# (Some version updates were missed here...) +# 2.0 = 2.3.1 +# 2.1 = 2.3.2 +# (Some version updates were missed here...) +# 2.2 = 2.6 +# 2.3 = 2.7 +# 2.4 = 2.9 +# 2.5 = 2.10 +# 2.6 = 2.11 +# 2.7 = 2.12 +# 2.8 = 2.13 +# 2.9 = 2.14 +# 3.1 = 3.1 +# 3.2 = 3.2 +_version=3.2 +# +# +# Character set encoding used to read and write JMeter XML files and CSV results +# +_file_encoding=UTF-8 +# +#--------------------------------------------------------- +# +# The following properties are used to create aliases +# [Must all start with capital letter] +# +AccessLogSampler=org.apache.jmeter.protocol.http.sampler.AccessLogSampler +AjpSampler=org.apache.jmeter.protocol.http.sampler.AjpSampler +AjpSamplerGui=org.apache.jmeter.protocol.http.control.gui.AjpSamplerGui +AnchorModifier=org.apache.jmeter.protocol.http.modifier.AnchorModifier +AnchorModifierGui=org.apache.jmeter.protocol.http.modifier.gui.AnchorModifierGui +Argument=org.apache.jmeter.config.Argument +Arguments=org.apache.jmeter.config.Arguments +ArgumentsPanel=org.apache.jmeter.config.gui.ArgumentsPanel +AssertionGui=org.apache.jmeter.assertions.gui.AssertionGui +AssertionVisualizer=org.apache.jmeter.visualizers.AssertionVisualizer +AuthManager=org.apache.jmeter.protocol.http.control.AuthManager +Authorization=org.apache.jmeter.protocol.http.control.Authorization +AuthPanel=org.apache.jmeter.protocol.http.gui.AuthPanel +BackendListener=org.apache.jmeter.visualizers.backend.BackendListener +BackendListenerGui=org.apache.jmeter.visualizers.backend.BackendListenerGui +BeanShellAssertion=org.apache.jmeter.assertions.BeanShellAssertion +BeanShellAssertionGui=org.apache.jmeter.assertions.gui.BeanShellAssertionGui +BeanShellListener=org.apache.jmeter.visualizers.BeanShellListener +BeanShellPostProcessor=org.apache.jmeter.extractor.BeanShellPostProcessor +BeanShellPreProcessor=org.apache.jmeter.modifiers.BeanShellPreProcessor +BeanShellSampler=org.apache.jmeter.protocol.java.sampler.BeanShellSampler +BeanShellSamplerGui=org.apache.jmeter.protocol.java.control.gui.BeanShellSamplerGui +BeanShellTimer=org.apache.jmeter.timers.BeanShellTimer +BSFAssertion=org.apache.jmeter.assertions.BSFAssertion +BSFListener=org.apache.jmeter.visualizers.BSFListener +BSFPreProcessor=org.apache.jmeter.modifiers.BSFPreProcessor +BSFPostProcessor=org.apache.jmeter.extractor.BSFPostProcessor +BSFSampler=org.apache.jmeter.protocol.java.sampler.BSFSampler +BSFSamplerGui=org.apache.jmeter.protocol.java.control.gui.BSFSamplerGui +BSFTimer=org.apache.jmeter.timers.BSFTimer +CacheManager=org.apache.jmeter.protocol.http.control.CacheManager +CacheManagerGui=org.apache.jmeter.protocol.http.gui.CacheManagerGui +CompareAssertion=org.apache.jmeter.assertions.CompareAssertion +ComparisonVisualizer=org.apache.jmeter.visualizers.ComparisonVisualizer +ConfigTestElement=org.apache.jmeter.config.ConfigTestElement +ConstantThroughputTimer=org.apache.jmeter.timers.ConstantThroughputTimer +ConstantTimer=org.apache.jmeter.timers.ConstantTimer +ConstantTimerGui=org.apache.jmeter.timers.gui.ConstantTimerGui +Cookie=org.apache.jmeter.protocol.http.control.Cookie +CookieManager=org.apache.jmeter.protocol.http.control.CookieManager +CookiePanel=org.apache.jmeter.protocol.http.gui.CookiePanel +CounterConfig=org.apache.jmeter.modifiers.CounterConfig +CriticalSectionController=org.apache.jmeter.control.CriticalSectionController +CriticalSectionControllerGui=org.apache.jmeter.control.gui.CriticalSectionControllerGui +CounterConfigGui=org.apache.jmeter.modifiers.gui.CounterConfigGui +CSVDataSet=org.apache.jmeter.config.CSVDataSet +DebugPostProcessor=org.apache.jmeter.extractor.DebugPostProcessor +DebugSampler=org.apache.jmeter.sampler.DebugSampler +# removed in 3.1, class was deleted in r1763837 +DistributionGraphVisualizer=org.apache.jmeter.visualizers.DistributionGraphVisualizer +DNSCacheManager=org.apache.jmeter.protocol.http.control.DNSCacheManager +DNSCachePanel=org.apache.jmeter.protocol.http.gui.DNSCachePanel +DurationAssertion=org.apache.jmeter.assertions.DurationAssertion +DurationAssertionGui=org.apache.jmeter.assertions.gui.DurationAssertionGui +# Should really have been defined as floatProp to agree with other properties +# No point changing this now +FloatProperty=org.apache.jmeter.testelement.property.FloatProperty +ForeachController=org.apache.jmeter.control.ForeachController +ForeachControlPanel=org.apache.jmeter.control.gui.ForeachControlPanel +FtpConfigGui=org.apache.jmeter.protocol.ftp.config.gui.FtpConfigGui +FTPSampler=org.apache.jmeter.protocol.ftp.sampler.FTPSampler +FtpTestSamplerGui=org.apache.jmeter.protocol.ftp.control.gui.FtpTestSamplerGui +GaussianRandomTimer=org.apache.jmeter.timers.GaussianRandomTimer +GaussianRandomTimerGui=org.apache.jmeter.timers.gui.GaussianRandomTimerGui +GenericController=org.apache.jmeter.control.GenericController +GraphAccumVisualizer=org.apache.jmeter.visualizers.GraphAccumVisualizer +GraphVisualizer=org.apache.jmeter.visualizers.GraphVisualizer +Header=org.apache.jmeter.protocol.http.control.Header +HeaderManager=org.apache.jmeter.protocol.http.control.HeaderManager +HeaderPanel=org.apache.jmeter.protocol.http.gui.HeaderPanel +HTMLAssertion=org.apache.jmeter.assertions.HTMLAssertion +HTMLAssertionGui=org.apache.jmeter.assertions.gui.HTMLAssertionGui +HTTPArgument=org.apache.jmeter.protocol.http.util.HTTPArgument +HTTPArgumentsPanel=org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel +HTTPFileArg=org.apache.jmeter.protocol.http.util.HTTPFileArg +HTTPFileArgs=org.apache.jmeter.protocol.http.util.HTTPFileArgs +HttpDefaultsGui=org.apache.jmeter.protocol.http.config.gui.HttpDefaultsGui +HtmlExtractor=org.apache.jmeter.extractor.HtmlExtractor +HtmlExtractorGui=org.apache.jmeter.extractor.gui.HtmlExtractorGui +# removed in r1039684, probably not released. Not present in r322831 or since. +#HttpGenericSampler=org.apache.jmeter.protocol.http.sampler.HttpGenericSampler +# removed in r1039684, probably not released. Not present in r322831 or since. +#HttpGenericSamplerGui=org.apache.jmeter.protocol.http.control.gui.HttpGenericSamplerGui +HttpMirrorControl=org.apache.jmeter.protocol.http.control.HttpMirrorControl +HttpMirrorControlGui=org.apache.jmeter.protocol.http.control.gui.HttpMirrorControlGui +# r397955 - removed test class. Keep as commented entry for info only. +#HTTPNullSampler=org.apache.jmeter.protocol.http.sampler.HTTPNullSampler +# Merge previous 2 HTTP samplers into one +HTTPSampler_=org.apache.jmeter.protocol.http.sampler.HTTPSampler +HTTPSampler2_=org.apache.jmeter.protocol.http.sampler.HTTPSampler2 +HTTPSamplerProxy,HTTPSampler,HTTPSampler2=org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy +# Merge GUIs +HttpTestSampleGui,HttpTestSampleGui2=org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui +#HttpTestSampleGui2=org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui2 +IfController=org.apache.jmeter.control.IfController +IfControllerPanel=org.apache.jmeter.control.gui.IfControllerPanel +IncludeController=org.apache.jmeter.control.IncludeController +IncludeControllerGui=org.apache.jmeter.control.gui.IncludeControllerGui +InterleaveControl=org.apache.jmeter.control.InterleaveControl +InterleaveControlGui=org.apache.jmeter.control.gui.InterleaveControlGui +JavaConfig=org.apache.jmeter.protocol.java.config.JavaConfig +JavaConfigGui=org.apache.jmeter.protocol.java.config.gui.JavaConfigGui +JavaSampler=org.apache.jmeter.protocol.java.sampler.JavaSampler +JavaTest=org.apache.jmeter.protocol.java.test.JavaTest +JavaTestSamplerGui=org.apache.jmeter.protocol.java.control.gui.JavaTestSamplerGui +JDBCDataSource=org.apache.jmeter.protocol.jdbc.config.DataSourceElement +JDBCPostProcessor=org.apache.jmeter.protocol.jdbc.processor.JDBCPostProcessor +JDBCPreProcessor=org.apache.jmeter.protocol.jdbc.processor.JDBCPreProcessor +JDBCSampler=org.apache.jmeter.protocol.jdbc.sampler.JDBCSampler +# Renamed to JMSSamplerGui; keep original entry for backwards compatibility +JMSConfigGui=org.apache.jmeter.protocol.jms.control.gui.JMSConfigGui +JMSProperties=org.apache.jmeter.protocol.jms.sampler.JMSProperties +JMSProperty=org.apache.jmeter.protocol.jms.sampler.JMSProperty +JMSPublisherGui=org.apache.jmeter.protocol.jms.control.gui.JMSPublisherGui +JMSSampler=org.apache.jmeter.protocol.jms.sampler.JMSSampler +JMSSamplerGui=org.apache.jmeter.protocol.jms.control.gui.JMSSamplerGui +JMSSubscriberGui=org.apache.jmeter.protocol.jms.control.gui.JMSSubscriberGui +JSONPostProcessor=org.apache.jmeter.extractor.json.jsonpath.JSONPostProcessor +JSONPostProcessorGui=org.apache.jmeter.extractor.json.jsonpath.gui.JSONPostProcessorGui +# Removed in r545311 as Jndi no longer present; keep for compat. +JndiDefaultsGui=org.apache.jmeter.protocol.jms.control.gui.JndiDefaultsGui +JSR223Assertion=org.apache.jmeter.assertions.JSR223Assertion +JSR223Listener=org.apache.jmeter.visualizers.JSR223Listener +JSR223PostProcessor=org.apache.jmeter.extractor.JSR223PostProcessor +JSR223PreProcessor=org.apache.jmeter.modifiers.JSR223PreProcessor +JSR223Sampler=org.apache.jmeter.protocol.java.sampler.JSR223Sampler +JSR223Timer=org.apache.jmeter.timers.JSR223Timer +JUnitSampler=org.apache.jmeter.protocol.java.sampler.JUnitSampler +JUnitTestSamplerGui=org.apache.jmeter.protocol.java.control.gui.JUnitTestSamplerGui +KeystoreConfig=org.apache.jmeter.config.KeystoreConfig +LDAPArgument=org.apache.jmeter.protocol.ldap.config.gui.LDAPArgument +LDAPArguments=org.apache.jmeter.protocol.ldap.config.gui.LDAPArguments +LDAPArgumentsPanel=org.apache.jmeter.protocol.ldap.config.gui.LDAPArgumentsPanel +LdapConfigGui=org.apache.jmeter.protocol.ldap.config.gui.LdapConfigGui +LdapExtConfigGui=org.apache.jmeter.protocol.ldap.config.gui.LdapExtConfigGui +LDAPExtSampler=org.apache.jmeter.protocol.ldap.sampler.LDAPExtSampler +LdapExtTestSamplerGui=org.apache.jmeter.protocol.ldap.control.gui.LdapExtTestSamplerGui +LDAPSampler=org.apache.jmeter.protocol.ldap.sampler.LDAPSampler +LdapTestSamplerGui=org.apache.jmeter.protocol.ldap.control.gui.LdapTestSamplerGui +LogicControllerGui=org.apache.jmeter.control.gui.LogicControllerGui +LoginConfig=org.apache.jmeter.config.LoginConfig +LoginConfigGui=org.apache.jmeter.config.gui.LoginConfigGui +LoopController=org.apache.jmeter.control.LoopController +LoopControlPanel=org.apache.jmeter.control.gui.LoopControlPanel +MailerModel=org.apache.jmeter.reporters.MailerModel +MailerResultCollector=org.apache.jmeter.reporters.MailerResultCollector +MailerVisualizer=org.apache.jmeter.visualizers.MailerVisualizer +MailReaderSampler=org.apache.jmeter.protocol.mail.sampler.MailReaderSampler +MailReaderSamplerGui=org.apache.jmeter.protocol.mail.sampler.gui.MailReaderSamplerGui +MD5HexAssertion=org.apache.jmeter.assertions.MD5HexAssertion +MD5HexAssertionGUI=org.apache.jmeter.assertions.gui.MD5HexAssertionGUI +ModuleController=org.apache.jmeter.control.ModuleController +ModuleControllerGui=org.apache.jmeter.control.gui.ModuleControllerGui +MongoScriptSampler=org.apache.jmeter.protocol.mongodb.sampler.MongoScriptSampler +MongoSourceElement=org.apache.jmeter.protocol.mongodb.config.MongoSourceElement + +# removed in 3.2, class was deleted in r +MonitorHealthVisualizer=org.apache.jmeter.visualizers.MonitorHealthVisualizer + +NamePanel=org.apache.jmeter.gui.NamePanel +ObsoleteGui=org.apache.jmeter.config.gui.ObsoleteGui +OnceOnlyController=org.apache.jmeter.control.OnceOnlyController +OnceOnlyControllerGui=org.apache.jmeter.control.gui.OnceOnlyControllerGui +# removed in 3.0, class was deleted in r1722962 +ParamMask=org.apache.jmeter.protocol.http.modifier.ParamMask +# removed in 3.0, class was deleted in r1722757 +ParamModifier=org.apache.jmeter.protocol.http.modifier.ParamModifier +# removed in 3.0, class was deleted in r1722757 +ParamModifierGui=org.apache.jmeter.protocol.http.modifier.gui.ParamModifierGui +PoissonRandomTimer=org.apache.jmeter.timers.PoissonRandomTimer +PoissonRandomTimerGui=org.apache.jmeter.timers.gui.PoissonRandomTimerGui +PropertyControlGui=org.apache.jmeter.visualizers.PropertyControlGui +ProxyControl=org.apache.jmeter.protocol.http.proxy.ProxyControl +ProxyControlGui=org.apache.jmeter.protocol.http.proxy.gui.ProxyControlGui +PublisherSampler=org.apache.jmeter.protocol.jms.sampler.PublisherSampler +RandomControlGui=org.apache.jmeter.control.gui.RandomControlGui +RandomController=org.apache.jmeter.control.RandomController +RandomOrderController=org.apache.jmeter.control.RandomOrderController +RandomOrderControllerGui=org.apache.jmeter.control.gui.RandomOrderControllerGui +RandomVariableConfig=org.apache.jmeter.config.RandomVariableConfig +RecordController=org.apache.jmeter.protocol.http.control.gui.RecordController +RecordingController=org.apache.jmeter.protocol.http.control.RecordingController +# removed in r1039684, class was deleted in r580452 +ReflectionThreadGroup=org.apache.jmeter.threads.ReflectionThreadGroup +RegexExtractor=org.apache.jmeter.extractor.RegexExtractor +RegexExtractorGui=org.apache.jmeter.extractor.gui.RegexExtractorGui +RegExUserParameters=org.apache.jmeter.protocol.http.modifier.RegExUserParameters +RegExUserParametersGui=org.apache.jmeter.protocol.http.modifier.gui.RegExUserParametersGui +RemoteListenerWrapper=org.apache.jmeter.samplers.RemoteListenerWrapper +RemoteSampleListenerWrapper=org.apache.jmeter.samplers.RemoteSampleListenerWrapper +RemoteTestListenerWrapper=org.apache.jmeter.samplers.RemoteTestListenerWrapper +RemoteThreadsListenerWrapper=org.apache.jmeter.threads.RemoteThreadsListenerWrapper +ResponseAssertion=org.apache.jmeter.assertions.ResponseAssertion +RespTimeGraphVisualizer=org.apache.jmeter.visualizers.RespTimeGraphVisualizer +ResultAction=org.apache.jmeter.reporters.ResultAction +ResultActionGui=org.apache.jmeter.reporters.gui.ResultActionGui +ResultCollector=org.apache.jmeter.reporters.ResultCollector +ResultSaver=org.apache.jmeter.reporters.ResultSaver +ResultSaverGui=org.apache.jmeter.reporters.gui.ResultSaverGui +RunTime=org.apache.jmeter.control.RunTime +RunTimeGui=org.apache.jmeter.control.gui.RunTimeGui +SampleSaveConfiguration=org.apache.jmeter.samplers.SampleSaveConfiguration +SampleTimeout=org.apache.jmeter.modifiers.SampleTimeout +SampleTimeoutGui=org.apache.jmeter.modifiers.gui.SampleTimeoutGui +SimpleConfigGui=org.apache.jmeter.config.gui.SimpleConfigGui +SimpleDataWriter=org.apache.jmeter.visualizers.SimpleDataWriter +SizeAssertion=org.apache.jmeter.assertions.SizeAssertion +SizeAssertionGui=org.apache.jmeter.assertions.gui.SizeAssertionGui +SMIMEAssertion=org.apache.jmeter.assertions.SMIMEAssertionTestElement +SMIMEAssertionGui=org.apache.jmeter.assertions.gui.SMIMEAssertionGui +SmtpSampler=org.apache.jmeter.protocol.smtp.sampler.SmtpSampler +SmtpSamplerGui=org.apache.jmeter.protocol.smtp.sampler.gui.SmtpSamplerGui + +# removed in 3.2, class was deleted in r +SoapSampler=org.apache.jmeter.protocol.http.sampler.SoapSampler +# removed in 3.2, class was deleted in r +SoapSamplerGui=org.apache.jmeter.protocol.http.control.gui.SoapSamplerGui + +# removed in 3.1, class was deleted in r1763837 +SplineVisualizer=org.apache.jmeter.visualizers.SplineVisualizer +# Originally deleted in r397955 as class is obsolete; needed for compat. +SqlConfigGui=org.apache.jmeter.protocol.jdbc.config.gui.SqlConfigGui +StaticHost=org.apache.jmeter.protocol.http.control.StaticHost +StatGraphVisualizer=org.apache.jmeter.visualizers.StatGraphVisualizer +StatVisualizer=org.apache.jmeter.visualizers.StatVisualizer +SubscriberSampler=org.apache.jmeter.protocol.jms.sampler.SubscriberSampler +SubstitutionElement=org.apache.jmeter.assertions.SubstitutionElement +Summariser=org.apache.jmeter.reporters.Summariser +SummariserGui=org.apache.jmeter.reporters.gui.SummariserGui +SummaryReport=org.apache.jmeter.visualizers.SummaryReport +SwitchController=org.apache.jmeter.control.SwitchController +SwitchControllerGui=org.apache.jmeter.control.gui.SwitchControllerGui +SyncTimer=org.apache.jmeter.timers.SyncTimer +SystemSampler=org.apache.jmeter.protocol.system.SystemSampler +SystemSamplerGui=org.apache.jmeter.protocol.system.gui.SystemSamplerGui +TableVisualizer=org.apache.jmeter.visualizers.TableVisualizer +TCPConfigGui=org.apache.jmeter.protocol.tcp.config.gui.TCPConfigGui +TCPSampler=org.apache.jmeter.protocol.tcp.sampler.TCPSampler +TCPSamplerGui=org.apache.jmeter.protocol.tcp.control.gui.TCPSamplerGui +TestAction=org.apache.jmeter.sampler.TestAction +TestActionGui=org.apache.jmeter.sampler.gui.TestActionGui +TestBeanGUI=org.apache.jmeter.testbeans.gui.TestBeanGUI +TestFragmentController=org.apache.jmeter.control.TestFragmentController +TestFragmentControllerGui=org.apache.jmeter.control.gui.TestFragmentControllerGui +TestPlan=org.apache.jmeter.testelement.TestPlan +TestPlanGui=org.apache.jmeter.control.gui.TestPlanGui +ThreadGroup=org.apache.jmeter.threads.ThreadGroup +ThreadGroupGui=org.apache.jmeter.threads.gui.ThreadGroupGui +PostThreadGroup=org.apache.jmeter.threads.PostThreadGroup +PostThreadGroupGui=org.apache.jmeter.threads.gui.PostThreadGroupGui +SetupThreadGroup=org.apache.jmeter.threads.SetupThreadGroup +SetupThreadGroupGui=org.apache.jmeter.threads.gui.SetupThreadGroupGui +ThroughputController=org.apache.jmeter.control.ThroughputController +ThroughputControllerGui=org.apache.jmeter.control.gui.ThroughputControllerGui +TransactionController=org.apache.jmeter.control.TransactionController +TransactionControllerGui=org.apache.jmeter.control.gui.TransactionControllerGui +TransactionSampler=org.apache.jmeter.control.TransactionSampler +UniformRandomTimer=org.apache.jmeter.timers.UniformRandomTimer +UniformRandomTimerGui=org.apache.jmeter.timers.gui.UniformRandomTimerGui +URLRewritingModifier=org.apache.jmeter.protocol.http.modifier.URLRewritingModifier +URLRewritingModifierGui=org.apache.jmeter.protocol.http.modifier.gui.URLRewritingModifierGui +UserParameterModifier=org.apache.jmeter.protocol.http.modifier.UserParameterModifier +UserParameterModifierGui=org.apache.jmeter.protocol.http.modifier.gui.UserParameterModifierGui +UserParameters=org.apache.jmeter.modifiers.UserParameters +UserParametersGui=org.apache.jmeter.modifiers.gui.UserParametersGui +ViewResultsFullVisualizer=org.apache.jmeter.visualizers.ViewResultsFullVisualizer +# removed in 3.0, class was deleted in r1722757 +WebServiceSampler=org.apache.jmeter.protocol.http.sampler.WebServiceSampler +# removed in 3.0, class was deleted in r1722757 +WebServiceSamplerGui=org.apache.jmeter.protocol.http.control.gui.WebServiceSamplerGui +WhileController=org.apache.jmeter.control.WhileController +WhileControllerGui=org.apache.jmeter.control.gui.WhileControllerGui +WorkBench=org.apache.jmeter.testelement.WorkBench +WorkBenchGui=org.apache.jmeter.control.gui.WorkBenchGui +XMLAssertion=org.apache.jmeter.assertions.XMLAssertion +XMLAssertionGui=org.apache.jmeter.assertions.gui.XMLAssertionGui +XMLSchemaAssertion=org.apache.jmeter.assertions.XMLSchemaAssertion +XMLSchemaAssertionGUI=org.apache.jmeter.assertions.gui.XMLSchemaAssertionGUI +XPathAssertion=org.apache.jmeter.assertions.XPathAssertion +XPathAssertionGui=org.apache.jmeter.assertions.gui.XPathAssertionGui +XPathExtractor=org.apache.jmeter.extractor.XPathExtractor +XPathExtractorGui=org.apache.jmeter.extractor.gui.XPathExtractorGui +# +# Properties - all start with lower case letter and end with Prop +# +boolProp=org.apache.jmeter.testelement.property.BooleanProperty +collectionProp=org.apache.jmeter.testelement.property.CollectionProperty +doubleProp=org.apache.jmeter.testelement.property.DoubleProperty +elementProp=org.apache.jmeter.testelement.property.TestElementProperty +# see above - already defined as FloatProperty +#floatProp=org.apache.jmeter.testelement.property.FloatProperty +intProp=org.apache.jmeter.testelement.property.IntegerProperty +longProp=org.apache.jmeter.testelement.property.LongProperty +mapProp=org.apache.jmeter.testelement.property.MapProperty +objProp=org.apache.jmeter.testelement.property.ObjectProperty +stringProp=org.apache.jmeter.testelement.property.StringProperty +# +# Other - must start with a lower case letter (and not end with Prop) +# (otherwise they could clash with the initial set of aliases) +# +hashTree=org.apache.jorphan.collections.ListedHashTree +jmeterTestPlan=org.apache.jmeter.save.ScriptWrapper +sample=org.apache.jmeter.samplers.SampleResult +httpSample=org.apache.jmeter.protocol.http.sampler.HTTPSampleResult +statSample=org.apache.jmeter.samplers.StatisticalSampleResult +testResults=org.apache.jmeter.save.TestResultWrapper +assertionResult=org.apache.jmeter.assertions.AssertionResult + +# removed in 3.2, class was deleted in r +monitorStats=org.apache.jmeter.visualizers.MonitorStats +sampleEvent=org.apache.jmeter.samplers.SampleEvent +# +# Converters to register. Must start line with '_' +# If the converter is a collection of subitems, set equal to "collection" +# If the converter needs to know the class mappings but is not a collection of +# subitems, set it equal to "mapping" +_org.apache.jmeter.protocol.http.sampler.HTTPSamplerBaseConverter=collection +_org.apache.jmeter.protocol.http.util.HTTPResultConverter=collection +_org.apache.jmeter.save.converters.BooleanPropertyConverter= +_org.apache.jmeter.save.converters.IntegerPropertyConverter= +_org.apache.jmeter.save.converters.LongPropertyConverter= +_org.apache.jmeter.save.converters.MultiPropertyConverter=collection +_org.apache.jmeter.save.converters.SampleEventConverter= +_org.apache.jmeter.save.converters.SampleResultConverter=collection +_org.apache.jmeter.save.converters.SampleSaveConfigurationConverter=collection +_org.apache.jmeter.save.converters.StringPropertyConverter= +_org.apache.jmeter.save.converters.HashTreeConverter=collection +_org.apache.jmeter.save.converters.TestElementConverter=collection +_org.apache.jmeter.save.converters.TestElementPropertyConverter=collection +_org.apache.jmeter.save.converters.TestResultWrapperConverter=collection +_org.apache.jmeter.save.ScriptWrapperConverter=mapping +# +# Remember to update the _version entry +# diff --git a/tools/jmeter/src/main/resources/bin/upgrade.properties b/tools/jmeter/src/main/resources/bin/upgrade.properties new file mode 100644 index 0000000000..97dc396504 --- /dev/null +++ b/tools/jmeter/src/main/resources/bin/upgrade.properties @@ -0,0 +1,123 @@ +# Class, property and value upgrade equivalences. + +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. + +# +# Format is as follows -- +# for renamed test element & GUI classes: +# old.class.Name=new.class.Name +# old.class.Name|guiClassName=new.class.Name +# (e.g. for ConfigTestElement) +# +# for renamed / deleted properties: +# class.Name/Old.propertyName=newPropertyName +# if newPropertyName is omitted, then property is deleted +# +# for renamed values: +# old.class.Name.old.propertyName/oldValue=newValue +# + +org.apache.jmeter.protocol.http.config.gui.UrlConfigGui=org.apache.jmeter.protocol.http.config.gui.HttpDefaultsGui +org.apache.jmeter.assertions.Assertion=org.apache.jmeter.assertions.ResponseAssertion +org.apache.jmeter.protocol.http.sampler.HTTPSamplerFull=org.apache.jmeter.protocol.http.sampler.HTTPSampler +org.apache.jmeter.control.gui.RecordController=org.apache.jmeter.protocol.http.control.gui.RecordController + +org.apache.jmeter.timers.gui.ConstantThroughputTimerGui=org.apache.jmeter.testbeans.gui.TestBeanGUI +org.apache.jmeter.timers.ConstantThroughputTimer/ConstantThroughputTimer.throughput=throughput + +org.apache.jmeter.protocol.jdbc.control.gui.JdbcTestSampleGui=org.apache.jmeter.testbeans.gui.TestBeanGUI +org.apache.jmeter.protocol.jdbc.sampler.JDBCSampler/JDBCSampler.query=query +#org.apache.jmeter.protocol.jdbc.sampler.JDBCSampler.JDBCSampler.dataSource/NULL= + +# Convert DBconfig +org.apache.jmeter.protocol.jdbc.config.gui.DbConfigGui=org.apache.jmeter.testbeans.gui.TestBeanGUI +org.apache.jmeter.config.ConfigTestElement|org.apache.jmeter.protocol.jdbc.config.gui.DbConfigGui=org.apache.jmeter.protocol.jdbc.config.DataSourceElement +org.apache.jmeter.protocol.jdbc.config.DataSourceElement/JDBCSampler.url=dbUrl +org.apache.jmeter.protocol.jdbc.config.DataSourceElement/JDBCSampler.driver=driver +org.apache.jmeter.protocol.jdbc.config.DataSourceElement/JDBCSampler.query=query +org.apache.jmeter.protocol.jdbc.config.DataSourceElement/ConfigTestElement.username=username +org.apache.jmeter.protocol.jdbc.config.DataSourceElement/ConfigTestElement.password=password + +# Convert PoolConfig +org.apache.jmeter.protocol.jdbc.config.gui.PoolConfigGui=org.apache.jmeter.testbeans.gui.TestBeanGUI +org.apache.jmeter.config.ConfigTestElement|org.apache.jmeter.protocol.jdbc.config.gui.PoolConfigGui=org.apache.jmeter.protocol.jdbc.config.DataSourceElement +org.apache.jmeter.protocol.jdbc.config.DataSourceElement/JDBCSampler.connections= +org.apache.jmeter.protocol.jdbc.config.DataSourceElement/JDBCSampler.connPoolClass= +org.apache.jmeter.protocol.jdbc.config.DataSourceElement/JDBCSampler.maxuse=poolMax + +# SQL Config +org.apache.jmeter.config.ConfigTestElement/JDBCSampler.query=query +org.apache.jmeter.protocol.http.control.Header/TestElement.name=Header.name + +# Upgrade AccessLogSampler +org.apache.jmeter.protocol.http.control.gui.AccessLogSamplerGui=org.apache.jmeter.testbeans.gui.TestBeanGUI +org.apache.jmeter.protocol.http.sampler.AccessLogSampler/AccessLogSampler.log_file=logFile +org.apache.jmeter.protocol.http.sampler.AccessLogSampler/HTTPSampler.port=portString +#Is the following used now? +#org.apache.jmeter.protocol.http.sampler.AccessLogSampler/AccessLogSampler.generator_class_name= +#Looks to be a new field +#filterClassName +org.apache.jmeter.protocol.http.sampler.AccessLogSampler/HTTPSampler.domain=domain +org.apache.jmeter.protocol.http.sampler.AccessLogSampler/AccessLogSampler.parser_class_name=parserClassName +org.apache.jmeter.protocol.http.sampler.AccessLogSampler/HTTPSampler.image_parser=imageParsing + +# Renamed class +org.apache.jmeter.protocol.jms.control.gui.JMSConfigGui=org.apache.jmeter.protocol.jms.control.gui.JMSSamplerGui + +# These classes have been deleted; there's no defined replacement +org.apache.jmeter.protocol.jdbc.config.gui.SqlConfigGui=org.apache.jmeter.config.gui.ObsoleteGui +org.apache.jmeter.protocol.jms.control.gui.JndiDefaultsGui=org.apache.jmeter.config.gui.ObsoleteGui +# Should probably map to something other than ObsoleteGui... +org.apache.jmeter.threads.ReflectionThreadGroup=org.apache.jmeter.config.gui.ObsoleteGui + +# Convert BSFSamplerGui +org.apache.jmeter.protocol.java.control.gui.BSFSamplerGui=org.apache.jmeter.testbeans.gui.TestBeanGUI +org.apache.jmeter.protocol.java.sampler.BSFSampler/BSFSampler.filename=filename +org.apache.jmeter.protocol.java.sampler.BSFSampler/BSFSampler.language=scriptLanguage +org.apache.jmeter.protocol.java.sampler.BSFSampler/BSFSampler.parameters=parameters +org.apache.jmeter.protocol.java.sampler.BSFSampler/BSFSampler.query=script + +# Obsolete Http user Parameters modifier test element +# Note: ConfigTestElement is the test element associated with ObsoleteGui +org.apache.jmeter.protocol.http.modifier.UserParameterModifier=org.apache.jmeter.config.ConfigTestElement +org.apache.jmeter.protocol.http.modifier.gui.UserParameterModifierGui=org.apache.jmeter.config.gui.ObsoleteGui + +# Obsolete Graph Full Results listener +org.apache.jmeter.visualizers.GraphAccumVisualizer=org.apache.jmeter.config.gui.ObsoleteGui +# removed in 3.0, class was deleted in r1722757 +org.apache.jmeter.protocol.http.sampler.WebServiceSampler=org.apache.jmeter.config.ConfigTestElement +# removed in 3.0, class was deleted in r1722757 +org.apache.jmeter.protocol.http.control.gui.WebServiceSamplerGui=org.apache.jmeter.config.gui.ObsoleteGui +# removed in 3.0, class was deleted in r1722757 +org.apache.jmeter.protocol.http.modifier.ParamModifier=org.apache.jmeter.config.ConfigTestElement +# removed in 3.0, class was deleted in r1722962 +org.apache.jmeter.protocol.http.modifier.ParamMask=org.apache.jmeter.config.ConfigTestElement +# removed in 3.0, class was deleted in r1722757 +org.apache.jmeter.protocol.http.modifier.gui.ParamModifierGui=org.apache.jmeter.config.gui.ObsoleteGui + +# removed in 3.1, class was deleted in r1774947 +org.apache.jmeter.visualizers.SplineVisualizer=org.apache.jmeter.config.gui.ObsoleteGui +# removed in 3.1 class was deleted in r1763837 +org.apache.jmeter.visualizers.DistributionGraphVisualizer=org.apache.jmeter.config.gui.ObsoleteGui + +# removed in 3.2 class was deleted in r1771608 +org.apache.jmeter.visualizers.MonitorStats=org.apache.jmeter.config.ConfigTestElement +org.apache.jmeter.visualizers.MonitorHealthVisualizer=org.apache.jmeter.config.gui.ObsoleteGui + +# removed in 3.2 class was deleted in r1783280 +org.apache.jmeter.protocol.http.sampler.HTTPSampler2=org.apache.jmeter.config.ConfigTestElement +org.apache.jmeter.protocol.http.sampler.SoapSampler=org.apache.jmeter.config.ConfigTestElement +org.apache.jmeter.protocol.http.control.gui.SoapSamplerGui=org.apache.jmeter.config.gui.ObsoleteGui \ No newline at end of file diff --git a/tools/jmeter/src/main/resources/jmeter.properties b/tools/jmeter/src/main/resources/jmeter.properties new file mode 100644 index 0000000000..e4463eb2f7 --- /dev/null +++ b/tools/jmeter/src/main/resources/jmeter.properties @@ -0,0 +1,1242 @@ +################################################################################ +# Apache JMeter Property file +################################################################################ + +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. + +################################################################################ +# +# THIS FILE SHOULD NOT BE MODIFIED +# +# This avoids having to re-apply the modifications when upgrading JMeter +# Instead only user.properties should be modified: +# 1/ copy the property you want to modify to user.properties from jmeter.properties +# 2/ Change its value there +# +################################################################################ + +# JMeter properties are described in the file +# http://jmeter.apache.org/usermanual/properties_reference.html +# A local copy can be found in +# printable_docs/usermanual/properties_reference.html + +#Preferred GUI language. Comment out to use the JVM default locale's language. +#language=en + + +# Additional locale(s) to add to the displayed list. +# The current default list is: en, fr, de, no, es, tr, ja, zh_CN, zh_TW, pl, pt_BR +# [see JMeterMenuBar#makeLanguageMenu()] +# The entries are a comma-separated list of language names +#locales.add=zu + + +#--------------------------------------------------------------------------- +# XML Parser +#--------------------------------------------------------------------------- + +# Path to a Properties file containing Namespace mapping in the form +# prefix=Namespace +# Example: +# ns=http://biz.aol.com/schema/2006-12-18 +#xpath.namespace.config= + +#--------------------------------------------------------------------------- +# SSL configuration +#--------------------------------------------------------------------------- + +## SSL System properties are now in system.properties + +# JMeter no longer converts javax.xxx property entries in this file into System properties. +# These must now be defined in the system.properties file or on the command-line. +# The system.properties file gives more flexibility. + +# By default, SSL session contexts are now created per-thread, rather than being shared. +# The original behaviour can be enabled by setting the JMeter property to true +#https.sessioncontext.shared=false + +# Be aware that https default protocol may vary depending on the version of JVM +# See https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https +# See https://bz.apache.org/bugzilla/show_bug.cgi?id=58236 +# Default HTTPS protocol level: +#https.default.protocol=TLS +# This may need to be changed here (or in user.properties) to: +#https.default.protocol=SSLv3 + +# List of protocols to enable. You may have to select only a subset if you find issues with target server. +# This is needed when server does not support Socket version negotiation, this can lead to: +# javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated +# java.net.SocketException: Connection reset +# see https://bz.apache.org/bugzilla/show_bug.cgi?id=54759 +#https.socket.protocols=SSLv2Hello SSLv3 TLSv1 + +# Control if we allow reuse of cached SSL context between iterations +# set the value to 'false' to reset the SSL context each iteration +#https.use.cached.ssl.context=true + +# Start and end index to be used with keystores with many entries +# The default is to use entry 0, i.e. the first +#https.keyStoreStartIndex=0 +#https.keyStoreEndIndex=0 + +#--------------------------------------------------------------------------- +# Look and Feel configuration +#--------------------------------------------------------------------------- + +#Classname of the Swing default UI +# +# The LAF classnames that are available are now displayed as ToolTip text +# when hovering over the Options/Look and Feel selection list. +# +# You can either use a full class name, as shown below, +# or one of the strings "System" or "CrossPlatform" which means +# JMeter will use the corresponding string returned by UIManager.getLookAndFeelClassName() + +# LAF can be overridden by os.name (lowercased, spaces replaced by '_') +# Sample os.name LAF: +#jmeter.laf.windows_xp=javax.swing.plaf.metal.MetalLookAndFeel + +# Failing that, the OS family = os.name, but only up to first space: +# Sample OS family LAF: +#jmeter.laf.windows=com.sun.java.swing.plaf.windows.WindowsLookAndFeel + +# Mac apparently looks better with the System LAF +jmeter.laf.mac=System + +# Failing that, the JMeter default laf can be defined: +#jmeter.laf=System + +# If none of the above jmeter.laf properties are defined, JMeter uses the CrossPlatform LAF. +# This is because the CrossPlatform LAF generally looks better than the System LAF. +# See https://bz.apache.org/bugzilla/show_bug.cgi?id=52026 for details +# N.B. the laf can be defined in user.properties. + +# LoggerPanel display +# default to false +#jmeter.loggerpanel.display=false + +# Enable LogViewer Panel to receive log event even if closed +# Enabled since 2.12 +# Note this has some impact on performances, but as GUI mode must +# not be used for Load Test it is acceptable +#jmeter.loggerpanel.enable_when_closed=true + +# Max lines kept in LoggerPanel, default to 1000 chars +# 0 means no limit +#jmeter.loggerpanel.maxlength=1000 + +# Interval period in ms to process the queue of events of the listeners +#jmeter.gui.refresh_period=500 + +# HiDPI mode (default: false) +# Activate a 'pseudo'-hidpi mode. Allows to increase size of some UI elements +# which are not correctly managed by JVM with high resolution screens in Linux or Windows +#jmeter.hidpi.mode=false +# To enable pseudo-hidpi mode change to true +#jmeter.hidpi.mode=true +# HiDPI scale factor +#jmeter.hidpi.scale.factor=1.0 +# Suggested value for HiDPI +#jmeter.hidpi.scale.factor=2.0 + +# Toolbar display +# Toolbar icon definitions +#jmeter.toolbar.icons=org/apache/jmeter/images/toolbar/icons-toolbar.properties +# Toolbar list +#jmeter.toolbar=new,open,close,save,save_as_testplan,|,cut,copy,paste,|,expand,collapse,toggle,|,test_start,test_stop,test_shutdown,|,test_start_remote_all,test_stop_remote_all,test_shutdown_remote_all,|,test_clear,test_clear_all,|,search,search_reset,|,function_helper,help +# Toolbar icons default size: 22x22. Available sizes are: 22x22, 32x32, 48x48 +#jmeter.toolbar.icons.size=22x22 +# Suggested value for HiDPI +#jmeter.toolbar.icons.size=48x48 + +# Icon definitions +# default: +#jmeter.icons=org/apache/jmeter/images/icon.properties +# alternate: +#jmeter.icons=org/apache/jmeter/images/icon_1.properties +# Historical icon set (deprecated) +#jmeter.icons=org/apache/jmeter/images/icon_old.properties + +# Tree icons default size: 19x19. Available sizes are: 19x19, 24x24, 32x32, 48x48 +# Useful for HiDPI display (see below) +#jmeter.tree.icons.size=19x19 +# Suggested value for HiDPI screen like 3200x1800: +#jmeter.tree.icons.size=32x32 + +#Components to not display in JMeter GUI (GUI class name or static label) +# These elements are deprecated and will be removed in next version: +# MongoDB Script, MongoDB Source Config, Monitor Results +# BSF Elements +not_in_menu=org.apache.jmeter.protocol.mongodb.sampler.MongoScriptSampler,org.apache.jmeter.protocol.mongodb.config.MongoSourceElement,\ + org.apache.jmeter.timers.BSFTimer,org.apache.jmeter.modifiers.BSFPreProcessor,org.apache.jmeter.extractor.BSFPostProcessor,org.apache.jmeter.assertions.BSFAssertion,\ + org.apache.jmeter.visualizers.BSFListener,org.apache.jmeter.protocol.java.sampler.BSFSampler,\ + org.apache.jmeter.protocol.http.control.gui.SoapSamplerGui + +# Number of items in undo history +# Feature is disabled by default (0) due to known and not fixed bugs: +# https://bz.apache.org/bugzilla/show_bug.cgi?id=57043 +# https://bz.apache.org/bugzilla/show_bug.cgi?id=57039 +# https://bz.apache.org/bugzilla/show_bug.cgi?id=57040 +# Set it to a number > 0 (25 can be a good default) +# The bigger it is, the more it consumes memory +#undo.history.size=0 + +# Hotkeys to add JMeter components, will add elements when you press Ctrl+0 .. Ctrl+9 (Command+0 .. Command+9 on Mac) +gui.quick_0=ThreadGroupGui +gui.quick_1=HttpTestSampleGui +gui.quick_2=RegexExtractorGui +gui.quick_3=AssertionGui +gui.quick_4=ConstantTimerGui +gui.quick_5=TestActionGui +gui.quick_6=JSR223PostProcessor +gui.quick_7=JSR223PreProcessor +gui.quick_8=DebugSampler +gui.quick_9=ViewResultsFullVisualizer + + +#--------------------------------------------------------------------------- +# JMX Backup configuration +#--------------------------------------------------------------------------- +#Enable auto backups of the .jmx file when a test plan is saved. +#When enabled, before the .jmx is saved, it will be backed up to the directory pointed +#by the jmeter.gui.action.save.backup_directory property (see below). Backup file names are built +#after the jmx file being saved. For example, saving test-plan.jmx will create a test-plan-000012.jmx +#in the backup directory provided that the last created backup file is test-plan-000011.jmx. +#Default value is true indicating that auto backups are enabled +#jmeter.gui.action.save.backup_on_save=true + +#Set the backup directory path where JMX backups will be created upon save in the GUI. +#If not set (what it defaults to) then backup files will be created in +#a sub-directory of the JMeter base installation. The default directory is ${JMETER_HOME}/backups +#If set and the directory does not exist, it will be created. +#jmeter.gui.action.save.backup_directory= + +#Set the maximum time (in hours) that backup files should be preserved since the save time. +#By default no expiration time is set which means we keep backups for ever. +#jmeter.gui.action.save.keep_backup_max_hours=0 + +#Set the maximum number of backup files that should be preserved. By default 10 backups will be preserved. +#Setting this to zero will cause the backups to not being deleted (unless keep_backup_max_hours is set to a non zero value) +#jmeter.gui.action.save.keep_backup_max_count=10 + + +#--------------------------------------------------------------------------- +# Remote hosts and RMI configuration +#--------------------------------------------------------------------------- + +# Remote Hosts - comma delimited +remote_hosts=127.0.0.1:20100,127.0.0.1:20101,127.0.0.1:20102,127.0.0.1:20103,127.0.0.1:20104 +#remote_hosts=localhost:1099,localhost:2010 + +# RMI port to be used by the server (must start rmiregistry with same port) +#server_port=1099 + +# To change the port to (say) 1234: +# On the server(s) +# - set server_port=1234 +# - start rmiregistry with port 1234 +# On Windows this can be done by: +# SET SERVER_PORT=1234 +# JMETER-SERVER +# +# On Unix: +# SERVER_PORT=1234 jmeter-server +# +# On the client: +# - set remote_hosts=server:1234 + +# Parameter that controls the RMI port used by the RemoteSampleListenerImpl (The Controler) +# Default value is 0 which means port is randomly assigned +# You may need to open Firewall port on the Controller machine +client.rmi.localport=4001 + +# When distributed test is starting, there may be several attempts to initialize +# remote engines. By default, only single try is made. Increase following property +# to make it retry for additional times +#client.tries=1 + +# If there is initialization retries, following property sets delay between attempts +#client.retries_delay=5000 + +# When all initialization tries was made, test will fail if some remote engines are failed +# Set following property to true to ignore failed nodes and proceed with test +#client.continue_on_fail=false + +# To change the default port (1099) used to access the server: +#server.rmi.port=1234 + +# To use a specific port for the JMeter server engine, define +# the following property before starting the server: +server.rmi.localport=5000 + +# From JMeter 2.3.1, the jmeter server creates the RMI registry as part of the server process. +# To stop the server creating the RMI registry: +#server.rmi.create=false + +# From JMeter 2.3.1, define the following property to cause JMeter to exit after the first test +#server.exitaftertest=true + +#--------------------------------------------------------------------------- +# Include Controller +#--------------------------------------------------------------------------- + +# Prefix used by IncludeController when building file name +#includecontroller.prefix= + +#--------------------------------------------------------------------------- +# HTTP Java configuration +#--------------------------------------------------------------------------- + +# Number of connection retries performed by HTTP Java sampler before giving up +# 0 means no retry since version 3.0 +#http.java.sampler.retries=0 + +#--------------------------------------------------------------------------- +# Following properties apply to Apache HttpClient +#--------------------------------------------------------------------------- + +# set the socket timeout (or use the parameter http.socket.timeout) +# for AJP Sampler implementation. +# Value is in milliseconds +#httpclient.timeout=0 +# 0 == no timeout + +# Set the http version (defaults to 1.1) +#httpclient.version=1.1 (or use the parameter http.protocol.version) + +# Define characters per second > 0 to emulate slow connections +#httpclient.socket.http.cps=0 +#httpclient.socket.https.cps=0 + +#Enable loopback protocol +#httpclient.loopback=true + +# Define the local host address to be used for multi-homed hosts +#httpclient.localaddress=1.2.3.4 + +#--------------------------------------------------------------------------- +# AuthManager Kerberos configuration +#--------------------------------------------------------------------------- + +# AuthManager Kerberos configuration +# Name of application module used in jaas.conf +#kerberos_jaas_application=JMeter + +# Should ports be stripped from urls before constructing SPNs +# for SPNEGO authentication +#kerberos.spnego.strip_port=true + +#--------------------------------------------------------------------------- +# Apache HttpComponents HTTPClient configuration (HTTPClient4) +#--------------------------------------------------------------------------- + +# define a properties file for overriding Apache HttpClient parameters +# Uncomment this line if you put anything in hc.parameters file +#hc.parameters.file=hc.parameters + +# Preemptively send Authorization Header when BASIC auth is used +#httpclient4.auth.preemptive=true + +# Number of retries to attempt (default 0) +#httpclient4.retrycount=0 + +# true if it's OK to retry requests that have been sent +# This will retry Idempotent and non Idempotent requests +# This should usually be false, but it can be useful +# when testing against some Load Balancers like Amazon ELB +#httpclient4.request_sent_retry_enabled=false + +# Idle connection timeout (Milliseconds) to apply if the server does not send +# Keep-Alive headers (default 0) +# Set this > 0 to compensate for servers that don't send a Keep-Alive header +# If <= 0, idle timeout will only apply if the server sends a Keep-Alive header +#httpclient4.idletimeout=0 + +# Check connections if the elapsed time (Milliseconds) since the last +# use of the connection exceed this value +#httpclient4.validate_after_inactivity=1700 + +# TTL (in Milliseconds) represents an absolute value. +# No matter what, the connection will not be re-used beyond its TTL. +#httpclient4.time_to_live=2000 + +# Max size in bytes of PUT body to retain in result sampler. Bigger results will be clipped. +#httpclient4.max_body_retain_size=32768 + +#--------------------------------------------------------------------------- +# HTTP Cache Manager configuration +#--------------------------------------------------------------------------- +# +# Space or comma separated list of methods that can be cached +#cacheable_methods=GET +# N.B. This property is currently a temporary solution for Bug 56162 + +# Since 2.12, JMeter does not create anymore a Sample Result with 204 response +# code for a resource found in cache which is inline with what browser do. +#cache_manager.cached_resource_mode=RETURN_NO_SAMPLE + +# You can choose between 3 modes: +# RETURN_NO_SAMPLE (default) +# RETURN_200_CACHE +# RETURN_CUSTOM_STATUS + +# Those mode have the following behaviours: +# RETURN_NO_SAMPLE : this mode returns no Sample Result, it has no additional configuration +# RETURN_200_CACHE : this mode will return Sample Result with response code to 200 and response message to "(ex cache)", you can modify response message by setting +# RETURN_200_CACHE.message=(ex cache) +# RETURN_CUSTOM_STATUS : This mode lets you select what response code and message you want to return, if you use this mode you need to set those properties +# RETURN_CUSTOM_STATUS.code= +# RETURN_CUSTOM_STATUS.message= + +#--------------------------------------------------------------------------- +# Results file configuration +#--------------------------------------------------------------------------- + +# This section helps determine how result data will be saved. +# The commented out values are the defaults. + +# legitimate values: xml, csv, db. Only xml and csv are currently supported. +#jmeter.save.saveservice.output_format=csv + + +# true when field should be saved; false otherwise + +# assertion_results_failure_message only affects CSV output +#jmeter.save.saveservice.assertion_results_failure_message=true +# +# legitimate values: none, first, all +#jmeter.save.saveservice.assertion_results=none +# +#jmeter.save.saveservice.data_type=true +#jmeter.save.saveservice.label=true +#jmeter.save.saveservice.response_code=true +# response_data is not currently supported for CSV output +#jmeter.save.saveservice.response_data=false +# Save ResponseData for failed samples +#jmeter.save.saveservice.response_data.on_error=false +#jmeter.save.saveservice.response_message=true +#jmeter.save.saveservice.successful=true +#jmeter.save.saveservice.thread_name=true +#jmeter.save.saveservice.time=true +#jmeter.save.saveservice.subresults=true +#jmeter.save.saveservice.assertions=true +#jmeter.save.saveservice.latency=true +# Only available with HttpClient4 +#jmeter.save.saveservice.connect_time=true +#jmeter.save.saveservice.samplerData=false +#jmeter.save.saveservice.responseHeaders=false +#jmeter.save.saveservice.requestHeaders=false +#jmeter.save.saveservice.encoding=false +#jmeter.save.saveservice.bytes=true +# Only available with HttpClient4 +#jmeter.save.saveservice.sent_bytes=true +#jmeter.save.saveservice.url=false +#jmeter.save.saveservice.filename=false +#jmeter.save.saveservice.hostname=false +#jmeter.save.saveservice.thread_counts=true +#jmeter.save.saveservice.sample_count=false +#jmeter.save.saveservice.idle_time=true + +# Timestamp format - this only affects CSV output files +# legitimate values: none, ms, or a format suitable for SimpleDateFormat +#jmeter.save.saveservice.timestamp_format=ms +#jmeter.save.saveservice.timestamp_format=yyyy/MM/dd HH:mm:ss.SSS + +# For use with Comma-separated value (CSV) files or other formats +# where the fields' values are separated by specified delimiters. +# Default: +#jmeter.save.saveservice.default_delimiter=, +# For TAB, since JMeter 2.3 one can use: +#jmeter.save.saveservice.default_delimiter=\t + +# Only applies to CSV format files: +# Print field names as first line in CSV +#jmeter.save.saveservice.print_field_names=true + +# Optional list of JMeter variable names whose values are to be saved in the result data files. +# Use commas to separate the names. For example: +#sample_variables=SESSION_ID,REFERENCE +# N.B. The current implementation saves the values in XML as attributes, +# so the names must be valid XML names. +# Versions of JMeter after 2.3.2 send the variable to all servers +# to ensure that the correct data is available at the client. + +# Optional xml processing instruction for line 2 of the file: +# Example: +#jmeter.save.saveservice.xml_pi= +# Default value: +#jmeter.save.saveservice.xml_pi= + +# Prefix used to identify filenames that are relative to the current base +#jmeter.save.saveservice.base_prefix=~/ + +# AutoFlush on each line written in XML or CSV output +# Setting this to true will result in less test results data loss in case of Crash +# but with impact on performances, particularly for intensive tests (low or no pauses) +# Since JMeter 2.10, this is false by default +#jmeter.save.saveservice.autoflush=false + +#--------------------------------------------------------------------------- +# Settings that affect SampleResults +#--------------------------------------------------------------------------- + +# Save the start time stamp instead of the end +# This also affects the timestamp stored in result files +sampleresult.timestamp.start=true + +# Whether to use System.nanoTime() - otherwise only use System.currentTimeMillis() +#sampleresult.useNanoTime=true + +# Use a background thread to calculate the nanoTime offset +# Set this to <= 0 to disable the background thread +#sampleresult.nanoThreadSleep=5000 + +#--------------------------------------------------------------------------- +# Upgrade property +#--------------------------------------------------------------------------- + +# File that holds a record of name changes for backward compatibility issues +upgrade_properties=/bin/upgrade.properties + +#--------------------------------------------------------------------------- +# JMeter Test Script recorder configuration +# +# N.B. The element was originally called the Proxy recorder, which is why the +# properties have the prefix "proxy". +#--------------------------------------------------------------------------- + +# If the recorder detects a gap of at least 5s (default) between HTTP requests, +# it assumes that the user has clicked a new URL +#proxy.pause=5000 + +# Add numeric prefix to Sampler names (default true) +#proxy.number.requests=true + +# List of URL patterns that will be added to URL Patterns to exclude +# Separate multiple lines with ; +#proxy.excludes.suggested=.*\\.(bmp|css|js|gif|ico|jpe?g|png|swf|woff|woff2) + +# Change the default HTTP Sampler (currently HttpClient4) +# Java: +#jmeter.httpsampler=HTTPSampler +#or +#jmeter.httpsampler=Java +# +# HttpClient4.x +#jmeter.httpsampler=HttpClient4 + +# By default JMeter tries to be more lenient with RFC2616 redirects and allows +# relative paths. +# If you want to test strict conformance, set this value to true +# When the property is true, JMeter follows http://tools.ietf.org/html/rfc3986#section-5.2 +#jmeter.httpclient.strict_rfc2616=false + +# Default content-type include filter to use +#proxy.content_type_include=text/html|text/plain|text/xml +# Default content-type exclude filter to use +#proxy.content_type_exclude=image/.*|text/css|application/.* + +# Default headers to remove from Header Manager elements +# (Cookie and Authorization are always removed) +#proxy.headers.remove=If-Modified-Since,If-None-Match,Host + +# Binary content-type handling +# These content-types will be handled by saving the request in a file: +#proxy.binary.types=application/x-amf,application/x-java-serialized-object +# The files will be saved in this directory: +#proxy.binary.directory=user.dir +# The files will be created with this file filesuffix: +#proxy.binary.filesuffix=.binary + +#--------------------------------------------------------------------------- +# Test Script Recorder certificate configuration +#--------------------------------------------------------------------------- + +#proxy.cert.directory= +#proxy.cert.file=proxyserver.jks +#proxy.cert.type=JKS +#proxy.cert.keystorepass=password +#proxy.cert.keypassword=password +#proxy.cert.factory=SunX509 +# define this property if you wish to use your own keystore +#proxy.cert.alias= +# The default validity for certificates created by JMeter +#proxy.cert.validity=7 +# Use dynamic key generation (if supported by JMeter/JVM) +# If false, will revert to using a single key with no certificate +#proxy.cert.dynamic_keys=true + +#--------------------------------------------------------------------------- +# Test Script Recorder miscellaneous configuration +#--------------------------------------------------------------------------- + +# Whether to attempt disabling of samples that resulted from redirects +# where the generated samples use auto-redirection +#proxy.redirect.disabling=true + +# SSL configuration +#proxy.ssl.protocol=TLS + +#--------------------------------------------------------------------------- +# JMeter Proxy configuration +#--------------------------------------------------------------------------- +# use command-line flags for user-name and password +#http.proxyDomain=NTLM domain, if required by HTTPClient sampler + +#--------------------------------------------------------------------------- +# HTTPSampleResponse Parser configuration +#--------------------------------------------------------------------------- + +# Space-separated list of parser groups +HTTPResponse.parsers=htmlParser wmlParser cssParser +# for each parser, there should be a parser.types and a parser.className property + +# CSS Parser based on ph-css +cssParser.className=org.apache.jmeter.protocol.http.parser.CssParser +cssParser.types=text/css + +# CSS parser LRU cache size +# This cache stores the URLs found in a CSS to avoid continuously parsing the CSS +# By default the cache size is 400 +# It can be disabled by setting its value to 0 +#css.parser.cache.size=400 + +# Let the CSS Parser ingore all css errors +#css.parser.ignore_all_css_errors=true + +#--------------------------------------------------------------------------- +# HTML Parser configuration +#--------------------------------------------------------------------------- + +# Define the HTML parser to be used. +# Default parser: +# This new parser (since 2.10) should perform better than all others +# see https://bz.apache.org/bugzilla/show_bug.cgi?id=55632 +# Do not comment this property +htmlParser.className=org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser + +# Other parsers: +# Default parser before 2.10 +#htmlParser.className=org.apache.jmeter.protocol.http.parser.JTidyHTMLParser +# Note that Regexp extractor may detect references that have been commented out. +# In many cases it will work OK, but you should be aware that it may generate +# additional references. +#htmlParser.className=org.apache.jmeter.protocol.http.parser.RegexpHTMLParser +# This parser is based on JSoup, it should be the most accurate but less performant +# than LagartoBasedHtmlParser +#htmlParser.className=org.apache.jmeter.protocol.http.parser.JsoupBasedHtmlParser + +#Used by HTTPSamplerBase to associate htmlParser with content types below +htmlParser.types=text/html application/xhtml+xml application/xml text/xml + +#--------------------------------------------------------------------------- +# WML Parser configuration +#--------------------------------------------------------------------------- + +wmlParser.className=org.apache.jmeter.protocol.http.parser.RegexpHTMLParser + +#Used by HTTPSamplerBase to associate wmlParser with content types below +wmlParser.types=text/vnd.wap.wml + +#--------------------------------------------------------------------------- +# Remote batching configuration +#--------------------------------------------------------------------------- +# How is Sample sender implementations configured: +# - true (default) means client configuration will be used +# - false means server configuration will be used +#sample_sender_client_configured=true + +# By default when Stripping modes are used JMeter since 3.1 will strip +# response even for SampleResults in error. +# If you want to revert to previous behaviour (no stripping of Responses in error) +# set this property to false +#sample_sender_strip_also_on_error=true + +# Remote batching support +# Since JMeter 2.9, default is MODE_STRIPPED_BATCH, which returns samples in +# batch mode (every 100 samples or every minute by default) +# Note also that MODE_STRIPPED_BATCH strips response data from SampleResult, so if you need it change to +# another mode +# Hold retains samples until end of test (may need lots of memory) +# Batch returns samples in batches +# Statistical returns sample summary statistics +# hold_samples was originally defined as a separate property, +# but can now also be defined using mode=Hold +# mode can also be the class name of an implementation of org.apache.jmeter.samplers.SampleSender +#mode=Standard +#mode=Batch +#mode=Hold +#mode=Statistical +#Set to true to key statistical samples on threadName rather than threadGroup +#key_on_threadname=false +#mode=Stripped +#mode=StrippedBatch +#mode=org.example.load.MySampleSender +# +#num_sample_threshold=100 +# Value is in milliseconds +#time_threshold=60000 +# +# Asynchronous sender; uses a queue and background worker process to return the samples +#mode=Asynch +# default queue size +#asynch.batch.queue.size=100 +# Same as Asynch but strips response data from SampleResult +mode=StrippedAsynch +# +# DiskStore: as for Hold mode, but serialises the samples to disk, rather than saving in memory +#mode=DiskStore +# Same as DiskStore but strips response data from SampleResult +#mode=StrippedDiskStore +# Note: the mode is currently resolved on the client; +# other properties (e.g. time_threshold) are resolved on the server. + +#--------------------------------------------------------------------------- +# JDBC Request configuration +#--------------------------------------------------------------------------- + +# String used to indicate a null value +#jdbcsampler.nullmarker=]NULL[ +# +# Max size of BLOBs and CLOBs to store in JDBC sampler. Result will be cut off +#jdbcsampler.max_retain_result_size=65536 + +# Database validation query +# based in https://stackoverflow.com/questions/10684244/dbcp-validationquery-for-different-databases list +jdbc.config.check.query=select 1 from INFORMATION_SCHEMA.SYSTEM_USERS|select 1 from dual|select 1 from sysibm.sysdummy1|select 1|select 1 from rdb$database +jdbc.config.jdbc.driver.class=com.mysql.jdbc.Driver|org.postgresql.Driver|oracle.jdbc.OracleDriver|com.ingres.jdbc.IngresDriver|com.microsoft.sqlserver.jdbc.SQLServerDriver|com.microsoft.jdbc.sqlserver.SQLServerDriver|org.apache.derby.jdbc.ClientDriver|org.hsqldb.jdbc.JDBCDriver|com.ibm.db2.jcc.DB2Driver|org.apache.derby.jdbc.ClientDriver|org.h2.Driver|org.firebirdsql.jdbc.FBDrivery|org.mariadb.jdbc.Driver|org.sqlite.JDBC|net.sourceforge.jtds.jdbc.Driver + +#--------------------------------------------------------------------------- +# OS Process Sampler configuration +#--------------------------------------------------------------------------- +# Polling to see if process has finished its work, used when a timeout is configured on sampler +#os_sampler.poll_for_timeout=100 + +#--------------------------------------------------------------------------- +# TCP Sampler configuration +#--------------------------------------------------------------------------- + +# The default handler class +#tcp.handler=TCPClientImpl +# +# eolByte = byte value for end of line +# set this to a value outside the range -128 to +127 to skip eol checking +#tcp.eolByte=1000 +# +# TCP Charset, used by org.apache.jmeter.protocol.tcp.sampler.TCPClientImpl +# default to Platform defaults charset as returned by Charset.defaultCharset().name() +#tcp.charset= +# +# status.prefix and suffix = strings that enclose the status response code +#tcp.status.prefix=Status= +#tcp.status.suffix=. +# +# status.properties = property file to convert codes to messages +#tcp.status.properties=mytestfiles/tcpstatus.properties + +# The length prefix used by LengthPrefixedBinaryTCPClientImpl implementation +# defaults to 2 bytes. +#tcp.binarylength.prefix.length=2 + +#--------------------------------------------------------------------------- +# Summariser - Generate Summary Results - configuration (mainly applies to non-GUI mode) +#--------------------------------------------------------------------------- +# +# Comment the following property to disable the default non-GUI summariser +# [or change the value to rename it] +# (applies to non-GUI mode only) +summariser.name=summary +# +# interval between summaries (in seconds) default 30 seconds +#summariser.interval=30 +# +# Write messages to log file +#summariser.log=true +# +# Write messages to System.out +#summariser.out=true + +# Ignore SampleResults generated by TransactionControllers +# defaults to true +#summariser.ignore_transaction_controller_sample_result=true + + +#--------------------------------------------------------------------------- +# Aggregate Report and Aggregate Graph - configuration +#--------------------------------------------------------------------------- +# +# Percentiles to display in reports +# Can be float value between 0 and 100 +# First percentile to display, defaults to 90% +#aggregate_rpt_pct1=90 +# Second percentile to display, defaults to 95% +#aggregate_rpt_pct2=95 +# Second percentile to display, defaults to 99% +#aggregate_rpt_pct3=99 + +#--------------------------------------------------------------------------- +# BackendListener - configuration +#--------------------------------------------------------------------------- +# +# Backend metrics window mode (fixed=fixed-size window, timed=time boxed) +#backend_metrics_window_mode=fixed +# Backend metrics sliding window size for Percentiles, Min, Max +#backend_metrics_window=100 + +# Backend metrics sliding window size for Percentiles, Min, Max +# when backend_metrics_window_mode is timed +# Setting this value too high can lead to OOM +#backend_metrics_large_window=5000 + +######################## +# Graphite Backend +######################## +# Send interval in second +# Defaults to 1 second +#backend_graphite.send_interval=1 + +######################## +# Influx Backend +######################## + +# Send interval in second +# Defaults to 5 seconds +#backend_influxdb.send_interval=5 +#Influxdb timeouts +#backend_influxdb.connection_timeout=1000 +#backend_influxdb.socket_timeout=3000 +#backend_influxdb.connection_request_timeout=100 + +#--------------------------------------------------------------------------- +# BeanShell configuration +#--------------------------------------------------------------------------- + +# BeanShell Server properties +# +# Define the port number as non-zero to start the http server on that port +#beanshell.server.port=9000 +# The telnet server will be started on the next port + +# +# Define the server initialisation file +beanshell.server.file=../extras/startup.bsh + +# +# Define a file to be processed at startup +# This is processed using its own interpreter. +#beanshell.init.file= + +# +# Define the intialisation files for BeanShell Sampler, Function and other BeanShell elements +# N.B. Beanshell test elements do not share interpreters. +# Each element in each thread has its own interpreter. +# This is retained between samples. +#beanshell.sampler.init=BeanShellSampler.bshrc +#beanshell.function.init=BeanShellFunction.bshrc +#beanshell.assertion.init=BeanShellAssertion.bshrc +#beanshell.listener.init=etc +#beanshell.postprocessor.init=etc +#beanshell.preprocessor.init=etc +#beanshell.timer.init=etc + +# The file BeanShellListeners.bshrc contains sample definitions +# of Test and Thread Listeners. + +#--------------------------------------------------------------------------- +# Groovy function +#--------------------------------------------------------------------------- + +#Path to Groovy file containing utility functions to make available to __groovy function +#groovy.utilities= + +# Example +#groovy.utilities=bin/utility.groovy + +#--------------------------------------------------------------------------- +# MailerModel configuration +#--------------------------------------------------------------------------- + +# Number of successful samples before a message is sent +#mailer.successlimit=2 +# +# Number of failed samples before a message is sent +#mailer.failurelimit=2 + +#--------------------------------------------------------------------------- +# CSVRead configuration +#--------------------------------------------------------------------------- + +# CSVRead delimiter setting (default ",") +# Make sure that there are no trailing spaces or tabs after the delimiter +# characters, or these will be included in the list of valid delimiters +#csvread.delimiter=, +#csvread.delimiter=; +#csvread.delimiter=! +#csvread.delimiter=~ +# The following line has a tab after the = +#csvread.delimiter= + +#--------------------------------------------------------------------------- +# __time() function configuration +# +# The properties below can be used to redefine the default formats +#--------------------------------------------------------------------------- +#time.YMD=yyyyMMdd +#time.HMS=HHmmss +#time.YMDHMS=yyyyMMdd-HHmmss +#time.USER1= +#time.USER2= + +#--------------------------------------------------------------------------- +# CSV DataSet configuration +#--------------------------------------------------------------------------- + +# String to return at EOF (if recycle not used) +#csvdataset.eofstring= +#list in https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html +csvdataset.file.encoding_list=UTF-8|UTF-16|ISO-8859-15|US-ASCII + + +#--------------------------------------------------------------------------- +# LDAP Sampler configuration +#--------------------------------------------------------------------------- +# Maximum number of search results returned by a search that will be sorted +# to guarantee a stable ordering (if more results then this limit are returned +# then no sorting is done). Set to 0 to turn off all sorting, in which case +# "Equals" response assertions will be very likely to fail against search results. +# +#ldapsampler.max_sorted_results=1000 + +# Number of characters to log for each of three sections (starting matching section, diff section, +# ending matching section where not all sections will appear for all diffs) diff display when an Equals +# assertion fails. So a value of 100 means a maximum of 300 characters of diff text will be displayed +# (+ a number of extra characters like "..." and "[[["/"]]]" which are used to decorate it). +#assertion.equals_section_diff_len=100 +# test written out to log to signify start/end of diff delta +#assertion.equals_diff_delta_start=[[[ +#assertion.equals_diff_delta_end=]]] + +#--------------------------------------------------------------------------- +# Miscellaneous configuration +#--------------------------------------------------------------------------- +# Used to control what happens when you start a test and +# have listeners that could overwrite existing result files +# Possible values: +# ASK : Ask user +# APPEND : Append results to existing file +# DELETE : Delete existing file and start a new file +#resultcollector.action_if_file_exists=ASK + +# If defined, then start the mirror server on the port +#mirror.server.port=8081 + +# ORO PatternCacheLRU size +#oro.patterncache.size=1000 + +#TestBeanGui +# +#propertyEditorSearchPath=null + +# Turn expert mode on/off: expert mode will show expert-mode beans and properties +#jmeter.expertMode=true + +# Max size of bytes stored in memory per SampleResult +# Ensure you don't exceed max capacity of a Java Array and remember +# that the higher it is, the higher JMeter will consume heap +# Defaults to 0, which means no truncation +#httpsampler.max_bytes_to_store_per_request=0 + +# Max size of buffer in bytes used when reading responses +# Defaults to 64k +#httpsampler.max_buffer_size=66560 + +# Maximum redirects to follow in a single sequence (default 20) +#httpsampler.max_redirects=20 +# Maximum frame/iframe nesting depth (default 5) +#httpsampler.max_frame_depth=5 + +# Revert to BUG 51939 behaviour (no separate container for embedded resources) by setting the following false: +#httpsampler.separate.container=true + +# If embedded resources download fails due to missing resources or other reasons, if this property is true +# Parent sample will not be marked as failed +#httpsampler.ignore_failed_embedded_resources=false + +#keep alive time for the parallel download threads (in seconds) +#httpsampler.parallel_download_thread_keepalive_inseconds=60 + +# Don't keep the embedded resources response data : just keep the size and the md5 +# default to false +#httpsampler.embedded_resources_use_md5=false + +# List of extra HTTP methods that should be available in select box +#httpsampler.user_defined_methods=VERSION-CONTROL,REPORT,CHECKOUT,CHECKIN,UNCHECKOUT,MKWORKSPACE,UPDATE,LABEL,MERGE,BASELINE-CONTROL,MKACTIVITY + +# The encoding to be used if none is provided (default ISO-8859-1) +#sampleresult.default.encoding=ISO-8859-1 + +# Network response size calculation method +# Use real size: number of bytes for response body return by webserver +# (i.e. the network bytes received for response) +# if set to false, the (uncompressed) response data size will used (default before 2.5) +# Include headers: add the headers size in real size +#sampleresult.getbytes.body_real_size=true +#sampleresult.getbytes.headers_size=true + +# CookieManager behaviour - should cookies with null/empty values be deleted? +# Default is true. Use false to revert to original behaviour +#CookieManager.delete_null_cookies=true + +# CookieManager behaviour - should variable cookies be allowed? +# Default is true. Use false to revert to original behaviour +#CookieManager.allow_variable_cookies=true + +# CookieManager behaviour - should Cookies be stored as variables? +# Default is false +#CookieManager.save.cookies=false + +# CookieManager behaviour - prefix to add to cookie name before storing it as a variable +# Default is COOKIE_; to remove the prefix, define it as one or more spaces +#CookieManager.name.prefix= + +# CookieManager behaviour - check received cookies are valid before storing them? +# Default is true. Use false to revert to previous behaviour +#CookieManager.check.cookies=true + +# Netscape HTTP Cookie file +cookies=cookies + +# Ability to switch to Nashorn as default Javascript Engine used by IfController and __javaScript function +# JMeter works as following: +# - JDK >= 8 and javascript.use_rhino=false or not set : Nashorn +# - JDK >= 8 and javascript.use_rhino=true: Rhino +# If you want to use Rhino on JDK8, set this property to true +#javascript.use_rhino=false + +# Number of milliseconds to wait for a thread to stop +#jmeterengine.threadstop.wait=5000 + +#Whether to invoke System.exit(0) in server exit code after stopping RMI +#jmeterengine.remote.system.exit=false + +# Whether to call System.exit(1) on failure to stop threads in non-GUI mode. +# This only takes effect if the test was explicitly requested to stop. +# If this is disabled, it may be necessary to kill the JVM externally +#jmeterengine.stopfail.system.exit=true + +# Whether to force call System.exit(0) at end of test in non-GUI mode, even if +# there were no failures and the test was not explicitly asked to stop. +# Without this, the JVM may never exit if there are other threads spawned by +# the test which never exit. +#jmeterengine.force.system.exit=false + +# How long to pause (in ms) in the daemon thread before reporting that the JVM has failed to exit. +# If the value is <= 0, the JMeter does not start the daemon thread +#jmeter.exit.check.pause=2000 + +# If running non-GUI, then JMeter listens on the following port for a shutdown message. +# To disable, set the port to 1000 or less. +#jmeterengine.nongui.port=4445 +# +# If the initial port is busy, keep trying until this port is reached +# (to disable searching, set the value less than or equal to the .port property) +#jmeterengine.nongui.maxport=4455 + +# How often to check for shutdown during ramp-up (milliseconds) +#jmeterthread.rampup.granularity=1000 + +#Should JMeter expand the tree when loading a test plan? +# default value is false since JMeter 2.7 +#onload.expandtree=false + +#JSyntaxTextArea configuration +#jsyntaxtextarea.wrapstyleword=true +#jsyntaxtextarea.linewrap=true +#jsyntaxtextarea.codefolding=true +# Set 0 to disable undo feature in JSyntaxTextArea +#jsyntaxtextarea.maxundos=50 +# Change the font on the (JSyntax) Text Areas. (Useful for HiDPI screens) +#jsyntaxtextarea.font.family=Hack +#jsyntaxtextarea.font.size=14 + +# Set this to false to disable the use of JSyntaxTextArea for the Console Logger panel +#loggerpanel.usejsyntaxtext=true + +# Maximum size of HTML page that can be displayed; default=10 mbytes +# Set to 0 to disable the size check and display the whole response +#view.results.tree.max_size=10485760 + +# Order of Renderers in View Results Tree +# Note full class names should be used for non jmeter core renderers +# For JMeter core renderers, class names start with . and are automatically +# prefixed with org.apache.jmeter.visualizers +view.results.tree.renderers_order=.RenderAsText,.RenderAsRegexp,.RenderAsCssJQuery,.RenderAsXPath,org.apache.jmeter.extractor.json.render.RenderAsJsonRenderer,.RenderAsHTML,.RenderAsHTMLFormatted,.RenderAsHTMLWithEmbedded,.RenderAsDocument,.RenderAsJSON,.RenderAsXML + +# Maximum number of results in the results tree +# Set to 0 to store all results (might consume a lot of memory) +#view.results.tree.max_results=500 + +# Maximum size of Document that can be parsed by Tika engine; defaut=10 * 1024 * 1024 (10MB) +# Set to 0 to disable the size check +#document.max_size=0 + +#JMS options +# Enable the following property to stop JMS Point-to-Point Sampler from using +# the properties java.naming.security.[principal|credentials] when creating the queue connection +#JMSSampler.useSecurity.properties=false + +# Set the following value to true in order to skip the delete confirmation dialogue +#confirm.delete.skip=false + +# Used by JSR223 elements +# Size of compiled scripts cache +#jsr223.compiled_scripts_cache_size=100 + +#--------------------------------------------------------------------------- +# Classpath configuration +#--------------------------------------------------------------------------- + +# List of directories (separated by ;) to search for additional JMeter plugin classes, +# for example new GUI elements and samplers. +# Any jar file in such a directory will be automatically included, +# jar files in sub directories are ignored. +# The given value is in addition to any jars found in the lib/ext directory. +# Do not use this for utility or plugin dependency jars. +#search_paths=/app1/lib;/app2/lib + +# List of directories that JMeter will search for utility and plugin dependency classes. +# Use your platform path separator to separate multiple paths. +# Any jar file in such a directory will be automatically included, +# jar files in sub directories are ignored. +# The given value is in addition to any jars found in the lib directory. +# All entries will be added to the class path of the system class loader +# and also to the path of the JMeter internal loader. +# Paths with spaces may cause problems for the JVM +#user.classpath=../classes;../lib + +# List of directories (separated by ;) that JMeter will search for utility +# and plugin dependency classes. +# Any jar file in such a directory will be automatically included, +# jar files in sub directories are ignored. +# The given value is in addition to any jars found in the lib directory +# or given by the user.classpath property. +# All entries will be added to the path of the JMeter internal loader only. +# For plugin dependencies this property should be used instead of user.classpath. +#plugin_dependency_paths=../dependencies/lib;../app1/;../app2/ + +# Classpath finder +# ================ +# The classpath finder currently needs to load every single JMeter class to find +# the classes it needs. +# For non-GUI mode, it's only necessary to scan for Function classes, but all classes +# are still loaded. +# All current Function classes include ".function." in their name, +# and none include ".gui." in the name, so the number of unwanted classes loaded can be +# reduced by checking for these. However, if a valid function class name does not match +# these restrictions, it will not be loaded. If problems are encountered, then comment +# or change the following properties: +classfinder.functions.contain=.functions. +classfinder.functions.notContain=.gui. + + +#--------------------------------------------------------------------------- +# Additional property files to load +#--------------------------------------------------------------------------- + +# Should JMeter automatically load additional JMeter properties? +# File name to look for (comment to disable) +user.properties=user.properties + +# Should JMeter automatically load additional system properties? +# File name to look for (comment to disable) +system.properties=system.properties + +# Comma separated list of files that contain reference to templates and their description +# Path must be relative to JMeter root folder +#template.files=/bin/templates/templates.xml + + +#--------------------------------------------------------------------------- +# Thread Group Validation feature +#--------------------------------------------------------------------------- + +# Validation is the name of the feature used to rapidly validate a Thread Group runs fine +# Default implementation is org.apache.jmeter.gui.action.validation.TreeClonerForValidation +# It runs validation without timers, with 1 thread, 1 iteration and Startup Delay set to 0 +# You can implement your own policy that must extend org.apache.jmeter.engine.TreeCloner +# JMeter will instantiate it and use it to create the Tree used to run validation on Thread Group +#testplan_validation.tree_cloner_class=org.apache.jmeter.validation.ComponentTreeClonerForValidation + +# Number of threads to use to validate a Thread Group +#testplan_validation.nb_threads_per_thread_group=1 + +# Ignore BackendListener when validating the thread group of plan +#testplan_validation.ignore_backends=true + +# Ignore timers when validating the thread group of plan +#testplan_validation.ignore_timers=true + +# Number of iterations to use to validate a Thread Group +#testplan_validation.number_iterations=1 + +# Force throuput controllers that work in percentage mode to be a 100% +# Disabled by default +#testplan_validation.tpc_force_100_pct=false + +#--------------------------------------------------------------------------- +# Think Time configuration +#--------------------------------------------------------------------------- + +# +# Apply a factor on computed pauses by the following Timers: +# - Gaussian Random Timer +# - Uniform Random Timer +# - Poisson Random Timer +# +#timer.factor=1.0f + +# Default implementation that create the Timer structure to add to Test Plan +# Implementation of interface org.apache.jmeter.gui.action.thinktime.ThinkTimeCreator +#think_time_creator.impl=org.apache.jmeter.thinktime.DefaultThinkTimeCreator + +# Default Timer GUI class added to Test Plan by DefaultThinkTimeCreator +#think_time_creator.default_timer_implementation=org.apache.jmeter.timers.gui.UniformRandomTimerGui + +# Default constant pause of Timer +#think_time_creator.default_constant_pause=1000 + +# Default range pause of Timer +#think_time_creator.default_range=100 + + +# Change this parameter if you want to override the APDEX satisfaction threshold. +jmeter.reportgenerator.apdex_satisfied_threshold=500 + +# Change this parameter if you want to override the APDEX tolerance threshold. +jmeter.reportgenerator.apdex_tolerated_threshold=1500 + +#--------------------------------------------------------------------------- +# Naming Policy configuration +#--------------------------------------------------------------------------- + +# Prefix used when naming elements +#naming_policy.prefix= +# Suffix used when naming elements +#naming_policy.suffix= + +# Implementation of interface org.apache.jmeter.gui.action.TreeNodeNamingPolicy +#naming_policy.impl=org.apache.jmeter.gui.action.impl.DefaultTreeNodeNamingPolicy + diff --git a/tools/jmeter/src/main/resources/lib/ext/readme.txt b/tools/jmeter/src/main/resources/lib/ext/readme.txt new file mode 100644 index 0000000000..6243f40248 --- /dev/null +++ b/tools/jmeter/src/main/resources/lib/ext/readme.txt @@ -0,0 +1 @@ +This directory is expected by JMeter \ No newline at end of file diff --git a/tools/jmeter/src/main/resources/lib/junit/readme.txt b/tools/jmeter/src/main/resources/lib/junit/readme.txt new file mode 100644 index 0000000000..6243f40248 --- /dev/null +++ b/tools/jmeter/src/main/resources/lib/junit/readme.txt @@ -0,0 +1 @@ +This directory is expected by JMeter \ No newline at end of file diff --git a/tools/jmeter/src/main/resources/log4j2.xml b/tools/jmeter/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..7c81df7e7c --- /dev/null +++ b/tools/jmeter/src/main/resources/log4j2.xml @@ -0,0 +1,21 @@ + + + + info + + + + + + + + + + + + + + + + diff --git a/tools/jmeter/src/main/resources/perf-node-1.properties b/tools/jmeter/src/main/resources/perf-node-1.properties new file mode 100644 index 0000000000..3b29059afc --- /dev/null +++ b/tools/jmeter/src/main/resources/perf-node-1.properties @@ -0,0 +1 @@ +server.rmi.localport=10101 diff --git a/tools/jmeter/src/main/resources/perf-node-2.properties b/tools/jmeter/src/main/resources/perf-node-2.properties new file mode 100644 index 0000000000..97a2fed339 --- /dev/null +++ b/tools/jmeter/src/main/resources/perf-node-2.properties @@ -0,0 +1 @@ +server.rmi.localport=10102 diff --git a/tools/jmeter/src/main/resources/perf-node-3.properties b/tools/jmeter/src/main/resources/perf-node-3.properties new file mode 100644 index 0000000000..4381c5a309 --- /dev/null +++ b/tools/jmeter/src/main/resources/perf-node-3.properties @@ -0,0 +1 @@ +server.rmi.localport=10103 diff --git a/tools/jmeter/src/main/resources/perf-node-4.properties b/tools/jmeter/src/main/resources/perf-node-4.properties new file mode 100644 index 0000000000..c1a29df71d --- /dev/null +++ b/tools/jmeter/src/main/resources/perf-node-4.properties @@ -0,0 +1 @@ +server.rmi.localport=10104 diff --git a/tools/jmeter/src/main/resources/perf-notary.properties b/tools/jmeter/src/main/resources/perf-notary.properties new file mode 100644 index 0000000000..b307059e23 --- /dev/null +++ b/tools/jmeter/src/main/resources/perf-notary.properties @@ -0,0 +1 @@ +server.rmi.localport=10100