ENT-2579 Move sensitive data out of resources (#1492)

* Move testplans and sensitive config out of resources into a new data directory. Required code/config changes for that to work.
Server RMI mappings are now mandatory on the cmd line when using ssh tunnels, no more defaults in the resources.

* Add sample test plans that show what we do without having any passwords or hostnames in them.

* Add more descriptions/comments to the sample test plans.
This commit is contained in:
Christian Sailer 2018-10-23 09:41:14 +01:00 committed by GitHub
parent d6c76c69aa
commit a8eb02855e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 2630 additions and 8 deletions

View File

@ -107,6 +107,8 @@ run {
args+= Eval.me(jmeterHosts)
}
args += [ "-XserverRmiMappings", sourceSets.main.resources.getSrcDirs().first().getPath() + "/../data/server-rmi.config"]
args+= [ "-XjmeterProperties", sourceSets.main.resources.getSrcDirs().first().getPath()+"/jmeter.properties",
"--",
"-d", sourceSets.main.resources.getSrcDirs().first().getPath() ]
@ -140,7 +142,6 @@ task buildJMeterJAR(type: FatCapsule) {
from(processResources) {
include "log4j2.xml"
include "*.properties"
include "server-rmi.config"
include "bin/*.properties"
}

View File

@ -0,0 +1,195 @@
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="3.2" jmeter="3.3 r1808647">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments">A very simple test plan that connects to a node via RPC and self issues
cash
</stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel"
testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel"
testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">1000</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">3</stringProp>
<stringProp name="ThreadGroup.ramp_time"></stringProp>
<longProp name="ThreadGroup.start_time">1509455820000</longProp>
<longProp name="ThreadGroup.end_time">1509455820000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
<stringProp name="TestPlan.comments">The thread group controls how often the requests are run. Expand it on the
left hand side to see the sampler configuration.
</stringProp>
</ThreadGroup>
<hashTree>
<JavaSampler guiclass="JavaTestSamplerGui" testclass="JavaSampler" testname="Cash Issue Request" enabled="true">
<stringProp name="TestPlan.comments">This is configured to invoke the CashIssueSampler - the RPC details and
the notary name for the test set-up need to be entered for it to work.
</stringProp>
<elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments"
enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="label" elementType="Argument">
<stringProp name="Argument.name">label</stringProp>
<stringProp name="Argument.value">${__samplerName}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="host" elementType="Argument">
<stringProp name="Argument.name">host</stringProp>
<stringProp name="Argument.value">Hostname of RPC target here</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="port" elementType="Argument">
<stringProp name="Argument.name">port</stringProp>
<stringProp name="Argument.value">RPC port here</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="username" elementType="Argument">
<stringProp name="Argument.name">username</stringProp>
<stringProp name="Argument.value">RPC user name here</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="password" elementType="Argument">
<stringProp name="Argument.name">password</stringProp>
<stringProp name="Argument.value">RPC password Here</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="notaryName" elementType="Argument">
<stringProp name="Argument.name">notaryName</stringProp>
<stringProp name="Argument.value">X500 name of the notary here</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</elementProp>
<stringProp name="classname">com.r3.corda.jmeter.CashIssueSampler</stringProp>
</JavaSampler>
<hashTree/>
</hashTree>
<ResultCollector guiclass="StatGraphVisualizer" testclass="ResultCollector" testname="Aggregate Graph"
enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
<ResultCollector guiclass="GraphVisualizer" testclass="ResultCollector" testname="Graph Results" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
<ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="View Results in Table"
enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
<WorkBench guiclass="WorkBenchGui" testclass="WorkBench" testname="WorkBench" enabled="true">
<boolProp name="WorkBench.save">true</boolProp>
</WorkBench>
<hashTree/>
</hashTree>
</jmeterTestPlan>

File diff suppressed because it is too large Load Diff

View File

@ -94,12 +94,14 @@ class Launcher {
} else {
File(cmdLine.jMeterProperties).toPath()
}
val serverRmiMappingFile = if (cmdLine.serverRmiMappings.isBlank()) {
(jMeterHome / "server-rmi.config").toString()
val serverRmiMappings = if (!cmdLine.serverRmiMappings.isBlank()) {
readHostAndPortMap(cmdLine.serverRmiMappings)
} else {
cmdLine.serverRmiMappings
if (!cmdLine.sshHosts.isEmpty()) {
throw LauncherException("Enabling ssh tunneling requires providing rmi mappings via -XserverRmiMappings")
}
emptyMap()
}
val serverRmiMappings = readHostAndPortMap(serverRmiMappingFile)
// we want to add the jMeter properties file here - it must not be part of the user specified jMeter
// arguments
@ -118,9 +120,12 @@ class Launcher {
if (port != null) {
val rmiPropsFile = (jMeterHome / "server-rmi.properties").toFile()
rmiPropsFile.writeText("server.rmi.localport=$port")
jMeterArgs.addAll(listOf("-q", rmiPropsFile.toString()))
logger.info("Starting jmeter server using mapped server.rmi.localport=$port")
} else {
logger.info("No rmi server mapping found, using default server.rmi.localport - assuming no ssh tunnelling in effect")
}
}
return JMeterArgsPlus(jMeterArgs, jMeterPropertiesFile, serverRmiMappings)
}

View File

@ -118,11 +118,12 @@ class TestLauncherHelpers {
SystemPropertySetter("jmeter.home", temporaryFolder.root.toString()).use {
val defaultJmeterPropertiesFile = createFileInTmpFolder("jmeter.properties")
createFileInTmpFolder("custom.properties")
createFileInTmpFolder("server-rmi.config", "${InetAddress.getLocalHost().hostName}:10101")
createFileInTmpFolder("nomatch-rmi.config", "notmatching:10101")
val cmdLine = LauncherCommandLine()
cmdLine.jMeterArguments.addAll(listOf("-s"))
cmdLine.serverRmiMappings = createFileInTmpFolder("server-rmi.config", "${InetAddress.getLocalHost().hostName}:10101")
val result = Launcher.prepareJMeterArguments(cmdLine)
assertEquals(defaultJmeterPropertiesFile, result.jmeterPropertiesFile.toString())
@ -158,6 +159,23 @@ class TestLauncherHelpers {
}
}
@Test
fun testJMeterArgPreparationServerMissingRmiMapping() {
SystemPropertySetter("jmeter.home", temporaryFolder.root.toString()).use {
createFileInTmpFolder("jmeter.properties")
val customJmeterPropertiesFile = createFileInTmpFolder("custom.properties")
createFileInTmpFolder("server-rmi.config", "${InetAddress.getLocalHost().hostName}:10101")
createFileInTmpFolder("nomatch-rmi.config", "notmatching:10101")
val cmdLine = LauncherCommandLine()
cmdLine.jMeterArguments.addAll(listOf("-s"))
cmdLine.sshHosts = mutableListOf("node1.mydomain.com")
cmdLine.jMeterProperties = customJmeterPropertiesFile
testForException("Enabling ssh tunneling requires providing rmi mappings via -XserverRmiMappings") { Launcher.prepareJMeterArguments(cmdLine) }
}
}
@Test
fun testJMeterArgPreparationClient() {
SystemPropertySetter("jmeter.home", temporaryFolder.root.toString()).use {
@ -170,7 +188,6 @@ class TestLauncherHelpers {
val result = Launcher.prepareJMeterArguments(cmdLine)
assertEquals(defaultJmeterPropertiesFile, result.jmeterPropertiesFile.toString())
assertEquals(mapOf(InetAddress.getLocalHost().hostName to 10101), result.serverRmiMappings)
val expectedServerPropsFile = temporaryFolder.root.toPath() / "server-rmi.properties"
assertEquals(listOf("-p", defaultJmeterPropertiesFile), result.jmeterArgs)
val serverPropsFile = expectedServerPropsFile.toFile()