mirror of https://github.com/apache/jmeter.git
				
				
				
			Fix NPE when using nested Transaction Controllers with parent samples
git-svn-id: https://svn.apache.org/repos/asf/jakarta/jmeter/trunk@674210 13f79535-47bb-0310-9956-ffa450edef68
Former-commit-id: e5f3ecb5c7
			
			
This commit is contained in:
		
							parent
							
								
									3f920e2cb1
								
							
						
					
					
						commit
						9be8566a56
					
				|  | @ -237,13 +237,49 @@ public class JMeterThread implements Runnable, Serializable { | |||
| 			while (running) { | ||||
| 				Sampler sam; | ||||
| 				while (running && (sam = controller.next()) != null) { | ||||
| 					process_sampler(sam, null); | ||||
| 				} | ||||
| 				if (controller.isDone()) { | ||||
| 					running = false; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		// Might be found by contoller.next() | ||||
| 		catch (JMeterStopTestException e) { | ||||
| 			log.info("Stopping Test: " + e.toString()); | ||||
| 			stopTest(); | ||||
| 		} catch (JMeterStopThreadException e) { | ||||
| 			log.info("Stop Thread seen: " + e.toString()); | ||||
| 		} catch (Exception e) { | ||||
| 			log.error("Test failed!", e); | ||||
| 		} catch (ThreadDeath e) { | ||||
| 			throw e; // Must not ignore this one | ||||
| 		} catch (Error e) {// Make sure errors are output to the log file | ||||
| 			log.error("Test failed!", e); | ||||
| 		} finally { | ||||
| 			threadContext.clear(); | ||||
| 			log.info("Thread " + threadName + " is done"); | ||||
| 			monitor.threadFinished(this); | ||||
| 			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(sam); | ||||
|         	threadContext.setCurrentSampler(current); | ||||
|              | ||||
|             // Check if we are running a transaction | ||||
|             TransactionSampler transactionSampler = null; | ||||
|                         if(sam instanceof TransactionSampler) { | ||||
|                             transactionSampler = (TransactionSampler) sam; | ||||
|             if(current instanceof TransactionSampler) { | ||||
|                 transactionSampler = (TransactionSampler) current; | ||||
|             } | ||||
|             // Find the package for the transaction | ||||
|             SamplePackage transactionPack = null; | ||||
|  | @ -253,7 +289,7 @@ public class JMeterThread implements Runnable, Serializable { | |||
|                 // Check if the transaction is done | ||||
|                 if(transactionSampler.isTransactionDone()) { | ||||
|                     // Get the transaction sample result | ||||
|                                 SampleResult transactionResult = transactionSampler.getTransactionResult(); | ||||
|                     transactionResult = transactionSampler.getTransactionResult(); | ||||
|                     transactionResult.setThreadName(threadName); | ||||
|                     transactionResult.setGroupThreads(threadGroup.getNumberOfThreads()); | ||||
|                     transactionResult.setAllThreads(JMeterContextService.getNumberOfThreads()); | ||||
|  | @ -261,21 +297,32 @@ public class JMeterThread implements Runnable, Serializable { | |||
|                     // 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 | ||||
|                                 sam = null; | ||||
|                     current = null; | ||||
|                 } | ||||
|                 else { | ||||
|                     Sampler prev = current; | ||||
|                     // It is the sub sampler of the transaction that will be sampled | ||||
|                                 sam = transactionSampler.getSubSampler(); | ||||
|                     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(sam != null) { | ||||
|             if(current != null) { | ||||
|                 // Get the sampler ready to sample | ||||
|                             SamplePackage pack = compiler.configureSampler(sam); | ||||
|                 SamplePackage pack = compiler.configureSampler(current); | ||||
| 
 | ||||
|         	    // Hack: save the package for any transaction controllers | ||||
|         		threadVars.putObject(PACKAGE_OBJECT, pack); | ||||
|  | @ -287,7 +334,8 @@ public class JMeterThread implements Runnable, Serializable { | |||
|                 TestBeanHelper.prepare(sampler); | ||||
|              | ||||
|                 // Perform the actual sample | ||||
|                             SampleResult result = sampler.sample(null);  | ||||
|                 SampleResult  | ||||
|                 result = sampler.sample(null);  | ||||
|                 // TODO: remove this useless Entry parameter | ||||
|              | ||||
|                 // If we got any results, then perform processing on the result | ||||
|  | @ -329,36 +377,13 @@ public class JMeterThread implements Runnable, Serializable { | |||
|         	log.info("Stopping Thread: " + e.toString()); | ||||
|         	stopThread(); | ||||
|         } catch (Exception e) { | ||||
| 					    if (sam != null) { | ||||
| 	                        log.error("Error while processing sampler '"+sam.getName()+"' :", e);					         | ||||
|             if (current != null) { | ||||
|                 log.error("Error while processing sampler '"+current.getName()+"' :", e);					         | ||||
|             } else { | ||||
|                 log.error("", e); | ||||
|             } | ||||
|         } | ||||
| 				} | ||||
| 				if (controller.isDone()) { | ||||
| 					running = false; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		// Might be found by contoller.next() | ||||
| 		catch (JMeterStopTestException e) { | ||||
| 			log.info("Stopping Test: " + e.toString()); | ||||
| 			stopTest(); | ||||
| 		} catch (JMeterStopThreadException e) { | ||||
| 			log.info("Stop Thread seen: " + e.toString()); | ||||
| 		} catch (Exception e) { | ||||
| 			log.error("Test failed!", e); | ||||
| 		} catch (ThreadDeath e) { | ||||
| 			throw e; // Must not ignore this one | ||||
| 		} catch (Error e) {// Make sure errors are output to the log file | ||||
| 			log.error("Test failed!", e); | ||||
| 		} finally { | ||||
| 			threadContext.clear(); | ||||
| 			log.info("Thread " + threadName + " is done"); | ||||
| 			monitor.threadFinished(this); | ||||
| 			threadFinished(); | ||||
| 		} | ||||
|         return transactionResult; | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|  |  | |||
|  | @ -63,6 +63,7 @@ but otherwise its behaviour is not consistent (or clearly specified).</p> | |||
| 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 @@ It does not affect test plans or test behaviour. | |||
| <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> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue