Return-Path: Delivered-To: apmail-jakarta-httpclient-commits-archive@www.apache.org Received: (qmail 52792 invoked from network); 15 Dec 2005 19:11:07 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 15 Dec 2005 19:11:07 -0000 Received: (qmail 34597 invoked by uid 500); 15 Dec 2005 19:11:06 -0000 Mailing-List: contact httpclient-commits-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: httpclient-dev@jakarta.apache.org Delivered-To: mailing list httpclient-commits@jakarta.apache.org Received: (qmail 34586 invoked by uid 99); 15 Dec 2005 19:11:06 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 15 Dec 2005 11:11:06 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Thu, 15 Dec 2005 11:11:05 -0800 Received: (qmail 52685 invoked by uid 65534); 15 Dec 2005 19:10:45 -0000 Message-ID: <20051215191045.52684.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r357059 - in /jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark: ./ BenchmarkWorker.java HttpBenchmark.java Stats.java Date: Thu, 15 Dec 2005 19:10:44 -0000 To: httpclient-commits@jakarta.apache.org From: olegk@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: olegk Date: Thu Dec 15 11:10:35 2005 New Revision: 357059 URL: http://svn.apache.org/viewcvs?rev=357059&view=rev Log: Added HTTP performance benchmark tool (the first, rough cut) Added: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/ jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/BenchmarkWorker.java (with props) jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/HttpBenchmark.java (with props) jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/Stats.java (with props) Added: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/BenchmarkWorker.java URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/BenchmarkWorker.java?rev=357059&view=auto ============================================================================== --- jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/BenchmarkWorker.java (added) +++ jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/BenchmarkWorker.java Thu Dec 15 11:10:35 2005 @@ -0,0 +1,84 @@ +package org.apache.http.contrib.benchmark; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.http.Header; +import org.apache.http.HttpClientConnection; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.executor.HttpRequestExecutor; + +public class BenchmarkWorker { + + private final int verbosity; + private final HttpRequestExecutor httpexecutor; + + public BenchmarkWorker(final HttpRequestExecutor httpexecutor, int verbosity) { + super(); + this.httpexecutor = httpexecutor; + this.verbosity = verbosity; + } + + public Stats execute( + final HttpRequest request, + final HttpClientConnection conn, + int count, + boolean keepalive) throws HttpException { + HttpResponse response = null; + Stats stats = new Stats(); + stats.start(); + for (int i = 0; i < count; i++) { + try { + if (this.verbosity >= 4) { + System.out.println(">> " + request.getRequestLine().toString()); + Header[] headers = request.getAllHeaders(); + for (int h = 0; h < headers.length; h++) { + System.out.println(">> " + headers[h].toString()); + } + System.out.println(); + } + response = this.httpexecutor.execute(request, conn); + if (this.verbosity >= 3) { + System.out.println(response.getStatusLine().getStatusCode()); + } + if (this.verbosity >= 4) { + System.out.println("<< " + response.getStatusLine().toString()); + Header[] headers = response.getAllHeaders(); + for (int h = 0; h < headers.length; h++) { + System.out.println("<< " + headers[h].toString()); + } + System.out.println(); + } + InputStream instream = response.getEntity().getContent(); + byte[] buffer = new byte[4096]; + long contentlen = 0; + int l = 0; + while ((l = instream.read(buffer)) != -1) { + stats.incTotal(l); + contentlen += l; + } + if (!keepalive) { + conn.close(); + } + stats.setContentLength(contentlen); + stats.incSuccessCount(); + } catch (IOException ex) { + stats.incFailureCount(); + if (this.verbosity >= 2) { + System.err.println("I/O error: " + ex.getMessage()); + } + } + } + stats.finish(); + if (response != null) { + Header header = response.getFirstHeader("Server"); + if (header != null) { + stats.setServerName(header.getValue()); + } + } + return stats; + } + +} Propchange: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/BenchmarkWorker.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/BenchmarkWorker.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/BenchmarkWorker.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/HttpBenchmark.java URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/HttpBenchmark.java?rev=357059&view=auto ============================================================================== --- jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/HttpBenchmark.java (added) +++ jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/HttpBenchmark.java Thu Dec 15 11:10:35 2005 @@ -0,0 +1,238 @@ +package org.apache.http.contrib.benchmark; + +import java.io.File; +import java.net.URL; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.PosixParser; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpVersion; +import org.apache.http.Scheme; +import org.apache.http.entity.FileEntity; +import org.apache.http.executor.HttpRequestExecutor; +import org.apache.http.impl.DefaultHttpClientConnection; +import org.apache.http.impl.DefaultHttpParams; +import org.apache.http.impl.io.PlainSocketFactory; +import org.apache.http.impl.io.SSLSocketFactory; +import org.apache.http.message.HttpGet; +import org.apache.http.message.HttpPost; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.RequestConnControl; +import org.apache.http.protocol.RequestContent; +import org.apache.http.protocol.RequestExpectContinue; +import org.apache.http.protocol.RequestTargetHost; +import org.apache.http.protocol.RequestUserAgent; + +public class HttpBenchmark { + + private static HttpRequestExecutor createRequestExecutor() { + HttpParams params = new DefaultHttpParams(null); + params.setParameter(HttpProtocolParams.PROTOCOL_VERSION, HttpVersion.HTTP_1_1) + .setParameter(HttpProtocolParams.USER_AGENT, "Jakarta HttpComponents") + .setBooleanParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false) + .setBooleanParameter(HttpConnectionParams.STALE_CONNECTION_CHECK, false); + + HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); + httpexecutor.setParams(params); + + // Required request interceptors + httpexecutor.addRequestInterceptor(new RequestContent()); + httpexecutor.addRequestInterceptor(new RequestTargetHost()); + // Recommended request interceptors + httpexecutor.addRequestInterceptor(new RequestConnControl()); + httpexecutor.addRequestInterceptor(new RequestUserAgent()); + httpexecutor.addRequestInterceptor(new RequestExpectContinue()); + return httpexecutor; + } + + public static void main(String[] args) throws Exception { + + Option kopt = new Option("k", false, "Enable the HTTP KeepAlive feature, " + + "i.e., perform multiple requests within one HTTP session. " + + "Default is no KeepAlive"); + kopt.setRequired(false); + + Option nopt = new Option("n", true, "Number of requests to perform for the " + + "benchmarking session. The default is to just perform a single " + + "request which usually leads to non-representative benchmarking " + + "results."); + nopt.setRequired(false); + nopt.setArgName("requests"); + + Option popt = new Option("p", true, "File containing data to POST."); + popt.setRequired(false); + popt.setArgName("POST-file"); + + Option Topt = new Option("T", true, "Content-type header to use for POST data."); + Topt.setRequired(false); + Topt.setArgName("content-type"); + + Option vopt = new Option("v", true, "Set verbosity level - 4 and above prints " + + "information on headers, 3 and above prints response codes (404, 200, " + + "etc.), 2 and above prints warnings and info."); + vopt.setRequired(false); + vopt.setArgName("verbosity"); + + Option hopt = new Option("h", false, "Display usage information."); + nopt.setRequired(false); + + Options options = new Options(); + options.addOption(kopt); + options.addOption(nopt); + options.addOption(popt); + options.addOption(Topt); + options.addOption(vopt); + options.addOption(hopt); + + if (args.length == 0) { + showUsage(options); + System.exit(1); + } + + CommandLineParser parser = new PosixParser(); + CommandLine cmd = parser.parse(options, args); + + if (cmd.hasOption('h')) { + showUsage(options); + System.exit(1); + } + + int verbosity = 0; + if(cmd.hasOption('v')) { + String s = cmd.getOptionValue('v'); + try { + verbosity = Integer.parseInt(s); + } catch (NumberFormatException ex) { + System.err.println("Invalid verbosity level: " + s); + showUsage(options); + System.exit(-1); + } + } + + boolean keepAlive = false; + if(cmd.hasOption('k')) { + keepAlive = true; + } + + int num = 1; + if(cmd.hasOption('n')) { + String s = cmd.getOptionValue('n'); + try { + num = Integer.parseInt(s); + } catch (NumberFormatException ex) { + System.err.println("Invalid number of requests: " + s); + showUsage(options); + System.exit(-1); + } + } + + args = cmd.getArgs(); + if (args.length != 1) { + showUsage(options); + System.exit(-1); + } + // Parse the target url + URL url = new URL(args[0]); + + // Register standard protocol schemes + Scheme.registerScheme("http", + new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + Scheme.registerScheme("https", + new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); + + // Prepare connection + HttpHost host = new HttpHost( + url.getHost(), + url.getPort(), + Scheme.getScheme(url.getProtocol())); + DefaultHttpClientConnection conn = new DefaultHttpClientConnection(host); + + // Prepare request + HttpRequest request = null; + if (cmd.hasOption('p')) { + File file = new File(cmd.getOptionValue('p')); + if (!file.exists()) { + System.err.println("File not found: " + file); + System.exit(-1); + } + String contenttype = null; + if (cmd.hasOption('T')) { + contenttype = cmd.getOptionValue('T'); + } + FileEntity entity = new FileEntity(file, contenttype); + if (file.length() > 100000) { + entity.setChunked(true); + } + HttpPost httppost = new HttpPost(url.getPath()); + httppost.setEntity(entity); + request = httppost; + } else { + HttpGet httpget = new HttpGet(url.getPath()); + request = httpget; + } + + // Prepare request executor + HttpRequestExecutor executor = createRequestExecutor(); + BenchmarkWorker worker = new BenchmarkWorker(executor, verbosity); + + // Execute + Stats stats = null; + try { + stats = worker.execute(request, conn, num, keepAlive); + } finally { + conn.close(); + } + + // Show the results + float totalTimeSec = (float)stats.getDuration() / 1000; + float reqsPerSec = (float)stats.getSuccessCount() / totalTimeSec; + float timePerReqMs = (float)stats.getDuration() / (float)stats.getSuccessCount(); + + System.out.print("Server Software:\t"); + System.out.println(stats.getServerName()); + System.out.print("Server Hostname:\t"); + System.out.println(host.getHostName()); + System.out.print("Server Port:\t\t"); + if (host.getPort() > 0) { + System.out.println(host.getPort()); + } else { + System.out.println(host.getScheme().getDefaultPort()); + } + System.out.println(); + System.out.print("Document Path:\t\t"); + System.out.println(request.getRequestLine().getUri()); + System.out.print("Document Length:\t"); + System.out.print(stats.getContentLength()); + System.out.println(" bytes"); + System.out.println(); + System.out.print("Time taken for tests:\t"); + System.out.print(totalTimeSec); + System.out.println(" seconds"); + System.out.print("Complete requests:\t"); + System.out.println(stats.getSuccessCount()); + System.out.print("Failed requests:\t"); + System.out.println(stats.getFailureCount()); + System.out.print("Content transferred:\t"); + System.out.print(stats.getTotal()); + System.out.println(" bytes"); + System.out.print("Requests per second:\t"); + System.out.print(reqsPerSec); + System.out.println(" [#/sec] (mean)"); + System.out.print("Time per request:\t"); + System.out.print(timePerReqMs); + System.out.println(" [ms] (mean)"); + } + + private static void showUsage(final Options options) { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("HttpBenchmark [options] [http://]hostname[:port]/path", options); + } + +} Propchange: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/HttpBenchmark.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/HttpBenchmark.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/HttpBenchmark.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/Stats.java URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/Stats.java?rev=357059&view=auto ============================================================================== --- jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/Stats.java (added) +++ jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/Stats.java Thu Dec 15 11:10:35 2005 @@ -0,0 +1,80 @@ +package org.apache.http.contrib.benchmark; + +public class Stats { + + private long startTime = -1; + private long finishTime = -1; + private int successCount = 0; + private int failureCount = 0; + private String serverName = null; + private long total = 0; + private long contentLength = -1; + + public Stats() { + super(); + } + + public void start() { + this.startTime = System.currentTimeMillis(); + } + + public void finish() { + this.finishTime = System.currentTimeMillis(); + } + + public long getFinishTime() { + return this.finishTime; + } + + public long getStartTime() { + return this.startTime; + } + + public long getDuration() { + if (this.startTime < 0 || this.finishTime < 0) { + throw new IllegalStateException(); + } + return this.finishTime - this.startTime; + } + + public void incSuccessCount() { + this.successCount++; + } + + public void incFailureCount() { + this.failureCount++; + } + + public int getFailureCount() { + return this.failureCount; + } + + public int getSuccessCount() { + return this.successCount; + } + + public long getTotal() { + return this.total; + } + + public void incTotal(int n) { + this.total += n; + } + + public long getContentLength() { + return this.contentLength; + } + + public void setContentLength(long contentLength) { + this.contentLength = contentLength; + } + + public String getServerName() { + return this.serverName; + } + + public void setServerName(final String serverName) { + this.serverName = serverName; + } + +} Propchange: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/Stats.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/Stats.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: jakarta/httpcomponents/trunk/http-core/src/contrib/org/apache/http/contrib/benchmark/Stats.java ------------------------------------------------------------------------------ svn:mime-type = text/plain