Introduction

ATS provides some ready-to-use parameter generation patterns which fulfill most of the needs. But still, in reality, there are cases when you need to implement your very own logic.

Here we show such a pattern that is not available with the ATS distribution but can be used as a starting point for creating your own custom pattern.

The code might look somewhat longer compared to most examples in this user guide, but:

  • you will rarely hit such need
  • code is not difficult
  • half of the code are comments which help understanding it



What does this custom example do?

Our example demonstrates how to create simple words. These words have some length and letters as defined by the test.

Let's say you set all letters to be 7 characters long and all characters to fall in the range between P and W . The result is words like UQQRUPT, SQUPTQS, SVUURQP, etc

All values will be provided depending on the specified parameter provider level



The test code

Here is how our test will look like

    private static final String PARAMETRIZED_PARAM = "<parameter name>";

    @Test
    public void myTest() {

		// create a load client and provide the loader it works on
		LoadClient loader = new LoadClient( LOADER_ADDRESS );
 
		// set some threading pattern
		loader.setThreadingPattern( new AllAtOncePattern( 10, true, 50, 1000 ) );

		// call our custom parameter configurator
		// the letters will be changing from 'P' to 'W'
		// there will be 7 repeated letters in each produced value
        loader.addParameterDataConfigurator( new RandomWordCreatorDataConfig( PARAMETRIZED_PARAM, 'P', 'W', 7, ParameterProviderLevel.PER_INVOCATION ) );

		// give a name to your action queue
        loader.startQueueing( "Test custom parametrization" );

		// list the actions, one of them must have an input parameter that match the one we have parametrized above
		// ...
		// ...

		// now execute the requested action queue according to the threading pattern
        loader.executeQueuedActions();
    }

As you can see this test code looks as easy(or difficult) as any other example with the already available parameter generation patterns

Now in order to make it work you need to make your own instances of CustomParameterDataConfig and CustomParameterDataProvider classes



Example of custom data configuration

Please have a look at the code and the comments inside.

We basically remember the configuration as comes from the test. We also take care of distributing the values in case of using more than one loader.


import com.axway.ats.agent.core.model.EvenLoadDistributingUtils;
import com.axway.ats.agent.core.threading.data.CustomParameterDataProvider;
import com.axway.ats.agent.core.threading.data.config.CustomParameterDataConfig;
import com.axway.ats.agent.core.threading.data.config.ParameterDataConfig;
import com.axway.ats.agent.core.threading.data.config.ParameterProviderLevel;

/**
 * Example of custom data configuration. 
 * It creates words by filling it with random characters.
 */
public class RandomWordCreatorDataConfig extends CustomParameterDataConfig {
    private static final long serialVersionUID = 1L;

    /**
     * @param parameterName name of action parameter
     * @param startChar the lowest possible character as defined in the ASCII table
     * @param endChar the highest possible character as defined in the ASCII table
     * @param numberChars how long is a word 
     */
    public RandomWordCreatorDataConfig( String parameterName, char startChar, char endChar, int numberChars ) {
        this( parameterName, startChar, endChar, numberChars, ParameterProviderLevel.PER_THREAD_STATIC );
    }

    /**
     * @param parameterName name of action parameter
     * @param startChar the lowest possible character as defined in the ASCII table
     * @param endChar the highest possible character as defined in the ASCII table
     * @param numberChars how long is a word 
     * @param parameterProviderLevel parameter provider level
     */
    public RandomWordCreatorDataConfig( String parameterName, char startChar, char endChar, int numberChars, ParameterProviderLevel parameterProviderLevel ) {
        super( parameterName, new HashMap<String, String>(), parameterProviderLevel );

        // save these control tokens as given from the test
        controlTokens.put( RandomWordCreatorDataProvider.START_CHAR, String.valueOf( startChar ) );
        controlTokens.put( RandomWordCreatorDataProvider.END_CHAR, String.valueOf( endChar ) );
        controlTokens.put( RandomWordCreatorDataProvider.NUMBER_CHARS, String.valueOf( numberChars ) );
    }

