233 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			233 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package controllers;
 | |
| 
 | |
| import static java.time.temporal.ChronoUnit.SECONDS;
 | |
| import static org.junit.Assert.assertEquals;
 | |
| import static play.mvc.Http.Status.SERVICE_UNAVAILABLE;
 | |
| 
 | |
| import akka.Done;
 | |
| import akka.actor.ActorSystem;
 | |
| import akka.stream.ActorMaterializer;
 | |
| import akka.stream.javadsl.Sink;
 | |
| import akka.util.ByteString;
 | |
| import java.io.IOException;
 | |
| import java.io.OutputStream;
 | |
| import java.nio.file.Files;
 | |
| import java.nio.file.Path;
 | |
| import java.time.Duration;
 | |
| import java.util.OptionalInt;
 | |
| import java.util.concurrent.CompletionStage;
 | |
| import java.util.concurrent.CountDownLatch;
 | |
| import java.util.concurrent.ExecutionException;
 | |
| import java.util.concurrent.TimeUnit;
 | |
| import java.util.concurrent.TimeoutException;
 | |
| import java.util.concurrent.atomic.AtomicInteger;
 | |
| import java.util.stream.IntStream;
 | |
| import org.apache.http.HttpStatus;
 | |
| import org.junit.Before;
 | |
| import org.junit.Test;
 | |
| import org.slf4j.Logger;
 | |
| import org.slf4j.LoggerFactory;
 | |
| import play.Application;
 | |
| import play.inject.guice.GuiceApplicationBuilder;
 | |
| import play.libs.concurrent.Futures;
 | |
| import play.libs.ws.WSClient;
 | |
| import play.libs.ws.WSResponse;
 | |
| import play.libs.ws.ahc.AhcCurlRequestLogger;
 | |
| import play.mvc.Result;
 | |
| import play.mvc.Results;
 | |
| import play.test.WithServer;
 | |
| 
 | |
