001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.protocol.java.test;
020:
021: import java.io.Serializable;
022: import java.util.Iterator;
023:
024: import org.apache.jmeter.config.Arguments;
025: import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
026: import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
027: import org.apache.jmeter.samplers.SampleResult;
028: import org.apache.jmeter.testelement.TestElement;
029:
030: /**
031: * The <code>JavaTest</code> class is a simple sampler which is intended for
032: * use when developing test plans. The sampler generates results internally, so
033: * does not need access to any external resources such as web, ftp or LDAP
034: * servers. In addition, because the exact values of most of the SampleResult
035: * can be directly set, it is possible to easily test most Assertions that use
036: * the sample results.
037: *
038: * <p>
039: * During each sample, this client will sleep for some amount of time. The
040: * amount of time to sleep is determined from the two parameters Sleep_Time and
041: * Sleep_Mask using the formula:
042: *
043: * <pre>
044: * totalSleepTime = Sleep_Time + (System.currentTimeMillis() % Sleep_Mask)
045: * </pre>
046: *
047: * Thus, the Sleep_Mask provides a way to add a random component to the sleep
048: * time.
049: * <p>
050: * The sampler is able to define the precise values of:
051: *
052: * <pre>
053: *
054: * - responseCode
055: * - responseMessage
056: * - Label
057: * - success/fail status
058: *
059: * </pre>
060: *
061: * The elapsed time and end-time cannot be directly controlled.
062: * <p>
063: * Note: this class was derived from {@link SleepTest}.
064: *
065: * @author ANO
066: * @version $Version: 1.3 $ $Date: 2007-01-07 18:10:21 +0000 (Sun, 07 Jan 2007) $
067: */
068:
069: public class JavaTest extends AbstractJavaSamplerClient implements
070: Serializable {
071: /** The base number of milliseconds to sleep during each sample. */
072: private long sleepTime;
073:
074: /** The default value of the SleepTime parameter, in milliseconds. */
075: public static final long DEFAULT_SLEEP_TIME = 100;
076:
077: /** The name used to store the SleepTime parameter. */
078: private static final String SLEEP_NAME = "Sleep_Time";
079:
080: /**
081: * A mask to be applied to the current time in order to add a semi-random
082: * component to the sleep time.
083: */
084: private long sleepMask;
085:
086: /** The default value of the SleepMask parameter. */
087: public static final long DEFAULT_SLEEP_MASK = 0xff;
088:
089: /** Formatted string representation of the default SleepMask. */
090: private static final String DEFAULT_MASK_STRING = "0x"
091: + (Long.toHexString(DEFAULT_SLEEP_MASK)).toUpperCase();
092:
093: /** The name used to store the SleepMask parameter. */
094: private static final String MASK_NAME = "Sleep_Mask";
095:
096: /** The label to store in the sample result. */
097: private String label;
098:
099: /** The default value of the Label parameter. */
100: // private static final String LABEL_DEFAULT = "JavaTest";
101: /** The name used to store the Label parameter. */
102: private static final String LABEL_NAME = "Label";
103:
104: /** The response message to store in the sample result. */
105: private String responseMessage;
106:
107: /** The default value of the ResponseMessage parameter. */
108: private static final String RESPONSE_MESSAGE_DEFAULT = "";
109:
110: /** The name used to store the ResponseMessage parameter. */
111: private static final String RESPONSE_MESSAGE_NAME = "ResponseMessage";
112:
113: /** The response code to be stored in the sample result. */
114: private String responseCode;
115:
116: /** The default value of the ResponseCode parameter. */
117: private static final String RESPONSE_CODE_DEFAULT = "";
118:
119: /** The name used to store the ResponseCode parameter. */
120: private static final String RESPONSE_CODE_NAME = "ResponseCode";
121:
122: /** The sampler data (shown as Request Data in the Tree display). */
123: private String samplerData;
124:
125: /** The default value of the SamplerData parameter. */
126: private static final String SAMPLER_DATA_DEFAULT = "";
127:
128: /** The name used to store the SamplerData parameter. */
129: private static final String SAMPLER_DATA_NAME = "SamplerData";
130:
131: /** Holds the result data (shown as Response Data in the Tree display). */
132: private String resultData;
133:
134: /** The default value of the ResultData parameter. */
135: private static final String RESULT_DATA_DEFAULT = "";
136:
137: /** The name used to store the ResultData parameter. */
138: private static final String RESULT_DATA_NAME = "ResultData";
139:
140: /** The success status to be stored in the sample result. */
141: private boolean success;
142:
143: /** The default value of the Success Status parameter. */
144: private static final String SUCCESS_DEFAULT = "OK";
145:
146: /** The name used to store the Success Status parameter. */
147: private static final String SUCCESS_NAME = "Status";
148:
149: /**
150: * Default constructor for <code>JavaTest</code>.
151: *
152: * The Java Sampler uses the default constructor to instantiate an instance
153: * of the client class.
154: */
155: public JavaTest() {
156: getLogger().debug(whoAmI() + "\tConstruct");
157: }
158:
159: /*
160: * Utility method to set up all the values
161: */
162: private void setupValues(JavaSamplerContext context) {
163:
164: sleepTime = context.getLongParameter(SLEEP_NAME,
165: DEFAULT_SLEEP_TIME);
166: sleepMask = context.getLongParameter(MASK_NAME,
167: DEFAULT_SLEEP_MASK);
168:
169: responseMessage = context.getParameter(RESPONSE_MESSAGE_NAME,
170: RESPONSE_MESSAGE_DEFAULT);
171:
172: responseCode = context.getParameter(RESPONSE_CODE_NAME,
173: RESPONSE_CODE_DEFAULT);
174:
175: success = context.getParameter(SUCCESS_NAME, SUCCESS_DEFAULT)
176: .equalsIgnoreCase("OK");
177:
178: label = context.getParameter(LABEL_NAME, "");
179: if (label.length() == 0)
180: label = context.getParameter(TestElement.NAME); // default to name
181: // of element
182:
183: samplerData = context.getParameter(SAMPLER_DATA_NAME,
184: SAMPLER_DATA_DEFAULT);
185:
186: resultData = context.getParameter(RESULT_DATA_NAME,
187: RESULT_DATA_DEFAULT);
188: }
189:
190: /**
191: * Do any initialization required by this client.
192: *
193: * There is none, as it is done in runTest() in order to be able to vary the
194: * data for each sample.
195: *
196: * @param context
197: * the context to run with. This provides access to
198: * initialization parameters.
199: */
200: public void setupTest(JavaSamplerContext context) {
201: getLogger().debug(whoAmI() + "\tsetupTest()");
202: listParameters(context);
203: }
204:
205: /**
206: * Provide a list of parameters which this test supports. Any parameter
207: * names and associated values returned by this method will appear in the
208: * GUI by default so the user doesn't have to remember the exact names. The
209: * user can add other parameters which are not listed here. If this method
210: * returns null then no parameters will be listed. If the value for some
211: * parameter is null then that parameter will be listed in the GUI with an
212: * empty value.
213: *
214: * @return a specification of the parameters used by this test which should
215: * be listed in the GUI, or null if no parameters should be listed.
216: */
217: public Arguments getDefaultParameters() {
218: Arguments params = new Arguments();
219: params.addArgument(SLEEP_NAME, String
220: .valueOf(DEFAULT_SLEEP_TIME));
221: params.addArgument(MASK_NAME, DEFAULT_MASK_STRING);
222: params.addArgument(LABEL_NAME, "");
223: params.addArgument(RESPONSE_CODE_NAME, RESPONSE_CODE_DEFAULT);
224: params.addArgument(RESPONSE_MESSAGE_NAME,
225: RESPONSE_MESSAGE_DEFAULT);
226: params.addArgument(SUCCESS_NAME, SUCCESS_DEFAULT);
227: params.addArgument(SAMPLER_DATA_NAME, SAMPLER_DATA_DEFAULT);
228: params.addArgument(RESULT_DATA_NAME, SAMPLER_DATA_DEFAULT);
229: return params;
230: }
231:
232: /**
233: * Perform a single sample.<br>
234: * In this case, this method will simply sleep for some amount of time.
235: *
236: * This method returns a <code>SampleResult</code> object.
237: *
238: * <pre>
239: *
240: * The following fields are always set:
241: * - responseCode (default "")
242: * - responseMessage (default "")
243: * - label (set from LABEL_NAME parameter if it exists, else element name)
244: * - success (default true)
245: *
246: * </pre>
247: *
248: * The following fields are set from the user-defined parameters, if
249: * supplied:
250: *
251: * <pre>
252: * -samplerData - responseData
253: * </pre>
254: *
255: * @see org.apache.jmeter.samplers.SampleResult#sampleStart()
256: * @see org.apache.jmeter.samplers.SampleResult#sampleEnd()
257: * @see org.apache.jmeter.samplers.SampleResult#setSuccessful(boolean)
258: * @see org.apache.jmeter.samplers.SampleResult#setSampleLabel(String)
259: * @see org.apache.jmeter.samplers.SampleResult#setResponseCode(String)
260: * @see org.apache.jmeter.samplers.SampleResult#setResponseMessage(String)
261: * @see org.apache.jmeter.samplers.SampleResult#setResponseData(byte [])
262: * @see org.apache.jmeter.samplers.SampleResult#setDataType(String)
263: *
264: * @param context
265: * the context to run with. This provides access to
266: * initialization parameters.
267: *
268: * @return a SampleResult giving the results of this sample.
269: */
270: public SampleResult runTest(JavaSamplerContext context) {
271: setupValues(context);
272:
273: SampleResult results = new SampleResult();
274:
275: results.setResponseCode(responseCode);
276: results.setResponseMessage(responseMessage);
277: results.setSampleLabel(label);
278:
279: if (samplerData != null && samplerData.length() > 0) {
280: results.setSamplerData(samplerData);
281: }
282:
283: if (resultData != null && resultData.length() > 0) {
284: results.setResponseData(resultData.getBytes());
285: results.setDataType(SampleResult.TEXT);
286: }
287:
288: // Record sample start time.
289: results.sampleStart();
290:
291: long sleep = sleepTime;
292: if (sleepTime > 0 && sleepMask > 0) { // / Only do the calculation if
293: // it is needed
294: long start = System.currentTimeMillis();
295: // Generate a random-ish offset value using the current time.
296: sleep = sleepTime + (start % sleepMask);
297: }
298:
299: try {
300: // Execute the sample. In this case sleep for the
301: // specified time, if any
302: if (sleep > 0) {
303: Thread.sleep(sleep);
304: }
305: results.setSuccessful(success);
306: } catch (InterruptedException e) {
307: getLogger().warn("JavaTest: interrupted.");
308: results.setSuccessful(true);
309: } catch (Exception e) {
310: getLogger().error("JavaTest: error during sample", e);
311: results.setSuccessful(false);
312: } finally {
313: // Record end time and populate the results.
314: results.sampleEnd();
315: }
316:
317: if (getLogger().isDebugEnabled()) {
318: getLogger().debug(
319: whoAmI() + "\trunTest()" + "\tTime:\t"
320: + results.getTime());
321: listParameters(context);
322: }
323:
324: return results;
325: }
326:
327: /**
328: * Do any clean-up required by this test. In this case no clean-up is
329: * necessary, but some messages are logged for debugging purposes.
330: *
331: * @param context
332: * the context to run with. This provides access to
333: * initialization parameters.
334: */
335: public void teardownTest(JavaSamplerContext context) {
336: getLogger().debug(whoAmI() + "\tteardownTest()");
337: listParameters(context);
338: }
339:
340: /**
341: * Dump a list of the parameters in this context to the debug log.
342: *
343: * @param context
344: * the context which contains the initialization parameters.
345: */
346: private void listParameters(JavaSamplerContext context) {
347: if (getLogger().isDebugEnabled()) {
348: Iterator argsIt = context.getParameterNamesIterator();
349: while (argsIt.hasNext()) {
350: String name = (String) argsIt.next();
351: getLogger().debug(
352: name + "=" + context.getParameter(name));
353: }
354: }
355: }
356:
357: /**
358: * Generate a String identifier of this test for debugging purposes.
359: *
360: * @return a String identifier for this test instance
361: */
362: private String whoAmI() {
363: StringBuffer sb = new StringBuffer();
364: sb.append(Thread.currentThread().toString());
365: sb.append("@");
366: sb.append(Integer.toHexString(hashCode()));
367: return sb.toString();
368: }
369:
370: }
|