1
votes

I'm trying to programmatically traverse all elements (Controllers, Managers, Samplers, etc) in an existing jmeter jmx file, but every example resource I'm finding only allows me to traverse all of a given element in one big Collection cluster (without maintaining the hierarchical ordering).

So far I have the following:

JMeterUtils.loadJMeterProperties(".../jmeter-3.0/bin/jmeter.properties");
JMeterUtils.setJMeterHome(".../apache-jmeter-3.0");
JMeterUtils.initLogging();
JMeterUtils.initLocale();
SaveService.loadProperties();

HashTree testPlanTree = SaveService.loadTree(new File(".../example.jmx"));

SearchByClass<ThreadGroup> threadGroups = new SearchByClass<>(ThreadGroup.class);
testPlanTree.traverse(threadGroups);
Collection<ThreadGroup> threadGroupsRes = threadGroups.getSearchResults();
for (ThreadGroup threadGroup : threadGroupsRes) {
  /* Gets me the main ThreadGroups for the test plan, but can't find a way 
  to traverse the threadGroup to find its Managers, Controllers,
  Sub-Controllers, Response Assertions, etc */
}

SearchByClass<LoopController> controllerGroups = new SearchByClass<>(LoopController.class);
testPlanTree.traverse(controllerGroups);
Collection<LoopController> loopControllers = controllerGroups.getSearchResults();
for(LoopController loopController : loopControllers){
  /* Gets every LoopController in the test plan but I can't find
    a way to determine what its parent and children elements are */
}

Our jmx file is very complex and uses several of the elements available with jmeter including Sub-Controllers and I'd ultimately like to be able to parse and re-compile the jmx with any needed changes (while maintaining the same hierarchy) but have not found many resources that fully explain the Jmeter java API.

2
There is no documentation indeed. You can try to use JMeter api (best way to learn it is to check out the source code and look at it), or just look at jmx as XML file and parse it that way (jmx file structure is fairly simple). - Kiril S.
@KirilS. Unfortunately I don't have weeks to dig in to the source code to try to determine how it's intended to work. I have also concluded that I will likely need to use XML libraries to create my own API. - user2812481
Yes, parsing jmx as xml is not too hard. It's <hashTree> all the way down :) - Kiril S.
Is there the actual source code available for JMeter Java API? That is cool! At least debugging I can probably try to figure out how to deal with the results. - Giuseppe

2 Answers

0
votes

The jmx is just an xml with < hashtree > tags. You can parse it with Jmeter java API using org.apache.jorphan.collections.HashTree class. Here is a sample.

JMeterUtils.loadJMeterProperties(jmeterHome+"/bin/jmeter.properties");
JMeterUtils.setJMeterHome(jmeterHome); 
//JMeterUtils.initLogging();// you can comment this line out to see extra log messages of i.e. DEBUG level
JMeterUtils.initLocale();  
SaveService.loadProperties();
//load the jmx file
HashTree testPlanTree = SaveService.loadTree(new File("yourJmxFile.jmx")); 
//list of keys on testPlan level
List<Object> testPlanTreeKeys= (List<Object>) testPlanTree.list();  
//access testplan hashtree
HashTree testPlanRoot=testPlanTree.get(testPlanTreeKeys.get(0));
// get the list of thread groups
List<Object> testPlanRootKeys= (List<Object>) testPlanRoot.list();
//access first thread group
HashTree threadGroupRoot=testPlanRoot.get(testPlanRootKeys.get(0));

//Iterate over thread group elements
for(Object obj : threadGroupRoot.list()){
  if( obj  instanceof HTTPSampler ) {
    // http sampler
    }
 }  
0
votes

I found a way to traverse all the thread groups. However, I, myself, have a problem in traversing all the http samplers in thread group. The iterator of http sampler gives me null all the time. Anyway, here is your answer:

public class App {
public static void main(String[] args) throws IOException {
    // LOAD EXITISTING JMETER XML
    HashTree testPlanTree = SaveService.loadTree(new File("yourJmxFile.jmx"));

    SearchByClass testPlanSearcher = new SearchByClass(TestPlan.class);
    SearchByClass threadGroupSearcher = new SearchByClass(ThreadGroup.class);
    SearchByClass httpSamplerSearcher = new SearchByClass(HTTPSampler.class);

    testPlanTree.traverse(testPlanSearcher);
    Iterator testPlanIter = testPlanSearcher.getSearchResults().iterator();
    TestPlan testPlan = (TestPlan) testPlanIter.next();

    HashTree subTreeOfTestPlan = testPlanSearcher.getSubTree(testPlan);
    subTreeOfTestPlan.traverse(threadGroupSearcher);
    Iterator threadGroupIter = threadGroupSearcher.getSearchResults().iterator();
    while(threadGroupIter.hasNext()) {
        ThreadGroup threadGroup = (ThreadGroup) threadGroupIter.next();
        //HashTree subTreeOfThreadGroup = threadGroupSearcher.getSubTree(threadGroup);
        //subTreeOfThreadGroup.traverse(httpSamplerSearcher);
        //Iterator httpSamplerIter = httpSamplerSearcher.getSearchResults().iterator();
        //while (httpSamplerIter.hasNext()) {
            //httpSamplerIter.next();
            //System.out.println("I found a http sampler");
        //} You do not need the commented code.
    }
}

}