Skip to content

Commit 01258c6

Browse files
authored
Bael-3842 - How to Pass a Variable From One Thread Group to Another in JMeter (#18687)
* first draft * renaming to avoid errors with RetrieveUuidControllerUnitTest
1 parent b6b8e32 commit 01258c6

File tree

7 files changed

+536
-0
lines changed

7 files changed

+536
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.baeldung.sharedthreadvars;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class SharedThreadVarsApplication {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(SharedThreadVarsApplication.class, args);
11+
}
12+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.baeldung.sharedthreadvars.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
6+
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
7+
import org.springframework.security.web.SecurityFilterChain;
8+
9+
@Configuration
10+
public class SecurityConfiguration {
11+
12+
@Bean
13+
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
14+
http.csrf(CsrfConfigurer::disable)
15+
.authorizeHttpRequests(auth -> auth.anyRequest()
16+
.permitAll());
17+
return http.build();
18+
}
19+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.baeldung.sharedthreadvars.controller;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.UUID;
6+
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
import org.springframework.http.HttpStatus;
10+
import org.springframework.web.bind.annotation.GetMapping;
11+
import org.springframework.web.bind.annotation.PostMapping;
12+
import org.springframework.web.bind.annotation.RequestBody;
13+
import org.springframework.web.bind.annotation.RequestMapping;
14+
import org.springframework.web.bind.annotation.RequestParam;
15+
import org.springframework.web.bind.annotation.RestController;
16+
import org.springframework.web.server.ResponseStatusException;
17+
18+
@RestController
19+
@RequestMapping("/api")
20+
public class RestApi {
21+
22+
private final Logger log = LoggerFactory.getLogger(RestApi.class);
23+
24+
private Map<UUID, String> items = new HashMap<>();
25+
26+
@PostMapping
27+
public String post(@RequestBody String name) {
28+
UUID uuid = UUID.randomUUID();
29+
items.put(uuid, name);
30+
31+
log.debug("put {}={}", uuid, name);
32+
return uuid.toString();
33+
}
34+
35+
@GetMapping
36+
public String get(@RequestParam("uuid") String uuid) {
37+
String name = items.remove(UUID.fromString(uuid));
38+
39+
if (name == null)
40+
throw new ResponseStatusException(HttpStatus.EXPECTATION_FAILED);
41+
42+
log.debug("get {}={}", uuid, name);
43+
return name;
44+
}
45+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.6.3">
3+
<hashTree>
4+
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan">
5+
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables">
6+
<collectionProp name="Arguments.arguments"/>
7+
</elementProp>
8+
<boolProp name="TestPlan.functional_mode">false</boolProp>
9+
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
10+
</TestPlan>
11+
<hashTree>
12+
<SetupThreadGroup guiclass="SetupThreadGroupGui" testclass="SetupThreadGroup" testname="setup-threads">
13+
<intProp name="ThreadGroup.num_threads">3</intProp>
14+
<intProp name="ThreadGroup.ramp_time">1</intProp>
15+
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
16+
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
17+
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller">
18+
<stringProp name="LoopController.loops">1</stringProp>
19+
<boolProp name="LoopController.continue_forever">false</boolProp>
20+
</elementProp>
21+
</SetupThreadGroup>
22+
<hashTree>
23+
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="post-data">
24+
<stringProp name="HTTPSampler.domain">localhost</stringProp>
25+
<stringProp name="HTTPSampler.port">8080</stringProp>
26+
<stringProp name="HTTPSampler.path">/api</stringProp>
27+
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
28+
<stringProp name="HTTPSampler.method">POST</stringProp>
29+
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
30+
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
31+
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
32+
<collectionProp name="Arguments.arguments">
33+
<elementProp name="" elementType="HTTPArgument">
34+
<boolProp name="HTTPArgument.always_encode">false</boolProp>
35+
<stringProp name="Argument.value">${__RandomString(5)}</stringProp>
36+
<stringProp name="Argument.metadata">=</stringProp>
37+
</elementProp>
38+
</collectionProp>
39+
</elementProp>
40+
</HTTPSamplerProxy>
41+
<hashTree/>
42+
<JSR223PostProcessor guiclass="TestBeanGUI" testclass="JSR223PostProcessor" testname="store-response">
43+
<stringProp name="cacheKey">true</stringProp>
44+
<stringProp name="filename"></stringProp>
45+
<stringProp name="parameters"></stringProp>
46+
<stringProp name="script">String response = prev.getResponseDataAsString();
47+
48+
if (bsh.shared.uuidQueue == void) {
49+
bsh.shared.uuidQueue= new LinkedList();
50+
log.info(&quot;--&gt; setup: created queue&quot;);
51+
}
52+
bsh.shared.uuidQueue.add(response);
53+
54+
log.info(&quot;--&gt; setup: &quot;+response);
55+
</stringProp>
56+
<stringProp name="scriptLanguage">java</stringProp>
57+
</JSR223PostProcessor>
58+
<hashTree/>
59+
</hashTree>
60+
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="worker-threads" enabled="true">
61+
<intProp name="ThreadGroup.num_threads">3</intProp>
62+
<intProp name="ThreadGroup.ramp_time">1</intProp>
63+
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
64+
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
65+
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller">
66+
<stringProp name="LoopController.loops">1</stringProp>
67+
<boolProp name="LoopController.continue_forever">false</boolProp>
68+
</elementProp>
69+
</ThreadGroup>
70+
<hashTree>
71+
<JSR223PreProcessor guiclass="TestBeanGUI" testclass="JSR223PreProcessor" testname="prepare-request">
72+
<stringProp name="cacheKey">true</stringProp>
73+
<stringProp name="filename"></stringProp>
74+
<stringProp name="parameters"></stringProp>
75+
<stringProp name="script">String uuid = bsh.shared.uuidQueue.poll();
76+
vars.put(&quot;uuid&quot;, uuid);
77+
78+
log.info(&quot;&lt;-- worker - next: &quot;+uuid);
79+
</stringProp>
80+
<stringProp name="scriptLanguage">java</stringProp>
81+
</JSR223PreProcessor>
82+
<hashTree/>
83+
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="get-data" enabled="true">
84+
<stringProp name="HTTPSampler.domain">localhost</stringProp>
85+
<stringProp name="HTTPSampler.port">8080</stringProp>
86+
<stringProp name="HTTPSampler.path">/api?uuid=${uuid}</stringProp>
87+
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
88+
<stringProp name="HTTPSampler.method">GET</stringProp>
89+
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
90+
<boolProp name="HTTPSampler.postBodyRaw">false</boolProp>
91+
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables">
92+
<collectionProp name="Arguments.arguments"/>
93+
</elementProp>
94+
</HTTPSamplerProxy>
95+
<hashTree/>
96+
</hashTree>
97+
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
98+
<boolProp name="ResultCollector.error_logging">false</boolProp>
99+
<objProp>
100+
<name>saveConfig</name>
101+
<value class="SampleSaveConfiguration">
102+
<time>true</time>
103+
<latency>true</latency>
104+
<timestamp>true</timestamp>
105+
<success>true</success>
106+
<label>true</label>
107+
<code>true</code>
108+
<message>true</message>
109+
<threadName>true</threadName>
110+
<dataType>true</dataType>
111+
<encoding>false</encoding>
112+
<assertions>true</assertions>
113+
<subresults>true</subresults>
114+
<responseData>false</responseData>
115+
<samplerData>false</samplerData>
116+
<xml>false</xml>
117+
<fieldNames>true</fieldNames>
118+
<responseHeaders>false</responseHeaders>
119+
<requestHeaders>false</requestHeaders>
120+
<responseDataOnError>false</responseDataOnError>
121+
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
122+
<assertionsResultsToSave>0</assertionsResultsToSave>
123+
<bytes>true</bytes>
124+
<sentBytes>true</sentBytes>
125+
<url>true</url>
126+
<threadCounts>true</threadCounts>
127+
<idleTime>true</idleTime>
128+
<connectTime>true</connectTime>
129+
</value>
130+
</objProp>
131+
<stringProp name="filename"></stringProp>
132+
</ResultCollector>
133+
<hashTree/>
134+
</hashTree>
135+
</hashTree>
136+
</jmeterTestPlan>
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.6.3">
3+
<hashTree>
4+
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan">
5+
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables">
6+
<collectionProp name="Arguments.arguments"/>
7+
</elementProp>
8+
<boolProp name="TestPlan.functional_mode">false</boolProp>
9+
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
10+
</TestPlan>
11+
<hashTree>
12+
<SetupThreadGroup guiclass="SetupThreadGroupGui" testclass="SetupThreadGroup" testname="setup-threads">
13+
<intProp name="ThreadGroup.num_threads">3</intProp>
14+
<intProp name="ThreadGroup.ramp_time">1</intProp>
15+
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
16+
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
17+
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller">
18+
<stringProp name="LoopController.loops">1</stringProp>
19+
<boolProp name="LoopController.continue_forever">false</boolProp>
20+
</elementProp>
21+
</SetupThreadGroup>
22+
<hashTree>
23+
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="post-data" enabled="true">
24+
<stringProp name="HTTPSampler.domain">localhost</stringProp>
25+
<stringProp name="HTTPSampler.port">8080</stringProp>
26+
<stringProp name="HTTPSampler.path">/api</stringProp>
27+
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
28+
<stringProp name="HTTPSampler.method">POST</stringProp>
29+
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
30+
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
31+
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
32+
<collectionProp name="Arguments.arguments">
33+
<elementProp name="" elementType="HTTPArgument">
34+
<boolProp name="HTTPArgument.always_encode">false</boolProp>
35+
<stringProp name="Argument.value">${__RandomString(5)}</stringProp>
36+
<stringProp name="Argument.metadata">=</stringProp>
37+
</elementProp>
38+
</collectionProp>
39+
</elementProp>
40+
</HTTPSamplerProxy>
41+
<hashTree/>
42+
<JSR223PostProcessor guiclass="TestBeanGUI" testclass="JSR223PostProcessor" testname="store-response">
43+
<stringProp name="cacheKey">true</stringProp>
44+
<stringProp name="filename"></stringProp>
45+
<stringProp name="parameters"></stringProp>
46+
<stringProp name="script">String response = prev.getResponseDataAsString();
47+
File file = new File(&quot;/tmp/shared-file&quot;+ctx.getThreadNum()+&quot;.txt&quot;);
48+
49+
try {
50+
FileWriter writer = new FileWriter(file);
51+
writer.write(response);
52+
writer.close();
53+
log.info(&quot;--&gt; setup: &quot;+response+&quot; - &quot;+file);
54+
} catch (IOException e) {
55+
log.error(&quot;Failed to write response to file&quot;, e);
56+
}
57+
</stringProp>
58+
<stringProp name="scriptLanguage">java</stringProp>
59+
</JSR223PostProcessor>
60+
<hashTree/>
61+
</hashTree>
62+
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="worker-threads" enabled="true">
63+
<intProp name="ThreadGroup.num_threads">3</intProp>
64+
<intProp name="ThreadGroup.ramp_time">1</intProp>
65+
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
66+
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
67+
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller">
68+
<stringProp name="LoopController.loops">1</stringProp>
69+
<boolProp name="LoopController.continue_forever">false</boolProp>
70+
</elementProp>
71+
</ThreadGroup>
72+
<hashTree>
73+
<JSR223PreProcessor guiclass="TestBeanGUI" testclass="JSR223PreProcessor" testname="prepare-request">
74+
<stringProp name="cacheKey">true</stringProp>
75+
<stringProp name="filename"></stringProp>
76+
<stringProp name="parameters"></stringProp>
77+
<stringProp name="script">File file = new File(&quot;/tmp/shared-file&quot;+ctx.getThreadNum()+&quot;.txt&quot;);
78+
79+
try {
80+
Scanner reader = new Scanner(file);
81+
String uuid = reader.hasNextLine() ? reader.nextLine().trim() : &quot;&quot;;
82+
reader.close();
83+
84+
vars.put(&quot;uuid&quot;, uuid);
85+
86+
log.info(&quot;&lt;-- worker - next: &quot;+uuid+&quot; - &quot;+file);
87+
} catch (IOException e) {
88+
log.error(&quot;Failed to read response file&quot;, e);
89+
}
90+
</stringProp>
91+
<stringProp name="scriptLanguage">java</stringProp>
92+
</JSR223PreProcessor>
93+
<hashTree/>
94+
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="get-data" enabled="true">
95+
<stringProp name="HTTPSampler.domain">localhost</stringProp>
96+
<stringProp name="HTTPSampler.port">8080</stringProp>
97+
<stringProp name="HTTPSampler.path">/api?uuid=${uuid}</stringProp>
98+
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
99+
<stringProp name="HTTPSampler.method">GET</stringProp>
100+
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
101+
<boolProp name="HTTPSampler.postBodyRaw">false</boolProp>
102+
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables">
103+
<collectionProp name="Arguments.arguments"/>
104+
</elementProp>
105+
</HTTPSamplerProxy>
106+
<hashTree/>
107+
</hashTree>
108+
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
109+
<boolProp name="ResultCollector.error_logging">false</boolProp>
110+
<objProp>
111+
<name>saveConfig</name>
112+
<value class="SampleSaveConfiguration">
113+
<time>true</time>
114+
<latency>true</latency>
115+
<timestamp>true</timestamp>
116+
<success>true</success>
117+
<label>true</label>
118+
<code>true</code>
119+
<message>true</message>
120+
<threadName>true</threadName>
121+
<dataType>true</dataType>
122+
<encoding>false</encoding>
123+
<assertions>true</assertions>
124+
<subresults>true</subresults>
125+
<responseData>false</responseData>
126+
<samplerData>false</samplerData>
127+
<xml>false</xml>
128+
<fieldNames>true</fieldNames>
129+
<responseHeaders>false</responseHeaders>
130+
<requestHeaders>false</requestHeaders>
131+
<responseDataOnError>false</responseDataOnError>
132+
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
133+
<assertionsResultsToSave>0</assertionsResultsToSave>
134+
<bytes>true</bytes>
135+
<sentBytes>true</sentBytes>
136+
<url>true</url>
137+
<threadCounts>true</threadCounts>
138+
<idleTime>true</idleTime>
139+
<connectTime>true</connectTime>
140+
</value>
141+
</objProp>
142+
<stringProp name="filename"></stringProp>
143+
</ResultCollector>
144+
<hashTree/>
145+
</hashTree>
146+
</hashTree>
147+
</jmeterTestPlan>

0 commit comments

Comments
 (0)