|
15 | 15 | */ |
16 | 16 | package com.google.cloud.opentelemetry.extension.auth; |
17 | 17 |
|
18 | | -import static com.google.cloud.opentelemetry.extension.auth.testbackend.DummyOTelHttpEndpoint.HEADER_VERIFIED; |
19 | | -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; |
20 | 18 | import static org.junit.jupiter.api.Assertions.assertEquals; |
21 | 19 | import static org.junit.jupiter.api.Assertions.assertTrue; |
22 | 20 |
|
| 21 | +import com.google.cloud.opentelemetry.extension.auth.testbackend.DummyOTelHttpEndpoint; |
| 22 | +import com.sun.net.httpserver.HttpServer; |
| 23 | +import java.io.BufferedReader; |
23 | 24 | import java.io.File; |
24 | 25 | import java.io.IOException; |
25 | | -import java.net.URI; |
26 | | -import java.net.http.HttpClient; |
27 | | -import java.net.http.HttpRequest; |
28 | | -import java.net.http.HttpResponse; |
29 | | -import java.net.http.HttpResponse.BodyHandlers; |
30 | | -import java.util.concurrent.atomic.AtomicReference; |
31 | | -import org.junit.jupiter.api.AfterAll; |
32 | | -import org.junit.jupiter.api.BeforeAll; |
| 26 | +import java.io.InputStreamReader; |
| 27 | +import java.lang.ProcessBuilder.Redirect; |
33 | 28 | import org.junit.jupiter.api.Test; |
34 | | -import org.slf4j.Logger; |
35 | | -import org.slf4j.LoggerFactory; |
36 | | -import org.testcontainers.containers.GenericContainer; |
37 | | -import org.testcontainers.containers.output.Slf4jLogConsumer; |
38 | | -import org.testcontainers.containers.wait.strategy.Wait; |
39 | | -import org.testcontainers.utility.DockerImageName; |
40 | | -import org.testcontainers.utility.MountableFile; |
41 | 29 |
|
42 | 30 | public class ExtensionIntegrationTest { |
43 | 31 |
|
44 | | - private static final String TEST_SERVER_PATH = "/doWork"; |
45 | | - private static GenericContainer<?> applicationContainer; |
46 | | - private static Integer applicationPort; |
47 | | - |
48 | | - private static final Logger logger = LoggerFactory.getLogger(ExtensionIntegrationTest.class); |
49 | | - |
50 | | - @BeforeAll |
51 | | - static void setup() { |
| 32 | + @Test |
| 33 | + public void smokeTest() throws IOException, InterruptedException { |
52 | 34 | String testAppJarPath = |
53 | 35 | new File("./build/libs/auto-instrumented-test-server.jar").getAbsolutePath(); |
54 | | - String dummyBackendJarPath = new File("./build/libs/dummy-otlp-backend.jar").getAbsolutePath(); |
| 36 | + |
55 | 37 | String javaAgentJarPath = new File("./build/libs/otel-agent.jar").getAbsolutePath(); |
56 | 38 | String authExtensionJarPath = new File("./build/libs/gcp-auth-extension.jar").getAbsolutePath(); |
57 | 39 |
|
58 | | - DockerImageName dockerBaseImage = DockerImageName.parse("openjdk:17-jdk-slim"); |
59 | | - int preferredApplicationPort = 8000; |
60 | | - |
61 | | - String runJavaTestApp = |
62 | | - "java -javaagent:/agent.jar -Dotel.javaagent.extensions=/auth-ext.jar -Dotel.java.global-autoconfigure.enabled=true -Dgoogle.cloud.project=dummy-test-project -Dotel.exporter.otlp.endpoint=http://localhost:4318/ -Dotel.traces.exporter=otlp,logging -Dotel.metrics.exporter=none -jar /test-app.jar " |
63 | | - + preferredApplicationPort; |
64 | | - String runOtelBackend = "java -jar /test-backend.jar &"; |
65 | | - |
66 | | - applicationContainer = |
67 | | - new GenericContainer<>(dockerBaseImage) |
68 | | - .withExposedPorts(preferredApplicationPort) |
69 | | - .withCopyFileToContainer( |
70 | | - MountableFile.forHostPath(dummyBackendJarPath), "/test-backend.jar") |
71 | | - .withCopyFileToContainer(MountableFile.forHostPath(testAppJarPath), "/test-app.jar") |
72 | | - .withCopyFileToContainer(MountableFile.forHostPath(javaAgentJarPath), "/agent.jar") |
73 | | - .withCopyFileToContainer( |
74 | | - MountableFile.forHostPath(authExtensionJarPath), "/auth-ext.jar") |
75 | | - .withCommand("sh", "-c", runOtelBackend + runJavaTestApp) |
76 | | - .withLogConsumer(new Slf4jLogConsumer(logger)) |
77 | | - .waitingFor(Wait.forLogMessage(".*Waiting for requests.*", 1)); |
78 | | - applicationContainer.start(); |
79 | | - applicationPort = applicationContainer.getMappedPort(preferredApplicationPort); |
80 | | - } |
81 | | - |
82 | | - @AfterAll |
83 | | - static void tearDown() { |
84 | | - if (applicationContainer != null) { |
85 | | - applicationContainer.stop(); |
| 40 | + HttpServer backendServer; |
| 41 | + try { |
| 42 | + backendServer = DummyOTelHttpEndpoint.createTestServer(); |
| 43 | + } catch (IOException e) { |
| 44 | + throw new RuntimeException(e); |
86 | 45 | } |
87 | | - } |
88 | | - |
89 | | - @Test |
90 | | - public void testSampleAppResponding() { |
91 | | - AtomicReference<HttpResponse<String>> response = new AtomicReference<>(); |
92 | | - assertDoesNotThrow(() -> response.set(sendRequestToSampleApp())); |
93 | | - assertEquals(200, response.get().statusCode()); |
94 | | - } |
95 | | - |
96 | | - @Test |
97 | | - public void testExtensionAttachesCorrectHeaders() throws IOException, InterruptedException { |
98 | | - HttpResponse<String> response = sendRequestToSampleApp(); |
99 | | - assertEquals(200, response.statusCode()); |
100 | | - |
101 | | - applicationContainer.waitingFor(Wait.forLogMessage(".*Received trace data.*", 1)); |
102 | | - |
103 | | - String logs = applicationContainer.getLogs(); |
104 | | - assertTrue(logs.contains(HEADER_VERIFIED)); |
105 | | - } |
106 | | - |
107 | | - private HttpResponse<String> sendRequestToSampleApp() throws IOException, InterruptedException { |
108 | | - String url = |
109 | | - "http://" + applicationContainer.getHost() + ":" + applicationPort + TEST_SERVER_PATH; |
110 | | - HttpClient client = HttpClient.newHttpClient(); |
111 | | - HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build(); |
112 | | - |
113 | | - return client.send(request, BodyHandlers.ofString()); |
| 46 | + backendServer.start(); |
| 47 | + Process p = |
| 48 | + new ProcessBuilder( |
| 49 | + "java", |
| 50 | + "-javaagent:" + javaAgentJarPath, |
| 51 | + "-Dotel.javaagent.extensions=" + authExtensionJarPath, |
| 52 | + "-Dotel.java.global-autoconfigure.enabled=true", |
| 53 | + "-Dgoogle.cloud.project=dummy-test-project", |
| 54 | + "-Dotel.exporter.otlp.endpoint=http://localhost:4318", |
| 55 | + "-Dotel.exporter.otlp.insecure=true", |
| 56 | + "-Dotel.traces.exporter=otlp,logging", |
| 57 | + "-Dotel.metrics.exporter=none", |
| 58 | + "-Dotel.javaagent.debug=false", |
| 59 | + "-Dotel.exporter.otlp.protocol=http/protobuf", |
| 60 | + "-jar", |
| 61 | + testAppJarPath) |
| 62 | + .redirectError( |
| 63 | + Redirect.INHERIT) // Redirect stderr from this process to the current process |
| 64 | + .start(); |
| 65 | + p.waitFor(); // wait for the process running the test app to finish |
| 66 | + |
| 67 | + // flush logs from instrumented app process |
| 68 | + BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); |
| 69 | + reader.lines().forEach(System.out::println); |
| 70 | + System.out.println("Instrumented app process finished"); |
| 71 | + |
| 72 | + backendServer.stop(0); // stop the mock HTTP server |
| 73 | + |
| 74 | + // assert on number of requests |
| 75 | + assertEquals(1, DummyOTelHttpEndpoint.receivedRequests.size()); |
| 76 | + // ensure headers were verified for all requests |
| 77 | + DummyOTelHttpEndpoint.receivedRequests.forEach((request, verified) -> assertTrue(verified)); |
114 | 78 | } |
115 | 79 | } |
0 commit comments