From c8db84a5af5647be351a2477351f51d8f12e47b4 Mon Sep 17 00:00:00 2001 From: Min Xia Date: Fri, 24 May 2024 10:32:36 -0700 Subject: [PATCH] Contract test the new DB resource type and identifier attributes --- .../test/jdbc/JdbcContractTestBase.java | 256 ++++++++++++------ .../appsignals/test/jdbc/JdbcH2Test.java | 4 +- .../appsignals/test/jdbc/JdbcMySQLTest.java | 20 +- .../test/jdbc/JdbcPostgresTest.java | 20 +- 4 files changed, 216 insertions(+), 84 deletions(-) diff --git a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcContractTestBase.java b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcContractTestBase.java index 84d344ac7..833e37734 100644 --- a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcContractTestBase.java +++ b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcContractTestBase.java @@ -17,6 +17,7 @@ import static io.opentelemetry.proto.trace.v1.Span.SpanKind.SPAN_KIND_CLIENT; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertThat; import io.opentelemetry.proto.common.v1.KeyValue; import io.opentelemetry.proto.metrics.v1.ExponentialHistogramDataPoint; @@ -33,6 +34,7 @@ public class JdbcContractTestBase extends ContractTestBase { protected static final String DB_USER = "sa"; protected static final String DB_PASSWORD = "password"; protected static final String DB_OPERATION = "SELECT"; + protected static final String DB_RESOURCE_TYPE = "DB::Connection"; @Override protected String getApplicationImageName() { @@ -49,13 +51,16 @@ protected void assertAwsSpanAttributes( String method, String path, String dbSystem, - String dbOperation) { + String dbOperation, + String type, + String identifier) { assertThat(resourceScopeSpans) .satisfiesOnlyOnce( rss -> { assertThat(rss.getSpan().getKind()).isEqualTo(SPAN_KIND_CLIENT); var attributesList = rss.getSpan().getAttributesList(); - assertAwsAttributes(attributesList, method, path, dbSystem, dbOperation); + assertAwsAttributes( + attributesList, method, path, dbSystem, dbOperation, type, identifier); }); } @@ -64,35 +69,52 @@ protected void assertAwsAttributes( String method, String endpoint, String dbSystem, - String dbOperation) { - assertThat(attributesList) - .satisfiesOnlyOnce( - attribute -> { - assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_LOCAL_OPERATION); - assertThat(attribute.getValue().getStringValue()) - .isEqualTo(String.format("%s /%s", method, endpoint)); - }) - .satisfiesOnlyOnce( - attribute -> { - assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_LOCAL_SERVICE); - assertThat(attribute.getValue().getStringValue()) - .isEqualTo(getApplicationOtelServiceName()); - }) - .satisfiesOnlyOnce( - attribute -> { - assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_REMOTE_SERVICE); - assertThat(attribute.getValue().getStringValue()).isEqualTo(dbSystem); - }) - .satisfiesOnlyOnce( - attribute -> { - assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_REMOTE_OPERATION); - assertThat(attribute.getValue().getStringValue()).isEqualTo(dbOperation); - }) - .satisfiesOnlyOnce( - attribute -> { - assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_SPAN_KIND); - assertThat(attribute.getValue().getStringValue()).isEqualTo("CLIENT"); - }); + String dbOperation, + String type, + String identifier) { + var assertions = + assertThat(attributesList) + .satisfiesOnlyOnce( + attribute -> { + assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_LOCAL_OPERATION); + assertThat(attribute.getValue().getStringValue()) + .isEqualTo(String.format("%s /%s", method, endpoint)); + }) + .satisfiesOnlyOnce( + attribute -> { + assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_LOCAL_SERVICE); + assertThat(attribute.getValue().getStringValue()) + .isEqualTo(getApplicationOtelServiceName()); + }) + .satisfiesOnlyOnce( + attribute -> { + assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_REMOTE_SERVICE); + assertThat(attribute.getValue().getStringValue()).isEqualTo(dbSystem); + }) + .satisfiesOnlyOnce( + attribute -> { + assertThat(attribute.getKey()) + .isEqualTo(AppSignalsConstants.AWS_REMOTE_OPERATION); + assertThat(attribute.getValue().getStringValue()).isEqualTo(dbOperation); + }) + .satisfiesOnlyOnce( + attribute -> { + assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_SPAN_KIND); + assertThat(attribute.getValue().getStringValue()).isEqualTo("CLIENT"); + }); + if (type != null && identifier != null) { + assertions.satisfiesOnlyOnce( + (attribute) -> { + assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_REMOTE_RESOURCE_TYPE); + assertThat(attribute.getValue().getStringValue()).isEqualTo(type); + }); + assertions.satisfiesOnlyOnce( + (attribute) -> { + assertThat(attribute.getKey()) + .isEqualTo(AppSignalsConstants.AWS_REMOTE_RESOURCE_IDENTIFIER); + assertThat(attribute.getValue().getStringValue()).isEqualTo(identifier); + }); + } } protected void assertSemanticConventionsSpanAttributes( @@ -181,7 +203,9 @@ protected void assertMetricAttributes( String metricName, Double expectedSum, String dbSystem, - String dbOperation) { + String dbOperation, + String type, + String identifier) { assertThat(resourceScopeMetrics) .anySatisfy( metric -> { @@ -193,42 +217,58 @@ protected void assertMetricAttributes( dp -> { List attributesList = dp.getAttributesList(); assertThat(attributesList).isNotNull(); - assertThat(attributesList) - .satisfiesOnlyOnce( - attribute -> { - assertThat(attribute.getKey()) - .isEqualTo(AppSignalsConstants.AWS_SPAN_KIND); - assertThat(attribute.getValue().getStringValue()) - .isEqualTo("CLIENT"); - }) - .satisfiesOnlyOnce( - attribute -> { - assertThat(attribute.getKey()) - .isEqualTo(AppSignalsConstants.AWS_LOCAL_OPERATION); - assertThat(attribute.getValue().getStringValue()) - .isEqualTo(String.format("%s /%s", method, path)); - }) - .satisfiesOnlyOnce( - attribute -> { - assertThat(attribute.getKey()) - .isEqualTo(AppSignalsConstants.AWS_LOCAL_SERVICE); - assertThat(attribute.getValue().getStringValue()) - .isEqualTo(getApplicationOtelServiceName()); - }) - .satisfiesOnlyOnce( - attribute -> { - assertThat(attribute.getKey()) - .isEqualTo(AppSignalsConstants.AWS_REMOTE_SERVICE); - assertThat(attribute.getValue().getStringValue()) - .isEqualTo(dbSystem); - }) - .satisfiesOnlyOnce( - attribute -> { - assertThat(attribute.getKey()) - .isEqualTo(AppSignalsConstants.AWS_REMOTE_OPERATION); - assertThat(attribute.getValue().getStringValue()) - .isEqualTo(dbOperation); - }); + var assertions = + assertThat(attributesList) + .satisfiesOnlyOnce( + attribute -> { + assertThat(attribute.getKey()) + .isEqualTo(AppSignalsConstants.AWS_SPAN_KIND); + assertThat(attribute.getValue().getStringValue()) + .isEqualTo("CLIENT"); + }) + .satisfiesOnlyOnce( + attribute -> { + assertThat(attribute.getKey()) + .isEqualTo(AppSignalsConstants.AWS_LOCAL_OPERATION); + assertThat(attribute.getValue().getStringValue()) + .isEqualTo(String.format("%s /%s", method, path)); + }) + .satisfiesOnlyOnce( + attribute -> { + assertThat(attribute.getKey()) + .isEqualTo(AppSignalsConstants.AWS_LOCAL_SERVICE); + assertThat(attribute.getValue().getStringValue()) + .isEqualTo(getApplicationOtelServiceName()); + }) + .satisfiesOnlyOnce( + attribute -> { + assertThat(attribute.getKey()) + .isEqualTo(AppSignalsConstants.AWS_REMOTE_SERVICE); + assertThat(attribute.getValue().getStringValue()) + .isEqualTo(dbSystem); + }) + .satisfiesOnlyOnce( + attribute -> { + assertThat(attribute.getKey()) + .isEqualTo(AppSignalsConstants.AWS_REMOTE_OPERATION); + assertThat(attribute.getValue().getStringValue()) + .isEqualTo(dbOperation); + }); + if (type != null && identifier != null) { + assertions.satisfiesOnlyOnce( + (attribute) -> { + assertThat(attribute.getKey()) + .isEqualTo(AppSignalsConstants.AWS_REMOTE_RESOURCE_TYPE); + assertThat(attribute.getValue().getStringValue()).isEqualTo(type); + }); + assertions.satisfiesOnlyOnce( + (attribute) -> { + assertThat(attribute.getKey()) + .isEqualTo(AppSignalsConstants.AWS_REMOTE_RESOURCE_IDENTIFIER); + assertThat(attribute.getValue().getStringValue()) + .isEqualTo(identifier); + }); + } if (expectedSum != null) { double actualSum = dp.getSum(); @@ -245,7 +285,13 @@ protected void assertMetricAttributes( } protected void assertSuccess( - String dbSystem, String dbOperation, String dbUser, String dbName, String jdbcUrl) { + String dbSystem, + String dbOperation, + String dbUser, + String dbName, + String jdbcUrl, + String type, + String identifier) { var path = "success"; var method = "GET"; var otelStatusCode = "STATUS_CODE_UNSET"; @@ -255,7 +301,7 @@ protected void assertSuccess( assertThat(response.status().isSuccess()).isTrue(); var traces = mockCollectorClient.getTraces(); - assertAwsSpanAttributes(traces, method, path, dbSystem, dbOperation); + assertAwsSpanAttributes(traces, method, path, dbSystem, dbOperation, type, identifier); assertSemanticConventionsSpanAttributes( traces, otelStatusCode, dbSqlTable, dbSystem, dbOperation, dbUser, dbName, jdbcUrl); @@ -266,15 +312,45 @@ protected void assertSuccess( AppSignalsConstants.ERROR_METRIC, AppSignalsConstants.FAULT_METRIC)); assertMetricAttributes( - metrics, method, path, AppSignalsConstants.LATENCY_METRIC, 5000.0, dbSystem, dbOperation); + metrics, + method, + path, + AppSignalsConstants.LATENCY_METRIC, + 5000.0, + dbSystem, + dbOperation, + type, + identifier); assertMetricAttributes( - metrics, method, path, AppSignalsConstants.ERROR_METRIC, 0.0, dbSystem, dbOperation); + metrics, + method, + path, + AppSignalsConstants.ERROR_METRIC, + 0.0, + dbSystem, + dbOperation, + type, + identifier); assertMetricAttributes( - metrics, method, path, AppSignalsConstants.FAULT_METRIC, 0.0, dbSystem, dbOperation); + metrics, + method, + path, + AppSignalsConstants.FAULT_METRIC, + 0.0, + dbSystem, + dbOperation, + type, + identifier); } protected void assertFault( - String dbSystem, String dbOperation, String dbUser, String dbName, String jdbcUrl) { + String dbSystem, + String dbOperation, + String dbUser, + String dbName, + String jdbcUrl, + String type, + String identifier) { var path = "fault"; var method = "GET"; var otelStatusCode = "STATUS_CODE_ERROR"; @@ -283,7 +359,7 @@ protected void assertFault( assertThat(response.status().isServerError()).isTrue(); var traces = mockCollectorClient.getTraces(); - assertAwsSpanAttributes(traces, method, path, dbSystem, dbOperation); + assertAwsSpanAttributes(traces, method, path, dbSystem, dbOperation, type, identifier); assertSemanticConventionsSpanAttributes( traces, otelStatusCode, dbSqlTable, dbSystem, dbOperation, dbUser, dbName, jdbcUrl); @@ -294,10 +370,34 @@ protected void assertFault( AppSignalsConstants.ERROR_METRIC, AppSignalsConstants.FAULT_METRIC)); assertMetricAttributes( - metrics, method, path, AppSignalsConstants.LATENCY_METRIC, 5000.0, dbSystem, dbOperation); + metrics, + method, + path, + AppSignalsConstants.LATENCY_METRIC, + 5000.0, + dbSystem, + dbOperation, + type, + identifier); assertMetricAttributes( - metrics, method, path, AppSignalsConstants.ERROR_METRIC, 0.0, dbSystem, dbOperation); + metrics, + method, + path, + AppSignalsConstants.ERROR_METRIC, + 0.0, + dbSystem, + dbOperation, + type, + identifier); assertMetricAttributes( - metrics, method, path, AppSignalsConstants.FAULT_METRIC, 1.0, dbSystem, dbOperation); + metrics, + method, + path, + AppSignalsConstants.FAULT_METRIC, + 1.0, + dbSystem, + dbOperation, + type, + identifier); } } diff --git a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcH2Test.java b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcH2Test.java index 8f685aa0d..ab5b69da5 100644 --- a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcH2Test.java +++ b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcH2Test.java @@ -32,12 +32,12 @@ public class JdbcH2Test extends JdbcContractTestBase { @Test public void testSuccess() { - assertSuccess(DB_SYSTEM, DB_OPERATION, DB_USER, DB_NAME, DB_CONNECTION_STRING); + assertSuccess(DB_SYSTEM, DB_OPERATION, DB_USER, DB_NAME, DB_CONNECTION_STRING, null, null); } @Test public void testFault() { - assertFault(DB_SYSTEM, DB_OPERATION, DB_USER, DB_NAME, DB_CONNECTION_STRING); + assertFault(DB_SYSTEM, DB_OPERATION, DB_USER, DB_NAME, DB_CONNECTION_STRING, null, null); } @Override diff --git a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcMySQLTest.java b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcMySQLTest.java index 9e82a4887..f9be5b6ca 100644 --- a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcMySQLTest.java +++ b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcMySQLTest.java @@ -38,6 +38,8 @@ public class JdbcMySQLTest extends JdbcContractTestBase { private static final String DB_URL = String.format("jdbc:%s/%s", DB_CONNECTION_STRING, DB_NAME); private static final String DB_DRIVER = "com.mysql.cj.jdbc.Driver"; private static final String DB_PLATFORM = "org.hibernate.dialect.MySQL8Dialect"; + private static final String MYSQL_IDENTIFIER = + String.format("%s|%s|%s", DB_NAME, NETWORK_ALIAS, MySQLContainer.MYSQL_PORT); private MySQLContainer mySQLContainer; @@ -48,12 +50,26 @@ public void afterEach() { @Test public void testSuccess() { - assertSuccess(DB_SYSTEM, DB_OPERATION, DB_USER, DB_NAME, DB_CONNECTION_STRING); + assertSuccess( + DB_SYSTEM, + DB_OPERATION, + DB_USER, + DB_NAME, + DB_CONNECTION_STRING, + DB_RESOURCE_TYPE, + MYSQL_IDENTIFIER); } @Test public void testFault() { - assertFault(DB_SYSTEM, DB_OPERATION, DB_USER, DB_NAME, DB_CONNECTION_STRING); + assertFault( + DB_SYSTEM, + DB_OPERATION, + DB_USER, + DB_NAME, + DB_CONNECTION_STRING, + DB_RESOURCE_TYPE, + MYSQL_IDENTIFIER); } @Override diff --git a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcPostgresTest.java b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcPostgresTest.java index 19f039ad3..056c7c448 100644 --- a/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcPostgresTest.java +++ b/appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcPostgresTest.java @@ -37,6 +37,8 @@ public class JdbcPostgresTest extends JdbcContractTestBase { private static final String DB_URL = String.format("jdbc:%s/%s", DB_CONNECTION_STRING, DB_NAME); private static final String DB_DRIVER = "org.postgresql.Driver"; private static final String DB_PLATFORM = "org.hibernate.dialect.PostgreSQLDialect"; + private static final String POSTGRES_IDENTIFIER = + String.format("%s|%s|%s", DB_NAME, NETWORK_ALIAS, PostgreSQLContainer.POSTGRESQL_PORT); private PostgreSQLContainer postgreSqlContainer; @@ -48,12 +50,26 @@ public void afterEach() { @Test public void testSuccess() { - assertSuccess(DB_SYSTEM, DB_OPERATION, DB_USER, DB_NAME, DB_CONNECTION_STRING); + assertSuccess( + DB_SYSTEM, + DB_OPERATION, + DB_USER, + DB_NAME, + DB_CONNECTION_STRING, + DB_RESOURCE_TYPE, + POSTGRES_IDENTIFIER); } @Test public void testFault() { - assertFault(DB_SYSTEM, DB_OPERATION, DB_USER, DB_NAME, DB_CONNECTION_STRING); + assertFault( + DB_SYSTEM, + DB_OPERATION, + DB_USER, + DB_NAME, + DB_CONNECTION_STRING, + DB_RESOURCE_TYPE, + POSTGRES_IDENTIFIER); } @Override