Fix for #308862 (Update test suite to JUnit4 - Module jetty-server).

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1766 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Simone Bordet 2010-05-12 13:36:26 +00:00
parent becb140427
commit be3c8682ed
8 changed files with 621 additions and 739 deletions

View File

@ -12,6 +12,7 @@ jetty-7.1.1-SNAPSHOT
+ 308863 Update test suite to JUnit4 - Module jetty-servlet
+ 308855 Update test suite to JUnit4 - Module jetty-io
+ 310918 Fixed write blocking for client HttpConnection
+ 308862 Update test suite to JUnit4 - Module jetty-server
jetty-7.1.0 5 May 2010
+ 306353 fixed cross context dispatch to root context.

View File

@ -20,184 +20,189 @@ import java.io.PrintWriter;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.log.Log;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class AbstractConnectorTest extends TestCase
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class AbstractConnectorTest
{
private Server _server;
private Handler _handler;
private AbstractConnector _connector;
private String _request = "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n";
private static Server _server;
private static AbstractConnector _connector;
private static CyclicBarrier _connect;
private static CountDownLatch _closed;
private Socket[] _socket;
private PrintWriter[] _out;
private BufferedReader[] _in;
private CyclicBarrier _connect;
private CountDownLatch _closed;
@Override
protected void setUp() throws Exception
@BeforeClass
public static void init() throws Exception
{
_connect = new CyclicBarrier(2);
_server = new Server();
_connector = new SelectChannelConnector()
{
public void connectionClosed(Connection connection)
{
super.connectionClosed(connection);
_closed.countDown();
}
_connector =
new SelectChannelConnector() {
public void connectionClosed(Connection connection)
{
super.connectionClosed(connection);
_closed.countDown();
}
};
_server.addConnector(_connector);
};
_connector.setStatsOn(true);
_server.addConnector(_connector);
HandlerWrapper wrapper =
new HandlerWrapper() {
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
HandlerWrapper wrapper = new HandlerWrapper()
{
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
{
try
{
try
{
_connect.await();
}
catch (Exception ex)
{
Log.debug(ex);
}
finally
{
super.handle(path, request, httpRequest, httpResponse);
}
_connect.await();
}
catch (Exception ex)
{
Log.debug(ex);
}
};
_server.setHandler(wrapper);
finally
{
super.handle(path, request, httpRequest, httpResponse);
}
}
};
_server.setHandler(wrapper);
Handler handler = new AbstractHandler()
{
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
baseRequest.setHandled(true);
PrintWriter out = response.getWriter();
out.write("Server response\n");
out.close();
response.setStatus(HttpServletResponse.SC_OK);
}
};
wrapper.setHandler(handler);
_handler =
new AbstractHandler() {
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
baseRequest.setHandled(true);
PrintWriter out = response.getWriter();
out.write("Server response\n");
out.close();
response.setStatus(HttpServletResponse.SC_OK);
}
};
wrapper.setHandler(_handler);
_server.start();
}
@Override
protected void tearDown() throws Exception
@AfterClass
public static void destroy() throws Exception
{
_server.stop();
_server.join();
}
public void testSingleRequest()
throws Exception
@Before
public void reset()
{
doInit(1);
_connector.statsReset();
}
@Test
public void testSingleRequest() throws Exception
{
int connections = 1;
doInit(connections);
sendRequest(1, 1);
doClose(1);
assertEquals(1, _connector.getConnections());
doClose(connections);
assertEquals(connections, _connector.getConnections());
assertEquals(0, _connector.getConnectionsOpen());
assertEquals(1, _connector.getConnectionsOpenMax());
assertEquals(connections, _connector.getConnectionsOpenMax());
assertTrue(_connector.getConnectionsOpen() <= _connector.getConnectionsOpenMax());
assertTrue(_connector.getConnectionsDurationMean() > 0);
assertTrue(_connector.getConnectionsDurationMax() > 0);
assertTrue(_connector.getConnectionsDurationMean() <= _connector.getConnectionsDurationMax());
assertEquals(1, _connector.getRequests());
assertEquals(1.0, _connector.getConnectionsRequestsMean());
assertEquals(1.0, _connector.getConnectionsRequestsMean(), 0.01);
assertEquals(1, _connector.getConnectionsRequestsMax());
assertTrue(_connector.getConnectionsRequestsMean() <= _connector.getConnectionsRequestsMax());
}
public void testMultipleRequests()
throws Exception
@Test
public void testMultipleRequests() throws Exception
{
doInit(1);
sendRequest(1, 1);
sendRequest(1, 1);
doClose(1);
assertEquals(1, _connector.getConnections());
assertEquals(0, _connector.getConnectionsOpen());
assertEquals(1, _connector.getConnectionsOpenMax());
assertTrue(_connector.getConnectionsOpen() <= _connector.getConnectionsOpenMax());
assertTrue(_connector.getConnectionsDurationMean() > 0);
assertTrue(_connector.getConnectionsDurationMax() > 0);
assertTrue(_connector.getConnectionsDurationMean() <= _connector.getConnectionsDurationMax());
assertEquals(2, _connector.getRequests());
assertEquals(2.0, _connector.getConnectionsRequestsMean());
assertEquals(2.0, _connector.getConnectionsRequestsMean(), 0.01);
assertEquals(2, _connector.getConnectionsRequestsMax());
assertTrue(_connector.getConnectionsRequestsMean() <= _connector.getConnectionsRequestsMax());
}
public void testMultipleConnections()
throws Exception
@Test
public void testMultipleConnections() throws Exception
{
doInit(3);
sendRequest(1, 1); // request 1 connection 1
sendRequest(2, 2); // request 1 connection 2
sendRequest(3, 3); // request 1 connection 3
sendRequest(2, 3); // request 2 connection 2
sendRequest(3, 3); // request 2 connection 3
sendRequest(3, 3); // request 3 connection 3
doClose(3);
assertEquals(3, _connector.getConnections());
assertEquals(0, _connector.getConnectionsOpen());
assertEquals(3, _connector.getConnectionsOpenMax());
assertTrue(_connector.getConnectionsOpen() <= _connector.getConnectionsOpenMax());
assertTrue(_connector.getConnectionsDurationMean() > 0);
assertTrue(_connector.getConnectionsDurationMax() > 0);
assertTrue(_connector.getConnectionsDurationMean() <= _connector.getConnectionsDurationMax());
assertEquals(6, _connector.getRequests());
assertEquals(2.0, _connector.getConnectionsRequestsMean());
assertEquals(2.0, _connector.getConnectionsRequestsMean(), 0.01);
assertEquals(3, _connector.getConnectionsRequestsMax());
assertTrue(_connector.getConnectionsRequestsMean() <= _connector.getConnectionsRequestsMax());
}
protected void doInit(int count)
{
_socket = new Socket[count];
@ -206,9 +211,8 @@ public class AbstractConnectorTest extends TestCase
_closed = new CountDownLatch(count);
}
protected void doClose(int count)
throws Exception
private void doClose(int count) throws Exception
{
for (int idx=0; idx < count; idx++)
{
@ -217,35 +221,34 @@ public class AbstractConnectorTest extends TestCase
if (_in[idx] != null)
_in[idx].close();
if (_socket[idx] != null)
_socket[idx].close();
}
_closed.await();
}
protected void sendRequest(int id, int count)
throws Exception
private void sendRequest(int id, int count) throws Exception
{
int idx = id - 1;
if (idx < 0)
throw new IllegalArgumentException("Connection ID <= 0");
_socket[idx] = _socket[idx] == null ? new Socket("localhost", _connector.getLocalPort()) : _socket[idx];
_out[idx] = _out[idx] == null ? new PrintWriter(_socket[idx].getOutputStream(), true) : _out[idx];
_in[idx] = _in[idx] == null ? new BufferedReader(new InputStreamReader(_socket[idx].getInputStream())) : _in[idx];
_connect.reset();
_out[idx].write(_request);
_out[idx].write("GET / HTTP/1.1\r\nHost: localhost\r\n\r\n");
_out[idx].flush();
_connect.await();
assertEquals(count, _connector.getConnectionsOpen());
while(_in[idx].ready())
{
_in[idx].readLine();

View File

@ -4,23 +4,26 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import org.eclipse.jetty.server.nio.BlockingChannelConnector;
import org.junit.BeforeClass;
/**
* HttpServer Tester.
*/
public class BlockingChannelServerTest extends HttpServerTestBase
{
public BlockingChannelServerTest()
@BeforeClass
public static void init() throws Exception
{
super(new BlockingChannelConnector());
}
startServer(new BlockingChannelConnector());
}
}

View File

@ -4,11 +4,11 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
@ -23,22 +23,18 @@ import org.eclipse.jetty.io.nio.NIOBuffer;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.BeforeClass;
/**
* HttpServer Tester.
*/
public class BusySelectChannelServerTest extends HttpServerTestBase
{
public BusySelectChannelServerTest()
@BeforeClass
public static void init() throws Exception
{
super(new SelectChannelConnector()
startServer(new SelectChannelConnector()
{
/* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see org.eclipse.jetty.server.server.nio.SelectChannelConnector#newEndPoint(java.nio.channels.SocketChannel, org.eclipse.io.nio.SelectorManager.SelectSet, java.nio.channels.SelectionKey)
*/
@Override
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
{
@ -46,7 +42,7 @@ public class BusySelectChannelServerTest extends HttpServerTestBase
{
int write;
int read;
/* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see org.eclipse.io.nio.SelectChannelEndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer)
@ -103,7 +99,7 @@ public class BusySelectChannelServerTest extends HttpServerTestBase
buffer.put(one.peek(0));
return l;
}
if (x<24 && buffer.space()>=2)
{
NIOBuffer two = new IndirectNIOBuffer(2);
@ -114,7 +110,7 @@ public class BusySelectChannelServerTest extends HttpServerTestBase
buffer.put(two.peek(1));
return l;
}
if (x<64 && buffer.space()>=3)
{
NIOBuffer three = new IndirectNIOBuffer(3);
@ -127,18 +123,11 @@ public class BusySelectChannelServerTest extends HttpServerTestBase
buffer.put(three.peek(2));
return l;
}
return super.fill(buffer);
}
};
}
});
}
@Override
protected void configServer(Server server)
{
server.setThreadPool(new QueuedThreadPool());
}
});
}
}

View File

@ -4,11 +4,11 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
@ -26,25 +26,26 @@ import java.net.Socket;
import java.net.URL;
import java.util.Arrays;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.AfterClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
/**
* HttpServer Tester.
*
*/
public class HttpServerTestBase extends TestCase
public abstract class HttpServerTestBase
{
private static boolean stress=Boolean.getBoolean("STRESS");
// ~ Static fields/initializers
// ---------------------------------------------
private static final boolean stress = Boolean.getBoolean("STRESS");
/** The request. */
private static final String REQUEST1_HEADER="POST / HTTP/1.0\n"+"Host: localhost\n"+"Content-Type: text/xml; charset=utf-8\n"+"Connection: close\n"+"Content-Length: ";
@ -67,7 +68,6 @@ public class HttpServerTestBase extends TestCase
"Host: localhost\n"+
"Content-Type: text/xml\n"+
"Content-Length: ";
private static final String REQUEST2_CONTENT=
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"+
"<nimbus xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"+
@ -78,9 +78,9 @@ public class HttpServerTestBase extends TestCase
" </getJobDetails>\n"+
" </request>\n"+
"</nimbus>";
private static final String REQUEST2=REQUEST2_HEADER+REQUEST2_CONTENT.getBytes().length+"\n\n"+REQUEST2_CONTENT;
/** The second expected response. */
private static final String RESPONSE2_CONTENT=
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"+
"<nimbus xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"+
@ -104,87 +104,102 @@ public class HttpServerTestBase extends TestCase
private static final int LOOPS=stress?250:25;
private static final String HOST="localhost";
private Connector _connector;
private int port=0;
private static Server _server;
private static Connector _connector;
protected void tearDown() throws Exception
protected static void startServer(Connector connector) throws Exception
{
super.tearDown();
Thread.sleep(100);
_server = new Server();
_connector = connector;
_server.addConnector(_connector);
_server.setHandler(new HandlerWrapper());
_server.start();
}
// ~ Methods
// ----------------------------------------------------------------
@AfterClass
public static void stopServer() throws Exception
{
_server.stop();
_server.join();
}
/**
protected void configureServer(Handler handler) throws Exception
{
HandlerWrapper current = (HandlerWrapper)_server.getHandler();
current.stop();
current.setHandler(handler);
current.start();
}
/*
* Feed the server the entire request at once.
*
* @throws Exception
* @throws InterruptedException
*/
public void testRequest1_jetty() throws Exception, InterruptedException
@Test
public void testRequest1_jetty() throws Exception
{
Server server=startServer(new HelloWorldHandler());
Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
os.write(REQUEST1.getBytes());
os.flush();
// Read the response.
String response=readResponse(client);
// Shut down
client.close();
server.stop();
// Check the response
assertEquals("response",RESPONSE1,response);
}
/* --------------------------------------------------------------- */
public void testFragmentedChunk() throws Exception
{
Server server=startServer(new EchoHandler());
Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
os.write(("GET /R2 HTTP/1.1\015\012"+"Host: localhost\015\012"+"Transfer-Encoding: chunked\015\012"+"Content-Type: text/plain\015\012"
+"Connection: close\015\012"+"\015\012").getBytes());
os.flush();
Thread.sleep(PAUSE);
os.write(("5\015\012").getBytes());
os.flush();
Thread.sleep(PAUSE);
os.write(("ABCDE\015\012"+"0;\015\012\015\012").getBytes());
os.flush();
// Read the response.
String response=readResponse(client);
// Shut down
client.close();
server.stop();
assertTrue(true); // nothing checked yet.
}
/**
* Feed the server fragmentary headers and see how it copes with it.
*
* @throws Exception
* @throws InterruptedException
*/
public void testRequest1Fragments_jetty() throws Exception, InterruptedException
{
Server server=startServer(new HelloWorldHandler());
String response;
configureServer(new HelloWorldHandler());
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
OutputStream os=client.getOutputStream();
os.write(REQUEST1.getBytes());
os.flush();
// Read the response.
String response=readResponse(client);
// Check the response
assertEquals("response",RESPONSE1,response);
}
finally
{
client.close();
}
}
@Test
public void testFragmentedChunk() throws Exception
{
configureServer(new EchoHandler());
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
OutputStream os=client.getOutputStream();
os.write(("GET /R2 HTTP/1.1\015\012"+"Host: localhost\015\012"+"Transfer-Encoding: chunked\015\012"+"Content-Type: text/plain\015\012"
+"Connection: close\015\012"+"\015\012").getBytes());
os.flush();
Thread.sleep(PAUSE);
os.write(("5\015\012").getBytes());
os.flush();
Thread.sleep(PAUSE);
os.write(("ABCDE\015\012"+"0;\015\012\015\012").getBytes());
os.flush();
// Read the response.
String response=readResponse(client);
assertTrue(true); // nothing checked yet.
}
finally
{
client.close();
}
}
/*
* Feed the server fragmentary headers and see how it copes with it.
*/
@Test
public void testRequest1Fragments_jetty() throws Exception, InterruptedException
{
configureServer(new HelloWorldHandler());
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
// Write a fragment, flush, sleep, write the next fragment, etc.
@ -198,30 +213,29 @@ public class HttpServerTestBase extends TestCase
os.flush();
// Read the response
response=readResponse(client);
String response = readResponse(client);
// Shut down
client.close();
// Check the response
assertEquals("response",RESPONSE1,response);
}
finally
{
server.stop();
client.close();
}
// Check the response
assertEquals("response",RESPONSE1,response);
}
@Test
public void testRequest2_jetty() throws Exception
{
byte[] bytes=REQUEST2.getBytes();
Server server=startServer(new EchoHandler());
configureServer(new EchoHandler());
try
byte[] bytes=REQUEST2.getBytes();
for (int i=0; i<LOOPS; i++)
{
for (int i=0; i<LOOPS; i++)
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
os.write(bytes);
@ -229,50 +243,44 @@ public class HttpServerTestBase extends TestCase
// Read the response
String response=readResponse(client);
client.close();
// Check the response
assertEquals("response "+i,RESPONSE2,response);
}
}
finally
{
// Shut down
server.stop();
finally
{
client.close();
}
}
}
/**
* @throws Exception
*/
@Test
public void testRequest2Fragments_jetty() throws Exception
{
Random random=new Random(System.currentTimeMillis());
configureServer(new EchoHandler());
byte[] bytes=REQUEST2.getBytes();
final int pointCount=2;
Server server=startServer(new EchoHandler());
try
Random random=new Random(System.currentTimeMillis());
for (int i=0; i<LOOPS; i++)
{
int[] points=new int[pointCount];
StringBuilder message=new StringBuilder();
for (int i=0; i<LOOPS; i++)
message.append("iteration #").append(i + 1);
// Pick fragment points at random
for (int j=0; j<points.length; ++j)
{
points[j]=random.nextInt(bytes.length);
}
int[] points=new int[pointCount];
StringBuilder message=new StringBuilder();
// Sort the list
Arrays.sort(points);
message.append("iteration #").append(i + 1);
// Pick fragment points at random
for (int j=0; j<points.length; ++j)
{
points[j]=random.nextInt(bytes.length);
}
// Sort the list
Arrays.sort(points);
Socket client=new Socket(HOST,port);
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
OutputStream os=client.getOutputStream();
writeFragments(bytes,points,message,os);
@ -280,38 +288,35 @@ public class HttpServerTestBase extends TestCase
// Read the response
String response=readResponse(client);
// Close the client
client.close();
// Check the response
assertEquals("response for "+i+" "+message.toString(),RESPONSE2,response);
}
}
finally
{
// Shut down
server.stop();
finally
{
client.close();
}
}
}
@Test
public void testRequest2Iterate_jetty() throws Exception
{
configureServer(new EchoHandler());
byte[] bytes=REQUEST2.getBytes();
Server server=startServer(new EchoHandler());
try
for (int i=0; i<bytes.length; i+=3)
{
for (int i=0; i<bytes.length; i+=3)
int[] points=new int[] { i };
StringBuilder message=new StringBuilder();
message.append("iteration #").append(i + 1);
// Sort the list
Arrays.sort(points);
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
int[] points=new int[] { i };
StringBuilder message=new StringBuilder();
message.append("iteration #").append(i + 1);
// Sort the list
Arrays.sort(points);
Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
writeFragments(bytes,points,message,os);
@ -319,42 +324,37 @@ public class HttpServerTestBase extends TestCase
// Read the response
String response=readResponse(client);
// Close the client
client.close();
// Check the response
assertEquals("response for "+i+" "+message.toString(),RESPONSE2,response);
}
}
finally
{
// Shut down
server.stop();
finally
{
client.close();
}
}
}
/**
/*
* After several iterations, I generated some known bad fragment points.
*
* @throws Exception
*/
@Test
public void testRequest2KnownBad_jetty() throws Exception
{
configureServer(new EchoHandler());
byte[] bytes=REQUEST2.getBytes();
int[][] badPoints=new int[][]
{
{ 70 }, // beginning here, drops last line of request
{ 70 }, // beginning here, drops last line of request
{ 71 }, // no response at all
{ 72 }, // again starts drops last line of request
{ 74 }, // again, no response at all
};
Server server=startServer(new EchoHandler());
try
for (int i=0; i<badPoints.length; ++i)
{
for (int i=0; i<badPoints.length; ++i)
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
StringBuilder message=new StringBuilder();
@ -364,86 +364,66 @@ public class HttpServerTestBase extends TestCase
// Read the response
String response=readResponse(client);
// Close the client
client.close();
// Check the response
// TODO - change to equals when code gets fixed
assertNotSame("response for "+message.toString(),RESPONSE2,response);
}
}
finally
{
// Shut down
server.stop();
finally
{
client.close();
}
}
}
/**
* After several iterations, I generated some known bad fragment points.
*
* @throws Exception
*/
@Test
public void testFlush() throws Exception
{
Server server=startServer(new DataHandler());
try
{
String[] encoding = {"NONE","UTF-8","ISO-8859-1","ISO-8859-2"};
configureServer(new DataHandler());
for (int e =0; e<encoding.length;e++)
String[] encoding = {"NONE","UTF-8","ISO-8859-1","ISO-8859-2"};
for (int e =0; e<encoding.length;e++)
{
for (int b=1;b<=128;b=b==1?2:b==2?32:b==32?128:129)
{
for (int b=1;b<=128;b=b==1?2:b==2?32:b==32?128:129)
for (int w=41;w<42;w+=4096)
{
for (int w=41;w<42;w+=4096)
for (int c=0;c<1;c++)
{
for (int c=0;c<1;c++)
String test=encoding[e]+"x"+b+"x"+w+"x"+c;
try
{
String test=encoding[e]+"x"+b+"x"+w+"x"+c;
try
{
URL url=new URL("http://"+HOST+":"+port+"/?writes="+w+"&block="+b+ (e==0?"":("&encoding="+encoding[e]))+(c==0?"&chars=true":""));
InputStream in = (InputStream)url.getContent();
String response=IO.toString(in,e==0?null:encoding[e]);
URL url=new URL("http://"+HOST+":"+_connector.getLocalPort()+"/?writes="+w+"&block="+b+ (e==0?"":("&encoding="+encoding[e]))+(c==0?"&chars=true":""));
InputStream in = (InputStream)url.getContent();
String response=IO.toString(in,e==0?null:encoding[e]);
assertEquals(test,b*w,response.length());
}
catch(Exception ex)
{
System.err.println(test);
throw ex;
}
assertEquals(test,b*w,response.length());
}
catch(Exception x)
{
System.err.println(test);
throw x;
}
}
}
}
}
finally
{
// Shut down
server.stop();
Thread.yield();
}
}
/**
* After several iterations, I generated some known bad fragment points.
*
* @throws Exception
*/
@Test
public void testReadWriteBlocking() throws Exception
{
Server server=startServer(new DataHandler());
configureServer(new DataHandler());
long start=System.currentTimeMillis();
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
long start=System.currentTimeMillis();
Socket client=new Socket(HOST,port);
{
OutputStream os=client.getOutputStream();
InputStream is=client.getInputStream();
os.write((
"GET /data?writes=1024&block=256 HTTP/1.1\r\n"+
"host: "+HOST+":"+port+"\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"connection: close\r\n"+
"content-type: unknown\r\n"+
"content-length: 30\r\n"+
@ -465,11 +445,11 @@ public class HttpServerTestBase extends TestCase
"0987654321\r\n"
).getBytes());
os.flush();
int total=0;
int len=0;
byte[] buf=new byte[1024*64];
while(len>=0)
{
Thread.sleep(500);
@ -483,29 +463,21 @@ public class HttpServerTestBase extends TestCase
}
finally
{
// Shut down
server.stop();
Thread.yield();
client.close();
}
}
/**
* After several iterations, I generated some known bad fragment points.
*
* @throws Exception
*/
@Test
public void testPipeline() throws Exception
{
Server server=startServer(new HelloWorldHandler());
configureServer(new HelloWorldHandler());
try
{
//for (int pipeline=1;pipeline<32;pipeline++)
for (int pipeline=1;pipeline<32;pipeline++)
{
Socket client=new Socket(HOST,port);
//for (int pipeline=1;pipeline<32;pipeline++)
for (int pipeline=1;pipeline<32;pipeline++)
{
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
client.setSoTimeout(5000);
OutputStream os=client.getOutputStream();
@ -514,15 +486,15 @@ public class HttpServerTestBase extends TestCase
for (int i=1;i<pipeline;i++)
request+=
"GET /data?writes=1&block=16&id="+i+" HTTP/1.1\r\n"+
"host: "+HOST+":"+port+"\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"user-agent: testharness/1.0 (blah foo/bar)\r\n"+
"accept-encoding: nothing\r\n"+
"cookie: aaa=1234567890\r\n"+
"\r\n";
request+=
"GET /data?writes=1&block=16 HTTP/1.1\r\n"+
"host: "+HOST+":"+port+"\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"user-agent: testharness/1.0 (blah foo/bar)\r\n"+
"accept-encoding: nothing\r\n"+
"cookie: aaa=bbbbbb\r\n"+
@ -544,53 +516,38 @@ public class HttpServerTestBase extends TestCase
}
assertEquals(pipeline,count);
}
finally
{
client.close();
}
}
finally
{
// Shut down
server.stop();
Thread.yield();
}
}
public void testStoppable() throws Exception
{
Server server=startServer(null);
server.setThreadPool(new QueuedThreadPool());
server.start();
Thread.sleep(1000);
server.stop();
}
/**
*/
@Test
public void testRecycledWriters() throws Exception
{
Server server=startServer(new EchoHandler());
configureServer(new EchoHandler());
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
long start=System.currentTimeMillis();
Socket client=new Socket(HOST,port);
{
OutputStream os=client.getOutputStream();
InputStream is=client.getInputStream();
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
"host: "+HOST+":"+port+"\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: 10\r\n"+
"\r\n").getBytes("iso-8859-1"));
os.write((
"123456789\n"
).getBytes("utf-8"));
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
"host: "+HOST+":"+port+"\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: 10\r\n"+
"\r\n"
@ -604,7 +561,7 @@ public class HttpServerTestBase extends TestCase
byte[] contentB=content.getBytes("utf-8");
os.write((
"POST /echo?charset=utf-16 HTTP/1.1\r\n"+
"host: "+HOST+":"+port+"\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: "+contentB.length+"\r\n"+
"connection: close\r\n"+
@ -613,7 +570,7 @@ public class HttpServerTestBase extends TestCase
os.write(contentB);
os.flush();
ByteArrayOutputStream bout = new ByteArrayOutputStream();
IO.copy(is,bout);
byte[] b=bout.toByteArray();
@ -634,57 +591,51 @@ public class HttpServerTestBase extends TestCase
if (state==1||state==3)
state++;
continue;
default:
state=0;
}
}
String in = new String(b,0,i,"utf-8");
assertTrue(in.indexOf("123456789")>=0);
assertTrue(in.indexOf("abcdefghZ")>=0);
assertTrue(in.indexOf("Wibble")<0);
in = new String(b,i,b.length-i,"utf-16");
assertEquals("Wibble\n",in);
}
finally
{
// Shut down
server.stop();
Thread.yield();
client.close();
}
}
/**
*/
@Test
public void testRecycledReaders() throws Exception
{
Server server=startServer(new EchoHandler());
configureServer(new EchoHandler());
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
long start=System.currentTimeMillis();
Socket client=new Socket(HOST,port);
{
OutputStream os=client.getOutputStream();
InputStream is=client.getInputStream();
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
"host: "+HOST+":"+port+"\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: 10\r\n"+
"\r\n").getBytes("iso-8859-1"));
os.write((
"123456789\n"
).getBytes("utf-8"));
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
"host: "+HOST+":"+port+"\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-8\r\n"+
"content-length: 10\r\n"+
"\r\n"
@ -698,7 +649,7 @@ public class HttpServerTestBase extends TestCase
byte[] contentB=content.getBytes("utf-16");
os.write((
"POST /echo?charset=utf-8 HTTP/1.1\r\n"+
"host: "+HOST+":"+port+"\r\n"+
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
"content-type: text/plain; charset=utf-16\r\n"+
"content-length: "+contentB.length+"\r\n"+
"connection: close\r\n"+
@ -707,30 +658,24 @@ public class HttpServerTestBase extends TestCase
os.write(contentB);
os.flush();
String in = IO.toString(is);
assertTrue(in.indexOf("123456789")>=0);
assertTrue(in.indexOf("abcdefghi")>=0);
assertTrue(in.indexOf("Wibble")>=0);
}
finally
{
// Shut down
server.stop();
Thread.yield();
client.close();
}
}
/**
* Read entire response from the client. Close the output.
*
* @param client
* Open client socket.
*
*
* @param client Open client socket.
* @return The response string.
*
* @throws IOException
* @throws IOException in case of I/O problems
*/
private static String readResponse(Socket client) throws IOException
{
@ -760,41 +705,6 @@ public class HttpServerTestBase extends TestCase
}
}
protected HttpServerTestBase(Connector connector)
{
_connector=connector;
}
/**
* Create the server.
*
* @param handler
*
* @return Newly created server, ready to start.
*
* @throws Exception
*/
protected Server startServer(Handler handler) throws Exception
{
Server server=new Server();
_connector.setPort(0);
server.setConnectors(new Connector[]
{ _connector });
server.setHandler(handler);
configServer(server);
server.start();
port=_connector.getLocalPort();
return server;
}
protected void configServer(Server server)
{
}
private void writeFragments(byte[] bytes, int[] points, StringBuilder message, OutputStream os) throws IOException, InterruptedException
{
int last=0;
@ -819,12 +729,8 @@ public class HttpServerTestBase extends TestCase
Thread.sleep(PAUSE);
}
// ~ Inner Classes
// ----------------------------------------------------------
private static class EchoHandler extends AbstractHandler
{
// ~ Methods
// ------------------------------------------------------------
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
@ -835,12 +741,12 @@ public class HttpServerTestBase extends TestCase
response.setCharacterEncoding(request.getParameter("charset"));
else if (request.getCharacterEncoding()!=null)
response.setCharacterEncoding(request.getCharacterEncoding());
PrintWriter writer=response.getWriter();
BufferedReader reader=request.getReader();
int count=0;
String line;
while ((line=reader.readLine())!=null)
{
writer.print(line);
@ -850,20 +756,18 @@ public class HttpServerTestBase extends TestCase
if (count==0)
throw new IllegalStateException("no input recieved");
// just to be difficult
reader.close();
writer.close();
if (reader.read()>=0)
throw new IllegalStateException("Not closed");
}
}
// ----------------------------------------------------------
private static class HelloWorldHandler extends AbstractHandler
{
// ------------------------------------------------------------
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
@ -872,25 +776,23 @@ public class HttpServerTestBase extends TestCase
}
}
// ----------------------------------------------------------
private static class DataHandler extends AbstractHandler
{
// ------------------------------------------------------------
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
response.setStatus(200);
InputStream in = request.getInputStream();
String input=IO.toString(in);
String tmp = request.getParameter("writes");
int writes=Integer.parseInt(tmp==null?"10":tmp);
tmp = request.getParameter("block");
int block=Integer.parseInt(tmp==null?"10":tmp);
String encoding=request.getParameter("encoding");
String chars=request.getParameter("chars");
String chunk = (input+"\u0a870123456789A\u0a87CDEFGHIJKLMNOPQRSTUVWXYZ\u0250bcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
.substring(0,block);
response.setContentType("text/plain");
@ -909,15 +811,14 @@ public class HttpServerTestBase extends TestCase
for (int i=0;i<writes;i++)
out.write(c);
}
else
else
{
response.setCharacterEncoding(encoding);
Writer out=response.getWriter();
for (int i=0;i<writes;i++)
out.write(chunk);
}
}
}
}

