Skip to content

Commit ab6d02d

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

File tree

9 files changed

+706
-7
lines changed

9 files changed

+706
-7
lines changed

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

Lines changed: 239 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,182 @@ 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+
}
2384+
2385+
protected void doTestStepFunctionsDescribeActivity() throws Exception {
2386+
appClient.get("/sfn/describeactivity/test-activity").aggregate().join();
2387+
var traces = mockCollectorClient.getTraces();
2388+
var metrics = mockCollectorClient.getMetrics(
2389+
Set.of(
2390+
AppSignalsConstants.ERROR_METRIC,
2391+
AppSignalsConstants.FAULT_METRIC,
2392+
AppSignalsConstants.LATENCY_METRIC));
2393+
2394+
var localService = getApplicationOtelServiceName();
2395+
var localOperation = "GET /sfn/describeactivity/:name";
2396+
var type = "AWS::StepFunctions::Activity";
2397+
var identifier = "test-activity";
2398+
var cloudformationIdentifier = "arn:aws:states:us-west-2:000000000000:activity:test-activity";
2399+
2400+
assertSpanClientAttributes(
2401+
traces,
2402+
stepFunctionsSpanName("DescribeActivity"),
2403+
getStepFunctionsRpcServiceName(),
2404+
localService,
2405+
localOperation,
2406+
getStepFunctionsServiceName(),
2407+
"DescribeActivity",
2408+
type,
2409+
identifier,
2410+
cloudformationIdentifier,
2411+
"localstack",
2412+
4566,
2413+
"http://localstack:4566",
2414+
200,
2415+
List.of(
2416+
assertAttribute(
2417+
SemanticConventionsConstants.AWS_ACTIVITY_ARN,
2418+
"arn:aws:states:us-west-2:000000000000:activity:test-activity")));
2419+
2420+
}
21882421
}

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

Lines changed: 35 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,19 @@ 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+
}
268+
269+
@Test
270+
void testStepFunctionsDescribeActivity() throws Exception {
271+
doTestStepFunctionsDescribeActivity();
272+
}
238273
}

0 commit comments

Comments
 (0)