1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.server.session;
15
16 import java.io.IOException;
17 import java.io.PrintWriter;
18 import java.util.Random;
19 import java.util.concurrent.CyclicBarrier;
20 import java.util.concurrent.ExecutorService;
21 import java.util.concurrent.Executors;
22 import java.util.concurrent.TimeUnit;
23
24 import javax.servlet.ServletException;
25 import javax.servlet.http.HttpServlet;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpServletResponse;
28 import javax.servlet.http.HttpSession;
29
30 import org.eclipse.jetty.client.ContentExchange;
31 import org.eclipse.jetty.client.HttpClient;
32 import org.eclipse.jetty.http.HttpMethods;
33 import org.junit.Test;
34 import static org.junit.Assert.assertEquals;
35 import static org.junit.Assert.assertTrue;
36
37
38
39
40
41 public abstract class AbstractLightLoadTest
42 {
43 protected boolean _stress = Boolean.getBoolean( "STRESS" );
44
45 public abstract AbstractTestServer createServer(int port);
46
47 @Test
48 public void testLightLoad()
49 throws Exception
50 {
51 if ( _stress )
52 {
53 Random random = new Random( System.nanoTime() );
54
55 String contextPath = "";
56 String servletMapping = "/server";
57 int port1 = random.nextInt( 50000 ) + 10000;
58 AbstractTestServer server1 = createServer( port1 );
59 server1.addContext( contextPath ).addServlet( TestServlet.class, servletMapping );
60 server1.start();
61 try
62 {
63 int port2 = random.nextInt( 50000 ) + 10000;
64 AbstractTestServer server2 = createServer( port2 );
65 server2.addContext( contextPath ).addServlet( TestServlet.class, servletMapping );
66 server2.start();
67 try
68 {
69 HttpClient client = new HttpClient();
70 client.setConnectorType( HttpClient.CONNECTOR_SOCKET );
71 client.start();
72 try
73 {
74 String[] urls = new String[2];
75 urls[0] = "http://localhost:" + port1 + contextPath + servletMapping;
76 urls[1] = "http://localhost:" + port2 + contextPath + servletMapping;
77
78 ContentExchange exchange1 = new ContentExchange( true );
79 exchange1.setMethod( HttpMethods.GET );
80 exchange1.setURL( urls[0] + "?action=init" );
81 client.send( exchange1 );
82 exchange1.waitForDone();
83 assertEquals(HttpServletResponse.SC_OK,exchange1.getResponseStatus());
84 String sessionCookie = exchange1.getResponseFields().getStringField( "Set-Cookie" );
85 assertTrue(sessionCookie != null);
86
87 sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
88
89 ExecutorService executor = Executors.newCachedThreadPool();
90 int clientsCount = 50;
91 CyclicBarrier barrier = new CyclicBarrier( clientsCount + 1 );
92 int requestsCount = 100;
93 Worker[] workers = new Worker[clientsCount];
94 for ( int i = 0; i < clientsCount; ++i )
95 {
96 workers[i] = new Worker( barrier, requestsCount, sessionCookie, urls );
97 workers[i].start();
98 executor.execute( workers[i] );
99 }
100
101 barrier.await();
102 long start = System.nanoTime();
103
104
105 barrier.await();
106 long end = System.nanoTime();
107 long elapsed = TimeUnit.NANOSECONDS.toMillis( end - start );
108 System.out.println( "elapsed ms: " + elapsed );
109
110 for ( Worker worker : workers )
111 worker.stop();
112 executor.shutdownNow();
113
114
115 ContentExchange exchange2 = new ContentExchange( true );
116 exchange2.setMethod( HttpMethods.GET );
117 exchange2.setURL( urls[0] + "?action=result" );
118 exchange2.getRequestFields().add( "Cookie", sessionCookie );
119 client.send( exchange2 );
120 exchange2.waitForDone();
121 assertEquals(HttpServletResponse.SC_OK,exchange2.getResponseStatus());
122 String response = exchange2.getResponseContent();
123 System.out.println( "get = " + response );
124 assertEquals(response.trim(), String.valueOf( clientsCount * requestsCount ) );
125 }
126 finally
127 {
128 client.stop();
129 }
130 }
131 finally
132 {
133 server2.stop();
134 }
135 }
136 finally
137 {
138 server1.stop();
139 }
140 }
141 }
142
143 public static class Worker
144 implements Runnable
145 {
146 private final HttpClient client;
147
148 private final CyclicBarrier barrier;
149
150 private final int requestsCount;
151
152 private final String sessionCookie;
153
154 private final String[] urls;
155
156 public Worker( CyclicBarrier barrier, int requestsCount, String sessionCookie, String[] urls )
157 {
158 this.client = new HttpClient();
159 this.client.setConnectorType( HttpClient.CONNECTOR_SOCKET );
160 this.barrier = barrier;
161 this.requestsCount = requestsCount;
162 this.sessionCookie = sessionCookie;
163 this.urls = urls;
164 }
165
166 public void start()
167 throws Exception
168 {
169 client.start();
170 }
171
172 public void stop()
173 throws Exception
174 {
175 client.stop();
176 }
177
178 public void run()
179 {
180 try
181 {
182
183 barrier.await();
184
185 Random random = new Random( System.nanoTime() );
186
187 for ( int i = 0; i < requestsCount; ++i )
188 {
189 int urlIndex = random.nextInt( urls.length );
190
191 ContentExchange exchange = new ContentExchange( true );
192 exchange.setMethod( HttpMethods.GET );
193 exchange.setURL( urls[urlIndex] + "?action=increment" );
194 exchange.getRequestFields().add( "Cookie", sessionCookie );
195 client.send( exchange );
196 exchange.waitForDone();
197 assertEquals(HttpServletResponse.SC_OK,exchange.getResponseStatus());
198 }
199
200
201 barrier.await();
202 }
203 catch ( Exception x )
204 {
205 throw new RuntimeException( x );
206 }
207 }
208 }
209
210 public static class TestServlet
211 extends HttpServlet
212 {
213 @Override
214 protected void doGet( HttpServletRequest request, HttpServletResponse response )
215 throws ServletException, IOException
216 {
217 String action = request.getParameter( "action" );
218 if ( "init".equals( action ) )
219 {
220 HttpSession session = request.getSession( true );
221 session.setAttribute( "value", 0 );
222 }
223 else if ( "increment".equals( action ) )
224 {
225
226 HttpSession session = request.getSession( false );
227 int value = (Integer) session.getAttribute( "value" );
228 session.setAttribute( "value", value + 1 );
229 }
230 else if ( "result".equals( action ) )
231 {
232 HttpSession session = request.getSession( false );
233 int value = (Integer) session.getAttribute( "value" );
234 PrintWriter writer = response.getWriter();
235 writer.println( value );
236 writer.flush();
237 }
238 }
239 }
240 }