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.
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
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