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