KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > httpclient > TestHttpConnectionManager


1 /*
2  * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java,v 1.8.2.5 2004/03/28 21:06:24 mbecke Exp $
3  * $Revision: 1.8.2.5 $
4  * $Date: 2004/03/28 21:06:24 $
5  * ====================================================================
6  *
7  * Copyright 1999-2004 The Apache Software Foundation
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ====================================================================
21  *
22  * This software consists of voluntary contributions made by many
23  * individuals on behalf of the Apache Software Foundation. For more
24  * information on the Apache Software Foundation, please see
25  * <http://www.apache.org/>.
26  *
27  * [Additional notices, if required by prior licensing conditions]
28  *
29  */

30
31 package org.apache.commons.httpclient;
32
33 import java.io.IOException JavaDoc;
34 import java.lang.ref.WeakReference JavaDoc;
35
36 import junit.framework.Test;
37 import junit.framework.TestSuite;
38
39 import org.apache.commons.httpclient.methods.GetMethod;
40
41 /**
42  * Unit tests for {@link HttpConnectionManager}.
43  *
44  * @author Marc A. Saegesser
45  * @version $Id: TestHttpConnectionManager.java,v 1.8.2.5 2004/03/28 21:06:24 mbecke Exp $
46  */

47 public class TestHttpConnectionManager extends TestLocalHostBase {
48
49     // ------------------------------------------------------------ Constructor
50
public TestHttpConnectionManager(String JavaDoc testName) {
51         super(testName);
52     }
53
54     // ------------------------------------------------------------------- Main
55
public static void main(String JavaDoc args[]) {
56         String JavaDoc[] testCaseName = { TestHttpConnectionManager.class.getName() };
57         junit.textui.TestRunner.main(testCaseName);
58     }
59
60     // ------------------------------------------------------- TestCase Methods
61

62     public static Test suite() {
63         return new TestSuite(TestHttpConnectionManager.class);
64     }
65
66
67     // ----------------------------------------------------------- Test Methods
68

69     // Test the accessor methods
70
public void testMaxConnectionsAccessors() {
71         MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
72
73         // First test the default value
74
assertEquals("Default MaxConnections", 2, mgr.getMaxConnectionsPerHost());
75
76         mgr.setMaxConnectionsPerHost(10);
77         assertEquals("MaxConnections", 10, mgr.getMaxConnectionsPerHost());
78     }
79
80     /**
81      * Test that the ConnectMethod correctly releases connections when
82      * CONNECT fails.
83      */

84     public void testConnectMethodFailureRelease() {
85         
86         MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
87         mgr.setMaxTotalConnections(1);
88         
89         // we're going to execute a connect method against the localhost, assuming
90
// that CONNECT is not supported. This should test the fakeResponse()
91
// code on HttpMethodBase.
92
HostConfiguration hostConfiguration = new HostConfiguration();
93         hostConfiguration.setHost(getHost(), getPort(), getProtocol());
94         
95         GetMethod get = new GetMethod("/");
96         try {
97             HttpConnection connection = mgr.getConnection(hostConfiguration);
98             ConnectMethod connect = new ConnectMethod(get);
99             assertTrue(connect.execute(new HttpState(), connection) != 200);
100         } catch (IOException JavaDoc e) {
101             e.printStackTrace();
102             fail("Error executing connect: " + e);
103         }
104
105         // this should calling releaseConnection() releases the connection
106
try {
107             get.releaseConnection();
108             mgr.getConnection(hostConfiguration, 1).releaseConnection();
109         } catch (HttpException e1) {
110             fail("Connection should have been available.");
111         }
112         
113         get = new GetMethod("/");
114         
115         try {
116             HttpConnection connection = mgr.getConnection(hostConfiguration);
117             ConnectMethod connect = new ConnectMethod(get);
118             assertTrue(connect.execute(new HttpState(), connection) != 200);
119         } catch (IOException JavaDoc e) {
120             e.printStackTrace();
121             fail("Error executing connect: " + e);
122         }
123
124         // make sure reading the response fully releases the connection
125
try {
126             get.getResponseBodyAsString();
127             mgr.getConnection(hostConfiguration, 1).releaseConnection();
128         } catch (HttpException e1) {
129             fail("Connection should have been available.");
130         }
131         
132         get = new GetMethod("/");
133         
134         try {
135             HttpConnection connection = mgr.getConnection(hostConfiguration);
136             ConnectMethod connect = new ConnectMethod(get);
137             assertTrue(connect.execute(new HttpState(), connection) != 200);
138         } catch (IOException JavaDoc e) {
139             e.printStackTrace();
140             fail("Error executing connect: " + e);
141         }
142
143         // make sure closing the output stream releases the connection
144
try {
145             get.getResponseBodyAsStream().close();
146             mgr.getConnection(hostConfiguration, 1).releaseConnection();
147         } catch (HttpException e) {
148             fail("Connection should have been available.");
149         } catch (IOException JavaDoc e) {
150             e.printStackTrace();
151             fail("Close connection failed: " + e);
152         }
153     }
154
155     public void testGetConnection() {
156         MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
157
158         HostConfiguration hostConfiguration = new HostConfiguration();
159         hostConfiguration.setHost("www.nosuchserver.com", 80, "http");
160
161         // Create a new connection
162
HttpConnection conn = mgr.getConnection(hostConfiguration);
163         // Validate the connection properties
164
assertEquals("Host", "www.nosuchserver.com", conn.getHost());
165         assertEquals("Port", 80, conn.getPort());
166         // Release the connection
167
mgr.releaseConnection(conn);
168
169         // Create a new connection
170
hostConfiguration.setHost("www.nosuchserver.com", -1, "https");
171         conn = mgr.getConnection(hostConfiguration);
172         // Validate the connection properties
173
assertEquals("Host", "www.nosuchserver.com", conn.getHost());
174         assertEquals("Port", 443, conn.getPort());
175         // Release the connection
176
mgr.releaseConnection(conn);
177
178         // Create a new connection
179
hostConfiguration.setHost("www.nowhere.org", 8080, "http");
180         conn = mgr.getConnection(hostConfiguration);
181         // Validate the connection properties
182
assertEquals("Host", "www.nowhere.org", conn.getHost());
183         assertEquals("Port", 8080, conn.getPort());
184         // Release the connection
185
mgr.releaseConnection(conn);
186
187     }
188
189     public void testDroppedThread() throws Exception JavaDoc {
190
191         MultiThreadedHttpConnectionManager mthcm = new MultiThreadedHttpConnectionManager();
192         HttpClient httpClient = createHttpClient(mthcm);
193         WeakReference JavaDoc wr = new WeakReference JavaDoc(mthcm);
194
195         GetMethod method = new GetMethod("/");
196         httpClient.executeMethod(method);
197         method.releaseConnection();
198
199         mthcm = null;
200         httpClient = null;
201         method = null;
202         
203         System.gc();
204
205         // this sleep appears to be necessary in order to give the JVM
206
// time to clean up the miscellaneous pointers to the connection manager
207
try {
208             Thread.sleep(1000);
209         } catch (InterruptedException JavaDoc e) {
210             fail("shouldn't be interrupted.");
211         }
212
213         Object JavaDoc connectionManager = wr.get();
214         assertNull("connectionManager should be null", connectionManager);
215     }
216     
217     public void testWriteRequestReleaseConnection() {
218
219         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
220         connectionManager.setMaxConnectionsPerHost(1);
221
222         HttpClient client = createHttpClient(connectionManager);
223         
224         GetMethod get = new GetMethod("/") {
225             protected boolean writeRequestBody(HttpState state, HttpConnection conn)
226                 throws IOException JavaDoc, HttpException {
227                 throw new IOException JavaDoc("Oh no!!");
228             }
229         };
230         
231         try {
232             client.executeMethod(get);
233             fail("An exception should have occurred.");
234         } catch (HttpException e) {
235             e.printStackTrace();
236             fail("HttpException should not have occurred: " + e);
237         } catch (IOException JavaDoc e) {
238             // expected
239
}
240         
241         try {
242             connectionManager.getConnection(client.getHostConfiguration(), 1);
243         } catch (HttpException e) {
244             e.printStackTrace();
245             fail("Connection was not released: " + e);
246         }
247         
248     }
249     
250     public void testReleaseConnection() {
251
252         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
253         connectionManager.setMaxConnectionsPerHost(1);
254
255         HttpClient client = createHttpClient(connectionManager);
256         // we shouldn't have to wait if a connection is available
257
client.setHttpConnectionFactoryTimeout( 1 );
258
259         GetMethod getMethod = new GetMethod("/");
260
261         try {
262             client.executeMethod(getMethod);
263         } catch (Exception JavaDoc e) {
264             fail("error reading from server: " + e);
265         }
266
267         try {
268             // this should fail quickly since the connection has not been released
269
client.executeMethod(getMethod);
270             fail("a httpConnection should not be available");
271         } catch (HttpException e) {
272         } catch (IOException JavaDoc e) {
273             fail("error reading from server; " + e);
274         }
275
276         // this should release the connection
277
getMethod.releaseConnection();
278
279         getMethod = new GetMethod("/");
280
281         try {
282             // this should fail quickly if the connection has not been released
283
client.executeMethod(getMethod);
284         } catch (HttpException e) {
285             fail("httpConnection does not appear to have been released: " + e);
286         } catch (IOException JavaDoc e) {
287             fail("error reading from server; " + e);
288         }
289
290     }
291
292     /**
293      * Makes sure that a connection gets released after the content of the body
294      * is read.
295      */

296     public void testResponseAutoRelease() {
297
298         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
299         connectionManager.setMaxConnectionsPerHost(1);
300
301         HttpClient client = createHttpClient(connectionManager);
302         // we shouldn't have to wait if a connection is available
303
client.setHttpConnectionFactoryTimeout( 1 );
304
305         GetMethod getMethod = new GetMethod("/");
306
307         try {
308             client.executeMethod(getMethod);
309         } catch (Exception JavaDoc e) {
310             fail("error reading from server: " + e);
311         }
312         
313         // this should release the connection
314
getMethod.getResponseBody();
315
316         getMethod = new GetMethod("/");
317
318         try {
319             // this should fail quickly if the connection has not been released
320
client.executeMethod(getMethod);
321         } catch (HttpException e) {
322             fail("httpConnection does not appear to have been released: " + e);
323         } catch (IOException JavaDoc e) {
324             fail("error reading from server; " + e);
325         }
326
327     }
328     
329     /**
330      * Tests the MultiThreadedHttpConnectionManager's ability to reclaim unused
331      * connections.
332      */

333     public void testConnectionReclaiming() {
334         
335         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
336         connectionManager.setMaxConnectionsPerHost(1);
337         connectionManager.setMaxTotalConnections(1);
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 connection = connectionManager.getConnection(host1);
346         // now release this connection
347
connection.releaseConnection();
348         connection = null;
349         
350         try {
351             // the connection from host1 should be reclaimed
352
connection = connectionManager.getConnection(host2, 100);
353         } catch (HttpException e) {
354             e.printStackTrace();
355             fail("a httpConnection should have been available: " + e);
356         }
357     }
358     
359     /**
360      * Tests that {@link MultiThreadedHttpConnectionManager#shutdownAll()} closes all resources
361      * and makes all connection mangers unusable.
362      */

363     public void testShutdownAll() {
364
365         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
366         connectionManager.setMaxConnectionsPerHost(1);
367         connectionManager.setMaxTotalConnections(1);
368
369         HostConfiguration host1 = new HostConfiguration();
370         host1.setHost("host1", -1, "http");
371
372         // hold on to the only connection
373
HttpConnection connection = connectionManager.getConnection(host1);
374
375         // wait for a connection on another thread
376
GetConnectionThread getConn = new GetConnectionThread(host1, connectionManager, 0);
377         getConn.start();
378         
379         MultiThreadedHttpConnectionManager.shutdownAll();
380         
381         // now release this connection, this should close the connection, but have no other effect
382
connection.releaseConnection();
383         connection = null;
384         
385         try {
386             getConn.join();
387         } catch (InterruptedException JavaDoc e) {
388             e.printStackTrace();
389         }
390         
391         // this thread should have caught an exception without getting a connection
392
assertNull("Not connection should have been checked out", getConn.getConnection());
393         assertNotNull("There should have been an exception", getConn.getException());
394         
395         try {
396             connectionManager.getConnection(host1);
397             fail("An exception should have occurred");
398         } catch (Exception JavaDoc e) {
399             // this is expected
400
}
401     }
402         
403     /**
404      * Tests that {@link MultiThreadedHttpConnectionManager#shutdown()} closes all resources
405      * and makes the connection manger unusable.
406      */

407     public void testShutdown() {
408
409         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
410         connectionManager.setMaxConnectionsPerHost(1);
411         connectionManager.setMaxTotalConnections(1);
412
413         HostConfiguration host1 = new HostConfiguration();
414         host1.setHost("host1", -1, "http");
415
416         // hold on to the only connection
417
HttpConnection connection = connectionManager.getConnection(host1);
418
419         // wait for a connection on another thread
420
GetConnectionThread getConn = new GetConnectionThread(host1, connectionManager, 0);
421         getConn.start();
422         
423         connectionManager.shutdown();
424         
425         // now release this connection, this should close the connection, but have no other effect
426
connection.releaseConnection();
427         connection = null;
428         
429         try {
430             getConn.join();
431         } catch (InterruptedException JavaDoc e) {
432             e.printStackTrace();
433         }
434         
435         // this thread should have caught an exception without getting a connection
436
assertNull("Not connection should have been checked out", getConn.getConnection());
437         assertNotNull("There should have been an exception", getConn.getException());
438         
439         try {
440             connectionManager.getConnection(host1);
441             fail("An exception should have occurred");
442         } catch (Exception JavaDoc e) {
443             // this is expected
444
}
445     }
446     
447     /**
448      * Tests the MultiThreadedHttpConnectionManager's ability to restrict the maximum number
449      * of connections.
450      */

451     public void testMaxConnections() {
452         
453         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
454         connectionManager.setMaxConnectionsPerHost(1);
455         connectionManager.setMaxTotalConnections(2);
456
457         HostConfiguration host1 = new HostConfiguration();
458         host1.setHost("host1", -1, "http");
459
460         HostConfiguration host2 = new HostConfiguration();
461         host2.setHost("host2", -1, "http");
462
463         HttpConnection connection1 = connectionManager.getConnection(host1);
464         HttpConnection connection2 = connectionManager.getConnection(host2);
465     
466         try {
467             // this should fail quickly since the connection has not been released
468
connectionManager.getConnection(host2, 100);
469             fail("a httpConnection should not be available");
470         } catch (HttpException e) {
471             // this should throw an exception
472
}
473         
474         // release one of the connections
475
connection2.releaseConnection();
476         connection2 = null;
477         
478         try {
479             // there should be a connection available now
480
connection2 = connectionManager.getConnection(host2, 100);
481         } catch (HttpException e) {
482             e.printStackTrace();
483             fail("a httpConnection should have been available: " + e);
484         }
485     }
486
487     public void testHostReusePreference() {
488         
489         final MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
490         connectionManager.setMaxConnectionsPerHost(1);
491         connectionManager.setMaxTotalConnections(1);
492
493         final HostConfiguration host1 = new HostConfiguration();
494         host1.setHost("host1", -1, "http");
495
496         final HostConfiguration host2 = new HostConfiguration();
497         host2.setHost("host2", -1, "http");
498
499         HttpConnection connection = connectionManager.getConnection(host1);
500
501         GetConnectionThread getHost1 = new GetConnectionThread(host1, connectionManager, 200);
502         GetConnectionThread getHost2 = new GetConnectionThread(host2, connectionManager, 200);
503         
504         getHost2.start();
505         getHost1.start();
506         
507         // give the threads some time to startup
508
try {
509             Thread.sleep(100);
510         } catch (InterruptedException JavaDoc e1) {
511             e1.printStackTrace();
512         }
513             
514         // after the connection to host1 is released it should be given to getHost1
515
connection.releaseConnection();
516         connection = null;
517
518         try {
519             getHost1.join();
520             getHost2.join();
521         } catch (InterruptedException JavaDoc e) {
522             e.printStackTrace();
523         }
524
525         assertNotSame(
526             "Connection should have been given to someone",
527             getHost1.getConnection(),
528             getHost2.getConnection()
529         );
530         assertNotNull("Connection should have been given to host1", getHost1.getConnection());
531         assertNull("Connection should NOT have been given to host2", getHost2.getConnection());
532         
533     }
534     
535     public void testMaxConnectionsPerServer() {
536      
537         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
538         connectionManager.setMaxConnectionsPerHost(1);
539
540         HttpClient client = createHttpClient(connectionManager);
541         // we shouldn't have to wait if a connection is available
542
client.setHttpConnectionFactoryTimeout( 1 );
543
544         GetMethod getMethod = new GetMethod("/");
545
546         try {
547             client.executeMethod(getMethod);
548         } catch (Exception JavaDoc e) {
549             fail("error reading from server: " + e);
550         }
551
552         GetMethod getMethod2 = new GetMethod("/");
553
554         try {
555             // this should fail quickly since the connection has not been released
556
client.executeMethod(getMethod2);
557             fail("a httpConnection should not be available");
558         } catch (HttpException e) {
559         } catch (IOException JavaDoc e) {
560             fail("error reading from server; " + e);
561         }
562                 
563     }
564     
565     public void testReclaimUnusedConnection() {
566
567         MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
568         connectionManager.setMaxConnectionsPerHost(1);
569
570         HttpClient client = createHttpClient(connectionManager);
571         // we shouldn't have to wait if a connection is available
572
client.setHttpConnectionFactoryTimeout( 30000 );
573
574         GetMethod getMethod = new GetMethod("/");
575
576         try {
577             client.executeMethod(getMethod);
578         } catch (Exception JavaDoc e) {
579             fail("error reading from server: " + e);
580         }
581
582         getMethod = new GetMethod("/");
583         
584         Runtime.getRuntime().gc();
585
586         try {
587             // we didn't explicitly release the connection, but it should be
588
// reclaimed by the garbage collector, we hope:)
589
client.executeMethod(getMethod);
590         } catch (HttpException e) {
591             fail("httpConnection does not appear to have been reclaimed by the GC: " + e);
592         } catch (IOException JavaDoc e) {
593             fail("error reading from server; " + e);
594         }
595
596     }
597     
598     public void testGetFromMultipleThreads() {
599         
600         HttpClient client = createHttpClient(new MultiThreadedHttpConnectionManager());
601         ExecuteMethodThread[] threads = new ExecuteMethodThread[10];
602         
603         for (int i = 0; i < threads.length; i++) {
604             GetMethod method = new GetMethod("/");
605             method.setFollowRedirects(true);
606             
607             threads[i] = new ExecuteMethodThread(method, client);
608             threads[i].start();
609         }
610         
611         for (int i = 0; i < threads.length; i++) {
612             try {
613                 // wait until this thread finishes. we'll give it 10 seconds,
614
// but it shouldn't take that long
615
threads[i].join(10000);
616             } catch (InterruptedException JavaDoc e) {
617             }
618             // make sure an exception did not occur
619
Exception JavaDoc e = threads[i].getException();
620             if (e != null) {
621                 fail("An error occured in the get: " + e);
622             }
623             // we should have a 200 status
624
assertEquals(threads[i].getMethod().getStatusCode(), HttpStatus.SC_OK);
625         }
626     }
627
628     public void testTimeout() {
629         MultiThreadedHttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
630         mgr.setMaxConnectionsPerHost(2);
631         
632         try{
633             HostConfiguration hostConfig = new HostConfiguration();
634             hostConfig.setHost("www.nosuchserver.com", 80, "http");
635             
636             HttpConnection conn1 = mgr.getConnection(hostConfig);
637             HttpConnection conn2 = mgr.getConnection(hostConfig);
638             
639             HttpConnection conn3 = mgr.getConnection(hostConfig, 1000);
640             fail("Expected an HttpException.");
641             
642         }catch(HttpException e){
643             //Expected result
644
}
645     }
646     
647     static class GetConnectionThread extends Thread JavaDoc {
648         
649         private HostConfiguration hostConfiguration;
650         private MultiThreadedHttpConnectionManager connectionManager;
651         private HttpConnection connection;
652         private long timeout;
653         private Exception JavaDoc exception;
654         
655         public GetConnectionThread(
656             HostConfiguration hostConfiguration,
657             MultiThreadedHttpConnectionManager connectionManager,
658             long timeout
659         ) {
660             this.hostConfiguration = hostConfiguration;
661             this.connectionManager = connectionManager;
662             this.timeout = timeout;
663         }
664         
665         public void run() {
666             try {
667                 connection = connectionManager.getConnection(hostConfiguration, timeout);
668             } catch (Exception JavaDoc e) {
669                 exception = e;
670             }
671         }
672         
673         public Exception JavaDoc getException() {
674             return exception;
675         }
676         
677         public HttpConnection getConnection() {
678             return connection;
679         }
680
681     }
682     
683 }
684
685
Popular Tags