View File

@ -4,23 +4,25 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.junit.BeforeClass;
/**
* HttpServer Tester.
*/
public class SelectChannelServerTest extends HttpServerTestBase
{
public SelectChannelServerTest()
@BeforeClass
public static void init() throws Exception
{
super(new SelectChannelConnector());
}
startServer(new SelectChannelConnector());
}
}

View File

@ -4,29 +4,25 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.junit.BeforeClass;
/**
* HttpServer Tester.
*/
public class SocketServerTest extends HttpServerTestBase
{
public SocketServerTest()
@BeforeClass
public static void init() throws Exception
{
super(new SocketConnector());
}
@Override
public void testFlush() throws Exception
{
super.testFlush();
startServer(new SocketConnector());
}
}

View File

@ -4,51 +4,47 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Queue;
import java.util.Random;
import java.util.Timer;
import java.util.concurrent.ConcurrentLinkedQueue;
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.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class StressTest extends TestCase
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class StressTest
{
protected Server _server = new Server();
protected TestHandler _handler = new TestHandler();
protected Connector _connector;
protected InetAddress _addr;
protected int _port;
protected volatile AtomicInteger[] _loops;
protected QueuedThreadPool _threads=new QueuedThreadPool(new BlockingArrayQueue<Runnable>(4,4));
// protected ExecutorThreadPool _threads=new ExecutorThreadPool(100,500,10000,TimeUnit.MILLISECONDS);
protected boolean _stress;
private AtomicInteger _handled=new AtomicInteger(0);
private ConcurrentLinkedQueue[] _latencies= {
private static boolean _stress;
private static QueuedThreadPool _threads;
private static Server _server;
private static SelectChannelConnector _connector;
private static final AtomicInteger _handled=new AtomicInteger(0);
private static final ConcurrentLinkedQueue[] _latencies= {
new ConcurrentLinkedQueue<Long>(),
new ConcurrentLinkedQueue<Long>(),
new ConcurrentLinkedQueue<Long>(),
@ -56,44 +52,10 @@ public class StressTest extends TestCase
new ConcurrentLinkedQueue<Long>(),
new ConcurrentLinkedQueue<Long>()
};
private Random _random=new Random();
@Override
protected void setUp() throws Exception
{
_stress= Boolean.getBoolean("STRESS");
_threads.setMaxThreads(500);
_server.setThreadPool(_threads);
SelectChannelConnector c_connector=new SelectChannelConnector();
c_connector.setAcceptors(1);
c_connector.setAcceptQueueSize(1000);
// c_connector.setPort(8080);
_connector=c_connector;
_connector.setMaxIdleTime(30000);
_server.setConnectors(new Connector[]{ _connector });
_server.setHandler(_handler);
_server.start();
_port=_connector.getLocalPort();
_addr=InetAddress.getLocalHost();
// _addr=Inet4Address.getByName("10.10.1.16");
// System.err.println("ADDR "+_addr+":"+_port);
for (Queue q:_latencies)
q.clear();
_handled.set(0);
}
@Override
protected void tearDown() throws Exception
{
_server.stop();
}
final static String[] __tests =
private volatile AtomicInteger[] _loops;
private final Random _random=new Random();
private static final String[] __tests =
{
"/path/0",
"/path/1",
@ -112,166 +74,103 @@ public class StressTest extends TestCase
"/path/e",
"/path/f",
};
public void doPaths(int thread,String name,boolean persistent) throws Exception
@BeforeClass
public static void init() throws Exception
{
if (persistent)
_stress= Boolean.getBoolean("STRESS");
_threads = new QueuedThreadPool(new BlockingArrayQueue<Runnable>(4,4));
_threads.setMaxThreads(500);
_server = new Server();
_server.setThreadPool(_threads);
_connector = new SelectChannelConnector();
_connector.setAcceptors(1);
_connector.setAcceptQueueSize(1000);
_connector.setMaxIdleTime(30000);
_server.addConnector(_connector);
TestHandler _handler = new TestHandler();
_server.setHandler(_handler);
_server.start();
}
@AfterClass
public static void destroy() throws Exception
{
_server.stop();
_server.join();
}
@Before
public void reset()
{
_handled.set(0);
for (Queue q : _latencies)
q.clear();
}
@Test
public void testNonPersistent() throws Throwable
{
if (_stress)
{
long start=System.currentTimeMillis();
Socket socket= new Socket(_addr,_port);
socket.setSoTimeout(30000);
socket.setSoLinger(false,0);
long connected=System.currentTimeMillis();
for (int i=0;i<__tests.length;i++)
{
String uri=__tests[i]+"/"+name+"/"+i;
String close=((i+1)<__tests.length)?"":"Connection: close\r\n";
String request =
"GET "+uri+" HTTP/1.1\r\n"+
"Host: localhost\r\n"+
"start: "+start+"\r\n"+
close+"\r\n";
socket.getOutputStream().write(request.getBytes());
socket.getOutputStream().flush();
Thread.yield();
}
long written=System.currentTimeMillis();
String response = IO.toString(socket.getInputStream());
socket.close();
long end=System.currentTimeMillis();
int bodies = count(response,"HTTP/1.1 200 OK");
if (__tests.length!=bodies)
System.err.println("responses=\n"+response+"\n---");
assertEquals(name,__tests.length,bodies);bodies = count(response,"HTTP/1.1 200 OK");
long bind=connected-start;
long flush=(written-connected)/__tests.length;
long read=(end-written)/__tests.length;
int offset=0;
for (int i=0;i<__tests.length;i++)
{
offset=response.indexOf("DATA "+__tests[i],offset);
assertTrue(offset>=0);
offset+=__tests[i].length()+5;
if (bind<0 || flush<0 || read <0)
{
System.err.println(bind+","+flush+","+read);
}
_latencies[0].add((i==0)?new Long(bind):0);
_latencies[1].add((i==0)?new Long(bind+flush):flush);
_latencies[5].add((i==0)?new Long(bind+flush+read):(flush+read));
}
System.err.println("STRESS!");
doThreads(200,100,false);
}
else
{
for (int i=0;i<__tests.length;i++)
{
String uri=__tests[i]+"/"+name+"/"+i;
long start=System.currentTimeMillis();
String close="Connection: close\r\n";
String request =
"GET "+uri+" HTTP/1.1\r\n"+
"Host: localhost\r\n"+
"start: "+start+"\r\n"+
close+"\r\n";
Socket socket = new Socket(_addr,_port);
socket.setSoTimeout(10000);
socket.setSoLinger(false,0);
_latencies[0].add(new Long(System.currentTimeMillis()-start));
socket.getOutputStream().write(request.getBytes());
socket.getOutputStream().flush();
_latencies[1].add(new Long(System.currentTimeMillis()-start));
String response = IO.toString(socket.getInputStream());
socket.close();
long end=System.currentTimeMillis();
response=response.substring(response.indexOf("\r\n\r\n")+4);
assertTrue(uri,response.startsWith("DATA "+__tests[i]));
long latency=end-start;
_latencies[5].add(new Long(latency));
}
}
}
public void doLoops(int thread, String name, int loops,boolean persistent) throws Exception
{
try
{
for (int i=0;i<loops;i++)
{
_loops[thread].set(i);
doPaths(thread,name+"-"+i,persistent);
Thread.sleep(1+_random.nextInt(10)*_random.nextInt(10));
Thread.sleep(10);
}
_loops[thread].set(loops);
}
catch(Exception e)
{
System.err.println(e);
_loops[thread].set(-_loops[thread].get());
throw e;
}
doThreads(10,20,false);
}
public void doThreads(int threads,final int loops,final boolean persistent) throws Throwable
@Test
public void testPersistent() throws Throwable
{
final Throwable[] throwable=new Throwable[threads];
final Thread[] thread=new Thread[threads];
if (_stress)
{
System.err.println("STRESS!");
doThreads(200,100,true);
}
else
doThreads(20,40,true);
}
private void doThreads(int threadCount, final int loops, final boolean persistent) throws Throwable
{
final Throwable[] throwables = new Throwable[threadCount];
final Thread[] threads = new Thread[threadCount];
try
{
for (int i=0;i<threads;i++)
for (int i=0;i< threadCount;i++)
{
final int id=i;
final String name = "T"+i;
thread[i]=new Thread()
threads[i]=new Thread()
{
@Override
public void run()
{
public void run()
{
try
{
doLoops(id,name,loops,persistent);
doLoops(id,name,loops,persistent);
}
catch(Throwable th)
{
th.printStackTrace();
throwable[id]=th;
}
finally
{
throwables[id]=th;
}
}
};
}
_loops=new AtomicInteger[threads];
for (int i=0;i<threads;i++)
_loops=new AtomicInteger[threadCount];
for (int i=0;i< threadCount;i++)
{
_loops[i]=new AtomicInteger(0);
thread[i].start();
threads[i].start();
}
String last=null;
@ -285,7 +184,7 @@ public class StressTest extends TestCase
int min=loops;
int max=0;
int total=0;
for (int i=0;i<threads;i++)
for (int i=0;i< threadCount;i++)
{
int l=_loops[i].get();
if (l<0)
@ -301,10 +200,10 @@ public class StressTest extends TestCase
max=l;
total+=l;
if (l==loops)
finished++;
}
finished++;
}
}
String status = "min/ave/max/target="+min+"/"+(total/threads)+"/"+max+"/"+loops+" errors/finished/loops="+errors+"/"+finished+"/"+threads+" idle/threads="+(_threads.getIdleThreads())+"/"+_threads.getThreads();
String status = "min/ave/max/target="+min+"/"+(total/ threadCount)+"/"+max+"/"+loops+" errors/finished/loops="+errors+"/"+finished+"/"+ threadCount +" idle/threads="+(_threads.getIdleThreads())+"/"+_threads.getThreads();
if (status.equals(last))
{
if (same++>5)
@ -320,19 +219,19 @@ public class StressTest extends TestCase
same=0;
last=status;
Log.info(_server.getThreadPool().toString()+" "+status);
if ((finished+errors)==threads)
if ((finished+errors)== threadCount)
break;
}
for (int i=0;i<threads;i++)
thread[i].join();
for (Thread thread : threads)
thread.join();
for (int i=0;i<threads;i++)
if (throwable[i]!=null)
throw throwable[i];
for (int i=0;i<_latencies.length;i++)
assertEquals(_handled.get(),_latencies[i].size());
for (Throwable throwable : throwables)
if (throwable!=null)
throw throwable;
for (ConcurrentLinkedQueue _latency : _latencies)
assertEquals(_handled.get(), _latency.size());
}
finally
{
@ -348,18 +247,18 @@ public class StressTest extends TestCase
length[i] = latencies.size();
loop:
for (long latency:(Queue<Long>)(_latencies[i]))
for (long latency : latencies)
{
for (int q=0;q<quantums;q++)
{
for (int q=0;q<quantums;q++)
if (latency>=(q*100) && latency<((q+1)*100))
{
if (latency>=(q*100) && latency<((q+1)*100))
{
count[i][q]++;
continue loop;
}
count[i][q]++;
continue loop;
}
other[i]++;
}
other[i]++;
}
}
System.out.println(" stage:\tbind\twrite\trecv\tdispatch\twrote\ttotal");
@ -387,76 +286,164 @@ public class StressTest extends TestCase
}
}
public void testNonPersistent() throws Throwable
private void doLoops(int thread, String name, int loops,boolean persistent) throws Exception
{
if (_stress)
try
{
System.err.println("STRESS!");
doThreads(200,100,false);
for (int i=0;i<loops;i++)
{
_loops[thread].set(i);
doPaths(thread,name+"-"+i,persistent);
Thread.sleep(1+_random.nextInt(10)*_random.nextInt(10));
Thread.sleep(10);
}
_loops[thread].set(loops);
}
catch(Exception e)
{
System.err.println(e);
_loops[thread].set(-_loops[thread].get());
throw e;
}
else
doThreads(10,20,false);
}
public void testPersistent() throws Throwable
private void doPaths(int thread,String name,boolean persistent) throws Exception
{
if (_stress)
if (persistent)
{
System.err.println("STRESS!");
doThreads(200,100,true);
long start=System.currentTimeMillis();
Socket socket= new Socket("localhost", _connector.getLocalPort());
socket.setSoTimeout(30000);
socket.setSoLinger(false,0);
long connected=System.currentTimeMillis();
for (int i=0;i<__tests.length;i++)
{
String uri=__tests[i]+"/"+name+"/"+i;
String close=((i+1)<__tests.length)?"":"Connection: close\r\n";
String request =
"GET "+uri+" HTTP/1.1\r\n"+
"Host: localhost\r\n"+
"start: "+start+"\r\n"+
close+"\r\n";
socket.getOutputStream().write(request.getBytes());
socket.getOutputStream().flush();
Thread.yield();
}
long written=System.currentTimeMillis();
String response = IO.toString(socket.getInputStream());
socket.close();
long end=System.currentTimeMillis();
int bodies = count(response,"HTTP/1.1 200 OK");
if (__tests.length!=bodies)
System.err.println("responses=\n"+response+"\n---");
assertEquals(name,__tests.length,bodies);
bodies = count(response,"HTTP/1.1 200 OK");
long bind=connected-start;
long flush=(written-connected)/__tests.length;
long read=(end-written)/__tests.length;
int offset=0;
for (int i=0;i<__tests.length;i++)
{
offset=response.indexOf("DATA "+__tests[i],offset);
assertTrue(offset>=0);
offset+=__tests[i].length()+5;
if (bind<0 || flush<0 || read <0)
{
System.err.println(bind+","+flush+","+read);
}
_latencies[0].add((i==0)?new Long(bind):0);
_latencies[1].add((i==0)?new Long(bind+flush):flush);
_latencies[5].add((i==0)?new Long(bind+flush+read):(flush+read));
}
}
else
doThreads(20,40,true);
{
for (int i=0;i<__tests.length;i++)
{
String uri=__tests[i]+"/"+name+"/"+i;
long start=System.currentTimeMillis();
String close="Connection: close\r\n";
String request =
"GET "+uri+" HTTP/1.1\r\n"+
"Host: localhost\r\n"+
"start: "+start+"\r\n"+
close+"\r\n";
Socket socket = new Socket("localhost", _connector.getLocalPort());
socket.setSoTimeout(10000);
socket.setSoLinger(false,0);
_latencies[0].add(new Long(System.currentTimeMillis()-start));
socket.getOutputStream().write(request.getBytes());
socket.getOutputStream().flush();
_latencies[1].add(new Long(System.currentTimeMillis()-start));
String response = IO.toString(socket.getInputStream());
socket.close();
long end=System.currentTimeMillis();
response=response.substring(response.indexOf("\r\n\r\n")+4);
assertTrue(uri,response.startsWith("DATA "+__tests[i]));
long latency=end-start;
_latencies[5].add(new Long(latency));
}
}
}
private int count(String s,String sub)
{
int count=0;
int index=s.indexOf(sub);
while(index>=0)
{
count++;
index=s.indexOf(sub,index+sub.length());
}
}
return count;
}
private class TestHandler extends HandlerWrapper
private static class TestHandler extends HandlerWrapper
{
private Timer _timer;
public TestHandler()
{
_timer=new Timer();
}
@Override
public void handle(String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
{
long now=System.currentTimeMillis();
long start=Long.parseLong(baseRequest.getHeader("start"));
long received=baseRequest.getTimeStamp();
_handled.incrementAndGet();
long delay=received-start;
if (delay<0)
delay=0;
_latencies[2].add(new Long(delay));
_latencies[3].add(new Long(now-start));
response.setStatus(200);
response.getOutputStream().print("DATA "+request.getPathInfo()+"\n\n");
baseRequest.setHandled(true);
long end=System.currentTimeMillis();
_latencies[4].add(new Long(System.currentTimeMillis()-start));
return;
}
}
}