1 // $Header: /home/cvs/jakarta-jmeter/src/protocol/java/org/apache/jmeter/protocol/java/test/JavaTest.java,v 1.14 2005/07/12 20:51:07 mstover1 Exp $ 2 /* 3 * Copyright 2003-2004 The Apache Software Foundation. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package org.apache.jmeter.protocol.java.test; 20 21 import java.io.Serializable; 22 import java.util.Iterator; 23 24 import org.apache.jmeter.config.Arguments; 25 import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient; 26 import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext; 27 import org.apache.jmeter.samplers.SampleResult; 28 import org.apache.jmeter.testelement.TestElement; 29 30 /** 31 * The <code>JavaTest</code> class is a simple sampler which is intended for 32 * use when developing test plans. The sampler generates results internally, so 33 * does not need access to any external resources such as web, ftp or LDAP 34 * servers. In addition, because the exact values of most of the SampleResult 35 * can be directly set, it is possible to easily test most Assertions that use 36 * the sample results. 37 * 38 * <p> 39 * During each sample, this client will sleep for some amount of time. The 40 * amount of time to sleep is determined from the two parameters Sleep_Time and 41 * Sleep_Mask using the formula: 42 * 43 * <pre> 44 * totalSleepTime = Sleep_Time + (System.currentTimeMillis() % Sleep_Mask) 45 * </pre> 46 * 47 * Thus, the Sleep_Mask provides a way to add a random component to the sleep 48 * time. 49 * <p> 50 * The sampler is able to define the precise values of: 51 * 52 * <pre> 53 * 54 * - responseCode 55 * - responseMessage 56 * - Label 57 * - success/fail status 58 * 59 * </pre> 60 * 61 * The elapsed time and end-time cannot be directly controlled. 62 * <p> 63 * Note: this class was derived from {@link SleepTest}. 64 * 65 * @author ANO 66 * @version $Version: 1.3 $ $Date: 2005/07/12 20:51:07 $ 67 */ 68 69 public class JavaTest extends AbstractJavaSamplerClient implements Serializable { 70 /** The base number of milliseconds to sleep during each sample. */ 71 private long sleepTime; 72 73 /** The default value of the SleepTime parameter, in milliseconds. */ 74 public static final long DEFAULT_SLEEP_TIME = 100; 75 76 /** The name used to store the SleepTime parameter. */ 77 private static final String SLEEP_NAME = "Sleep_Time"; 78 79 /** 80 * A mask to be applied to the current time in order to add a semi-random 81 * component to the sleep time. 82 */ 83 private long sleepMask; 84 85 /** The default value of the SleepMask parameter. */ 86 public static final long DEFAULT_SLEEP_MASK = 0xff; 87 88 /** Formatted string representation of the default SleepMask. */ 89 private static final String DEFAULT_MASK_STRING = "0x" + (Long.toHexString(DEFAULT_SLEEP_MASK)).toUpperCase(); 90 91 /** The name used to store the SleepMask parameter. */ 92 private static final String MASK_NAME = "Sleep_Mask"; 93 94 /** The label to store in the sample result. */ 95 private String label; 96 97 /** The default value of the Label parameter. */ 98 // private static final String LABEL_DEFAULT = "JavaTest"; 99 /** The name used to store the Label parameter. */ 100 private static final String LABEL_NAME = "Label"; 101 102 /** The response message to store in the sample result. */ 103 private String responseMessage; 104 105 /** The default value of the ResponseMessage parameter. */ 106 private static final String RESPONSE_MESSAGE_DEFAULT = ""; 107 108 /** The name used to store the ResponseMessage parameter. */ 109 private static final String RESPONSE_MESSAGE_NAME = "ResponseMessage"; 110 111 /** The response code to be stored in the sample result. */ 112 private String responseCode; 113 114 /** The default value of the ResponseCode parameter. */ 115 private static final String RESPONSE_CODE_DEFAULT = ""; 116 117 /** The name used to store the ResponseCode parameter. */ 118 private static final String RESPONSE_CODE_NAME = "ResponseCode"; 119 120 /** The sampler data (shown as Request Data in the Tree display). */ 121 private String samplerData; 122 123 /** The default value of the SamplerData parameter. */ 124 private static final String SAMPLER_DATA_DEFAULT = ""; 125 126 /** The name used to store the SamplerData parameter. */ 127 private static final String SAMPLER_DATA_NAME = "SamplerData"; 128 129 /** Holds the result data (shown as Response Data in the Tree display). */ 130 private String resultData; 131 132 /** The default value of the ResultData parameter. */ 133 private static final String RESULT_DATA_DEFAULT = ""; 134 135 /** The name used to store the ResultData parameter. */ 136 private static final String RESULT_DATA_NAME = "ResultData"; 137 138 /** The success status to be stored in the sample result. */ 139 private boolean success; 140 141 /** The default value of the Success Status parameter. */ 142 private static final String SUCCESS_DEFAULT = "OK"; 143 144 /** The name used to store the Success Status parameter. */ 145 private static final String SUCCESS_NAME = "Status"; 146 147 /** 148 * Default constructor for <code>JavaTest</code>. 149 * 150 * The Java Sampler uses the default constructor to instantiate an instance 151 * of the client class. 152 */ 153 public JavaTest() { 154 getLogger().debug(whoAmI() + "\tConstruct"); 155 } 156 157 /* 158 * Utility method to set up all the values 159 */ 160 private void setupValues(JavaSamplerContext context) { 161 162 sleepTime = context.getLongParameter(SLEEP_NAME, DEFAULT_SLEEP_TIME); 163 sleepMask = context.getLongParameter(MASK_NAME, DEFAULT_SLEEP_MASK); 164 165 responseMessage = context.getParameter(RESPONSE_MESSAGE_NAME, RESPONSE_MESSAGE_DEFAULT); 166 167 responseCode = context.getParameter(RESPONSE_CODE_NAME, RESPONSE_CODE_DEFAULT); 168 169 success = context.getParameter(SUCCESS_NAME, SUCCESS_DEFAULT).equalsIgnoreCase("OK"); 170 171 label = context.getParameter(LABEL_NAME, ""); 172 if (label.length() == 0) 173 label = context.getParameter(TestElement.NAME); // default to name 174 // of element 175 176 samplerData = context.getParameter(SAMPLER_DATA_NAME, SAMPLER_DATA_DEFAULT); 177 178 resultData = context.getParameter(RESULT_DATA_NAME, RESULT_DATA_DEFAULT); 179 } 180 181 /** 182 * Do any initialization required by this client. 183 * 184 * There is none, as it is done in runTest() in order to be able to vary the 185 * data for each sample. 186 * 187 * @param context 188 * the context to run with. This provides access to 189 * initialization parameters. 190 */ 191 public void setupTest(JavaSamplerContext context) { 192 getLogger().debug(whoAmI() + "\tsetupTest()"); 193 listParameters(context); 194 } 195 196 /** 197 * Provide a list of parameters which this test supports. Any parameter 198 * names and associated values returned by this method will appear in the 199 * GUI by default so the user doesn't have to remember the exact names. The 200 * user can add other parameters which are not listed here. If this method 201 * returns null then no parameters will be listed. If the value for some 202 * parameter is null then that parameter will be listed in the GUI with an 203 * empty value. 204 * 205 * @return a specification of the parameters used by this test which should 206 * be listed in the GUI, or null if no parameters should be listed. 207 */ 208 public Arguments getDefaultParameters() { 209 Arguments params = new Arguments(); 210 params.addArgument(SLEEP_NAME, String.valueOf(DEFAULT_SLEEP_TIME)); 211 params.addArgument(MASK_NAME, DEFAULT_MASK_STRING); 212 params.addArgument(LABEL_NAME, ""); 213 params.addArgument(RESPONSE_CODE_NAME, RESPONSE_CODE_DEFAULT); 214 params.addArgument(RESPONSE_MESSAGE_NAME, RESPONSE_MESSAGE_DEFAULT); 215 params.addArgument(SUCCESS_NAME, SUCCESS_DEFAULT); 216 params.addArgument(SAMPLER_DATA_NAME, SAMPLER_DATA_DEFAULT); 217 params.addArgument(RESULT_DATA_NAME, SAMPLER_DATA_DEFAULT); 218 return params; 219 } 220 221 /** 222 * Perform a single sample.<br> 223 * In this case, this method will simply sleep for some amount of time. 224 * 225 * This method returns a <code>SampleResult</code> object. 226 * 227 * <pre> 228 * 229 * The following fields are always set: 230 * - responseCode (default "") 231 * - responseMessage (default "") 232 * - label (set from LABEL_NAME parameter if it exists, else element name) 233 * - success (default true) 234 * 235 * </pre> 236 * 237 * The following fields are set from the user-defined parameters, if 238 * supplied: 239 * 240 * <pre> 241 * -samplerData - responseData 242 * </pre> 243 * 244 * @see org.apache.jmeter.samplers.SampleResult#sampleStart() 245 * @see org.apache.jmeter.samplers.SampleResult#sampleEnd() 246 * @see org.apache.jmeter.samplers.SampleResult#setSuccessful(boolean) 247 * @see org.apache.jmeter.samplers.SampleResult#setSampleLabel(String) 248 * @see org.apache.jmeter.samplers.SampleResult#setResponseCode(String) 249 * @see org.apache.jmeter.samplers.SampleResult#setResponseMessage(String) 250 * @see org.apache.jmeter.samplers.SampleResult#setResponseData(byte []) 251 * @see org.apache.jmeter.samplers.SampleResult#setDataType(String) 252 * 253 * @param context 254 * the context to run with. This provides access to 255 * initialization parameters. 256 * 257 * @return a SampleResult giving the results of this sample. 258 */ 259 public SampleResult runTest(JavaSamplerContext context) { 260 setupValues(context); 261 262 SampleResult results = new SampleResult(); 263 264 results.setResponseCode(responseCode); 265 results.setResponseMessage(responseMessage); 266 results.setSampleLabel(label); 267 268 if (samplerData != null && samplerData.length() > 0) { 269 results.setSamplerData(samplerData); 270 } 271 272 if (resultData != null && resultData.length() > 0) { 273 results.setResponseData(resultData.getBytes()); 274 results.setDataType(SampleResult.TEXT); 275 } 276 277 // Record sample start time. 278 results.sampleStart(); 279 280 long sleep = sleepTime; 281 if (sleepTime > 0 && sleepMask > 0) { // / Only do the calculation if 282 // it is needed 283 long start = System.currentTimeMillis(); 284 // Generate a random-ish offset value using the current time. 285 sleep = sleepTime + (start % sleepMask); 286 } 287 288 try { 289 // Execute the sample. In this case sleep for the 290 // specified time, if any 291 if (sleep > 0) { 292 Thread.sleep(sleep); 293 } 294 results.setSuccessful(success); 295 } catch (InterruptedException e) { 296 getLogger().warn("JavaTest: interrupted."); 297 results.setSuccessful(true); 298 } catch (Exception e) { 299 getLogger().error("JavaTest: error during sample", e); 300 results.setSuccessful(false); 301 } finally { 302 // Record end time and populate the results. 303 results.sampleEnd(); 304 } 305 306 if (getLogger().isDebugEnabled()) { 307 getLogger().debug(whoAmI() + "\trunTest()" + "\tTime:\t" + results.getTime()); 308 listParameters(context); 309 } 310 311 return results; 312 } 313 314 /** 315 * Do any clean-up required by this test. In this case no clean-up is 316 * necessary, but some messages are logged for debugging purposes. 317 * 318 * @param context 319 * the context to run with. This provides access to 320 * initialization parameters. 321 */ 322 public void teardownTest(JavaSamplerContext context) { 323 getLogger().debug(whoAmI() + "\tteardownTest()"); 324 listParameters(context); 325 } 326 327 /** 328 * Dump a list of the parameters in this context to the debug log. 329 * 330 * @param context 331 * the context which contains the initialization parameters. 332 */ 333 private void listParameters(JavaSamplerContext context) { 334 if (getLogger().isDebugEnabled()) { 335 Iterator argsIt = context.getParameterNamesIterator(); 336 while (argsIt.hasNext()) { 337 String name = (String) argsIt.next(); 338 getLogger().debug(name + "=" + context.getParameter(name)); 339 } 340 } 341 } 342 343 /** 344 * Generate a String identifier of this test for debugging purposes. 345 * 346 * @return a String identifier for this test instance 347 */ 348 private String whoAmI() { 349 StringBuffer sb = new StringBuffer(); 350 sb.append(Thread.currentThread().toString()); 351 sb.append("@"); 352 sb.append(Integer.toHexString(hashCode())); 353 return sb.toString(); 354 } 355 356 }