Author: sebb
Date: Sat Jul 5 09:48:57 2008
New Revision: 674210
URL: http://svn.apache.org/viewvc?rev=674210&view=rev
Log:
Fix NPE when using nested Transaction Controllers with parent samples
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
jakarta/jmeter/trunk/xdocs/changes.xml
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java?rev=674210&r1=674209&r2=674210&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
(original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
Sat Jul 5 09:48:57 2008
@@ -237,104 +237,7 @@
while (running) {
Sampler sam;
while (running && (sam = controller.next()) !=
null) {
- try {
-
threadContext.setCurrentSampler(sam);
-
- // Check if we are running a transaction
- TransactionSampler transactionSampler = null;
- if(sam instanceof TransactionSampler) {
- transactionSampler = (TransactionSampler) sam;
- }
- // Find the package for the transaction
- SamplePackage transactionPack = null;
- if(transactionSampler != null) {
- transactionPack =
compiler.configureTransactionSampler(transactionSampler);
-
- // Check if the transaction is done
- if(transactionSampler.isTransactionDone()) {
- // Get the transaction sample result
- SampleResult transactionResult =
transactionSampler.getTransactionResult();
- transactionResult.setThreadName(threadName);
-
transactionResult.setGroupThreads(threadGroup.getNumberOfThreads());
-
transactionResult.setAllThreads(JMeterContextService.getNumberOfThreads());
-
- // Check assertions for the transaction sample
-
checkAssertions(transactionPack.getAssertions(), transactionResult);
- // Notify listeners with the transaction
sample result
-
notifyListeners(transactionPack.getSampleListeners(), transactionResult);
- compiler.done(transactionPack);
- // Transaction is done, we do not have a
sampler to sample
- sam = null;
- }
- else {
- // It is the sub sampler of the transaction
that will be sampled
- sam = transactionSampler.getSubSampler();
- }
- }
-
- // Check if we have a sampler to sample
- if(sam != null) {
- // Get the sampler ready to sample
- SamplePackage pack =
compiler.configureSampler(sam);
-
- // Hack: save the package
for any transaction controllers
-
threadVars.putObject(PACKAGE_OBJECT, pack);
-
- delay(pack.getTimers());
- Sampler sampler = pack.getSampler();
- sampler.setThreadContext(threadContext);
- sampler.setThreadName(threadName);
- TestBeanHelper.prepare(sampler);
-
- // Perform the actual sample
- SampleResult result = sampler.sample(null);
- // TODO: remove this useless Entry parameter
-
- // If we got any results, then perform processing
on the result
- if (result != null) {
-
result.setGroupThreads(threadGroup.getNumberOfThreads());
-
result.setAllThreads(JMeterContextService.getNumberOfThreads());
- result.setThreadName(threadName);
- threadContext.setPreviousResult(result);
- runPostProcessors(pack.getPostProcessors());
- checkAssertions(pack.getAssertions(), result);
- // Do not send subsamples to listeners which
receive the transaction sample
- List sampleListeners =
getSampleListeners(pack, transactionPack, transactionSampler);
- notifyListeners(sampleListeners, result);
- compiler.done(pack);
- // Add the result as subsample of transaction
if we are in a transaction
- if(transactionSampler != null) {
-
transactionSampler.addSubSamplerResult(result);
- }
-
- // Check if thread or test should be stopped
- if (result.isStopThread() ||
(!result.isSuccessful() && onErrorStopThread)) {
- stopThread();
- }
- if (result.isStopTest() ||
(!result.isSuccessful() && onErrorStopTest)) {
- stopTest();
- }
- } else {
- compiler.done(pack); // Finish up
- }
- }
- if (scheduler) {
- // checks the scheduler
to stop the iteration
- stopScheduler();
- }
- } catch (JMeterStopTestException e) {
- log.info("Stopping Test: " +
e.toString());
- stopTest();
- } catch (JMeterStopThreadException e) {
- log.info("Stopping Thread: " +
e.toString());
- stopThread();
- } catch (Exception e) {
- if (sam != null) {
- log.error("Error while processing sampler
'"+sam.getName()+"' :", e);
- } else {
- log.error("", e);
- }
- }
+ process_sampler(sam, null);
}
if (controller.isDone()) {
running = false;
@@ -360,6 +263,128 @@
threadFinished();
}
}
+
+ /**
+ * Process the current sampler, handling transaction samplers.
+ *
+ * @param current sampler
+ * @param parent sampler
+ * @return SampleResult if a transaction was processed
+ */
+ private SampleResult process_sampler(Sampler current, Sampler parent) {
+ SampleResult transactionResult = null;
+ try {
+ threadContext.setCurrentSampler(current);
+
+ // Check if we are running a transaction
+ TransactionSampler transactionSampler = null;
+ if(current instanceof TransactionSampler) {
+ transactionSampler = (TransactionSampler) current;
+ }
+ // Find the package for the transaction
+ SamplePackage transactionPack = null;
+ if(transactionSampler != null) {
+ transactionPack =
compiler.configureTransactionSampler(transactionSampler);
+
+ // Check if the transaction is done
+ if(transactionSampler.isTransactionDone()) {
+ // Get the transaction sample result
+ transactionResult =
transactionSampler.getTransactionResult();
+ transactionResult.setThreadName(threadName);
+
transactionResult.setGroupThreads(threadGroup.getNumberOfThreads());
+
transactionResult.setAllThreads(JMeterContextService.getNumberOfThreads());
+
+ // Check assertions for the transaction sample
+ checkAssertions(transactionPack.getAssertions(),
transactionResult);
+ // Notify listeners with the transaction sample result
+ if (!(parent instanceof TransactionSampler)){
+ notifyListeners(transactionPack.getSampleListeners(),
transactionResult);
+ }
+ compiler.done(transactionPack);
+ // Transaction is done, we do not have a sampler to sample
+ current = null;
+ }
+ else {
+ Sampler prev = current;
+ // It is the sub sampler of the transaction that will be
sampled
+ current = transactionSampler.getSubSampler();
+ if (current instanceof TransactionSampler){
+ SampleResult res = process_sampler(current, prev);//
recursive call
+ threadContext.setCurrentSampler(prev);
+ current=null;
+ if (res!=null){
+ transactionSampler.addSubSamplerResult(res);
+ }
+ }
+ }
+ }
+
+ // Check if we have a sampler to sample
+ if(current != null) {
+ // Get the sampler ready to sample
+ SamplePackage pack = compiler.configureSampler(current);
+
+ // Hack: save the package for any transaction controllers
+ threadVars.putObject(PACKAGE_OBJECT, pack);
+
+ delay(pack.getTimers());
+ Sampler sampler = pack.getSampler();
+ sampler.setThreadContext(threadContext);
+ sampler.setThreadName(threadName);
+ TestBeanHelper.prepare(sampler);
+
+ // Perform the actual sample
+ SampleResult
+ result = sampler.sample(null);
+ // TODO: remove this useless Entry parameter
+
+ // If we got any results, then perform processing on the result
+ if (result != null) {
+
result.setGroupThreads(threadGroup.getNumberOfThreads());
+
result.setAllThreads(JMeterContextService.getNumberOfThreads());
+ result.setThreadName(threadName);
+ threadContext.setPreviousResult(result);
+ runPostProcessors(pack.getPostProcessors());
+ checkAssertions(pack.getAssertions(), result);
+ // Do not send subsamples to listeners which receive the
transaction sample
+ List sampleListeners = getSampleListeners(pack,
transactionPack, transactionSampler);
+ notifyListeners(sampleListeners, result);
+ compiler.done(pack);
+ // Add the result as subsample of transaction if we are in
a transaction
+ if(transactionSampler != null) {
+ transactionSampler.addSubSamplerResult(result);
+ }
+
+ // Check if thread or test should be stopped
+ if (result.isStopThread() || (!result.isSuccessful() &&
onErrorStopThread)) {
+ stopThread();
+ }
+ if (result.isStopTest() || (!result.isSuccessful() &&
onErrorStopTest)) {
+ stopTest();
+ }
+ } else {
+ compiler.done(pack); // Finish up
+ }
+ }
+ if (scheduler) {
+ // checks the scheduler to stop the iteration
+ stopScheduler();
+ }
+ } catch (JMeterStopTestException e) {
+ log.info("Stopping Test: " + e.toString());
+ stopTest();
+ } catch (JMeterStopThreadException e) {
+ log.info("Stopping Thread: " + e.toString());
+ stopThread();
+ } catch (Exception e) {
+ if (current != null) {
+ log.error("Error while processing sampler
'"+current.getName()+"' :", e);
+ } else {
+ log.error("", e);
+ }
+ }
+ return transactionResult;
+ }
/**
* Get the SampleListeners for the sampler. Listeners who receive
transaction sample
Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=674210&r1=674209&r2=674210&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Sat Jul 5 09:48:57 2008
@@ -63,6 +63,7 @@
The menu item Options / Choose Language does not change all the displayed text
to the new language.
To override the default local language, set the JMeter property "language"
before starting JMeter.
</p>
+
<h3>Incompatible changes</h3>
<ul>
The test element "Save Results to a file" is now shown as a Listener.
@@ -77,7 +78,8 @@
<li>The "prev" and "sampler" objects are now defined for BSF test elements</li>
<li>Prompt to overwrite an existing file when first saving a new test plan</li>
<li>The test element "Save Results to a file" is now shown as a Listener</li>
-<li>Correct TestBeans to show the correct popup menu for Listeners</li>
+<li>Amend TestBeans to show the correct popup menu for Listeners</li>
+<li>Fix NPE when using nested Transaction Controllers with parent samples</li>
</ul>
<h3>Improvements</h3>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]