razrog
razrog

Reputation: 41

JMeter From Java Code - How to add ConstantThroughputTimer to my Test

I have a Class which demonstrate a JMeter test from Java code.

The Object of the test is to set N requests per second.

I want to add a ConstantThroughputTimer to my test in order to set the max RPS(requests per second) JMeter is making.

Created one in the gui and its working well, but i want to run it from a java code.

Right now i have 2 issues :

  1. I don't know how to set the thread group 'loop count' forever. (see screenshot)
  2. I wasn't able to add the ConstantThroughputTimer to my test plan.

I've searched and i couldn't find any documentation about it , nor code example.

Any Help would be very much appreciated.

My Code:

public static void main(String[] args) {
    StandardJMeterEngine jMeterEngine = new StandardJMeterEngine();
    //Setting JMeter Properties
    File properties = JmeterUtils.getPropertiesFile();
    File home = JmeterUtils.getHomePath();
    JMeterUtils.setJMeterHome(home.getPath());
    JMeterUtils.loadJMeterProperties(properties.getPath());
    JMeterUtils.initLocale();

    //Creating HashTreeTestPlan
    HashTree testPlanTree = new HashTree();

    //Creating HttpSampler
    HTTPSamplerProxy sampler = new HTTPSamplerProxy();
    sampler.setMethod("GET");
    sampler.setDomain("example.com");
    sampler.setUseKeepAlive(true);
    sampler.setFollowRedirects(true);
    sampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
    sampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
    sampler.setEnabled(true);

    //Creating LoopController
    LoopController loopController = new LoopController();
    loopController.setContinueForever(true);
    loopController.setLoops(10000);
    loopController.setFirst(true);
    loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
    loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
    loopController.initialize();
    loopController.setEnabled(true);

    //Creating the number of Threads (clients)
    ThreadGroup threadGroup = new ThreadGroup();
    threadGroup.setName("threadGroup");
    threadGroup.setNumThreads(10);
    threadGroup.setScheduler(true);
    threadGroup.setRampUp(0);
    threadGroup.setDuration(60);
    threadGroup.setSamplerController(loopController);
    threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
    threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
    threadGroup.setEnabled(true);



    //Adding Constant Throughput Timer - This is what i want to add
    ConstantThroughputTimer timer = new ConstantThroughputTimer();
    timer.setProperty(TestElement.TEST_CLASS, ConstantThroughputTimer.class.getName());
    timer.setName("constantTimer");
    double rpsCalc = 10 * 60;
    timer.setThroughput(rpsCalc);
    timer.setEnabled(true);
    timer.setCalcMode(2);


    //NOT WORKING// 
    //NOT WORKING// 
    threadGroup.addTestElement(timer);



    //Test Plan
    TestPlan testPlan = new TestPlan("Test Plan");
    testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
    testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
    testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());

    // Construct Test Plan from previously initialized elements
    testPlanTree.add(testPlan);

    jMeterEngine.configure(testPlanTree);

    try {
        jMeterEngine.runTest();
    } catch (JMeterEngineException e) {
        e.printStackTrace();
    }
}

Upvotes: 1

Views: 1183

Answers (3)

razrog
razrog

Reputation: 41

Full working Solution

My Run Method

public void run(String domain, int rps, int durationInSeconds, String host){
    StandardJMeterEngine jMeterEngine = new StandardJMeterEngine();

    //Setting JMeter Properties
    File properties = JmeterUtils.getPropertiesFile();
    File home = JmeterUtils.getHomePath();
    JMeterUtils.setJMeterHome(home.getPath());
    JMeterUtils.loadJMeterProperties(properties.getPath());
    JMeterUtils.initLocale();

    //Creating HashTreeTestPlan
    HashTree testPlanTree = new HashTree();

    //Creating HttpSampler
    HTTPSamplerProxy httpSamplerProxy = JmeterUtils.createHttpSamplerGet(domain);

    //Creating Header Manager
    HeaderManager headerManager = JmeterUtils.createHeaderManager(host);

    //Creating LoopController
    LoopController loopController = JmeterUtils.createLoopController(-1, true);

    //Creating the number of Threads (clients)
    ThreadGroup threadGroup = JmeterUtils.createThreadGroup(domain, rps, durationInSeconds, loopController);

    //Adding Request Manager To requests HashTree
    HashTree requestHashTree = new HashTree();
    requestHashTree.add(httpSamplerProxy, headerManager);

    //Creating Throughput Timer - Controls the RPS
    ConstantThroughputTimer timer = JmeterUtils.createTimer(rps);

    //Creating Test Plan
    TestPlan testPlan = JmeterUtils.createTestPlan(domain);

    // Construct Test Plan from previously initialized elements
    testPlanTree.add(testPlan);
    HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
    threadGroupHashTree.add(requestHashTree);
    threadGroupHashTree.add(timer);

    //Configuring the Engine & Running the Test
    jMeterEngine.configure(testPlanTree);
    jMeterEngine.runTest();

}

