Skip to content

Commit b9dc01f

Browse files
committed
refactor: migrate Groovy tests in :src:functions to Kotlin
1 parent d5bc84c commit b9dc01f

4 files changed

Lines changed: 128 additions & 106 deletions

File tree

src/core/src/main/java/org/apache/jmeter/functions/gui/FunctionHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ private static String variablesToString(JMeterVariables jMeterVariables) {
272272
return sb.toString();
273273
}
274274

275-
private static String buildFunctionCallString(String functionName, Arguments args) {
275+
@VisibleForTesting
276+
static String buildFunctionCallString(String functionName, Arguments args) {
276277
StringBuilder functionCall = new StringBuilder("${");
277278
functionCall.append(functionName);
278279
if (args.getArguments().size() > 0) {

src/functions/src/test/kotlin/org/apache/jmeter/functions/ChangeCaseTest.kt

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -21,52 +21,59 @@ import org.apache.jmeter.engine.util.CompoundVariable
2121
import org.apache.jmeter.samplers.SampleResult
2222
import org.apache.jmeter.threads.JMeterContextService
2323
import org.apache.jmeter.threads.JMeterVariables
24+
import org.junit.jupiter.api.Assertions.assertEquals
25+
import org.junit.jupiter.api.Assumptions.assumeTrue
26+
import org.junit.jupiter.params.ParameterizedTest
27+
import org.junit.jupiter.params.provider.MethodSource
28+
import java.util.Locale
2429

25-
import spock.lang.IgnoreIf
26-
import spock.lang.Specification
27-
import spock.lang.Unroll
30+
class ChangeCaseTest {
31+
data class ExecuteCase(val input: String, val mode: String, val output: String)
2832

29-
@Unroll
30-
class ChangeCaseSpec extends Specification {
31-
32-
// See https://github.com/apache/jmeter/issues/5723
33-
@IgnoreIf({ 'i'.toUpperCase() != 'I' || 'I'.toLowerCase() != 'i' })
34-
def "convert '#input' using mode #mode to '#output'"() {
35-
given:
36-
def changeCase = new ChangeCase()
37-
def jMCtx = JMeterContextService.getContext()
38-
def result = new SampleResult()
39-
result.setResponseData("dummy data", null)
40-
jMCtx.setVariables(new JMeterVariables())
41-
jMCtx.setPreviousResult(result)
42-
when:
43-
changeCase.setParameters([new CompoundVariable(input), new CompoundVariable(mode)])
44-
then:
45-
output == changeCase.execute(result, null)
46-
where:
47-
input | mode | output
48-
"simple" | "lower" | "simple"
49-
"simple" | "upper" | "SIMPLE"
50-
"simple" | "capitalize" | "Simple"
51-
"simple" | "" | "SIMPLE"
52-
" with space " | "lower" | " with space "
53-
" with space " | "upper" | " WITH SPACE "
54-
" with space " | "capitalize" | " with space "
55-
"#_with-signs." | "lower" | "#_with-signs."
56-
"#_with-signs." | "upper" | "#_WITH-SIGNS."
57-
"#_with-signs." | "capitalize" | "#_with-signs."
58-
"m4u file" | "lower" | "m4u file"
59-
"m4u file" | "upper" | "M4U FILE"
60-
"m4u file" | "capitalize" | "M4u file"
61-
"WITH Ümläuts" | "lower" | "with ümläuts"
62-
"WITH Ümläuts" | "upper" | "WITH ÜMLÄUTS"
63-
"WITH Ümläuts" | "capitalize" | "WITH Ümläuts"
64-
"+ - special space" | "lower" | "+ - special space"
65-
"+ - special space" | "upper" | "+ - SPECIAL SPACE"
66-
"+ - special space" | "capitalize" | "+ - special space"
67-
" " | "lower" | " "
68-
" " | "upper" | " "
69-
" " | "capitalize" | " "
33+
companion object {
34+
@JvmStatic
35+
fun executeCases() = listOf(
36+
ExecuteCase("simple", "lower", "simple"),
37+
ExecuteCase("simple", "upper", "SIMPLE"),
38+
ExecuteCase("simple", "capitalize", "Simple"),
39+
ExecuteCase("simple", "", "SIMPLE"),
40+
ExecuteCase(" with space ", "lower", " with space "),
41+
ExecuteCase(" with space ", "upper", " WITH SPACE "),
42+
ExecuteCase(" with space ", "capitalize", " with space "),
43+
ExecuteCase("#_with-signs.", "lower", "#_with-signs."),
44+
ExecuteCase("#_with-signs.", "upper", "#_WITH-SIGNS."),
45+
ExecuteCase("#_with-signs.", "capitalize", "#_with-signs."),
46+
ExecuteCase("m4u file", "lower", "m4u file"),
47+
ExecuteCase("m4u file", "upper", "M4U FILE"),
48+
ExecuteCase("m4u file", "capitalize", "M4u file"),
49+
ExecuteCase("WITH Ümläuts", "lower", "with ümläuts"),
50+
ExecuteCase("WITH Ümläuts", "upper", "WITH ÜMLÄUTS"),
51+
ExecuteCase("WITH Ümläuts", "capitalize", "WITH Ümläuts"),
52+
ExecuteCase("+ - special space", "lower", "+ - special space"),
53+
ExecuteCase("+ - special space", "upper", "+ - SPECIAL SPACE"),
54+
ExecuteCase("+ - special space", "capitalize", "+ - special space"),
55+
ExecuteCase(" ", "lower", " "),
56+
ExecuteCase(" ", "upper", " "),
57+
ExecuteCase(" ", "capitalize", " "),
58+
).also {
59+
assumeTrue(
60+
"i".uppercase(Locale.getDefault()) == "I" && "I".lowercase(Locale.getDefault()) == "i",
61+
"ChangeCase does not behave well in tr_TR locale, see https://github.com/apache/jmeter/issues/5723"
62+
)
63+
}
7064
}
7165

66+
@ParameterizedTest
67+
@MethodSource("executeCases")
68+
fun changeCase(case: ExecuteCase) {
69+
val changeCase = ChangeCase()
70+
val jMCtx = JMeterContextService.getContext()
71+
val result = SampleResult()
72+
result.setResponseData("dummy data", null)
73+
jMCtx.variables = JMeterVariables()
74+
jMCtx.previousResult = result
75+
changeCase.setParameters(listOf(CompoundVariable(case.input), CompoundVariable(case.mode)))
76+
77+
assertEquals(case.output, changeCase.execute(result, null))
78+
}
7279
}

src/functions/src/test/kotlin/org/apache/jmeter/functions/IterationCounterTest.kt

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,51 +15,57 @@
1515
* limitations under the License.
1616
*/
1717

18-
package org.apache.jmeter.functions;
19-
20-
import java.util.concurrent.CountDownLatch
18+
package org.apache.jmeter.functions
2119

2220
import org.apache.jmeter.engine.util.CompoundVariable
2321
import org.apache.jmeter.threads.JMeterContextService
2422
import org.apache.jmeter.threads.JMeterVariables
23+
import org.junit.jupiter.api.Assertions
24+
import org.junit.jupiter.api.Test
25+
import java.util.concurrent.CountDownLatch
26+
import kotlin.concurrent.thread
27+
28+
class IterationCounterTest {
2529

26-
import spock.lang.Specification
27-
import spock.lang.Unroll
30+
@Test
31+
fun `Counter per thread counts for each thread`() {
32+
val context = JMeterContextService.getContext()
33+
context.variables = JMeterVariables()
34+
val counter = IterationCounter()
35+
counter.setParameters(listOf(CompoundVariable("true"), CompoundVariable("var")))
2836

29-
@Unroll
30-
class IterationCounterSpec extends Specification {
37+
thread(start = true) {
38+
repeat(7) { counter.execute(null, null) }
39+
}.join()
3140

32-
def "Counter per thread counts for each thread"() {
33-
given:
34-
def context = JMeterContextService.getContext()
35-
context.setVariables(new JMeterVariables())
36-
def counter = new IterationCounter()
37-
counter.setParameters(Arrays.asList(new CompoundVariable("true"), new CompoundVariable("var")))
38-
when:
39-
Thread.start({ (1..10).each { counter.execute(null, null) } }).join()
40-
(1..10).each { counter.execute(null, null) }
41-
then:
42-
context.getVariables().get("var") == "10"
41+
repeat(10) { counter.execute(null, null) }
42+
43+
Assertions.assertEquals("10", context.variables.get("var")) {
44+
"Only 10 executions happended in the current thread, so expecting 10. " +
45+
"Note there were 7 iterations in a different thread, however the counter should be per-thread"
46+
}
4347
}
4448

45-
def "global Counter counts for all threads"() {
46-
given:
47-
def context = JMeterContextService.getContext()
48-
context.setVariables(new JMeterVariables())
49-
def counter = new IterationCounter()
50-
counter.setParameters(Arrays.asList(new CompoundVariable("false"), new CompoundVariable("var")))
51-
def nrOfThreads = 100
52-
def latch = new CountDownLatch(nrOfThreads)
53-
when:
54-
(1..nrOfThreads).each {
55-
Thread.start({
56-
(1..1000).each { counter.execute(null, null) }
57-
latch.countDown()
58-
})
49+
@Test
50+
fun `global Counter counts for all threads`() {
51+
val context = JMeterContextService.getContext()
52+
context.variables = JMeterVariables()
53+
val counter = IterationCounter()
54+
counter.setParameters(listOf(CompoundVariable("false"), CompoundVariable("var")))
55+
val nrOfThreads = 100
56+
val latch = CountDownLatch(nrOfThreads)
57+
58+
repeat(nrOfThreads) {
59+
thread(start = true) {
60+
repeat(1000) { counter.execute(null, null) }
61+
latch.countDown()
5962
}
60-
latch.await()
61-
counter.execute(null, null)
62-
then:
63-
context.getVariables().get("var") == "100001"
63+
}
64+
latch.await()
65+
counter.execute(null, null)
66+
67+
Assertions.assertEquals("100001", context.variables.get("var")) {
68+
"$nrOfThreads should have increased the var by 1000, plus one in main thread"
69+
}
6470
}
6571
}

src/functions/src/test/kotlin/org/apache/jmeter/functions/gui/FunctionHelperTest.kt

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,41 @@ package org.apache.jmeter.functions.gui
1919

2020
import org.apache.jmeter.config.Argument
2121
import org.apache.jmeter.config.Arguments
22+
import org.apache.jmeter.test.gui.DisabledIfHeadless
23+
import org.junit.jupiter.api.Assertions.assertEquals
24+
import org.junit.jupiter.params.ParameterizedTest
25+
import org.junit.jupiter.params.provider.MethodSource
2226

23-
import spock.lang.IgnoreIf
24-
import spock.lang.Specification
25-
import spock.lang.Unroll
27+
class FunctionHelperTest {
28+
data class BuildCallCase(val functionName: String, val parameters: List<String>, val combined: String)
2629

27-
@Unroll
28-
class FunctionHelperSpec extends Specification {
30+
companion object {
31+
@JvmStatic
32+
fun buildCallCases() = listOf(
33+
BuildCallCase("fname", listOf(), "\${fname}"),
34+
BuildCallCase("fname", listOf("a"), "\${fname(a)}"),
35+
BuildCallCase("fname", listOf("a,b"), "\${fname(a\\,b)}"),
36+
BuildCallCase("fname", listOf("a,b,c"), "\${fname(a\\,b\\,c)}"),
37+
BuildCallCase("fname", listOf("a", "b"), "\${fname(a,b)}"),
38+
BuildCallCase("fname", listOf("a,b", "c"), "\${fname(a\\,b,c)}"),
39+
BuildCallCase("fname", listOf("\\\${f(a,b)}"), "\${fname(\\\${f(a\\,b)})}"),
40+
BuildCallCase("fname", listOf("\${f(a,b)},c,\${g(d,e)}", "h"), "\${fname(\${f(a,b)}\\,c\\,\${g(d,e)},h)}"),
41+
BuildCallCase("fname", listOf("a,\${f(b,\${g(c,d)},e)},f", "h"), "\${fname(a\\,\${f(b,\${g(c,d)},e)}\\,f,h)}"),
42+
)
43+
}
44+
45+
@DisabledIfHeadless
46+
@ParameterizedTest
47+
@MethodSource("buildCallCases")
48+
fun `construct correct call string for parameters #parameters`(case: BuildCallCase) {
49+
val args = Arguments()
50+
args.setArguments(case.parameters.map { Argument("dummy$it", it) })
2951

30-
@IgnoreIf({ System.properties['java.awt.headless'] as boolean })
31-
def "construct correct call string for parameters #parameters"() {
32-
setup:
33-
def functionHelper = new FunctionHelper()
34-
when:
35-
def args = new Arguments()
36-
args.setArguments(parameters.collect { new Argument("dummy${it}", it) })
37-
then:
38-
functionHelper.buildFunctionCallString(functionName, args).toString() == combined
39-
where:
40-
functionName | parameters | combined
41-
"fname" | [] | "\${fname}"
42-
"fname" | ["a"] | "\${fname(a)}"
43-
"fname" | ["a,b"] | "\${fname(a\\,b)}"
44-
"fname" | ["a,b,c"] | "\${fname(a\\,b\\,c)}"
45-
"fname" | ["a", "b"] | "\${fname(a,b)}"
46-
"fname" | ["a,b", "c"] | "\${fname(a\\,b,c)}"
47-
"fname" | ["\\\${f(a,b)}"] | "\${fname(\\\${f(a\\,b)})}"
48-
"fname" | ["\${f(a,b)},c,\${g(d,e)}", "h"] | "\${fname(\${f(a,b)}\\,c\\,\${g(d,e)},h)}"
49-
"fname" | ["a,\${f(b,\${g(c,d)},e)},f", "h"] | "\${fname(a\\,\${f(b,\${g(c,d)},e)}\\,f,h)}"
52+
assertEquals(
53+
case.combined,
54+
FunctionHelper.buildFunctionCallString(case.functionName, args).toString()
55+
) {
56+
"buildFunctionCallString(${case.functionName}, ${case.parameters})"
57+
}
5058
}
5159
}

0 commit comments

Comments
 (0)