Skip to content
100 changes: 100 additions & 0 deletions compat/aws/cloudformation_compat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/aws/aws-sdk-go-v2/aws"
awscfn "github.com/aws/aws-sdk-go-v2/service/cloudformation"
cfntypes "github.com/aws/aws-sdk-go-v2/service/cloudformation/types"

cloudemu "github.com/stackshy/cloudemu/v2"
"github.com/stackshy/cloudemu/v2/internal/compat"
Expand Down Expand Up @@ -89,6 +90,19 @@ func TestAWSCloudFormationCompat(t *testing.T) {
return err
})

sess.Op(svc, "GetTemplateSummary", func() error {
out, err := client.GetTemplateSummary(ctx, &awscfn.GetTemplateSummaryInput{StackName: aws.String(stack)})
if err != nil {
return err
}

if len(out.ResourceTypes) != 2 {
return errCompat("expected 2 resource types")
}

return nil
})

sess.Op(svc, "UpdateStack", func() error {
_, err := client.UpdateStack(ctx, &awscfn.UpdateStackInput{
StackName: aws.String(stack),
Expand All @@ -102,12 +116,98 @@ func TestAWSCloudFormationCompat(t *testing.T) {
return continueUpdateRollback(ctx, client)
})

changeSetOps(ctx, sess, client)

sess.Op(svc, "DeleteStack", func() error {
_, err := client.DeleteStack(ctx, &awscfn.DeleteStackInput{StackName: aws.String(stack)})
return err
})
}

// changeSetOps creates a stack from a CREATE change set, then creates and
// deletes an UPDATE change set on it.
func changeSetOps(ctx context.Context, sess *compat.AWSSession, client *awscfn.Client) {
const (
svc = "cloudformation"
stack = "compat-cs"
)

var id string

sess.Op(svc, "CreateChangeSet", func() error {
out, err := client.CreateChangeSet(ctx, &awscfn.CreateChangeSetInput{
StackName: aws.String(stack), ChangeSetName: aws.String("create"),
ChangeSetType: cfntypes.ChangeSetTypeCreate, TemplateBody: aws.String(changeSetTemplate),
})
if err != nil {
return err
}

id = aws.ToString(out.Id)

return nil
})

sess.Op(svc, "DescribeChangeSet", func() error {
out, err := client.DescribeChangeSet(ctx, &awscfn.DescribeChangeSetInput{ChangeSetName: aws.String(id)})
if err != nil {
return err
}

if out.Status != cfntypes.ChangeSetStatusCreateComplete || len(out.Changes) != 1 {
return errCompat("change set " + string(out.Status))
}

return nil
})

sess.Op(svc, "ListChangeSets", func() error {
out, err := client.ListChangeSets(ctx, &awscfn.ListChangeSetsInput{StackName: aws.String(stack)})
if err != nil {
return err
}

if len(out.Summaries) != 1 {
return errCompat("expected 1 change set")
}

return nil
})

sess.Op(svc, "ExecuteChangeSet", func() error {
if _, err := client.ExecuteChangeSet(ctx, &awscfn.ExecuteChangeSetInput{ChangeSetName: aws.String(id)}); err != nil {
return err
}

out, err := client.DescribeStacks(ctx, &awscfn.DescribeStacksInput{StackName: aws.String(stack)})
if err != nil {
return err
}

if out.Stacks[0].StackStatus != cfntypes.StackStatusCreateComplete {
return errCompat("status " + string(out.Stacks[0].StackStatus))
}

return nil
})

sess.Op(svc, "DeleteChangeSet", func() error {
if _, err := client.CreateChangeSet(ctx, &awscfn.CreateChangeSetInput{
StackName: aws.String(stack), ChangeSetName: aws.String("update"), UsePreviousTemplate: aws.Bool(true),
}); err != nil {
return err
}

_, err := client.DeleteChangeSet(ctx, &awscfn.DeleteChangeSetInput{
StackName: aws.String(stack), ChangeSetName: aws.String("update"),
})

return err
})
}

const changeSetTemplate = `{"Resources":{"Bucket":{"Type":"AWS::S3::Bucket","Properties":{"BucketName":"compat-cs-bucket"}}}}`

// continueUpdateRollback drives a stack into UPDATE_ROLLBACK_FAILED, where
// Parameter Store refuses to move a parameter back from the Advanced tier,
// then continues the rollback skipping it.
Expand Down
8 changes: 7 additions & 1 deletion docs/compat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,25 @@ Each service's summary breaks the verified counts out per SDK/language. Only lan
| Operation | AWS (CloudFormation) |
|---|---|
| ContinueUpdateRollback | ✅ |
| CreateChangeSet | ✅ |
| CreateStack | ✅ |
| DeleteChangeSet | ✅ |
| DeleteStack | ✅ |
| DescribeChangeSet | ✅ |
| DescribeStackEvents | ✅ |
| DescribeStackResources | ✅ |
| DescribeStacks | ✅ |
| ExecuteChangeSet | ✅ |
| GetTemplate | ✅ |
| GetTemplateSummary | ✅ |
| ListChangeSets | ✅ |
| ListStackResources | ✅ |
| ListStacks | ✅ |
| UpdateStack | ✅ |
| ValidateTemplate | ✅ |

**cloudformation verified per language:**
- Go: AWS 11/11
- Go: AWS 17/17

## compute

Expand Down
78 changes: 78 additions & 0 deletions docs/compat/compat.json
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,19 @@
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "CreateChangeSet",
"providers": {
"aws": {
"native": "CloudFormation",
"clients": {
"sdkGo": "pass"
}
}
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "CreateStack",
Expand All @@ -342,6 +355,19 @@
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "DeleteChangeSet",
"providers": {
"aws": {
"native": "CloudFormation",
"clients": {
"sdkGo": "pass"
}
}
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "DeleteStack",
Expand All @@ -355,6 +381,19 @@
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "DescribeChangeSet",
"providers": {
"aws": {
"native": "CloudFormation",
"clients": {
"sdkGo": "pass"
}
}
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "DescribeStackEvents",
Expand Down Expand Up @@ -394,6 +433,19 @@
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "ExecuteChangeSet",
"providers": {
"aws": {
"native": "CloudFormation",
"clients": {
"sdkGo": "pass"
}
}
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "GetTemplate",
Expand All @@ -407,6 +459,32 @@
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "GetTemplateSummary",
"providers": {
"aws": {
"native": "CloudFormation",
"clients": {
"sdkGo": "pass"
}
}
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "ListChangeSets",
"providers": {
"aws": {
"native": "CloudFormation",
"clients": {
"sdkGo": "pass"
}
}
},
"status": "green"
},
{
"service": "cloudformation",
"operation": "ListStackResources",
Expand Down
2 changes: 1 addition & 1 deletion docs/coverage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ code does not implement. Machine-readable: [`coverage.json`](./coverage.json).
| `cloudasset` | - | - | [Cloudasset](./gcp/cloudasset.md) | - | 11 |
| `cloudbilling` | - | - | [Cloudbilling](./gcp/cloudbilling.md) | - | 14 |
| `clouddeploy` | - | - | [CloudDeploy](./gcp/clouddeploy.md) | - | 11 |
| `cloudformation` | [CloudFormation](./aws/cloudformation.md) | - | - | - | 11 |
| `cloudformation` | [CloudFormation](./aws/cloudformation.md) | - | - | - | 17 |
| `cloudfront` | [CloudFront](./aws/cloudfront.md) | - | - | - | 11 |
| `cloudids` | - | - | [CloudIDS](./gcp/cloudids.md) | - | 6 |
| `cloudrun` | - | - | [CloudRun](./gcp/cloudrun.md) | - | 18 |
Expand Down
2 changes: 1 addition & 1 deletion docs/coverage/aws/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Services cloudemu emulates for AWS, by native name. Back to the [cross-provider
| [Bedrock](./bedrock.md) | `bedrock` | 65 |
| [BedrockAgent](./bedrockagent.md) | `bedrockagent` | 32 |
| [BedrockAgentRuntime](./bedrockagentruntime.md) | `bedrockagentruntime` | 3 |
| [CloudFormation](./cloudformation.md) | (provider-native) | 11 |
| [CloudFormation](./cloudformation.md) | (provider-native) | 17 |
| [CloudFront](./cloudfront.md) | `cloudfront` | 11 |
| [CloudTrail](./cloudtrail.md) | `cloudtrail` | 60 |
| [CloudWatch](./cloudwatch.md) | `monitoring` | 12 |
Expand Down
8 changes: 7 additions & 1 deletion docs/coverage/aws/cloudformation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@

provider-native `cloudformation` wire service (AWS-only) · no portable driver · [AWS index](./README.md)

## Operations (11)
## Operations (17)

| Operation | Description |
| --- | --- |
| `ContinueUpdateRollback` | |
| `CreateChangeSet` | |
| `CreateStack` | |
| `DeleteChangeSet` | |
| `DeleteStack` | |
| `DescribeChangeSet` | |
| `DescribeStackEvents` | |
| `DescribeStackResources` | |
| `DescribeStacks` | |
| `ExecuteChangeSet` | |
| `GetTemplate` | |
| `GetTemplateSummary` | |
| `ListChangeSets` | |
| `ListStackResources` | |
| `ListStacks` | |
| `UpdateStack` | |
Expand Down
18 changes: 18 additions & 0 deletions docs/coverage/coverage.json
Original file line number Diff line number Diff line change
Expand Up @@ -3137,12 +3137,21 @@
{
"name": "ContinueUpdateRollback"
},
{
"name": "CreateChangeSet"
},
{
"name": "CreateStack"
},
{
"name": "DeleteChangeSet"
},
{
"name": "DeleteStack"
},
{
"name": "DescribeChangeSet"
},
{
"name": "DescribeStackEvents"
},
Expand All @@ -3152,9 +3161,18 @@
{
"name": "DescribeStacks"
},
{
"name": "ExecuteChangeSet"
},
{
"name": "GetTemplate"
},
{
"name": "GetTemplateSummary"
},
{
"name": "ListChangeSets"
},
{
"name": "ListStackResources"
},
Expand Down
Loading
Loading