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,44 +20,42 @@ 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 static Server _server;
private static AbstractConnector _connector;
private static CyclicBarrier _connect;
private static CountDownLatch _closed;
private String _request = "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n";
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() {
_connector = new SelectChannelConnector()
{
public void connectionClosed(Connection connection)
{
super.connectionClosed(connection);
@ -65,11 +63,11 @@ public class AbstractConnectorTest extends TestCase
}
};
_server.addConnector(_connector);
_connector.setStatsOn(true);
_server.addConnector(_connector);
HandlerWrapper wrapper =
new HandlerWrapper() {
HandlerWrapper wrapper = new HandlerWrapper()
{
public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
{
try
@ -88,8 +86,8 @@ public class AbstractConnectorTest extends TestCase
};
_server.setHandler(wrapper);
_handler =
new AbstractHandler() {
Handler handler = new AbstractHandler()
{
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
@ -102,30 +100,37 @@ public class AbstractConnectorTest extends TestCase
response.setStatus(HttpServletResponse.SC_OK);
}
};
wrapper.setHandler(_handler);
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);
doClose(connections);
assertEquals(1, _connector.getConnections());
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);
@ -133,13 +138,13 @@ public class AbstractConnectorTest extends TestCase
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);
@ -159,13 +164,13 @@ public class AbstractConnectorTest extends TestCase
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);
@ -193,7 +198,7 @@ public class AbstractConnectorTest extends TestCase
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());
}
@ -207,8 +212,7 @@ 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++)
{
@ -225,8 +229,7 @@ public class AbstractConnectorTest extends TestCase
_closed.await();
}
protected void sendRequest(int id, int count)
throws Exception
private void sendRequest(int id, int count) throws Exception
{
int idx = id - 1;
@ -239,7 +242,7 @@ public class AbstractConnectorTest extends TestCase
_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();

View File

@ -12,15 +12,18 @@
// ========================================================================
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

@ -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
{
@ -134,11 +130,4 @@ public class BusySelectChannelServerTest extends HttpServerTestBase
}
});
}
@Override
protected void configServer(Server server)
{
server.setThreadPool(new QueuedThreadPool());
}
}

View File

@ -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;
/**
* HttpServer Tester.
*/
public class HttpServerTestBase extends TestCase
{
private static boolean stress=Boolean.getBoolean("STRESS");
import org.junit.AfterClass;
import org.junit.Test;
// ~ Static fields/initializers
// ---------------------------------------------
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
/**
*
*/
public abstract class HttpServerTestBase
{
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,28 +104,44 @@ 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
// ----------------------------------------------------------------
/**
* Feed the server the entire request at once.
*
* @throws Exception
* @throws InterruptedException
*/
public void testRequest1_jetty() throws Exception, InterruptedException
@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.
*/
@Test
public void testRequest1_jetty() throws Exception
{
configureServer(new HelloWorldHandler());
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
Server server=startServer(new HelloWorldHandler());
Socket client=new Socket(HOST,port);
OutputStream os=client.getOutputStream();
os.write(REQUEST1.getBytes());
@ -134,20 +150,23 @@ public class HttpServerTestBase extends TestCase
// Read the response.
String response=readResponse(client);
// Shut down
client.close();
server.stop();
// Check the response
assertEquals("response",RESPONSE1,response);
}
finally
{
client.close();
}
}
/* --------------------------------------------------------------- */
@Test
public void testFragmentedChunk() throws Exception
{
configureServer(new EchoHandler());
Server server=startServer(new EchoHandler());
Socket client=new Socket(HOST,port);
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"
@ -162,29 +181,25 @@ public class HttpServerTestBase extends TestCase
// Read the response.
String response=readResponse(client);
// Shut down
client.close();
server.stop();
assertTrue(true); // nothing checked yet.
}
finally
{
client.close();
}
}
/**
/*
* Feed the server fragmentary headers and see how it copes with it.
*
* @throws Exception
* @throws InterruptedException
*/
@Test
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
{
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);
// Shut down
client.close();
}
finally
{
server.stop();
}
String response = readResponse(client);
// Check the response
assertEquals("response",RESPONSE1,response);
}
finally
{
client.close();
}
}
@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++)
{
Socket client=new Socket(HOST,port);
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
OutputStream os=client.getOutputStream();
os.write(bytes);
@ -229,35 +243,27 @@ 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();
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();
@ -272,7 +278,9 @@ public class HttpServerTestBase extends TestCase
// 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,27 +288,22 @@ 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();
client.close();
}
}
}
@Test
public void testRequest2Iterate_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<bytes.length; i+=3)
{
int[] points=new int[] { i };
@ -311,7 +314,9 @@ public class HttpServerTestBase extends TestCase
// 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);
@ -319,27 +324,24 @@ 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();
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[][]
{
@ -348,13 +350,11 @@ public class HttpServerTestBase extends TestCase
{ 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)
{
Socket client=new Socket(HOST,port);
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
OutputStream os=client.getOutputStream();
StringBuilder message=new StringBuilder();
@ -364,33 +364,23 @@ 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();
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());
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)
@ -402,48 +392,38 @@ public class HttpServerTestBase extends TestCase
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":""));
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)
catch(Exception x)
{
System.err.println(test);
throw ex;
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"+
@ -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);
Socket client=new Socket(HOST,_connector.getLocalPort());
try
{
client.setSoTimeout(5000);
OutputStream os=client.getOutputStream();
@ -514,7 +486,7 @@ 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"+
@ -522,7 +494,7 @@ public class HttpServerTestBase extends TestCase
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,42 +516,27 @@ public class HttpServerTestBase extends TestCase
}
assertEquals(pipeline,count);
}
}
finally
{
// Shut down
server.stop();
Thread.yield();
client.close();
}
}
}
}
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"));
@ -590,7 +547,7 @@ public class HttpServerTestBase extends TestCase
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"+
@ -640,7 +597,6 @@ public class HttpServerTestBase extends TestCase
}
}
String in = new String(b,0,i,"utf-8");
assertTrue(in.indexOf("123456789")>=0);
assertTrue(in.indexOf("abcdefghZ")>=0);
@ -648,32 +604,27 @@ public class HttpServerTestBase extends TestCase
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"));
@ -684,7 +635,7 @@ public class HttpServerTestBase extends TestCase
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"+
@ -712,25 +663,19 @@ public class HttpServerTestBase extends TestCase
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);
@ -860,10 +766,8 @@ public class HttpServerTestBase extends TestCase
}
}
// ----------------------------------------------------------
private static class HelloWorldHandler extends AbstractHandler
{
// ------------------------------------------------------------
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
@ -872,10 +776,8 @@ 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);
@ -919,5 +821,4 @@ public class HttpServerTestBase extends TestCase
}
}
}

