Skip to content

Commit

Permalink
Merge pull request #813 from mxiamxia/db-rest-test
Browse files Browse the repository at this point in the history
Contract test the new DB resource type and identifier attributes
  • Loading branch information
thpierce authored May 24, 2024
2 parents 0a1dbff + c8db84a commit ff295b7
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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() {
Expand All @@ -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);
});
}

Expand All @@ -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(
Expand Down Expand Up @@ -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 -> {
Expand All @@ -193,42 +217,58 @@ protected void assertMetricAttributes(
dp -> {
List<KeyValue> 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();
Expand All @@ -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";
Expand All @@ -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);

Expand All @@ -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";
Expand All @@ -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);

Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
Expand Down
Loading

0 comments on commit ff295b7

Please sign in to comment.