1 /* 2 * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v 1.8 2003/04/28 23:19:58 mbecke Exp $ 3 * $Revision: 1.8 $ 4 * $Date: 2003/04/28 23:19:58 $ 5 * ==================================================================== 6 * 7 * The Apache Software License, Version 1.1 8 * 9 * Copyright (c) 1999-2003 The Apache Software Foundation. All rights 10 * reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in 21 * the documentation and/or other materials provided with the 22 * distribution. 23 * 24 * 3. The end-user documentation included with the redistribution, if 25 * any, must include the following acknowlegement: 26 * "This product includes software developed by the 27 * Apache Software Foundation (http://www.apache.org/)." 28 * Alternately, this acknowlegement may appear in the software itself, 29 * if and wherever such third-party acknowlegements normally appear. 30 * 31 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software 32 * Foundation" must not be used to endorse or promote products derived 33 * from this software without prior written permission. For written 34 * permission, please contact apache@apache.org. 35 * 36 * 5. Products derived from this software may not be called "Apache" 37 * nor may "Apache" appear in their names without prior written 38 * permission of the Apache Group. 39 * 40 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 41 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 42 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 43 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 47 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 48 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 49 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 50 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * ==================================================================== 53 * 54 * This software consists of voluntary contributions made by many 55 * individuals on behalf of the Apache Software Foundation. For more 56 * information on the Apache Software Foundation, please see 57 * <http://www.apache.org/>;. 58 * 59 * [Additional notices, if required by prior licensing conditions] 60 * 61 */ 62 63 package org.apache.commons.httpclient; 64 65 import java.io.IOException; 66 67 import junit.framework.Test; 68 import junit.framework.TestSuite; 69 70 import org.apache.commons.httpclient.methods.GetMethod; 71 72 /*** 73 * Unit tests for {@link HttpConnectionManager}. 74 * 75 * @author Marc A. Saegesser 76 * @version $Id: TestHttpConnectionManager.java,v 1.8 2003/04/28 23:19:58 mbecke Exp $ 77 */ 78 public class TestHttpConnectionManager extends TestLocalHostBase { 79 80 // ------------------------------------------------------------ Constructor 81 public TestHttpConnectionManager(String testName) { 82 super(testName); 83 } 84 85 // ------------------------------------------------------------------- Main 86 public static void main(String args[]) { 87 String[] testCaseName = { TestHttpConnectionManager.class.getName() }; 88 junit.textui.TestRunner.main(testCaseName); 89 } 90 91 // ------------------------------------------------------- TestCase Methods 92 93 public static Test suite() { 94 return new TestSuite(TestHttpConnectionManager.class); 95 } 96 97 98 // ----------------------------------------------------------- Test Methods 99 100 // Test the accessor methods 101 public void testMaxConnectionsAccessors() { 102 MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager(); 103 104 // First test the default value 105 assertEquals("Default MaxConnections", 2, mgr.getMaxConnectionsPerHost()); 106 107 mgr.setMaxConnectionsPerHost(10); 108 assertEquals("MaxConnections", 10, mgr.getMaxConnectionsPerHost()); 109 } 110 111 /*** 112 * Test that the ConnectMethod correctly releases connections when 113 * CONNECT fails. 114 */ 115 public void testConnectMethodFailureRelease() { 116 117 MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager(); 118 mgr.setMaxTotalConnections(1); 119 120 // we're going to execute a connect method against the localhost, assuming 121 // that CONNECT is not supported. This should test the fakeResponse() 122 // code on HttpMethodBase. 123 HostConfiguration hostConfiguration = new HostConfiguration(); 124 hostConfiguration.setHost(getHost(), getPort(), getProtocol()); 125 126 GetMethod get = new GetMethod("/"); 127 try { 128 HttpConnection connection = mgr.getConnection(hostConfiguration); 129 ConnectMethod connect = new ConnectMethod(get); 130 assertTrue(connect.execute(new HttpState(), connection) != 200); 131 } catch (IOException e) { 132 e.printStackTrace(); 133 fail("Error executing connect: " + e); 134 } 135 136 // this should calling releaseConnection() releases the connection 137 try { 138 get.releaseConnection(); 139 mgr.getConnection(hostConfiguration, 1).releaseConnection(); 140 } catch (HttpException e1) { 141 fail("Connection should have been available."); 142 } 143 144 get = new GetMethod("/"); 145 146 try { 147 HttpConnection connection = mgr.getConnection(hostConfiguration); 148 ConnectMethod connect = new ConnectMethod(get); 149 assertTrue(connect.execute(new HttpState(), connection) != 200); 150 } catch (IOException e) { 151 e.printStackTrace(); 152 fail("Error executing connect: " + e); 153 } 154 155 // make sure reading the response fully releases the connection 156 try { 157 get.getResponseBodyAsString(); 158 mgr.getConnection(hostConfiguration, 1).releaseConnection(); 159 } catch (HttpException e1) { 160 fail("Connection should have been available."); 161 } 162 163 get = new GetMethod("/"); 164 165 try { 166 HttpConnection connection = mgr.getConnection(hostConfiguration); 167 ConnectMethod connect = new ConnectMethod(get); 168 assertTrue(connect.execute(new HttpState(), connection) != 200); 169 } catch (IOException e) { 170 e.printStackTrace(); 171 fail("Error executing connect: " + e); 172 } 173 174 // make sure closing the output stream releases the connection 175 try { 176 get.getResponseBodyAsStream().close(); 177 mgr.getConnection(hostConfiguration, 1).releaseConnection(); 178 } catch (HttpException e) { 179 fail("Connection should have been available."); 180 } catch (IOException e) { 181 e.printStackTrace(); 182 fail("Close connection failed: " + e); 183 } 184 } 185 186 public void testGetConnection() { 187 MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager(); 188 189 HostConfiguration hostConfiguration = new HostConfiguration(); 190 hostConfiguration.setHost("www.nosuchserver.com", 80, "http"); 191 192 // Create a new connection 193 HttpConnection conn = mgr.getConnection(hostConfiguration); 194 // Validate the connection properties 195 assertEquals("Host", "www.nosuchserver.com", conn.getHost()); 196 assertEquals("Port", 80, conn.getPort()); 197 // Release the connection 198 mgr.releaseConnection(conn); 199 200 // Create a new connection 201 hostConfiguration.setHost("www.nosuchserver.com", -1, "https"); 202 conn = mgr.getConnection(hostConfiguration); 203 // Validate the connection properties 204 assertEquals("Host", "www.nosuchserver.com", conn.getHost()); 205 assertEquals("Port", 443, conn.getPort()); 206 // Release the connection 207 mgr.releaseConnection(conn); 208 209 // Create a new connection 210 hostConfiguration.setHost("www.nowhere.org", 8080, "http"); 211 conn = mgr.getConnection(hostConfiguration); 212 // Validate the connection properties 213 assertEquals("Host", "www.nowhere.org", conn.getHost()); 214 assertEquals("Port", 8080, conn.getPort()); 215 // Release the connection 216 mgr.releaseConnection(conn); 217 218 } 219 220 public void testReleaseConnection() { 221 222 MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); 223 connectionManager.setMaxConnectionsPerHost(1); 224 225 HttpClient client = createHttpClient(connectionManager); 226 // we shouldn't have to wait if a connection is available 227 client.setHttpConnectionFactoryTimeout( 1 ); 228 229 GetMethod getMethod = new GetMethod("/"); 230 231 try { 232 client.executeMethod(getMethod); 233 } catch (Exception e) { 234 fail("error reading from server: " + e); 235 } 236 237 try { 238 // this should fail quickly since the connection has not been released 239 client.executeMethod(getMethod); 240 fail("a httpConnection should not be available"); 241 } catch (HttpException e) { 242 } catch (IOException e) { 243 fail("error reading from server; " + e); 244 } 245 246 // this should release the connection 247 getMethod.releaseConnection(); 248 249 getMethod = new GetMethod("/"); 250 251 try { 252 // this should fail quickly if the connection has not been released 253 client.executeMethod(getMethod); 254 } catch (HttpException e) { 255 fail("httpConnection does not appear to have been released: " + e); 256 } catch (IOException e) { 257 fail("error reading from server; " + e); 258 } 259 260 } 261 262 /*** 263 * Makes sure that a connection gets released after the content of the body 264 * is read. 265 */ 266 public void testResponseAutoRelease() { 267 268 MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); 269 connectionManager.setMaxConnectionsPerHost(1); 270 271 HttpClient client = createHttpClient(connectionManager); 272 // we shouldn't have to wait if a connection is available 273 client.setHttpConnectionFactoryTimeout( 1 ); 274 275 GetMethod getMethod = new GetMethod("/"); 276 277 try { 278 client.executeMethod(getMethod); 279 } catch (Exception e) { 280 fail("error reading from server: " + e); 281 } 282 283 // this should release the connection 284 getMethod.getResponseBody(); 285 286 getMethod = new GetMethod("/"); 287 288 try { 289 // this should fail quickly if the connection has not been released 290 client.executeMethod(getMethod); 291 } catch (HttpException e) { 292 fail("httpConnection does not appear to have been released: " + e); 293 } catch (IOException e) { 294 fail("error reading from server; " + e); 295 } 296 297 } 298 299 /*** 300 * Tests the MultiThreadedHttpConnectionManager's ability to reclaim unused 301 * connections. 302 */ 303 public void testConnectionReclaiming() { 304 305 MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); 306 connectionManager.setMaxConnectionsPerHost(1); 307 connectionManager.setMaxTotalConnections(1); 308 309 HostConfiguration host1 = new HostConfiguration(); 310 host1.setHost("host1", -1, "http"); 311 312 HostConfiguration host2 = new HostConfiguration(); 313 host2.setHost("host2", -1, "http"); 314 315 HttpConnection connection = connectionManager.getConnection(host1); 316 // now release this connection 317 connection.releaseConnection(); 318 connection = null; 319 320 try { 321 // the connection from host1 should be reclaimed 322 connection = connectionManager.getConnection(host2, 100); 323 } catch (HttpException e) { 324 e.printStackTrace(); 325 fail("a httpConnection should have been available: " + e); 326 } 327 } 328 329 /*** 330 * Tests the MultiThreadedHttpConnectionManager's ability to restrict the maximum number 331 * of connections. 332 */ 333 public void testMaxConnections() { 334 335 MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); 336 connectionManager.setMaxConnectionsPerHost(1); 337 connectionManager.setMaxTotalConnections(2); 338 339 HostConfiguration host1 = new HostConfiguration(); 340 host1.setHost("host1", -1, "http"); 341 342 HostConfiguration host2 = new HostConfiguration(); 343 host2.setHost("host2", -1, "http"); 344 345 HttpConnection connection1 = connectionManager.getConnection(host1); 346 HttpConnection connection2 = connectionManager.getConnection(host2); 347 348 try { 349 // this should fail quickly since the connection has not been released 350 connectionManager.getConnection(host2, 100); 351 fail("a httpConnection should not be available"); 352 } catch (HttpException e) { 353 // this should throw an exception 354 } 355 356 // release one of the connections 357 connection2.releaseConnection(); 358 connection2 = null; 359 360 try { 361 // there should be a connection available now 362 connection2 = connectionManager.getConnection(host2, 100); 363 } catch (HttpException e) { 364 e.printStackTrace(); 365 fail("a httpConnection should have been available: " + e); 366 } 367 } 368 369 public void testHostReusePreference() { 370 371 final MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); 372 connectionManager.setMaxConnectionsPerHost(1); 373 connectionManager.setMaxTotalConnections(1); 374 375 final HostConfiguration host1 = new HostConfiguration(); 376 host1.setHost("host1", -1, "http"); 377 378 final HostConfiguration host2 = new HostConfiguration(); 379 host2.setHost("host2", -1, "http"); 380 381 HttpConnection connection = connectionManager.getConnection(host1); 382 383 GetConnectionThread getHost1 = new GetConnectionThread(host1, connectionManager, 200); 384 GetConnectionThread getHost2 = new GetConnectionThread(host2, connectionManager, 200); 385 386 getHost2.start(); 387 getHost1.start(); 388 389 // give the threads some time to startup 390 try { 391 Thread.sleep(100); 392 } catch (InterruptedException e1) { 393 e1.printStackTrace(); 394 } 395 396 // after the connection to host1 is released it should be given to getHost1 397 connection.releaseConnection(); 398 connection = null; 399 400 try { 401 getHost1.join(); 402 getHost2.join(); 403 } catch (InterruptedException e) { 404 e.printStackTrace(); 405 } 406 407 assertNotSame( 408 "Connection should have been given to someone", 409 getHost1.getConnection(), 410 getHost2.getConnection() 411 ); 412 assertNotNull("Connection should have been given to host1", getHost1.getConnection()); 413 assertNull("Connection should NOT have been given to host2", getHost2.getConnection()); 414 415 } 416 417 public void testMaxConnectionsPerServer() { 418 419 MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); 420 connectionManager.setMaxConnectionsPerHost(1); 421 422 HttpClient client = createHttpClient(connectionManager); 423 // we shouldn't have to wait if a connection is available 424 client.setHttpConnectionFactoryTimeout( 1 ); 425 426 GetMethod getMethod = new GetMethod("/"); 427 428 try { 429 client.executeMethod(getMethod); 430 } catch (Exception e) { 431 fail("error reading from server: " + e); 432 } 433 434 GetMethod getMethod2 = new GetMethod("/"); 435 436 try { 437 // this should fail quickly since the connection has not been released 438 client.executeMethod(getMethod2); 439 fail("a httpConnection should not be available"); 440 } catch (HttpException e) { 441 } catch (IOException e) { 442 fail("error reading from server; " + e); 443 } 444 445 } 446 447 public void testReclaimUnusedConnection() { 448 449 MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); 450 connectionManager.setMaxConnectionsPerHost(1); 451 452 HttpClient client = createHttpClient(connectionManager); 453 // we shouldn't have to wait if a connection is available 454 client.setHttpConnectionFactoryTimeout( 30000 ); 455 456 GetMethod getMethod = new GetMethod("/"); 457 458 try { 459 client.executeMethod(getMethod); 460 } catch (Exception e) { 461 fail("error reading from server: " + e); 462 } 463 464 getMethod = new GetMethod("/"); 465 466 Runtime.getRuntime().gc(); 467 468 try { 469 // we didn't explicitly release the connection, but it should be 470 // reclaimed by the garbage collector, we hope:) 471 client.executeMethod(getMethod); 472 } catch (HttpException e) { 473 fail("httpConnection does not appear to have been reclaimed by the GC: " + e); 474 } catch (IOException e) { 475 fail("error reading from server; " + e); 476 } 477 478 } 479 480 public void testGetFromMultipleThreads() { 481 482 HttpClient client = createHttpClient(new MultiThreadedHttpConnectionManager()); 483 ExecuteMethodThread[] threads = new ExecuteMethodThread[10]; 484 485 for (int i = 0; i < threads.length; i++) { 486 GetMethod method = new GetMethod("/"); 487 method.setFollowRedirects(true); 488 489 threads[i] = new ExecuteMethodThread(method, client); 490 threads[i].start(); 491 } 492 493 for (int i = 0; i < threads.length; i++) { 494 try { 495 // wait until this thread finishes. we'll give it 10 seconds, 496 // but it shouldn't take that long 497 threads[i].join(10000); 498 } catch (InterruptedException e) { 499 } 500 // make sure an exception did not occur 501 Exception e = threads[i].getException(); 502 if (e != null) { 503 fail("An error occured in the get: " + e); 504 } 505 // we should have a 200 status 506 assertEquals(threads[i].getMethod().getStatusCode(), HttpStatus.SC_OK); 507 } 508 } 509 510 public void testTimeout() { 511 MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager(); 512 mgr.setMaxConnectionsPerHost(2); 513 514 try{ 515 HostConfiguration hostConfig = new HostConfiguration(); 516 hostConfig.setHost("www.nosuchserver.com", 80, "http"); 517 518 HttpConnection conn1 = mgr.getConnection(hostConfig); 519 HttpConnection conn2 = mgr.getConnection(hostConfig); 520 521 HttpConnection conn3 = mgr.getConnection(hostConfig, 1000); 522 fail("Expected an HttpException."); 523 524 }catch(HttpException e){ 525 //Expected result 526 } 527 } 528 529 static class GetConnectionThread extends Thread { 530 531 private HostConfiguration hostConfiguration; 532 private MultiThreadedHttpConnectionManager connectionManager; 533 private HttpConnection connection; 534 private long timeout; 535 536 public GetConnectionThread( 537 HostConfiguration hostConfiguration, 538 MultiThreadedHttpConnectionManager connectionManager, 539 long timeout 540 ) { 541 this.hostConfiguration = hostConfiguration; 542 this.connectionManager = connectionManager; 543 this.timeout = timeout; 544 } 545 546 public void run() { 547 try { 548 connection = connectionManager.getConnection(hostConfiguration, timeout); 549 } catch (HttpException e) { 550 } 551 } 552 553 public HttpConnection getConnection() { 554 return connection; 555 } 556 557 } 558 559 } 560

This page was automatically generated by Maven