Skip to content

Commit c3cb430

Browse files
committed
feat: set up contract tests for secrets manager and step functions
1 parent 76f87a3 commit c3cb430

File tree

9 files changed

+590
-7
lines changed

9 files changed

+590
-7
lines changed

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/base/AwsSdkBaseTest.java

Lines changed: 202 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import java.util.List;
2424
import java.util.Map;
2525
import java.util.Set;
26+
import java.util.regex.Pattern;
27+
import java.util.regex.PatternSyntaxException;
2628
import org.assertj.core.api.ThrowingConsumer;
2729
import org.junit.jupiter.api.AfterAll;
2830
import org.junit.jupiter.api.BeforeAll;
@@ -42,7 +44,10 @@ public abstract class AwsSdkBaseTest extends ContractTestBase {
4244
LocalStackContainer.Service.S3,
4345
LocalStackContainer.Service.DYNAMODB,
4446
LocalStackContainer.Service.SQS,
45-
LocalStackContainer.Service.KINESIS)
47+
LocalStackContainer.Service.KINESIS,
48+
LocalStackContainer.Service.SECRETSMANAGER,
49+
LocalStackContainer.Service.IAM,
50+
LocalStackContainer.Service.STEPFUNCTIONS)
4651
.withEnv("DEFAULT_REGION", "us-west-2")
4752
.withNetwork(network)
4853
.withEnv("LOCALSTACK_HOST", "127.0.0.1")
@@ -102,6 +107,10 @@ protected String getApplicationWaitPattern() {
102107

103108
protected abstract String getBedrockAgentRuntimeSpanNamePrefix();
104109

110+
protected abstract String getSecretsManagerSpanNamePrefix();
111+
112+
protected abstract String getStepFunctionsSpanNamePrefix();
113+
105114
protected abstract String getS3RpcServiceName();
106115

107116
protected abstract String getDynamoDbRpcServiceName();
@@ -118,6 +127,10 @@ protected String getApplicationWaitPattern() {
118127

119128
protected abstract String getBedrockAgentRuntimeRpcServiceName();
120129

130+
protected abstract String getSecretsManagerRpcServiceName();
131+
132+
protected abstract String getStepFunctionsRpcServiceName();
133+
121134
private String getS3ServiceName() {
122135
return "AWS::S3";
123136
}
@@ -150,6 +163,14 @@ private String getBedrockRuntimeServiceName() {
150163
return "AWS::BedrockRuntime";
151164
}
152165

166+
private String getSecretsManagerServiceName() {
167+
return "AWS::SecretsManager";
168+
}
169+
170+
private String getStepFunctionsServiceName() {
171+
return "AWS::StepFunctions";
172+
}
173+
153174
private String s3SpanName(String operation) {
154175
return String.format("%s.%s", getS3SpanNamePrefix(), operation);
155176
}
@@ -182,10 +203,41 @@ private String bedrockAgentRuntimeSpanName(String operation) {
182203
return String.format("%s.%s", getBedrockAgentRuntimeSpanNamePrefix(), operation);
183204
}
184205

206+
private String secretsManagerSpanName(String operation) {
207+
return String.format("%s.%s", getSecretsManagerSpanNamePrefix(), operation);
208+
}
209+
210+
private String stepFunctionsSpanName(String operation) {
211+
return String.format("%s.%s", getStepFunctionsSpanNamePrefix(), operation);
212+
}
213+
214+
private boolean isValidRegex(String pattern) {
215+
try {
216+
Pattern.compile(pattern);
217+
return true;
218+
} catch (PatternSyntaxException e) {
219+
return false;
220+
}
221+
}
222+
185223
protected ThrowingConsumer<KeyValue> assertAttribute(String key, String value) {
186224
return (attribute) -> {
187225
assertThat(attribute.getKey()).isEqualTo(key);
188-
assertThat(attribute.getValue().getStringValue()).isEqualTo(value);
226+
var actualValue = attribute.getValue().getStringValue();
227+
228+
if (isValidRegex(value)) {
229+
System.out.println("ASSERTING REGEX: " + actualValue + " equivalent to " + value);
230+
assertThat(actualValue).matches(value);
231+
if (!actualValue.matches(value)) {
232+
System.out.println("ASSERTION FAILED between: " + actualValue + " and " + value);
233+
}
234+
} else {
235+
System.out.println("ASSERTING EXACT: " + actualValue + " equivalent to " + value);
236+
assertThat(actualValue).isEqualTo(value);
237+
if (!actualValue.equals(value)) {
238+
System.out.println("ASSERTION FAILED between: " + actualValue + " and " + value);
239+
}
240+
}
189241
};
190242
}
191243

@@ -413,13 +465,14 @@ private void assertAwsAttributes(
413465
.satisfiesOnlyOnce(assertAttribute(AppSignalsConstants.AWS_REMOTE_OPERATION, operation))
414466
.satisfiesOnlyOnce(assertAttribute(AppSignalsConstants.AWS_REMOTE_SERVICE, service))
415467
.satisfiesOnlyOnce(assertAttribute(AppSignalsConstants.AWS_SPAN_KIND, spanKind));
416-
if (type != null && identifier != null) {
468+
if (type != null && identifier != null && clouformationIdentifier != null) {
417469
assertions.satisfiesOnlyOnce(
418470
assertAttribute(AppSignalsConstants.AWS_REMOTE_RESOURCE_TYPE, type));
419471
assertions.satisfiesOnlyOnce(
420472
assertAttribute(AppSignalsConstants.AWS_REMOTE_RESOURCE_IDENTIFIER, identifier));
421473
assertions.satisfiesOnlyOnce(
422-
assertAttribute(AppSignalsConstants.AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER, clouformationIdentifier));
474+
assertAttribute(
475+
AppSignalsConstants.AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER, clouformationIdentifier));
423476
}
424477
}
425478

@@ -1995,7 +2048,8 @@ protected void doTestBedrockGuardrailId() {
19952048
var localOperation = "GET /bedrock/getguardrail";
19962049
String type = "AWS::Bedrock::Guardrail";
19972050
String identifier = "test-bedrock-guardrail";
1998-
String cloudformationIdentifier = "arn:aws:bedrock:us-east-1:000000000000:guardrail/test-bedrock-guardrail";
2051+
String cloudformationIdentifier =
2052+
"arn:aws:bedrock:us-east-1:000000000000:guardrail/test-bedrock-guardrail";
19992053
assertSpanClientAttributes(
20002054
traces,
20012055
bedrockSpanName("GetGuardrail"),
@@ -2015,7 +2069,8 @@ protected void doTestBedrockGuardrailId() {
20152069
assertAttribute(
20162070
SemanticConventionsConstants.AWS_GUARDRAIL_ID, "test-bedrock-guardrail"),
20172071
assertAttribute(
2018-
SemanticConventionsConstants.AWS_GUARDRAIL_ARN, "arn:aws:bedrock:us-east-1:000000000000:guardrail/test-bedrock-guardrail")));
2072+
SemanticConventionsConstants.AWS_GUARDRAIL_ARN,
2073+
"arn:aws:bedrock:us-east-1:000000000000:guardrail/test-bedrock-guardrail")));
20192074
assertMetricClientAttributes(
20202075
metrics,
20212076
AppSignalsConstants.LATENCY_METRIC,
@@ -2185,4 +2240,145 @@ protected void doTestBedrockAgentRuntimeKnowledgeBaseId() {
21852240
cloudformationIdentifier,
21862241
0.0);
21872242
}
2243+
2244+
protected void doTestSecretsManagerDescribeSecret() throws Exception {
2245+
appClient.get("/secretsmanager/describesecret/test-secret-id").aggregate().join();
2246+
var traces = mockCollectorClient.getTraces();
2247+
var metrics =
2248+
mockCollectorClient.getMetrics(
2249+
Set.of(
2250+
AppSignalsConstants.ERROR_METRIC,
2251+
AppSignalsConstants.FAULT_METRIC,
2252+
AppSignalsConstants.LATENCY_METRIC));
2253+
var localService = getApplicationOtelServiceName();
2254+
var localOperation = "GET /secretsmanager/describesecret/:secretId";
2255+
var type = "AWS::SecretsManager::Secret";
2256+
var identifier = "test-secret-id-[A-Za-z0-9]{6}";
2257+
var cloudformationIdentifier =
2258+
"arn:aws:secretsmanager:us-west-2:000000000000:secret:test-secret-id-[A-Za-z0-9]{6}";
2259+
2260+
assertSpanClientAttributes(
2261+
traces,
2262+
secretsManagerSpanName("DescribeSecret"),
2263+
getSecretsManagerRpcServiceName(),
2264+
localService,
2265+
localOperation,
2266+
getSecretsManagerServiceName(),
2267+
"DescribeSecret",
2268+
type,
2269+
identifier,
2270+
cloudformationIdentifier,
2271+
"localstack",
2272+
4566,
2273+
"http://localstack:4566",
2274+
200,
2275+
List.of(
2276+
assertAttribute(
2277+
SemanticConventionsConstants.AWS_SECRET_ARN,
2278+
"arn:aws:secretsmanager:us-west-2:000000000000:secret:test-secret-id-[A-Za-z0-9]{6}")));
2279+
assertMetricClientAttributes(
2280+
metrics,
2281+
AppSignalsConstants.LATENCY_METRIC,
2282+
localService,
2283+
localOperation,
2284+
getSecretsManagerServiceName(),
2285+
"DescribeSecret",
2286+
type,
2287+
identifier,
2288+
cloudformationIdentifier,
2289+
5000.0);
2290+
assertMetricClientAttributes(
2291+
metrics,
2292+
AppSignalsConstants.FAULT_METRIC,
2293+
localService,
2294+
localOperation,
2295+
getSecretsManagerServiceName(),
2296+
"DescribeSecret",
2297+
type,
2298+
identifier,
2299+
cloudformationIdentifier,
2300+
0.0);
2301+
assertMetricClientAttributes(
2302+
metrics,
2303+
AppSignalsConstants.ERROR_METRIC,
2304+
localService,
2305+
localOperation,
2306+
getSecretsManagerServiceName(),
2307+
"DescribeSecret",
2308+
type,
2309+
identifier,
2310+
cloudformationIdentifier,
2311+
0.0);
2312+
}
2313+
2314+
protected void doTestStepFunctionsDescribeStateMachine() throws Exception {
2315+
appClient.get("/sfn/describestatemachine/test-state-machine").aggregate().join();
2316+
var traces = mockCollectorClient.getTraces();
2317+
var metrics =
2318+
mockCollectorClient.getMetrics(
2319+
Set.of(
2320+
AppSignalsConstants.ERROR_METRIC,
2321+
AppSignalsConstants.FAULT_METRIC,
2322+
AppSignalsConstants.LATENCY_METRIC));
2323+
2324+
var localService = getApplicationOtelServiceName();
2325+
var localOperation = "GET /sfn/describestatemachine/:name";
2326+
var type = "AWS::StepFunctions::StateMachine";
2327+
var identifier = "test-state-machine";
2328+
var cloudformationIdentifier =
2329+
"arn:aws:states:us-west-2:000000000000:stateMachine:test-state-machine";
2330+
2331+
assertSpanClientAttributes(
2332+
traces,
2333+
stepFunctionsSpanName("DescribeStateMachine"),
2334+
getStepFunctionsRpcServiceName(),
2335+
localService,
2336+
localOperation,
2337+
getStepFunctionsServiceName(),
2338+
"DescribeStateMachine",
2339+
type,
2340+
identifier,
2341+
cloudformationIdentifier,
2342+
"localstack",
2343+
4566,
2344+
"http://localstack:4566",
2345+
200,
2346+
List.of(
2347+
assertAttribute(
2348+
SemanticConventionsConstants.AWS_STATE_MACHINE_ARN,
2349+
"arn:aws:states:us-west-2:000000000000:stateMachine:test-state-machine")));
2350+
assertMetricClientAttributes(
2351+
metrics,
2352+
AppSignalsConstants.LATENCY_METRIC,
2353+
localService,
2354+
localOperation,
2355+
getStepFunctionsServiceName(),
2356+
"DescribeStateMachine",
2357+
type,
2358+
identifier,
2359+
cloudformationIdentifier,
2360+
5000.0);
2361+
assertMetricClientAttributes(
2362+
metrics,
2363+
AppSignalsConstants.FAULT_METRIC,
2364+
localService,
2365+
localOperation,
2366+
getStepFunctionsServiceName(),
2367+
"DescribeStateMachine",
2368+
type,
2369+
identifier,
2370+
cloudformationIdentifier,
2371+
0.0);
2372+
assertMetricClientAttributes(
2373+
metrics,
2374+
AppSignalsConstants.ERROR_METRIC,
2375+
localService,
2376+
localOperation,
2377+
getStepFunctionsServiceName(),
2378+
"DescribeStateMachine",
2379+
type,
2380+
identifier,
2381+
cloudformationIdentifier,
2382+
0.0);
2383+
}
21882384
}

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v1/AwsSdkV1Test.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ protected String getBedrockAgentRuntimeSpanNamePrefix() {
7676
return "AWSBedrockAgentRuntime";
7777
}
7878

