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