1919import org .junit .jupiter .api .BeforeAll ;
2020import org .junit .jupiter .api .Test ;
2121
22- import java .io .File ;
2322import java .io .IOException ;
24- import java .net .InetSocketAddress ;
23+ import java .net .HttpURLConnection ;
2524import java .net .ServerSocket ;
26- import java .net .Socket ;
27- import java .net . SocketTimeoutException ;
25+ import java .net .URL ;
26+ import java .util . concurrent . Callable ;
2827
2928import static org .assertj .core .api .Assertions .assertThat ;
3029
3130class HttpClientTest {
3231
3332 private static int port ;
3433
34+ private static String uri ;
35+
3536 private static Process process ;
3637
3738 @ BeforeAll
@@ -40,15 +41,16 @@ static void beforeAll() throws IOException {
4041 port = findAvailablePort ();
4142 System .out .println ("Found port: " + port );
4243
44+ uri = "http://localhost:%d/" .formatted (port );
45+
4346 System .out .println ("Starting nginx ..." );
4447 process = new ProcessBuilder (
4548 "docker" , "run" , "--rm" , "-p" , port + ":80" , "nginx:1-alpine-slim" )
46- .redirectOutput (new File ("nginx-stdout.txt" ))
47- .redirectError (new File ("nginx-stderr.txt" ))
49+ .inheritIO ()
4850 .start ();
4951
5052 // Wait until connection can be established
51- waitUntilContainerStarted ( 60 );
53+ waitUntil (() -> openConnection ( uri ), 60 , 1 );
5254
5355 System .out .println ("nginx started" );
5456 }
@@ -62,42 +64,34 @@ private static int findAvailablePort() throws IOException {
6264 }
6365 }
6466
65- private static void waitUntilContainerStarted (int startupTimeoutSeconds ) {
66- System .out .println ("Waiting for nginx container to become available" );
67+ private static boolean openConnection (String uri ) throws Exception {
68+ HttpURLConnection connection = (HttpURLConnection ) new URL (uri ).openConnection ();
69+ connection .setReadTimeout (1000 );
70+ connection .setRequestMethod ("GET" );
71+ connection .connect ();
72+ return HttpURLConnection .HTTP_OK == connection .getResponseCode ();
73+ }
6774
68- Exception lastConnectionException = null ;
75+ private static void waitUntil (Callable <Boolean > conditionEvaluator , int timeoutSeconds , int sleepTimeSeconds ) {
76+ Exception lastException = null ;
6977
70- long end = System .currentTimeMillis () + startupTimeoutSeconds * 1000L ;
78+ long end = System .currentTimeMillis () + timeoutSeconds * 1000L ;
7179 while (System .currentTimeMillis () < end ) {
7280 try {
73- Thread .sleep (100L );
81+ Thread .sleep (sleepTimeSeconds * 1000L );
7482 } catch (InterruptedException e ) {
7583 // continue
7684 }
77- try (Socket socket = new Socket ()) {
78- socket .setSoTimeout (100 );
79- socket .connect (new InetSocketAddress ("localhost" , port ), 100 );
80- if (!check (socket )) {
81- continue ;
85+ try {
86+ if (conditionEvaluator .call ()) {
87+ return ;
8288 }
83- return ;
8489 } catch (Exception e ) {
85- lastConnectionException = e ;
86- }
87- }
88- throw new IllegalStateException ("nginx container cannot be accessed on localhost:" + port , lastConnectionException );
89- }
90-
91- private static boolean check (Socket socket ) throws IOException {
92- try {
93- // -1 indicates the socket has been closed immediately
94- // Other responses or a timeout are considered as success
95- if (socket .getInputStream ().read () == -1 ) {
96- return false ;
90+ lastException = e ;
9791 }
98- } catch (SocketTimeoutException ex ) {
9992 }
100- return true ;
93+ String errorMessage = "Condition was not fulfilled within " + timeoutSeconds + " seconds" ;
94+ throw lastException == null ? new IllegalStateException (errorMessage ) : new IllegalStateException (errorMessage , lastException );
10195 }
10296
10397 @ AfterAll
@@ -116,7 +110,7 @@ void testBasicSchemeDeserialization() throws Exception {
116110 HttpClientContext context = HttpClientContext .create ();
117111 context .setAuthCache (authCache );
118112
119- HttpGet httpGet = new HttpGet ("http://localhost:%d/" . formatted ( port ) );
113+ HttpGet httpGet = new HttpGet (uri );
120114 try (CloseableHttpClient httpclient = HttpClients .createDefault ()) {
121115 try (CloseableHttpResponse response = httpclient .execute (httpGet , context )) {
122116 assertThat (response .getStatusLine ().getStatusCode ()).isEqualTo (200 );
0 commit comments