Bug 55334 - Adding Include Controller to test plan (made of Include Controllers) without saving TestPlan leads to included code not being taken into account until save
Adding Include Controller to test plan (made of Include Controllers) without ...
Status: RESOLVED FIXED
Product: JMeter
Classification: Unclassified
Component: Main
2.9
All All
: P2 major (vote)
: ---
Assigned To: JMeter issues mailing list
:
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2013-07-31 23:54 UTC by Soul Patch
Modified: 2013-08-02 12:07 UTC (History)
2 users (show)



Attachments
proposed patch containing the fix for the issue. (677 bytes, patch)
2013-08-01 23:46 UTC, Soul Patch
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Soul Patch 2013-07-31 23:54:26 UTC
In a Test Plan, add a Thread Group which has Include Controllers in it. Each Include controller has a valid Test Fragment file path specified. The Test Plan as a whole is Valid.
Run the Test Plan to completion. Now add another Include Controller to this Test Plan using Add -> Logic Controller -> Include Controller.
Add a valid file path of a Test Fragment (This could be a duplicate of one of the other Include Controllers already in the Test Plan)
Now run the Test Plan. The following exception is encountered in the logs. 

ERROR - jmeter.threads.JMeterThread: Test failed! java.lang.ClassCastException: org.apache.jmeter.gui.tree.JMeterTreeNode cannot be cast to org.apache.jmeter.testelement.TestElement
	at org.apache.jmeter.threads.TestCompiler.addNode(TestCompiler.java:140)
	at org.apache.jorphan.collections.HashTree.traverseInto(HashTree.java:1001)
	at org.apache.jorphan.collections.HashTree.traverse(HashTree.java:986)
	at org.apache.jmeter.threads.JMeterThread.initRun(JMeterThread.java:532)
	at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:252)
	at java.lang.Thread.run(Unknown Source)
Comment 1 Soul Patch 2013-08-01 00:03:29 UTC
On Investigation it was found that when traversing the testTree in the initRun() method in JMeterThread.java class the newly added Include Controller is passed as a JMeterTreeNode instead of an IncludeController type.  

Following is the code flow : 
JMeterThread.run() --> JMeterThread.initRun() --> Traverses the testTree using the HashTreeTraverser 'compiler'. --> HashTree.traverse() called where the data.keySet() function returns all the keys. The definition of 'data'  says : 

****
// N.B. The keys can be either JMeterTreeNode or TestElement
    protected final Map<Object, HashTree> data;
****

TestCompiler.addNode() called which tries to cast the JMeterTreeNode received to TestElement and a ClassCastException is thrown.

Need to investigate why the data.keySet returns a JMeterTreeNode. If it is acceptable then a code should be in place to extract the TestElement from the JMeterTreeNode to avoid the ClassCastException.
Comment 2 Soul Patch 2013-08-01 14:54:35 UTC
Found a fix that works well. Don't know if this is the exact fix but it does nothing too radical. 
Checking for the instance type of the 'node' received. If it is a JMeterTreeNode then extract the TestElement and set it to 'node' and then move ahead. 
The TestCompiler.addNode() method now looks like this : 

 /** {@inheritDoc} */
    @Override
    public void addNode(Object node, HashTree subTree) {
    	if(node instanceof JMeterTreeNode){
    		stack.addLast(((JMeterTreeNode)node).getTestElement());
    	}else{
        stack.addLast((TestElement) node);
    	}
    }
Comment 3 Soul Patch 2013-08-01 23:46:41 UTC
Created attachment 30661 [details]
proposed patch containing the fix for the issue.

The patch should be applied to the src/core directory in the source code. It contains the fix for the reported issue. The patch modifies the code in the org.apache.jmeter.threads.TestCompiler.addNode() method. 

The method should look like this after adding the patch.

/** {@inheritDoc} */
    @Override
    public void addNode(Object node, HashTree subTree) {
    	if(node instanceof JMeterTreeNode){
    		stack.addLast(((JMeterTreeNode)node).getTestElement());
    	}else{
        stack.addLast((TestElement) node);
    	}
    }
Comment 4 Philippe Mouawad 2013-08-02 12:03:36 UTC
Date: Fri Aug  2 12:02:03 2013
New Revision: 1509647

URL: http://svn.apache.org/r1509647
Log:
Bug 55334 - Adding Include Controller to test plan (made of Include Controllers) without saving TestPlan leads to included code not being taken into account until save
Bugzilla Id: 55334

Modified:
    jmeter/trunk/src/core/org/apache/jmeter/JMeter.java
    jmeter/trunk/xdocs/changes.xml
Comment 5 Philippe Mouawad 2013-08-02 12:07:52 UTC
Thanks for patch, but in fact it was not fixing root cause which was due to ReplaceableController not being loaded when in GUI mode and before saving Test Tree.

This should be fixed now.
Also removed invalid code in o instanceof TestElement branch code:
------------------------------------------------------------
else { // null subTree
    convertSubTree(tree.getTree(item));
}
------------------------------------------------------------
in this branch, tree.getTree(item) can only be null, so calling convertSubTree would lead to NPE.



Thanks for reporting issue.