View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
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   * AbstractLightLoadTest
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                          // Mangle the cookie, replacing Path with $Path, etc.
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                         // Wait for all workers to be ready
102                         barrier.await();
103                         long start = System.nanoTime();
104 
105                         // Wait for all workers to be done
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                         // Perform one request to get the result
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                 // Wait for all workers to be ready
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                 // Wait for all workers to be done
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                 // Without synchronization, because it is taken care by Jetty/Terracotta
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 }