View File

@ -13,14 +13,16 @@
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

@ -13,20 +13,16 @@
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

@ -14,41 +14,37 @@
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",
@ -113,140 +75,80 @@ public class StressTest extends TestCase
"/path/f",
};
public void doPaths(int thread,String name,boolean persistent) throws Exception
@BeforeClass
public static void init() throws Exception
{
if (persistent)
{
long start=System.currentTimeMillis();
Socket socket= new Socket(_addr,_port);
socket.setSoTimeout(30000);
socket.setSoLinger(false,0);
_stress= Boolean.getBoolean("STRESS");
long connected=System.currentTimeMillis();
_threads = new QueuedThreadPool(new BlockingArrayQueue<Runnable>(4,4));
_threads.setMaxThreads(500);
for (int i=0;i<__tests.length;i++)
{
String uri=__tests[i]+"/"+name+"/"+i;
_server = new Server();
_server.setThreadPool(_threads);
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";
_connector = new SelectChannelConnector();
_connector.setAcceptors(1);
_connector.setAcceptQueueSize(1000);
_connector.setMaxIdleTime(30000);
_server.addConnector(_connector);
socket.getOutputStream().write(request.getBytes());
socket.getOutputStream().flush();
Thread.yield();
TestHandler _handler = new TestHandler();
_server.setHandler(_handler);
_server.start();
}
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++)
@AfterClass
public static void destroy() throws Exception
{
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);
_server.stop();
_server.join();
}
_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));
@Before
public void reset()
{
_handled.set(0);
for (Queue q : _latencies)
q.clear();
}
@Test
public void testNonPersistent() throws Throwable
{
if (_stress)
{
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));
}
}
doThreads(10,20,false);
}
public void doLoops(int thread, String name, int loops,boolean persistent) throws Exception
@Test
public void testPersistent() throws Throwable
{
try
if (_stress)
{
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;
System.err.println("STRESS!");
doThreads(200,100,true);
}
else
doThreads(20,40,true);
}
public void doThreads(int threads,final int loops,final boolean persistent) throws Throwable
private void doThreads(int threadCount, final int loops, final boolean persistent) throws Throwable
{
final Throwable[] throwable=new Throwable[threads];
final Thread[] thread=new Thread[threads];
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()
@ -258,20 +160,17 @@ public class StressTest extends TestCase
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)
@ -304,7 +203,7 @@ public class StressTest extends TestCase
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 (Throwable throwable : throwables)
if (throwable!=null)
throw throwable;
for (int i=0;i<_latencies.length;i++)
assertEquals(_handled.get(),_latencies[i].size());
for (ConcurrentLinkedQueue _latency : _latencies)
assertEquals(_handled.get(), _latency.size());
}
finally
{
@ -348,7 +247,7 @@ 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++)
{
@ -387,29 +286,126 @@ 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;
}
}
private void doPaths(int thread,String name,boolean persistent) throws Exception
{
if (persistent)
{
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(10,20,false);
}
public void testPersistent() throws Throwable
{
if (_stress)
for (int i=0;i<__tests.length;i++)
{
System.err.println("STRESS!");
doThreads(200,100,true);
}
else
doThreads(20,40,true);
}
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)
{
@ -424,15 +420,8 @@ public class StressTest extends TestCase
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
{
@ -457,6 +446,4 @@ public class StressTest extends TestCase
return;
}
}
}