Issue #696 Improve testing of LocalConnector

Fixed some races in the implementation
This commit is contained in:
Greg Wilkins 2016-07-08 21:15:36 +10:00
parent 0d74658ab6
commit adf3281ba8
5 changed files with 235 additions and 9 deletions

View File

@ -282,9 +282,10 @@ public class ByteArrayEndPoint extends AbstractEndPoint
try(Locker.Lock lock = _locker.lock())
{
if (BufferUtil.isEmpty(_out) && !_closed && !_oshut)
while (BufferUtil.isEmpty(_out) && !_closed && !_oshut)
{
_hasOutput.await(time,unit);
}
b=_out;
_out=BufferUtil.allocate(b.capacity());
}
@ -570,5 +571,20 @@ public class ByteArrayEndPoint extends AbstractEndPoint
_growOutput=growOutput;
}
/* ------------------------------------------------------------ */
@Override
public String toString()
{
int q;
ByteBuffer b;
String o;
try(Locker.Lock lock = _locker.lock())
{
q=_inQ.size();
b=_inQ.peek();
o=BufferUtil.toDetailString(_out);
}
return String.format("%s[q=%d,q[0]=%s,o=%s]",super.toString(),q,b,o);
}
}

View File

@ -667,11 +667,24 @@ public class HttpInput extends ServletInputStream implements Runnable
@Override
public String toString()
{
return String.format("%s@%x[c=%d,s=%s]",
State state;
long consumed;
int q;
Content content;
synchronized (_inputQ)
{
state=_state;
consumed=_contentConsumed;
q=_inputQ.size();
content=_inputQ.peekFirst();
}
return String.format("%s@%x[c=%d,q=%d,[0]=%s,s=%s]",
getClass().getSimpleName(),
hashCode(),
_contentConsumed,
_state);
consumed,
q,
content,
state);
}
public static class PoisonPillContent extends Content

View File

@ -182,6 +182,13 @@ public class LocalConnector extends AbstractConnector
return endp;
}
public LocalEndPoint connect()
{
LocalEndPoint endp = new LocalEndPoint();
_connects.add(endp);
return endp;
}
@Override
protected void accept(int acceptorID) throws IOException, InterruptedException
{
@ -502,6 +509,9 @@ public class LocalConnector extends AbstractConnector
}
}
}
if (bout.getCount()==0 && isOutputShutdown())
return null;
return ByteBuffer.wrap(bout.getBuf(),0,bout.getCount());
}
}

View File

@ -71,6 +71,16 @@ public class DumpHandler extends AbstractHandler
if (!isStarted())
return;
if (Boolean.valueOf(request.getParameter("flush")))
response.flushBuffer();
if (Boolean.valueOf(request.getParameter("empty")))
{
baseRequest.setHandled(true);
response.setStatus(200);
return;
}
StringBuilder read = null;
if (request.getParameter("read")!=null)
{
@ -214,6 +224,7 @@ public class DumpHandler extends AbstractHandler
}
catch(IOException e)
{
e.printStackTrace();
writer.write(e.toString());
}
}

View File

@ -19,6 +19,8 @@
package org.eclipse.jetty.server;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
@ -27,6 +29,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.After;
import org.junit.Before;
@ -105,22 +108,195 @@ public class LocalConnectorTest
@Test
public void testOneResponse_10_keep_alive() throws Exception
{
String response=_connector.getResponse("GET /R1 HTTP/1.0\r\n" +
String response=_connector.getResponse(
"GET /R1 HTTP/1.0\r\n" +
"Connection: keep-alive\r\n" +
"\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
}
@Test
public void testOneResponse_10_keep_alive_empty() throws Exception
{
String response=_connector.getResponse(
"GET /R1?empty=true HTTP/1.0\r\n" +
"Connection: keep-alive\r\n" +
"\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,not(containsString("pathInfo=/R1")));
}
@Test
public void testOneResponse_11() throws Exception
{
String response=_connector.getResponse("GET /R1 HTTP/1.1\r\n" +
String response=_connector.getResponse(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
}
@Test
public void testOneResponse_11_close() throws Exception
{
String response=_connector.getResponse(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n" +
"\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
}
@Test
public void testOneResponse_11_empty() throws Exception
{
String response=_connector.getResponse(
"GET /R1?empty=true HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Connection: close\r\n" +
"\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,not(containsString("pathInfo=/R1")));
}
@Test
public void testOneResponse_11_chunked() throws Exception
{
String response=_connector.getResponse(
"GET /R1?flush=true HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
assertThat(response,containsString("\r\n0\r\n"));
}
@Test
public void testThreeResponsePipeline_11() throws Exception
{
LocalEndPoint endp = _connector.connect();
endp.addInput(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"+
"GET /R2 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"+
"GET /R3 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"
);
String response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R2"));
response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R3"));
}
@Test
public void testThreeResponse_11() throws Exception
{
LocalEndPoint endp = _connector.connect();
endp.addInput(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n");
String response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
endp.addInput(
"GET /R2 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n");
response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R2"));
endp.addInput(
"GET /R3 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"
);
response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R3"));
}
@Test
public void testThreeResponseClosed_11() throws Exception
{
LocalEndPoint endp = _connector.connect();
endp.addInput(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"+
"GET /R2 HTTP/1.1\r\n" +
"Connection: close\r\n" +
"Host: localhost\r\n" +
"\r\n"+
"GET /R3 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"\r\n"
);
String response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
response=endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R2"));
response=endp.getResponse();
assertThat(response,nullValue());
}
@Test
public void testExpectContinuesAvailable() throws Exception
{
LocalEndPoint endp = _connector.connect();
endp.addInput(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Content-Type: text/plain; charset=UTF-8\r\n" +
"Expect: 100-Continue\r\n" +
"Content-Length: 10\r\n" +
"\r\n"+
"01234567890\r\n");
String response = endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
assertThat(response,containsString("0123456789"));
}
@Test
public void testExpectContinues() throws Exception
{
LocalEndPoint endp = _connector.executeRequest(
"GET /R1 HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Content-Type: text/plain; charset=UTF-8\r\n" +
"Expect: 100-Continue\r\n" +
"Content-Length: 10\r\n" +
"\r\n");
String response = endp.getResponse();
assertThat(response,containsString("HTTP/1.1 100 Continue"));
endp.addInput("01234567890\r\n");
response = endp.getResponse();
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
assertThat(response,containsString("0123456789"));
}
@Test
public void testStopStart() throws Exception
@ -213,11 +389,11 @@ public class LocalConnectorTest
@Test
public void testGETandGET() throws Exception
{
String response=_connector.getResponses("GET /R1 HTTP/1.0\r\n\r\n");
String response=_connector.getResponse("GET /R1 HTTP/1.0\r\n\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R1"));
response=_connector.getResponses("GET /R2 HTTP/1.0\r\n\r\n");
response=_connector.getResponse("GET /R2 HTTP/1.0\r\n\r\n");
assertThat(response,containsString("HTTP/1.1 200 OK"));
assertThat(response,containsString("pathInfo=/R2"));
}