79+
@Override
80+
protected String getSecretsManagerSpanNamePrefix() {
81+
return "AWSSecretsManager";
82+
}
83+
84+
@Override
85+
protected String getStepFunctionsSpanNamePrefix() {
86+
return "AWSStepFunctions";
87+
}
88+
7989
protected String getS3RpcServiceName() {
8090
return "Amazon S3";
8191
}
@@ -90,6 +100,16 @@ protected String getSqsRpcServiceName() {
90100
return "AmazonSQS";
91101
}
92102

103+
@Override
104+
protected String getSecretsManagerRpcServiceName() {
105+
return "AWSSecretsManager";
106+
}
107+
108+
@Override
109+
protected String getStepFunctionsRpcServiceName() {
110+
return "AWSStepFunctions";
111+
}
112+
93113
protected String getKinesisRpcServiceName() {
94114
return "AmazonKinesis";
95115
}
@@ -235,4 +255,14 @@ void testBedrockAgentRuntimeAgentId() {
235255
void testBedrockAgentRuntimeKnowledgeBaseId() {
236256
doTestBedrockAgentRuntimeKnowledgeBaseId();
237257
}
258+
259+
@Test
260+
void testSecretsManagerDescribeSecret() throws Exception {
261+
doTestSecretsManagerDescribeSecret();
262+
}
263+
264+
@Test
265+
void testStepFunctionsDescribeStateMachine() throws Exception {
266+
doTestStepFunctionsDescribeStateMachine();
267+
}
238268
}

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/awssdk/v2/AwsSdkV2Test.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ protected String getBedrockAgentRuntimeSpanNamePrefix() {
7575
return "BedrockAgentRuntime";
7676
}
7777

