From 9f13f0fa0fa447df3d29eabba3d0d5e153d92b62 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Tue, 21 Jan 2025 17:05:05 -0800 Subject: [PATCH 01/15] starting to write test, debug test server --- smoke-tests/apps/LiveMetrics/build.gradle.kts | 1 + .../smoketestapp/TestServlet.java | 11 +++ .../smoketest/LiveMetricsTest.java | 5 +- .../MockedAppInsightsIngestionServer.java | 21 ++++- .../MockedAppInsightsIngestionServlet.java | 16 +--- .../MockedQuickPulseServlet.java | 76 +++++++++++++++++++ 6 files changed, 110 insertions(+), 20 deletions(-) create mode 100644 smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java diff --git a/smoke-tests/apps/LiveMetrics/build.gradle.kts b/smoke-tests/apps/LiveMetrics/build.gradle.kts index 3a2467f1432..122b5ac7120 100644 --- a/smoke-tests/apps/LiveMetrics/build.gradle.kts +++ b/smoke-tests/apps/LiveMetrics/build.gradle.kts @@ -4,4 +4,5 @@ plugins { dependencies { smokeTestImplementation("org.awaitility:awaitility:4.2.0") + implementation("log4j:log4j:1.2.17") } diff --git a/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java b/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java index e68ac23f84f..658efa81f74 100644 --- a/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java +++ b/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java @@ -9,13 +9,24 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; @WebServlet("/*") public class TestServlet extends HttpServlet { + private static final Logger logger = LogManager.getLogger("smoketestapp-livemetrics"); + @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doWork(); resp.getWriter().println("ok"); } + + private void doWork() { + System.out.println("Doing work to generate a dependency call, exception, and trace."); + logger.error("This message should generate an exception!", new Exception("Fake Exception")); + logger.info("This message should generate a trace"); + } } diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index ed049775479..bcfaddd0375 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -30,11 +30,10 @@ abstract class LiveMetricsTest { @Test @TargetUri("/test") void doMostBasicTest() throws Exception { - testing.getTelemetry(0); Awaitility.await() - .atMost(Duration.ofSeconds(10)) - .until(() -> testing.mockedIngestion.isLiveMetricsPingReceived()); + .atMost(Duration.ofSeconds(10)); + //.until(() -> testing.mockedIngestion.isLiveMetricsPingReceived()); } @Environment(TOMCAT_8_JAVA_8) diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java index e54465ee54f..1dbd9e2f2e3 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java @@ -24,6 +24,7 @@ public class MockedAppInsightsIngestionServer { private final MockedAppInsightsIngestionServlet servlet; private final MockedProfilerSettingsServlet profilerSettingsServlet; + private final MockedQuickPulseServlet quickPulseServlet; private final Server server; public MockedAppInsightsIngestionServer() { @@ -33,9 +34,11 @@ public MockedAppInsightsIngestionServer() { servlet = new MockedAppInsightsIngestionServlet(); profilerSettingsServlet = new MockedProfilerSettingsServlet(); + quickPulseServlet = new MockedQuickPulseServlet(); handler.addServletWithMapping(new ServletHolder(profilerSettingsServlet), "/profiler/*"); - handler.addServletWithMapping(new ServletHolder(servlet), "/*"); + handler.addServletWithMapping(new ServletHolder(quickPulseServlet), "/QuickPulseService.svc/*"); + handler.addServletWithMapping(new ServletHolder(servlet), "/v2.1/track"); } @SuppressWarnings("SystemOut") @@ -276,8 +279,20 @@ public boolean test(Envelope input) { return items; } - public boolean isLiveMetricsPingReceived() { - return servlet.isLiveMetricsPingReceived(); + public int getNumPingsReceived() { + return quickPulseServlet.getNumPingsReceived(); + } + + public int getNumPostsReceived() { + return quickPulseServlet.getNumPostsReceived(); + } + + public String getLastPingBody() { + return quickPulseServlet.getPingBody(); + } + + public String getLastPostBody() { + return quickPulseServlet.getLastPostBody(); } @SuppressWarnings("SystemOut") diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java index 565365ab4d9..16b58c82fe1 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java @@ -32,8 +32,6 @@ class MockedAppInsightsIngestionServlet extends HttpServlet { private final Object multimapLock = new Object(); - private volatile boolean liveMetricsPingReceived; - private volatile boolean loggingEnabled; MockedAppInsightsIngestionServlet() { @@ -51,7 +49,6 @@ void resetData() { synchronized (multimapLock) { type2envelope.clear(); } - liveMetricsPingReceived = false; } boolean hasData() { @@ -100,14 +97,11 @@ List waitForItems( throw new TimeoutException("timed out waiting for items"); } - boolean isLiveMetricsPingReceived() { - return liveMetricsPingReceived; - } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { - if (!"/v2.1/track".equals(req.getPathInfo()) - && !"/QuickPulseService.svc/ping".equals(req.getPathInfo())) { + logit("request path info: " + req.getPathInfo()); + if (!"/v2.1/track".equals(req.getPathInfo())) { resp.sendError(404, "Unknown URI"); return; } @@ -126,12 +120,6 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I resp.setContentType("application/json"); logit("raw payload:\n\n" + body + "\n"); - if ("/QuickPulseService.svc/ping".equals(req.getPathInfo())) { - liveMetricsPingReceived = true; - resp.setHeader("x-ms-qps-subscribed", "false"); - return; - } - String[] lines = body.split("\n"); for (String line : lines) { Envelope envelope = JsonHelper.GSON.fromJson(line.trim(), Envelope.class); diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java new file mode 100644 index 00000000000..54a2118dd2e --- /dev/null +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.microsoft.applicationinsights.smoketest.fakeingestion; + +import com.google.common.io.CharStreams; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.StringWriter; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +public class MockedQuickPulseServlet extends HttpServlet { + + private final AtomicInteger liveMetricsPingReceived = new AtomicInteger(); + + private final AtomicInteger liveMetricsPostReceived = new AtomicInteger(); + + private final AtomicReference pingBody = new AtomicReference<>(); + private final AtomicReference lastPostBody = new AtomicReference<>(); + + private static final String MOCK_RESPONSE_JSON_DEFAULT_CONFIG = + "{\"ETag\":\"fake::etag\",\"Metrics\":[],\"QuotaInfo\":null,\"DocumentStreams\":[{\"Id\":\"all-types-default\",\"DocumentFilterGroups\":[{\"TelemetryType\":\"Request\",\"Filters\":{\"Filters\":[{\"FieldName\":\"Success\",\"Predicate\":\"Equal\",\"Comparand\":\"false\"}]}},{\"TelemetryType\":\"Dependency\",\"Filters\":{\"Filters\":[{\"FieldName\":\"Success\",\"Predicate\":\"Equal\",\"Comparand\":\"false\"}]}},{\"TelemetryType\":\"Exception\",\"Filters\":{\"Filters\":[]}},{\"TelemetryType\":\"Event\",\"Filters\":{\"Filters\":[]}},{\"TelemetryType\":\"Trace\",\"Filters\":{\"Filters\":[]}}]}]}"; + + public MockedQuickPulseServlet() { + + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + Readable reader = req.getReader(); + StringWriter sw = new StringWriter(); + CharStreams.copy(reader, sw); + String body = sw.toString(); + + String path = req.getPathInfo(); + System.out.println("QuickPulse received: " + path); + if (path.equals("QuickPulse.svc/ping")) { + liveMetricsPingReceived.incrementAndGet(); + pingBody.set(body); + System.out.println("ping body: " + body); + // want the following request to be a post + resp.setHeader("x-ms-qps-subscribed", "true"); + resp.setContentType("application/json"); + resp.getWriter().write(MOCK_RESPONSE_JSON_DEFAULT_CONFIG); + + } else if (path.equals("QuickPulse.svc/post")) { + liveMetricsPostReceived.incrementAndGet(); + lastPostBody.set(body); + System.out.println("post body: " + body); + // continue to post + resp.setHeader("x-ms-qps-subscribed", "true"); + } else { + resp.setStatus(404); + } + } + + public int getNumPingsReceived() { + return liveMetricsPingReceived.get(); + } + + public int getNumPostsReceived() { + return liveMetricsPostReceived.get(); + } + + public String getPingBody() { + return pingBody.get(); + } + + public String getLastPostBody() { + return lastPostBody.get(); + } + +} From 0b4861ab92b7e17d43fc137f1182c553074c9945 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Wed, 22 Jan 2025 15:58:24 -0800 Subject: [PATCH 02/15] changes before merge from main --- smoke-tests/apps/LiveMetrics/build.gradle.kts | 1 + .../smoketestapp/TestServlet.java | 2 ++ .../smoketest/LiveMetricsTest.java | 3 ++- .../smoketest/SmokeTestExtension.java | 2 ++ .../MockedAppInsightsIngestionServer.java | 4 ++++ .../MockedAppInsightsIngestionServlet.java | 6 ----- .../MockedQuickPulseServlet.java | 22 ++++++++++++++----- 7 files changed, 28 insertions(+), 12 deletions(-) diff --git a/smoke-tests/apps/LiveMetrics/build.gradle.kts b/smoke-tests/apps/LiveMetrics/build.gradle.kts index 122b5ac7120..23dc25cb37e 100644 --- a/smoke-tests/apps/LiveMetrics/build.gradle.kts +++ b/smoke-tests/apps/LiveMetrics/build.gradle.kts @@ -5,4 +5,5 @@ plugins { dependencies { smokeTestImplementation("org.awaitility:awaitility:4.2.0") implementation("log4j:log4j:1.2.17") + implementation("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:1.22.1") } diff --git a/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java b/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java index 658efa81f74..00925c558fb 100644 --- a/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java +++ b/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java @@ -9,6 +9,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import io.opentelemetry.instrumentation.annotations.WithSpan; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; @@ -24,6 +25,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) resp.getWriter().println("ok"); } + @WithSpan private void doWork() { System.out.println("Doing work to generate a dependency call, exception, and trace."); logger.error("This message should generate an exception!", new Exception("Fake Exception")); diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index bcfaddd0375..675a913479b 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -32,7 +32,8 @@ abstract class LiveMetricsTest { void doMostBasicTest() throws Exception { Awaitility.await() - .atMost(Duration.ofSeconds(10)); + .atMost(Duration.ofSeconds(20)); + //.until(() -> testing.mockedIngestion.isLiveMetricsPingReceived()); } diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/SmokeTestExtension.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/SmokeTestExtension.java index bfb8d32e4dc..6adf0ac2212 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/SmokeTestExtension.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/SmokeTestExtension.java @@ -205,6 +205,7 @@ private void prepareEnvironment(Environment environment) throws Exception { } mockedIngestion.startServer(); mockedIngestion.setRequestLoggingEnabled(true); + mockedIngestion.setQuickPulseRequestLoggingEnabled(true); if (useOtlpEndpoint) { mockedOtlpIngestion.startServer(); } @@ -536,6 +537,7 @@ public void afterAll(ExtensionContext context) throws Exception { mockedIngestion.stopServer(); mockedIngestion.setRequestLoggingEnabled(false); + mockedIngestion.setQuickPulseRequestLoggingEnabled(false); if (useOtlpEndpoint) { mockedOtlpIngestion.stopServer(); } diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java index 1dbd9e2f2e3..ba5d6dd3f61 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java @@ -319,4 +319,8 @@ public void run() { public void setRequestLoggingEnabled(boolean enabled) { servlet.setRequestLoggingEnabled(enabled); } + + public void setQuickPulseRequestLoggingEnabled(boolean enabled) { + quickPulseServlet.setRequestLoggingEnabled(enabled); + } } diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java index 16b58c82fe1..2fc3f57671c 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java @@ -100,12 +100,6 @@ List waitForItems( @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { - logit("request path info: " + req.getPathInfo()); - if (!"/v2.1/track".equals(req.getPathInfo())) { - resp.sendError(404, "Unknown URI"); - return; - } - String contentEncoding = req.getHeader("content-encoding"); Readable reader; if ("gzip".equals(contentEncoding)) { diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java index 54a2118dd2e..fe2f85f8544 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java @@ -23,10 +23,18 @@ public class MockedQuickPulseServlet extends HttpServlet { private static final String MOCK_RESPONSE_JSON_DEFAULT_CONFIG = "{\"ETag\":\"fake::etag\",\"Metrics\":[],\"QuotaInfo\":null,\"DocumentStreams\":[{\"Id\":\"all-types-default\",\"DocumentFilterGroups\":[{\"TelemetryType\":\"Request\",\"Filters\":{\"Filters\":[{\"FieldName\":\"Success\",\"Predicate\":\"Equal\",\"Comparand\":\"false\"}]}},{\"TelemetryType\":\"Dependency\",\"Filters\":{\"Filters\":[{\"FieldName\":\"Success\",\"Predicate\":\"Equal\",\"Comparand\":\"false\"}]}},{\"TelemetryType\":\"Exception\",\"Filters\":{\"Filters\":[]}},{\"TelemetryType\":\"Event\",\"Filters\":{\"Filters\":[]}},{\"TelemetryType\":\"Trace\",\"Filters\":{\"Filters\":[]}}]}]}"; + private volatile boolean loggingEnabled; public MockedQuickPulseServlet() { } + @SuppressWarnings("SystemOut") + private void logit(String message) { + if (loggingEnabled) { + System.out.println("FAKE INGESTION: INFO - " + message); + } + } + @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { @@ -36,20 +44,20 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) String body = sw.toString(); String path = req.getPathInfo(); - System.out.println("QuickPulse received: " + path); - if (path.equals("QuickPulse.svc/ping")) { + logit("QuickPulse received: " + path); + if (path.equals("/ping")) { liveMetricsPingReceived.incrementAndGet(); pingBody.set(body); - System.out.println("ping body: " + body); + logit("ping body: " + body); // want the following request to be a post resp.setHeader("x-ms-qps-subscribed", "true"); resp.setContentType("application/json"); resp.getWriter().write(MOCK_RESPONSE_JSON_DEFAULT_CONFIG); - } else if (path.equals("QuickPulse.svc/post")) { + } else if (path.equals("/post")) { liveMetricsPostReceived.incrementAndGet(); lastPostBody.set(body); - System.out.println("post body: " + body); + logit("post body: " + body); // continue to post resp.setHeader("x-ms-qps-subscribed", "true"); } else { @@ -73,4 +81,8 @@ public String getLastPostBody() { return lastPostBody.get(); } + public void setRequestLoggingEnabled(boolean enabled) { + loggingEnabled = enabled; + } + } From eef5b9f03ade7221eff87188d9970f6c0d833586 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Thu, 23 Jan 2025 14:14:06 -0800 Subject: [PATCH 03/15] stuff --- smoke-tests/apps/LiveMetrics/build.gradle.kts | 1 + .../smoketest/LiveMetricsTest.java | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/smoke-tests/apps/LiveMetrics/build.gradle.kts b/smoke-tests/apps/LiveMetrics/build.gradle.kts index 23dc25cb37e..84de81c464c 100644 --- a/smoke-tests/apps/LiveMetrics/build.gradle.kts +++ b/smoke-tests/apps/LiveMetrics/build.gradle.kts @@ -6,4 +6,5 @@ dependencies { smokeTestImplementation("org.awaitility:awaitility:4.2.0") implementation("log4j:log4j:1.2.17") implementation("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:1.22.1") + implementation("com.azure:azure-json:1.0.0") } diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index 675a913479b..a1027c5c106 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -16,11 +16,14 @@ import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.TOMCAT_8_JAVA_8_OPENJ9; import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.WILDFLY_13_JAVA_8; import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.WILDFLY_13_JAVA_8_OPENJ9; +import static org.assertj.core.api.Assertions.assertThat; import java.time.Duration; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import com.azure.json.JsonProviders; +import com.azure.json.JsonReader; @UseAgent abstract class LiveMetricsTest { @@ -29,12 +32,22 @@ abstract class LiveMetricsTest { @Test @TargetUri("/test") - void doMostBasicTest() throws Exception { + void testPingPostAndTelemetryDataFlow() throws Exception { Awaitility.await() - .atMost(Duration.ofSeconds(20)); + .atMost(Duration.ofSeconds(15)); + + assertThat(testing.mockedIngestion.getNumPingsReceived()).isEqualTo(1); + //ping body + String pingBody = testing.mockedIngestion.getLastPingBody(); + + // After the ping, we expect a post to happen roughly every second. + assertThat(testing.mockedIngestion.getNumPostsReceived()).isGreaterThanOrEqualTo(10); + String postBody = testing.mockedIngestion.getLastPostBody(); + + MonitoringDataPoint pingDataPoint = MonitoringDataPoint.fromJson(pingBody); + - //.until(() -> testing.mockedIngestion.isLiveMetricsPingReceived()); } @Environment(TOMCAT_8_JAVA_8) From 4c24f73d004068307e8362d9e560a4e5394a71c7 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Mon, 27 Jan 2025 10:37:04 -0800 Subject: [PATCH 04/15] minor --- smoke-tests/apps/LiveMetrics/build.gradle.kts | 1 + .../smoketest/LiveMetricsTest.java | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/smoke-tests/apps/LiveMetrics/build.gradle.kts b/smoke-tests/apps/LiveMetrics/build.gradle.kts index 84de81c464c..bbe666d28bb 100644 --- a/smoke-tests/apps/LiveMetrics/build.gradle.kts +++ b/smoke-tests/apps/LiveMetrics/build.gradle.kts @@ -7,4 +7,5 @@ dependencies { implementation("log4j:log4j:1.2.17") implementation("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:1.22.1") implementation("com.azure:azure-json:1.0.0") + implementation("com.azure:azure-monitor-opentelemetry-autoconfigure:1.0.0-beta.1") } diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index a1027c5c106..7b3387a08d6 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -18,12 +18,19 @@ import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.WILDFLY_13_JAVA_8_OPENJ9; import static org.assertj.core.api.Assertions.assertThat; +import java.io.IOException; import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import com.azure.json.JsonToken; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentIngress; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentStreamInfo; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import com.azure.json.JsonProviders; import com.azure.json.JsonReader; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.MonitoringDataPoint; @UseAgent abstract class LiveMetricsTest { @@ -45,7 +52,14 @@ void testPingPostAndTelemetryDataFlow() throws Exception { assertThat(testing.mockedIngestion.getNumPostsReceived()).isGreaterThanOrEqualTo(10); String postBody = testing.mockedIngestion.getLastPostBody(); - MonitoringDataPoint pingDataPoint = MonitoringDataPoint.fromJson(pingBody); + // Verify that the telemetry data is in the last post body + JsonReader reader = JsonProviders.createReader(postBody); + List dataPoints = reader.readArray(MonitoringDataPoint::fromJson); + assertThat(dataPoints).hasSize(1); + + MonitoringDataPoint dataPoint = dataPoints.get(0); + List docs = dataPoint.getDocuments(); + } From a78c06a0394b2b59697bed34569851a6a2d8ddaa Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Thu, 30 Jan 2025 15:04:28 -0800 Subject: [PATCH 05/15] initial test changes --- .../smoketest/LiveMetricsTest.java | 88 ++++++++++++++----- .../MockedAppInsightsIngestionServer.java | 16 +--- .../MockedQuickPulseServlet.java | 42 ++++----- 3 files changed, 87 insertions(+), 59 deletions(-) diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index 7b3387a08d6..a13937f8faf 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -22,9 +22,11 @@ import java.time.Duration; import java.util.ArrayList; import java.util.List; -import com.azure.json.JsonToken; import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentIngress; -import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentStreamInfo; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.Exception; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.Trace; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentType; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.MetricPoint; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -39,28 +41,68 @@ abstract class LiveMetricsTest { @Test @TargetUri("/test") - void testPingPostAndTelemetryDataFlow() throws Exception { - + void testTelemetryDataFlow() throws java.lang.Exception { Awaitility.await() - .atMost(Duration.ofSeconds(15)); - - assertThat(testing.mockedIngestion.getNumPingsReceived()).isEqualTo(1); - //ping body - String pingBody = testing.mockedIngestion.getLastPingBody(); - - // After the ping, we expect a post to happen roughly every second. - assertThat(testing.mockedIngestion.getNumPostsReceived()).isGreaterThanOrEqualTo(10); - String postBody = testing.mockedIngestion.getLastPostBody(); - - // Verify that the telemetry data is in the last post body - JsonReader reader = JsonProviders.createReader(postBody); - List dataPoints = reader.readArray(MonitoringDataPoint::fromJson); - assertThat(dataPoints).hasSize(1); - - MonitoringDataPoint dataPoint = dataPoints.get(0); - List docs = dataPoint.getDocuments(); - - + .atMost(Duration.ofSeconds(20)); + + + assertThat(testing.mockedIngestion.isPingReceived()).isTrue(); + + + List postBodies = testing.mockedIngestion.getPostBodies(); + assertThat(postBodies).hasSizeGreaterThan(0); // should post at least once + + boolean foundExceptionDoc = false; + boolean foundTraceDoc = false; + boolean foundDependency = false; + boolean foundRequest = false; + + for (String postBody : postBodies) { + // Verify that the telemetry data is in the last post body + List dataPoints = new ArrayList<>(); + try { + JsonReader reader = JsonProviders.createReader(postBody); + dataPoints = reader.readArray(MonitoringDataPoint::fromJson); + } catch (IOException e) { + throw new java.lang.Exception("Failed to parse post request body", e); + } + + assertThat(dataPoints).hasSize(1); + MonitoringDataPoint dataPoint = dataPoints.get(0); + List docs = dataPoint.getDocuments(); + List metrics = dataPoint.getMetrics(); + // check that the expected documents are present + // With the default filtering configuration, we should only see the exception and trace documents. + // Request/Dep did not fail, so there should not be documents for those. + + for (DocumentIngress doc : docs) { + if (doc.getDocumentType().equals(DocumentType.EXCEPTION) && + ((Exception) doc).getExceptionMessage().equals("Fake Exception")) { + foundExceptionDoc = true; + } else if (doc.getDocumentType().equals(DocumentType.TRACE) && + ((Trace) doc).getMessage().equals("This message should generate a trace")) { + foundTraceDoc = true; + } + } + + // check that the expected metrics have the correct values + + for (MetricPoint metric : metrics) { + String name = metric.getName(); + double value = metric.getValue(); + if (name.equals("\\ApplicationInsights\\Dependency Calls/Sec") && value == 1) { + foundDependency = true; + } else if (name.equals("\\ApplicationInsights\\Requests/Sec") && value == 1) { + foundRequest = true; + } + } + + } + + assertThat(foundExceptionDoc).isTrue(); + assertThat(foundTraceDoc).isTrue(); + assertThat(foundDependency).isTrue(); + assertThat(foundRequest).isTrue(); } diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java index ba5d6dd3f61..e19208e73c0 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java @@ -279,20 +279,12 @@ public boolean test(Envelope input) { return items; } - public int getNumPingsReceived() { - return quickPulseServlet.getNumPingsReceived(); + public boolean isPingReceived() { + return quickPulseServlet.isPingReceived(); } - public int getNumPostsReceived() { - return quickPulseServlet.getNumPostsReceived(); - } - - public String getLastPingBody() { - return quickPulseServlet.getPingBody(); - } - - public String getLastPostBody() { - return quickPulseServlet.getLastPostBody(); + public List getPostBodies() { + return quickPulseServlet.getPostBodies(); } @SuppressWarnings("SystemOut") diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java index fe2f85f8544..6abc1c74d49 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java @@ -8,17 +8,15 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.StringWriter; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; public class MockedQuickPulseServlet extends HttpServlet { - private final AtomicInteger liveMetricsPingReceived = new AtomicInteger(); - - private final AtomicInteger liveMetricsPostReceived = new AtomicInteger(); - - private final AtomicReference pingBody = new AtomicReference<>(); - private final AtomicReference lastPostBody = new AtomicReference<>(); + private final AtomicBoolean pingReceived = new AtomicBoolean(false); + private final List postBodies = new ArrayList<>(); + private final Object lock = new Object(); private static final String MOCK_RESPONSE_JSON_DEFAULT_CONFIG = "{\"ETag\":\"fake::etag\",\"Metrics\":[],\"QuotaInfo\":null,\"DocumentStreams\":[{\"Id\":\"all-types-default\",\"DocumentFilterGroups\":[{\"TelemetryType\":\"Request\",\"Filters\":{\"Filters\":[{\"FieldName\":\"Success\",\"Predicate\":\"Equal\",\"Comparand\":\"false\"}]}},{\"TelemetryType\":\"Dependency\",\"Filters\":{\"Filters\":[{\"FieldName\":\"Success\",\"Predicate\":\"Equal\",\"Comparand\":\"false\"}]}},{\"TelemetryType\":\"Exception\",\"Filters\":{\"Filters\":[]}},{\"TelemetryType\":\"Event\",\"Filters\":{\"Filters\":[]}},{\"TelemetryType\":\"Trace\",\"Filters\":{\"Filters\":[]}}]}]}"; @@ -46,39 +44,35 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) String path = req.getPathInfo(); logit("QuickPulse received: " + path); if (path.equals("/ping")) { - liveMetricsPingReceived.incrementAndGet(); - pingBody.set(body); + pingReceived.set(true); logit("ping body: " + body); // want the following request to be a post + resp.setHeader("x-ms-qps-configuration-etag", "fake::etag"); resp.setHeader("x-ms-qps-subscribed", "true"); resp.setContentType("application/json"); resp.getWriter().write(MOCK_RESPONSE_JSON_DEFAULT_CONFIG); } else if (path.equals("/post")) { - liveMetricsPostReceived.incrementAndGet(); - lastPostBody.set(body); + synchronized (lock) { + postBodies.add(body); + } logit("post body: " + body); // continue to post resp.setHeader("x-ms-qps-subscribed", "true"); + resp.setHeader("x-ms-qps-configuration-etag", "fake::etag"); } else { resp.setStatus(404); } } - public int getNumPingsReceived() { - return liveMetricsPingReceived.get(); - } - - public int getNumPostsReceived() { - return liveMetricsPostReceived.get(); + public boolean isPingReceived() { + return pingReceived.get(); } - public String getPingBody() { - return pingBody.get(); - } - - public String getLastPostBody() { - return lastPostBody.get(); + public List getPostBodies() { + synchronized (lock) { + return new ArrayList<>(postBodies); + } } public void setRequestLoggingEnabled(boolean enabled) { From e0f12740c97c61b17303aa58f79d9d28c68ef224 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Thu, 30 Jan 2025 15:37:10 -0800 Subject: [PATCH 06/15] spotless apply --- .../smoketestapp/TestServlet.java | 2 +- .../smoketest/LiveMetricsTest.java | 45 +++++++------- .../MockedAppInsightsIngestionServlet.java | 1 - .../MockedQuickPulseServlet.java | 62 +++++++++---------- 4 files changed, 52 insertions(+), 58 deletions(-) diff --git a/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java b/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java index 00925c558fb..ff1969fb500 100644 --- a/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java +++ b/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java @@ -3,13 +3,13 @@ package com.microsoft.applicationinsights.smoketestapp; +import io.opentelemetry.instrumentation.annotations.WithSpan; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import io.opentelemetry.instrumentation.annotations.WithSpan; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index a13937f8faf..bd7da7d684d 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -18,21 +18,21 @@ import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.WILDFLY_13_JAVA_8_OPENJ9; import static org.assertj.core.api.Assertions.assertThat; +import com.azure.json.JsonProviders; +import com.azure.json.JsonReader; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentIngress; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentType; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.Exception; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.MetricPoint; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.MonitoringDataPoint; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.Trace; import java.io.IOException; import java.time.Duration; import java.util.ArrayList; import java.util.List; -import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentIngress; -import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.Exception; -import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.Trace; -import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentType; -import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.MetricPoint; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import com.azure.json.JsonProviders; -import com.azure.json.JsonReader; -import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.MonitoringDataPoint; @UseAgent abstract class LiveMetricsTest { @@ -42,13 +42,10 @@ abstract class LiveMetricsTest { @Test @TargetUri("/test") void testTelemetryDataFlow() throws java.lang.Exception { - Awaitility.await() - .atMost(Duration.ofSeconds(20)); - + Awaitility.await().atMost(Duration.ofSeconds(20)); assertThat(testing.mockedIngestion.isPingReceived()).isTrue(); - List postBodies = testing.mockedIngestion.getPostBodies(); assertThat(postBodies).hasSizeGreaterThan(0); // should post at least once @@ -58,35 +55,37 @@ void testTelemetryDataFlow() throws java.lang.Exception { boolean foundRequest = false; for (String postBody : postBodies) { - // Verify that the telemetry data is in the last post body + // Each post body is a list with a singular MonitoringDataPoint List dataPoints = new ArrayList<>(); try { JsonReader reader = JsonProviders.createReader(postBody); + // See live metrics swagger to understand MonitoringDataPoint structure dataPoints = reader.readArray(MonitoringDataPoint::fromJson); } catch (IOException e) { throw new java.lang.Exception("Failed to parse post request body", e); } + // Because the mock ping/posts should succeed, we should only have one MonitoringDataPoint per + // post assertThat(dataPoints).hasSize(1); MonitoringDataPoint dataPoint = dataPoints.get(0); List docs = dataPoint.getDocuments(); List metrics = dataPoint.getMetrics(); - // check that the expected documents are present - // With the default filtering configuration, we should only see the exception and trace documents. - // Request/Dep did not fail, so there should not be documents for those. + // check that the expected documents are present + // With the default filtering configuration, we should only see the exception and trace + // documents. for (DocumentIngress doc : docs) { - if (doc.getDocumentType().equals(DocumentType.EXCEPTION) && - ((Exception) doc).getExceptionMessage().equals("Fake Exception")) { + if (doc.getDocumentType().equals(DocumentType.EXCEPTION) + && ((Exception) doc).getExceptionMessage().equals("Fake Exception")) { foundExceptionDoc = true; - } else if (doc.getDocumentType().equals(DocumentType.TRACE) && - ((Trace) doc).getMessage().equals("This message should generate a trace")) { + } else if (doc.getDocumentType().equals(DocumentType.TRACE) + && ((Trace) doc).getMessage().equals("This message should generate a trace")) { foundTraceDoc = true; } } - // check that the expected metrics have the correct values - + // See if dependency and request are counted for (MetricPoint metric : metrics) { String name = metric.getName(); double value = metric.getValue(); @@ -96,14 +95,12 @@ void testTelemetryDataFlow() throws java.lang.Exception { foundRequest = true; } } - } assertThat(foundExceptionDoc).isTrue(); assertThat(foundTraceDoc).isTrue(); assertThat(foundDependency).isTrue(); assertThat(foundRequest).isTrue(); - } @Environment(TOMCAT_8_JAVA_8) diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java index 2fc3f57671c..fd5cd6c69a8 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServlet.java @@ -97,7 +97,6 @@ List waitForItems( throw new TimeoutException("timed out waiting for items"); } - @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { String contentEncoding = req.getHeader("content-encoding"); diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java index 6abc1c74d49..9bd20c148fa 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java @@ -1,16 +1,17 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. + package com.microsoft.applicationinsights.smoketest.fakeingestion; import com.google.common.io.CharStreams; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; public class MockedQuickPulseServlet extends HttpServlet { @@ -22,9 +23,8 @@ public class MockedQuickPulseServlet extends HttpServlet { "{\"ETag\":\"fake::etag\",\"Metrics\":[],\"QuotaInfo\":null,\"DocumentStreams\":[{\"Id\":\"all-types-default\",\"DocumentFilterGroups\":[{\"TelemetryType\":\"Request\",\"Filters\":{\"Filters\":[{\"FieldName\":\"Success\",\"Predicate\":\"Equal\",\"Comparand\":\"false\"}]}},{\"TelemetryType\":\"Dependency\",\"Filters\":{\"Filters\":[{\"FieldName\":\"Success\",\"Predicate\":\"Equal\",\"Comparand\":\"false\"}]}},{\"TelemetryType\":\"Exception\",\"Filters\":{\"Filters\":[]}},{\"TelemetryType\":\"Event\",\"Filters\":{\"Filters\":[]}},{\"TelemetryType\":\"Trace\",\"Filters\":{\"Filters\":[]}}]}]}"; private volatile boolean loggingEnabled; - public MockedQuickPulseServlet() { - } + public MockedQuickPulseServlet() {} @SuppressWarnings("SystemOut") private void logit(String message) { @@ -34,35 +34,34 @@ private void logit(String message) { } @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) - throws IOException { - Readable reader = req.getReader(); - StringWriter sw = new StringWriter(); - CharStreams.copy(reader, sw); - String body = sw.toString(); + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + Readable reader = req.getReader(); + StringWriter sw = new StringWriter(); + CharStreams.copy(reader, sw); + String body = sw.toString(); - String path = req.getPathInfo(); - logit("QuickPulse received: " + path); - if (path.equals("/ping")) { - pingReceived.set(true); - logit("ping body: " + body); - // want the following request to be a post - resp.setHeader("x-ms-qps-configuration-etag", "fake::etag"); - resp.setHeader("x-ms-qps-subscribed", "true"); - resp.setContentType("application/json"); - resp.getWriter().write(MOCK_RESPONSE_JSON_DEFAULT_CONFIG); + String path = req.getPathInfo(); + logit("QuickPulse received: " + path); + if (path.equals("/ping")) { + pingReceived.set(true); + logit("ping body: " + body); + // want the following request to be a post + resp.setHeader("x-ms-qps-configuration-etag", "fake::etag"); + resp.setHeader("x-ms-qps-subscribed", "true"); + resp.setContentType("application/json"); + resp.getWriter().write(MOCK_RESPONSE_JSON_DEFAULT_CONFIG); - } else if (path.equals("/post")) { - synchronized (lock) { - postBodies.add(body); - } - logit("post body: " + body); - // continue to post - resp.setHeader("x-ms-qps-subscribed", "true"); - resp.setHeader("x-ms-qps-configuration-etag", "fake::etag"); - } else { - resp.setStatus(404); + } else if (path.equals("/post")) { + synchronized (lock) { + postBodies.add(body); } + logit("post body: " + body); + // continue to post + resp.setHeader("x-ms-qps-subscribed", "true"); + resp.setHeader("x-ms-qps-configuration-etag", "fake::etag"); + } else { + resp.setStatus(404); + } } public boolean isPingReceived() { @@ -78,5 +77,4 @@ public List getPostBodies() { public void setRequestLoggingEnabled(boolean enabled) { loggingEnabled = enabled; } - } From 7a6ab01eec0db0b8d3e7290cb763bda271c76523 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Fri, 31 Jan 2025 15:23:44 -0800 Subject: [PATCH 07/15] fix failing tests --- .../fakeingestion/MockedAppInsightsIngestionServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java index e19208e73c0..29011e77c3e 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedAppInsightsIngestionServer.java @@ -38,7 +38,7 @@ public MockedAppInsightsIngestionServer() { handler.addServletWithMapping(new ServletHolder(profilerSettingsServlet), "/profiler/*"); handler.addServletWithMapping(new ServletHolder(quickPulseServlet), "/QuickPulseService.svc/*"); - handler.addServletWithMapping(new ServletHolder(servlet), "/v2.1/track"); + handler.addServletWithMapping(new ServletHolder(servlet), "/*"); } @SuppressWarnings("SystemOut") From 226d4c30a4c6e8570166e4193680198851448973 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Fri, 31 Jan 2025 15:58:13 -0800 Subject: [PATCH 08/15] slight change to wait --- .../applicationinsights/smoketest/LiveMetricsTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index bd7da7d684d..106251f2d59 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -27,10 +27,8 @@ import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.MonitoringDataPoint; import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.Trace; import java.io.IOException; -import java.time.Duration; import java.util.ArrayList; import java.util.List; -import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -42,7 +40,7 @@ abstract class LiveMetricsTest { @Test @TargetUri("/test") void testTelemetryDataFlow() throws java.lang.Exception { - Awaitility.await().atMost(Duration.ofSeconds(20)); + testing.mockedIngestion.waitForItems("RequestData", 1); assertThat(testing.mockedIngestion.isPingReceived()).isTrue(); From 39a5be4e3b76a6f18e84602badd473137a3e2030 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Fri, 31 Jan 2025 16:30:09 -0800 Subject: [PATCH 09/15] Revert "slight change to wait" This reverts commit 226d4c30a4c6e8570166e4193680198851448973. --- .../applicationinsights/smoketest/LiveMetricsTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index 106251f2d59..bd7da7d684d 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -27,8 +27,10 @@ import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.MonitoringDataPoint; import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.Trace; import java.io.IOException; +import java.time.Duration; import java.util.ArrayList; import java.util.List; +import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -40,7 +42,7 @@ abstract class LiveMetricsTest { @Test @TargetUri("/test") void testTelemetryDataFlow() throws java.lang.Exception { - testing.mockedIngestion.waitForItems("RequestData", 1); + Awaitility.await().atMost(Duration.ofSeconds(20)); assertThat(testing.mockedIngestion.isPingReceived()).isTrue(); From e400d19e70ea8778dd9bad796ccb76975e023bf7 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Fri, 31 Jan 2025 17:00:59 -0800 Subject: [PATCH 10/15] trying a different wait strategy --- .../applicationinsights/smoketest/LiveMetricsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index bd7da7d684d..fbbc02d4d2f 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -42,7 +42,7 @@ abstract class LiveMetricsTest { @Test @TargetUri("/test") void testTelemetryDataFlow() throws java.lang.Exception { - Awaitility.await().atMost(Duration.ofSeconds(20)); + Awaitility.await().atMost(Duration.ofSeconds(20)).until(() -> testing.mockedIngestion.getCountForType("RequestData") == 1); assertThat(testing.mockedIngestion.isPingReceived()).isTrue(); From 30619bf2804fa8d1a5c6dbab83cf31c49c0e9eea Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Fri, 31 Jan 2025 17:10:49 -0800 Subject: [PATCH 11/15] spotless --- .../applicationinsights/smoketest/LiveMetricsTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index fbbc02d4d2f..2b42d0cac1c 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -42,7 +42,9 @@ abstract class LiveMetricsTest { @Test @TargetUri("/test") void testTelemetryDataFlow() throws java.lang.Exception { - Awaitility.await().atMost(Duration.ofSeconds(20)).until(() -> testing.mockedIngestion.getCountForType("RequestData") == 1); + Awaitility.await() + .atMost(Duration.ofSeconds(20)) + .until(() -> testing.mockedIngestion.getCountForType("RequestData") == 1); assertThat(testing.mockedIngestion.isPingReceived()).isTrue(); From 714623f03b12011519210775cb1073b1f1489351 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Fri, 7 Feb 2025 15:12:49 -0800 Subject: [PATCH 12/15] pr comments round 1 --- .../smoketestapp/TestServlet.java | 1 - .../smoketest/LiveMetricsTest.java | 106 ++++++++++-------- .../MockedQuickPulseServlet.java | 7 +- 3 files changed, 65 insertions(+), 49 deletions(-) diff --git a/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java b/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java index ff1969fb500..27c2fc24dca 100644 --- a/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java +++ b/smoke-tests/apps/LiveMetrics/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestServlet.java @@ -27,7 +27,6 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) @WithSpan private void doWork() { - System.out.println("Doing work to generate a dependency call, exception, and trace."); logger.error("This message should generate an exception!", new Exception("Fake Exception")); logger.info("This message should generate a trace"); } diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index 2b42d0cac1c..a20637ae422 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -39,6 +39,11 @@ abstract class LiveMetricsTest { @RegisterExtension static final SmokeTestExtension testing = SmokeTestExtension.create(); + private boolean foundExceptionDoc = false; + private boolean foundTraceDoc = false; + private boolean foundDependency = false; + private boolean foundRequest = false; + @Test @TargetUri("/test") void testTelemetryDataFlow() throws java.lang.Exception { @@ -51,52 +56,8 @@ void testTelemetryDataFlow() throws java.lang.Exception { List postBodies = testing.mockedIngestion.getPostBodies(); assertThat(postBodies).hasSizeGreaterThan(0); // should post at least once - boolean foundExceptionDoc = false; - boolean foundTraceDoc = false; - boolean foundDependency = false; - boolean foundRequest = false; - for (String postBody : postBodies) { - // Each post body is a list with a singular MonitoringDataPoint - List dataPoints = new ArrayList<>(); - try { - JsonReader reader = JsonProviders.createReader(postBody); - // See live metrics swagger to understand MonitoringDataPoint structure - dataPoints = reader.readArray(MonitoringDataPoint::fromJson); - } catch (IOException e) { - throw new java.lang.Exception("Failed to parse post request body", e); - } - - // Because the mock ping/posts should succeed, we should only have one MonitoringDataPoint per - // post - assertThat(dataPoints).hasSize(1); - MonitoringDataPoint dataPoint = dataPoints.get(0); - List docs = dataPoint.getDocuments(); - List metrics = dataPoint.getMetrics(); - - // check that the expected documents are present - // With the default filtering configuration, we should only see the exception and trace - // documents. - for (DocumentIngress doc : docs) { - if (doc.getDocumentType().equals(DocumentType.EXCEPTION) - && ((Exception) doc).getExceptionMessage().equals("Fake Exception")) { - foundExceptionDoc = true; - } else if (doc.getDocumentType().equals(DocumentType.TRACE) - && ((Trace) doc).getMessage().equals("This message should generate a trace")) { - foundTraceDoc = true; - } - } - - // See if dependency and request are counted - for (MetricPoint metric : metrics) { - String name = metric.getName(); - double value = metric.getValue(); - if (name.equals("\\ApplicationInsights\\Dependency Calls/Sec") && value == 1) { - foundDependency = true; - } else if (name.equals("\\ApplicationInsights\\Requests/Sec") && value == 1) { - foundRequest = true; - } - } + searchPostBody(postBody); } assertThat(foundExceptionDoc).isTrue(); @@ -105,6 +66,61 @@ void testTelemetryDataFlow() throws java.lang.Exception { assertThat(foundRequest).isTrue(); } + // check if the expected trace/exception documents are present. + // With the default filtering configuration, we should not see successful requests/dependencies, + // only trace and exception. + private void searchDocs(List docs) { + for (DocumentIngress doc : docs) { + if (doc.getDocumentType().equals(DocumentType.EXCEPTION) + && ((Exception) doc).getExceptionMessage().equals("Fake Exception")) { + foundExceptionDoc = true; + } else if (doc.getDocumentType().equals(DocumentType.TRACE) + && ((Trace) doc).getMessage().equals("This message should generate a trace")) { + foundTraceDoc = true; + } else { + assertThat(doc.getDocumentType()).isNotEqualTo(DocumentType.REMOTE_DEPENDENCY); + assertThat(doc.getDocumentType()).isNotEqualTo(DocumentType.REQUEST); + } + } + } + + private void searchMetrics(List metrics) { + for (MetricPoint metric : metrics) { + String name = metric.getName(); + double value = metric.getValue(); + if (name.equals("\\ApplicationInsights\\Dependency Calls/Sec") && value == 1) { + foundDependency = true; + } else if (name.equals("\\ApplicationInsights\\Requests/Sec") && value == 1) { + foundRequest = true; + } else if (name.equals("\\Process\\Physical Bytes") || name.equals("\\% Process\\Processor Time Normalized")) { + assertThat(value).isNotEqualTo(0); + } + } + } + + + private void searchPostBody(String postBody) { + // Each post body is a list with a singular MonitoringDataPoint + List dataPoints = new ArrayList<>(); + try { + JsonReader reader = JsonProviders.createReader(postBody); + dataPoints = reader.readArray(MonitoringDataPoint::fromJson); + } catch (IOException e) { + throw new IllegalStateException("Failed to parse post request body", e); + } + + // Because the mock ping/posts should succeed, we should only have one MonitoringDataPoint per + // post + assertThat(dataPoints).hasSize(1); + MonitoringDataPoint dataPoint = dataPoints.get(0); + + List docs = dataPoint.getDocuments(); + List metrics = dataPoint.getMetrics(); + + searchDocs(docs); + searchMetrics(metrics); + } + @Environment(TOMCAT_8_JAVA_8) static class Tomcat8Java8Test extends LiveMetricsTest {} diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java index 9bd20c148fa..ad024a3fe32 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java @@ -6,6 +6,7 @@ import com.google.common.io.CharStreams; import java.io.IOException; import java.io.StringWriter; +import java.rmi.ServerError; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -19,7 +20,7 @@ public class MockedQuickPulseServlet extends HttpServlet { private final List postBodies = new ArrayList<>(); private final Object lock = new Object(); - private static final String MOCK_RESPONSE_JSON_DEFAULT_CONFIG = + private static final String BODY = "{\"ETag\":\"fake::etag\",\"Metrics\":[],\"QuotaInfo\":null,\"DocumentStreams\":[{\"Id\":\"all-types-default\",\"DocumentFilterGroups\":[{\"TelemetryType\":\"Request\",\"Filters\":{\"Filters\":[{\"FieldName\":\"Success\",\"Predicate\":\"Equal\",\"Comparand\":\"false\"}]}},{\"TelemetryType\":\"Dependency\",\"Filters\":{\"Filters\":[{\"FieldName\":\"Success\",\"Predicate\":\"Equal\",\"Comparand\":\"false\"}]}},{\"TelemetryType\":\"Exception\",\"Filters\":{\"Filters\":[]}},{\"TelemetryType\":\"Event\",\"Filters\":{\"Filters\":[]}},{\"TelemetryType\":\"Trace\",\"Filters\":{\"Filters\":[]}}]}]}"; private volatile boolean loggingEnabled; @@ -49,7 +50,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I resp.setHeader("x-ms-qps-configuration-etag", "fake::etag"); resp.setHeader("x-ms-qps-subscribed", "true"); resp.setContentType("application/json"); - resp.getWriter().write(MOCK_RESPONSE_JSON_DEFAULT_CONFIG); + resp.getWriter().write(BODY); } else if (path.equals("/post")) { synchronized (lock) { @@ -60,7 +61,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I resp.setHeader("x-ms-qps-subscribed", "true"); resp.setHeader("x-ms-qps-configuration-etag", "fake::etag"); } else { - resp.setStatus(404); + throw new ServerError("Unexpected path: " + path + " please fix the test/mock server setup", new Error()); } } From ea3da396d0f9114988ce0789f76fbcc8d3c52a42 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Fri, 7 Feb 2025 15:47:18 -0800 Subject: [PATCH 13/15] make more modular --- .../smoketest/LiveMetricsTest.java | 101 ++++++++++++------ .../MockedQuickPulseServlet.java | 3 +- 2 files changed, 68 insertions(+), 36 deletions(-) diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index a20637ae422..94c3f7e6771 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -66,39 +66,6 @@ void testTelemetryDataFlow() throws java.lang.Exception { assertThat(foundRequest).isTrue(); } - // check if the expected trace/exception documents are present. - // With the default filtering configuration, we should not see successful requests/dependencies, - // only trace and exception. - private void searchDocs(List docs) { - for (DocumentIngress doc : docs) { - if (doc.getDocumentType().equals(DocumentType.EXCEPTION) - && ((Exception) doc).getExceptionMessage().equals("Fake Exception")) { - foundExceptionDoc = true; - } else if (doc.getDocumentType().equals(DocumentType.TRACE) - && ((Trace) doc).getMessage().equals("This message should generate a trace")) { - foundTraceDoc = true; - } else { - assertThat(doc.getDocumentType()).isNotEqualTo(DocumentType.REMOTE_DEPENDENCY); - assertThat(doc.getDocumentType()).isNotEqualTo(DocumentType.REQUEST); - } - } - } - - private void searchMetrics(List metrics) { - for (MetricPoint metric : metrics) { - String name = metric.getName(); - double value = metric.getValue(); - if (name.equals("\\ApplicationInsights\\Dependency Calls/Sec") && value == 1) { - foundDependency = true; - } else if (name.equals("\\ApplicationInsights\\Requests/Sec") && value == 1) { - foundRequest = true; - } else if (name.equals("\\Process\\Physical Bytes") || name.equals("\\% Process\\Processor Time Normalized")) { - assertThat(value).isNotEqualTo(0); - } - } - } - - private void searchPostBody(String postBody) { // Each post body is a list with a singular MonitoringDataPoint List dataPoints = new ArrayList<>(); @@ -117,8 +84,72 @@ private void searchPostBody(String postBody) { List docs = dataPoint.getDocuments(); List metrics = dataPoint.getMetrics(); - searchDocs(docs); - searchMetrics(metrics); + confirmDocsAreFiltered(docs); + confirmPerfCountersNonZero(metrics); + foundExceptionDoc = foundExceptionDoc || hasException(docs); + foundTraceDoc = foundTraceDoc || hasTrace(docs); + foundDependency = foundDependency || hasDependency(metrics); + foundRequest = foundRequest || hasRequest(metrics); + } + + private void confirmDocsAreFiltered(List docs) { + for (DocumentIngress doc : docs) { + assertThat(doc.getDocumentType()).isNotEqualTo(DocumentType.REMOTE_DEPENDENCY); + assertThat(doc.getDocumentType()).isNotEqualTo(DocumentType.REQUEST); + } + } + + private boolean hasException(List docs) { + for (DocumentIngress doc : docs) { + if (doc.getDocumentType().equals(DocumentType.EXCEPTION) + && ((Exception) doc).getExceptionMessage().equals("Fake Exception")) { + return true; + } + } + return false; + } + + private boolean hasTrace(List docs) { + for (DocumentIngress doc : docs) { + if (doc.getDocumentType().equals(DocumentType.TRACE) + && ((Trace) doc).getMessage().equals("This message should generate a trace")) { + return true; + } + } + return false; + } + + private boolean hasDependency(List metrics) { + for (MetricPoint metric : metrics) { + String name = metric.getName(); + double value = metric.getValue(); + if (name.equals("\\ApplicationInsights\\Dependency Calls/Sec")) { + return value == 1; + } + } + return false; + } + + private boolean hasRequest(List metrics) { + for (MetricPoint metric : metrics) { + String name = metric.getName(); + double value = metric.getValue(); + if (name.equals("\\ApplicationInsights\\Requests/Sec")) { + return value == 1; + } + } + return false; + } + + private void confirmPerfCountersNonZero(List metrics) { + for (MetricPoint metric : metrics) { + String name = metric.getName(); + double value = metric.getValue(); + if (name.equals("\\Process\\Physical Bytes") + || name.equals("\\% Process\\Processor Time Normalized")) { + assertThat(value).isNotEqualTo(0); + } + } } @Environment(TOMCAT_8_JAVA_8) diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java index ad024a3fe32..2da75479175 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java @@ -61,7 +61,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I resp.setHeader("x-ms-qps-subscribed", "true"); resp.setHeader("x-ms-qps-configuration-etag", "fake::etag"); } else { - throw new ServerError("Unexpected path: " + path + " please fix the test/mock server setup", new Error()); + throw new ServerError( + "Unexpected path: " + path + " please fix the test/mock server setup", new Error()); } } From a3e29d877a572cc120c5d8e76943ee926a45d1e2 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Fri, 7 Feb 2025 16:08:45 -0800 Subject: [PATCH 14/15] try to reduce flakiness --- .../applicationinsights/smoketest/LiveMetricsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index 94c3f7e6771..4415e83cc25 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -48,7 +48,7 @@ abstract class LiveMetricsTest { @TargetUri("/test") void testTelemetryDataFlow() throws java.lang.Exception { Awaitility.await() - .atMost(Duration.ofSeconds(20)) + .atMost(Duration.ofSeconds(60)) .until(() -> testing.mockedIngestion.getCountForType("RequestData") == 1); assertThat(testing.mockedIngestion.isPingReceived()).isTrue(); From 8b7cd8c1a9dd00a796fcd33882589147e9801213 Mon Sep 17 00:00:00 2001 From: Harsimar Kaur Date: Mon, 10 Feb 2025 09:54:52 -0800 Subject: [PATCH 15/15] pr comments --- .../smoketest/LiveMetricsTest.java | 166 ++++++++++-------- .../MockedQuickPulseServlet.java | 5 +- 2 files changed, 95 insertions(+), 76 deletions(-) diff --git a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java index 4415e83cc25..e4ed179055a 100644 --- a/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java +++ b/smoke-tests/apps/LiveMetrics/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/LiveMetricsTest.java @@ -39,11 +39,6 @@ abstract class LiveMetricsTest { @RegisterExtension static final SmokeTestExtension testing = SmokeTestExtension.create(); - private boolean foundExceptionDoc = false; - private boolean foundTraceDoc = false; - private boolean foundDependency = false; - private boolean foundRequest = false; - @Test @TargetUri("/test") void testTelemetryDataFlow() throws java.lang.Exception { @@ -51,103 +46,128 @@ void testTelemetryDataFlow() throws java.lang.Exception { .atMost(Duration.ofSeconds(60)) .until(() -> testing.mockedIngestion.getCountForType("RequestData") == 1); + PostBodyVerifier postBodyVerifier = new PostBodyVerifier(); + assertThat(testing.mockedIngestion.isPingReceived()).isTrue(); List postBodies = testing.mockedIngestion.getPostBodies(); assertThat(postBodies).hasSizeGreaterThan(0); // should post at least once for (String postBody : postBodies) { - searchPostBody(postBody); + postBodyVerifier.searchPostBody(postBody); } - assertThat(foundExceptionDoc).isTrue(); - assertThat(foundTraceDoc).isTrue(); - assertThat(foundDependency).isTrue(); - assertThat(foundRequest).isTrue(); + assertThat(postBodyVerifier.hasExceptionDoc()).isTrue(); + assertThat(postBodyVerifier.hasTraceDoc()).isTrue(); + assertThat(postBodyVerifier.hasDependency()).isTrue(); + assertThat(postBodyVerifier.hasRequest()).isTrue(); } - private void searchPostBody(String postBody) { - // Each post body is a list with a singular MonitoringDataPoint - List dataPoints = new ArrayList<>(); - try { - JsonReader reader = JsonProviders.createReader(postBody); - dataPoints = reader.readArray(MonitoringDataPoint::fromJson); - } catch (IOException e) { - throw new IllegalStateException("Failed to parse post request body", e); + class PostBodyVerifier { + boolean foundExceptionDoc = false; + boolean foundTraceDoc = false; + boolean foundDependency = false; + boolean foundRequest = false; + + public void searchPostBody(String postBody) { + // Each post body is a list with a singular MonitoringDataPoint + List dataPoints = new ArrayList<>(); + try { + JsonReader reader = JsonProviders.createReader(postBody); + dataPoints = reader.readArray(MonitoringDataPoint::fromJson); + } catch (IOException e) { + throw new IllegalStateException("Failed to parse post request body", e); + } + + // Because the mock ping/posts should succeed, we should only have one MonitoringDataPoint per + // post + assertThat(dataPoints).hasSize(1); + MonitoringDataPoint dataPoint = dataPoints.get(0); + + List docs = dataPoint.getDocuments(); + List metrics = dataPoint.getMetrics(); + + confirmDocsAreFiltered(docs); + confirmPerfCountersNonZero(metrics); + foundExceptionDoc = foundExceptionDoc || hasException(docs); + foundTraceDoc = foundTraceDoc || hasTrace(docs); + foundDependency = foundDependency || hasDependency(metrics); + foundRequest = foundRequest || hasRequest(metrics); } - // Because the mock ping/posts should succeed, we should only have one MonitoringDataPoint per - // post - assertThat(dataPoints).hasSize(1); - MonitoringDataPoint dataPoint = dataPoints.get(0); + public boolean hasExceptionDoc() { + return foundExceptionDoc; + } - List docs = dataPoint.getDocuments(); - List metrics = dataPoint.getMetrics(); + public boolean hasTraceDoc() { + return foundTraceDoc; + } - confirmDocsAreFiltered(docs); - confirmPerfCountersNonZero(metrics); - foundExceptionDoc = foundExceptionDoc || hasException(docs); - foundTraceDoc = foundTraceDoc || hasTrace(docs); - foundDependency = foundDependency || hasDependency(metrics); - foundRequest = foundRequest || hasRequest(metrics); - } + public boolean hasDependency() { + return foundDependency; + } - private void confirmDocsAreFiltered(List docs) { - for (DocumentIngress doc : docs) { - assertThat(doc.getDocumentType()).isNotEqualTo(DocumentType.REMOTE_DEPENDENCY); - assertThat(doc.getDocumentType()).isNotEqualTo(DocumentType.REQUEST); + public boolean hasRequest() { + return foundRequest; } - } - private boolean hasException(List docs) { - for (DocumentIngress doc : docs) { - if (doc.getDocumentType().equals(DocumentType.EXCEPTION) - && ((Exception) doc).getExceptionMessage().equals("Fake Exception")) { - return true; + private void confirmDocsAreFiltered(List docs) { + for (DocumentIngress doc : docs) { + assertThat(doc.getDocumentType()).isNotEqualTo(DocumentType.REMOTE_DEPENDENCY); + assertThat(doc.getDocumentType()).isNotEqualTo(DocumentType.REQUEST); } } - return false; - } - private boolean hasTrace(List docs) { - for (DocumentIngress doc : docs) { - if (doc.getDocumentType().equals(DocumentType.TRACE) - && ((Trace) doc).getMessage().equals("This message should generate a trace")) { - return true; + private boolean hasException(List docs) { + for (DocumentIngress doc : docs) { + if (doc.getDocumentType().equals(DocumentType.EXCEPTION) + && ((Exception) doc).getExceptionMessage().equals("Fake Exception")) { + return true; + } } + return false; } - return false; - } - private boolean hasDependency(List metrics) { - for (MetricPoint metric : metrics) { - String name = metric.getName(); - double value = metric.getValue(); - if (name.equals("\\ApplicationInsights\\Dependency Calls/Sec")) { - return value == 1; + private boolean hasTrace(List docs) { + for (DocumentIngress doc : docs) { + if (doc.getDocumentType().equals(DocumentType.TRACE) + && ((Trace) doc).getMessage().equals("This message should generate a trace")) { + return true; + } } + return false; } - return false; - } - private boolean hasRequest(List metrics) { - for (MetricPoint metric : metrics) { - String name = metric.getName(); - double value = metric.getValue(); - if (name.equals("\\ApplicationInsights\\Requests/Sec")) { - return value == 1; + private boolean hasDependency(List metrics) { + for (MetricPoint metric : metrics) { + String name = metric.getName(); + double value = metric.getValue(); + if (name.equals("\\ApplicationInsights\\Dependency Calls/Sec")) { + return value == 1; + } } + return false; + } + + private boolean hasRequest(List metrics) { + for (MetricPoint metric : metrics) { + String name = metric.getName(); + double value = metric.getValue(); + if (name.equals("\\ApplicationInsights\\Requests/Sec")) { + return value == 1; + } + } + return false; } - return false; - } - private void confirmPerfCountersNonZero(List metrics) { - for (MetricPoint metric : metrics) { - String name = metric.getName(); - double value = metric.getValue(); - if (name.equals("\\Process\\Physical Bytes") - || name.equals("\\% Process\\Processor Time Normalized")) { - assertThat(value).isNotEqualTo(0); + private void confirmPerfCountersNonZero(List metrics) { + for (MetricPoint metric : metrics) { + String name = metric.getName(); + double value = metric.getValue(); + if (name.equals("\\Process\\Physical Bytes") + || name.equals("\\% Process\\Processor Time Normalized")) { + assertThat(value).isNotEqualTo(0); + } } } } diff --git a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java index 2da75479175..654dfef505e 100644 --- a/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java +++ b/smoke-tests/framework/src/main/java/com/microsoft/applicationinsights/smoketest/fakeingestion/MockedQuickPulseServlet.java @@ -6,7 +6,6 @@ import com.google.common.io.CharStreams; import java.io.IOException; import java.io.StringWriter; -import java.rmi.ServerError; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -61,8 +60,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I resp.setHeader("x-ms-qps-subscribed", "true"); resp.setHeader("x-ms-qps-configuration-etag", "fake::etag"); } else { - throw new ServerError( - "Unexpected path: " + path + " please fix the test/mock server setup", new Error()); + throw new IllegalStateException( + "Unexpected path: " + path + " please fix the test/mock server setup"); } }