001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/oac.hc3x/tags/HTTPCLIENT_3_1/src/contrib/org/apache/commons/httpclient/contrib/benchmark/HttpBenchmark.java $
003: * $Revision: 480424 $
004: * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005: *
006: * ====================================================================
007: *
008: * Licensed to the Apache Software Foundation (ASF) under one or more
009: * contributor license agreements. See the NOTICE file distributed with
010: * this work for additional information regarding copyright ownership.
011: * The ASF licenses this file to You under the Apache License, Version 2.0
012: * (the "License"); you may not use this file except in compliance with
013: * the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing, software
018: * distributed under the License is distributed on an "AS IS" BASIS,
019: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020: * See the License for the specific language governing permissions and
021: * limitations under the License.
022: * ====================================================================
023: *
024: * This software consists of voluntary contributions made by many
025: * individuals on behalf of the Apache Software Foundation. For more
026: * information on the Apache Software Foundation, please see
027: * <http://www.apache.org/>.
028: *
029: */
030: package org.apache.commons.httpclient.contrib.benchmark;
031:
032: import java.io.File;
033: import java.net.URL;
034:
035: import org.apache.commons.cli.CommandLine;
036: import org.apache.commons.cli.CommandLineParser;
037: import org.apache.commons.cli.HelpFormatter;
038: import org.apache.commons.cli.Option;
039: import org.apache.commons.cli.Options;
040: import org.apache.commons.cli.PosixParser;
041: import org.apache.commons.httpclient.HostConfiguration;
042: import org.apache.commons.httpclient.HttpClient;
043: import org.apache.commons.httpclient.HttpMethod;
044: import org.apache.commons.httpclient.HttpVersion;
045: import org.apache.commons.httpclient.methods.FileRequestEntity;
046: import org.apache.commons.httpclient.methods.GetMethod;
047: import org.apache.commons.httpclient.methods.HeadMethod;
048: import org.apache.commons.httpclient.methods.PostMethod;
049: import org.apache.commons.httpclient.params.HttpMethodParams;
050:
051: /**
052: * <p>A simple HTTP benchmark tool, which implements a subset of AB (Apache Benchmark) interface</p>
053: *
054: * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
055: *
056: * @version $Revision: 480424 $
057: */
058: public class HttpBenchmark {
059:
060: private static HttpClient createRequestExecutor() {
061: HttpClient httpclient = new HttpClient();
062: httpclient.getParams().setVersion(HttpVersion.HTTP_1_1);
063: httpclient.getParams().setBooleanParameter(
064: HttpMethodParams.USE_EXPECT_CONTINUE, false);
065: httpclient.getHttpConnectionManager().getParams()
066: .setStaleCheckingEnabled(false);
067: return httpclient;
068: }
069:
070: public static void main(String[] args) throws Exception {
071:
072: Option iopt = new Option("i", false,
073: "Do HEAD requests instead of GET.");
074: iopt.setRequired(false);
075:
076: Option kopt = new Option(
077: "k",
078: false,
079: "Enable the HTTP KeepAlive feature, "
080: + "i.e., perform multiple requests within one HTTP session. "
081: + "Default is no KeepAlive");
082: kopt.setRequired(false);
083:
084: Option nopt = new Option(
085: "n",
086: true,
087: "Number of requests to perform for the "
088: + "benchmarking session. The default is to just perform a single "
089: + "request which usually leads to non-representative benchmarking "
090: + "results.");
091: nopt.setRequired(false);
092: nopt.setArgName("requests");
093:
094: Option popt = new Option("p", true,
095: "File containing data to POST.");
096: popt.setRequired(false);
097: popt.setArgName("POST-file");
098:
099: Option Topt = new Option("T", true,
100: "Content-type header to use for POST data.");
101: Topt.setRequired(false);
102: Topt.setArgName("content-type");
103:
104: Option vopt = new Option(
105: "v",
106: true,
107: "Set verbosity level - 4 and above prints "
108: + "information on headers, 3 and above prints response codes (404, 200, "
109: + "etc.), 2 and above prints warnings and info.");
110: vopt.setRequired(false);
111: vopt.setArgName("verbosity");
112:
113: Option hopt = new Option("h", false,
114: "Display usage information.");
115: nopt.setRequired(false);
116:
117: Options options = new Options();
118: options.addOption(iopt);
119: options.addOption(kopt);
120: options.addOption(nopt);
121: options.addOption(popt);
122: options.addOption(Topt);
123: options.addOption(vopt);
124: options.addOption(hopt);
125:
126: if (args.length == 0) {
127: showUsage(options);
128: System.exit(1);
129: }
130:
131: CommandLineParser parser = new PosixParser();
132: CommandLine cmd = parser.parse(options, args);
133:
134: if (cmd.hasOption('h')) {
135: showUsage(options);
136: System.exit(1);
137: }
138:
139: int verbosity = 0;
140: if (cmd.hasOption('v')) {
141: String s = cmd.getOptionValue('v');
142: try {
143: verbosity = Integer.parseInt(s);
144: } catch (NumberFormatException ex) {
145: System.err.println("Invalid verbosity level: " + s);
146: showUsage(options);
147: System.exit(-1);
148: }
149: }
150:
151: boolean keepAlive = false;
152: if (cmd.hasOption('k')) {
153: keepAlive = true;
154: }
155:
156: int num = 1;
157: if (cmd.hasOption('n')) {
158: String s = cmd.getOptionValue('n');
159: try {
160: num = Integer.parseInt(s);
161: } catch (NumberFormatException ex) {
162: System.err.println("Invalid number of requests: " + s);
163: showUsage(options);
164: System.exit(-1);
165: }
166: }
167:
168: args = cmd.getArgs();
169: if (args.length != 1) {
170: showUsage(options);
171: System.exit(-1);
172: }
173: // Parse the target url
174: URL url = new URL(args[0]);
175:
176: // Prepare host configuration
177: HostConfiguration hostconf = new HostConfiguration();
178: hostconf.setHost(url.getHost(), url.getPort(), url
179: .getProtocol());
180:
181: // Prepare request
182: HttpMethod method = null;
183: if (cmd.hasOption('p')) {
184: PostMethod httppost = new PostMethod(url.getPath());
185: File file = new File(cmd.getOptionValue('p'));
186: if (!file.exists()) {
187: System.err.println("File not found: " + file);
188: System.exit(-1);
189: }
190: String contenttype = null;
191: if (cmd.hasOption('T')) {
192: contenttype = cmd.getOptionValue('T');
193: }
194: FileRequestEntity entity = new FileRequestEntity(file,
195: contenttype);
196: httppost.setRequestEntity(entity);
197: if (file.length() > 100000) {
198: httppost.setContentChunked(true);
199: }
200: method = httppost;
201: } else if (cmd.hasOption('i')) {
202: HeadMethod httphead = new HeadMethod(url.getPath());
203: method = httphead;
204: } else {
205: GetMethod httpget = new GetMethod(url.getPath());
206: method = httpget;
207: }
208: if (!keepAlive) {
209: method.addRequestHeader("Connection", "close");
210: }
211:
212: // Prepare request executor
213: HttpClient executor = createRequestExecutor();
214: BenchmarkWorker worker = new BenchmarkWorker(executor,
215: verbosity);
216:
217: // Execute
218: Stats stats = worker.execute(hostconf, method, num, keepAlive);
219:
220: // Show the results
221: float totalTimeSec = (float) stats.getDuration() / 1000;
222: float reqsPerSec = (float) stats.getSuccessCount()
223: / totalTimeSec;
224: float timePerReqMs = (float) stats.getDuration()
225: / (float) stats.getSuccessCount();
226:
227: System.out.print("Server Software:\t");
228: System.out.println(stats.getServerName());
229: System.out.print("Server Hostname:\t");
230: System.out.println(hostconf.getHost());
231: System.out.print("Server Port:\t\t");
232: if (hostconf.getPort() > 0) {
233: System.out.println(hostconf.getPort());
234: } else {
235: System.out.println(hostconf.getProtocol().getDefaultPort());
236: }
237: System.out.println();
238: System.out.print("Document Path:\t\t");
239: System.out.println(method.getURI());
240: System.out.print("Document Length:\t");
241: System.out.print(stats.getContentLength());
242: System.out.println(" bytes");
243: System.out.println();
244: System.out.print("Time taken for tests:\t");
245: System.out.print(totalTimeSec);
246: System.out.println(" seconds");
247: System.out.print("Complete requests:\t");
248: System.out.println(stats.getSuccessCount());
249: System.out.print("Failed requests:\t");
250: System.out.println(stats.getFailureCount());
251: System.out.print("Content transferred:\t");
252: System.out.print(stats.getTotal());
253: System.out.println(" bytes");
254: System.out.print("Requests per second:\t");
255: System.out.print(reqsPerSec);
256: System.out.println(" [#/sec] (mean)");
257: System.out.print("Time per request:\t");
258: System.out.print(timePerReqMs);
259: System.out.println(" [ms] (mean)");
260: }
261:
262: private static void showUsage(final Options options) {
263: HelpFormatter formatter = new HelpFormatter();
264: formatter
265: .printHelp(
266: "HttpBenchmark [options] [http://]hostname[:port]/path",
267: options);
268: }
269:
270: }
|