JMeter из Java-кода - как добавить ConstantThroughputTimer в мой тест

У меня есть класс, который демонстрирует тест JMeter из кода Java.

Цель теста - установить N запросов в секунду.

Я хочу добавить ConstantThroughputTimer к моему тесту, чтобы установить максимальное число запросов в секунду (запросов в секунду), которое выполняет JMeter.

Создал один в графическом интерфейсе, и он работает хорошо, но я хочу запустить его из кода Java.

Прямо сейчас у меня есть 2 вопроса:

  1. Я не знаю, как установить группу потоков "счетчик циклов" навсегда. (см. скриншот)
  2. Я не смог добавить ConstantThroughputTimer в свой план тестирования.

Я искал, и я не мог найти ни документацию об этом, ни пример кода.

Любая помощь будет очень высоко ценится.

Мой код:

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();
    }
}

3 ответа

Решение

Полное рабочее решение

Мой метод бега

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();

}

Мой 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;
}

}

Ну, согласно документации:

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.

Так как у вас есть только один сэмплер, и вам нужен этот таймер, тогда

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.

Попробуйте это, возможно? Я имею в виду, добавить таймер непосредственно в сэмплер.

PS Хотя это выглядит уже законным для меня, по крайней мере, в обычной перспективе JMeter GUI. Не уверен, в чем проблема.

PPS Полагаю, что здесь можно сделать, если вы действительно посвятили себя этому - вы можете сохранить свой план в формате.jmx, затем сделать то же самое в графическом интерфейсе JMeter - и сравнить.

  1. Чтобы настроить поток группы для вечной работы:

    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. Чтобы настроить постоянный таймер пропускной способности:

    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. Для получения дополнительной информации см.:

Другие вопросы по тегам