ecspresso
The atago project wrote these specs on its own initiative and runs them in its own CI, to exercise atago against a real program. They are not ecspresso’s official test suite, and the ecspresso project is not affiliated with atago.
Summary #
2 suites · 8 scenarios
Contents #
- ecspresso + deploy (real ECS deploy against a mock) — 1 scenario
- ecspresso (Amazon ECS deploy tool) — 7 scenarios
- version prints without error
- render substitutes an env template function
- render falls back to the template default when the env is unset
- render evaluates a jsonnet task definition with an external variable
- render config resolves the defaults
- an undefined must_env fails the render
- a missing config file fails cleanly
ecspresso + deploy (real ECS deploy against a mock) #
The thing ecspresso exists to do: deploy an ECS service, and roll it when the definition changes. This suite runs that for real against a mock AWS endpoint (moto, an in-memory AWS mock), so no AWS account is involved and nothing is billed.
The deploy is verified from the outside. Rather than trusting ecspresso’s
own log output, the resulting ECS state is read back with
aws ecs describe-services — a second, independent client — so the
assertion is about what the service actually looks like afterwards.
Source: test/e2e/thirdparty/ecspresso/deploy.atago.yaml
Scenario: deploy registers the task definition, creates the service, and rolls it #
only when command -v ecspresso && command -v moto_server && command -v aws succeeds
Given #
- Background service
motois started:moto_server -H 127.0.0.1 -p 15111. - Fixture file
ecspresso.ymlis created. - Fixture file
taskdef.jsonis created. - Fixture file
servicedef.jsonis created.
Inputs #
Fixture ecspresso.yml:
region: us-east-1
cluster: demo
service: web
task_definition: taskdef.json
service_definition: servicedef.json
Fixture taskdef.json:
{
"family": "web",
"containerDefinitions": [
{ "name": "web", "image": "nginx:1.0", "cpu": 128, "memory": 256, "essential": true }
]
}
Fixture servicedef.json:
{ "launchType": "EC2", "desiredCount": 2, "schedulingStrategy": "REPLICA" }
When #
aws --endpoint-url http://127.0.0.1:15111 ecs create-cluster --cluster-name demo
ecspresso deploy --config ecspresso.yml --no-wait
aws --endpoint-url http://127.0.0.1:15111 ecs describe-services --cluster demo --services web --query "services[0].status" --output text
aws --endpoint-url http://127.0.0.1:15111 ecs describe-services --cluster demo --services web --query "services[0].taskDefinition" --output text
aws --endpoint-url http://127.0.0.1:15111 ecs describe-services --cluster demo --services web --query "services[0].desiredCount" --output text
sed 's/nginx:1.0/nginx:2.0/' taskdef.json > taskdef.new && mv taskdef.new taskdef.json
ecspresso deploy --config ecspresso.yml --no-wait
aws --endpoint-url http://127.0.0.1:15111 ecs describe-services --cluster demo --services web --query "services[0].taskDefinition" --output text
aws --endpoint-url http://127.0.0.1:15111 ecs list-task-definitions --query "length(taskDefinitionArns)" --output text
Then #
- after
aws --endpoint-url http://127.0.0.1:15111 ecs create-cluster --cluster-name demo:- exit code is
0
- exit code is
- after
ecspresso deploy --config ecspresso.yml --no-wait:- exit code is
0
- exit code is
- after
aws --endpoint-url http://127.0.0.1:15111 ecs describe-services --cluster demo --services web --query "services[0].status" --output text:- exit code is
0 - stdout contains
ACTIVE
- exit code is
- after
aws --endpoint-url http://127.0.0.1:15111 ecs describe-services --cluster demo --services web --query "services[0].taskDefinition" --output text:- exit code is
0 - stdout contains
web:1
- exit code is
- after
aws --endpoint-url http://127.0.0.1:15111 ecs describe-services --cluster demo --services web --query "services[0].desiredCount" --output text:- exit code is
0 - stdout contains
2
- exit code is
- after
sed 's/nginx:1.0/nginx:2.0/' taskdef.json > taskdef.new && mv taskdef.new taskdef.json:- exit code is
0
- exit code is
- after
ecspresso deploy --config ecspresso.yml --no-wait:- exit code is
0
- exit code is
- after
aws --endpoint-url http://127.0.0.1:15111 ecs describe-services --cluster demo --services web --query "services[0].taskDefinition" --output text:- exit code is
0 - stdout contains
web:2
- exit code is
- after
aws --endpoint-url http://127.0.0.1:15111 ecs list-task-definitions --query "length(taskDefinitionArns)" --output text:- exit code is
0 - stdout contains
2
- exit code is
ecspresso (Amazon ECS deploy tool) #
ecspresso deploys ECS services, which
needs AWS — but everything that decides what gets deployed happens locally
first. ecspresso render evaluates a task and service definition without
touching a cluster, and that is the surface pinned here: the step where a
mistake becomes a bad deploy.
What is guaranteed: template functions expand to the documented values and
fall back to their defaults when unset; jsonnet definitions resolve with
external variables supplied; config paths resolve as documented; and the
failure modes stay loud and distinct — an undefined must_env and a missing
config file each fail with their own exit code rather than rendering
something half-substituted.
The rendered task definition is asserted as structured JSON, so a reformatting change cannot break the suite while a semantic change slips through.
Source: test/e2e/thirdparty/ecspresso/ecspresso.atago.yaml
Scenario: version prints without error #
only when ecspresso version succeeds
When #
ecspresso version
Then #
- exit code is
0
Scenario: render substitutes an env template function #
only when ecspresso version succeeds
Given #
- Fixture file
ecspresso.ymlis created. - Fixture file
taskdef.jsonis created. - Environment variables are set: IMAGE_TAG.
Inputs #
Fixture ecspresso.yml:
region: ap-northeast-1
cluster: demo
service: web
task_definition: taskdef.json
Fixture taskdef.json:
{
"family": "web",
"containerDefinitions": [
{
"name": "web",
"image": "nginx:{{ env `IMAGE_TAG` `latest` }}",
"cpu": 128,
"memory": 256
}
]
}
When #
ecspresso render --config ecspresso.yml taskdef
Then #
- exit code is
0 - stdout at
$.containerDefinitions[0].imageequalsnginx:1.2.3
Scenario: render falls back to the template default when the env is unset #
only when ecspresso version succeeds
Given #
- Fixture file
ecspresso.ymlis created. - Fixture file
taskdef.jsonis created.
Inputs #
Fixture ecspresso.yml:
region: ap-northeast-1
cluster: demo
service: web
task_definition: taskdef.json
Fixture taskdef.json:
{
"family": "web",
"containerDefinitions": [
{
"name": "web",
"image": "nginx:{{ env `IMAGE_TAG` `latest` }}",
"cpu": 128,
"memory": 256
}
]
}
When #
ecspresso render --config ecspresso.yml taskdef
Then #
- exit code is
0 - stdout at
$.containerDefinitions[0].imageequalsnginx:latest
Scenario: render evaluates a jsonnet task definition with an external variable #
only when ecspresso version succeeds
Given #
- Fixture file
ecspresso.ymlis created. - Fixture file
task.jsonnetis created.
Inputs #
Fixture ecspresso.yml:
region: ap-northeast-1
cluster: demo
service: web
task_definition: task.jsonnet
Fixture task.jsonnet:
{
family: "web",
containerDefinitions: [
{
name: "web",
image: "nginx:" + std.extVar("tag"),
cpu: 64,
memory: 128,
},
],
}
When #
ecspresso render --config ecspresso.yml --ext-str tag=9.9.9 taskdef
Then #
- exit code is
0 - stdout at
$.containerDefinitions[0].imageequalsnginx:9.9.9
Scenario: render config resolves the defaults #
only when ecspresso version succeeds
Given #
- Fixture file
ecspresso.ymlis created. - Fixture file
taskdef.jsonis created.
Inputs #
Fixture ecspresso.yml:
region: ap-northeast-1
cluster: demo
service: web
task_definition: taskdef.json
Fixture taskdef.json:
{"family": "web", "containerDefinitions": []}
When #
ecspresso render --config ecspresso.yml config
Then #
- exit code is
0 - stdout contains
cluster: demo,timeout:
Scenario: an undefined must_env fails the render #
only when ecspresso version succeeds
Given #
- Fixture file
ecspresso.ymlis created. - Fixture file
taskdef.jsonis created.
Inputs #
Fixture ecspresso.yml:
region: ap-northeast-1
cluster: demo
service: web
task_definition: taskdef.json
Fixture taskdef.json:
{
"family": "web",
"containerDefinitions": [
{
"name": "web",
"image": "nginx:{{ must_env `REQUIRED_TAG` }}",
"cpu": 1,
"memory": 1
}
]
}
When #
ecspresso render --config ecspresso.yml taskdef
Then #
- exit code is
2 - stderr contains
REQUIRED_TAG is not defined
Scenario: a missing config file fails cleanly #
only when ecspresso version succeeds
When #
ecspresso render --config nonexistent.yml taskdef
Then #
- exit code is
1 - stderr contains
failed to load config file