diff --git a/instrumentation/avaje-jex-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/avaje/jex/v3_0/JexTest.java b/instrumentation/avaje-jex-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/avaje/jex/v3_0/JexTest.java index 2d897e29282d..0cc7bb581716 100644 --- a/instrumentation/avaje-jex-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/avaje/jex/v3_0/JexTest.java +++ b/instrumentation/avaje-jex-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/avaje/jex/v3_0/JexTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.avaje.jex.v3_0; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; @@ -120,14 +121,10 @@ void testHttpRouteMetricWithPathParamResponseSuccessful() { assertThat(content).isEqualTo(id); assertThat(response.status().code()).isEqualTo(200); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentation, - metric -> - metric - .hasName("http.server.request.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> point.hasAttribute(HTTP_ROUTE, "/test/param/{id}")))); + histogram( + metric -> metric.hasName("http.server.request.duration"), + point -> point.hasAttribute(HTTP_ROUTE, "/test/param/{id}"))); } } diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsMetricsAssertions.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsMetricsAssertions.java index 48840de45937..501c27849f49 100644 --- a/instrumentation/aws-lambda/aws-lambda-events-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsMetricsAssertions.java +++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsMetricsAssertions.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.awslambdaevents.v2_2; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.ErrorAttributes.ERROR_TYPE; @@ -14,7 +15,9 @@ import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MessagingSystemIncubatingValues.AWS_SQS; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; -import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.testing.assertj.HistogramPointAssert; +import io.opentelemetry.sdk.testing.assertj.MetricAssert; +import java.util.function.Consumer; public class AwsLambdaSqsMetricsAssertions { @@ -45,86 +48,63 @@ public static void assertMetrics( String errorType, long failedProcessCount, String failedProcessErrorType) { - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - "messaging.process.duration", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasUnit("s") - .hasDescription("Duration of processing operation.") - .hasHistogramSatisfying( - histogram -> { - if (failedProcessCount == 0) { - histogram.hasPointsSatisfying( - point -> - point - .satisfies( - data -> - assertThat(data.getCount()) - .isEqualTo(processCount)) - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "process"), - equalTo(MESSAGING_SYSTEM, AWS_SQS), - equalTo(MESSAGING_DESTINATION_NAME, destination), - equalTo(ERROR_TYPE, errorType))); - } else { - histogram.hasPointsSatisfying( - point -> - point - .satisfies( - data -> - assertThat(data.getCount()) - .isEqualTo(processCount)) - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "process"), - equalTo(MESSAGING_SYSTEM, AWS_SQS), - equalTo(MESSAGING_DESTINATION_NAME, destination), - equalTo(ERROR_TYPE, errorType)), - point -> - point - .satisfies( - data -> - assertThat(data.getCount()) - .isEqualTo(failedProcessCount)) - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "process"), - equalTo(MESSAGING_SYSTEM, AWS_SQS), - equalTo(MESSAGING_DESTINATION_NAME, destination), - equalTo(ERROR_TYPE, failedProcessErrorType))); - } - }))); - testing.waitAndAssertMetrics( - instrumentationName, - "messaging.client.consumed.messages", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasUnit("{message}") - .hasDescription( - "Number of messages that were delivered to the application.") - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - point -> - point - .hasValue(consumedMessageCount) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "process"), - equalTo(MESSAGING_SYSTEM, AWS_SQS), - equalTo(MESSAGING_DESTINATION_NAME, destination), - equalTo(ERROR_TYPE, errorType)))))); - assertThat(testing.metrics()) - .filteredOn( - metric -> metric.getInstrumentationScopeInfo().getName().equals(instrumentationName)) - .extracting(MetricData::getName) - .containsExactlyInAnyOrder( - "messaging.process.duration", "messaging.client.consumed.messages"); + processingDurationAssertion( + destination, processCount, errorType, failedProcessCount, failedProcessErrorType), + metric -> + metric + .hasName("messaging.client.consumed.messages") + .hasUnit("{message}") + .hasDescription("Number of messages that were delivered to the application.") + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + point -> + point + .hasValue(consumedMessageCount) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "process"), + equalTo(MESSAGING_SYSTEM, AWS_SQS), + equalTo(MESSAGING_DESTINATION_NAME, destination), + equalTo(ERROR_TYPE, errorType))))); + } + + private static Consumer processingDurationAssertion( + String destination, + long processCount, + String errorType, + long failedProcessCount, + String failedProcessErrorType) { + Consumer metricAssertion = + metric -> + metric + .hasName("messaging.process.duration") + .hasUnit("s") + .hasDescription("Duration of processing operation."); + Consumer processPoint = + processPointAssertion(processCount, destination, errorType); + + if (failedProcessCount == 0) { + return histogram(metricAssertion, processPoint); + } + return histogram( + metricAssertion, + processPoint, + processPointAssertion(failedProcessCount, destination, failedProcessErrorType)); + } + + private static Consumer processPointAssertion( + long processCount, String destination, String errorType) { + return point -> + point + .satisfies(data -> assertThat(data.getCount()).isEqualTo(processCount)) + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "process"), + equalTo(MESSAGING_SYSTEM, AWS_SQS), + equalTo(MESSAGING_DESTINATION_NAME, destination), + equalTo(ERROR_TYPE, errorType)); } private AwsLambdaSqsMetricsAssertions() {} diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/testBedrockRuntime/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/Aws2BedrockRuntimeTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/testBedrockRuntime/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/Aws2BedrockRuntimeTest.java index 0198a01ec9a4..318348fef89d 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/testBedrockRuntime/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/Aws2BedrockRuntimeTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/testBedrockRuntime/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/Aws2BedrockRuntimeTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.awssdk.v2_2.internal; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.incubating.EventIncubatingAttributes.EVENT_NAME; import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GEN_AI_OPERATION_NAME; @@ -172,49 +173,45 @@ void testConverseToolCallNoMessageContent() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(415) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(162) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(415) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(162) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -308,49 +305,45 @@ void testConverseToolCallNoMessageContent() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(554) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(57) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(554) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(57) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -518,49 +511,45 @@ void testConverseToolCallStreamNoMessageContent() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(415) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(162) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(415) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(162) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -674,49 +663,45 @@ void testConverseToolCallStreamNoMessageContent() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(554) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(59) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(554) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(59) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -932,49 +917,45 @@ void testInvokeModelToolCallAmazonNovaNoMessageContent() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(416) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(166) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(416) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(166) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); getTesting() @@ -1096,49 +1077,45 @@ void testInvokeModelToolCallAmazonNovaNoMessageContent() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(559) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(59) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(559) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(59) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1374,49 +1351,45 @@ public void accept(PayloadPart chunk) { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(416) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(165) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(416) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(165) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); getTesting() @@ -1582,49 +1555,45 @@ public void accept(PayloadPart chunk) { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(558) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(58) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(558) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(58) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1791,49 +1760,45 @@ void testInvokeModelToolCallAnthropicClaudeNoMessageContent() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(380) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(133) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(380) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(133) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); getTesting() @@ -1933,49 +1898,45 @@ void testInvokeModelToolCallAnthropicClaudeNoMessageContent() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(590) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(132) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(590) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(132) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -2214,49 +2175,45 @@ public void accept(PayloadPart chunk) { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(380) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(144) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(380) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(144) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); getTesting() @@ -2397,49 +2354,45 @@ public void accept(PayloadPart chunk) { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(601) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(145) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(601) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(145) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2BedrockRuntimeTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2BedrockRuntimeTest.java index eae06304a749..ebe065deb4e4 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2BedrockRuntimeTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2BedrockRuntimeTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.awssdk.v2_2; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; import static io.opentelemetry.semconv.incubating.AwsIncubatingAttributes.AWS_BEDROCK_GUARDRAIL_ID; @@ -159,49 +160,45 @@ void testConverseBasic() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(8) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(14) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(8) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(14) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -281,49 +278,45 @@ void testConverseOptions() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("max_tokens"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(8) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(10) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(8) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(10) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -412,49 +405,45 @@ void testConverseToolCall() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(415) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(162) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(415) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(162) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -570,49 +559,45 @@ void testConverseToolCall() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(554) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(57) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(554) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(57) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -881,49 +866,45 @@ void testConverseToolCallStream() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(415) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(162) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(415) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(162) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1059,49 +1040,45 @@ void testConverseToolCallStream() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(554) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(59) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(554) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(59) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1305,49 +1282,45 @@ void testConverseStream() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(8) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(10) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(8) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(10) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1534,49 +1507,45 @@ void testInvokeModelAmazonTitan() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("LENGTH"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(5) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(10) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(5) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(10) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1683,49 +1652,45 @@ void testInvokeModelWithResponseStreamAmazonTitan() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("LENGTH"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(7) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(100) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(7) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(100) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, TEXT_COMPLETION), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1840,49 +1805,45 @@ void testInvokeModelAmazonNova() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("max_tokens"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(5) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(10) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(5) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(10) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -2009,49 +1970,45 @@ void testInvokeModelWithResponseStreamAmazonNova() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("max_tokens"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(7) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(100) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(7) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(100) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -2152,49 +2109,45 @@ void testInvokeModelAnthropicClaude(String modelId) { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("max_tokens"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(14) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(10) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(14) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(10) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -2553,49 +2506,45 @@ void testInvokeModelWithResponseStreamAnthropicClaude() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("max_tokens"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(16) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(10) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(16) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(10) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -2749,49 +2698,45 @@ void testInvokeModelToolCallAmazonNova() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(416) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(166) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(416) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(166) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); getTesting() @@ -2935,49 +2880,45 @@ void testInvokeModelToolCallAmazonNova() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(559) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(59) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(559) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(59) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -3248,49 +3189,45 @@ public void accept(PayloadPart chunk) { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(416) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(165) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(416) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(165) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); getTesting() @@ -3478,49 +3415,45 @@ public void accept(PayloadPart chunk) { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(558) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(58) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(558) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(58) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -3723,49 +3656,45 @@ void testInvokeModelToolCallAnthropicClaude() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(380) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(133) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(380) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(133) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); getTesting() @@ -3887,49 +3816,45 @@ void testInvokeModelToolCallAnthropicClaude() { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(590) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(132) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(590) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(132) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -4206,49 +4131,45 @@ public void accept(PayloadPart chunk) { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("tool_use"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(380) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(144) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(380) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(144) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx0 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); getTesting() @@ -4411,49 +4332,45 @@ public void accept(PayloadPart chunk) { equalTo(GEN_AI_RESPONSE_FINISH_REASONS, asList("end_turn"))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasUnit("{token}") - .hasDescription("Measures number of input and output tokens used.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(601) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, INPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)), - point -> - point - .hasSum(145) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId)))), - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasUnit("s") - .hasDescription("GenAI operation duration.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, modelId))))); + histogram( + metric -> + metric + .hasName("gen_ai.client.token.usage") + .hasUnit("{token}") + .hasDescription("Measures number of input and output tokens used."), + point -> + point + .hasSum(601) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, INPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)), + point -> + point + .hasSum(145) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId))), + histogram( + metric -> + metric + .hasName("gen_ai.client.operation.duration") + .hasUnit("s") + .hasDescription("GenAI operation duration."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, AWS_BEDROCK), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, modelId)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); diff --git a/instrumentation/cassandra/cassandra-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraTest.java b/instrumentation/cassandra/cassandra-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraTest.java index 039345d94388..97bda27b61e1 100644 --- a/instrumentation/cassandra/cassandra-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraTest.java +++ b/instrumentation/cassandra/cassandra-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.cassandra.v4_0; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.DbAttributes.DB_COLLECTION_NAME; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME; @@ -105,23 +106,19 @@ void responsePeerComesFromTheChannel() { assertThat(span.getAttributes().get(NETWORK_PEER_PORT)).isEqualTo(cassandraPort); assertThat(span.getAttributes().get(NETWORK_TYPE)).isEqualTo(null); }); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( getInstrumentationName(), - metric -> - metric - .hasName("db.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfyingExactly( - equalTo(DB_COLLECTION_NAME, "system.local"), - equalTo(DB_OPERATION_NAME, "SELECT"), - equalTo(DB_QUERY_SUMMARY, "SELECT system.local"), - equalTo(DB_SYSTEM_NAME, "cassandra"), - equalTo(NETWORK_PEER_ADDRESS, cassandraIp), - equalTo(NETWORK_PEER_PORT, cassandraPort), - equalTo(SERVER_ADDRESS, cassandraHost), - equalTo(SERVER_PORT, cassandraPort))))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> + point.hasAttributesSatisfyingExactly( + equalTo(DB_COLLECTION_NAME, "system.local"), + equalTo(DB_OPERATION_NAME, "SELECT"), + equalTo(DB_QUERY_SUMMARY, "SELECT system.local"), + equalTo(DB_SYSTEM_NAME, "cassandra"), + equalTo(NETWORK_PEER_ADDRESS, cassandraIp), + equalTo(NETWORK_PEER_PORT, cassandraPort), + equalTo(SERVER_ADDRESS, cassandraHost), + equalTo(SERVER_PORT, cassandraPort)))); } } diff --git a/instrumentation/cassandra/cassandra-4.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_4/CassandraTest.java b/instrumentation/cassandra/cassandra-4.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_4/CassandraTest.java index 73b3625db5e1..68b92f0f7c49 100644 --- a/instrumentation/cassandra/cassandra-4.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_4/CassandraTest.java +++ b/instrumentation/cassandra/cassandra-4.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_4/CassandraTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.cassandra.v4_4; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.DbAttributes.DB_COLLECTION_NAME; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME; @@ -100,24 +101,20 @@ void responsePeerComesFromTheChannel() throws ReflectiveOperationException { assertThat(span.getAttributes().get(NETWORK_PEER_PORT)).isEqualTo(cassandraPort); assertThat(span.getAttributes().get(NETWORK_TYPE)).isEqualTo(null); }); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( getInstrumentationName(), - metric -> - metric - .hasName("db.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfyingExactly( - equalTo(DB_COLLECTION_NAME, "system.local"), - equalTo(DB_OPERATION_NAME, "SELECT"), - equalTo(DB_QUERY_SUMMARY, "SELECT system.local"), - equalTo(DB_SYSTEM_NAME, "cassandra"), - equalTo(NETWORK_PEER_ADDRESS, cassandraIp), - equalTo(NETWORK_PEER_PORT, cassandraPort), - equalTo(SERVER_ADDRESS, "localhost"), - equalTo(SERVER_PORT, cassandraPort))))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> + point.hasAttributesSatisfyingExactly( + equalTo(DB_COLLECTION_NAME, "system.local"), + equalTo(DB_OPERATION_NAME, "SELECT"), + equalTo(DB_QUERY_SUMMARY, "SELECT system.local"), + equalTo(DB_SYSTEM_NAME, "cassandra"), + equalTo(NETWORK_PEER_ADDRESS, cassandraIp), + equalTo(NETWORK_PEER_PORT, cassandraPort), + equalTo(SERVER_ADDRESS, "localhost"), + equalTo(SERVER_PORT, cassandraPort)))); } private static CqlSession getDelegate(CqlSession session) throws IllegalAccessException { diff --git a/instrumentation/clickhouse/clickhouse-client-v1-0.5/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/clickhouse/clientv1/v0_5/ClickHouseClientV1Test.java b/instrumentation/clickhouse/clickhouse-client-v1-0.5/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/clickhouse/clientv1/v0_5/ClickHouseClientV1Test.java index 4ffe448ab4bd..0f0036447006 100644 --- a/instrumentation/clickhouse/clickhouse-client-v1-0.5/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/clickhouse/clientv1/v0_5/ClickHouseClientV1Test.java +++ b/instrumentation/clickhouse/clickhouse-client-v1-0.5/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/clickhouse/clientv1/v0_5/ClickHouseClientV1Test.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.clickhouse.clientv1.v0_5; import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE; import static io.opentelemetry.semconv.DbAttributes.DB_QUERY_SUMMARY; @@ -376,15 +377,11 @@ void testExecuteAndWaitThrowsException() { NETWORK_PEER_PORT, SERVER_ADDRESS, SERVER_PORT); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.clickhouse-client-v1-0.5", - metric -> - metric - .hasName("db.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> point.hasAttribute(ERROR_TYPE, "60")))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> point.hasAttribute(ERROR_TYPE, "60"))); } @Test diff --git a/instrumentation/clickhouse/clickhouse-client-v2-0.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/clickhouse/clientv2/v0_8/ClickHouseClientV2Test.java b/instrumentation/clickhouse/clickhouse-client-v2-0.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/clickhouse/clientv2/v0_8/ClickHouseClientV2Test.java index d88118a1eebf..63b571421626 100644 --- a/instrumentation/clickhouse/clickhouse-client-v2-0.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/clickhouse/clientv2/v0_8/ClickHouseClientV2Test.java +++ b/instrumentation/clickhouse/clickhouse-client-v2-0.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/clickhouse/clientv2/v0_8/ClickHouseClientV2Test.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.clickhouse.clientv2.v0_8; import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE; import static io.opentelemetry.semconv.DbAttributes.DB_QUERY_SUMMARY; @@ -342,15 +343,11 @@ void testQueryThrowsServerException() { NETWORK_PEER_PORT, SERVER_ADDRESS, SERVER_PORT); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.clickhouse-client-v2-0.8", - metric -> - metric - .hasName("db.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> point.hasAttribute(ERROR_TYPE, "60")))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> point.hasAttribute(ERROR_TYPE, "60"))); } @Test diff --git a/instrumentation/dropwizard/dropwizard-metrics-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/dropwizardmetrics/v4_0/DropwizardMetricsTest.java b/instrumentation/dropwizard/dropwizard-metrics-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/dropwizardmetrics/v4_0/DropwizardMetricsTest.java index 539b57eab6d2..e1c596be5168 100644 --- a/instrumentation/dropwizard/dropwizard-metrics-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/dropwizardmetrics/v4_0/DropwizardMetricsTest.java +++ b/instrumentation/dropwizard/dropwizard-metrics-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/dropwizardmetrics/v4_0/DropwizardMetricsTest.java @@ -16,6 +16,7 @@ import com.codahale.metrics.Timer; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.instrumentation.testing.util.MetricAssertions; import java.util.concurrent.atomic.AtomicLong; import org.assertj.core.api.AbstractIterableAssert; import org.junit.jupiter.api.Test; @@ -39,7 +40,7 @@ void gauge() { metricRegistry.gauge("test'gauge", () -> value::get); // then - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -67,7 +68,7 @@ void counter() { counter.dec(5); // then - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -96,15 +97,10 @@ void histogram() { histogram.update(30); // then - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testhistogram") - .hasHistogramSatisfying( - histogramMetric -> - histogramMetric.hasPointsSatisfying( - point -> point.hasSum(42).hasCount(2)))); + MetricAssertions.histogram( + metric -> metric.hasName("testhistogram"), point -> point.hasSum(42).hasCount(2))); testing.clearData(); // when @@ -127,7 +123,7 @@ void meter() { meter.mark(11); // then - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -157,15 +153,11 @@ void timer() { timer.update(234_000, NANOSECONDS); // then - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testtimer") - .hasUnit("ms") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying(point -> point.hasSum(1.234).hasCount(2)))); + MetricAssertions.histogram( + metric -> metric.hasName("testtimer").hasUnit("ms"), + point -> point.hasSum(1.234).hasCount(2))); testing.clearData(); // when diff --git a/instrumentation/failsafe-3.0/library/src/test/java/io/opentelemetry/instrumentation/failsafe/v3_0/FailsafeTelemetryTest.java b/instrumentation/failsafe-3.0/library/src/test/java/io/opentelemetry/instrumentation/failsafe/v3_0/FailsafeTelemetryTest.java index f937bcaa21cd..829b237f821c 100644 --- a/instrumentation/failsafe-3.0/library/src/test/java/io/opentelemetry/instrumentation/failsafe/v3_0/FailsafeTelemetryTest.java +++ b/instrumentation/failsafe-3.0/library/src/test/java/io/opentelemetry/instrumentation/failsafe/v3_0/FailsafeTelemetryTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.instrumentation.failsafe.v3_0; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static org.assertj.core.api.Assertions.assertThat; @@ -52,7 +53,7 @@ void captureCircuitBreakerMetrics() { } // then - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.failsafe-3.0", metricAssert -> metricAssert @@ -106,7 +107,7 @@ void captureRetryPolicyMetrics() { } // then - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.failsafe-3.0", metricAssert -> metricAssert @@ -117,32 +118,26 @@ void captureRetryPolicyMetrics() { .hasPointsSatisfying( buildRetryPolicyAssertion(2, "failure"), buildRetryPolicyAssertion(3, "success"))), - metricAssert -> - metricAssert - .hasName("failsafe.retry_policy.attempts") - .hasHistogramSatisfying( - histogramAssert -> - histogramAssert.hasPointsSatisfying( - histogramPointAssert -> - histogramPointAssert - .hasCount(3) - .hasMin(1) - .hasMax(3) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("failsafe.retry_policy.name"), "testing"), - equalTo( - stringKey("failsafe.retry_policy.outcome"), "success")) - .hasBucketCounts(1L, 1L, 1L, 0L, 0L), - histogramPointAssert -> - histogramPointAssert - .hasCount(2) - .hasMin(3) - .hasMax(3) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("failsafe.retry_policy.name"), "testing"), - equalTo( - stringKey("failsafe.retry_policy.outcome"), "failure")) - .hasBucketCounts(0L, 0L, 2L, 0L, 0L)))); + histogram( + metricAssert -> metricAssert.hasName("failsafe.retry_policy.attempts"), + histogramPointAssert -> + histogramPointAssert + .hasCount(3) + .hasMin(1) + .hasMax(3) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("failsafe.retry_policy.name"), "testing"), + equalTo(stringKey("failsafe.retry_policy.outcome"), "success")) + .hasBucketCounts(1L, 1L, 1L, 0L, 0L), + histogramPointAssert -> + histogramPointAssert + .hasCount(2) + .hasMin(3) + .hasMax(3) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("failsafe.retry_policy.name"), "testing"), + equalTo(stringKey("failsafe.retry_policy.outcome"), "failure")) + .hasBucketCounts(0L, 0L, 2L, 0L, 0L))); } private static Consumer buildCircuitBreakerAssertion( diff --git a/instrumentation/iceberg-1.8/testing/src/main/java/io/opentelemetry/instrumentation/iceberg/v1_8/AbstractIcebergTest.java b/instrumentation/iceberg-1.8/testing/src/main/java/io/opentelemetry/instrumentation/iceberg/v1_8/AbstractIcebergTest.java index 3050fda468b0..a3bd1ae74e9e 100644 --- a/instrumentation/iceberg-1.8/testing/src/main/java/io/opentelemetry/instrumentation/iceberg/v1_8/AbstractIcebergTest.java +++ b/instrumentation/iceberg-1.8/testing/src/main/java/io/opentelemetry/instrumentation/iceberg/v1_8/AbstractIcebergTest.java @@ -7,13 +7,16 @@ import static io.opentelemetry.api.common.AttributeKey.longKey; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.sdk.testing.assertj.MetricAssert; import java.io.File; import java.io.IOException; +import java.util.function.Consumer; import org.apache.iceberg.DataFile; import org.apache.iceberg.DataFiles; import org.apache.iceberg.FileScanTask; @@ -93,298 +96,227 @@ void testCreateTelemetry() throws IOException { assertThat(reporter.report).isInstanceOf(ScanReport.class); ScanReport expected = (ScanReport) reporter.report; - assertScanDurationMetric(expected); - assertDataFilesCountMetrics(expected); - assertDeleteFilesCountMetrics(expected); - assertDataManifestCountMetrics(expected); - assertDeleteManifestCountMetrics(expected); - assertSizeMetric( - "iceberg.scan.data_files.size", - expected, - expected.scanMetrics().totalFileSizeInBytes().value()); - assertSizeMetric( - "iceberg.scan.delete_files.size", - expected, - expected.scanMetrics().totalDeleteFileSizeInBytes().value()); - } - - private void assertScanDurationMetric(ScanReport expectedReport) { testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metricAssert -> - metricAssert - .hasName("iceberg.scan.planning.duration") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName()))))); + assertScanDurationMetric(expected), + assertDataFilesCountMetrics(expected), + assertDeleteFilesCountMetrics(expected), + assertDataManifestCountMetrics(expected), + assertDeleteManifestCountMetrics(expected), + assertSizeMetric( + "iceberg.scan.data_files.size", + expected, + expected.scanMetrics().totalFileSizeInBytes().value()), + assertSizeMetric( + "iceberg.scan.delete_files.size", + expected, + expected.scanMetrics().totalDeleteFileSizeInBytes().value())); } - private void assertDataFilesCountMetrics(ScanReport expectedReport) { - testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metricAssert -> - metricAssert - .hasName("iceberg.scan.data_files.count") - .hasUnit("{file}") - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - longSumAssert -> - longSumAssert - .hasValue( - expectedReport.scanMetrics().resultDataFiles().value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "scanned"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName())), - longSumAssert -> - longSumAssert - .hasValue( - expectedReport.scanMetrics().skippedDataFiles().value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "skipped"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName()))))); + private static Consumer assertScanDurationMetric(ScanReport expectedReport) { + return histogram( + metric -> metric.hasName("iceberg.scan.planning.duration").hasUnit("s"), + point -> + point + .hasSumGreaterThan(0.0) + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo(stringKey("iceberg.table.name"), expectedReport.tableName()))); } - private void assertDataManifestCountMetrics(ScanReport expectedReport) { - testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metricAssert -> - metricAssert - .hasName("iceberg.scan.data_manifests.count") - .hasUnit("{file}") - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - longSumAssert -> - longSumAssert - .hasValue( - expectedReport - .scanMetrics() - .scannedDataManifests() - .value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "scanned"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName())), - longSumAssert -> - longSumAssert - .hasValue( - expectedReport - .scanMetrics() - .skippedDataManifests() - .value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "skipped"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName()))))); + private static Consumer assertDataFilesCountMetrics(ScanReport expectedReport) { + return metricAssert -> + metricAssert + .hasName("iceberg.scan.data_files.count") + .hasUnit("{file}") + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + longSumAssert -> + longSumAssert + .hasValue(expectedReport.scanMetrics().resultDataFiles().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "scanned"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())), + longSumAssert -> + longSumAssert + .hasValue(expectedReport.scanMetrics().skippedDataFiles().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "skipped"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())))); } - private void assertDeleteManifestCountMetrics(ScanReport expectedReport) { - testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metricAssert -> - metricAssert - .hasName("iceberg.scan.delete_manifests.count") - .hasUnit("{file}") - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - longSumAssert -> - longSumAssert - .hasValue( - expectedReport - .scanMetrics() - .scannedDeleteManifests() - .value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "scanned"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName())), - longSumAssert -> - longSumAssert - .hasValue( - expectedReport - .scanMetrics() - .skippedDeleteManifests() - .value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "skipped"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName()))))); + private static Consumer assertDataManifestCountMetrics(ScanReport expectedReport) { + return metricAssert -> + metricAssert + .hasName("iceberg.scan.data_manifests.count") + .hasUnit("{file}") + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + longSumAssert -> + longSumAssert + .hasValue( + expectedReport.scanMetrics().scannedDataManifests().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "scanned"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())), + longSumAssert -> + longSumAssert + .hasValue( + expectedReport.scanMetrics().skippedDataManifests().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "skipped"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())))); } - private void assertDeleteFilesCountMetrics(ScanReport expectedReport) { - testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metricAssert -> - metricAssert - .hasName("iceberg.scan.delete_files.count") - .hasUnit("{file}") - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - longSumAssert -> - longSumAssert - .hasValue( - expectedReport - .scanMetrics() - .resultDeleteFiles() - .value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "scanned"), - equalTo(stringKey("iceberg.delete_file.type"), "all"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName())), - longSumAssert -> - longSumAssert - .hasValue( - expectedReport - .scanMetrics() - .skippedDeleteFiles() - .value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "skipped"), - equalTo(stringKey("iceberg.delete_file.type"), "all"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName())), - longSumAssert -> - longSumAssert - .hasValue( - expectedReport - .scanMetrics() - .indexedDeleteFiles() - .value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "scanned"), - equalTo( - stringKey("iceberg.delete_file.type"), "indexed"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName())), - longSumAssert -> - longSumAssert - .hasValue( - expectedReport - .scanMetrics() - .equalityDeleteFiles() - .value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "scanned"), - equalTo( - stringKey("iceberg.delete_file.type"), "equality"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName())), - longSumAssert -> - longSumAssert - .hasValue( - expectedReport - .scanMetrics() - .positionalDeleteFiles() - .value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "scanned"), - equalTo( - stringKey("iceberg.delete_file.type"), "position"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName())), - longSumAssert -> - longSumAssert - .hasValue(expectedReport.scanMetrics().dvs().value()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("iceberg.scan.state"), "scanned"), - equalTo(stringKey("iceberg.delete_file.type"), "dvs"), - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName()))))); + private static Consumer assertDeleteManifestCountMetrics( + ScanReport expectedReport) { + return metricAssert -> + metricAssert + .hasName("iceberg.scan.delete_manifests.count") + .hasUnit("{file}") + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + longSumAssert -> + longSumAssert + .hasValue( + expectedReport.scanMetrics().scannedDeleteManifests().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "scanned"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())), + longSumAssert -> + longSumAssert + .hasValue( + expectedReport.scanMetrics().skippedDeleteManifests().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "skipped"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())))); } - private void assertSizeMetric( + private static Consumer assertDeleteFilesCountMetrics(ScanReport expectedReport) { + return metricAssert -> + metricAssert + .hasName("iceberg.scan.delete_files.count") + .hasUnit("{file}") + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + longSumAssert -> + longSumAssert + .hasValue(expectedReport.scanMetrics().resultDeleteFiles().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "scanned"), + equalTo(stringKey("iceberg.delete_file.type"), "all"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())), + longSumAssert -> + longSumAssert + .hasValue(expectedReport.scanMetrics().skippedDeleteFiles().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "skipped"), + equalTo(stringKey("iceberg.delete_file.type"), "all"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())), + longSumAssert -> + longSumAssert + .hasValue(expectedReport.scanMetrics().indexedDeleteFiles().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "scanned"), + equalTo(stringKey("iceberg.delete_file.type"), "indexed"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())), + longSumAssert -> + longSumAssert + .hasValue( + expectedReport.scanMetrics().equalityDeleteFiles().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "scanned"), + equalTo(stringKey("iceberg.delete_file.type"), "equality"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())), + longSumAssert -> + longSumAssert + .hasValue( + expectedReport.scanMetrics().positionalDeleteFiles().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "scanned"), + equalTo(stringKey("iceberg.delete_file.type"), "position"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())), + longSumAssert -> + longSumAssert + .hasValue(expectedReport.scanMetrics().dvs().value()) + .hasAttributesSatisfyingExactly( + equalTo(stringKey("iceberg.scan.state"), "scanned"), + equalTo(stringKey("iceberg.delete_file.type"), "dvs"), + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())))); + } + + private static Consumer assertSizeMetric( String otelMetricName, ScanReport expectedReport, long expectedValue) { - testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metricAssert -> - metricAssert - .hasName(otelMetricName) - .hasUnit("By") - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - longSumAssert -> - longSumAssert - .hasValue(expectedValue) - .hasAttributesSatisfyingExactly( - equalTo( - longKey("iceberg.schema.id"), - expectedReport.schemaId()), - equalTo( - stringKey("iceberg.table.name"), - expectedReport.tableName()))))); + return metricAssert -> + metricAssert + .hasName(otelMetricName) + .hasUnit("By") + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + longSumAssert -> + longSumAssert + .hasValue(expectedValue) + .hasAttributesSatisfyingExactly( + equalTo( + longKey("iceberg.schema.id"), expectedReport.schemaId()), + equalTo( + stringKey("iceberg.table.name"), + expectedReport.tableName())))); } private static class SimpleReporter implements MetricsReporter { diff --git a/instrumentation/javalin/testing/src/main/java/io/opentelemetry/instrumentation/javalin/AbstractJavalinTest.java b/instrumentation/javalin/testing/src/main/java/io/opentelemetry/instrumentation/javalin/AbstractJavalinTest.java index 57dd0f071e71..8337e03a5cce 100644 --- a/instrumentation/javalin/testing/src/main/java/io/opentelemetry/instrumentation/javalin/AbstractJavalinTest.java +++ b/instrumentation/javalin/testing/src/main/java/io/opentelemetry/instrumentation/javalin/AbstractJavalinTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.javalin; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; @@ -161,14 +162,10 @@ void testHttpRouteMetricWithPathParamResponseSuccessful() { assertThat(content).isEqualTo(id); assertThat(response.status().code()).isEqualTo(200); testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( getJettyInstrumentation(), - metric -> - metric - .hasName("http.server.request.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> point.hasAttribute(HTTP_ROUTE, "/param/{id}")))); + histogram( + metric -> metric.hasName("http.server.request.duration"), + point -> point.hasAttribute(HTTP_ROUTE, "/param/{id}"))); } } diff --git a/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/datasource/JdbcTelemetryTest.java b/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/datasource/JdbcTelemetryTest.java index 73e91f613f52..5302bf626959 100644 --- a/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/datasource/JdbcTelemetryTest.java +++ b/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/datasource/JdbcTelemetryTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.instrumentation.jdbc.datasource; import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_BATCH_SIZE; @@ -169,15 +170,11 @@ void error(int errorCode, String sqlState, String expectedErrorType) throws SQLE DB_SYSTEM_NAME, ERROR_TYPE, SERVER_ADDRESS); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.jdbc", - metric -> - metric - .hasName("db.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> point.hasAttribute(ERROR_TYPE, expectedErrorType)))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> point.hasAttribute(ERROR_TYPE, expectedErrorType))); } private static Stream errorCodes() { diff --git a/instrumentation/jedis/jedis-2.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v2_0/ShardedJedisClientTest.java b/instrumentation/jedis/jedis-2.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v2_0/ShardedJedisClientTest.java index e49d71d2a987..fafb5f7761c4 100644 --- a/instrumentation/jedis/jedis-2.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v2_0/ShardedJedisClientTest.java +++ b/instrumentation/jedis/jedis-2.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v2_0/ShardedJedisClientTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.jedis.v2_0; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME; @@ -144,15 +145,11 @@ void commandFromAllShardsUsesConfiguredTarget() { NETWORK_PEER_ADDRESS, peerAddress.getAddress().getHostAddress()), equalTo(NETWORK_PEER_PORT, (long) peerAddress.getPort())))); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.jedis-2.0", - metric -> - metric - .hasName("db.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> point.hasAttribute(SERVER_ADDRESS, configuredTarget)))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> point.hasAttribute(SERVER_ADDRESS, configuredTarget))); } @Test diff --git a/instrumentation/jedis/jedis-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v3_0/ShardedJedis30ClientTest.java b/instrumentation/jedis/jedis-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v3_0/ShardedJedis30ClientTest.java index 63e62200ec1b..0391ed26385c 100644 --- a/instrumentation/jedis/jedis-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v3_0/ShardedJedis30ClientTest.java +++ b/instrumentation/jedis/jedis-3.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v3_0/ShardedJedis30ClientTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.jedis.v3_0; import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE; @@ -153,20 +154,15 @@ void commandFromAllShardsUsesConfiguredTarget() { SERVER_ADDRESS, NETWORK_PEER_ADDRESS, NETWORK_PEER_PORT); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.jedis-3.0", - metric -> - metric - .hasName("db.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasAttribute(SERVER_ADDRESS, configuredTarget) - .hasAttributesSatisfying( - attributes -> - assertThat(attributes.asMap()) - .doesNotContainKey(SERVER_PORT))))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> + point + .hasAttribute(SERVER_ADDRESS, configuredTarget) + .hasAttributesSatisfying( + attributes -> + assertThat(attributes.asMap()).doesNotContainKey(SERVER_PORT)))); } } diff --git a/instrumentation/jedis/jedis-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v4_0/Jedis40ClientTest.java b/instrumentation/jedis/jedis-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v4_0/Jedis40ClientTest.java index 68afc7385599..4f2c489166a6 100644 --- a/instrumentation/jedis/jedis-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v4_0/Jedis40ClientTest.java +++ b/instrumentation/jedis/jedis-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jedis/v4_0/Jedis40ClientTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.jedis.v4_0; import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_BATCH_SIZE; @@ -154,19 +155,15 @@ void mappedCommandUsesConfiguredTarget() { equalTo(NETWORK_PEER_PORT, port), equalTo(NETWORK_PEER_ADDRESS, ip)))); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.jedis-4.0", - metric -> - metric - .hasName("db.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasAttribute(DB_OPERATION_NAME, "SET") - .hasAttribute(SERVER_ADDRESS, configuredHost) - .hasAttribute(SERVER_PORT, (long) configuredPort)))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> + point + .hasAttribute(DB_OPERATION_NAME, "SET") + .hasAttribute(SERVER_ADDRESS, configuredHost) + .hasAttribute(SERVER_PORT, (long) configuredPort))); } @Test diff --git a/instrumentation/kubernetes-client-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/v7_0/KubernetesClientTest.java b/instrumentation/kubernetes-client-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/v7_0/KubernetesClientTest.java index 871a638f04f8..839c99a65f08 100644 --- a/instrumentation/kubernetes-client-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/v7_0/KubernetesClientTest.java +++ b/instrumentation/kubernetes-client-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/v7_0/KubernetesClientTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.testing.junit.service.SemconvServiceStabilityUtil.maybeStablePeerService; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.orderByRootSpanName; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; @@ -104,16 +105,15 @@ void synchronousCall() throws ApiException { experimental("namespace")), equalTo(stringKey("kubernetes-client.name"), experimental("name"))))); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.kubernetes-client-7.0", - metric -> - metric - .hasName("http.client.request.duration") - .hasDescription("Duration of HTTP client requests.") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying(point -> point.hasSumGreaterThan(0.0)))); + histogram( + metric -> + metric + .hasName("http.client.request.duration") + .hasDescription("Duration of HTTP client requests.") + .hasUnit("s"), + point -> point.hasSumGreaterThan(0.0))); } @Test diff --git a/instrumentation/kubernetes-client-7.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/v7_0/KubernetesClientVer20Test.java b/instrumentation/kubernetes-client-7.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/v7_0/KubernetesClientVer20Test.java index 0696a7cd31f3..64eb523a2c5a 100644 --- a/instrumentation/kubernetes-client-7.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/v7_0/KubernetesClientVer20Test.java +++ b/instrumentation/kubernetes-client-7.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/v7_0/KubernetesClientVer20Test.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.testing.junit.service.SemconvServiceStabilityUtil.maybeStablePeerService; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.orderByRootSpanName; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; @@ -108,16 +109,15 @@ void synchronousCall() throws ApiException { experimental("namespace")), equalTo(stringKey("kubernetes-client.name"), experimental("name"))))); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.kubernetes-client-7.0", - metric -> - metric - .hasName("http.client.request.duration") - .hasDescription("Duration of HTTP client requests.") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying(point -> point.hasSumGreaterThan(0.0)))); + histogram( + metric -> + metric + .hasName("http.client.request.duration") + .hasDescription("Duration of HTTP client requests.") + .hasUnit("s"), + point -> point.hasSumGreaterThan(0.0))); } @Test diff --git a/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceReactiveClientTest.java b/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceReactiveClientTest.java index 29bcfb1cf545..8655a4842859 100644 --- a/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceReactiveClientTest.java +++ b/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceReactiveClientTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.booleanKey; import static io.opentelemetry.api.common.AttributeKey.longKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.javaagent.instrumentation.lettuce.v5_0.ExperimentalHelper.EXPERIMENTAL_ATTRIBUTES_ENABLED; import static io.opentelemetry.javaagent.instrumentation.lettuce.v5_0.ExperimentalHelper.experimental; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; @@ -435,13 +436,11 @@ void testNoResponseCommandFluxCancellationEndsSpanOnce() { trace -> trace.hasSpansSatisfyingExactly( span -> span.hasName("DEBUG " + host + ":" + port).hasKind(SpanKind.CLIENT))); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.lettuce-5.0", - metrics -> - metrics - .hasName("db.client.operation.duration") - .hasHistogramSatisfying( - histogram -> histogram.hasPointsSatisfying(point -> point.hasCount(1)))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> point.hasCount(1))); }); } diff --git a/instrumentation/lettuce/lettuce-5.1/testing/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceClientTest.java b/instrumentation/lettuce/lettuce-5.1/testing/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceClientTest.java index 6846fcece1db..66c829df4d47 100644 --- a/instrumentation/lettuce/lettuce-5.1/testing/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceClientTest.java +++ b/instrumentation/lettuce/lettuce-5.1/testing/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceClientTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.lettuce.v5_1; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.instrumentation.testing.util.TestLatestDeps.testLatestDeps; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; @@ -101,19 +102,11 @@ protected static void assertCommandErrorEvents(SpanData span) { protected void assertCommandErrorMetric(String errorType) { testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( "io.opentelemetry.lettuce-5.1", - "db.client.operation.duration", - metrics -> - metrics.anySatisfy( - metric -> - assertThat(metric) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfying( - equalTo(ERROR_TYPE, errorType)))))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> point.hasAttributesSatisfying(equalTo(ERROR_TYPE, errorType)))); } protected String spanName(String operation) { diff --git a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractDistributionSummaryHistogramGaugesTest.java b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractDistributionSummaryHistogramGaugesTest.java index 318a346dc897..301e6de6ff21 100644 --- a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractDistributionSummaryHistogramGaugesTest.java +++ b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractDistributionSummaryHistogramGaugesTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.micrometer.v1_5.AbstractCounterTest.INSTRUMENTATION_NAME; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import io.micrometer.core.instrument.DistributionSummary; @@ -44,25 +45,19 @@ void testMicrometerHistogram() { // then testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testSummary") - .hasDescription("This is a test distribution summary") - .hasUnit("things") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - points -> - points - .hasSum(555.5) - .hasCount(4) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value"))))); - testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, + histogram( + metric -> + metric + .hasName("testSummary") + .hasDescription("This is a test distribution summary") + .hasUnit("things"), + point -> + point + .hasSum(555.5) + .hasCount(4) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value"))), metric -> metric .hasName("testSummary.histogram") @@ -112,25 +107,19 @@ void testMicrometerPercentiles() { // then testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testSummary") - .hasDescription("This is a test distribution summary") - .hasUnit("things") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(150) - .hasCount(2) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value"))))); - testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, + histogram( + metric -> + metric + .hasName("testSummary") + .hasDescription("This is a test distribution summary") + .hasUnit("things"), + point -> + point + .hasSum(150) + .hasCount(2) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value"))), metric -> metric .hasName("testSummary.percentile") diff --git a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractDistributionSummaryTest.java b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractDistributionSummaryTest.java index ee0b50d3bb95..8b3016e79a07 100644 --- a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractDistributionSummaryTest.java +++ b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractDistributionSummaryTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.micrometer.v1_5.AbstractCounterTest.INSTRUMENTATION_NAME; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import io.micrometer.core.instrument.DistributionSummary; @@ -44,23 +45,20 @@ void testMicrometerDistributionSummary() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testSummary") - .hasDescription("This is a test distribution summary") - .hasUnit("things") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(7) - .hasCount(3) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value")) - .hasBucketBoundaries(NO_BUCKETS)))); + histogram( + metric -> + metric + .hasName("testSummary") + .hasDescription("This is a test distribution summary") + .hasUnit("things"), + point -> + point + .hasSum(7) + .hasCount(3) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value")) + .hasBucketBoundaries(NO_BUCKETS))); // micrometer gauge histogram is not emitted testing() @@ -73,20 +71,15 @@ void testMicrometerDistributionSummary() { // then // The synchronous histogram returns its previous value after removal. testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testSummary") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(7) - .hasCount(3) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value"))))); + histogram( + metric -> metric.hasName("testSummary"), + point -> + point + .hasSum(7) + .hasCount(3) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value")))); } @Test @@ -109,24 +102,21 @@ void testMicrometerDistributionSummaryWithCustomBuckets() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testSummaryWithCustomBuckets") - .hasDescription("This is a test distribution summary") - .hasUnit("things") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - points -> - points - .hasSum(555.5) - .hasCount(4) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value")) - .hasBucketBoundaries(1, 10, 100, 1000) - .hasBucketCounts(1, 1, 1, 1, 0)))); + histogram( + metric -> + metric + .hasName("testSummaryWithCustomBuckets") + .hasDescription("This is a test distribution summary") + .hasUnit("things"), + points -> + points + .hasSum(555.5) + .hasCount(4) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value")) + .hasBucketBoundaries(1, 10, 100, 1000) + .hasBucketCounts(1, 1, 1, 1, 0))); // micrometer gauge histogram is not emitted testing() diff --git a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractNamingConventionTest.java b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractNamingConventionTest.java index e3ae8cf73f2a..27e7a7abc0e1 100644 --- a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractNamingConventionTest.java +++ b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractNamingConventionTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.micrometer.v1_5.AbstractCounterTest.INSTRUMENTATION_NAME; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.SECONDS; @@ -62,7 +63,7 @@ void renameCounter() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -85,17 +86,13 @@ void renameDistributionSummary() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("test.renamedSummary") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfyingExactly( - equalTo(stringKey("test.tag"), "test.value"))))); + histogram( + metric -> metric.hasName("test.renamedSummary"), + point -> + point.hasAttributesSatisfyingExactly( + equalTo(stringKey("test.tag"), "test.value")))); } @Test @@ -105,7 +102,7 @@ void renameFunctionCounter() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -127,7 +124,7 @@ void renameCustomMeterStatistic() { .register(Metrics.globalRegistry); testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -152,7 +149,7 @@ void renameFunctionTimer() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -162,10 +159,7 @@ void renameFunctionTimer() { sum.hasPointsSatisfying( point -> point.hasAttributesSatisfyingExactly( - equalTo(stringKey("test.tag"), "test.value"))))); - testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, + equalTo(stringKey("test.tag"), "test.value")))), metric -> metric .hasName("test.renamedFunctionTimer.sum") @@ -184,7 +178,7 @@ void renameGauge() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -207,7 +201,7 @@ void renameLongTaskTimer() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -217,10 +211,7 @@ void renameLongTaskTimer() { sum.hasPointsSatisfying( point -> point.hasAttributesSatisfyingExactly( - equalTo(stringKey("test.tag"), "test.value"))))); - testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, + equalTo(stringKey("test.tag"), "test.value")))), metric -> metric .hasName("test.renamedLongTaskTimer.duration") @@ -242,16 +233,12 @@ void renameTimer() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("test.renamedTimer") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfyingExactly( - equalTo(stringKey("test.tag"), "test.value"))))); + histogram( + metric -> metric.hasName("test.renamedTimer"), + point -> + point.hasAttributesSatisfyingExactly( + equalTo(stringKey("test.tag"), "test.value")))); } } diff --git a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractPrometheusModeTest.java b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractPrometheusModeTest.java index 2d78a0b1a232..55ea4719b882 100644 --- a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractPrometheusModeTest.java +++ b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractPrometheusModeTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.micrometer.v1_5.AbstractCounterTest.INSTRUMENTATION_NAME; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.Collections.singletonList; @@ -50,7 +51,7 @@ void testCounter() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -84,22 +85,19 @@ void testDistributionSummary() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testPrometheusSummary.items") - .hasDescription("This is a test summary") - .hasUnit("items") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(54) - .hasCount(2) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value"))))); + histogram( + metric -> + metric + .hasName("testPrometheusSummary.items") + .hasDescription("This is a test summary") + .hasUnit("items"), + point -> + point + .hasSum(54) + .hasCount(2) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value")))); } @Test @@ -135,10 +133,7 @@ void testFunctionTimer() { point .hasValue(1) .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value"))))); - testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, + equalTo(stringKey("tag"), "value")))), metric -> metric .hasName("testPrometheusFunctionTimer.seconds.sum") @@ -165,7 +160,7 @@ void testGauge() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -196,7 +191,7 @@ void testLongTaskTimer() throws InterruptedException { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -211,10 +206,7 @@ void testLongTaskTimer() throws InterruptedException { point .hasValue(1) .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value"))))); - testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, + equalTo(stringKey("tag"), "value")))), metric -> metric .hasName("testPrometheusLongTaskTimer.seconds.duration") @@ -281,7 +273,7 @@ void testMeter() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric @@ -315,22 +307,19 @@ void testTimer() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testPrometheusTimer.seconds") - .hasDescription("This is a test timer") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(16.789) - .hasCount(3) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value"))))); + histogram( + metric -> + metric + .hasName("testPrometheusTimer.seconds") + .hasDescription("This is a test timer") + .hasUnit("s"), + point -> + point + .hasSum(16.789) + .hasCount(3) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value")))); } @Test @@ -355,16 +344,13 @@ void testSameNameDifferentTypeKeepsOwnDescription() { // then each instrument keeps its own description testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, metric -> metric .hasName("testPrometheusSharedName") .hasDescription("This is a test counter") - .hasDoubleSumSatisfying(sum -> sum.isMonotonic())); - testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, + .hasDoubleSumSatisfying(sum -> sum.isMonotonic()), metric -> metric .hasName("testPrometheusSharedName.seconds") @@ -387,29 +373,24 @@ void testTimerCustomBucketBoundaryFormatting() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testPrometheusTimerBoundary.seconds") - .hasDescription("This is a test timer") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(0.1) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value")) - .satisfies( - pointData -> { - assertThat(pointData.getBoundaries()).hasSize(1); - assertThat( - Double.toString( - pointData.getBoundaries().get(0))) - .isEqualTo("0.3"); - })))); + histogram( + metric -> + metric + .hasName("testPrometheusTimerBoundary.seconds") + .hasDescription("This is a test timer") + .hasUnit("s"), + point -> + point + .hasSum(0.1) + .hasCount(1) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value")) + .satisfies( + pointData -> { + assertThat(pointData.getBoundaries()).hasSize(1); + assertThat(Double.toString(pointData.getBoundaries().get(0))) + .isEqualTo("0.3"); + }))); } } diff --git a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerHistogramGaugesTest.java b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerHistogramGaugesTest.java index d206a385ac8a..c3c052707ac0 100644 --- a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerHistogramGaugesTest.java +++ b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerHistogramGaugesTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.micrometer.v1_5.AbstractCounterTest.INSTRUMENTATION_NAME; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; @@ -45,25 +46,16 @@ void testMicrometerHistogram() { // then testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testTimer") - .hasDescription("This is a test timer") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(555.5) - .hasCount(4) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value"))))); - testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, + histogram( + metric -> + metric.hasName("testTimer").hasDescription("This is a test timer").hasUnit("s"), + point -> + point + .hasSum(555.5) + .hasCount(4) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value"))), metric -> metric .hasName("testTimer.histogram") @@ -112,25 +104,16 @@ void testMicrometerPercentiles() { // then testing() - .waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testTimer") - .hasDescription("This is a test timer") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(0.55) - .hasCount(2) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value"))))); - testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, + histogram( + metric -> + metric.hasName("testTimer").hasDescription("This is a test timer").hasUnit("s"), + point -> + point + .hasSum(0.55) + .hasCount(2) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value"))), metric -> metric .hasName("testTimer.percentile") diff --git a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerMillisecondsTest.java b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerMillisecondsTest.java index 8a6d1357d8f3..7d4a26d5ce37 100644 --- a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerMillisecondsTest.java +++ b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerMillisecondsTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.micrometer.v1_5.AbstractCounterTest.INSTRUMENTATION_NAME; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; @@ -38,22 +39,19 @@ void testTimerWithBaseUnitMilliseconds() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testTimerMilliseconds") - .hasDescription("This is a test timer") - .hasUnit("ms") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(23_345) - .hasCount(3) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value"))))); + histogram( + metric -> + metric + .hasName("testTimerMilliseconds") + .hasDescription("This is a test timer") + .hasUnit("ms"), + point -> + point + .hasSum(23_345) + .hasCount(3) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value")))); // when Metrics.globalRegistry.remove(timer); diff --git a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerTest.java b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerTest.java index 2658fc4b1122..cd85e27471f9 100644 --- a/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerTest.java +++ b/instrumentation/micrometer/micrometer-1.5/testing/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/AbstractTimerTest.java @@ -7,6 +7,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.micrometer.v1_5.AbstractCounterTest.INSTRUMENTATION_NAME; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -45,23 +46,17 @@ void testTimer() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testTimer") - .hasDescription("This is a test timer") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(42) - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value")) - .hasBucketBoundaries(NO_BUCKETS)))); + histogram( + metric -> + metric.hasName("testTimer").hasDescription("This is a test timer").hasUnit("s"), + point -> + point + .hasSum(42) + .hasCount(1) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value")) + .hasBucketBoundaries(NO_BUCKETS))); // micrometer gauge histogram is not emitted testing() @@ -88,20 +83,11 @@ void testNanoPrecision() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testNanoTimer") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(0.001234) - .hasCount(1) - .hasAttributes(Attributes.empty())))); + histogram( + metric -> metric.hasName("testNanoTimer").hasUnit("s"), + point -> point.hasSum(0.001234).hasCount(1).hasAttributes(Attributes.empty()))); } @Test @@ -127,24 +113,21 @@ void testMicrometerTimerWithCustomBuckets() { // then testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("testTimerWithCustomBuckets") - .hasDescription("This is a test timer") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(555.5) - .hasCount(4) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("tag"), "value")) - .satisfies(hasBucketBoundaries(1, 10, 100, 1_000)) - .hasBucketCounts(1, 1, 1, 1, 0)))); + histogram( + metric -> + metric + .hasName("testTimerWithCustomBuckets") + .hasDescription("This is a test timer") + .hasUnit("s"), + point -> + point + .hasSum(555.5) + .hasCount(4) + .hasAttributesSatisfyingExactly(equalTo(stringKey("tag"), "value")) + .satisfies(hasBucketBoundaries(1, 10, 100, 1_000)) + .hasBucketCounts(1, 1, 1, 1, 0))); } private static ThrowingConsumer hasBucketBoundaries(double... buckets) { diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoConfiguredTargetTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoConfiguredTargetTest.java index 06112e14ea42..f17552853eff 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoConfiguredTargetTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoConfiguredTargetTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.mongo.v4_0; import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.semconv.DbAttributes.DB_COLLECTION_NAME; import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME; @@ -91,16 +92,10 @@ void severalSeedsAreTheOperationDurationLogicalServer() { DB_OPERATION_NAME, DB_COLLECTION_NAME, SERVER_ADDRESS); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.mongo-4.0", - metric -> - metric - .hasName("db.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttribute( - SERVER_ADDRESS, "db1.example:27017,db2.example:27018")))); + histogram( + metric -> metric.hasName("db.client.operation.duration"), + point -> point.hasAttribute(SERVER_ADDRESS, "db1.example:27017,db2.example:27018"))); } } diff --git a/instrumentation/openai/openai-java-1.1/library/src/test/java/io/opentelemetry/instrumentation/openai/v1_1/ChatTest.java b/instrumentation/openai/openai-java-1.1/library/src/test/java/io/opentelemetry/instrumentation/openai/v1_1/ChatTest.java index dd6ab772df2c..af8682febb6b 100644 --- a/instrumentation/openai/openai-java-1.1/library/src/test/java/io/opentelemetry/instrumentation/openai/v1_1/ChatTest.java +++ b/instrumentation/openai/openai-java-1.1/library/src/test/java/io/opentelemetry/instrumentation/openai/v1_1/ChatTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.openai.v1_1; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; import static io.opentelemetry.semconv.incubating.EventIncubatingAttributes.EVENT_NAME; @@ -126,49 +127,38 @@ void basicNoCaptureContent() { equalTo(GEN_AI_USAGE_OUTPUT_TOKENS, 2L)))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(22.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(2.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(22.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(2.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -229,49 +219,38 @@ void multipleChoicesNoCaptureContent() { equalTo(GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, 0L)))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(22.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(7.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(22.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(7.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -361,49 +340,38 @@ void toolCallsNoCaptureContent() { equalTo(GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, 0L)))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(67) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(46.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(67) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(46.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -486,49 +454,38 @@ void toolCallsNoCaptureContent() { equalTo(GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, 0L)))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(99) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(25.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(99) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(25.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -638,24 +595,18 @@ void streamNoCaptureContent() { val -> val.containsExactly("stop")))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, - TEST_CHAT_RESPONSE_MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -735,24 +686,18 @@ void streamMultipleChoicesNoCaptureContent() { val -> val.containsExactly("stop", "stop")))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, - TEST_CHAT_RESPONSE_MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -838,24 +783,18 @@ void streamToolCallsNoCaptureContent() { val -> val.containsExactly("tool_calls")))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, - TEST_CHAT_RESPONSE_MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -941,24 +880,18 @@ void streamToolCallsNoCaptureContent() { val -> val.containsExactly("stop")))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, - TEST_CHAT_RESPONSE_MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); diff --git a/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractChatTest.java b/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractChatTest.java index 455d8e2f712a..4ae793b131a3 100644 --- a/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractChatTest.java +++ b/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractChatTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.instrumentation.openai.v1_1; import static io.opentelemetry.instrumentation.api.internal.SemconvExceptionSignal.emitExceptionAsSpanEvents; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; import static io.opentelemetry.semconv.ErrorAttributes.ERROR_TYPE; @@ -205,49 +206,38 @@ void basic() { equalTo(GEN_AI_USAGE_OUTPUT_TOKENS, 2L))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(22.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(2.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(22.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(2.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -373,49 +363,38 @@ void allTheClientOptions() { equalTo(GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, 0L))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(22.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(3.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(22.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(3.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -478,49 +457,38 @@ void multipleChoices() { equalTo(GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, 0L))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(22.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(7.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(22.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(7.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -613,49 +581,38 @@ void toolCalls() { equalTo(GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, 0L))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(67) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(46.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(67) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(46.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -765,49 +722,38 @@ void toolCalls() { equalTo(GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, 0L))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(99) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(25.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(99) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(25.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -939,22 +885,18 @@ void connectionError() { equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(ERROR_TYPE, OpenAIIoException.class.getName()), - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(ERROR_TYPE, OpenAIIoException.class.getName()), + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1007,24 +949,18 @@ void stream() { val -> val.containsExactly("stop")))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, - TEST_CHAT_RESPONSE_MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1134,49 +1070,38 @@ void streamIncludeUsage() { equalTo(GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, 0L))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(22.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(3.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(22.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(3.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1256,24 +1181,18 @@ void streamMultipleChoices() { val -> val.containsExactly("stop", "stop")))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, - TEST_CHAT_RESPONSE_MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1411,24 +1330,18 @@ void streamToolCalls() { val -> val.containsExactly("tool_calls")))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, - TEST_CHAT_RESPONSE_MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1544,24 +1457,18 @@ void streamToolCalls() { val -> val.containsExactly("stop")))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), - equalTo( - GEN_AI_RESPONSE_MODEL, - TEST_CHAT_RESPONSE_MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, TEST_CHAT_RESPONSE_MODEL)))); SpanContext spanCtx1 = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); @@ -1694,22 +1601,18 @@ void streamConnectionError() { equalTo(GEN_AI_REQUEST_STREAM, true))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(ERROR_TYPE, OpenAIIoException.class.getName()), - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(ERROR_TYPE, OpenAIIoException.class.getName()), + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, TEST_CHAT_MODEL)))); SpanContext spanCtx = getTesting().waitForTraces(1).get(0).get(0).getSpanContext(); diff --git a/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractEmbeddingsTest.java b/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractEmbeddingsTest.java index f3d3cdab7099..28324a798b53 100644 --- a/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractEmbeddingsTest.java +++ b/instrumentation/openai/openai-java-1.1/testing/src/main/java/io/opentelemetry/instrumentation/openai/v1_1/AbstractEmbeddingsTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.instrumentation.openai.v1_1; import static io.opentelemetry.instrumentation.api.internal.SemconvExceptionSignal.emitExceptionAsSpanEvents; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; @@ -112,37 +113,29 @@ void basic() { val -> val.isIn(singletonList("base64"), null)))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(4.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(4.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)))); } @Test @@ -177,37 +170,29 @@ GEN_AI_REQUEST_ENCODING_FORMATS, singletonList("base64")), equalTo(GEN_AI_USAGE_INPUT_TOKENS, 4))))); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(4.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(4.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)))); } @Test @@ -261,21 +246,17 @@ void connectionError() { getTesting().waitAndAssertLogRecords(genAiClientExceptionLogs(thrown)); getTesting() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(ERROR_TYPE, OpenAIIoException.class.getName()), - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), - equalTo(GEN_AI_REQUEST_MODEL, MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(ERROR_TYPE, OpenAIIoException.class.getName()), + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, EMBEDDINGS), + equalTo(GEN_AI_REQUEST_MODEL, MODEL)))); } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/MeterTest.java index 6ebe4174f8e6..cc69b31e3d3c 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/MeterTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/MeterTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import io.opentelemetry.api.common.Attributes; @@ -337,26 +338,21 @@ void longHistogram() { instrument.record(5, Attributes.of(stringKey("q"), "r")); instrument.record(6, Attributes.of(stringKey("q"), "r")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(11.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("q"), "r"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point.hasSum(11.0).hasAttributesSatisfyingExactly(equalTo(stringKey("q"), "r")))); } @Test @@ -367,26 +363,21 @@ void doubleHistogram() { instrument.record(5.5, Attributes.of(stringKey("q"), "r")); instrument.record(6.6, Attributes.of(stringKey("q"), "r")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(12.1) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("q"), "r"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point.hasSum(12.1).hasAttributesSatisfyingExactly(equalTo(stringKey("q"), "r")))); } @Test diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/MeterTest.java index acd7d2d25b35..ee22784a369e 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/MeterTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/MeterTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_31.metrics; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.Collections.singletonList; @@ -225,27 +226,24 @@ void longHistogram() { instrument.record(5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); instrument.record(6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(11.0) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(11.0) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } @Test @@ -262,27 +260,24 @@ void doubleHistogram() { instrument.record(5.5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); instrument.record(6.6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(12.1) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(12.1) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } @Test diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/MeterTest.java index 7dd5db361405..a9605da6d67e 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/MeterTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/MeterTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.incubator.metrics; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.Collections.singletonList; @@ -225,27 +226,24 @@ void longHistogram() { instrument.record(5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); instrument.record(6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(11.0) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(11.0) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } @Test @@ -262,27 +260,24 @@ void doubleHistogram() { instrument.record(5.5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); instrument.record(6.6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(12.1) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(12.1) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } @Test diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/MeterTest.java index 0a1f8a2bde9c..44927bf33a08 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/MeterTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/MeterTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.metrics; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -64,27 +65,24 @@ void longHistogram() { instrument.record(5, Attributes.of(stringKey("test"), "test")); instrument.record(6, Attributes.of(stringKey("test"), "test")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(11.0) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(11.0) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } @Test @@ -98,26 +96,23 @@ void doubleHistogram() { instrument.record(5.5, Attributes.of(stringKey("test"), "test")); instrument.record(6.6, Attributes.of(stringKey("test"), "test")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(12.1) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(12.1) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/metrics/MeterTest.java index c9cf6cc2a2b3..34d0de05e22a 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/metrics/MeterTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/metrics/MeterTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_37.incubator.metrics; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.Collections.singletonList; @@ -225,27 +226,24 @@ void longHistogram() { instrument.record(5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); instrument.record(6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(11.0) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(11.0) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } @Test @@ -262,27 +260,24 @@ void doubleHistogram() { instrument.record(5.5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); instrument.record(6.6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(12.1) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(12.1) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } @Test diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/oldAndNewIncubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/oldAndNewIncubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/metrics/MeterTest.java index c9cf6cc2a2b3..34d0de05e22a 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/oldAndNewIncubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/metrics/MeterTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/oldAndNewIncubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/metrics/MeterTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_37.incubator.metrics; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.Collections.singletonList; @@ -225,27 +226,24 @@ void longHistogram() { instrument.record(5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); instrument.record(6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(11.0) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(11.0) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } @Test @@ -262,27 +260,24 @@ void doubleHistogram() { instrument.record(5.5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); instrument.record(6.6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(12.1) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(12.1) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } @Test diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/metrics/MeterTest.java index b520c8338250..72eb8509864e 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/metrics/MeterTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/metrics/MeterTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_37.metrics; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -62,27 +63,24 @@ void longHistogram() { instrument.record(5, Attributes.of(stringKey("test"), "test")); instrument.record(6, Attributes.of(stringKey("test"), "test")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(11.0) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(11.0) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } @Test @@ -96,26 +94,23 @@ void doubleHistogram() { instrument.record(5.5, Attributes.of(stringKey("test"), "test")); instrument.record(6.6, Attributes.of(stringKey("test"), "test")); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( instrumentationName, - metric -> - metric - .hasName("test") - .hasDescription("d") - .hasUnit("u") - .hasInstrumentationScope( - InstrumentationScopeInfo.builder(instrumentationName) - .setVersion("1.2.3") - .setSchemaUrl("http://schema.org") - .build()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(12.1) - .hasBucketBoundaries(10.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("test"), "test"))))); + histogram( + metric -> + metric + .hasName("test") + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build()), + point -> + point + .hasSum(12.1) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfyingExactly(equalTo(stringKey("test"), "test")))); } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.65/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_65/incubator/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.65/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_65/incubator/metrics/MeterTest.java index 5fd58a2cb2a3..67932fea6009 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.65/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_65/incubator/metrics/MeterTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.65/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_65/incubator/metrics/MeterTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_65.incubator.metrics; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; @@ -166,19 +167,12 @@ void boundLongHistogram() { ((ExtendedLongHistogram) longHistogram).bind(Attributes.of(stringKey("q"), "r")); bound.record(11); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "test-bound-long-histogram", - metric -> - metric - .hasName("test") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(11.0) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("q"), "r"))))); + histogram( + metric -> metric.hasName("test"), + point -> + point.hasSum(11.0).hasAttributesSatisfyingExactly(equalTo(stringKey("q"), "r")))); } @Test @@ -192,19 +186,12 @@ void boundDoubleHistogram() { ((ExtendedDoubleHistogram) doubleHistogram).bind(Attributes.of(stringKey("q"), "r")); bound.record(12.1); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "test-bound-double-histogram", - metric -> - metric - .hasName("test") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(12.1) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("q"), "r"))))); + histogram( + metric -> metric.hasName("test"), + point -> + point.hasSum(12.1).hasAttributesSatisfyingExactly(equalTo(stringKey("q"), "r")))); } @Test diff --git a/instrumentation/pulsar/pulsar-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/pulsar/v2_8/PulsarClientTest.java b/instrumentation/pulsar/pulsar-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/pulsar/v2_8/PulsarClientTest.java index 04a77471b741..7d66c3041e2c 100644 --- a/instrumentation/pulsar/pulsar-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/pulsar/v2_8/PulsarClientTest.java +++ b/instrumentation/pulsar/pulsar-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/pulsar/v2_8/PulsarClientTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.pulsar.v2_8; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.asRemote; import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.orderByRootSpanKind; import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.orderByRootSpanName; @@ -67,112 +68,87 @@ void testConsumeNonPartitionedTopic() throws Exception { latch.await(1, MINUTES); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - "messaging.process.duration", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasUnit("s") - .hasDescription("Duration of processing operation.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "process"), - equalTo(MESSAGING_SYSTEM, "pulsar"), - equalTo(MESSAGING_DESTINATION_NAME, topic), - equalTo( - MESSAGING_DESTINATION_SUBSCRIPTION_NAME, - "test_sub")) - .hasBucketBoundaries(DURATION_BUCKETS))))); - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, - "messaging.client.consumed.messages", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasUnit("{message}") - .hasDescription( - "Number of messages that were delivered to the application.") - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - point -> - point - .hasValue(1) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "receive"), - equalTo(MESSAGING_SYSTEM, "pulsar"), - equalTo(MESSAGING_DESTINATION_NAME, topic), - equalTo( - MESSAGING_DESTINATION_SUBSCRIPTION_NAME, - "test_sub"), - equalTo(SERVER_ADDRESS, brokerHost), - equalTo(SERVER_PORT, brokerPort)))))); - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, - "messaging.client.sent.messages", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasUnit("{message}") - .hasDescription( - "Number of messages producer attempted to send to the broker.") - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - point -> - point - .hasValue(1) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "send"), - equalTo(MESSAGING_SYSTEM, "pulsar"), - equalTo(MESSAGING_DESTINATION_NAME, topic), - equalTo(SERVER_ADDRESS, brokerHost), - equalTo(SERVER_PORT, brokerPort)))))); - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, - "messaging.client.operation.duration", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasUnit("s") - .hasDescription( - "Duration of messaging operation initiated by a producer or consumer client.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "send"), - equalTo(MESSAGING_SYSTEM, "pulsar"), - equalTo(MESSAGING_DESTINATION_NAME, topic), - equalTo(MESSAGING_OPERATION_TYPE, "send"), - equalTo(SERVER_ADDRESS, brokerHost), - equalTo(SERVER_PORT, brokerPort)), - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "receive"), - equalTo(MESSAGING_SYSTEM, "pulsar"), - equalTo(MESSAGING_DESTINATION_NAME, topic), - equalTo( - MESSAGING_DESTINATION_SUBSCRIPTION_NAME, - "test_sub"), - equalTo(MESSAGING_OPERATION_TYPE, "receive"), - equalTo(SERVER_ADDRESS, brokerHost), - equalTo(SERVER_PORT, brokerPort)))))); + histogram( + metric -> + metric + .hasName("messaging.process.duration") + .hasUnit("s") + .hasDescription("Duration of processing operation."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "process"), + equalTo(MESSAGING_SYSTEM, "pulsar"), + equalTo(MESSAGING_DESTINATION_NAME, topic), + equalTo(MESSAGING_DESTINATION_SUBSCRIPTION_NAME, "test_sub")) + .hasBucketBoundaries(DURATION_BUCKETS)), + metric -> + metric + .hasName("messaging.client.consumed.messages") + .hasUnit("{message}") + .hasDescription("Number of messages that were delivered to the application.") + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + point -> + point + .hasValue(1) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "receive"), + equalTo(MESSAGING_SYSTEM, "pulsar"), + equalTo(MESSAGING_DESTINATION_NAME, topic), + equalTo( + MESSAGING_DESTINATION_SUBSCRIPTION_NAME, "test_sub"), + equalTo(SERVER_ADDRESS, brokerHost), + equalTo(SERVER_PORT, brokerPort)))), + metric -> + metric + .hasName("messaging.client.sent.messages") + .hasUnit("{message}") + .hasDescription("Number of messages producer attempted to send to the broker.") + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + point -> + point + .hasValue(1) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "send"), + equalTo(MESSAGING_SYSTEM, "pulsar"), + equalTo(MESSAGING_DESTINATION_NAME, topic), + equalTo(SERVER_ADDRESS, brokerHost), + equalTo(SERVER_PORT, brokerPort)))), + histogram( + metric -> + metric + .hasName("messaging.client.operation.duration") + .hasUnit("s") + .hasDescription( + "Duration of messaging operation initiated by a producer or consumer client."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "send"), + equalTo(MESSAGING_SYSTEM, "pulsar"), + equalTo(MESSAGING_DESTINATION_NAME, topic), + equalTo(MESSAGING_OPERATION_TYPE, "send"), + equalTo(SERVER_ADDRESS, brokerHost), + equalTo(SERVER_PORT, brokerPort)), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "receive"), + equalTo(MESSAGING_SYSTEM, "pulsar"), + equalTo(MESSAGING_DESTINATION_NAME, topic), + equalTo(MESSAGING_DESTINATION_SUBSCRIPTION_NAME, "test_sub"), + equalTo(MESSAGING_OPERATION_TYPE, "receive"), + equalTo(SERVER_ADDRESS, brokerHost), + equalTo(SERVER_PORT, brokerPort)))); AtomicReference producerSpan = new AtomicReference<>(); testing.waitAndAssertSortedTraces( diff --git a/instrumentation/ratpack/ratpack-1.4/javaagent/src/version17Test/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_4/httpclient/client/RatpackHttpClientTest.java b/instrumentation/ratpack/ratpack-1.4/javaagent/src/version17Test/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_4/httpclient/client/RatpackHttpClientTest.java index 6c5ec8f0dd8d..16ee0c980042 100644 --- a/instrumentation/ratpack/ratpack-1.4/javaagent/src/version17Test/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_4/httpclient/client/RatpackHttpClientTest.java +++ b/instrumentation/ratpack/ratpack-1.4/javaagent/src/version17Test/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_4/httpclient/client/RatpackHttpClientTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.ratpack.v1_4.httpclient.client; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD; import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE; @@ -64,24 +65,22 @@ void durationMetricHasProtocolVersion() throws Exception { }), span -> assertServerSpan(span).hasParent(trace.getSpan(0)))); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.ratpack-1.4", - metric -> - metric - .hasName("http.client.request.duration") - .satisfies( - metricData -> - assertThat(metricData.getInstrumentationScopeInfo().getVersion()) - .isNotEmpty()) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfyingExactly( - equalTo(HTTP_REQUEST_METHOD, "GET"), - equalTo(HTTP_RESPONSE_STATUS_CODE, 200), - equalTo(NETWORK_PROTOCOL_VERSION, "1.1"), - equalTo(SERVER_ADDRESS, uri.getHost()), - equalTo(SERVER_PORT, uri.getPort()))))); + histogram( + metric -> + metric + .hasName("http.client.request.duration") + .satisfies( + metricData -> + assertThat(metricData.getInstrumentationScopeInfo().getVersion()) + .isNotEmpty()), + point -> + point.hasAttributesSatisfyingExactly( + equalTo(HTTP_REQUEST_METHOD, "GET"), + equalTo(HTTP_RESPONSE_STATUS_CODE, 200), + equalTo(NETWORK_PROTOCOL_VERSION, "1.1"), + equalTo(SERVER_ADDRESS, uri.getHost()), + equalTo(SERVER_PORT, uri.getPort())))); } } diff --git a/instrumentation/rocketmq/rocketmq-client-4.8/library/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v4_8/RocketMqMetricsTest.java b/instrumentation/rocketmq/rocketmq-client-4.8/library/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v4_8/RocketMqMetricsTest.java index 2fa7072d59d0..263bdd835f6e 100644 --- a/instrumentation/rocketmq/rocketmq-client-4.8/library/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v4_8/RocketMqMetricsTest.java +++ b/instrumentation/rocketmq/rocketmq-client-4.8/library/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v4_8/RocketMqMetricsTest.java @@ -5,7 +5,7 @@ package io.opentelemetry.instrumentation.rocketmqclient.v4_8; -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.ErrorAttributes.ERROR_TYPE; import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_CONSUMER_GROUP_NAME; @@ -26,8 +26,9 @@ import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; -import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.testing.assertj.MetricAssert; import java.util.List; +import java.util.function.Consumer; import java.util.stream.Stream; import org.apache.rocketmq.client.consumer.listener.ConsumeReturnType; import org.apache.rocketmq.client.hook.ConsumeMessageContext; @@ -63,21 +64,22 @@ void recordsProducerMetrics( Context context = instrumenter.start(Context.root(), request); instrumenter.end(context, request, null, error); - assertMessageCount( - "messaging.client.sent.messages", - expectedCount, - "send", - message.getTopic(), - null, - errorType); - assertDuration( - "messaging.client.operation.duration", "send", message.getTopic(), null, "send", errorType); - assertThat(testing.metrics()) - .filteredOn( - metric -> metric.getInstrumentationScopeInfo().getName().equals(INSTRUMENTATION_NAME)) - .extracting(MetricData::getName) - .containsExactlyInAnyOrder( - "messaging.client.sent.messages", "messaging.client.operation.duration"); + testing.waitAndAssertMetricsExactly( + INSTRUMENTATION_NAME, + assertMessageCount( + "messaging.client.sent.messages", + expectedCount, + "send", + message.getTopic(), + null, + errorType), + assertDuration( + "messaging.client.operation.duration", + "send", + message.getTopic(), + null, + "send", + errorType)); } private static Stream producerCases() { @@ -123,26 +125,22 @@ void recordsProcessMetrics( instrumenter.end(consumerContext, response); String destination = messages.get(0).getTopic(); - assertMessageCount( - "messaging.client.consumed.messages", - expectedCount, - "process", - destination, - "consumer-group", - consumeErrorType); - assertDuration( - "messaging.process.duration", - "process", - destination, - "consumer-group", - null, - consumeErrorType); - assertThat(testing.metrics()) - .filteredOn( - metric -> metric.getInstrumentationScopeInfo().getName().equals(INSTRUMENTATION_NAME)) - .extracting(MetricData::getName) - .containsExactlyInAnyOrder( - "messaging.client.consumed.messages", "messaging.process.duration"); + testing.waitAndAssertMetricsExactly( + INSTRUMENTATION_NAME, + assertMessageCount( + "messaging.client.consumed.messages", + expectedCount, + "process", + destination, + "consumer-group", + consumeErrorType), + assertDuration( + "messaging.process.duration", + "process", + destination, + "consumer-group", + null, + consumeErrorType)); } private static Stream consumerCases() { @@ -178,64 +176,48 @@ private static MessageExt messageExt(String topic) { return message; } - private static void assertMessageCount( + private static Consumer assertMessageCount( String metricName, long expectedCount, String operationName, String destination, String consumerGroup, String errorType) { - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metricName, - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - point -> - point - .hasValue(expectedCount) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, operationName), - equalTo(MESSAGING_SYSTEM, "rocketmq"), - equalTo(ERROR_TYPE, errorType), - equalTo( - MESSAGING_CONSUMER_GROUP_NAME, consumerGroup), - equalTo( - MESSAGING_DESTINATION_NAME, destination)))))); + return metric -> + metric + .hasName(metricName) + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + point -> + point + .hasValue(expectedCount) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, operationName), + equalTo(MESSAGING_SYSTEM, "rocketmq"), + equalTo(ERROR_TYPE, errorType), + equalTo(MESSAGING_CONSUMER_GROUP_NAME, consumerGroup), + equalTo(MESSAGING_DESTINATION_NAME, destination)))); } - private static void assertDuration( + private static Consumer assertDuration( String metricName, String operationName, String destination, String consumerGroup, String operationType, String errorType) { - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metricName, - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, operationName), - equalTo(MESSAGING_SYSTEM, "rocketmq"), - equalTo(ERROR_TYPE, errorType), - equalTo( - MESSAGING_CONSUMER_GROUP_NAME, consumerGroup), - equalTo(MESSAGING_DESTINATION_NAME, destination), - equalTo( - MESSAGING_OPERATION_TYPE, operationType)))))); + return histogram( + metric -> metric.hasName(metricName), + point -> + point + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, operationName), + equalTo(MESSAGING_SYSTEM, "rocketmq"), + equalTo(ERROR_TYPE, errorType), + equalTo(MESSAGING_CONSUMER_GROUP_NAME, consumerGroup), + equalTo(MESSAGING_DESTINATION_NAME, destination), + equalTo(MESSAGING_OPERATION_TYPE, operationType))); } } diff --git a/instrumentation/rocketmq/rocketmq-client-5.0/javaagent/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v5_0/AbstractRocketMqClientSuppressReceiveSpanTest.java b/instrumentation/rocketmq/rocketmq-client-5.0/javaagent/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v5_0/AbstractRocketMqClientSuppressReceiveSpanTest.java index 85500429b6a1..59a9be634906 100644 --- a/instrumentation/rocketmq/rocketmq-client-5.0/javaagent/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v5_0/AbstractRocketMqClientSuppressReceiveSpanTest.java +++ b/instrumentation/rocketmq/rocketmq-client-5.0/javaagent/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v5_0/AbstractRocketMqClientSuppressReceiveSpanTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.rocketmqclient.v5_0; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.asRemote; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; @@ -150,100 +151,56 @@ void testSendAndConsumeMessage() throws ClientException { private void assertMetrics(String topic, String consumerGroup) { testing() - .waitAndAssertMetrics( + .waitAndAssertMetricsExactly( "io.opentelemetry.rocketmq-client-5.0", - "messaging.client.sent.messages", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .satisfies( - data -> assertThat(data.getLongSumData().getPoints()).hasSize(1)) - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - point -> - point - .hasValue(1) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "send"), - equalTo(MESSAGING_SYSTEM, "rocketmq"), - equalTo(MESSAGING_DESTINATION_NAME, topic)))))); - testing() - .waitAndAssertMetrics( - "io.opentelemetry.rocketmq-client-5.0", - "messaging.client.operation.duration", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "send"), - equalTo(MESSAGING_SYSTEM, "rocketmq"), - equalTo(MESSAGING_DESTINATION_NAME, topic), - equalTo(MESSAGING_OPERATION_TYPE, "send")))))); - testing() - .waitAndAssertMetrics( - "io.opentelemetry.rocketmq-client-5.0", - "messaging.process.duration", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "process"), - equalTo(MESSAGING_SYSTEM, "rocketmq"), - equalTo( - MESSAGING_CONSUMER_GROUP_NAME, - consumerGroup), - equalTo(MESSAGING_DESTINATION_NAME, topic)))))); - testing() - .waitAndAssertMetrics( - "io.opentelemetry.rocketmq-client-5.0", - "messaging.client.consumed.messages", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .satisfies( - data -> assertThat(data.getLongSumData().getPoints()).hasSize(1)) - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - point -> - point - .hasValue(1) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "process"), - equalTo(MESSAGING_SYSTEM, "rocketmq"), - equalTo( - MESSAGING_CONSUMER_GROUP_NAME, - consumerGroup), - equalTo(MESSAGING_DESTINATION_NAME, topic)))))); - assertThat(testing().metrics()) - .filteredOn( metric -> metric - .getInstrumentationScopeInfo() - .getName() - .equals("io.opentelemetry.rocketmq-client-5.0")) - .extracting(metric -> metric.getName()) - .containsExactlyInAnyOrder( - "messaging.client.sent.messages", - "messaging.client.operation.duration", - "messaging.process.duration", - "messaging.client.consumed.messages"); + .hasName("messaging.client.sent.messages") + .satisfies(data -> assertThat(data.getLongSumData().getPoints()).hasSize(1)) + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + point -> + point + .hasValue(1) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "send"), + equalTo(MESSAGING_SYSTEM, "rocketmq"), + equalTo(MESSAGING_DESTINATION_NAME, topic)))), + histogram( + metric -> metric.hasName("messaging.client.operation.duration"), + point -> + point + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "send"), + equalTo(MESSAGING_SYSTEM, "rocketmq"), + equalTo(MESSAGING_DESTINATION_NAME, topic), + equalTo(MESSAGING_OPERATION_TYPE, "send"))), + histogram( + metric -> metric.hasName("messaging.process.duration"), + point -> + point + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "process"), + equalTo(MESSAGING_SYSTEM, "rocketmq"), + equalTo(MESSAGING_CONSUMER_GROUP_NAME, consumerGroup), + equalTo(MESSAGING_DESTINATION_NAME, topic))), + metric -> + metric + .hasName("messaging.client.consumed.messages") + .satisfies(data -> assertThat(data.getLongSumData().getPoints()).hasSize(1)) + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + point -> + point + .hasValue(1) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "process"), + equalTo(MESSAGING_SYSTEM, "rocketmq"), + equalTo(MESSAGING_CONSUMER_GROUP_NAME, consumerGroup), + equalTo(MESSAGING_DESTINATION_NAME, topic))))); } } diff --git a/instrumentation/rocketmq/rocketmq-client-5.0/javaagent/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v5_0/RocketMqSimpleConsumerTest.java b/instrumentation/rocketmq/rocketmq-client-5.0/javaagent/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v5_0/RocketMqSimpleConsumerTest.java index b045a731e726..f418c3729f9e 100644 --- a/instrumentation/rocketmq/rocketmq-client-5.0/javaagent/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v5_0/RocketMqSimpleConsumerTest.java +++ b/instrumentation/rocketmq/rocketmq-client-5.0/javaagent/src/test/java/io/opentelemetry/instrumentation/rocketmqclient/v5_0/RocketMqSimpleConsumerTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.rocketmqclient.v5_0; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.asRemote; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; @@ -194,45 +195,33 @@ void shouldInstrumentReceiveWhenReceiveTelemetryDisabled() throws ClientExceptio }); assertSuccessfulReceiveTrace("disabled receive parent", sendSpan); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - "messaging.client.operation.duration", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasCount(1) - .hasAttributesSatisfyingExactly( - equalTo( - MESSAGING_CONSUMER_GROUP_NAME, CONSUMER_GROUP), - equalTo(MESSAGING_SYSTEM, "rocketmq"), - equalTo(MESSAGING_DESTINATION_NAME, TOPIC), - equalTo(MESSAGING_OPERATION_NAME, "receive"), - equalTo(MESSAGING_OPERATION_TYPE, "receive")))))); - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, - "messaging.client.consumed.messages", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - point -> - point - .hasValue(1) - .hasAttributesSatisfyingExactly( - equalTo( - MESSAGING_CONSUMER_GROUP_NAME, CONSUMER_GROUP), - equalTo(MESSAGING_SYSTEM, "rocketmq"), - equalTo(MESSAGING_DESTINATION_NAME, TOPIC), - equalTo(MESSAGING_OPERATION_NAME, "receive")))))); + histogram( + metric -> metric.hasName("messaging.client.operation.duration"), + point -> + point + .hasCount(1) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_CONSUMER_GROUP_NAME, CONSUMER_GROUP), + equalTo(MESSAGING_SYSTEM, "rocketmq"), + equalTo(MESSAGING_DESTINATION_NAME, TOPIC), + equalTo(MESSAGING_OPERATION_NAME, "receive"), + equalTo(MESSAGING_OPERATION_TYPE, "receive"))), + metric -> + metric + .hasName("messaging.client.consumed.messages") + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + point -> + point + .hasValue(1) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_CONSUMER_GROUP_NAME, CONSUMER_GROUP), + equalTo(MESSAGING_SYSTEM, "rocketmq"), + equalTo(MESSAGING_DESTINATION_NAME, TOPIC), + equalTo(MESSAGING_OPERATION_NAME, "receive"))))); } @Test diff --git a/instrumentation/runtime-telemetry/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JmxRuntimeMetricsTest.java b/instrumentation/runtime-telemetry/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JmxRuntimeMetricsTest.java index 235b3026a798..4b04a37a69eb 100644 --- a/instrumentation/runtime-telemetry/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JmxRuntimeMetricsTest.java +++ b/instrumentation/runtime-telemetry/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/runtimetelemetry/JmxRuntimeMetricsTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.runtimetelemetry; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; import static io.opentelemetry.semconv.JvmAttributes.JVM_GC_ACTION; import static io.opentelemetry.semconv.JvmAttributes.JVM_GC_NAME; @@ -25,7 +26,7 @@ void runtimeMetricsAreEnabled() { // Force a gc to "ensure" gc metrics System.gc(); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.runtime-telemetry", metric -> metric.hasName("jvm.class.loaded"), metric -> metric.hasName("jvm.class.unloaded"), @@ -33,17 +34,13 @@ void runtimeMetricsAreEnabled() { metric -> metric.hasName("jvm.cpu.time"), metric -> metric.hasName("jvm.cpu.count"), metric -> metric.hasName("jvm.cpu.recent_utilization"), - metric -> - metric - .hasName("jvm.gc.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfyingExactly( - satisfies(JVM_GC_NAME, val -> val.isNotBlank()), - satisfies(JVM_GC_ACTION, val -> val.isNotBlank()), - satisfies(JVM_GC_CAUSE, val -> val.isNotBlank())))), + histogram( + metric -> metric.hasName("jvm.gc.duration"), + point -> + point.hasAttributesSatisfyingExactly( + satisfies(JVM_GC_NAME, val -> val.isNotBlank()), + satisfies(JVM_GC_ACTION, val -> val.isNotBlank()), + satisfies(JVM_GC_CAUSE, val -> val.isNotBlank()))), metric -> metric.hasName("jvm.memory.used"), metric -> metric.hasName("jvm.memory.committed"), metric -> metric.hasName("jvm.memory.limit"), diff --git a/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/GarbageCollectorTest.java b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/GarbageCollectorTest.java index 40b482b43aba..766ac67fe41a 100644 --- a/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/GarbageCollectorTest.java +++ b/instrumentation/runtime-telemetry/library/src/test/java/io/opentelemetry/instrumentation/runtimetelemetry/internal/GarbageCollectorTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.runtimetelemetry.internal; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.JvmAttributes.JVM_GC_ACTION; import static io.opentelemetry.semconv.JvmAttributes.JVM_GC_NAME; @@ -69,34 +70,32 @@ void registerObservers() { listener.handleNotification( createTestNotification("G1 Old Generation", "end of major GC", "System.gc()", 11), null); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "test", - metric -> - metric - .hasName("jvm.gc.duration") - .hasDescription("Duration of JVM garbage collection actions.") - .hasUnit("s") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasCount(2) - .hasSum(0.022) - .hasAttributesSatisfyingExactly( - equalTo(JVM_GC_NAME, "G1 Young Generation"), - equalTo(JVM_GC_ACTION, "end of minor GC"), - equalTo(JVM_GC_CAUSE, "Allocation Failure")) - .hasBucketBoundaries(GC_DURATION_BUCKETS), - point -> - point - .hasCount(1) - .hasSum(0.011) - .hasAttributesSatisfyingExactly( - equalTo(JVM_GC_NAME, "G1 Old Generation"), - equalTo(JVM_GC_ACTION, "end of major GC"), - equalTo(JVM_GC_CAUSE, "System.gc()")) - .hasBucketBoundaries(GC_DURATION_BUCKETS)))); + histogram( + metric -> + metric + .hasName("jvm.gc.duration") + .hasDescription("Duration of JVM garbage collection actions.") + .hasUnit("s"), + point -> + point + .hasCount(2) + .hasSum(0.022) + .hasAttributesSatisfyingExactly( + equalTo(JVM_GC_NAME, "G1 Young Generation"), + equalTo(JVM_GC_ACTION, "end of minor GC"), + equalTo(JVM_GC_CAUSE, "Allocation Failure")) + .hasBucketBoundaries(GC_DURATION_BUCKETS), + point -> + point + .hasCount(1) + .hasSum(0.011) + .hasAttributesSatisfyingExactly( + equalTo(JVM_GC_NAME, "G1 Old Generation"), + equalTo(JVM_GC_ACTION, "end of major GC"), + equalTo(JVM_GC_CAUSE, "System.gc()")) + .hasBucketBoundaries(GC_DURATION_BUCKETS))); } private static Notification createTestNotification( diff --git a/instrumentation/spring/spring-ai-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/ai/v1_0/AbstractOpenAiChatModelTest.java b/instrumentation/spring/spring-ai-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/ai/v1_0/AbstractOpenAiChatModelTest.java index b389fbf190f5..878d5581afe6 100644 --- a/instrumentation/spring/spring-ai-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/ai/v1_0/AbstractOpenAiChatModelTest.java +++ b/instrumentation/spring/spring-ai-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/ai/v1_0/AbstractOpenAiChatModelTest.java @@ -11,6 +11,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.api.trace.SpanKind.CLIENT; import static io.opentelemetry.api.trace.SpanKind.INTERNAL; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GEN_AI_OPERATION_NAME; import static io.opentelemetry.semconv.incubating.GenAiIncubatingAttributes.GEN_AI_PROVIDER_NAME; @@ -104,46 +105,38 @@ void callRecordsOpenAiSpringAiResponse() { } private static void assertMetrics() { - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, RESPONSE_MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(22.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(2.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, OPENAI), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, RESPONSE_MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, RESPONSE_MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(22.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(2.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, OPENAI), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, RESPONSE_MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); } private static void assertMessageEvents(SpanContext spanContext) { diff --git a/instrumentation/spring/spring-ai-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/ai/v1_0/ChatModelTest.java b/instrumentation/spring/spring-ai-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/ai/v1_0/ChatModelTest.java index b1257ac1fb9f..a69e124f88c4 100644 --- a/instrumentation/spring/spring-ai-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/ai/v1_0/ChatModelTest.java +++ b/instrumentation/spring/spring-ai-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/ai/v1_0/ChatModelTest.java @@ -8,6 +8,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.api.trace.SpanKind.CLIENT; import static io.opentelemetry.api.trace.SpanKind.INTERNAL; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.ErrorAttributes.ERROR_TYPE; @@ -855,65 +856,53 @@ private static void assertErrorTrace(IllegalStateException error, boolean stream } private static void assertMetrics() { - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, "test"), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, MODEL)))), - metric -> - metric - .hasName("gen_ai.client.token.usage") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSum(3.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, "test"), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, MODEL), - equalTo(GEN_AI_TOKEN_TYPE, INPUT)), - point -> - point - .hasSum(2.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, "test"), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, MODEL), - equalTo(GEN_AI_TOKEN_TYPE, OUTPUT))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, "test"), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL))), + histogram( + metric -> metric.hasName("gen_ai.client.token.usage"), + point -> + point + .hasSum(3.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, "test"), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL), + equalTo(GEN_AI_TOKEN_TYPE, INPUT)), + point -> + point + .hasSum(2.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, "test"), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL), + equalTo(GEN_AI_TOKEN_TYPE, OUTPUT)))); } private static void assertMetricsWithoutTokenUsage() { - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( INSTRUMENTATION_NAME, - metric -> - metric - .hasName("gen_ai.client.operation.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(GEN_AI_PROVIDER_NAME, "test"), - equalTo(GEN_AI_OPERATION_NAME, CHAT), - equalTo(GEN_AI_REQUEST_MODEL, MODEL), - equalTo(GEN_AI_RESPONSE_MODEL, MODEL))))); + histogram( + metric -> metric.hasName("gen_ai.client.operation.duration"), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(GEN_AI_PROVIDER_NAME, "test"), + equalTo(GEN_AI_OPERATION_NAME, CHAT), + equalTo(GEN_AI_REQUEST_MODEL, MODEL), + equalTo(GEN_AI_RESPONSE_MODEL, MODEL)))); testing.waitAndAssertMetrics( INSTRUMENTATION_NAME, "gen_ai.client.token.usage", metrics -> metrics.isEmpty()); } diff --git a/instrumentation/spring/spring-pulsar-1.0/testing/src/main/java/io/opentelemetry/instrumentation/spring/pulsar/v1_0/AbstractSpringPulsarTest.java b/instrumentation/spring/spring-pulsar-1.0/testing/src/main/java/io/opentelemetry/instrumentation/spring/pulsar/v1_0/AbstractSpringPulsarTest.java index 798befb4b1cf..4b30965b9239 100644 --- a/instrumentation/spring/spring-pulsar-1.0/testing/src/main/java/io/opentelemetry/instrumentation/spring/pulsar/v1_0/AbstractSpringPulsarTest.java +++ b/instrumentation/spring/spring-pulsar-1.0/testing/src/main/java/io/opentelemetry/instrumentation/spring/pulsar/v1_0/AbstractSpringPulsarTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.instrumentation.spring.pulsar.v1_0; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; @@ -112,27 +113,6 @@ void testSpringPulsar() throws PulsarClientException, InterruptedException { protected void assertProcessMetrics() { - testing.waitAndAssertMetrics( - "io.opentelemetry.spring-pulsar-1.0", - "messaging.process.duration", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasUnit("s") - .hasDescription("Duration of processing operation.") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point - .hasSumGreaterThan(0.0) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "process"), - equalTo(MESSAGING_SYSTEM, "pulsar"), - equalTo( - MESSAGING_DESTINATION_NAME, OTEL_TOPIC)))))); - testing.waitAndAssertMetrics( "io.opentelemetry.pulsar-2.8", "messaging.client.consumed.messages", @@ -158,24 +138,34 @@ protected void assertProcessMetrics() { OTEL_SUBSCRIPTION), equalTo(SERVER_ADDRESS, brokerHost), equalTo(SERVER_PORT, brokerPort)))))); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.spring-pulsar-1.0", - "messaging.client.consumed.messages", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasLongSumSatisfying( - sum -> - sum.hasPointsSatisfying( - point -> - point - .hasValue(1) - .hasAttributesSatisfyingExactly( - equalTo(MESSAGING_OPERATION_NAME, "process"), - equalTo(MESSAGING_SYSTEM, "pulsar"), - equalTo( - MESSAGING_DESTINATION_NAME, OTEL_TOPIC)))))); + histogram( + metric -> + metric + .hasName("messaging.process.duration") + .hasUnit("s") + .hasDescription("Duration of processing operation."), + point -> + point + .hasSumGreaterThan(0.0) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "process"), + equalTo(MESSAGING_SYSTEM, "pulsar"), + equalTo(MESSAGING_DESTINATION_NAME, OTEL_TOPIC))), + metric -> + metric + .hasName("messaging.client.consumed.messages") + .hasLongSumSatisfying( + sum -> + sum.hasPointsSatisfying( + point -> + point + .hasValue(1) + .hasAttributesSatisfyingExactly( + equalTo(MESSAGING_OPERATION_NAME, "process"), + equalTo(MESSAGING_SYSTEM, "pulsar"), + equalTo(MESSAGING_DESTINATION_NAME, OTEL_TOPIC))))); } protected List publishAttributes() { diff --git a/instrumentation/spring/spring-rabbit-1.0/javaagent/src/version11Test/java/io/opentelemetry/javaagent/instrumentation/spring/rabbit/v1_0/SpringRabbit11SimpleMessageListenerContainerTest.java b/instrumentation/spring/spring-rabbit-1.0/javaagent/src/version11Test/java/io/opentelemetry/javaagent/instrumentation/spring/rabbit/v1_0/SpringRabbit11SimpleMessageListenerContainerTest.java index 8bef994eb938..076b4dbd5195 100644 --- a/instrumentation/spring/spring-rabbit-1.0/javaagent/src/version11Test/java/io/opentelemetry/javaagent/instrumentation/spring/rabbit/v1_0/SpringRabbit11SimpleMessageListenerContainerTest.java +++ b/instrumentation/spring/spring-rabbit-1.0/javaagent/src/version11Test/java/io/opentelemetry/javaagent/instrumentation/spring/rabbit/v1_0/SpringRabbit11SimpleMessageListenerContainerTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.spring.rabbit.v1_0; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static java.util.concurrent.TimeUnit.SECONDS; import static org.assertj.core.api.Assertions.assertThat; @@ -106,25 +107,14 @@ void shouldUseSpringProcessTelemetry() throws InterruptedException { span -> span.hasName("consumer").hasParent(processSpan)); }); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( SPRING_INSTRUMENTATION_NAME, - "messaging.process.duration", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying(point -> point.hasCount(1))))); - testing.waitAndAssertMetrics( - SPRING_INSTRUMENTATION_NAME, - "messaging.client.consumed.messages", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasLongSumSatisfying( - sum -> sum.hasPointsSatisfying(point -> point.hasValue(1))))); + histogram( + metric -> metric.hasName("messaging.process.duration"), point -> point.hasCount(1)), + metric -> + metric + .hasName("messaging.client.consumed.messages") + .hasLongSumSatisfying(sum -> sum.hasPointsSatisfying(point -> point.hasValue(1)))); assertThat(testing.metrics()) .filteredOn( metric -> diff --git a/instrumentation/spring/spring-rabbit-1.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/spring/rabbit/v1_0/SpringRabbit20DirectMessageListenerContainerTest.java b/instrumentation/spring/spring-rabbit-1.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/spring/rabbit/v1_0/SpringRabbit20DirectMessageListenerContainerTest.java index 7a2b6ab1c648..24de3e6adc8d 100644 --- a/instrumentation/spring/spring-rabbit-1.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/spring/rabbit/v1_0/SpringRabbit20DirectMessageListenerContainerTest.java +++ b/instrumentation/spring/spring-rabbit-1.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/spring/rabbit/v1_0/SpringRabbit20DirectMessageListenerContainerTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.spring.rabbit.v1_0; import static io.opentelemetry.instrumentation.testing.util.InstrumentationScopeAssertions.hasScopeName; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static java.util.concurrent.TimeUnit.SECONDS; import static org.assertj.core.api.Assertions.assertThat; @@ -101,25 +102,14 @@ void shouldUseSpringProcessTelemetry() throws InterruptedException { span -> span.hasName("consumer").hasParent(processSpan)); }); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( SPRING_INSTRUMENTATION_NAME, - "messaging.process.duration", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying(point -> point.hasCount(1))))); - testing.waitAndAssertMetrics( - SPRING_INSTRUMENTATION_NAME, - "messaging.client.consumed.messages", - metrics -> - metrics.satisfiesExactly( - metric -> - assertThat(metric) - .hasLongSumSatisfying( - sum -> sum.hasPointsSatisfying(point -> point.hasValue(1))))); + histogram( + metric -> metric.hasName("messaging.process.duration"), point -> point.hasCount(1)), + metric -> + metric + .hasName("messaging.client.consumed.messages") + .hasLongSumSatisfying(sum -> sum.hasPointsSatisfying(point -> point.hasValue(1)))); assertThat(testing.metrics()) .filteredOn( metric -> diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/client/SpringWebfluxClientInstrumentationTest.java b/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/client/SpringWebfluxClientInstrumentationTest.java index 70045d60f343..2efbf979f209 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/client/SpringWebfluxClientInstrumentationTest.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/client/SpringWebfluxClientInstrumentationTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.spring.webflux.v5_0.client; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD; import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE; @@ -66,20 +67,16 @@ void shouldAddProtocolVersionToDurationMetric() { assertThat(responseCode).isEqualTo(200); - testing.waitAndAssertMetrics( + testing.waitAndAssertMetricsExactly( "io.opentelemetry.spring-webflux-5.0", - metric -> - metric - .hasName("http.client.request.duration") - .hasHistogramSatisfying( - histogram -> - histogram.hasPointsSatisfying( - point -> - point.hasAttributesSatisfyingExactly( - equalTo(HTTP_REQUEST_METHOD, "GET"), - equalTo(HTTP_RESPONSE_STATUS_CODE, 200), - equalTo(NETWORK_PROTOCOL_VERSION, "1.1"), - equalTo(SERVER_ADDRESS, uri.getHost()), - equalTo(SERVER_PORT, uri.getPort()))))); + histogram( + metric -> metric.hasName("http.client.request.duration"), + point -> + point.hasAttributesSatisfyingExactly( + equalTo(HTTP_REQUEST_METHOD, "GET"), + equalTo(HTTP_RESPONSE_STATUS_CODE, 200), + equalTo(NETWORK_PROTOCOL_VERSION, "1.1"), + equalTo(SERVER_ADDRESS, uri.getHost()), + equalTo(SERVER_PORT, uri.getPort())))); } } diff --git a/testing-common/integration-tests/src/test/java/instrumentation/MetricAssertionsTest.java b/testing-common/integration-tests/src/test/java/instrumentation/MetricAssertionsTest.java new file mode 100644 index 000000000000..675fa656b6e6 --- /dev/null +++ b/testing-common/integration-tests/src/test/java/instrumentation/MetricAssertionsTest.java @@ -0,0 +1,58 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package instrumentation; + +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +class MetricAssertionsTest { + + @RegisterExtension + static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + @Test + void repeatedObservableGaugeExportsHaveOneMetricIdentity() { + testing + .getOpenTelemetry() + .getMeter("test-exhaustive-metric-pre-read") + .gaugeBuilder("repeated.gauge") + .ofLongs() + .buildWithCallback(measurement -> measurement.record(1)); + + testing.metrics(); + + testing.waitAndAssertMetricsExactly( + "test-exhaustive-metric-pre-read", + metric -> + metric + .hasName("repeated.gauge") + .hasLongGaugeSatisfying( + gauge -> gauge.hasPointsSatisfying(point -> point.hasValue(1)))); + } + + @Test + void retriesAssertionsAcrossRepeatedObservableGaugeExports() { + AtomicBoolean emitExpectedValue = new AtomicBoolean(); + testing + .getOpenTelemetry() + .getMeter("test-exhaustive-metric") + .gaugeBuilder("retry.gauge") + .ofLongs() + .buildWithCallback(measurement -> measurement.record(emitExpectedValue.get() ? 1 : 0)); + + testing.waitAndAssertMetricsExactly( + "test-exhaustive-metric", + metric -> { + metric.hasName("retry.gauge"); + emitExpectedValue.set(true); + metric.hasLongGaugeSatisfying( + gauge -> gauge.hasPointsSatisfying(point -> point.hasValue(1))); + }); + } +} diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunner.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunner.java index e6c286ae7881..6268eece2ec1 100644 --- a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunner.java +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunner.java @@ -25,6 +25,8 @@ import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; +import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert; import io.opentelemetry.sdk.testing.assertj.MetricAssert; import io.opentelemetry.sdk.testing.assertj.TraceAssert; @@ -40,6 +42,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; @@ -244,6 +247,92 @@ public final void waitAndAssertMetrics( } } + /** + * Waits for the supplied assertions to match all distinct metric identities from the given + * instrumentation exactly once, in any order. A metric identity consists of its resource, full + * instrumentation scope, name, description, unit, and data type. Each assertion may match any + * historical snapshot for its identity, including snapshots from different collections; it need + * not match the latest value, and measurements are not aggregated across snapshots. + */ + @SafeVarargs + @SuppressWarnings("varargs") + public final void waitAndAssertMetricsExactly( + String instrumentationName, Consumer... assertions) { + awaitUntilAsserted( + () -> { + List> metricGroups = + groupMetricSnapshots(instrumentationMetrics(instrumentationName)); + assertThat(metricGroups).satisfiesExactlyInAnyOrder(toMetricGroupAssertions(assertions)); + }); + + TelemetryDataUtil.assertMetricScopeVersion(metricsForScope(instrumentationName)); + + if (Boolean.getBoolean("collectMetadata")) { + collectEmittedMetrics(getExportedMetrics()); + } + } + + private static List> groupMetricSnapshots(List metrics) { + Map> metricGroups = new HashMap<>(); + for (MetricData metric : metrics) { + metricGroups + .computeIfAbsent(new MetricIdentity(metric), ignored -> new ArrayList<>()) + .add(metric); + } + return new ArrayList<>(metricGroups.values()); + } + + // The runtime array type is Consumer and every element is a Consumer>. + @SuppressWarnings("unchecked") + private static Consumer>[] toMetricGroupAssertions( + Consumer[] assertions) { + Consumer>[] metricAssertions = + (Consumer>[]) new Consumer[assertions.length]; + for (int i = 0; i < assertions.length; i++) { + Consumer assertion = assertions[i]; + metricAssertions[i] = + metrics -> assertThat(metrics).anySatisfy(metric -> assertion.accept(assertThat(metric))); + } + return metricAssertions; + } + + private static final class MetricIdentity { + private final Resource resource; + private final InstrumentationScopeInfo instrumentationScope; + private final String name; + private final String description; + private final String unit; + private final MetricDataType type; + + private MetricIdentity(MetricData metric) { + resource = metric.getResource(); + instrumentationScope = metric.getInstrumentationScopeInfo(); + name = metric.getName(); + description = metric.getDescription(); + unit = metric.getUnit(); + type = metric.getType(); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof MetricIdentity)) { + return false; + } + MetricIdentity that = (MetricIdentity) other; + return resource.equals(that.resource) + && instrumentationScope.equals(that.instrumentationScope) + && name.equals(that.name) + && description.equals(that.description) + && unit.equals(that.unit) + && type == that.type; + } + + @Override + public int hashCode() { + return Objects.hash(resource, instrumentationScope, name, description, unit, type); + } + } + private List metricsForScope(String instrumentationName) { return getExportedMetrics().stream() .filter(m -> m.getInstrumentationScopeInfo().getName().equals(instrumentationName)) diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/InstrumentationExtension.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/InstrumentationExtension.java index eaade23e08a7..ec7fdc1804cc 100644 --- a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/InstrumentationExtension.java +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/InstrumentationExtension.java @@ -115,6 +115,20 @@ public final void waitAndAssertMetrics( testRunner.waitAndAssertMetrics(instrumentationName, assertions); } + /** + * Waits for the supplied assertions to match all distinct metric identities from the given + * instrumentation exactly once, in any order. A metric identity consists of its resource, full + * instrumentation scope, name, description, unit, and data type. Each assertion may match any + * historical snapshot for its identity, including snapshots from different collections; it need + * not match the latest value, and measurements are not aggregated across snapshots. + */ + @SafeVarargs + @SuppressWarnings("varargs") + public final void waitAndAssertMetricsExactly( + String instrumentationName, Consumer... assertions) { + testRunner.waitAndAssertMetricsExactly(instrumentationName, assertions); + } + /** * Removes all captured telemetry data. After calling this method {@link #spans()} and {@link * #metrics()} will return empty lists until more telemetry data is captured. diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/util/MetricAssertions.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/util/MetricAssertions.java new file mode 100644 index 000000000000..39805105314f --- /dev/null +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/util/MetricAssertions.java @@ -0,0 +1,38 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.testing.util; + +import io.opentelemetry.sdk.testing.assertj.HistogramPointAssert; +import io.opentelemetry.sdk.testing.assertj.MetricAssert; +import java.util.function.Consumer; + +/** Composable assertions on metrics. */ +public final class MetricAssertions { + + /** + * Returns an assertion that validates metric metadata and exactly matches the histogram points, + * in any order. + * + *
{@code
+   * testing.waitAndAssertMetricsExactly(
+   *     "test",
+   *     histogram(
+   *         metric -> metric.hasName("duration").hasUnit("s"),
+   *         point -> point.hasCount(1)));
+   * }
+ */ + @SafeVarargs + @SuppressWarnings("varargs") + public static Consumer histogram( + Consumer metricAssertion, Consumer... pointAssertions) { + return metric -> { + metricAssertion.accept(metric); + metric.hasHistogramSatisfying(histogram -> histogram.hasPointsSatisfying(pointAssertions)); + }; + } + + private MetricAssertions() {} +} diff --git a/testing-common/src/test/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunnerTest.java b/testing-common/src/test/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunnerTest.java new file mode 100644 index 000000000000..029f0b9ff165 --- /dev/null +++ b/testing-common/src/test/java/io/opentelemetry/instrumentation/testing/InstrumentationTestRunnerTest.java @@ -0,0 +1,241 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.testing; + +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.HistogramPointData; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableHistogramPointData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.data.SpanData; +import java.io.IOException; +import java.time.Duration; +import java.util.List; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class InstrumentationTestRunnerTest { + + @BeforeEach + void setAwaitilityDefaults() { + Awaitility.setDefaultPollDelay(Duration.ZERO); + Awaitility.setDefaultPollInterval(Duration.ofMillis(1)); + Awaitility.setDefaultTimeout(Duration.ofMillis(20)); + } + + @AfterEach + void resetAwaitilityDefaults() { + Awaitility.reset(); + } + + @Test + void matchesAllMetricsInScopeInAnyOrderAndIgnoresOtherScopes() { + MetricData duration = histogramData("test", "duration", "s", point(2), point(1)); + MetricData gauge = + ImmutableMetricData.createLongGauge( + Resource.empty(), + InstrumentationScopeInfo.create("test"), + "request.count", + "", + "", + ImmutableGaugeData.empty()); + MetricData unrelatedScope = histogramData("other", "unrelated", "s", point(3)); + + runner(asList(duration, gauge, unrelatedScope)) + .waitAndAssertMetricsExactly( + "test", + metric -> metric.hasName("request.count"), + histogram( + metric -> metric.hasName("duration").hasUnit("s"), + pointAssert -> pointAssert.hasCount(1).hasSum(1), + pointAssert -> pointAssert.hasCount(1).hasSum(2))); + } + + @Test + void repeatedSnapshotsOfOneMetricIdentityCanMatchAnyHistoricalValue() { + InstrumentationTestRunner runner = + runner( + asList( + histogramData("test", "duration", "s", point(1)), + histogramData("test", "duration", "s", point(2)))); + + runner.waitAndAssertMetricsExactly( + "test", + histogram( + metric -> metric.hasName("duration").hasUnit("s"), + pointAssert -> pointAssert.hasCount(1).hasSum(1))); + } + + @Test + void repeatedSnapshotsOfOneMetricIdentityCannotSatisfyMultipleAssertions() { + InstrumentationTestRunner runner = + runner( + asList( + histogramData("test", "duration", "s", point(1)), + histogramData("test", "duration", "s", point(2)))); + + assertThatThrownBy( + () -> + runner.waitAndAssertMetricsExactly( + "test", + histogram( + metric -> metric.hasName("duration").hasUnit("s"), + pointAssert -> pointAssert.hasCount(1).hasSum(1)), + histogram( + metric -> metric.hasName("duration").hasUnit("s"), + pointAssert -> pointAssert.hasCount(1).hasSum(2)))) + .isInstanceOf(AssertionError.class); + } + + @Test + void rejectsMissingMetrics() { + InstrumentationTestRunner runner = + runner(singletonList(histogramData("test", "duration", "s", point(1)))); + + assertThatThrownBy( + () -> + runner.waitAndAssertMetricsExactly( + "test", + metric -> metric.hasName("duration"), + metric -> metric.hasName("request.count"))) + .isInstanceOf(AssertionError.class); + } + + @Test + void rejectsExtraAndDuplicateMetricsEvenWhenTheirAssertionsFail() { + MetricData duration = histogramData("test", "duration", "s", point(1)); + MetricData extra = histogramData("test", "extra", "ms", point(2)); + MetricData duplicateWithWrongMetadata = histogramData("test", "duration", "ms", point(3)); + + for (List metrics : + asList(asList(duration, extra), asList(duration, duplicateWithWrongMetadata))) { + assertThatThrownBy( + () -> + runner(metrics) + .waitAndAssertMetricsExactly( + "test", + histogram( + metric -> metric.hasName("duration").hasUnit("s"), + pointAssert -> pointAssert.hasCount(1)))) + .isInstanceOf(AssertionError.class); + } + } + + @Test + void histogramAssertionRejectsExtraPoints() { + InstrumentationTestRunner runner = + runner(singletonList(histogramData("test", "duration", "s", point(1), point(2)))); + + assertThatThrownBy( + () -> + runner.waitAndAssertMetricsExactly( + "test", + histogram( + metric -> metric.hasName("duration"), + pointAssert -> pointAssert.hasCount(1).hasSum(1)))) + .isInstanceOf(AssertionError.class); + } + + @Test + void histogramAssertionRejectsNonHistogramMetricType() { + MetricData gauge = + ImmutableMetricData.createLongGauge( + Resource.empty(), + InstrumentationScopeInfo.create("test"), + "duration", + "", + "", + ImmutableGaugeData.empty()); + + assertThatThrownBy( + () -> + histogram( + metric -> metric.hasName("duration"), + pointAssert -> pointAssert.hasCount(1)) + .accept(assertThat(gauge))) + .isInstanceOf(AssertionError.class); + } + + private static InstrumentationTestRunner runner(List metrics) { + return new FixedMetricsTestRunner(metrics); + } + + private static MetricData histogramData( + String scopeName, String metricName, String unit, HistogramPointData... points) { + return ImmutableMetricData.createDoubleHistogram( + Resource.empty(), + InstrumentationScopeInfo.create(scopeName), + metricName, + "", + unit, + ImmutableHistogramData.create(AggregationTemporality.CUMULATIVE, asList(points))); + } + + private static HistogramPointData point(long sum) { + return ImmutableHistogramPointData.create( + 0, 1, Attributes.empty(), (double) sum, false, 0, false, 0, emptyList(), singletonList(1L)); + } + + private static class FixedMetricsTestRunner extends InstrumentationTestRunner { + + private final List metrics; + + private FixedMetricsTestRunner(List metrics) { + super(OpenTelemetry.noop()); + this.metrics = metrics; + } + + @Override + public void beforeTestClass() {} + + @Override + public void afterTestClass() throws IOException {} + + @Override + public void clearAllExportedData() {} + + @Override + public OpenTelemetry getOpenTelemetry() { + return OpenTelemetry.noop(); + } + + @Override + public List getExportedSpans() { + return emptyList(); + } + + @Override + public List getExportedMetrics() { + return metrics; + } + + @Override + public List getExportedLogRecords() { + return emptyList(); + } + + @Override + public boolean forceFlushCalled() { + return false; + } + } +} diff --git a/testing-common/src/test/java/io/opentelemetry/instrumentation/testing/junit/LibraryInstrumentationExtensionTest.java b/testing-common/src/test/java/io/opentelemetry/instrumentation/testing/junit/LibraryInstrumentationExtensionTest.java index cc048e8f7d38..092e2dbd3c8b 100644 --- a/testing-common/src/test/java/io/opentelemetry/instrumentation/testing/junit/LibraryInstrumentationExtensionTest.java +++ b/testing-common/src/test/java/io/opentelemetry/instrumentation/testing/junit/LibraryInstrumentationExtensionTest.java @@ -5,7 +5,12 @@ package io.opentelemetry.instrumentation.testing.junit; +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.util.MetricAssertions.histogram; + +import io.opentelemetry.api.common.Attributes; import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; class LibraryInstrumentationExtensionTest { @@ -36,4 +41,48 @@ void shouldCollectTraces() { parentSpan -> parentSpan.hasName("parent"), childSpan -> childSpan.hasName("child"))); } + + @Test + void shouldAssertAllMetricsForScope() { + Attributes firstAttributes = Attributes.of(stringKey("key"), "first"); + Attributes secondAttributes = Attributes.of(stringKey("key"), "second"); + testing + .getOpenTelemetry() + .getMeter("test") + .histogramBuilder("duration") + .setUnit("s") + .setDescription("Test duration.") + .build() + .record(2, firstAttributes); + testing + .getOpenTelemetry() + .getMeter("test") + .histogramBuilder("duration") + .setUnit("s") + .setDescription("Test duration.") + .build() + .record(4, secondAttributes); + testing + .getOpenTelemetry() + .getMeter("test") + .histogramBuilder("other") + .setUnit("ms") + .build() + .record(3); + testing + .getOpenTelemetry() + .getMeter("other-scope") + .histogramBuilder("duration") + .build() + .record(5); + + testing.waitAndAssertMetricsExactly( + "test", + histogram( + metric -> metric.hasName("duration").hasUnit("s").hasDescription("Test duration."), + point -> point.hasCount(1).hasSum(4).hasAttributes(secondAttributes), + point -> point.hasCount(1).hasSum(2).hasAttributes(firstAttributes)), + histogram( + metric -> metric.hasName("other").hasUnit("ms"), point -> point.hasCount(1).hasSum(3))); + } }