My JmeterUtils

public class JmeterUtils {

private static final File PROPERTIES_FILE = new File(System.getProperty("user.dir") + "/testdata/JMeter/bin/jmeter.properties");
private static final File HOME_PATH = new File(System.getProperty("user.dir") + "/testdata/JMeter");

static HeaderManager createHeaderManager(String host){
    HeaderManager headerManager = new HeaderManager();
    if(host != null){
        headerManager.add(new Header("Host",host));
    }
    headerManager.add(new Header("Connection", "Close"));
    headerManager.add(new Header("Cache-Control", "max-age=0"));
    headerManager.add(new Header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.52 Safari/536.5"));
    headerManager.setProperty(TestElement.TEST_CLASS, HeaderManager.class.getName());
    headerManager.setProperty(TestElement.GUI_CLASS, HeaderPanel.class.getName());
    headerManager.setEnabled(true);
    return headerManager;
}

static HTTPSamplerProxy createHttpSamplerGet(String domain){
    HTTPSamplerProxy sampler = new HTTPSamplerProxy();
    sampler.setMethod("GET");
    sampler.setDomain(domain);
    sampler.setUseKeepAlive(true);
    sampler.setFollowRedirects(true);
    sampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
    sampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
    sampler.setEnabled(true);
    return sampler;
}

static ThreadGroup createThreadGroup(String name, int numOfThreads, int durationInSeconds, LoopController loopController){
    ThreadGroup threadGroup = new ThreadGroup();
    threadGroup.setName(name);
    threadGroup.setNumThreads(numOfThreads);
    threadGroup.setScheduler(true);
    threadGroup.setRampUp(0);
    threadGroup.setDuration(durationInSeconds);
    threadGroup.setSamplerController(loopController);
    threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
    threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
    threadGroup.setEnabled(true);

    return threadGroup;
}

static LoopController createLoopController(int numOfLoops,boolean continueForever){
    LoopController loopController = new LoopController();
    if(continueForever){
        loopController.setLoops(-1);
    }
    else{
        loopController.setLoops(numOfLoops);
    }
    loopController.setFirst(true);
    loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
    loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
    loopController.initialize();
    loopController.setEnabled(true);

    return loopController;
}

static ConstantThroughputTimer createTimer(int rps){
    ConstantThroughputTimer timer = new ConstantThroughputTimer();
    long rpsCalc = rps * 60;
    timer.setProperty("throughput", rpsCalc);
    timer.setProperty("calcMode", 2);
    timer.setCalcMode(2);
    timer.setThroughput(rpsCalc);
    timer.setEnabled(true);
    timer.setProperty(TestElement.TEST_CLASS, ConstantThroughputTimer.class.getName());
    timer.setProperty(TestElement.GUI_CLASS, TestBeanGUI.class.getName());
    return timer;
}

static TestPlan createTestPlan(String domain){
    TestPlan testPlan = new TestPlan("Traffic Generator\t[" + domain + "]");
    testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
    testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
    testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());
    return testPlan;
}


static File getPropertiesFile(){
    return PROPERTIES_FILE;
}
static File getHomePath(){
    return HOME_PATH;
}

}

Upvotes: 2

Yuri G
Yuri G

Reputation: 1213

Well, according to documentation:

Timers are only processed in conjunction with a sampler. A timer which is not in the same scope as a sampler will not be processed at all.

Since you only have one sampler, and you actually need this timer to be applied right on it, then

To apply a timer to a single sampler, add the timer as a child element of the sampler. The timer will be applied before the sampler is executed. To apply a timer after a sampler, either add it to the next sampler, or add it as the child of a Test Action Sampler.

Try this, perhaps? I mean, add the timer directly to the sampler.

PS Although it looks already legit to me, at least in usual JMeter GUI perspective. Not sure what the problem is.

PPS I guess, what can be done here, if you really dedicated to nail it - you can save your plan as the .jmx, then do the same in JMeter GUI - and compare.

Upvotes: 0

Dmitri T
Dmitri T

Reputation: 168072

  1. To configure Thread Group to run forever:

    LoopController 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();    
    
  2. To configure Constant Throughput Timer:

    ConstantThroughputTimer ctt = new ConstantThroughputTimer();
    ctt.setName("Constant Throughput Timer");
    ctt.setProperty("throughput", 60 * 10);
    ctt.setProperty("calcMode", 2);
    ctt.setCalcMode(2);
    ctt.setProperty(TestElement.TEST_CLASS, ConstantThroughputTimer.class.getName());
    ctt.setProperty(TestElement.GUI_CLASS, TestBeanGUI.class.getName());
    
  3. For more information see:

Upvotes: 0

Related Questions