You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by pm...@apache.org on 2017/12/09 14:10:53 UTC
svn commit: r1817611 - in /jmeter/trunk:
src/components/org/apache/jmeter/assertions/
src/components/org/apache/jmeter/control/ test/src/org/apache/jmeter/
test/src/org/apache/jmeter/assertions/ test/src/org/apache/jmeter/control/
test/src/org/apache/j...
Author: pmouawad
Date: Sat Dec 9 14:10:53 2017
New Revision: 1817611
URL: http://svn.apache.org/viewvc?rev=1817611&view=rev
Log:
Re-wrote some existing tests in Spock
Contributed by Graham Russell
This closes #353
Added:
jmeter/trunk/test/src/org/apache/jmeter/assertions/MD5HexAssertionSpec.groovy
jmeter/trunk/test/src/org/apache/jmeter/control/RandomOrderControllerSpec.groovy
jmeter/trunk/test/src/org/apache/jmeter/control/ThroughputControllerSpec.groovy
jmeter/trunk/test/src/org/apache/jmeter/engine/util/PackageSpec.groovy
Removed:
jmeter/trunk/test/src/org/apache/jmeter/assertions/MD5HexAssertionTest.java
jmeter/trunk/test/src/org/apache/jmeter/control/TestRandomOrderController.java
jmeter/trunk/test/src/org/apache/jmeter/control/TestThroughputController.java
jmeter/trunk/test/src/org/apache/jmeter/engine/util/PackageTest.java
Modified:
jmeter/trunk/src/components/org/apache/jmeter/assertions/MD5HexAssertion.java
jmeter/trunk/src/components/org/apache/jmeter/control/RandomOrderController.java
jmeter/trunk/src/components/org/apache/jmeter/control/ThroughputController.java
jmeter/trunk/test/src/org/apache/jmeter/JMeterVersionTest.java
jmeter/trunk/test/src/org/apache/jmeter/engine/DistributedRunnerTest.java
jmeter/trunk/xdocs/changes.xml
Modified: jmeter/trunk/src/components/org/apache/jmeter/assertions/MD5HexAssertion.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/assertions/MD5HexAssertion.java?rev=1817611&r1=1817610&r2=1817611&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/assertions/MD5HexAssertion.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/assertions/MD5HexAssertion.java Sat Dec 9 14:10:53 2017
@@ -47,9 +47,6 @@ public class MD5HexAssertion extends Abs
/** Key for storing assertion-information in the jmx-file. */
private static final String MD5HEX_KEY = "MD5HexAssertion.size";
- /*
- * @param response @return
- */
@Override
public AssertionResult getResult(SampleResult response) {
@@ -72,15 +69,16 @@ public class MD5HexAssertion extends Abs
return result;
}
- String md5Result = baMD5Hex(resultData);
+ String md5Result = md5Hex(resultData);
if (!md5Result.equalsIgnoreCase(getAllowedMD5Hex())) {
result.setFailure(true);
Object[] arguments = { md5Result, getAllowedMD5Hex() };
- String message = MessageFormat.format(JMeterUtils.getResString("md5hex_assertion_failure"), arguments); // $NON-NLS-1$
+ String message = MessageFormat.format(
+ JMeterUtils.getResString("md5hex_assertion_failure"), // $NON-NLS-1$
+ arguments);
result.setFailureMessage(message);
-
}
return result;
@@ -94,13 +92,11 @@ public class MD5HexAssertion extends Abs
return getPropertyAsString(MD5HexAssertion.MD5HEX_KEY);
}
- // package protected so can be accessed by test class
- static String baMD5Hex(byte[] ba) {
+ private static String md5Hex(byte[] bytes) {
byte[] md5Result = {};
try {
- MessageDigest md = MessageDigest.getInstance("MD5");
- md5Result = md.digest(ba);
+ md5Result = MessageDigest.getInstance("MD5").digest(bytes);
} catch (NoSuchAlgorithmException e) {
log.error("Message digestion failed.", e);
}
Modified: jmeter/trunk/src/components/org/apache/jmeter/control/RandomOrderController.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/control/RandomOrderController.java?rev=1817611&r1=1817610&r2=1817611&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/control/RandomOrderController.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/control/RandomOrderController.java Sat Dec 9 14:10:53 2017
@@ -21,15 +21,11 @@ import java.util.Collections;
/**
* A controller that runs its children each at most once, but in a random order.
- *
*/
public class RandomOrderController extends GenericController implements Serializable {
private static final long serialVersionUID = 240L;
- /**
- * Create a new RandomOrderController.
- */
public RandomOrderController() {
}
Modified: jmeter/trunk/src/components/org/apache/jmeter/control/ThroughputController.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/control/ThroughputController.java?rev=1817611&r1=1817610&r2=1817611&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/control/ThroughputController.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/control/ThroughputController.java Sat Dec 9 14:10:53 2017
@@ -48,27 +48,24 @@ public class ThroughputController
private static final long serialVersionUID = 234L;
private static final Logger log = LoggerFactory.getLogger(ThroughputController.class);
- public static final int BYNUMBER = 0;
+ public static final int BYNUMBER = 0;
public static final int BYPERCENT = 1;
private static final String STYLE = "ThroughputController.style";// $NON-NLS-1$
-
private static final String PERTHREAD = "ThroughputController.perThread";// $NON-NLS-1$
-
private static final String MAXTHROUGHPUT = "ThroughputController.maxThroughput";// $NON-NLS-1$
-
private static final String PERCENTTHROUGHPUT = "ThroughputController.percentThroughput";// $NON-NLS-1$
private static class MutableInteger{
private int integer;
MutableInteger(int value){
- integer=value;
+ integer = value;
}
int incr(){
return ++integer;
}
- public int intValue() {
+ int intValue() {
return integer;
}
}
@@ -76,9 +73,7 @@ public class ThroughputController
// These items are shared between threads in a group by the clone() method
// They are initialised by testStarted() so don't need to be serialised
private transient MutableInteger globalNumExecutions;
-
private transient MutableInteger globalIteration;
-
private transient Object counterLock = new Object(); // ensure counts are updated correctly
/** Number of iterations on which we've chosen to deliver samplers. */
@@ -180,9 +175,6 @@ public class ThroughputController
return numExecutions;
}
- /**
- * @see org.apache.jmeter.control.Controller#next()
- */
@Override
public Sampler next() {
if (runThisTime) {
@@ -201,18 +193,12 @@ public class ThroughputController
return (100.0 * executions + 50.0) / (iterations + 1) < getPercentThroughputAsFloat();
}
- /**
- * @see org.apache.jmeter.control.Controller#isDone()
- */
@Override
public boolean isDone() {
- if (subControllersAndSamplers.isEmpty()) {
- return true;
- } else {
- return getStyle() == BYNUMBER
- && getExecutions() >= getMaxThroughputAsInt()
- && current >= getSubControllers().size();
- }
+ return subControllersAndSamplers.isEmpty()
+ || (getStyle() == BYNUMBER
+ && getExecutions() >= getMaxThroughputAsInt()
+ && current >= getSubControllers().size());
}
@Override
Modified: jmeter/trunk/test/src/org/apache/jmeter/JMeterVersionTest.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/JMeterVersionTest.java?rev=1817611&r1=1817610&r2=1817611&view=diff
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/JMeterVersionTest.java (original)
+++ jmeter/trunk/test/src/org/apache/jmeter/JMeterVersionTest.java Sat Dec 9 14:10:53 2017
@@ -168,9 +168,12 @@ public class JMeterVersionTest extends J
}
}
String expected = versions.get(jar);
- if(expected == null) {
- System.err.println("Didn't find version for jar name extracted by regexp, jar name extracted:"+jar+", version extracted:"+version+", current line:"+line);
- fail("Didn't find version for jar name extracted by regexp, jar name extracted:"+jar+", version extracted:"+version+", current line:"+line);
+ if (expected == null) {
+ final String message =
+ "Didn't find version for jar name extracted by regexp, jar name extracted:"
+ + jar + ", version extracted:" + version + ", current line:" + line;
+ System.err.println(message);
+ fail(message);
}
// Process ${xxx.version} references
final Matcher mp = versionPat.matcher(expected);
Added: jmeter/trunk/test/src/org/apache/jmeter/assertions/MD5HexAssertionSpec.groovy
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/assertions/MD5HexAssertionSpec.groovy?rev=1817611&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/assertions/MD5HexAssertionSpec.groovy (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/assertions/MD5HexAssertionSpec.groovy Sat Dec 9 14:10:53 2017
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+package org.apache.jmeter.assertions
+
+import org.apache.commons.lang3.StringUtils
+import org.apache.jmeter.junit.spock.JMeterSpec
+import org.apache.jmeter.samplers.SampleResult
+import spock.lang.Unroll
+
+import java.nio.charset.StandardCharsets
+
+@Unroll
+class MD5HexAssertionSpec extends JMeterSpec {
+
+ def sut = new MD5HexAssertion()
+
+ def "unset allowable hash with empty response fails"() {
+ when:
+ def result = sut.getResult(sampleResult(""))
+ then:
+ result.isFailure()
+ StringUtils.isNotBlank(result.getFailureMessage())
+ }
+
+ def "incorrect hash #allowedHex causes result failure"() {
+ given:
+ sut.setAllowedMD5Hex(allowedHex)
+ when:
+ def result = sut.getResult(sampleResult("anything"))
+ then:
+ result.isFailure()
+ StringUtils.isNotBlank(result.getFailureMessage())
+ where:
+ allowedHex << ["", "anything", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
+ }
+
+ def "example MD5s - '#sampleData' == '#hash'"() {
+ given:
+ sut.setAllowedMD5Hex(hash)
+ when:
+ def result = sut.getResult(sampleResult(sampleData))
+ then:
+ !result.isFailure()
+ !result.isError()
+ result.getFailureMessage() == null
+ where:
+ sampleData | hash
+ "anything" | "f0e166dc34d14d6c228ffac576c9a43c"
+ "anything" | "F0e166Dc34D14d6c228ffac576c9a43c"
+ }
+
+ def "empty array has MD5 hash of D41D8CD98F00B204E9800998ECF8427E"() {
+ given:
+ def emptyByteArray = [] as byte[]
+ expect:
+ MD5HexAssertion.md5Hex(emptyByteArray)
+ .toUpperCase(Locale.ENGLISH) == "D41D8CD98F00B204E9800998ECF8427E"
+ }
+
+ def sampleResult(String data) {
+ SampleResult response = new SampleResult()
+ response.setResponseData(data.getBytes(StandardCharsets.UTF_8))
+ return response
+ }
+}
Added: jmeter/trunk/test/src/org/apache/jmeter/control/RandomOrderControllerSpec.groovy
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/control/RandomOrderControllerSpec.groovy?rev=1817611&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/control/RandomOrderControllerSpec.groovy (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/control/RandomOrderControllerSpec.groovy Sat Dec 9 14:10:53 2017
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+package org.apache.jmeter.control
+
+import org.apache.jmeter.junit.stubs.TestSampler
+import org.apache.jmeter.testelement.TestElement
+import spock.lang.Specification
+
+class RandomOrderControllerSpec extends Specification {
+
+ def sut = new RandomOrderController()
+
+ def "next() on an empty controller returns null"() {
+ given:
+ sut.initialize()
+ when:
+ def nextSampler = sut.next()
+ then:
+ nextSampler == null
+ }
+
+ def "next() returns only provided sampler"() {
+ given:
+ def sampler = new TestSampler("the one and only")
+ sut.addTestElement(sampler)
+ sut.initialize()
+ when:
+ def nextSampler = sut.next()
+ def nextSamplerAfterEnd = sut.next()
+ then:
+ nextSampler == sampler
+ nextSamplerAfterEnd == null
+ }
+
+ def "next() returns exactly all added elements in random order"() {
+ given:
+ def samplerNames = (1..50).collect { it.toString() }
+ samplerNames.each {
+ sut.addTestElement(new TestSampler(it))
+ }
+ sut.initialize()
+ when:
+ def elements = getAllTestElements(sut)
+ then: "the same elements are returned but in a different order"
+ def elementNames = elements.collect { it.getName() }
+ elementNames.toSet() == samplerNames.toSet() // same elements
+ elementNames != samplerNames // not the same order
+
+ }
+
+ def "next() is null if isDone() is true"() {
+ given:
+ sut.addTestElement(Mock(TestElement))
+ sut.initialize()
+ sut.setDone(true)
+ when:
+ def nextSampler = sut.next()
+ then:
+ sut.isDone()
+ nextSampler == null
+ }
+
+ /**
+ * Builds and returns a list by 'iterating' through the
+ * {@link GenericController}, using {@link GenericController#next()},
+ * placing each item in a list until <code>null</code> is encountered.
+ *
+ * @param controller the {@link GenericController} to 'iterate' though
+ * @return a list of all items (in order) returned from next()
+ * method, excluding null
+ */
+ def getAllTestElements(GenericController controller) {
+ def sample
+ def samplers = []
+ while ((sample = controller.next()) != null) {
+ samplers.add(sample)
+ }
+ return samplers
+ }
+}
Added: jmeter/trunk/test/src/org/apache/jmeter/control/ThroughputControllerSpec.groovy
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/control/ThroughputControllerSpec.groovy?rev=1817611&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/control/ThroughputControllerSpec.groovy (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/control/ThroughputControllerSpec.groovy Sat Dec 9 14:10:53 2017
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.jmeter.control
+
+import org.apache.jmeter.junit.stubs.TestSampler
+import spock.lang.Specification
+
+class ThroughputControllerSpec extends Specification {
+
+ def sut = new ThroughputController()
+
+ def setup() {
+ sut.addTestElement(new TestSampler("one"))
+ sut.addTestElement(new TestSampler("two"))
+ }
+
+ def "new TC isDone is true"() {
+ given:
+ def newTC = new ThroughputController()
+ expect:
+ newTC.isDone()
+ }
+
+ def "2 maxThroughput runs samplers inside the TC only twice"() {
+ given:
+ sut.setStyle(ThroughputController.BYNUMBER)
+ sut.setMaxThroughput(2)
+
+ def expectedNames =
+ ["zero", "one", "two", "three",
+ "zero", "one", "two", "three",
+ "zero", "three",
+ "zero", "three",
+ "zero", "three",]
+
+ def loop = createLoopController(5)
+ when:
+ def actualNames = expectedNames.collect({
+ loop.next().getName()
+ })
+ then:
+ loop.next() == null
+ actualNames == expectedNames
+ sut.isDone()
+ sut.testEnded()
+ }
+
+ def "0 maxThroughput does not run any samplers inside the TC"() {
+ given:
+ sut.setStyle(ThroughputController.BYNUMBER)
+ sut.setMaxThroughput(0)
+
+ def loops = 3
+ def loop = createLoopController(loops)
+
+ def expectedNames = ["zero", "three"] * loops
+ when:
+ def actualNames = expectedNames.collect({
+ loop.next().getName()
+ })
+ then:
+ loop.next() == null
+ actualNames == expectedNames
+ sut.testEnded()
+ }
+
+ def "33.33% will run all the samplers inside the TC every 3 iterations"() {
+ given:
+ sut.setStyle(ThroughputController.BYPERCENT)
+ sut.setPercentThroughput(33.33f)
+
+ def loop = createLoopController(9)
+ // Expected results established using the DDA algorithm - see:
+ // http://www.siggraph.org/education/materials/HyperGraph/scanline/outprims/drawline.htm
+ def expectedNames =
+ ["zero", "three", // 0/1 vs. 1/1 -> 0 is closer to 33.33
+ "zero", "one", "two", "three", // 0/2 vs. 1/2 -> 50.0 is closer to 33.33
+ "zero", "three", // 1/3 vs. 2/3 -> 33.33 is closer to 33.33
+ "zero", "three", // 1/4 vs. 2/4 -> 25.0 is closer to 33.33
+ "zero", "one", "two", "three", // 1/5 vs. 2/5 -> 40.0 is closer to 33.33
+ "zero", "three", // 2/6 vs. 3/6 -> 33.33 is closer to 33.33
+ "zero", "three", // 2/7 vs. 3/7 -> 0.2857 is closer to 33.33
+ "zero", "one", "two", "three", // 2/8 vs. 3/8 -> 0.375 is closer to 33.33
+ "zero", "three", // ...
+ ]
+ when:
+ def actualNames = expectedNames.collect({
+ loop.next().getName()
+ })
+ then:
+ loop.next() == null
+ actualNames == expectedNames
+ sut.testEnded()
+ }
+
+ def "0% does not run any samplers inside the TC"() {
+ given:
+ sut.setStyle(ThroughputController.BYPERCENT)
+ sut.setPercentThroughput(0.0f)
+
+ def loops = 3
+ def loop = createLoopController(loops)
+
+ def expectedNames = ["zero", "three",] * loops
+ when:
+ def actualNames = expectedNames.collect({
+ loop.next().getName()
+ })
+ then:
+ loop.next() == null
+ actualNames == expectedNames
+ sut.testEnded()
+ }
+
+ def "100% always runs all samplers inside the TC"() {
+ given:
+ sut.setStyle(ThroughputController.BYPERCENT)
+ sut.setPercentThroughput(100.0f)
+
+ def loops = 3
+ def loop = createLoopController(loops)
+
+ def expectedNames = ["zero", "one", "two", "three",] * loops
+ when:
+ def actualNames = expectedNames.collect({
+ loop.next().getName()
+ })
+ then:
+ loop.next() == null
+ actualNames == expectedNames
+ sut.testEnded()
+ }
+
+ /**
+ * Create a LoopController, executed once, which contains an inner loop that
+ * runs {@code innerLoops} times, this inner loop contains a TestSampler ("zero")
+ * the {@link ThroughputController} which contains two test samplers
+ * ("one" and "two") followed by a final TestSampler ("three"):
+ *
+ * <pre>
+ * - outerLoop
+ * - innerLoop
+ * - sampler zero
+ * - ThroughputController (sut)
+ * - sampler one
+ * - sampler two
+ * - sampler three
+ * </pre>
+ *
+ * @param innerLoops number of times to loop the {@link ThroughputController}
+ * @return the {@link LoopController}
+ */
+ def createLoopController(int innerLoops) {
+ LoopController innerLoop = new LoopController()
+ innerLoop.setLoops(innerLoops)
+ innerLoop.addTestElement(new TestSampler("zero"))
+ innerLoop.addTestElement(sut)
+ innerLoop.addIterationListener(sut)
+ innerLoop.addTestElement(new TestSampler("three"))
+
+ def outerLoop = new LoopController()
+ outerLoop.setLoops(1)
+ outerLoop.addTestElement(innerLoop)
+ sut.testStarted()
+ outerLoop.setRunningVersion(true)
+ sut.setRunningVersion(true)
+ innerLoop.setRunningVersion(true)
+ outerLoop.initialize()
+ outerLoop
+ }
+}
Modified: jmeter/trunk/test/src/org/apache/jmeter/engine/DistributedRunnerTest.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/engine/DistributedRunnerTest.java?rev=1817611&r1=1817610&r2=1817611&view=diff
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/engine/DistributedRunnerTest.java (original)
+++ jmeter/trunk/test/src/org/apache/jmeter/engine/DistributedRunnerTest.java Sat Dec 9 14:10:53 2017
@@ -24,9 +24,6 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
-import java.net.MalformedURLException;
-import java.rmi.NotBoundException;
-import java.rmi.RemoteException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
@@ -41,7 +38,7 @@ import org.slf4j.LoggerFactory;
public class DistributedRunnerTest {
- public static void createJmeterEnv() throws IOException {
+ public static void createJmeterEnv() {
File propsFile;
try {
propsFile = File.createTempFile("jmeter", ".properties");
@@ -126,8 +123,8 @@ public class DistributedRunnerTest {
public List<EmulatorEngine> engines = new LinkedList<>();
@Override
- protected JMeterEngine createEngine(String address) throws RemoteException, NotBoundException, MalformedURLException {
- if(engines.size()==0) {
+ protected JMeterEngine createEngine(String address) {
+ if (engines.isEmpty()) {
throw new IllegalArgumentException("Throwing on Engine creation to simulate failure");
}
EmulatorEngine engine = engines.remove(0);
Added: jmeter/trunk/test/src/org/apache/jmeter/engine/util/PackageSpec.groovy
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/engine/util/PackageSpec.groovy?rev=1817611&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/engine/util/PackageSpec.groovy (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/engine/util/PackageSpec.groovy Sat Dec 9 14:10:53 2017
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+package org.apache.jmeter.engine.util
+
+import org.apache.jmeter.junit.spock.JMeterSpec
+import org.apache.jmeter.samplers.SampleResult
+import org.apache.jmeter.testelement.property.JMeterProperty
+import org.apache.jmeter.testelement.property.StringProperty
+import org.apache.jmeter.threads.JMeterContextService
+import org.apache.jmeter.threads.JMeterVariables
+import spock.lang.Unroll
+
+/**
+ * To run this test stand-alone, ensure that ApacheJMeter_functions.jar is on the classpath,
+ * as it is needed to resolve the functions.
+ */
+class PackageSpec extends JMeterSpec {
+
+ def transformer
+ def jmctx
+
+ def setup() {
+ def variables = ["my_regex": ".*",
+ "server" : "jakarta.apache.org"]
+ transformer = new ReplaceStringWithFunctions(new CompoundVariable(), variables)
+ jmctx = JMeterContextService.getContext()
+ jmctx.setVariables(new JMeterVariables())
+ jmctx.setSamplingStarted(true)
+ def result = new SampleResult()
+ result.setResponseData('<a>hello world</a> costs: $3.47,$5.67', null)
+ jmctx.setPreviousResult(result)
+ jmctx.getVariables().put("server", "jakarta.apache.org")
+ jmctx.getVariables().put("my_regex", ".*")
+ }
+
+ def testFunctionParse1() {
+ given:
+ StringProperty prop = new StringProperty("date",
+ '${__javaScript((new Date().getDate() / 100).toString()' +
+ '.substr(${__javaScript(1+1,d\\,ay)}\\,2),heute)}')
+ when:
+ JMeterProperty newProp = transformer.transformValue(prop)
+ newProp.setRunningVersion(true)
+ then:
+ newProp.getClass().getName() == "org.apache.jmeter.testelement.property.FunctionProperty"
+ newProp.recoverRunningVersion(null)
+ Integer.parseInt(newProp.getStringValue()) >= 0
+ jmctx.getVariables().getObject("d,ay") == "2"
+ }
+
+ @Unroll
+ def "test parsing StringProperty '#propertyValue' == '#stringValue'"() {
+ given:
+ StringProperty prop = new StringProperty("a", propertyValue)
+ when:
+ JMeterProperty newProp = transformer.transformValue(prop)
+ newProp.setRunningVersion(true)
+ then:
+ newProp.getClass().getName() == 'org.apache.jmeter.testelement.property.StringProperty'
+ newProp.getStringValue() == stringValue
+ where:
+ propertyValue | stringValue
+ "" | ""
+ "just some text" | "just some text"
+ }
+
+ @Unroll
+ def "test parsing FunctionProperty '#propertyValue' == '#stringValue'"() {
+ given:
+ StringProperty prop = new StringProperty("a", propertyValue)
+ when:
+ JMeterProperty newProp = transformer.transformValue(prop)
+ newProp.setRunningVersion(true)
+ then:
+ newProp.getClass().getName() == 'org.apache.jmeter.testelement.property.FunctionProperty'
+ newProp.getStringValue() == stringValue
+ where:
+ propertyValue | stringValue
+ '${__regexFunction(<a>(.*)</a>,$1$)}' | "hello world"
+ 'It should say:\\${${__regexFunction(<a>(.+o)(.*)</a>,$1$$2$)}}' | 'It should say:${hello world}'
+ '${non - existing; function}' | '${non - existing; function}'
+ '${server}' | "jakarta.apache.org"
+ '${__regexFunction(<([a-z]*)>,$1$)}' | "a"
+ '${__regexFunction((\\\\$\\d+\\.\\d+),$1$)}' | '$3.47'
+ '${__regexFunction(([$]\\d+\\.\\d+),$1$)}' | '$3.47'
+ '${__regexFunction((\\\\\\$\\d+\\.\\d+\\,\\\\$\\d+\\.\\d+),$1$)}' | '$3.47,$5.67'
+
+ // Nested examples
+ '${__regexFunction(<a>(${my_regex})</a>,$1$)}' | "hello world"
+ '${__regexFunction(<a>(${my_regex})</a>,$1$)}${__regexFunction(<a>(.),$1$)}' | "hello worldh"
+ }
+
+ @Unroll
+ def "Backslashes are removed before escaped dollar, comma and backslash with FunctionProperty"() {
+ // N.B. See Bug 46831 which wanted to changed the behaviour of \$
+ // It's too late now, as this would invalidate some existing test plans,
+ // so document the current behaviour with some more tests.
+ given:
+ StringProperty prop = new StringProperty("a", propertyValue)
+ when:
+ JMeterProperty newProp = transformer.transformValue(prop)
+ newProp.setRunningVersion(true)
+ then:
+ newProp.getClass().getName() == 'org.apache.jmeter.testelement.property.' + className
+ newProp.getStringValue() == stringValue
+
+ where:
+ propertyValue | className | stringValue
+ // With no variable reference
+ '\\$a' | "StringProperty" | '\\$a'
+ '\\,' | "StringProperty" | '\\,'
+ '\\\\' | "StringProperty" | '\\\\'
+ '\\' | "StringProperty" | '\\'
+ '\\x' | "StringProperty" | '\\x'
+ and: // With variable reference
+ '\\$a \\, \\\\ \\ \\x ${server} \\$b\\,z' | "FunctionProperty" | '$a , \\ \\ \\x jakarta.apache.org $b,z'
+ '\\$a \\, \\\\ \\ \\x ${__missing(a)} \\$b\\,z' | "FunctionProperty" | '$a , \\ \\ \\x ${__missing(a)} $b,z'
+ '\\$a \\, \\\\ \\ \\x ${missing} \\$b\\,z' | "FunctionProperty" | '$a , \\ \\ \\x ${missing} $b,z'
+ '\\$a \\, \\\\ ${ z' | "FunctionProperty" | '$a , \\ z'
+ }
+
+}
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1817611&r1=1817610&r2=1817611&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Sat Dec 9 14:10:53 2017
@@ -185,6 +185,7 @@ Summary
<li><pr>349</pr> Add i18n resouces(zh_CN). Contributed by Helly Guo (https://github.com/hellyguo)</li>
<li><pr>351</pr> Fixed about dialog position on first view. Contributed by Graham Russell (graham at ham1.co.uk)</li>
<li><pr>352</pr> Menu bar - added mnemonics to more menu items. Contributed by Graham Russell (graham at ham1.co.uk)</li>
+ <li><pr>353</pr> Re-wrote some existing tests in Spock. Contributed by Graham Russell (graham at ham1.co.uk)</li>
</ul>
<ch_section>Non-functional changes</ch_section>