78+
@Override
79+
protected String getSecretsManagerSpanNamePrefix() {
80+
return "SecretsManager";
81+
}
82+
83+
@Override
84+
protected String getStepFunctionsSpanNamePrefix() {
85+
return "Sfn";
86+
}
87+
7888
@Override
7989
protected String getS3RpcServiceName() {
8090
return "S3";
@@ -114,6 +124,16 @@ protected String getBedrockAgentRuntimeRpcServiceName() {
114124
return "BedrockAgentRuntime";
115125
}
116126

127+
@Override
128+
protected String getSecretsManagerRpcServiceName() {
129+
return "SecretsManager";
130+
}
131+
132+
@Override
133+
protected String getStepFunctionsRpcServiceName() {
134+
return "Sfn";
135+
}
136+
117137
@Test
118138
void testS3CreateBucket() throws Exception {
119139
doTestS3CreateBucket();
@@ -240,4 +260,14 @@ void testBedrockAgentRuntimeAgentId() {
240260
// void testBedrockAgentRuntimeKnowledgeBaseId() {
241261
// doTestBedrockAgentRuntimeKnowledgeBaseId();
242262
// }
263+
264+
@Test
265+
void testSecretsManagerDescribeSecret() throws Exception {
266+
doTestSecretsManagerDescribeSecret();
267+
}
268+
269+
@Test
270+
void testStepFunctionsDescribeStateMachine() throws Exception {
271+
doTestStepFunctionsDescribeStateMachine();
272+
}
243273
}

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/utils/AppSignalsConstants.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public class AppSignalsConstants {
3131
public static final String AWS_REMOTE_OPERATION = "aws.remote.operation";
3232
public static final String AWS_REMOTE_RESOURCE_TYPE = "aws.remote.resource.type";
3333
public static final String AWS_REMOTE_RESOURCE_IDENTIFIER = "aws.remote.resource.identifier";
34-
public static final String AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER = "aws.remote.resource.cfn.primary.identifier";
34+
public static final String AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER =
35+
"aws.remote.resource.cfn.primary.identifier";
3536
public static final String AWS_SPAN_KIND = "aws.span.kind";
3637
public static final String AWS_REMOTE_DB_USER = "aws.remote.db.user";
3738
}

0 commit comments

Comments
 (0)