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