1
// ========================================================================
2
// Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
3
// ------------------------------------------------------------------------
4
// Licensed under the Apache License, Version 2.0 (the "License");
5
// you may not use this file except in compliance with the License.
6
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
8
// Unless required by applicable law or agreed to in writing, software
9
// distributed under the License is distributed on an "AS IS" BASIS,
10
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
// See the License for the specific language governing permissions and
12
// limitations under the License.
13
// ========================================================================
15
package org.mortbay.terracotta.servlet;
17
import java.io.IOException;
18
import java.io.PrintWriter;
19
import java.util.Random;
20
import java.util.concurrent.CyclicBarrier;
21
import java.util.concurrent.ExecutorService;
22
import java.util.concurrent.Executors;
23
import java.util.concurrent.TimeUnit;
25
import javax.servlet.ServletException;
26
import javax.servlet.http.HttpServlet;
27
import javax.servlet.http.HttpServletRequest;
28
import javax.servlet.http.HttpServletResponse;
29
import javax.servlet.http.HttpSession;
31
import org.mortbay.jetty.HttpMethods;
32
import org.mortbay.jetty.client.ContentExchange;
33
import org.mortbay.jetty.client.HttpClient;
34
import org.testng.annotations.Test;
37
* @version $Revision: 1457 $ $Date: 2009-02-26 16:09:48 +0100 (Do, 26. Feb 2009) $
39
public class LightLoadTest
41
private boolean _stress = Boolean.getBoolean( "STRESS" );
44
public void testLightLoad()
49
Random random = new Random( System.nanoTime() );
51
String contextPath = "";
52
String servletMapping = "/server";
53
int port1 = random.nextInt( 50000 ) + 10000;
54
TerracottaJettyServer server1 = new TerracottaJettyServer( port1 );
55
server1.addContext( contextPath ).addServlet( TestServlet.class, servletMapping );
59
int port2 = random.nextInt( 50000 ) + 10000;
60
TerracottaJettyServer server2 = new TerracottaJettyServer( port2 );
61
server2.addContext( contextPath ).addServlet( TestServlet.class, servletMapping );
65
HttpClient client = new HttpClient();
66
client.setConnectorType( HttpClient.CONNECTOR_SOCKET );
70
String[] urls = new String[2];
71
urls[0] = "http://localhost:" + port1 + contextPath + servletMapping;
72
urls[1] = "http://localhost:" + port2 + contextPath + servletMapping;
74
ContentExchange exchange1 = new ContentExchange( true );
75
exchange1.setMethod( HttpMethods.GET );
76
exchange1.setURL( urls[0] + "?action=init" );
77
client.send( exchange1 );
78
exchange1.waitForDone();
79
assert exchange1.getResponseStatus() == HttpServletResponse.SC_OK;
80
String sessionCookie = exchange1.getResponseFields().getStringField( "Set-Cookie" );
81
assert sessionCookie != null;
83
ExecutorService executor = Executors.newCachedThreadPool();
84
int clientsCount = 50;
85
CyclicBarrier barrier = new CyclicBarrier( clientsCount + 1 );
86
int requestsCount = 100;
87
Worker[] workers = new Worker[clientsCount];
88
for ( int i = 0; i < clientsCount; ++i )
90
workers[i] = new Worker( barrier, requestsCount, sessionCookie, urls );
92
executor.execute( workers[i] );
94
// Wait for all workers to be ready
96
long start = System.nanoTime();
98
// Wait for all workers to be done
100
long end = System.nanoTime();
101
long elapsed = TimeUnit.NANOSECONDS.toMillis( end - start );
102
System.out.println( "elapsed ms: " + elapsed );
104
for ( Worker worker : workers )
106
executor.shutdownNow();
108
// Perform one request to get the result
109
ContentExchange exchange2 = new ContentExchange( true );
110
exchange2.setMethod( HttpMethods.GET );
111
exchange2.setURL( urls[0] + "?action=result" );
112
exchange2.getRequestFields().add( "Cookie", sessionCookie );
113
client.send( exchange2 );
114
exchange2.waitForDone();
115
assert exchange2.getResponseStatus() == HttpServletResponse.SC_OK;
116
String response = exchange2.getResponseContent();
117
System.out.println( "get = " + response );
118
assert response.trim().equals( String.valueOf( clientsCount * requestsCount ) );
137
public static class Worker
140
private final HttpClient client;
142
private final CyclicBarrier barrier;
144
private final int requestsCount;
146
private final String sessionCookie;
148
private final String[] urls;
150
public Worker( CyclicBarrier barrier, int requestsCount, String sessionCookie, String[] urls )
152
this.client = new HttpClient();
153
this.client.setConnectorType( HttpClient.CONNECTOR_SOCKET );
154
this.barrier = barrier;
155
this.requestsCount = requestsCount;
156
this.sessionCookie = sessionCookie;
176
// Wait for all workers to be ready
179
Random random = new Random( System.nanoTime() );
181
for ( int i = 0; i < requestsCount; ++i )
183
int urlIndex = random.nextInt( urls.length );
185
ContentExchange exchange = new ContentExchange( true );
186
exchange.setMethod( HttpMethods.GET );
187
exchange.setURL( urls[urlIndex] + "?action=increment" );
188
exchange.getRequestFields().add( "Cookie", sessionCookie );
189
client.send( exchange );
190
exchange.waitForDone();
191
assert exchange.getResponseStatus() == HttpServletResponse.SC_OK;
194
// Wait for all workers to be done
197
catch ( Exception x )
199
throw new RuntimeException( x );
204
public static class TestServlet
208
protected void doGet( HttpServletRequest request, HttpServletResponse response )
209
throws ServletException, IOException
211
String action = request.getParameter( "action" );
212
if ( "init".equals( action ) )
214
HttpSession session = request.getSession( true );
215
session.setAttribute( "value", 0 );
217
else if ( "increment".equals( action ) )
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 );
224
else if ( "result".equals( action ) )
226
HttpSession session = request.getSession( false );
227
int value = (Integer) session.getAttribute( "value" );
228
PrintWriter writer = response.getWriter();
229
writer.println( value );