0
votes

I am constructing a .jmx file for jmeter GUI from Java. The .jmx only compose by http proxy samplers and threads groups. Both thread groups and proxy samplers are constructed based on a list, and ,thus, they are being arranged with a certain order. However, my problem is that the constructed .jmx has completely wrong order when comparing with the list.

I have read and try "Five Ways To Launch a JMeter Test without Using the JMeter GUI". What I did is trying to generalize the "Creating a New JMeter Test Purely in Java" to multiple thread groups and http proxy samplers. Here is the minimum code that I have worked on:

public static void createJmx(ArrayList<ArrayList<String>> calls, ArrayList<HashMap<String, String>> httpSamplerList) throws Exception {
        // get log file length
        int numberOfCalls = calls.size();
        int numberOfhttpSampler = httpSamplerList.size();

        // Engine
        StandardJMeterEngine jm = new StandardJMeterEngine();
        String jmeterHome = "D:\\Jenkins-Global-Workspace\\apache-jmeter-5.1.1";
        // jmeter.properties
        JMeterUtils.setJMeterHome(jmeterHome);
        JMeterUtils.loadJMeterProperties("D:\\Jenkins-Global-Workspace\\apache-jmeter-5.1.1\\bin\\jmeter.properties");

        JMeterUtils.initLogging();
        JMeterUtils.initLocale();

        // Create HashTree structure

        HashTree testPlanTree = new HashTree();
        TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");
        testPlanTree.add(testPlan);
        HTTPSamplerProxy examplecomSampler = null;
        LoopController loopController;
        ThreadGroup threadGroup = null;
        HashTree threadGroupHashTree = null;
        int j=0;
        for (int i = 0; i < numberOfCalls; i++) {
            if (calls.get(i).size() == 3) {
                System.out.println(calls.get(i));
                loopController = new LoopController();
                loopController.setLoops(1);
                loopController.setFirst(true);
                loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
                loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
                loopController.initialize();

                threadGroup = new ThreadGroup();
                threadGroup.setName(calls.get(i).get(1));
                threadGroup.setNumThreads(1);
                threadGroup.setRampUp(1);
                threadGroup.setSamplerController(loopController);
                threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
                threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
                testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
                testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
                testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());

                threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
            }
            else {
                System.out.println(calls.get(i));
                examplecomSampler = new HTTPSamplerProxy();
                examplecomSampler.setDomain("example.com");
                examplecomSampler.setPort(80);
                examplecomSampler.setPath("/");
                examplecomSampler.setMethod("GET");
                examplecomSampler.setName(Integer.toString(j)); // currently use a integer number naming as test
                examplecomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
                examplecomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
                threadGroupHashTree.add(examplecomSampler);
                j++;
            }
        }
//    // save generated test plan to JMeter's .jmx file format
    SaveService.saveTree(testPlanTree, new FileOutputStream(".\\test.jmx"));
//        
    }

I am using a variable j to keep track the order of http sampler , but some http samplers are complete in wrong wrong order.

Does some one know why and how to fix it?

cheers

1
I don't know the JMeter api but "HashTree" sounds like it's unordered and thus neither name nor insertion order might have any effect. - Thomas
I don't think that's true, since it is wrote everywhere in the jmx file of jmeter. - Alex
Side note: instead of for (int i = 0; i < numberOfCalls; i++) you could use for(ArrayList<String> elementList : calls) to get rid of all those calls.get(i). Additionally, you're only (re)initializing threadGroupHashTree if calls.get(i).size() == 3 - what if the sizes don't match that, e.g. if the first nested list has more or less elements? - Thomas
@Thomas Thanks for the side note. Basically, I create the array list from a log file , in which there is a test name, group, and number (thus 3 elements) for every starting unit test, and there are http requests with method, and number (thus 2 elements).in the following. I parse the log file into this array list, so it shouldn't happen the scenario you just metioned. - Alex
@Thomas your intuition is right.......HashTree does not support order functionality. Yet, there is a ListedHashTree provided in Jmeter API. I changed to the HashTree to ListedHashTree and ,then, everything is in order, LOL. - Alex

1 Answers

0
votes

For those who stumbles to this post. If you have multiple modules in a hash tree and you want them to be in the same order as you add them to the tree. Please use

org.apache.jorphan.collections.ListedHashTree;

instead of

org.apache.jorphan.collections.HashTree;