Skip to content

Commit cbf186f

Browse files
author
jvangaalen
committed
Clear transaction from subresults
1 parent 78a51ce commit cbf186f

4 files changed

Lines changed: 17 additions & 117 deletions

File tree

src/core/src/main/java/org/apache/jmeter/samplers/SampleResult.java

Lines changed: 2 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,9 @@
3030
import java.util.concurrent.TimeUnit;
3131

3232
import org.apache.jmeter.assertions.AssertionResult;
33-
import org.apache.jmeter.control.TransactionSampler;
3433
import org.apache.jmeter.gui.Searchable;
3534
import org.apache.jmeter.testelement.TestPlan;
36-
import org.apache.jmeter.threads.JMeterContext;
3735
import org.apache.jmeter.threads.JMeterContext.TestLogicalAction;
38-
import org.apache.jmeter.threads.JMeterContextService;
3936
import org.apache.jmeter.util.JMeterUtils;
4037
import org.apache.jorphan.util.JOrphanUtils;
4138
import org.slf4j.Logger;
@@ -66,15 +63,10 @@ public class SampleResult implements Serializable, Cloneable, Searchable {
6663
private static final String INVALID_CALL_SEQUENCE_MSG = "Invalid call sequence"; // $NON-NLS-1$
6764

6865

69-
// Bug 33196 - encoding ISO-8859-1 is only suitable for Western countries
70-
// However the suggested System.getProperty("file.encoding") is Cp1252 on
71-
// Windows
72-
// So use a new property with the original value as default
73-
// needs to be accessible from test code
7466
/**
7567
* The default encoding to be used to decode the responseData byte array.
7668
* The value is defined by the property "sampleresult.default.encoding"
77-
* with a default of DEFAULT_HTTP_ENCODING if that is not defined.
69+
* with a default of {@link #DEFAULT_HTTP_ENCODING} if that is not defined.
7870
*/
7971
protected static final String DEFAULT_ENCODING
8072
= JMeterUtils.getPropDefault("sampleresult.default.encoding", // $NON-NLS-1$
@@ -1602,62 +1594,10 @@ public void setStartNextThreadLoop(boolean startNextThreadLoop) {
16021594
}
16031595

16041596
/**
1605-
* Clean up cached data, but only if this is a root result (no parent)
1606-
* and not part of a parent transaction.
1597+
* Clean up cached data
16071598
*/
16081599
public void cleanAfterSample() {
1609-
// Only clean if this is a root result (no parent)
1610-
if (parent != null) {
1611-
return;
1612-
}
1613-
1614-
// Check if we're part of a parent transaction by walking up the sampler hierarchy
1615-
JMeterContext context = JMeterContextService.getContext();
1616-
if (context != null) {
1617-
Sampler currentSampler = context.getCurrentSampler();
1618-
if (currentSampler instanceof TransactionSampler) {
1619-
TransactionSampler transSampler = (TransactionSampler) currentSampler;
1620-
// Get the parent sampler from the transaction
1621-
Sampler parentSampler = transSampler.getSubSampler();
1622-
// If there's a parent sampler and it's a transaction, we're nested
1623-
if (parentSampler instanceof TransactionSampler) {
1624-
return;
1625-
}
1626-
}
1627-
}
1628-
1629-
cleanRecursively();
1630-
}
1631-
1632-
/**
1633-
* Internal method to clean this result and all its sub-results
1634-
*/
1635-
private void cleanRecursively() {
1636-
// Clean sub-results first
1637-
if (subResults != null) {
1638-
for (SampleResult subResult : subResults) {
1639-
if (subResult != null) {
1640-
subResult.cleanRecursively();
1641-
}
1642-
}
1643-
subResults.clear();
1644-
subResults = null;
1645-
}
1646-
1647-
// Clean assertion results
1648-
if (assertionResults != null) {
1649-
assertionResults.clear();
1650-
assertionResults = null;
1651-
}
1652-
1653-
// Clear only memory-heavy data and caches, preserve samplerData
1654-
this.parent = null;
16551600
this.responseDataAsString = null;
1656-
this.responseData = EMPTY_BA;
1657-
this.responseHeaders = "";
1658-
this.requestHeaders = "";
1659-
this.samplerData = null;
1660-
16611601
}
16621602

16631603
@Override
@@ -1725,50 +1665,4 @@ public TestLogicalAction getTestLogicalAction() {
17251665
public void setTestLogicalAction(TestLogicalAction testLogicalAction) {
17261666
this.testLogicalAction = testLogicalAction;
17271667
}
1728-
1729-
/**
1730-
* Create a deep copy for async listeners
1731-
* @return A deep copy of this result
1732-
*/
1733-
public SampleResult cloneForListeners() {
1734-
// Create clone with the correct type
1735-
SampleResult clone;
1736-
try {
1737-
// Use the same constructor that was used to create this instance
1738-
clone = this.getClass().getConstructor(this.getClass()).newInstance(this);
1739-
} catch (Exception e) {
1740-
// Fallback to base class if constructor is not available
1741-
log.debug("Could not create clone with type: " + this.getClass().getName() + ", using base class", e);
1742-
clone = new SampleResult(this);
1743-
}
1744-
1745-
// Deep copy mutable fields that the copy constructor doesn't handle deeply
1746-
if (responseData != EMPTY_BA) {
1747-
clone.responseData = responseData.clone();
1748-
}
1749-
1750-
// Deep copy subResults
1751-
if (subResults != null) {
1752-
clone.subResults = new ArrayList<>(subResults.size());
1753-
for (SampleResult sub : subResults) {
1754-
SampleResult subClone = sub.cloneForListeners();
1755-
subClone.setParent(clone);
1756-
clone.subResults.add(subClone);
1757-
}
1758-
}
1759-
1760-
// Deep copy assertion results
1761-
if (assertionResults != null) {
1762-
clone.assertionResults = new ArrayList<>(assertionResults.size());
1763-
for (AssertionResult assertionResult : assertionResults) {
1764-
clone.assertionResults.add(assertionResult); // AssertionResult is immutable
1765-
}
1766-
}
1767-
1768-
// Clear only the caches and unnecessary references in the clone
1769-
clone.responseDataAsString = null;
1770-
clone.parent = null; // Parent reference not needed in the clone
1771-
1772-
return clone;
1773-
}
17741668
}

src/core/src/main/java/org/apache/jmeter/threads/JMeterThread.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -678,12 +678,6 @@ private SampleResult doEndTransactionSampler(
678678
notifyListeners(transactionPack.getSampleListeners(), transactionResult);
679679
}
680680
compiler.done(transactionPack);
681-
682-
// Clean up the transaction result after listeners have processed it
683-
if (transactionResult != null) {
684-
transactionResult.cleanAfterSample();
685-
}
686-
687681
return transactionResult;
688682
}
689683

@@ -1044,7 +1038,7 @@ void notifyTestListeners() {
10441038
}
10451039

10461040
private void notifyListeners(List<SampleListener> listeners, SampleResult result) {
1047-
SampleEvent event = new SampleEvent(result.cloneForListeners(), threadGroup.getName(), threadVars);
1041+
SampleEvent event = new SampleEvent(result, threadGroup.getName(), threadVars);
10481042
notifier.notifyListeners(event, listeners);
10491043
}
10501044

src/core/src/main/java/org/apache/jmeter/threads/TestCompiler.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,21 @@ public SamplePackage configureTransactionSampler(TransactionSampler transactionS
115115
}
116116

117117
/**
118-
* Reset pack to its initial state
118+
* Reset pack to its initial state and clean up transaction results if needed
119119
* @param pack the {@link SamplePackage} to reset
120120
*/
121121
public void done(SamplePackage pack) {
122+
Sampler sampler = pack.getSampler();
123+
if (sampler instanceof TransactionSampler) {
124+
TransactionSampler transactionSampler = (TransactionSampler) sampler;
125+
TransactionController controller = transactionSampler.getTransactionController();
126+
if (transactionSampler.isTransactionDone()) {
127+
// Create new sampler for next iteration
128+
TransactionSampler newSampler = new TransactionSampler(controller, transactionSampler.getName());
129+
SamplePackage newPack = transactionControllerConfigMap.get(controller);
130+
newPack.setSampler(newSampler);
131+
}
132+
}
122133
pack.recoverRunningVersion();
123134
}
124135

src/dist-check/src/test/java/org/apache/jmeter/junit/JMeterTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,8 @@ static Stream<Serializable> serializableObjects() throws Throwable {
581581
return getObjects(Serializable.class)
582582
.stream()
583583
.map(Serializable.class::cast)
584-
.filter(o -> !o.getClass().getName().endsWith("_Stub"));
584+
.filter(o -> !o.getClass().getName().endsWith("_Stub"))
585+
.filter(o -> o.getClass().getName().startsWith("org.apache.jmeter."));
585586
}
586587

587588
/*

0 commit comments

Comments
 (0)