// ========================================================================
// Copyright 2009-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.mortbay.jetty.handler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Request;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.util.IO;
/**
* @version $Revision$ $Date$
*/
public class StatisticsHandlerTest extends TestCase
{
private final int workerCount = 100;
private final int requestCount = 50;
public void testSynchronizedStatisticsHandler() throws Exception
{
StatisticsHandler statisticsHandler = new StatisticsHandler();
runTestWithStatisticsHandler(statisticsHandler);
}
public void testAtomicStatisticsHandler() throws Exception
{
AtomicStatisticsHandler statisticsHandler = new AtomicStatisticsHandler();
runTestWithStatisticsHandler(statisticsHandler);
}
private void runTestWithStatisticsHandler(AbstractStatisticsHandler statisticsHandler) throws Exception
{
Server server = new Server();
Connector connector = new SelectChannelConnector();
server.setConnectors(new Connector[]{connector});
server.setHandler(statisticsHandler);
TestHandler test = new TestHandler();
statisticsHandler.setHandler(test);
server.start();
int serverPort = connector.getLocalPort();
try
{
AtomicInteger count = new AtomicInteger();
test.count=count;
CountDownLatch latch = new CountDownLatch(workerCount);
Worker[] workers = new Worker[workerCount];
for (int i = 0; i < workers.length; ++i)
workers[i] = new Worker(i, serverPort, requestCount, latch);
long start = System.nanoTime();
for (Worker worker : workers)
worker.start();
boolean latched = latch.await(100 * requestCount, TimeUnit.MILLISECONDS);
long end = System.nanoTime();
Thread.sleep(1000);
assertTrue(latched);
assertEquals(workers.length * requestCount,count.get());
assertEquals(workers.length * requestCount, statisticsHandler.getRequests());
assertEquals(workers.length * requestCount, statisticsHandler.getResponses2xx());
System.out.println(statisticsHandler.getClass().getSimpleName() + " - " + workerCount + " threads: " + TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
}
finally
{
server.stop();
}
}
private static class Worker extends Thread
{
private final int id;
private final int port;
private final int requestCount;
private final CountDownLatch latch;
private Worker(int id, int port, int requestCount, CountDownLatch latch)
{
this.id = id;
this.port = port;
this.requestCount = requestCount;
this.latch = latch;
}
public void run()
{
for (int i = 0; i < requestCount; i++)
{
try
{
Socket socket = new Socket(InetAddress.getByName(null), port);
OutputStream output = socket.getOutputStream();
for (int j=20;j-->0 && i+1<requestCount;)
{
String request = "GET /?id=" + id + " HTTP/1.1\r\n" + "Host: localhost\r\n\r\n";
output.write(request.getBytes("UTF-8"));
output.flush();
i++;
}
String request = "GET /?id=" + id + " HTTP/1.1\r\n" + "Host: localhost\r\nConnection: close\r\n\r\n";
output.write(request.getBytes("UTF-8"));
output.flush();
InputStream input = socket.getInputStream();
String responses = IO.toString(input);
socket.close();
}
catch (Exception x)
{
x.printStackTrace();
break;
}
}
latch.countDown();
}
}
private class TestHandler extends AbstractHandler
{
AtomicInteger count;
public void handle(String target, HttpServletRequest servletRequest, HttpServletResponse servletResponse, int dispatch) throws IOException, ServletException
{
count.incrementAndGet();
Request request = (Request)servletRequest;
request.setHandled(true);
servletResponse.setStatus(HttpServletResponse.SC_OK);
}
}
}