    /**
     * This method is called if we run performance tests using more than one ATS Loader
     * 
     * Here we have to properly split the configuration so at the side of the Tested Application it makes no 
     * difference if we are using one or many Loaders
     */
    @Override
    public List<ParameterDataConfig> distribute( int numberAgents ) {

        List<ParameterDataConfig> distributedParameterProviders = new ArrayList<ParameterDataConfig>();

        // read the control tokens as given from the test
        char startChar = controlTokens.get( RandomWordCreatorDataProvider.START_CHAR ).toCharArray()[0];
        char endChar = controlTokens.get( RandomWordCreatorDataProvider.END_CHAR ).toCharArray()[0];
        int numberChars = Integer.parseInt( controlTokens.get( RandomWordCreatorDataProvider.NUMBER_CHARS ) );

        int[] distributionValues = new EvenLoadDistributingUtils().getEvenLoad( endChar - startChar, numberAgents );

        for( int i = 0; i < numberAgents; i++ ) {
            distributedParameterProviders.add( new RandomWordCreatorDataConfig( this.parameterName, 
                                                                                startChar,
                                                                                ( char ) ( startChar + distributionValues[i] ),
                                                                                numberChars,
                                                                                this.parameterProviderLevel ) );
            startChar = ( char ) ( startChar + distributionValues[i] );
        }
        return distributedParameterProviders;
    }

    /**
     * Give the name of the data provider class
     */
    @Override
    public Class<? extends CustomParameterDataProvider> getDataProviderClass() {
        return RandomWordCreatorDataProvider.class;
    }
}



Example of a custom data provider

Please have a look at the code and the comments inside.

The doInitialize() method reads the configuration as comes from the test.

The createNewWord method generates each value when requested. Here the parameter provider level plays its role, you must make your logic working in all cases.

import com.axway.ats.agent.core.action.ArgumentValue;
import com.axway.ats.agent.core.threading.data.CustomParameterDataProvider;
import com.axway.ats.agent.core.threading.data.config.ParameterProviderLevel;
import com.axway.ats.agent.core.threading.exceptions.ParameterDataProviderInitalizationException;

/**
 * Example of custom parameter provider implementation.
 * 
 * This provider returns a random word.
 */
public class RandomWordCreatorDataProvider extends CustomParameterDataProvider {

    public final static String START_CHAR   = "START_CHAR";
    public final static String END_CHAR     = "END_CHAR";
    public final static String NUMBER_CHARS = "NUMBER_CHARS";

    private char               startChar;                    // the lowest possible character as defined in the ASCII table
    private char               endChar;                      // the highest possible character as defined in the ASCII table
    private int                numberChars;                  // how long is a word 

    public RandomWordCreatorDataProvider( String parameterName, Map<String, String> controlTokens,
                                          ParameterProviderLevel parameterProviderLevel ) {
        super( parameterName, controlTokens, parameterProviderLevel );
    }

    @Override
    protected void doInitialize() throws ParameterDataProviderInitalizationException {

        // read the control tokens as given from the test
        this.startChar = controlTokens.get( START_CHAR ).toCharArray()[0];
        this.endChar = controlTokens.get( END_CHAR ).toCharArray()[0];
        this.numberChars = Integer.parseInt( controlTokens.get( NUMBER_CHARS ) );
    }

    // This method is called if the "parameter provider level" is set to "per invocation"
    @Override
    protected ArgumentValue generateNewValuePerInvocation( List<ArgumentValue> alreadyResolvedValues ) {

        // use a new randomizer on each call
        String newWord = createNewWord( new Random() );
        return new ArgumentValue( parameterName, newWord );
    }

    // This method will be called if the "parameter provider level" is set to "per thread"
    @Override
    protected ArgumentValue generateNewValuePerThread( long currentThreadId,
                                                       List<ArgumentValue> alreadyResolvedValues ) {

        // check whether there is a randomizer already used by this thread
        Random randomizer = ( Random ) perThreadObjects.get( currentThreadId );

        if( randomizer == null ) {
            randomizer = new Random();
            perThreadObjects.put( currentThreadId, randomizer );
        }

        String newWord = createNewWord( randomizer );
        return new ArgumentValue( parameterName, newWord );
    }

    // This method will be called if the "parameter provider level" is set to "per thread static"
    @Override
    protected ArgumentValue generateNewValuePerThreadStatic( long currentThreadId,
                                                             List<ArgumentValue> alreadyResolvedValues ) {

        // check whether there is a word already assigned to this thread
        String wordForThisThread = ( String ) perThreadObjects.get( currentThreadId );

        if( wordForThisThread == null ) {
            // make a new word and assign it to this thread
            wordForThisThread = createNewWord( new Random() );
            perThreadObjects.put( currentThreadId, wordForThisThread );
        }

        return new ArgumentValue( parameterName, wordForThisThread );
    }

    // Returns a new word with content and length as defined in the test
    private String createNewWord( Random randomizer ) {

        String newWord = new String();
        for( int i = 0; i < numberChars; i++ ) {
            char newChar = ( char ) ( startChar + randomizer.nextInt( endChar - startChar ) );
            newWord = newWord + new Character( newChar ).toString();
        }
        return newWord;
    }
}



Back to parent page

Go to Table of Contents