@kensio/yulin 1.21.6 → 1.21.8
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/eventbridge/cfn/bus/sim-cfn-event-bus-creator.js +1 -0
- package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.d.ts +4 -0
- package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.js +26 -1
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-creator.js +3 -1
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-properties.d.ts +0 -7
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-properties.js +0 -20
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-unsimulated-properties.d.ts +13 -0
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-unsimulated-properties.js +59 -0
- package/dist/service/eventbridge/cfn/sim-cfn-event-bridge-resource-error.d.ts +1 -1
- package/dist/service/eventbridge/cfn/sim-cfn-event-bridge-resource-error.js +1 -1
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-properties.js +1 -1
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.d.ts +3 -2
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.js +25 -3
- 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/dist/service/sns/cfn/topic/sim-cfn-sns-topic-creator.js +1 -0
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-properties.d.ts +9 -4
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-properties.js +18 -6
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-property-names.d.ts +10 -0
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-property-names.js +16 -1
- package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-creator.js +1 -1
- package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-properties.d.ts +11 -6
- package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-properties.js +18 -9
- package/docs/README.md +40 -4
- package/docs/ai-skill/README.md +57 -54
- package/docs/cli/README.md +84 -94
- package/docs/factories/README.md +42 -54
- package/docs/lint/README.md +41 -67
- package/docs/non-aws-dependencies/README.md +72 -168
- package/docs/sdk/README.md +109 -95
- package/docs/serve/README.md +192 -898
- 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 +24 -20
- 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 +60 -80
- 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 +31 -33
- package/docs/services/sqs/README.md +14 -14
- package/docs/services/ssm/README.md +19 -21
- 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/terraform/README.md +108 -126
- package/docs/testing/README.md +228 -0
- package/docs/time/README.md +87 -117
- package/llms.txt +2 -1
- package/package.json +1 -1
package/docs/README.md
CHANGED
|
@@ -1,7 +1,42 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Yulin documentation
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Yulin runs simulated AWS services inside a Node.js process. Tests can use AWS SDK clients,
|
|
4
|
+
CloudFormation templates, or direct service calls without connecting to AWS. Each `SimAws` instance
|
|
5
|
+
holds its own state in memory.
|
|
6
|
+
|
|
7
|
+
Yulin implements selected AWS behaviour. The service pages describe what each simulation supports
|
|
8
|
+
and where it differs from AWS.
|
|
9
|
+
|
|
10
|
+
## Install Yulin
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install --save-dev @kensio/yulin
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Choose how to use Yulin
|
|
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
|
+
|
|
24
|
+
Start with [AWS SDK interception](https://yulinsim.dev/sdk/) when the code under test already uses an
|
|
25
|
+
AWS SDK client. Yulin intercepts the client's `send` calls and returns responses from a simulated
|
|
26
|
+
service. The application code continues to use the AWS SDK normally.
|
|
27
|
+
|
|
28
|
+
Use [event factories](https://yulinsim.dev/factories/) when a test calls a handler directly and only
|
|
29
|
+
needs an AWS event object. The factories fill in fields that the test does not care about.
|
|
30
|
+
|
|
31
|
+
Use [CloudFormation](https://yulinsim.dev/services/cloudformation/) to build a simulation from a
|
|
32
|
+
template. This also works with templates synthesized by AWS CDK and AWS SAM.
|
|
33
|
+
|
|
34
|
+
Use the [localhost server](https://yulinsim.dev/serve/) when the code runs in another process or
|
|
35
|
+
sends HTTP requests. The [AWS CLI guide](https://yulinsim.dev/cli/) explains how to point AWS CLI
|
|
36
|
+
commands at the same endpoint.
|
|
37
|
+
|
|
38
|
+
Read [simulated time](https://yulinsim.dev/time/) when a test needs to advance a schedule, expire a
|
|
39
|
+
credential, or run other work that depends on time passing.
|
|
5
40
|
|
|
6
41
|
## Service documentation
|
|
7
42
|
|
|
@@ -42,7 +77,7 @@ behaviour and includes example code that can be copied into tests or local devel
|
|
|
42
77
|
- [STS](https://yulinsim.dev/services/sts/ "Simulated STS usage docs")
|
|
43
78
|
- [WAFv2](https://yulinsim.dev/services/wafv2/ "Simulated WAFv2 usage docs")
|
|
44
79
|
|
|
45
|
-
## Feature
|
|
80
|
+
## Feature guides
|
|
46
81
|
|
|
47
82
|
- [AI skill](https://yulinsim.dev/ai-skill/ "Yulin AI skill usage docs")
|
|
48
83
|
- [The AWS CLI](https://yulinsim.dev/cli/ "The AWS CLI against simulated AWS usage docs")
|
|
@@ -52,4 +87,5 @@ behaviour and includes example code that can be copied into tests or local devel
|
|
|
52
87
|
- [Non-AWS dependencies](https://yulinsim.dev/non-aws-dependencies/ "Dependencies Yulin does not simulate usage docs")
|
|
53
88
|
- [Serving on localhost](https://yulinsim.dev/serve/ "Serving simulated AWS on localhost usage docs")
|
|
54
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")
|
|
55
91
|
- [Terraform](https://yulinsim.dev/terraform/ "Deploying Terraform into simulated AWS usage docs")
|
package/docs/ai-skill/README.md
CHANGED
|
@@ -1,69 +1,72 @@
|
|
|
1
|
-
# AI skill
|
|
1
|
+
# AI skill for Yulin
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[Agent Skills specification](https://agentskills.io/specification) and installable into Claude Code,
|
|
6
|
-
Codex CLI, Cursor, VS Code and anything else that reads one. It covers the part that lives outside
|
|
7
|
-
the API.
|
|
3
|
+
The `yulin-aws-simulation` skill gives coding agents instructions for using Yulin in tests and local
|
|
4
|
+
development.
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
and what its commands take. The skill says what to do with that. An AI agent reaching for Yulin
|
|
11
|
-
without it tends to build a harness around the simulator, leave hand-rolled stubs in place beside
|
|
12
|
-
it, or write an `instanceof` check against an SDK exception class that passes in production and
|
|
13
|
-
fails against the simulation.
|
|
6
|
+
## Install the skill
|
|
14
7
|
|
|
15
|
-
|
|
8
|
+
Install it in the current project's `.agents/skills/` directory:
|
|
16
9
|
|
|
17
10
|
```bash
|
|
18
11
|
npx @kensio/skills add yulin-aws-simulation
|
|
19
12
|
```
|
|
20
13
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
Codex CLI, Cursor, VS Code, and Gemini CLI read skills from that directory. To install the skill for
|
|
15
|
+
Claude Code, add `--agent claude`. Add `--user` to install it for every project under your user
|
|
16
|
+
account.
|
|
24
17
|
|
|
25
|
-
|
|
18
|
+
Claude Code can also install the skill from the Kensio plugin marketplace:
|
|
26
19
|
|
|
27
20
|
```bash
|
|
28
21
|
claude plugin marketplace add KensioSoftware/kensio.ai
|
|
29
22
|
claude plugin install yulin-aws-simulation@kensio
|
|
30
23
|
```
|
|
31
24
|
|
|
32
|
-
|
|
33
|
-
[kensio.ai release](https://github.com/KensioSoftware/kensio.ai/releases)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
## What
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
25
|
+
The skill is also published as the `@kensio/yulin-aws-simulation` npm package. Each
|
|
26
|
+
[kensio.ai release](https://github.com/KensioSoftware/kensio.ai/releases) includes a zip archive for
|
|
27
|
+
installations that cannot reach a package registry.
|
|
28
|
+
|
|
29
|
+
## What the skill teaches
|
|
30
|
+
|
|
31
|
+
The skill tells an agent how to:
|
|
32
|
+
|
|
33
|
+
- use `SimAws` and `SimSdk` directly
|
|
34
|
+
- deploy the same synthesized CDK template in tests and local development
|
|
35
|
+
- choose between deploying a resource and registering one directly
|
|
36
|
+
- intercept AWS SDK clients without keeping separate hand-written stubs
|
|
37
|
+
- control simulated time
|
|
38
|
+
- inspect simulated state in assertions
|
|
39
|
+
- match simulated service errors by `name`
|
|
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
|
|
42
|
+
- invoke code through a simulated Lambda function with its configured role and environment
|
|
43
|
+
- treat unsupported behaviour as a gap to report, not behaviour to guess
|
|
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
|
+
|
|
49
|
+
## Give the agent access to the API docs
|
|
50
|
+
|
|
51
|
+
The skill covers testing choices. The service guides document Yulin's APIs and supported AWS
|
|
52
|
+
behaviour.
|
|
53
|
+
|
|
54
|
+
The skill points agents to [yulinsim.dev/llms.txt](https://yulinsim.dev/llms.txt). That file indexes
|
|
55
|
+
plain Markdown versions of every guide on the documentation site. Append `llms.txt` to a page URL to
|
|
56
|
+
read that page as Markdown.
|
|
57
|
+
|
|
58
|
+
The npm package includes the same documentation under `node_modules/@kensio/yulin/docs/`. Its index
|
|
59
|
+
is `node_modules/@kensio/yulin/llms.txt`. These files match the installed Yulin version and remain
|
|
60
|
+
available without network access. Some search tools skip `node_modules` unless the path is given
|
|
61
|
+
explicitly.
|
|
62
|
+
|
|
63
|
+
## Limitations
|
|
64
|
+
|
|
65
|
+
- The skill does not replace the service guides. An agent still needs the relevant guide when it
|
|
66
|
+
works with a service command, event shape, or limitation.
|
|
67
|
+
- The skill is versioned separately from Yulin. The documentation included in the installed Yulin
|
|
68
|
+
package is the reference for that package version.
|
|
69
|
+
|
|
70
|
+
The skill source is available at
|
|
71
|
+
[kensio.ai/skills/yulin-aws-simulation](https://kensio.ai/skills/yulin-aws-simulation) under the
|
|
72
|
+
Apache-2.0 licence.
|
package/docs/cli/README.md
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
# AWS CLI
|
|
1
|
+
# Use the AWS CLI with Yulin
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Yulin's twenty-five SDK-facing services answer it.
|
|
3
|
+
Point the AWS CLI at a served `SimAws` instance to run supported commands against simulated AWS.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
covers the way in from a shell.
|
|
5
|
+
## Start a local endpoint
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Serving binds a simulated environment to a port. A served request runs as whoever signed it, and the
|
|
12
|
-
access key to sign the first one comes from simulated IAM in the process that built the environment:
|
|
7
|
+
Create an IAM user and access key in the simulation, then pass the same `SimAws` instance to
|
|
8
|
+
`serveSimAws`:
|
|
13
9
|
|
|
14
10
|
```typescript sim-cli-endpoint
|
|
15
11
|
/**
|
|
@@ -53,12 +49,11 @@ console.log(
|
|
|
53
49
|
console.log(`export AWS_DEFAULT_REGION=${simAws.defaultRegionName}`);
|
|
54
50
|
```
|
|
55
51
|
|
|
56
|
-
|
|
57
|
-
is free.
|
|
52
|
+
Set `port` when scripts need a stable endpoint. If you omit it, Yulin chooses an available port.
|
|
58
53
|
|
|
59
|
-
##
|
|
54
|
+
## Configure the CLI
|
|
60
55
|
|
|
61
|
-
|
|
56
|
+
Export the endpoint, simulated credentials, and Region printed by the setup script:
|
|
62
57
|
|
|
63
58
|
```bash
|
|
64
59
|
export AWS_ENDPOINT_URL=http://localhost:8787
|
|
@@ -67,8 +62,8 @@ export AWS_SECRET_ACCESS_KEY=RzIvKRp1sd5yXfEifA1twsUTd4GlHL5JpzvECpox
|
|
|
67
62
|
export AWS_DEFAULT_REGION=us-east-1
|
|
68
63
|
```
|
|
69
64
|
|
|
70
|
-
`sts get-caller-identity`
|
|
71
|
-
|
|
65
|
+
Run `sts get-caller-identity` to check the connection. It returns the simulated principal that owns
|
|
66
|
+
the access key:
|
|
72
67
|
|
|
73
68
|
```bash
|
|
74
69
|
aws sts get-caller-identity
|
|
@@ -79,16 +74,15 @@ aws sts get-caller-identity
|
|
|
79
74
|
}
|
|
80
75
|
```
|
|
81
76
|
|
|
82
|
-
The credentials
|
|
83
|
-
|
|
77
|
+
The credentials must come from simulated IAM. Yulin rejects an unknown key with `403 Forbidden`.
|
|
78
|
+
It also rejects unsigned AWS API requests.
|
|
84
79
|
|
|
85
|
-
A Region is required
|
|
86
|
-
|
|
80
|
+
A Region is required. Changing `AWS_DEFAULT_REGION` selects another simulated Region. For example,
|
|
81
|
+
a queue created in `eu-west-2` is absent from `us-east-1`.
|
|
87
82
|
|
|
88
|
-
###
|
|
83
|
+
### Use a named profile
|
|
89
84
|
|
|
90
|
-
|
|
91
|
-
of the ambient environment:
|
|
85
|
+
You can put the endpoint and credentials in the AWS CLI config:
|
|
92
86
|
|
|
93
87
|
```ini
|
|
94
88
|
[profile sim]
|
|
@@ -98,12 +92,12 @@ aws_access_key_id = AKIAVEXOWARWMKBOA0MP
|
|
|
98
92
|
aws_secret_access_key = RzIvKRp1sd5yXfEifA1twsUTd4GlHL5JpzvECpox
|
|
99
93
|
```
|
|
100
94
|
|
|
101
|
-
`aws --profile sim sts get-caller-identity`
|
|
102
|
-
|
|
103
|
-
|
|
95
|
+
Now `aws --profile sim sts get-caller-identity` reaches Yulin. The profile must contain its own
|
|
96
|
+
credentials because the CLI stops reading `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` after you
|
|
97
|
+
pass `--profile`.
|
|
104
98
|
|
|
105
|
-
`role_arn` and `source_profile` work
|
|
106
|
-
with the
|
|
99
|
+
Profiles with `role_arn` and `source_profile` also work. The CLI calls simulated STS and signs later
|
|
100
|
+
requests with the returned role session:
|
|
107
101
|
|
|
108
102
|
```ini
|
|
109
103
|
[profile reader]
|
|
@@ -113,10 +107,10 @@ role_arn = arn:aws:iam::888888888888:role/Reader
|
|
|
113
107
|
source_profile = sim
|
|
114
108
|
```
|
|
115
109
|
|
|
116
|
-
##
|
|
110
|
+
## Create more simulated identities
|
|
117
111
|
|
|
118
|
-
Only the first key
|
|
119
|
-
|
|
112
|
+
Only the first access key needs to come from the setup process. Use `aws iam` to create more users
|
|
113
|
+
and keys through the endpoint:
|
|
120
114
|
|
|
121
115
|
```bash
|
|
122
116
|
aws iam create-user --user-name shopper
|
|
@@ -125,8 +119,8 @@ aws iam put-user-policy --user-name shopper --policy-name read-buckets \
|
|
|
125
119
|
aws iam create-access-key --user-name shopper
|
|
126
120
|
```
|
|
127
121
|
|
|
128
|
-
`create-access-key`
|
|
129
|
-
|
|
122
|
+
`create-access-key` returns the secret once. Requests signed with the new key run as the new user and
|
|
123
|
+
are checked against its simulated IAM policies:
|
|
130
124
|
|
|
131
125
|
```bash
|
|
132
126
|
aws s3api create-bucket --bucket nope
|
|
@@ -136,8 +130,8 @@ arn:aws:iam::888888888888:user/shopper is not authorized to perform: s3:CreateBu
|
|
|
136
130
|
arn:aws:s3:::nope
|
|
137
131
|
```
|
|
138
132
|
|
|
139
|
-
`aws sts assume-role`
|
|
140
|
-
|
|
133
|
+
`aws sts assume-role` returns temporary credentials. Export the access key, secret key, and session
|
|
134
|
+
token to run later commands as the role:
|
|
141
135
|
|
|
142
136
|
```bash
|
|
143
137
|
aws sts assume-role --role-arn arn:aws:iam::888888888888:role/Reader --role-session-name probe
|
|
@@ -146,17 +140,12 @@ export AWS_SECRET_ACCESS_KEY=jm2N56vfVtLgJEo11OtbIXbgnJBgxpUMrszPrQdl
|
|
|
146
140
|
export AWS_SESSION_TOKEN=11568oBDksY9czECUMiAWk9tzmvG7zlQNjtLI1WmhZFS...
|
|
147
141
|
```
|
|
148
142
|
|
|
149
|
-
The
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
## What answers
|
|
143
|
+
The credentials expire according to [simulated time](https://yulinsim.dev/time/). Requests fail once
|
|
144
|
+
the `SimAws` clock passes their expiry.
|
|
153
145
|
|
|
154
|
-
|
|
155
|
-
along with the AWS JSON protocol services: DynamoDB, DynamoDB Streams, SQS, Cognito Identity
|
|
156
|
-
Provider, EventBridge, ECS, SSM, ACM, CloudWatch, CloudWatch Logs, KMS, Secrets Manager and
|
|
157
|
-
Rekognition.
|
|
146
|
+
## Run service commands
|
|
158
147
|
|
|
159
|
-
|
|
148
|
+
Use ordinary AWS CLI commands after the endpoint is configured:
|
|
160
149
|
|
|
161
150
|
```bash
|
|
162
151
|
aws s3 cp ./index.html s3://widgets/index.html
|
|
@@ -168,16 +157,12 @@ aws secretsmanager get-secret-value --secret-id shop/db --query SecretString --o
|
|
|
168
157
|
aws logs describe-log-groups --query 'logGroups[].logGroupName' --output text
|
|
169
158
|
```
|
|
170
159
|
|
|
171
|
-
`--query
|
|
172
|
-
client-side over an ordinary AWS response.
|
|
160
|
+
Client-side CLI options such as `--query` and `--output text` work with simulated responses.
|
|
173
161
|
|
|
174
|
-
|
|
175
|
-
|
|
162
|
+
The [localhost server guide](https://yulinsim.dev/serve/#which-services-answer) lists the operations
|
|
163
|
+
available for each service. Yulin returns `NotImplemented` for other operations.
|
|
176
164
|
|
|
177
|
-
##
|
|
178
|
-
|
|
179
|
-
Each of these is CLI behaviour, and each catches people out against real AWS too. They are collected
|
|
180
|
-
here because a simulated endpoint is often where someone meets them first.
|
|
165
|
+
## Commands that need extra configuration
|
|
181
166
|
|
|
182
167
|
### `--payload` needs `--cli-binary-format`
|
|
183
168
|
|
|
@@ -189,7 +174,7 @@ aws lambda invoke --function-name orders --payload '{"id":1}' out.json
|
|
|
189
174
|
aws: [ERROR]: Invalid base64: "{"id":1}"
|
|
190
175
|
```
|
|
191
176
|
|
|
192
|
-
Pass `--cli-binary-format raw-in-base64-out`
|
|
177
|
+
Pass `--cli-binary-format raw-in-base64-out` to send the JSON payload:
|
|
193
178
|
|
|
194
179
|
```bash
|
|
195
180
|
aws lambda invoke --function-name orders --payload '{"id":1}' \
|
|
@@ -197,22 +182,21 @@ aws lambda invoke --function-name orders --payload '{"id":1}' \
|
|
|
197
182
|
cat out.json
|
|
198
183
|
```
|
|
199
184
|
|
|
200
|
-
`--invocation-type Event`
|
|
201
|
-
|
|
185
|
+
`--invocation-type Event` returns `202` before the handler runs. Code in the server process can call
|
|
186
|
+
`simAws.backgroundTasksComplete()` before inspecting the result.
|
|
202
187
|
|
|
203
188
|
### S3 addressing style
|
|
204
189
|
|
|
205
|
-
The CLI
|
|
206
|
-
|
|
190
|
+
The CLI's default `auto` addressing style sends path-style requests to custom endpoints. Yulin
|
|
191
|
+
supports that form. AWS SDK clients need `forcePathStyle: true` when they use the served endpoint.
|
|
207
192
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
`404`.
|
|
193
|
+
Do not set `addressing_style = virtual` for the CLI profile. Yulin does not route virtual-hosted S3
|
|
194
|
+
API requests through the general endpoint.
|
|
211
195
|
|
|
212
196
|
### `aws cloudformation deploy` uses change sets
|
|
213
197
|
|
|
214
|
-
|
|
215
|
-
|
|
198
|
+
The CLI implements `aws cloudformation deploy` with change sets. Yulin does not serve
|
|
199
|
+
`CreateChangeSet`, so the command fails:
|
|
216
200
|
|
|
217
201
|
```bash
|
|
218
202
|
aws cloudformation deploy --stack-name site --template-file template.json
|
|
@@ -221,26 +205,25 @@ aws: [ERROR]: An error occurred (NotImplemented) when calling the CreateChangeSe
|
|
|
221
205
|
Simulated CloudFormation does not serve CreateChangeSet
|
|
222
206
|
```
|
|
223
207
|
|
|
224
|
-
`create-stack` and `describe-stacks`
|
|
225
|
-
|
|
208
|
+
Use `create-stack` and `describe-stacks` instead. `create-stack` returns while resource creation runs
|
|
209
|
+
in the background.
|
|
226
210
|
|
|
227
|
-
###
|
|
211
|
+
### Presigned S3 URLs
|
|
228
212
|
|
|
229
|
-
`aws s3 presign`
|
|
230
|
-
general endpoint has no Bucket in it for the endpoint to route on. Point the one command at
|
|
231
|
-
simulated S3's own hostname on the served port:
|
|
213
|
+
Run `aws s3 presign` against the configured endpoint:
|
|
232
214
|
|
|
233
215
|
```bash
|
|
234
|
-
aws
|
|
216
|
+
aws s3 presign s3://widgets/one.txt
|
|
235
217
|
```
|
|
236
218
|
|
|
237
|
-
The URL
|
|
238
|
-
|
|
219
|
+
The returned URL includes a signed credential scope, which Yulin uses to route the request to S3.
|
|
220
|
+
It works with `curl`, a browser, or another HTTP client. The S3 guide also covers
|
|
221
|
+
[presigned URLs built with the SDK](https://yulinsim.dev/services/s3/#presigned-urls).
|
|
239
222
|
|
|
240
223
|
### A bad key looks like an XML parse failure
|
|
241
224
|
|
|
242
|
-
STS, IAM and ELBv2
|
|
243
|
-
|
|
225
|
+
STS, IAM, and ELBv2 return XML responses. Yulin currently returns a rejected signature as JSON for
|
|
226
|
+
these services, so the CLI reports an XML parsing error:
|
|
244
227
|
|
|
245
228
|
```bash
|
|
246
229
|
aws sts get-caller-identity
|
|
@@ -250,18 +233,38 @@ XML received. Further retries may succeed:
|
|
|
250
233
|
b'{"Message":"Forbidden"}'
|
|
251
234
|
```
|
|
252
235
|
|
|
253
|
-
`Forbidden`
|
|
254
|
-
rejection as a plain `403`.
|
|
236
|
+
The `{"Message":"Forbidden"}` body means that the access key or signature was rejected. Other served
|
|
237
|
+
services report the rejection as a plain `403`.
|
|
238
|
+
|
|
239
|
+
## Available functionality
|
|
240
|
+
|
|
241
|
+
The served AWS API supports CLI operations for these services:
|
|
242
|
+
|
|
243
|
+
- ACM
|
|
244
|
+
- CloudFormation
|
|
245
|
+
- CloudWatch metrics and CloudWatch Logs
|
|
246
|
+
- Cognito Identity Provider
|
|
247
|
+
- DynamoDB and DynamoDB Streams
|
|
248
|
+
- ECS and Elastic Load Balancing v2
|
|
249
|
+
- EventBridge
|
|
250
|
+
- IAM and STS
|
|
251
|
+
- KMS and Secrets Manager
|
|
252
|
+
- Lambda
|
|
253
|
+
- Rekognition
|
|
254
|
+
- S3
|
|
255
|
+
- SNS and SQS
|
|
256
|
+
- SSM Parameter Store
|
|
257
|
+
|
|
258
|
+
Profiles and role assumption work with the endpoint. Client-side features such as JMESPath queries
|
|
259
|
+
and output formatting work with simulated responses.
|
|
255
260
|
|
|
256
261
|
## Limitations
|
|
257
262
|
|
|
258
|
-
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
- An operation a served service has not implemented is refused as `NotImplemented`. That is a
|
|
264
|
-
separate answer from the protocol refusal above. `aws iam list-users` reports
|
|
263
|
+
- Services absent from the list above are not available through the general AWS API endpoint. Use
|
|
264
|
+
`SimAws` directly or [SDK interception](https://yulinsim.dev/sdk/) where the service supports it.
|
|
265
|
+
Simulated ECR exposes only an in-process API.
|
|
266
|
+
- An unsupported operation on a served service returns `NotImplemented`. For example,
|
|
267
|
+
`aws iam list-users` reports
|
|
265
268
|
`Simulated IAM does not serve ListUsers`, and `aws lambda list-functions` names the path it
|
|
266
269
|
arrived at.
|
|
267
270
|
- `aws cloudwatch get-metric-statistics` and `aws cloudwatch get-metric-data` fail with
|
|
@@ -269,16 +272,3 @@ rejection as a plain `403`.
|
|
|
269
272
|
seconds and the endpoint hands that number to the simulation where a `Date` is expected. Both
|
|
270
273
|
reads work in process and through SDK interception. `put-metric-data` and `list-metrics` are
|
|
271
274
|
unaffected.
|
|
272
|
-
- `aws s3 cp` and `aws s3 sync` corrupt a **download** above the CLI's 8MB threshold
|
|
273
|
-
([#717](https://github.com/KensioSoftware/yulin/issues/717)). The CLI splits
|
|
274
|
-
the download into ranged GETs, simulated S3 ignores `Range` and returns the whole Object for each
|
|
275
|
-
one, and the parts land on top of each other. A 12MB Object arrives as a 20MB file. Uploads above
|
|
276
|
-
the threshold are fine, and so is any download under it. Two ways round it, both verified.
|
|
277
|
-
`aws s3api get-object` issues one unranged GET. Raising the threshold in the config file keeps
|
|
278
|
-
`aws s3 cp` on a single GET too.
|
|
279
|
-
|
|
280
|
-
```ini
|
|
281
|
-
[profile sim]
|
|
282
|
-
s3 =
|
|
283
|
-
multipart_threshold = 5GB
|
|
284
|
-
```
|
package/docs/factories/README.md
CHANGED
|
@@ -1,36 +1,11 @@
|
|
|
1
1
|
# Event factories
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
test is about are buried in them. Written out by hand, that literal is copied between files and
|
|
6
|
-
drifts.
|
|
3
|
+
Yulin's event factories create complete AWS event objects for tests that call a handler directly.
|
|
4
|
+
They use [`@kensio/part-factory`](https://partfactory.dev/) and do not need a `SimAws` instance.
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
test made with one says what the request or the message was and leaves the rest of the event alone.
|
|
10
|
-
They are ordinary factories, made in-process, and they need no `SimAws` instance and no simulated
|
|
11
|
-
service running. A handler test that runs without a simulator is who they are for. A test that does want
|
|
12
|
-
one (a Function URL served over HTTP, a queue with a real event source mapping) gets its events from
|
|
13
|
-
the simulator, and these factories make the same shapes that simulator delivers.
|
|
6
|
+
## Make a record or an event
|
|
14
7
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
| Factory | Import | Event |
|
|
18
|
-
| ----------------------------------------------------------------------------- | ---------------------------- | ----------------------------------- |
|
|
19
|
-
| `lambdaFunctionUrlEventFactory` | `@kensio/yulin/lambda` | A Lambda Function URL invocation |
|
|
20
|
-
| `lambdaSqsEventFactory`, `lambdaSqsEventRecordFactory` | `@kensio/yulin/lambda` | An SQS event source mapping's batch |
|
|
21
|
-
| `lambdaDynamoDbStreamEventFactory`, `lambdaDynamoDbStreamEventRecordFactory` | `@kensio/yulin/lambda` | A DynamoDB stream mapping's batch |
|
|
22
|
-
| `httpApiProxyEventFactory` | `@kensio/yulin/apigatewayv2` | An HTTP API `AWS_PROXY` invocation |
|
|
23
|
-
| `s3NotificationEventFactory`, `s3NotificationEventRecordFactory` | `@kensio/yulin/s3` | An S3 event notification |
|
|
24
|
-
| `cloudFrontViewerRequestEventFactory`, `cloudFrontViewerResponseEventFactory` | `@kensio/yulin/cloudfront` | A CloudFront Functions event |
|
|
25
|
-
|
|
26
|
-
Each service's own documentation covers what its events mean. This page is about how the factories
|
|
27
|
-
are shaped and what they have in common.
|
|
28
|
-
|
|
29
|
-
## One factory per shape, and one per record
|
|
30
|
-
|
|
31
|
-
An event that carries a list of records has two factories, one for a record and one for the event
|
|
32
|
-
around it. The record factory makes one record, and the event factory completes as many records as
|
|
33
|
-
the test asks for.
|
|
8
|
+
Pass the fields that matter to the test. The factory supplies the remaining fields:
|
|
34
9
|
|
|
35
10
|
```typescript factories-records-and-events
|
|
36
11
|
/**
|
|
@@ -68,17 +43,14 @@ const event = lambdaSqsEventFactory.make({
|
|
|
68
43
|
console.log(ordersHandler(event));
|
|
69
44
|
```
|
|
70
45
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
the handler as the only thing in those records, typed as a complete one and missing every field the
|
|
75
|
-
handler reads.
|
|
46
|
+
Factories whose names end in `RecordFactory` create one record. Their matching event factories
|
|
47
|
+
create the object that contains a `Records` array. The event factory makes one record by default and
|
|
48
|
+
completes every partial record passed in `Records`.
|
|
76
49
|
|
|
77
|
-
##
|
|
50
|
+
## Reuse a named event shape
|
|
78
51
|
|
|
79
|
-
Every
|
|
80
|
-
|
|
81
|
-
of request or message one application receives:
|
|
52
|
+
Every exported event factory implements `ItemFactory`. Wrap one in a `VariantFactory` to keep a
|
|
53
|
+
common event shape in one place:
|
|
82
54
|
|
|
83
55
|
```typescript factories-variants
|
|
84
56
|
/**
|
|
@@ -118,23 +90,39 @@ console.log(
|
|
|
118
90
|
);
|
|
119
91
|
```
|
|
120
92
|
|
|
121
|
-
##
|
|
93
|
+
## Keep related fields consistent
|
|
94
|
+
|
|
95
|
+
AWS events often repeat the same value in several fields. The factories calculate those fields from
|
|
96
|
+
the overrides. For example, an SQS record's `md5OfBody` follows its `body`, and an S3 notification's
|
|
97
|
+
bucket ARN follows its bucket name.
|
|
122
98
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
99
|
+
The factories keep these groups consistent:
|
|
100
|
+
|
|
101
|
+
- Function URL and HTTP API request paths, route keys, query strings, endpoint details, caller
|
|
102
|
+
details, and invocation times
|
|
103
|
+
- SQS message bodies, body digests, queue ARNs, and regions
|
|
104
|
+
- DynamoDB stream images, event names, view types, stream ARNs, and regions
|
|
105
|
+
- S3 bucket names, bucket ARNs, event names, and object metadata
|
|
106
|
+
|
|
107
|
+
You can still override both copies with different values. The factory preserves explicit overrides,
|
|
108
|
+
even when AWS would not produce that combination.
|
|
109
|
+
|
|
110
|
+
## Available factories
|
|
111
|
+
|
|
112
|
+
| Factory | Import | Event |
|
|
113
|
+
| ----------------------------------------------------------------------------- | ---------------------------- | ----------------------------------- |
|
|
114
|
+
| `lambdaFunctionUrlEventFactory` | `@kensio/yulin/lambda` | A Lambda Function URL invocation |
|
|
115
|
+
| `lambdaSqsEventFactory`, `lambdaSqsEventRecordFactory` | `@kensio/yulin/lambda` | An SQS event source mapping's batch |
|
|
116
|
+
| `lambdaDynamoDbStreamEventFactory`, `lambdaDynamoDbStreamEventRecordFactory` | `@kensio/yulin/lambda` | A DynamoDB stream mapping's batch |
|
|
117
|
+
| `httpApiProxyEventFactory` | `@kensio/yulin/apigatewayv2` | An HTTP API `AWS_PROXY` invocation |
|
|
118
|
+
| `s3NotificationEventFactory`, `s3NotificationEventRecordFactory` | `@kensio/yulin/s3` | An S3 event notification |
|
|
119
|
+
| `cloudFrontViewerRequestEventFactory`, `cloudFrontViewerResponseEventFactory` | `@kensio/yulin/cloudfront` | A CloudFront Functions event |
|
|
127
120
|
|
|
128
|
-
Each
|
|
129
|
-
What that covers is listed in each factory's own documentation, and in outline it is:
|
|
121
|
+
Each service page describes the fields and defaults for its own factories.
|
|
130
122
|
|
|
131
|
-
|
|
132
|
-
hostname and `host` header, the caller's user agent and address, and the invocation time
|
|
133
|
-
- **SQS records** — the digest of the body, and the Region of the queue ARN
|
|
134
|
-
- **DynamoDB stream records** — the images the reported change would carry, the view type naming
|
|
135
|
-
the images that are there, and the Region of the stream ARN
|
|
136
|
-
- **S3 notification records** — the ARN of the Bucket named, and whether the Object still exists to
|
|
137
|
-
have a size and an eTag
|
|
123
|
+
## Limitations
|
|
138
124
|
|
|
139
|
-
|
|
140
|
-
|
|
125
|
+
- Event factories create data only. They do not invoke a Lambda function, apply IAM permissions, or
|
|
126
|
+
run another simulated service.
|
|
127
|
+
- A factory accepts explicit overrides that disagree with each other. It does not validate that the
|
|
128
|
+
final event could have come from AWS.
|