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 public abstract class AbstractLightLoadTest
48 {
49 protected boolean _stress = Boolean.getBoolean( "STRESS" );
50
51 public abstract AbstractTestServer createServer(int port);
52
53 @Test
54 public void testLightLoad()
55 throws Exception
56 {
57 if ( _stress )
58 {
59 String contextPath = "";
60 String servletMapping = "/server";
61 AbstractTestServer server1 = createServer( 0 );
62 server1.addContext( contextPath ).addServlet( TestServlet.class, servletMapping );
63
64 try
65 {
66 server1.start();
67 int port1 = server1.getPort();
68 AbstractTestServer server2 = createServer( 0 );
69 server2.addContext( contextPath ).addServlet( TestServlet.class, servletMapping );
70
71 try
72 {
73 server2.start();
74 int port2=server2.getPort();
75 HttpClient client = new HttpClient();
76 client.start();
77 try
78 {
79 String[] urls = new String[2];
80 urls[0] = "http://localhost:" + port1 + contextPath + servletMapping;
81 urls[1] = "http://localhost:" + port2 + contextPath + servletMapping;
82
83 ContentResponse response1 = client.GET(urls[0] + "?action=init");
84 assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
85 String sessionCookie = response1.getHeaders().getStringField( "Set-Cookie" );
86 assertTrue(sessionCookie != null);
87
88 sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
89
90 ExecutorService executor = Executors.newCachedThreadPool();
91 int clientsCount = 50;
92 CyclicBarrier barrier = new CyclicBarrier( clientsCount + 1 );
93 int requestsCount = 100;
94 Worker[] workers = new Worker[clientsCount];
95 for ( int i = 0; i < clientsCount; ++i )
96 {
97 workers[i] = new Worker( barrier, requestsCount, sessionCookie, urls );
98 workers[i].start();
99 executor.execute( workers[i] );
100 }
101
102 barrier.await();
103 long start = System.nanoTime();
104
105
106 barrier.await();
107 long end = System.nanoTime();
108 long elapsed = TimeUnit.NANOSECONDS.toMillis( end - start );
109 System.out.println( "elapsed ms: " + elapsed );
110
111 for ( Worker worker : workers )
112 worker.stop();
113 executor.shutdownNow();
114
115
116 Request request = client.newRequest( urls[0] + "?action=result" );
117 request.header("Cookie", sessionCookie);
118 ContentResponse response2 = request.send();
119 assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
120 String response = response2.getContentAsString();
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
155 public Worker( CyclicBarrier barrier, int requestsCount, String sessionCookie, String[] urls )
156 {
157 this.client = new HttpClient();
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 Request request = client.newRequest(urls[urlIndex] + "?action=increment");
189 request.header("Cookie", sessionCookie);
190 ContentResponse response = request.send();
191 assertEquals(HttpServletResponse.SC_OK,response.getStatus());
192 }
193
194
195 barrier.await();
196 }
197 catch ( Exception x )
198 {
199 throw new RuntimeException( x );
200 }
201 }
202 }
203
204 public static class TestServlet
205 extends HttpServlet
206 {
207 @Override
208 protected void doGet( HttpServletRequest request, HttpServletResponse response )
209 throws ServletException, IOException
210 {
211 String action = request.getParameter( "action" );
212 if ( "init".equals( action ) )
213 {
214 HttpSession session = request.getSession( true );
215 session.setAttribute( "value", 0 );
216 }
217 else if ( "increment".equals( action ) )
218 {
219
220 HttpSession session = request.getSession( false );
221 int value = (Integer) session.getAttribute( "value" );
222 session.setAttribute( "value", value + 1 );
223 }
224 else if ( "result".equals( action ) )
225 {
226 HttpSession session = request.getSession( false );
227 int value = (Integer) session.getAttribute( "value" );
228 PrintWriter writer = response.getWriter();
229 writer.println( value );
230 writer.flush();
231 }
232 }
233 }
234 }