1919import org .asynchttpclient .AsyncHttpClient ;
2020import org .asynchttpclient .AsyncHttpClientConfig ;
2121import org .asynchttpclient .Response ;
22+ import org .junit .jupiter .api .AfterAll ;
2223import org .junit .jupiter .api .BeforeAll ;
2324import org .junit .jupiter .api .Test ;
2425import org .slf4j .Logger ;
2829import org .testcontainers .containers .output .Slf4jLogConsumer ;
2930import org .testcontainers .containers .wait .strategy .Wait ;
3031import org .testcontainers .images .builder .ImageFromDockerfile ;
31- import org .testcontainers .junit .jupiter .Container ;
3232import org .testcontainers .junit .jupiter .Testcontainers ;
3333
3434import java .nio .file .Path ;
4747public class HttpsProxyTestcontainersIntegrationTest {
4848
4949 private static final Logger LOGGER = LoggerFactory .getLogger (HttpsProxyTestcontainersIntegrationTest .class );
50-
50+
5151 private static final int SQUID_HTTP_PORT = 3128 ;
5252 private static final int SQUID_HTTPS_PORT = 3129 ;
53-
53+
5454 private static final String TARGET_HTTP_URL = "http://httpbin.org/get" ;
5555 private static final String TARGET_HTTPS_URL = "https://www.example.com/" ;
56-
56+
5757 private static boolean dockerAvailable = false ;
58-
58+ private static GenericContainer <?> squidProxy ;
59+
5960 @ BeforeAll
6061 static void checkDockerAvailability () {
6162 try {
@@ -65,136 +66,126 @@ static void checkDockerAvailability() {
6566 LOGGER .warn ("Failed to check Docker availability: {}" , e .getMessage ());
6667 dockerAvailable = false ;
6768 }
68-
6969 // Skip tests if Docker not available, unless force-enabled
7070 if (!dockerAvailable && !"true" .equals (System .getProperty ("docker.tests" ))) {
7171 assumeTrue (false , "Docker is not available - skipping integration tests. Use -Ddocker.tests=true to force run." );
7272 }
73-
7473 // Allow force-disabling Docker tests
7574 if ("true" .equals (System .getProperty ("no.docker.tests" ))) {
7675 assumeTrue (false , "Docker tests disabled via -Dno.docker.tests=true" );
7776 }
77+ // Only start container if Docker is available
78+ if (dockerAvailable ) {
79+ squidProxy = new GenericContainer <>(
80+ new ImageFromDockerfile ()
81+ .withFileFromPath ("Dockerfile" , Path .of ("src/test/resources/squid/Dockerfile" ))
82+ .withFileFromPath ("squid.conf" , Path .of ("src/test/resources/squid/squid.conf" ))
83+ )
84+ .withExposedPorts (SQUID_HTTP_PORT , SQUID_HTTPS_PORT )
85+ .withLogConsumer (new Slf4jLogConsumer (LOGGER ).withPrefix ("SQUID" ))
86+ .waitingFor (Wait .forLogMessage (".*Accepting HTTP.*" , 1 )
87+ .withStartupTimeout (Duration .ofMinutes (2 )));
88+ squidProxy .start ();
89+ }
7890 }
7991
80- /**
81- * Self-contained Squid proxy container that generates its own certificates and configuration.
82- * The container is automatically started before tests and stopped after tests.
83- */
84- @ Container
85- static final GenericContainer <?> squidProxy = new GenericContainer <>(
86- new ImageFromDockerfile ()
87- .withFileFromPath ("Dockerfile" , Path .of ("src/test/resources/squid/Dockerfile" ))
88- .withFileFromPath ("squid.conf" , Path .of ("src/test/resources/squid/squid.conf" ))
89- )
90- .withExposedPorts (SQUID_HTTP_PORT , SQUID_HTTPS_PORT )
91- .withLogConsumer (new Slf4jLogConsumer (LOGGER ).withPrefix ("SQUID" ))
92- .waitingFor (Wait .forLogMessage (".*Accepting HTTP.*" , 1 )
93- .withStartupTimeout (Duration .ofMinutes (2 )));
92+ @ AfterAll
93+ static void stopContainer () {
94+ if (squidProxy != null && squidProxy .isRunning ()) {
95+ squidProxy .stop ();
96+ }
97+ }
9498
9599 @ RepeatedIfExceptionsTest (repeats = 3 )
96100 public void testHttpProxyToHttpTarget () throws Exception {
101+ assumeTrue (dockerAvailable , "Docker is not available - skipping test" );
97102 LOGGER .info ("Testing HTTP proxy to HTTP target" );
98-
99103 AsyncHttpClientConfig config = config ()
100- .setProxyServer (proxyServer ("localhost" , squidProxy .getMappedPort (SQUID_HTTP_PORT ))
101- .setProxyType (ProxyType .HTTP )
102- .build ())
103- .setConnectTimeout (Duration .ofMillis (10000 ))
104- .setRequestTimeout (Duration .ofMillis (30000 ))
105- .build ();
106-
104+ .setProxyServer (proxyServer ("localhost" , squidProxy .getMappedPort (SQUID_HTTP_PORT ))
105+ .setProxyType (ProxyType .HTTP )
106+ .build ())
107+ .setConnectTimeout (Duration .ofMillis (10000 ))
108+ .setRequestTimeout (Duration .ofMillis (30000 ))
109+ .build ();
107110 try (AsyncHttpClient client = asyncHttpClient (config )) {
108111 Response response = client .executeRequest (get (TARGET_HTTP_URL )).get (30 , TimeUnit .SECONDS );
109-
110112 assertEquals (200 , response .getStatusCode ());
111113 assertTrue (response .getResponseBody ().contains ("httpbin" ));
112-
113114 LOGGER .info ("HTTP proxy to HTTP target test passed" );
114115 }
115116 }
116-
117+
117118 @ RepeatedIfExceptionsTest (repeats = 3 )
118119 public void testHttpsProxyToHttpTarget () throws Exception {
120+ assumeTrue (dockerAvailable , "Docker is not available - skipping test" );
119121 LOGGER .info ("Testing HTTPS proxy to HTTP target" );
120-
121122 AsyncHttpClientConfig config = config ()
122- .setProxyServer (proxyServer ("localhost" , squidProxy .getMappedPort (SQUID_HTTPS_PORT ))
123- .setProxyType (ProxyType .HTTPS )
124- .build ())
125- .setUseInsecureTrustManager (true ) // Accept self-signed proxy cert
126- .setConnectTimeout (Duration .ofMillis (10000 ))
127- .setRequestTimeout (Duration .ofMillis (30000 ))
128- .build ();
129-
123+ .setProxyServer (proxyServer ("localhost" , squidProxy .getMappedPort (SQUID_HTTPS_PORT ))
124+ .setProxyType (ProxyType .HTTPS )
125+ .build ())
126+ .setUseInsecureTrustManager (true )
127+ .setConnectTimeout (Duration .ofMillis (10000 ))
128+ .setRequestTimeout (Duration .ofMillis (30000 ))
129+ .build ();
130130 try (AsyncHttpClient client = asyncHttpClient (config )) {
131131 Response response = client .executeRequest (get (TARGET_HTTP_URL )).get (30 , TimeUnit .SECONDS );
132-
133132 assertEquals (200 , response .getStatusCode ());
134133 assertTrue (response .getResponseBody ().contains ("httpbin" ));
135-
136134 LOGGER .info ("HTTPS proxy to HTTP target test passed" );
137135 }
138136 }
139-
137+
140138 @ RepeatedIfExceptionsTest (repeats = 3 )
141139 public void testHttpProxyToHttpsTarget () throws Exception {
140+ assumeTrue (dockerAvailable , "Docker is not available - skipping test" );
142141 LOGGER .info ("Testing HTTP proxy to HTTPS target" );
143-
144142 AsyncHttpClientConfig config = config ()
145- .setProxyServer (proxyServer ("localhost" , squidProxy .getMappedPort (SQUID_HTTP_PORT ))
146- .setProxyType (ProxyType .HTTP )
147- .build ())
148- .setUseInsecureTrustManager (true ) // Accept any HTTPS target cert
149- .setConnectTimeout (Duration .ofMillis (10000 ))
150- .setRequestTimeout (Duration .ofMillis (30000 ))
151- .build ();
152-
143+ .setProxyServer (proxyServer ("localhost" , squidProxy .getMappedPort (SQUID_HTTP_PORT ))
144+ .setProxyType (ProxyType .HTTP )
145+ .build ())
146+ .setUseInsecureTrustManager (true )
147+ .setConnectTimeout (Duration .ofMillis (10000 ))
148+ .setRequestTimeout (Duration .ofMillis (30000 ))
149+ .build ();
153150 try (AsyncHttpClient client = asyncHttpClient (config )) {
154151 Response response = client .executeRequest (get (TARGET_HTTPS_URL )).get (30 , TimeUnit .SECONDS );
155-
156152 assertEquals (200 , response .getStatusCode ());
157- assertTrue (response .getResponseBody ().contains ("Example Domain" ) ||
158- response .getResponseBody ().contains ("example" ));
159-
153+ assertTrue (response .getResponseBody ().contains ("Example Domain" ) ||
154+ response .getResponseBody ().contains ("example" ));
160155 LOGGER .info ("HTTP proxy to HTTPS target test passed" );
161156 }
162157 }
163-
158+
164159 @ RepeatedIfExceptionsTest (repeats = 3 )
165160 public void testHttpsProxyToHttpsTarget () throws Exception {
161+ assumeTrue (dockerAvailable , "Docker is not available - skipping test" );
166162 LOGGER .info ("Testing HTTPS proxy to HTTPS target - validates issue #1907 fix" );
167-
168163 AsyncHttpClientConfig config = config ()
169- .setProxyServer (proxyServer ("localhost" , squidProxy .getMappedPort (SQUID_HTTPS_PORT ))
170- .setProxyType (ProxyType .HTTPS )
171- .build ())
172- .setUseInsecureTrustManager (true ) // Accept self-signed proxy cert and any HTTPS target cert
173- .setConnectTimeout (Duration .ofMillis (10000 ))
174- .setRequestTimeout (Duration .ofMillis (30000 ))
175- .build ();
176-
164+ .setProxyServer (proxyServer ("localhost" , squidProxy .getMappedPort (SQUID_HTTPS_PORT ))
165+ .setProxyType (ProxyType .HTTPS )
166+ .build ())
167+ .setUseInsecureTrustManager (true )
168+ .setConnectTimeout (Duration .ofMillis (10000 ))
169+ .setRequestTimeout (Duration .ofMillis (30000 ))
170+ .build ();
177171 try (AsyncHttpClient client = asyncHttpClient (config )) {
178172 Response response = client .executeRequest (get (TARGET_HTTPS_URL )).get (30 , TimeUnit .SECONDS );
179-
180173 assertEquals (200 , response .getStatusCode ());
181- assertTrue (response .getResponseBody ().contains ("Example Domain" ) ||
182- response .getResponseBody ().contains ("example" ));
183-
174+ assertTrue (response .getResponseBody ().contains ("Example Domain" ) ||
175+ response .getResponseBody ().contains ("example" ));
184176 LOGGER .info ("HTTPS proxy to HTTPS target test passed - core issue #1907 RESOLVED!" );
185177 }
186178 }
187-
179+
188180 @ Test
189181 public void testDockerInfrastructureReady () {
182+ assumeTrue (dockerAvailable , "Docker is not available - skipping test" );
190183 LOGGER .info ("Docker infrastructure test - validating container is ready" );
191184 LOGGER .info ("Squid HTTP proxy available at: localhost:{}" , squidProxy .getMappedPort (SQUID_HTTP_PORT ));
192185 LOGGER .info ("Squid HTTPS proxy available at: localhost:{}" , squidProxy .getMappedPort (SQUID_HTTPS_PORT ));
193-
194186 assertTrue (squidProxy .isRunning (), "Squid container should be running" );
195187 assertTrue (squidProxy .getMappedPort (SQUID_HTTP_PORT ) > 0 , "HTTP port should be mapped" );
196188 assertTrue (squidProxy .getMappedPort (SQUID_HTTPS_PORT ) > 0 , "HTTPS port should be mapped" );
197-
198189 LOGGER .info ("Docker infrastructure is ready and accessible" );
199190 }
200191}
0 commit comments