alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

JMeter example source code file (ThroughputController.java)

This example JMeter source code file (ThroughputController.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - JMeter tags/keywords

bynumber, floatproperty, integerproperty, integerproperty, io, jmeterproperty, mutableinteger, mutableinteger, non-nls-1, non-nls-1, override, string, string, stringproperty, throughputcontroller

The JMeter ThroughputController.java source code

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package org.apache.jmeter.control;

import java.io.Serializable;

import org.apache.jmeter.engine.event.LoopIterationEvent;
import org.apache.jmeter.engine.event.LoopIterationListener;
import org.apache.jmeter.samplers.Sampler;
import org.apache.jmeter.testelement.TestListener;
import org.apache.jmeter.testelement.property.BooleanProperty;
import org.apache.jmeter.testelement.property.FloatProperty;
import org.apache.jmeter.testelement.property.IntegerProperty;
import org.apache.jmeter.testelement.property.JMeterProperty;
import org.apache.jmeter.testelement.property.StringProperty;

/**
 * This class represents a controller that can control the number of times that
 * it is executed, either by the total number of times the user wants the
 * controller executed (BYNUMBER) or by the percentage of time it is called
 * (BYPERCENT)
 *
 * The current implementation executes the first N samples (BYNUMBER)
 * or the last N% of samples (BYPERCENT).
 */
public class ThroughputController extends GenericController implements Serializable, LoopIterationListener,
        TestListener {

    private static final long serialVersionUID = 233L;

    public static final int BYNUMBER = 0;

    public static final int BYPERCENT = 1;

    private static final String STYLE = "ThroughputController.style";// $NON-NLS-1$

    private static final String PERTHREAD = "ThroughputController.perThread";// $NON-NLS-1$

    private static final String MAXTHROUGHPUT = "ThroughputController.maxThroughput";// $NON-NLS-1$

    private static final String PERCENTTHROUGHPUT = "ThroughputController.percentThroughput";// $NON-NLS-1$

    private static class MutableInteger{
        private int integer;
        MutableInteger(int value){
            integer=value;
        }
        int incr(){
            return ++integer;
        }
        public int intValue() {
            return integer;
        }
    }

    // These items are shared between threads in a group by the clone() method
    // They are initialised by testStarted() so don't need to be serialised
    private transient MutableInteger globalNumExecutions;

    private transient MutableInteger globalIteration;

    private String counterLock = ""; // ensure counts are updated correctly
    // Need to use something that is serializable, so Object is no use

    /**
     * Number of iterations on which we've chosen to deliver samplers.
     */
    private int numExecutions = 0;

    /**
     * Index of the current iteration. 0-based.
     */
    private int iteration = -1;

    /**
     * Whether to deliver samplers on this iteration.
     */
    private boolean runThisTime;

    public ThroughputController() {
        setStyle(BYNUMBER);
        setPerThread(true);
        setMaxThroughput(1);
        setPercentThroughput(100);
        runThisTime = false;
    }

    public void setStyle(int style) {
        setProperty(new IntegerProperty(STYLE, style));
    }

    public int getStyle() {
        return getPropertyAsInt(STYLE);
    }

    public void setPerThread(boolean perThread) {
        setProperty(new BooleanProperty(PERTHREAD, perThread));
    }

    public boolean isPerThread() {
        return getPropertyAsBoolean(PERTHREAD);
    }

    public void setMaxThroughput(int maxThroughput) {
        setProperty(new IntegerProperty(MAXTHROUGHPUT, maxThroughput));
    }

    public void setMaxThroughput(String maxThroughput) {
        setProperty(new StringProperty(MAXTHROUGHPUT, maxThroughput));
    }

    public String getMaxThroughput() {
        return getPropertyAsString(MAXTHROUGHPUT);
    }

    protected int getMaxThroughputAsInt() {
        JMeterProperty prop = getProperty(MAXTHROUGHPUT);
        int retVal = 1;
        if (prop instanceof IntegerProperty) {
            retVal = (((IntegerProperty) prop).getIntValue());
        } else {
            try {
                retVal = Integer.parseInt(prop.getStringValue());
            } catch (NumberFormatException e) {
            }
        }
        return retVal;
    }

    public void setPercentThroughput(float percentThroughput) {
        setProperty(new FloatProperty(PERCENTTHROUGHPUT, percentThroughput));
    }

    public void setPercentThroughput(String percentThroughput) {
        setProperty(new StringProperty(PERCENTTHROUGHPUT, percentThroughput));
    }

    public String getPercentThroughput() {
        return getPropertyAsString(PERCENTTHROUGHPUT);
    }

    protected float getPercentThroughputAsFloat() {
        JMeterProperty prop = getProperty(PERCENTTHROUGHPUT);
        float retVal = 100;
        if (prop instanceof FloatProperty) {
            retVal = (((FloatProperty) prop).getFloatValue());
        } else {
            try {
                retVal = Float.parseFloat(prop.getStringValue());
            } catch (NumberFormatException e) {
            }
        }
        return retVal;
    }

    private int getExecutions() {
        if (!isPerThread()) {
            synchronized (counterLock) {
                return globalNumExecutions.intValue();
            }
        }
        return numExecutions;
    }

    /**
     * @see org.apache.jmeter.control.Controller#next()
     */
    @Override
    public Sampler next() {
        if (runThisTime) {
            return super.next();
        }
        return null;
    }

    /**
     * Decide whether to return any samplers on this iteration.
     */
    private boolean decide(int executions, int iterations) {
        if (getStyle() == BYNUMBER) {
            return executions < getMaxThroughputAsInt();
        }
        return (100.0 * executions + 50.0) / (iterations + 1) < getPercentThroughputAsFloat();
    }

    /**
     * @see org.apache.jmeter.control.Controller#isDone()
     */
    @Override
    public boolean isDone() {
        if (subControllersAndSamplers.size() == 0) {
            return true;
        } else if (getStyle() == BYNUMBER && getExecutions() >= getMaxThroughputAsInt()
                && current >= getSubControllers().size()) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Object clone() {
        ThroughputController clone = (ThroughputController) super.clone();
        clone.numExecutions = numExecutions;
        clone.iteration = iteration;
        clone.runThisTime = false;
        // Ensure global counters and lock are shared across threads in the group
        clone.globalIteration = globalIteration;
        clone.globalNumExecutions = globalNumExecutions;
        clone.counterLock = counterLock;
        return clone;
    }

    public void iterationStart(LoopIterationEvent iterEvent) {
        if (!isPerThread()) {
            synchronized (counterLock) {
                globalIteration.incr();
                runThisTime = decide(globalNumExecutions.intValue(), globalIteration.intValue());
                if (runThisTime) {
                    globalNumExecutions.incr();
                }
            }
        } else {
            iteration++;
            runThisTime = decide(numExecutions, iteration);
            if (runThisTime) {
                numExecutions++;
            }
        }
    }

    public void testStarted() {
        synchronized (counterLock) {
            globalNumExecutions = new MutableInteger(0);
            globalIteration = new MutableInteger(-1);
        }
    }

    public void testStarted(String host) {
        testStarted();
    }

    public void testEnded() {
    }

    public void testEnded(String host) {
    }

    public void testIterationStart(LoopIterationEvent event) {
    }
}

Other JMeter examples (source code examples)

Here is a short list of links related to this JMeter ThroughputController.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.