| public class HomeControllerTest extends WithServer {
 | |
| 
 | |
|     private final Logger log = LoggerFactory.getLogger(HomeControllerTest.class);
 | |
|     private String url;
 | |
|     private int port;
 | |
| 
 | |
|     @Override
 | |
|     protected Application provideApplication() {
 | |
|         return new GuiceApplicationBuilder().build();
 | |
|     }
 | |
| 
 | |
|     @Before
 | |
|     public void setup() {
 | |
|         OptionalInt optHttpsPort = testServer.getRunningHttpsPort();
 | |
|         if (optHttpsPort.isPresent()) {
 | |
|             port = optHttpsPort.getAsInt();
 | |
|             url = "https://localhost:" + port;
 | |
|         } else {
 | |
|             port = testServer.getRunningHttpPort()
 | |
|                              .getAsInt();
 | |
|             url = "http://localhost:" + port;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     @Test
 | |
|     public void givenASingleGetRequestWhenResponseThenBlockWithCompletableAndLog()
 | |
|       throws Exception {
 | |
|         WSClient ws = play.test.WSTestClient.newClient(port);
 | |
|         WSResponse wsResponse = ws.url(url)
 | |
|                                   .setRequestFilter(new AhcCurlRequestLogger())
 | |
|                                   .addHeader("key", "value")
 | |
|                                   .addQueryParameter("num", "" + 1)
 | |
|                                   .get()
 | |
|                                   .toCompletableFuture()
 | |
|                                   .get();
 | |
| 
 | |
|         log.debug("Thread#" + Thread.currentThread()
 | |
|                                     .getId() + " Request complete: Response code = "
 | |
|           + wsResponse.getStatus()
 | |
|           + " | Response: " + wsResponse.getBody() + " | Current Time:"
 | |
|           + System.currentTimeMillis());
 | |
|         assert (HttpStatus.SC_OK == wsResponse.getStatus());
 | |
|     }
 | |
| 
 | |
|     @Test
 | |
|     public void givenASingleGetRequestWhenResponseThenLog() throws Exception {
 | |
|         CountDownLatch latch = new CountDownLatch(1);
 | |
|         WSClient ws = play.test.WSTestClient.newClient(port);
 | |
|         ws.url(url)
 | |
|           .setRequestFilter(new AhcCurlRequestLogger())
 | |
|           .addHeader("key", "value")
 | |
|           .addQueryParameter("num", "" + 1)
 | |
|           .get()
 | |
|           .thenAccept(r -> {
 | |
|               log.debug("Thread#" + Thread.currentThread()
 | |
|                                           .getId() + " Request complete: Response code = "
 | |
|                 + r.getStatus()
 | |
|                 + " | Response: " + r.getBody() + " | Current Time:" + System.currentTimeMillis());
 | |
|               latch.countDown();
 | |
|           });
 | |
| 
 | |
|         log.debug(
 | |
|           "Waiting for requests to be completed. Current Time: " + System.currentTimeMillis());
 | |
|         latch.await(5, TimeUnit.SECONDS );
 | |
|         assertEquals(0, latch.getCount());
 | |
|         log.debug("All requests have been completed. Exiting test.");
 | |
|     }
 | |
| 
 | |
|     @Test
 | |
|     public void givenASinglePostRequestWhenResponseThenLog() throws Exception {
 | |
|         CountDownLatch latch = new CountDownLatch(1);
 | |
|         WSClient ws = play.test.WSTestClient.newClient(port);
 | |
|         ws.url(url)
 | |
|           .setContentType("application/x-www-form-urlencoded")
 | |
|           .post("key1=value1&key2=value2")
 | |
|           .thenAccept(r -> {
 | |
|               log.debug("Thread#" + Thread.currentThread()
 | |
|                                           .getId() + " Request complete: Response code = "
 | |
|                 + r.getStatus()
 | |
|                 + " | Response: " + r.getBody() + " | Current Time:" + System.currentTimeMillis());
 | |
|               latch.countDown();
 | |
|           });
 | |
| 
 | |
|         log.debug(
 | |
|           "Waiting for requests to be completed. Current Time: " + System.currentTimeMillis());
 | |
|         latch.await(5, TimeUnit.SECONDS );
 | |
|         assertEquals(0, latch.getCount());
 | |
|         log.debug("All requests have been completed. Exiting test.");
 | |
|     }
 | |
| 
 | |
|     @Test
 | |
|     public void givenMultipleRequestsWhenResponseThenLog() throws Exception {
 | |
|         CountDownLatch latch = new CountDownLatch(100);
 | |
|         WSClient ws = play.test.WSTestClient.newClient(port);
 | |
|         IntStream.range(0, 100)
 | |
|                  .parallel()
 | |
|                  .forEach(num ->
 | |
|                    ws.url(url)
 | |
|                      .setRequestFilter(new AhcCurlRequestLogger())
 | |
|                      .addHeader("key", "value")
 | |
|                      .addQueryParameter("num", "" + num)
 | |
|                      .get()
 | |
|                      .thenAccept(r -> {
 | |
|                          log.debug(
 | |
|                            "Thread#" + num + " Request complete: Response code = " + r.getStatus()
 | |
|                              + " | Response: " + r.getBody() + " | Current Time:"
 | |
|                              + System.currentTimeMillis());
 | |
|                          latch.countDown();
 | |
|                      })
 | |
|                  );
 | |
| 
 | |
|         log.debug(
 | |
|           "Waiting for requests to be completed. Current Time: " + System.currentTimeMillis());
 | |
|         latch.await(5, TimeUnit.SECONDS );
 | |
|         assertEquals(0, latch.getCount());
 | |
|         log.debug("All requests have been completed. Exiting test.");
 | |
|     }
 | |
| 
 | |
|     @Test
 | |
|     public void givenLongResponseWhenTimeoutThenHandle() throws Exception {
 | |
|         CountDownLatch latch = new CountDownLatch(1);
 | |
|         WSClient ws = play.test.WSTestClient.newClient(port);
 | |
|         Futures futures = app.injector()
 | |
|                              .instanceOf(Futures.class);
 | |
|         CompletionStage<Result> f = futures.timeout(
 | |
|           ws.url(url)
 | |
|             .setRequestTimeout(Duration.of(1, SECONDS))
 | |
|             .get()
 | |
|             .thenApply(result -> {
 | |
|                 try {
 | |
|                     Thread.sleep(2000L);
 | |
|                     return Results.ok();
 | |
|                 } catch (InterruptedException e) {
 | |
|                     return Results.status(
 | |
|                       SERVICE_UNAVAILABLE);
 | |
|                 }
 | |
|             }), 1L, TimeUnit.SECONDS
 | |
|         );
 | |
|         CompletionStage<Object> res = f.handleAsync((result, e) -> {
 | |
|             if (e != null) {
 | |
|                 log.error("Exception thrown", e);
 | |
|                 latch.countDown();
 | |
|                 return e.getCause();
 | |
|             } else {
 | |
|                 return result;
 | |
|             }
 | |
|         });
 | |
|         res.thenAccept(result -> assertEquals(TimeoutException.class, result));
 | |
| 
 | |
|         log.debug(
 | |
|           "Waiting for requests to be completed. Current Time: " + System.currentTimeMillis());
 | |
|         latch.await(5, TimeUnit.SECONDS );
 | |
|         assertEquals(0, latch.getCount());
 | |
|         log.debug("All requests have been completed. Exiting test.");
 | |
|     }
 | |
| 
 | |
|     @Test
 | |
|     public void givenMultigigabyteResponseConsumeWithStreams() throws Exception {
 | |
|         CountDownLatch latch = new CountDownLatch(1);
 | |
|         final ActorSystem system = ActorSystem.create();
 | |
|         final ActorMaterializer materializer = ActorMaterializer.create(system);
 | |
|         final Path path = Files.createTempFile("tmp_", ".out");
 | |
| 
 | |
|         WSClient ws = play.test.WSTestClient.newClient(port);
 | |
|         log.info("Starting test server on url: " + url);
 | |
|         ws.url(url)
 | |
|           .stream()
 | |
|           .thenAccept(
 | |
|             response -> {
 | |
|                 try {
 | |
|                     OutputStream outputStream = java.nio.file.Files.newOutputStream(path);
 | |
|                     Sink<ByteString, CompletionStage<Done>> outputWriter =
 | |
|                       Sink.foreach(bytes -> {
 | |
|                           log.info("Reponse: " + bytes.utf8String());
 | |
|                           outputStream.write(bytes.toArray());
 | |
|                       });
 | |
| 
 | |
|                     response.getBodyAsSource()
 | |
|                             .runWith(outputWriter, materializer);
 | |
| 
 | |
|                 } catch (IOException e) {
 | |
|                     log.error("An error happened while opening the output stream", e);
 | |
|                 }
 | |
|             })
 | |
|           .whenComplete((value, error) -> latch.countDown());
 | |
| 
 | |
|         log.debug(
 | |
|           "Waiting for requests to be completed. Current Time: " + System.currentTimeMillis());
 | |
|         latch.await(5, TimeUnit.SECONDS );
 | |
|         assertEquals(0, latch.getCount());
 | |
|         log.debug("All requests have been completed. Exiting test.");
 | |
|     }
 | |
| }
 |