@kensio/yulin 1.21.7 → 1.21.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -2
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-properties.js +2 -0
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.js +1 -1
- package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-input.d.ts +2 -0
- package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-input.js +4 -0
- package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-refusals.js +0 -5
- package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping.handler.d.ts +2 -0
- package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping.handler.js +2 -0
- package/dist/service/lambda/command/event-source-mapping/sim-lambda-event-source-mapping-commands.d.ts +2 -0
- package/dist/service/lambda/destination/sim-lambda-destination-targets.d.ts +2 -1
- package/dist/service/lambda/event-source/poll/kinesis/sim-lambda-kinesis-shard-poller.d.ts +0 -4
- package/dist/service/lambda/event-source/poll/kinesis/sim-lambda-kinesis-shard-poller.js +10 -15
- package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-event-source-poller.d.ts +1 -6
- package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-event-source-poller.js +9 -27
- package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-polling.d.ts +19 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-polling.js +27 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-event-source-function.d.ts +1 -1
- package/dist/service/lambda/event-source/poll/sim-lambda-event-source-function.js +3 -1
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-age.d.ts +13 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-age.js +27 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-info.d.ts +15 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-info.js +26 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-outcome.d.ts +1 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-outcome.js +7 -1
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-processing.d.ts +17 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-processing.js +12 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-cursor.d.ts +15 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-cursor.js +28 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-expiry.d.ts +19 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-expiry.js +23 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-context.d.ts +3 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-context.js +19 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-destination.d.ts +15 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-destination.js +38 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-record.d.ts +41 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-record.js +17 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress-state.d.ts +21 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress-state.js +39 -0
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress.d.ts +7 -37
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress.js +22 -62
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-retry.d.ts +4 -39
- package/dist/service/lambda/event-source/poll/sim-lambda-stream-retry.js +12 -64
- package/dist/service/lambda/event-source/sim-lambda-event-source-mapping.d.ts +10 -3
- package/dist/service/lambda/event-source/sim-lambda-event-source-mapping.js +12 -3
- package/dist/service/lambda/event-source/sim-lambda-stream-destination-config.d.ts +7 -0
- package/dist/service/lambda/event-source/sim-lambda-stream-destination-config.js +38 -0
- package/dist/service/lambda/event-source/stream/kinesis/sim-kinesis-event-source-streams.js +1 -0
- package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-reader.js +1 -0
- package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-shard.d.ts +1 -0
- package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-shard.js +7 -0
- package/dist/service/lambda/event-source/stream/sim-lambda-event-source-streams.d.ts +1 -0
- package/dist/service/lambda/index.d.ts +1 -0
- package/dist/service/lambda/sim-lambda-commands.js +1 -0
- package/dist/service/ses/command/authorize/sim-ses-authorizer.d.ts +9 -0
- package/dist/service/ses/command/authorize/sim-ses-authorizer.js +18 -2
- package/dist/service/ses/command/send/sim-ses-send-email.js +2 -1
- package/docs/README.md +7 -0
- package/docs/ai-skill/README.md +6 -1
- package/docs/sdk/README.md +15 -0
- package/docs/services/acm/README.md +24 -40
- package/docs/services/apigateway/README.md +52 -71
- package/docs/services/apigatewayv2/README.md +55 -74
- package/docs/services/athena/README.md +17 -26
- package/docs/services/backup/README.md +29 -39
- package/docs/services/bedrock/README.md +38 -52
- package/docs/services/cloudformation/README.md +43 -55
- package/docs/services/cloudfront/README.md +69 -95
- package/docs/services/cloudwatch/README.md +40 -54
- package/docs/services/cognito/README.md +30 -45
- package/docs/services/dynamodb/README.md +34 -51
- package/docs/services/ecr/README.md +36 -77
- package/docs/services/ecs/README.md +26 -46
- package/docs/services/elbv2/README.md +19 -29
- package/docs/services/eventbridge/README.md +14 -18
- package/docs/services/firehose/README.md +24 -32
- package/docs/services/glue/README.md +41 -78
- package/docs/services/iam/README.md +13 -15
- package/docs/services/kinesis/README.md +53 -93
- package/docs/services/kms/README.md +22 -32
- package/docs/services/lambda/README.md +112 -85
- package/docs/services/logs/README.md +41 -50
- package/docs/services/organizations/README.md +50 -85
- package/docs/services/personalize/README.md +28 -44
- package/docs/services/rekognition/README.md +26 -38
- package/docs/services/route53/README.md +17 -17
- package/docs/services/s3/README.md +47 -51
- package/docs/services/scheduler/README.md +41 -52
- package/docs/services/secretsmanager/README.md +27 -42
- package/docs/services/ses/README.md +24 -34
- package/docs/services/sns/README.md +18 -26
- package/docs/services/sqs/README.md +14 -14
- package/docs/services/ssm/README.md +13 -17
- package/docs/services/stepfunctions/README.md +18 -20
- package/docs/services/sts/README.md +32 -45
- package/docs/services/wafv2/README.md +12 -17
- package/docs/testing/README.md +228 -0
- package/docs/time/README.md +10 -0
- package/llms.txt +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { isRecord } from "../../../util/type-guard/record.js";
|
|
2
|
+
import { SimLambdaDestinationArn } from "../destination/sim-lambda-destination-arn.js";
|
|
3
|
+
import { SimLambdaInvalidParameterValueException } from "../error/sim-lambda.error.js";
|
|
4
|
+
/** Validate the same destination shape for SDK and CloudFormation requests. */
|
|
5
|
+
export function simLambdaStreamDestinationConfig(value, sourceKind) {
|
|
6
|
+
if (value === undefined)
|
|
7
|
+
return undefined;
|
|
8
|
+
if (sourceKind === "sqs") {
|
|
9
|
+
throw new SimLambdaInvalidParameterValueException("DestinationConfig is not supported for SQS event source mappings.");
|
|
10
|
+
}
|
|
11
|
+
if (!isRecord(value) ||
|
|
12
|
+
Object.keys(value).some((key) => key !== "OnFailure")) {
|
|
13
|
+
throw invalid();
|
|
14
|
+
}
|
|
15
|
+
const failure = value["OnFailure"];
|
|
16
|
+
if (failure === undefined)
|
|
17
|
+
return {};
|
|
18
|
+
if (!isRecord(failure) ||
|
|
19
|
+
Object.keys(failure).some((key) => key !== "Destination")) {
|
|
20
|
+
throw invalid();
|
|
21
|
+
}
|
|
22
|
+
const destination = failure["Destination"];
|
|
23
|
+
if (destination === undefined)
|
|
24
|
+
return { OnFailure: {} };
|
|
25
|
+
if (typeof destination !== "string")
|
|
26
|
+
throw invalid();
|
|
27
|
+
if (destination !== "") {
|
|
28
|
+
const arn = SimLambdaDestinationArn.of(destination);
|
|
29
|
+
if ((arn.service !== "sqs" && arn.service !== "sns") ||
|
|
30
|
+
arn.resource.endsWith(".fifo")) {
|
|
31
|
+
throw invalid();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return { OnFailure: { Destination: destination } };
|
|
35
|
+
}
|
|
36
|
+
function invalid() {
|
|
37
|
+
return new SimLambdaInvalidParameterValueException("DestinationConfig supports only OnFailure with a standard SQS queue or SNS topic ARN.");
|
|
38
|
+
}
|
|
@@ -29,6 +29,7 @@ export class SimDynamoDbEventSourceStreamReader {
|
|
|
29
29
|
const next = output.NextShardIterator;
|
|
30
30
|
return {
|
|
31
31
|
records: output.Records ?? [],
|
|
32
|
+
shardId: await this.shard.shardId(request),
|
|
32
33
|
next: simDynamoDbEventSourceNextPosition(next, position),
|
|
33
34
|
drained: next === undefined,
|
|
34
35
|
};
|
|
@@ -23,5 +23,6 @@ export declare class SimDynamoDbEventSourceStreamShard {
|
|
|
23
23
|
* is the shard.
|
|
24
24
|
*/
|
|
25
25
|
iteratorFor(request: SimLambdaEventSourceStreamRequest, position: SimLambdaEventSourceStreamNamedPosition): Promise<string>;
|
|
26
|
+
shardId(request: SimLambdaEventSourceStreamRequest): Promise<string>;
|
|
26
27
|
private describe;
|
|
27
28
|
}
|
|
@@ -49,6 +49,13 @@ export class SimDynamoDbEventSourceStreamShard {
|
|
|
49
49
|
}
|
|
50
50
|
return iterator.ShardIterator;
|
|
51
51
|
}
|
|
52
|
+
async shardId(request) {
|
|
53
|
+
const description = await this.describe(request);
|
|
54
|
+
const shardId = description.Shards?.[0]?.ShardId;
|
|
55
|
+
if (shardId === undefined)
|
|
56
|
+
refuse(request, "reports no shard to read records from");
|
|
57
|
+
return shardId;
|
|
58
|
+
}
|
|
52
59
|
async describe(request) {
|
|
53
60
|
const { caller, streamArn } = request;
|
|
54
61
|
const described = await this.commands.describeStream({ input: { StreamArn: streamArn } }, { caller });
|
|
@@ -84,6 +84,7 @@ export interface SimLambdaEventSourceStreamReadRequest extends SimLambdaEventSou
|
|
|
84
84
|
export interface SimLambdaEventSourceStreamProgressBatch {
|
|
85
85
|
readonly next: SimLambdaEventSourceStreamPosition;
|
|
86
86
|
readonly drained: boolean;
|
|
87
|
+
readonly shardId?: string;
|
|
87
88
|
}
|
|
88
89
|
/**
|
|
89
90
|
* What one read of a DynamoDB stream came back with.
|
|
@@ -16,3 +16,4 @@ export type { SimLambdaDynamoDbAttributeValue, SimLambdaDynamoDbImage, } from ".
|
|
|
16
16
|
export { SimLambdaStreamCascadeError } from "./event-source/stream/sim-lambda-stream-cascade.error.js";
|
|
17
17
|
export type { SimLambdaDestinationRecord, SimLambdaDestinationRequestContext, SimLambdaDestinationResponseContext, } from "./destination/sim-lambda-destination-record.js";
|
|
18
18
|
export type { SimLambdaInvocationCondition } from "./function/event-invoke/sim-lambda-event-invoke-config.js";
|
|
19
|
+
export type { SimLambdaStreamFailureRecord, SimLambdaStreamFailureCondition, } from "./event-source/poll/sim-lambda-stream-failure-record.js";
|
|
@@ -113,6 +113,7 @@ export class SimLambdaCommands {
|
|
|
113
113
|
background,
|
|
114
114
|
});
|
|
115
115
|
this.eventSourceMappings = new SimLambdaEventSourceMappingCommands({
|
|
116
|
+
destinations,
|
|
116
117
|
accountRegionScope,
|
|
117
118
|
pollers: new SimLambdaEventSourcePollers({
|
|
118
119
|
functions: this.functionLookup,
|
|
@@ -30,6 +30,15 @@ export declare class SimSesAuthorizer {
|
|
|
30
30
|
* ARN the identity is about to have.
|
|
31
31
|
*/
|
|
32
32
|
authorizeIdentity(action: string, emailIdentity: string, caller?: SimAwsCaller): SimAwsResolvedCaller;
|
|
33
|
+
/**
|
|
34
|
+
* Ensure the caller may send from one email identity and address.
|
|
35
|
+
*
|
|
36
|
+
* SES supplies the bare sender address as `ses:FromAddress`. A policy can
|
|
37
|
+
* use this key to grant one address under a verified domain identity.
|
|
38
|
+
*
|
|
39
|
+
* https://docs.aws.amazon.com/ses/latest/dg/sending-authorization-policy-examples.html#sending-authorization-policy-example-from
|
|
40
|
+
*/
|
|
41
|
+
authorizeSendEmail(emailIdentity: string, fromAddress: string, caller?: SimAwsCaller): SimAwsResolvedCaller;
|
|
33
42
|
/**
|
|
34
43
|
* Ensure the caller may perform an action on one email template.
|
|
35
44
|
*
|
|
@@ -40,6 +40,17 @@ export class SimSesAuthorizer {
|
|
|
40
40
|
authorizeIdentity(action, emailIdentity, caller) {
|
|
41
41
|
return this.authorizeResource(action, simSesIdentityArn(this.#accountRegionScope, emailIdentity), caller);
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Ensure the caller may send from one email identity and address.
|
|
45
|
+
*
|
|
46
|
+
* SES supplies the bare sender address as `ses:FromAddress`. A policy can
|
|
47
|
+
* use this key to grant one address under a verified domain identity.
|
|
48
|
+
*
|
|
49
|
+
* https://docs.aws.amazon.com/ses/latest/dg/sending-authorization-policy-examples.html#sending-authorization-policy-example-from
|
|
50
|
+
*/
|
|
51
|
+
authorizeSendEmail(emailIdentity, fromAddress, caller) {
|
|
52
|
+
return this.authorizeResource("ses:SendEmail", simSesIdentityArn(this.#accountRegionScope, emailIdentity), caller, { "ses:FromAddress": fromAddress });
|
|
53
|
+
}
|
|
43
54
|
/**
|
|
44
55
|
* Ensure the caller may perform an action on one email template.
|
|
45
56
|
*
|
|
@@ -73,8 +84,13 @@ export class SimSesAuthorizer {
|
|
|
73
84
|
authorizeNoResource(action, caller) {
|
|
74
85
|
return this.authorizeResource(action, noResource, caller);
|
|
75
86
|
}
|
|
76
|
-
authorizeResource(action, resource, caller) {
|
|
77
|
-
const decision = this.#iam.authorize({
|
|
87
|
+
authorizeResource(action, resource, caller, conditionContext) {
|
|
88
|
+
const decision = this.#iam.authorize({
|
|
89
|
+
action,
|
|
90
|
+
resource,
|
|
91
|
+
caller,
|
|
92
|
+
conditionContext,
|
|
93
|
+
});
|
|
78
94
|
if (decision.isDenied) {
|
|
79
95
|
throw new SimIamAccessDenied({
|
|
80
96
|
principal: decision.caller.principal,
|
|
@@ -42,8 +42,9 @@ export class SimSesSendEmail {
|
|
|
42
42
|
handle(command, options) {
|
|
43
43
|
const input = command.input;
|
|
44
44
|
const fromEmailAddress = requiredSimSesFromAddress(input.FromEmailAddress);
|
|
45
|
+
const bareFromAddress = simSesBareAddress(fromEmailAddress);
|
|
45
46
|
refuseUnsimulatedSendInput(input);
|
|
46
|
-
this.#authorizer.
|
|
47
|
+
this.#authorizer.authorizeSendEmail(this.#identities.covering(bareFromAddress), bareFromAddress, options?.caller);
|
|
47
48
|
const destination = readDestination(input.Destination);
|
|
48
49
|
const recipients = allRecipients(destination);
|
|
49
50
|
if (recipients.length === 0) {
|
package/docs/README.md
CHANGED
|
@@ -15,6 +15,12 @@ npm install --save-dev @kensio/yulin
|
|
|
15
15
|
|
|
16
16
|
## Choose how to use Yulin
|
|
17
17
|
|
|
18
|
+
Start with [test suite setup](https://yulinsim.dev/testing/) when adding Yulin to an application's
|
|
19
|
+
tests. Create one simulated environment, deploy the application's infrastructure, and install SDK
|
|
20
|
+
interception for the whole suite. Tests then use that shared environment as they would use an AWS
|
|
21
|
+
account or a container-based simulator. Put the smaller set of tests that control simulated time in
|
|
22
|
+
an isolated group because the clock belongs to the environment too.
|
|
23
|
+
|
|
18
24
|
Start with [AWS SDK interception](https://yulinsim.dev/sdk/) when the code under test already uses an
|
|
19
25
|
AWS SDK client. Yulin intercepts the client's `send` calls and returns responses from a simulated
|
|
20
26
|
service. The application code continues to use the AWS SDK normally.
|
|
@@ -81,4 +87,5 @@ credential, or run other work that depends on time passing.
|
|
|
81
87
|
- [Non-AWS dependencies](https://yulinsim.dev/non-aws-dependencies/ "Dependencies Yulin does not simulate usage docs")
|
|
82
88
|
- [Serving on localhost](https://yulinsim.dev/serve/ "Serving simulated AWS on localhost usage docs")
|
|
83
89
|
- [Simulated time](https://yulinsim.dev/time/ "Simulated time usage docs")
|
|
90
|
+
- [Test suite setup](https://yulinsim.dev/testing/ "Sharing one Yulin environment across a test suite")
|
|
84
91
|
- [Terraform](https://yulinsim.dev/terraform/ "Deploying Terraform into simulated AWS usage docs")
|
package/docs/ai-skill/README.md
CHANGED
|
@@ -37,10 +37,15 @@ The skill tells an agent how to:
|
|
|
37
37
|
- control simulated time
|
|
38
38
|
- inspect simulated state in assertions
|
|
39
39
|
- match simulated service errors by `name`
|
|
40
|
-
- share
|
|
40
|
+
- share one simulated deployment and SDK interception across a whole test suite
|
|
41
|
+
- give tests that control simulated time their own isolated Yulin environment
|
|
41
42
|
- invoke code through a simulated Lambda function with its configured role and environment
|
|
42
43
|
- treat unsupported behaviour as a gap to report, not behaviour to guess
|
|
43
44
|
|
|
45
|
+
The [test suite setup guide](https://yulinsim.dev/testing/) states the default explicitly. An agent
|
|
46
|
+
should set Yulin up once for the suite and let tests share it as they would share an AWS account or a
|
|
47
|
+
container-based simulator. Tests that move the shared simulated clock are the main exception.
|
|
48
|
+
|
|
44
49
|
## Give the agent access to the API docs
|
|
45
50
|
|
|
46
51
|
The skill covers testing choices. The service guides document Yulin's APIs and supported AWS
|
package/docs/sdk/README.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
`SimSdk` routes AWS SDK for JavaScript v3 commands to Yulin. Use it to test code that already sends
|
|
4
4
|
commands through AWS SDK clients.
|
|
5
5
|
|
|
6
|
+
## Install interception in suite setup
|
|
7
|
+
|
|
8
|
+
Application tests should normally create one `SimSdk` in Vitest suite setup and keep its class
|
|
9
|
+
interceptions installed for the whole suite. Every SDK client then reaches the same simulated state,
|
|
10
|
+
including clients created in different test files.
|
|
11
|
+
|
|
12
|
+
The [test suite setup guide](https://yulinsim.dev/testing/) shows how to share one in-process
|
|
13
|
+
environment across Vitest files. It also covers the worker and isolation settings this requires.
|
|
14
|
+
A separate `SimSdk` for each test or file remains supported when a case needs an empty environment.
|
|
15
|
+
Tests that control the simulation's clock should use a separate `SimSdk` so their time changes cannot
|
|
16
|
+
affect the shared suite.
|
|
17
|
+
|
|
6
18
|
## Intercept a client
|
|
7
19
|
|
|
8
20
|
Create a `SimSdk`, intercept a client class, and run the code under test:
|
|
@@ -147,6 +159,9 @@ Restore an interception before later code needs the client's original `send` met
|
|
|
147
159
|
- Call `simSdk.restoreAll()` to restore every client intercepted by that `SimSdk`.
|
|
148
160
|
- Declare `SimSdk` or an interception handle with `using` to restore it when the scope ends.
|
|
149
161
|
|
|
162
|
+
A suite-wide interception stays installed until the test worker exits. Do not restore it in a
|
|
163
|
+
per-file `afterAll`, since later files use the same interception and simulated state.
|
|
164
|
+
|
|
150
165
|
## Limit the intercepted commands
|
|
151
166
|
|
|
152
167
|
An interception handles every command by default. Pass an allow list when a test should accept only
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Simulated ACM
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Yulin simulates AWS Certificate Manager (ACM) in memory. You can request and inspect certificates,
|
|
4
|
+
exercise DNS validation against simulated Route53, and deploy certificate resources through
|
|
5
|
+
simulated CloudFormation.
|
|
6
6
|
|
|
7
7
|
## Prerequisites
|
|
8
8
|
|
|
@@ -12,9 +12,8 @@ with simulated CloudFormation.
|
|
|
12
12
|
|
|
13
13
|
## Request a certificate
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
3. Call `listCertificates` with a `ListCertificatesCommand` to confirm the certificate exists.
|
|
15
|
+
Create a `SimAws` instance, request a certificate, then list the certificates in that account and
|
|
16
|
+
region:
|
|
18
17
|
|
|
19
18
|
```typescript sim-acm-request-certificate
|
|
20
19
|
/**
|
|
@@ -145,9 +144,8 @@ for (const validation of domainValidationOptions) {
|
|
|
145
144
|
}
|
|
146
145
|
```
|
|
147
146
|
|
|
148
|
-
For DNS validation,
|
|
149
|
-
|
|
150
|
-
tests.
|
|
147
|
+
For DNS validation, ACM returns a deterministic CNAME record for the primary domain and each subject
|
|
148
|
+
alternative name. Tests can assert on these records directly.
|
|
151
149
|
|
|
152
150
|
For EMAIL validation, the validation method is recorded but no DNS resource record is returned.
|
|
153
151
|
|
|
@@ -187,11 +185,8 @@ console.log(validation?.ResourceRecord);
|
|
|
187
185
|
|
|
188
186
|
## Wait for certificate issuance
|
|
189
187
|
|
|
190
|
-
Requested certificates start
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
If your test needs the issued state, wait for background tasks to complete before describing the
|
|
194
|
-
certificate.
|
|
188
|
+
Requested certificates start as `PENDING_VALIDATION`. Wait for background tasks before asserting
|
|
189
|
+
that a certificate is `ISSUED`.
|
|
195
190
|
|
|
196
191
|
> **Note:** Where a simulated Route53 hosted zone covers the certificate domain, issuance waits for
|
|
197
192
|
> DNS validation first.
|
|
@@ -233,19 +228,14 @@ console.log(describeOutput.Certificate?.IssuedAt);
|
|
|
233
228
|
|
|
234
229
|
## Validate a certificate against simulated Route53
|
|
235
230
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
By default, the rules are:
|
|
231
|
+
ACM requires the validation CNAME when simulated Route53 is authoritative for the domain. The
|
|
232
|
+
default rules are:
|
|
240
233
|
|
|
241
234
|
- If a simulated Route53 hosted zone covers the certificate domain, the certificate waits for its validation record.
|
|
242
235
|
- If no hosted zone covers the domain, the certificate is issued as soon as background tasks drain.
|
|
243
236
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
[Two methods override that default](#override-when-validation-is-required) where it doesn't suit
|
|
248
|
-
your test.
|
|
237
|
+
This lets templates refer to externally managed hosted zones without leaving certificates pending.
|
|
238
|
+
[Two methods override the default](#override-when-validation-is-required).
|
|
249
239
|
|
|
250
240
|
```typescript sim-acm-dns-validation
|
|
251
241
|
/**
|
|
@@ -322,11 +312,9 @@ const issuedOutput = await simAws.acm().describeCertificate(
|
|
|
322
312
|
console.log(issuedOutput.Certificate?.Status); // ISSUED
|
|
323
313
|
```
|
|
324
314
|
|
|
325
|
-
Each domain
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
`DescribeCertificateCommand` reports `SUCCESS` for validated domains and `PENDING_VALIDATION` for
|
|
329
|
-
the rest.
|
|
315
|
+
Each domain is validated separately. A certificate is issued when every domain covered by a
|
|
316
|
+
simulated hosted zone has its validation record. `DescribeCertificateCommand` reports `SUCCESS` for
|
|
317
|
+
validated domains and `PENDING_VALIDATION` for the rest.
|
|
330
318
|
|
|
331
319
|
Hosted zones are looked up across every simulated account, matching real ACM validating against
|
|
332
320
|
public DNS. A certificate in one account can be validated by a hosted zone in another.
|
|
@@ -554,18 +542,16 @@ await scopedAcm.requestCertificate(
|
|
|
554
542
|
);
|
|
555
543
|
```
|
|
556
544
|
|
|
557
|
-
Each `SimAws` instance has its own isolated state.
|
|
545
|
+
Each `SimAws` instance has its own isolated state. Application tests should normally use the instance
|
|
546
|
+
from their shared [test suite setup](https://yulinsim.dev/testing/). A fresh instance remains useful
|
|
547
|
+
when a test specifically needs an empty simulated account.
|
|
558
548
|
|
|
559
549
|
## Register a certificate with a chosen ARN
|
|
560
550
|
|
|
561
|
-
`RequestCertificateCommand` allocates
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
The usual reason is a CDK app that creates its certificate in one stack and uses it in another. The
|
|
566
|
-
ARN crosses between the two as a plain string, and the stack using it carries that ARN into its
|
|
567
|
-
synthesized template. Simulated CloudFront checks the certificate before it creates a Distribution,
|
|
568
|
-
so registering the certificate first lets the template deploy as it is, with no rewriting.
|
|
551
|
+
`RequestCertificateCommand` allocates the ARN. If a fixture or another stack already provides the
|
|
552
|
+
ARN, register that certificate during test setup. This is useful when one CDK stack creates a
|
|
553
|
+
certificate and another uses its ARN. Simulated CloudFront can then resolve the certificate without
|
|
554
|
+
changing the synthesized template.
|
|
569
555
|
|
|
570
556
|
```typescript sim-acm-register-certificate
|
|
571
557
|
/**
|
|
@@ -791,9 +777,7 @@ A `HostedZoneId` that names a hosted zone the simulator doesn't hold is skipped
|
|
|
791
777
|
|
|
792
778
|
If a hosted zone covers the domain but the validation record never appears, the stack fails rather than hanging. Real CloudFormation sits in `CREATE_IN_PROGRESS` for hours before timing out, which is of little use in a test. The resource fails immediately and names the record it waited for.
|
|
793
779
|
|
|
794
|
-
##
|
|
795
|
-
|
|
796
|
-
Simulated ACM supports:
|
|
780
|
+
## Supported operations
|
|
797
781
|
|
|
798
782
|
- `RequestCertificateCommand`, `DescribeCertificateCommand`, and `ListCertificatesCommand`
|
|
799
783
|
- DNS validation against records in simulated Route53
|