From aff6796898ed277cdcee2bfe5656afd0d805a221 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Sun, 22 Dec 2024 10:39:44 +0100 Subject: [PATCH 01/40] Added component testing framework --- go.mod | 67 +- go.sum | 319 +-------- pkg/atmos/aws-component-helper/atmos.go | 201 +++--- .../aws-component-helper/atmos_component.go | 36 ++ .../atmos_component_test.go | 16 + pkg/atmos/aws-component-helper/cli.go | 86 ++- pkg/atmos/aws-component-helper/cli_test.go | 607 +++++++++--------- .../aws-component-helper/setup_component.go | 70 +- .../setup_component_test.go | 226 ++++--- .../aws-component-helper/setup_test_suite.go | 152 +++-- .../setup_test_suite_test.go | 138 ++-- pkg/atmos/aws-component-helper/shared.go | 2 + .../aws-component-helper/tear_down_suite.go | 43 +- .../aws-component-helper/test_component.go | 107 +++ .../test_component_test.go | 16 + pkg/atmos/aws-component-helper/test_suite.go | 543 ++++++++-------- .../aws-component-helper/x_test_suite.go | 75 +++ .../aws-component-helper/x_test_suite_test.go | 18 + .../aws-component-helper/x_test_suites.go | 145 +++++ .../x_test_suites_test.go | 130 ++++ pkg/atmos/describe_stacks.go | 66 +- pkg/atmos/describe_stacks_test.go | 29 + pkg/atmos/format.go | 17 + pkg/awsnuke/awsnuke.go | 152 ----- pkg/awsnuke/awsnuke.go.bk | 152 +++++ pkg/awsnuke/awsnuke.go.bk_test.go.bk | 57 ++ pkg/awsnuke/awsnuke_test.go | 57 -- test/fixtures/atmos/atmos.yaml | 25 - test/fixtures/aws-component-helper/atmos.yaml | 86 +++ .../components/terraform/account-map/.gitkeep | 0 .../components/terraform/assert/.gitkeep | 0 .../stacks/catalog/account-map.yaml | 46 ++ .../stacks/orgs/default/test/_defaults.yaml | 68 ++ .../stacks/orgs/default/test/tests.yaml | 40 ++ .../fixtures/aws-component-helper/vendor.yaml | 29 + 35 files changed, 2175 insertions(+), 1646 deletions(-) create mode 100644 pkg/atmos/aws-component-helper/atmos_component.go create mode 100644 pkg/atmos/aws-component-helper/atmos_component_test.go create mode 100644 pkg/atmos/aws-component-helper/test_component.go create mode 100644 pkg/atmos/aws-component-helper/test_component_test.go create mode 100644 pkg/atmos/aws-component-helper/x_test_suite.go create mode 100644 pkg/atmos/aws-component-helper/x_test_suite_test.go create mode 100644 pkg/atmos/aws-component-helper/x_test_suites.go create mode 100644 pkg/atmos/aws-component-helper/x_test_suites_test.go create mode 100644 pkg/atmos/describe_stacks_test.go delete mode 100644 pkg/awsnuke/awsnuke.go create mode 100644 pkg/awsnuke/awsnuke.go.bk create mode 100644 pkg/awsnuke/awsnuke.go.bk_test.go.bk delete mode 100644 pkg/awsnuke/awsnuke_test.go create mode 100644 test/fixtures/aws-component-helper/atmos.yaml create mode 100644 test/fixtures/aws-component-helper/components/terraform/account-map/.gitkeep create mode 100644 test/fixtures/aws-component-helper/components/terraform/assert/.gitkeep create mode 100644 test/fixtures/aws-component-helper/stacks/catalog/account-map.yaml create mode 100644 test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml create mode 100644 test/fixtures/aws-component-helper/stacks/orgs/default/test/tests.yaml create mode 100644 test/fixtures/aws-component-helper/vendor.yaml diff --git a/go.mod b/go.mod index 0d846ed..af14c11 100644 --- a/go.mod +++ b/go.mod @@ -2,18 +2,19 @@ module github.com/cloudposse/test-helpers go 1.23 +toolchain go1.23.0 + require ( dario.cat/mergo v1.0.1 github.com/aws/aws-sdk-go-v2/config v1.15.13 github.com/aws/aws-sdk-go-v2/service/sts v1.16.9 - github.com/ekristen/aws-nuke v2.10.0+incompatible github.com/gruntwork-io/terratest v0.47.0 github.com/jinzhu/copier v0.4.0 - github.com/rebuy-de/aws-nuke/v2 v2.25.0 github.com/stretchr/testify v1.9.0 - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 ) +// replace github.com/rebuy-de/aws-nuke/v2/mocks => github.com/ekristen/aws-nuke/v3 v3.29.0 + require ( cloud.google.com/go v0.110.10 // indirect cloud.google.com/go/compute v1.23.3 // indirect @@ -32,26 +33,12 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.11.11 // indirect github.com/aws/smithy-go v1.12.0 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect - github.com/boombuler/barcode v1.0.1 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.9.0 // indirect - github.com/go-errors/errors v1.4.2 // indirect - github.com/go-logr/logr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-sql-driver/mysql v1.6.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect - github.com/gruntwork-io/go-commons v0.13.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-getter v1.7.5 // indirect @@ -60,36 +47,22 @@ require ( github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hcl/v2 v2.19.1 // indirect github.com/hashicorp/terraform-json v0.22.1 // indirect - github.com/imdario/mergo v0.3.13 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.0 // indirect github.com/kr/pretty v0.3.1 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-zglob v0.0.3 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect - github.com/moby/spdystream v0.2.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/pquerna/otp v1.3.0 // indirect - github.com/rebuy-de/aws-nuke v2.10.0+incompatible // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/tmccombs/hcl2json v0.3.4 // indirect github.com/ulikunitz/xz v0.5.11 // indirect - github.com/urfave/cli/v2 v2.20.2 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/zclconf/go-cty v1.14.4 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/net v0.23.0 // indirect golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.153.0 // indirect @@ -100,33 +73,13 @@ require ( google.golang.org/grpc v1.60.1 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.28.4 // indirect - k8s.io/apimachinery v0.28.4 // indirect - k8s.io/client-go v0.28.4 // indirect - k8s.io/klog/v2 v2.100.1 // indirect - k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect - k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect ) require ( - github.com/aws/aws-sdk-go v1.54.19 - github.com/fatih/color v1.16.0 // indirect - github.com/google/uuid v1.5.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/aws/aws-sdk-go v1.54.20 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/sirupsen/logrus v1.9.3 - github.com/spf13/cobra v1.8.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.18.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.20.0 // indirect ) diff --git a/go.sum b/go.sum index 6bfdceb..16be344 100644 --- a/go.sum +++ b/go.sum @@ -32,38 +32,22 @@ cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34h cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y= cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= -cloud.google.com/go/accessapproval v1.7.4/go.mod h1:/aTEh45LzplQgFYdQdwPMR9YdX0UlhBmvB84uAmQKUc= -cloud.google.com/go/accesscontextmanager v1.8.4/go.mod h1:ParU+WbMpD34s5JFEnGAnPBYAgUHozaTmDJU7aCU9+M= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= -cloud.google.com/go/aiplatform v1.52.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/analytics v0.21.6/go.mod h1:eiROFQKosh4hMaNhF85Oc9WO97Cpa7RggD40e/RBy8w= -cloud.google.com/go/apigateway v1.6.4/go.mod h1:0EpJlVGH5HwAN4VF4Iec8TAzGN1aQgbxAWGJsnPCGGY= -cloud.google.com/go/apigeeconnect v1.6.4/go.mod h1:CapQCWZ8TCjnU0d7PobxhpOdVz/OVJ2Hr/Zcuu1xFx0= -cloud.google.com/go/apigeeregistry v0.8.2/go.mod h1:h4v11TDGdeXJDJvImtgK2AFVvMIgGWjSb0HRnBSjcX8= -cloud.google.com/go/appengine v1.8.4/go.mod h1:TZ24v+wXBujtkK77CXCpjZbnuTvsFNT41MUaZ28D6vg= cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/area120 v0.8.4/go.mod h1:jfawXjxf29wyBXr48+W+GyX/f8fflxp642D/bb9v68M= cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= -cloud.google.com/go/artifactregistry v1.14.6/go.mod h1:np9LSFotNWHcjnOgh8UVK0RFPCTUGbO0ve3384xyHfE= cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= -cloud.google.com/go/asset v1.15.3/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/assuredworkloads v1.11.4/go.mod h1:4pwwGNwy1RP0m+y12ef3Q/8PaiWrIDQ6nD2E8kvWI9U= cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= -cloud.google.com/go/automl v1.13.4/go.mod h1:ULqwX/OLZ4hBVfKQaMtxMSTlPx0GqGbWN8uA/1EqCP8= -cloud.google.com/go/baremetalsolution v1.2.3/go.mod h1:/UAQ5xG3faDdy180rCUv47e0jvpp3BFxT+Cl0PFjw5g= -cloud.google.com/go/batch v1.6.3/go.mod h1:J64gD4vsNSA2O5TtDB5AAux3nJ9iV8U3ilg3JDBYejU= -cloud.google.com/go/beyondcorp v1.0.3/go.mod h1:HcBvnEd7eYr+HGDd5ZbuVmBYX019C6CEXBonXbCVwJo= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -71,20 +55,12 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= -cloud.google.com/go/bigquery v1.57.1/go.mod h1:iYzC0tGVWt1jqSzBHqCr3lrRn0u13E8e+AqowBsDgug= cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= -cloud.google.com/go/billing v1.17.4/go.mod h1:5DOYQStCxquGprqfuid/7haD7th74kyMBHkjO/OvDtk= cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= -cloud.google.com/go/binaryauthorization v1.7.3/go.mod h1:VQ/nUGRKhrStlGr+8GMS8f6/vznYLkdK5vaKfdCIpvU= -cloud.google.com/go/certificatemanager v1.7.4/go.mod h1:FHAylPe/6IIKuaRmHbjbdLhGhVQ+CWHSD5Jq0k4+cCE= -cloud.google.com/go/channel v1.17.3/go.mod h1:QcEBuZLGGrUMm7kNj9IbU1ZfmJq2apotsV83hbxX7eE= -cloud.google.com/go/cloudbuild v1.14.3/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= -cloud.google.com/go/clouddms v1.7.3/go.mod h1:fkN2HQQNUYInAU3NQ3vRLkV2iWs8lIdmBKOx4nrL6Hc= cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= -cloud.google.com/go/cloudtasks v1.12.4/go.mod h1:BEPu0Gtt2dU6FxZHNqqNdGqIG86qyWKBPGnsb7udGY0= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= @@ -96,171 +72,97 @@ cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiV cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/contactcenterinsights v1.11.3/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= -cloud.google.com/go/container v1.27.1/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/containeranalysis v0.11.3/go.mod h1:kMeST7yWFQMGjiG9K7Eov+fPNQcGhb8mXj/UcTiWw9U= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= -cloud.google.com/go/datacatalog v1.18.3/go.mod h1:5FR6ZIF8RZrtml0VUao22FxhdjkoG+a0866rEnObryM= cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataflow v0.9.4/go.mod h1:4G8vAkHYCSzU8b/kmsoR2lWyHJD85oMJPHMtan40K8w= cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= -cloud.google.com/go/dataform v0.9.1/go.mod h1:pWTg+zGQ7i16pyn0bS1ruqIE91SdL2FDMvEYu/8oQxs= -cloud.google.com/go/datafusion v1.7.4/go.mod h1:BBs78WTOLYkT4GVZIXQCZT3GFpkpDN4aBY4NDX/jVlM= cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/datalabeling v0.8.4/go.mod h1:Z1z3E6LHtffBGrNUkKwbwbDxTiXEApLzIgmymj8A3S8= -cloud.google.com/go/dataplex v1.11.1/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= -cloud.google.com/go/dataproc/v2 v2.2.3/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= -cloud.google.com/go/dataqna v0.8.4/go.mod h1:mySRKjKg5Lz784P6sCov3p1QD+RZQONRMRjzGNcFd0c= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/datastore v1.15.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= -cloud.google.com/go/datastream v1.10.3/go.mod h1:YR0USzgjhqA/Id0Ycu1VvZe8hEWwrkjuXrGbzeDOSEA= -cloud.google.com/go/deploy v1.14.2/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= -cloud.google.com/go/dialogflow v1.44.3/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= -cloud.google.com/go/dlp v1.11.1/go.mod h1:/PA2EnioBeXTL/0hInwgj0rfsQb3lpE3R8XUJxqUNKI= cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= -cloud.google.com/go/documentai v1.23.5/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/domains v0.9.4/go.mod h1:27jmJGShuXYdUNjyDG0SodTfT5RwLi7xmH334Gvi3fY= cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/edgecontainer v1.1.4/go.mod h1:AvFdVuZuVGdgaE5YvlL1faAoa1ndRR/5XhXZvPBHbsE= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.6.5/go.mod h1:jjYbPzw0x+yglXC890l6ECJWdYeZ5dlYACTFL0U/VuM= -cloud.google.com/go/eventarc v1.13.3/go.mod h1:RWH10IAZIRcj1s/vClXkBgMHwh59ts7hSWcqD3kaclg= -cloud.google.com/go/filestore v1.7.4/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= -cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= -cloud.google.com/go/functions v1.15.4/go.mod h1:CAsTc3VlRMVvx+XqXxKqVevguqJpnVip4DdonFsX28I= cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= -cloud.google.com/go/gkebackup v1.3.4/go.mod h1:gLVlbM8h/nHIs09ns1qx3q3eaXcGSELgNu1DWXYz1HI= cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkeconnect v0.8.4/go.mod h1:84hZz4UMlDCKl8ifVW8layK4WHlMAFeq8vbzjU0yJkw= cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -cloud.google.com/go/gkehub v0.14.4/go.mod h1:Xispfu2MqnnFt8rV/2/3o73SK1snL8s9dYJ9G2oQMfc= -cloud.google.com/go/gkemulticloud v1.0.3/go.mod h1:7NpJBN94U6DY1xHIbsDqB2+TFZUfjLUKLjUX8NGLor0= cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= -cloud.google.com/go/gsuiteaddons v1.6.4/go.mod h1:rxtstw7Fx22uLOXBpsvb9DUbC+fiXs7rF4U29KHM/pE= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= -cloud.google.com/go/iap v1.9.3/go.mod h1:DTdutSZBqkkOm2HEOTBzhZxh2mwwxshfD/h3yofAiCw= -cloud.google.com/go/ids v1.4.4/go.mod h1:z+WUc2eEl6S/1aZWzwtVNWoSZslgzPxAboS0lZX0HjI= -cloud.google.com/go/iot v1.7.4/go.mod h1:3TWqDVvsddYBG++nHSZmluoCAVGr1hAcabbWZNKEZLk= -cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= -cloud.google.com/go/language v1.12.2/go.mod h1:9idWapzr/JKXBBQ4lWqVX/hcadxB194ry20m/bTrhWc= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/lifesciences v0.9.4/go.mod h1:bhm64duKhMi7s9jR9WYJYvjAFJwRqNj+Nia7hF0Z7JA= -cloud.google.com/go/logging v1.8.1/go.mod h1:TJjR+SimHwuC8MZ9cjByQulAMgni+RkXeI3wwctHJEI= -cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= -cloud.google.com/go/managedidentities v1.6.4/go.mod h1:WgyaECfHmF00t/1Uk8Oun3CQ2PGUtjc3e9Alh79wyiM= -cloud.google.com/go/maps v1.6.1/go.mod h1:4+buOHhYXFBp58Zj/K+Lc1rCmJssxxF4pJ5CJnhdz18= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/mediatranslation v0.8.4/go.mod h1:9WstgtNVAdN53m6TQa5GjIjLqKQPXe74hwSCxUP6nj4= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= -cloud.google.com/go/memcache v1.10.4/go.mod h1:v/d8PuC8d1gD6Yn5+I3INzLR01IDn0N4Ym56RgikSI0= cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= -cloud.google.com/go/metastore v1.13.3/go.mod h1:K+wdjXdtkdk7AQg4+sXS8bRrQa9gcOr+foOMF2tqINE= -cloud.google.com/go/monitoring v1.16.3/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= -cloud.google.com/go/networkconnectivity v1.14.3/go.mod h1:4aoeFdrJpYEXNvrnfyD5kIzs8YtHg945Og4koAjHQek= -cloud.google.com/go/networkmanagement v1.9.3/go.mod h1:y7WMO1bRLaP5h3Obm4tey+NquUvB93Co1oh4wpL+XcU= cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/networksecurity v0.9.4/go.mod h1:E9CeMZ2zDsNBkr8axKSYm8XyTqNhiCHf1JO/Vb8mD1w= cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= -cloud.google.com/go/notebooks v1.11.2/go.mod h1:z0tlHI/lREXC8BS2mIsUeR3agM1AkgLiS+Isov3SS70= -cloud.google.com/go/optimization v1.6.2/go.mod h1:mWNZ7B9/EyMCcwNl1frUGEuY6CPijSkz88Fz2vwKPOY= -cloud.google.com/go/orchestration v1.8.4/go.mod h1:d0lywZSVYtIoSZXb0iFjv9SaL13PGyVOKDxqGxEf/qI= -cloud.google.com/go/orgpolicy v1.11.4/go.mod h1:0+aNV/nrfoTQ4Mytv+Aw+stBDBjNf4d8fYRA9herfJI= cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= -cloud.google.com/go/osconfig v1.12.4/go.mod h1:B1qEwJ/jzqSRslvdOCI8Kdnp0gSng0xW4LOnIebQomA= cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= -cloud.google.com/go/oslogin v1.12.2/go.mod h1:CQ3V8Jvw4Qo4WRhNPF0o+HAM4DiLuE27Ul9CX9g2QdY= cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/phishingprotection v0.8.4/go.mod h1:6b3kNPAc2AQ6jZfFHioZKg9MQNybDg4ixFd4RPZZ2nE= -cloud.google.com/go/policytroubleshooter v1.10.2/go.mod h1:m4uF3f6LseVEnMV6nknlN2vYGRb+75ylQwJdnOXfnv0= cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= -cloud.google.com/go/privatecatalog v0.9.4/go.mod h1:SOjm93f+5hp/U3PqMZAHTtBtluqLygrDrVO8X8tYtG0= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= -cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= -cloud.google.com/go/recaptchaenterprise/v2 v2.8.3/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommendationengine v0.8.4/go.mod h1:GEteCf1PATl5v5ZsQ60sTClUE0phbWmo3rQ1Js8louU= cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= -cloud.google.com/go/recommender v1.11.3/go.mod h1:+FJosKKJSId1MBFeJ/TTyoGQZiEelQQIZMKYYD8ruK4= cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= -cloud.google.com/go/redis v1.14.1/go.mod h1:MbmBxN8bEnQI4doZPC1BzADU4HGocHBk2de3SbgOkqs= -cloud.google.com/go/resourcemanager v1.9.4/go.mod h1:N1dhP9RFvo3lUfwtfLWVxfUWq8+KUQ+XLlHLH3BoFJ0= -cloud.google.com/go/resourcesettings v1.6.4/go.mod h1:pYTTkWdv2lmQcjsthbZLNBP4QW140cs7wqA3DuqErVI= cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= -cloud.google.com/go/retail v1.14.4/go.mod h1:l/N7cMtY78yRnJqp5JW8emy7MB1nz8E4t2yfOmklYfg= -cloud.google.com/go/run v1.3.3/go.mod h1:WSM5pGyJ7cfYyYbONVQBN4buz42zFqwG67Q3ch07iK4= cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= -cloud.google.com/go/scheduler v1.10.4/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= -cloud.google.com/go/secretmanager v1.11.4/go.mod h1:wreJlbS9Zdq21lMzWmJ0XhWW2ZxgPeahsqeV/vZoJ3w= cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= -cloud.google.com/go/security v1.15.4/go.mod h1:oN7C2uIZKhxCLiAAijKUCuHLZbIt/ghYEo8MqwD/Ty4= cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= -cloud.google.com/go/securitycenter v1.24.2/go.mod h1:l1XejOngggzqwr4Fa2Cn+iWZGf+aBLTXtB/vXjy5vXM= cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= -cloud.google.com/go/servicedirectory v1.11.3/go.mod h1:LV+cHkomRLr67YoQy3Xq2tUXBGOs5z5bPofdq7qtiAw= -cloud.google.com/go/shell v1.7.4/go.mod h1:yLeXB8eKLxw0dpEmXQ/FjriYrBijNsONpwnWsdPqlKM= -cloud.google.com/go/spanner v1.51.0/go.mod h1:c5KNo5LQ1X5tJwma9rSQZsXNBDNvj4/n8BVc3LNahq0= cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= -cloud.google.com/go/speech v1.20.1/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= @@ -271,50 +173,22 @@ cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeL cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= -cloud.google.com/go/storagetransfer v1.10.3/go.mod h1:Up8LY2p6X68SZ+WToswpQbQHnJpOty/ACcMafuey8gc= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= -cloud.google.com/go/talent v1.6.5/go.mod h1:Mf5cma696HmE+P2BWJ/ZwYqeJXEeU0UqjHFXVLadEDI= -cloud.google.com/go/texttospeech v1.7.4/go.mod h1:vgv0002WvR4liGuSd5BJbWy4nDn5Ozco0uJymY5+U74= -cloud.google.com/go/tpu v1.6.4/go.mod h1:NAm9q3Rq2wIlGnOhpYICNI7+bpBebMJbh0yyp3aNw1Y= -cloud.google.com/go/trace v1.10.4/go.mod h1:Nso99EDIK8Mj5/zmB+iGr9dosS/bzWCJ8wGmE6TXNWY= -cloud.google.com/go/translate v1.9.3/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= -cloud.google.com/go/video v1.20.3/go.mod h1:TnH/mNZKVHeNtpamsSPygSR0iHtvrR/cW1/GDjN5+GU= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= -cloud.google.com/go/videointelligence v1.11.4/go.mod h1:kPBMAYsTPFiQxMLmmjpcZUMklJp3nC9+ipJJtprccD8= cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= -cloud.google.com/go/vision/v2 v2.7.5/go.mod h1:GcviprJLFfK9OLf0z8Gm6lQb6ZFUulvpZws+mm6yPLM= -cloud.google.com/go/vmmigration v1.7.4/go.mod h1:yBXCmiLaB99hEl/G9ZooNx2GyzgsjKnw5fWcINRgD70= -cloud.google.com/go/vmwareengine v1.0.3/go.mod h1:QSpdZ1stlbfKtyt6Iu19M6XRxjmXO+vb5a/R6Fvy2y4= -cloud.google.com/go/vpcaccess v1.7.4/go.mod h1:lA0KTvhtEOb/VOdnH/gwPuOzGgM+CWsmGu6bb4IoMKk= cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= -cloud.google.com/go/webrisk v1.9.4/go.mod h1:w7m4Ib4C+OseSr2GL66m0zMBywdrVNTDKsdEsfMl7X0= -cloud.google.com/go/websecurityscanner v1.6.4/go.mod h1:mUiyMQ+dGpPPRkHgknIZeCzSHJ45+fY4F52nZFDHm2o= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cloud.google.com/go/workflows v1.12.3/go.mod h1:fmOUeeqEwPzIU81foMjTRQIdwQHADi/vEr1cx9R1m5g= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-sdk-for-go v51.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= @@ -325,15 +199,11 @@ github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/ github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.54.19 h1:tyWV+07jagrNiCcGRzRhdtVjQs7Vy41NwsuOcl0IbVI= -github.com/aws/aws-sdk-go v1.54.19/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go v1.54.20 h1:FZ2UcXya7bUkvkpf7TaPmiL7EubK0go1nlXGLRwEsoo= +github.com/aws/aws-sdk-go v1.54.20/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.16.7 h1:zfBwXus3u14OszRxGcqCDS4MfMCv10e8SMJ2r8Xm0Ns= github.com/aws/aws-sdk-go-v2 v1.16.7/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3/go.mod h1:gNsR5CaXKmQSSzrmGxmwmct/r+ZBfbxorAuXYsj/M5Y= github.com/aws/aws-sdk-go-v2/config v1.15.13 h1:CJH9zn/Enst7lDiGpoguVt0lZr5HcpNVlRJWbJ6qreo= github.com/aws/aws-sdk-go-v2/config v1.15.13/go.mod h1:AcMu50uhV6wMBUlURnEXhr9b3fX6FLSTlEV89krTEGk= github.com/aws/aws-sdk-go-v2/credentials v1.12.8 h1:niTa7zc7uyOP2ufri0jPESBt1h9yP3Zc0q+xzih3h8o= @@ -346,15 +216,8 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.8 h1:2J+jdlBJWEmTyAwC82Y github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.8/go.mod h1:ZIV8GYoC6WLBW5KGs+o4rsc65/ozd+eQ0L31XF5VDwk= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.15 h1:QquxR7NH3ULBsKC+NoTpilzbKKS+5AELfNREInbhvas= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.15/go.mod h1:Tkrthp/0sNBShQQsamR7j/zY4p19tVTAs+nnqhH6R3c= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.5/go.mod h1:aIwFF3dUk95ocCcA3zfk3nhz0oLkpzHFWuMp8l/4nNs= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.47.2/go.mod h1:VoBcwURHnJVCWuXHdqVuG03i2lUlHJ5DTTqDSyCdEcc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3/go.mod h1:gkb2qADY+OHaGLKNTYxMaQNacfeyQpZ4csDTQMeFmcw= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.9/go.mod h1:EF5RLnD9l0xvEWwMRcktIS/dI6lF8lU5eV3B13k6sWo= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.8 h1:oKnAXxSF2FUvfgw8uzU/v9OTYorJJZ8eBmWhr9TWVVQ= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.8/go.mod h1:rDVhIMAX9N2r8nWxDUlbubvvaFMnfsm+3jAV7q+rpM4= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.8/go.mod h1:JlVwmWtT/1c5W+6oUsjXjAJ0iJZ+hlghdrDy/8JxGCU= -github.com/aws/aws-sdk-go-v2/service/s3 v1.27.1/go.mod h1:NffjpNsMUFXp6Ok/PahrktAncoekWrywvmIK83Q2raE= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.13/go.mod h1:ByZbrzJwj5ScH6gvAlGslJK/LgJtPd0tteTBoG+yjVc= github.com/aws/aws-sdk-go-v2/service/sso v1.11.11 h1:XOJWXNFXJyapJqQuCIPfftsOf0XZZioM0kK6OPRt9MY= github.com/aws/aws-sdk-go-v2/service/sso v1.11.11/go.mod h1:MO4qguFjs3wPGcCSpQ7kOFTwRvb+eu+fn+1vKleGHUk= github.com/aws/aws-sdk-go-v2/service/sts v1.16.9 h1:yOfILxyjmtr2ubRkRJldlHDFBhf5vw4CzhbwWIBmimQ= @@ -363,16 +226,9 @@ github.com/aws/smithy-go v1.12.0 h1:gXpeZel/jPoWQ7OEmLIgCUnhkFftqNfwWUwAHSlp1v0= github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= -github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/bradleyfalzon/ghinstallation v1.1.1/go.mod h1:vyCmHTciHx/uuyN82Zc3rXN3X2KTK8nUTCrTMwAhcug= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -382,29 +238,16 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= -github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/ekristen/aws-nuke v2.10.0+incompatible/go.mod h1:Ut8za5xnR9uu65XWYGQ+D/MWWD0C/Q2zgA/4nVVk/B8= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -414,34 +257,16 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/gemnasium/logrus-graylog-hook/v3 v3.1.0/go.mod h1:wi1zWv9tIvyLSMLCAzgRP+YR24oLVQVBHfPPKjtht44= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -477,17 +302,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gonvenience/bunt v1.3.5/go.mod h1:7ApqkVBEWvX04oJ28Q2WeI/BvJM6VtukaJAU/q/pTs8= -github.com/gonvenience/neat v1.3.12/go.mod h1:8OljAIgPelN0uPPO94VBqxK+Kz98d6ZFwHDg5o/PfkE= -github.com/gonvenience/term v1.0.2/go.mod h1:wThTR+3MzWtWn7XGVW6qQ65uaVf8GHED98KmwpuEQeo= -github.com/gonvenience/text v1.0.7/go.mod h1:OAjH+mohRszffLY6OjgQcUXiSkbrIavooFpfIt1ZwAs= -github.com/gonvenience/wrap v1.1.2/go.mod h1:GiryBSXoI3BAAhbWD1cZVj7RZmtiu0ERi/6R6eJfslI= -github.com/gonvenience/ytbx v1.4.4/go.mod h1:w37+MKCPcCMY/jpPNmEklD4xKqrOAVBO6kIWW2+uI6M= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -503,18 +319,14 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw= -github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E= -github.com/google/go-github/v44 v44.1.0/go.mod h1:iWn00mWcP6PRWHhXm0zuFJ8wbEjE5AGO5D5HXYM4zgw= -github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -535,8 +347,8 @@ github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -553,13 +365,8 @@ github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqE github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= -github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/gruntwork-io/go-commons v0.13.3 h1:tRNMZgXbmD9cgqhV/bEdYK4e0SndNKGH5ed2HCYhfnc= -github.com/gruntwork-io/go-commons v0.13.3/go.mod h1:ILC/UDRkC/+vTQNhdfnN/b4WySgc5kwXUO338hnS1f4= github.com/gruntwork-io/terratest v0.47.0 h1:xIy1pT7NbGVlMLDZEHl3+3iSnvffh8tN2pL6idn448c= github.com/gruntwork-io/terratest v0.47.0/go.mod h1:oywHw1cFKXSYvKPm27U7quZVzDUlA22H2xUrKCe26xM= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -582,112 +389,61 @@ github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5R github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= -github.com/homeport/dyff v1.6.0/go.mod h1:FlAOFYzeKvxmU5nTrnG+qrlJVWpsFew7pt8L99p5q8k= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3/go.mod h1:x1uk6vxTiVuNt6S5R2UYgdhpj3oKojXvOXauHZ7dEnI= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-zglob v0.0.3 h1:6Ry4EYsScDyt5di4OI6xw1bYhOqfE5S33Z1OPy+d+To= github.com/mattn/go-zglob v0.0.3/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= -github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 h1:NK3O7S5FRD/wj7ORQ5C3Mx1STpyEMuFe+/F0Lakd1Nk= -github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4/go.mod h1:FqD3ES5hx6zpzDainDaHgkTIqrPaI9uX4CVWqYZoQjY= -github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= -github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs= -github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rebuy-de/aws-nuke v2.10.0+incompatible h1:RLi5bm7BZAxOVeNjYA2JafFvZTuAhALpNQiD+Bjfz+E= -github.com/rebuy-de/aws-nuke v2.10.0+incompatible/go.mod h1:DyMsiA805cBWrullfs3ZHSEvbJ3mu7fsDuc4PG2Gt7Y= -github.com/rebuy-de/aws-nuke/v2 v2.25.0 h1:uM/KoDOOIau1Gcx++D3oDFL1vlLPj9uuzQKtNVZxrHs= -github.com/rebuy-de/aws-nuke/v2 v2.25.0/go.mod h1:2TTX8eMpEsFZPYCK1QaAb9uPYtdO9MeLQPKM9GQfY/w= -github.com/rebuy-de/rebuy-go-sdk/v4 v4.5.1/go.mod h1:ZSfnIcE8RFKz7IO6AFZjETDbPyMdUjtxCea9R7Q6pQE= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/slack-go/slack v0.10.3/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -697,23 +453,14 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/texttheater/golang-levenshtein v1.0.1/go.mod h1:PYAKrbF5sAiq9wd+H82hs7gNaen0CplQ9uvm6+enD/8= github.com/tmccombs/hcl2json v0.3.4 h1:pYzRaHVTJu6TfFumACORClRtsK431eeuv7WjNNLjT90= github.com/tmccombs/hcl2json v0.3.4/go.mod h1:l3Aq9eUyhC+0v26BH08BZHeyWEtOYcFtbu2i5Ryywig= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.20.2 h1:dKA0LUjznZpwmmbrc0pOgcLTEilnHeM8Av9Yng77gHM= -github.com/urfave/cli/v2 v2.20.2/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= -github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -755,7 +502,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -782,7 +528,6 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -874,8 +619,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -937,17 +682,15 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -960,8 +703,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1004,7 +747,6 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -1013,7 +755,6 @@ golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1021,7 +762,6 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1088,6 +828,7 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1194,7 +935,6 @@ google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2Ky google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20231120223509-83a465c0220f/go.mod h1:iIgEblxoG4klcXsG0d9cpoxJ4xndv6+1FkDROCHhPRI= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1254,19 +994,18 @@ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGm google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1274,16 +1013,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= -k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= -k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index 6716eb0..3f45c3e 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -1,108 +1,109 @@ package aws_component_helper import ( - "fmt" - "strings" - "testing" - - "dario.cat/mergo" "github.com/cloudposse/test-helpers/pkg/atmos" - "github.com/stretchr/testify/require" ) -func GetAtmosOptions(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) *atmos.Options { - mergedVars := map[string]interface{}{ - "attributes": []string{suite.RandomIdentifier}, - "region": suite.AwsRegion, - } - - // If we are not skipping the nuking of the test account, add the default tags - if !suite.SkipNukeTestAccount { - nukeVars := map[string]interface{}{ - "default_tags": map[string]string{ - "CreatedByTerratestRun": suite.RandomIdentifier, - }, - } - - err := mergo.Merge(&mergedVars, nukeVars) - require.NoError(t, err) - } - - // Merge in any additional vars passed in - err := mergo.Merge(&mergedVars, vars) - require.NoError(t, err) - - atmosOptions := atmos.WithDefaultRetryableErrors(t, &atmos.Options{ - AtmosBasePath: suite.TempDir, - Component: componentName, - Stack: stackName, - NoColor: true, - BackendConfig: map[string]interface{}{ - "workspace_key_prefix": strings.Join([]string{suite.RandomIdentifier, stackName}, "-"), - }, - Vars: mergedVars, - }) - return atmosOptions -} - -func deployDependencies(t *testing.T, suite *TestSuite) error { - for _, dependency := range suite.Dependencies { - _, _, err := deployComponent(t, suite, dependency.ComponentName, dependency.StackName, map[string]interface{}{}) - if err != nil { - return err - } - } - - return nil -} - -func destroyDependencies(t *testing.T, suite *TestSuite) error { - // iterate over dependencies in reverse order and destroy them - for i := len(suite.Dependencies) - 1; i >= 0; i-- { - _, _, err := destroyComponent(t, suite, suite.Dependencies[i].ComponentName, suite.Dependencies[i].StackName, map[string]interface{}{}) - if err != nil { - return err - } - } - return nil -} - -func deployComponent(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) (*atmos.Options, string, error) { - options := GetAtmosOptions(t, suite, componentName, stackName, vars) - out, err := atmos.ApplyE(t, options) +var ( + atmosApply = atmos.Apply + atmosDestroy = atmos.Destroy - return options, out, err -} - -func verifyEnabledFlag(t *testing.T, suite *TestSuite, componentName string, stackName string) (*atmos.Options, error) { - vars := map[string]interface{}{ - "enabled": false, - } - options := GetAtmosOptions(t, suite, componentName, stackName, vars) - - exitCode, err := atmos.PlanExitCodeE(t, options) - - if err != nil { - return options, err - } - - if exitCode != 0 { - return options, fmt.Errorf("running atmos terraform plan with enabled flag set to false resulted in resource changes") - } - - return options, nil -} - -func destroyComponent(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) (*atmos.Options, string, error) { - options := GetAtmosOptions(t, suite, componentName, stackName, vars) - out, err := atmos.DestroyE(t, options) - - return options, out, err -} - -func vendorDependencies(t *testing.T, suite *TestSuite) error { - options := GetAtmosOptions(t, suite, "", "", map[string]interface{}{}) - _, err := atmos.VendorPullE(t, options) + atmosPlanExitCodeE = atmos.PlanExitCodeE +) - return err -} +//func GetAtmosOptions(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) *atmos.Options { +// mergedVars := map[string]interface{}{ +// "attributes": []string{suite.RandomIdentifier}, +// "region": suite.AwsRegion, +// } +// +// // If we are not skipping the nuking of the test account, add the default tags +// if !suite.SkipNukeTestAccount { +// nukeVars := map[string]interface{}{ +// "default_tags": map[string]string{ +// "CreatedByTerratestRun": suite.RandomIdentifier, +// }, +// } +// +// err := mergo.Merge(&mergedVars, nukeVars) +// require.NoError(t, err) +// } +// +// // Merge in any additional vars passed in +// err := mergo.Merge(&mergedVars, vars) +// require.NoError(t, err) +// +// atmosOptions := atmos.WithDefaultRetryableErrors(t, &atmos.Options{ +// AtmosBasePath: suite.TempDir, +// Component: componentName, +// Stack: stackName, +// NoColor: true, +// BackendConfig: map[string]interface{}{ +// "workspace_key_prefix": strings.Join([]string{suite.RandomIdentifier, stackName}, "-"), +// }, +// Vars: mergedVars, +// }) +// return atmosOptions +//} +// +//func deployDependencies(t *testing.T, suite *TestSuite) error { +// for _, dependency := range suite.Dependencies { +// _, _, err := deployComponent(t, suite, dependency.ComponentName, dependency.StackName, map[string]interface{}{}) +// if err != nil { +// return err +// } +// } +// +// return nil +//} +// +//func destroyDependencies(t *testing.T, suite *TestSuite) error { +// // iterate over dependencies in reverse order and destroy them +// for i := len(suite.Dependencies) - 1; i >= 0; i-- { +// _, _, err := destroyComponent(t, suite, suite.Dependencies[i].ComponentName, suite.Dependencies[i].StackName, map[string]interface{}{}) +// if err != nil { +// return err +// } +// } +// return nil +//} +// +//func deployComponent(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) (*atmos.Options, string, error) { +// options := GetAtmosOptions(t, suite, componentName, stackName, vars) +// out, err := atmos.ApplyE(t, options) +// +// return options, out, err +//} + +//func verifyEnabledFlag(t *testing.T, suite *TestSuite, componentName string, stackName string) (*atmos.Options, error) { +// vars := map[string]interface{}{ +// "enabled": false, +// } +// options := GetAtmosOptions(t, suite, componentName, stackName, vars) +// +// exitCode, err := atmos.PlanExitCodeE(t, options) +// +// if err != nil { +// return options, err +// } +// +// if exitCode != 0 { +// return options, fmt.Errorf("running atmos terraform plan with enabled flag set to false resulted in resource changes") +// } +// +// return options, nil +//} + +//func destroyComponent(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) (*atmos.Options, string, error) { +// options := GetAtmosOptions(t, suite, componentName, stackName, vars) +// out, err := atmos.DestroyE(t, options) +// +// return options, out, err +//} +// +//func vendorDependencies(t *testing.T, suite *TestSuite) error { +// options := GetAtmosOptions(t, suite, "", "", map[string]interface{}{}) +// _, err := atmos.VendorPullE(t, options) +// +// return err +//} diff --git a/pkg/atmos/aws-component-helper/atmos_component.go b/pkg/atmos/aws-component-helper/atmos_component.go new file mode 100644 index 0000000..ac2cf04 --- /dev/null +++ b/pkg/atmos/aws-component-helper/atmos_component.go @@ -0,0 +1,36 @@ +package aws_component_helper + +import ( + "dario.cat/mergo" + "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/stretchr/testify/require" + "testing" +) + +type AtmosComponent struct { + Component string + Stack string + atmosOptions *atmos.Options +} + +func NewAtmosComponent(component string, stack string, options *atmos.Options) *AtmosComponent { + return &AtmosComponent{ + Component: component, + Stack: stack, + atmosOptions: options, + } +} + +func (ac *AtmosComponent) getAtmosOptions(t *testing.T, vars map[string]interface{}) *atmos.Options { + result, _ := ac.atmosOptions.Clone() + + // Merge in any additional vars passed in + err := mergo.Merge(&result.Vars, vars) + require.NoError(t, err) + + result.Component = ac.Component + result.Stack = ac.Component + + atmosOptions := atmos.WithDefaultRetryableErrors(t, result) + return atmosOptions +} diff --git a/pkg/atmos/aws-component-helper/atmos_component_test.go b/pkg/atmos/aws-component-helper/atmos_component_test.go new file mode 100644 index 0000000..dd36f44 --- /dev/null +++ b/pkg/atmos/aws-component-helper/atmos_component_test.go @@ -0,0 +1,16 @@ +package aws_component_helper + +import ( + "github.com/cloudposse/test-helpers/pkg/atmos" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAtmosComponent(t *testing.T) { + // Create a temporary atmos component + component := NewAtmosComponent("vpc", "default-test", &atmos.Options{}) + + assert.Equal(t, component.Component, "vpc") + assert.Equal(t, component.Stack, "default-test") +} diff --git a/pkg/atmos/aws-component-helper/cli.go b/pkg/atmos/aws-component-helper/cli.go index d20047c..8ba0d74 100644 --- a/pkg/atmos/aws-component-helper/cli.go +++ b/pkg/atmos/aws-component-helper/cli.go @@ -1,46 +1,44 @@ package aws_component_helper -import "flag" - -func parseCLIArgs(ts *TestSuite) *TestSuite { - forceNewSuite := flag.Bool("force-new-suite", false, "force new suite") - suiteIndex := flag.Int("suite-index", -1, "suite index") - skipAwsNuke := flag.Bool("skip-aws-nuke", ts.SkipNukeTestAccount, "skip aws nuke") - skipDeployDependencies := flag.Bool("skip-deploy-deps", ts.SkipDeployDependencies, "skip deploy dependencies") - skipDestroyDependencies := flag.Bool("skip-destroy-deps", ts.SkipDestroyDependencies, "skip destroy dependencies") - skipSetupComponentUnderTest := flag.Bool("skip-setup-cut", ts.SkipSetupComponentUnderTest, "skip setup component under test") - skipDeployComponentUnderTest := flag.Bool("skip-deploy-cut", ts.SkipDeployComponentUnderTest, "skip deploy component under test") - skipDestroyComponentUnderTest := flag.Bool("skip-destroy-cut", ts.SkipDestroyComponentUnderTest, "skip destroy component under test") - skipTeardownTestSuite := flag.Bool("skip-teardown", ts.SkipTeardownTestSuite, "skip test suite teardown") - skipVendorDependencies := flag.Bool("skip-vendor", ts.SkipVendorDependencies, "skip vendor dependencies") - skipVerifyEnabledFlag := flag.Bool("skip-verify-enabled-flag", ts.SkipVerifyEnabledFlag, "skip verify enabled flag") - skipTests := flag.Bool("skip-tests", ts.SkipTests, "skip tests") - - flag.Parse() - - ts.ForceNewSuite = *forceNewSuite - ts.Index = *suiteIndex - ts.SkipNukeTestAccount = *skipAwsNuke - ts.SkipDeployDependencies = *skipDeployDependencies - ts.SkipDestroyDependencies = *skipDestroyDependencies - ts.SkipSetupComponentUnderTest = *skipSetupComponentUnderTest - ts.SkipDeployComponentUnderTest = *skipDeployComponentUnderTest - ts.SkipDestroyComponentUnderTest = *skipDestroyComponentUnderTest - ts.SkipTeardownTestSuite = *skipTeardownTestSuite - ts.SkipVendorDependencies = *skipVendorDependencies - ts.SkipVerifyEnabledFlag = *skipVerifyEnabledFlag - ts.SkipTests = *skipTests - return ts -} - -func skipDestroyDependencies(ts *TestSuite) bool { - return ts.SkipDestroyDependencies || ts.SkipDestroyComponentUnderTest -} - -func skipTeardownTestSuite(ts *TestSuite) bool { - return ts.SkipTeardownTestSuite || skipDestroyDependencies(ts) -} - -func skipNukeTestAccount(ts *TestSuite) bool { - return ts.SkipNukeTestAccount || skipTeardownTestSuite(ts) -} +//func parseCLIArgs(ts *TestSuite) *TestSuite { +// forceNewSuite := flag.Bool("force-new-suite", false, "force new suite") +// suiteIndex := flag.Int("suite-index", -1, "suite index") +// skipAwsNuke := flag.Bool("skip-aws-nuke", ts.SkipNukeTestAccount, "skip aws nuke") +// skipDeployDependencies := flag.Bool("skip-deploy-deps", ts.SkipDeployDependencies, "skip deploy dependencies") +// skipDestroyDependencies := flag.Bool("skip-destroy-deps", ts.SkipDestroyDependencies, "skip destroy dependencies") +// skipSetupComponentUnderTest := flag.Bool("skip-setup-cut", ts.SkipSetupComponentUnderTest, "skip setup component under test") +// skipDeployComponentUnderTest := flag.Bool("skip-deploy-cut", ts.SkipDeployComponentUnderTest, "skip deploy component under test") +// skipDestroyComponentUnderTest := flag.Bool("skip-destroy-cut", ts.SkipDestroyComponentUnderTest, "skip destroy component under test") +// skipTeardownTestSuite := flag.Bool("skip-teardown", ts.SkipTeardownTestSuite, "skip test suite teardown") +// skipVendorDependencies := flag.Bool("skip-vendor", ts.SkipVendorDependencies, "skip vendor dependencies") +// skipVerifyEnabledFlag := flag.Bool("skip-verify-enabled-flag", ts.SkipVerifyEnabledFlag, "skip verify enabled flag") +// skipTests := flag.Bool("skip-tests", ts.SkipTests, "skip tests") +// +// flag.Parse() +// +// ts.ForceNewSuite = *forceNewSuite +// ts.Index = *suiteIndex +// ts.SkipNukeTestAccount = *skipAwsNuke +// ts.SkipDeployDependencies = *skipDeployDependencies +// ts.SkipDestroyDependencies = *skipDestroyDependencies +// ts.SkipSetupComponentUnderTest = *skipSetupComponentUnderTest +// ts.SkipDeployComponentUnderTest = *skipDeployComponentUnderTest +// ts.SkipDestroyComponentUnderTest = *skipDestroyComponentUnderTest +// ts.SkipTeardownTestSuite = *skipTeardownTestSuite +// ts.SkipVendorDependencies = *skipVendorDependencies +// ts.SkipVerifyEnabledFlag = *skipVerifyEnabledFlag +// ts.SkipTests = *skipTests +// return ts +//} +// +//func skipDestroyDependencies(ts *TestSuite) bool { +// return ts.SkipDestroyDependencies || ts.SkipDestroyComponentUnderTest +//} +// +//func skipTeardownTestSuite(ts *TestSuite) bool { +// return ts.SkipTeardownTestSuite || skipDestroyDependencies(ts) +//} +// +//func skipNukeTestAccount(ts *TestSuite) bool { +// return ts.SkipNukeTestAccount || skipTeardownTestSuite(ts) +//} diff --git a/pkg/atmos/aws-component-helper/cli_test.go b/pkg/atmos/aws-component-helper/cli_test.go index ecc3252..a290961 100644 --- a/pkg/atmos/aws-component-helper/cli_test.go +++ b/pkg/atmos/aws-component-helper/cli_test.go @@ -1,305 +1,306 @@ package aws_component_helper -import ( - "flag" - "os" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestParseCLIArgs(t *testing.T) { - // Save original args and restore after test - originalArgs := os.Args - defer func() { os.Args = originalArgs }() - - tests := []struct { - name string - args []string - initial *TestSuite - expected *TestSuite - }{ - { - name: "default values not changed when no flags provided", - args: []string{"prog"}, - initial: &TestSuite{ - SkipNukeTestAccount: false, - SkipDeployDependencies: false, - SkipDestroyDependencies: false, - SkipSetupComponentUnderTest: false, - SkipDeployComponentUnderTest: false, - SkipDestroyComponentUnderTest: false, - SkipTeardownTestSuite: false, - SkipVendorDependencies: false, - SkipVerifyEnabledFlag: false, - SkipTests: false, - ForceNewSuite: false, - Index: -1, - }, - expected: &TestSuite{ - SkipNukeTestAccount: false, - SkipDeployDependencies: false, - SkipDestroyDependencies: false, - SkipSetupComponentUnderTest: false, - SkipDeployComponentUnderTest: false, - SkipDestroyComponentUnderTest: false, - SkipTeardownTestSuite: false, - SkipVendorDependencies: false, - SkipVerifyEnabledFlag: false, - SkipTests: false, - ForceNewSuite: false, - Index: -1, - }, - }, - { - name: "all skip flags set to true", - args: []string{"prog", - "-skip-aws-nuke", - "-skip-deploy-deps", - "-skip-destroy-deps", - "-skip-setup-cut", - "-skip-deploy-cut", - "-skip-destroy-cut", - "-skip-teardown", - "-skip-vendor", - "-skip-verify-enabled-flag", - "-skip-tests", - }, - initial: &TestSuite{}, - expected: &TestSuite{ - SkipNukeTestAccount: true, - SkipDeployDependencies: true, - SkipDestroyDependencies: true, - SkipSetupComponentUnderTest: true, - SkipDeployComponentUnderTest: true, - SkipDestroyComponentUnderTest: true, - SkipTeardownTestSuite: true, - SkipVendorDependencies: true, - SkipVerifyEnabledFlag: true, - SkipTests: true, - ForceNewSuite: false, - Index: -1, - }, - }, - { - name: "force new suite and suite index", - args: []string{"prog", - "-force-new-suite", - "-suite-index=5", - }, - initial: &TestSuite{}, - expected: &TestSuite{ - ForceNewSuite: true, - Index: 5, - }, - }, - { - name: "initial values respected when not overridden", - args: []string{"prog", - "-skip-aws-nuke", - "-skip-deploy-deps", - }, - initial: &TestSuite{ - SkipDestroyDependencies: true, - SkipSetupComponentUnderTest: true, - SkipDeployComponentUnderTest: true, - SkipDestroyComponentUnderTest: true, - SkipTeardownTestSuite: true, - SkipVendorDependencies: true, - SkipVerifyEnabledFlag: true, - SkipTests: true, - }, - expected: &TestSuite{ - SkipNukeTestAccount: true, - SkipDeployDependencies: true, - SkipDestroyDependencies: true, - SkipSetupComponentUnderTest: true, - SkipDeployComponentUnderTest: true, - SkipDestroyComponentUnderTest: true, - SkipTeardownTestSuite: true, - SkipVendorDependencies: true, - SkipVerifyEnabledFlag: true, - SkipTests: true, - ForceNewSuite: false, - Index: -1, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - // Reset flags for each test - flag.CommandLine = flag.NewFlagSet(tt.args[0], flag.ExitOnError) - os.Args = tt.args - - result := parseCLIArgs(tt.initial) - assert.Equal(t, tt.expected, result) - }) - } -} - -func TestSkipDestroyDependencies(t *testing.T) { - tests := []struct { - name string - ts *TestSuite - expected bool - }{ - { - name: "both flags false", - ts: &TestSuite{ - SkipDestroyDependencies: false, - SkipDestroyComponentUnderTest: false, - }, - expected: false, - }, - { - name: "SkipDestroyDependencies true", - ts: &TestSuite{ - SkipDestroyDependencies: true, - SkipDestroyComponentUnderTest: false, - }, - expected: true, - }, - { - name: "SkipDestroyComponentUnderTest true", - ts: &TestSuite{ - SkipDestroyDependencies: false, - SkipDestroyComponentUnderTest: true, - }, - expected: true, - }, - { - name: "both flags true", - ts: &TestSuite{ - SkipDestroyDependencies: true, - SkipDestroyComponentUnderTest: true, - }, - expected: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result := skipDestroyDependencies(tt.ts) - assert.Equal(t, tt.expected, result) - }) - } -} - -func TestSkipTeardownTestSuite(t *testing.T) { - tests := []struct { - name string - ts *TestSuite - expected bool - }{ - { - name: "all flags false", - ts: &TestSuite{ - SkipTeardownTestSuite: false, - SkipDestroyDependencies: false, - SkipDestroyComponentUnderTest: false, - }, - expected: false, - }, - { - name: "SkipTeardownTestSuite true", - ts: &TestSuite{ - SkipTeardownTestSuite: true, - SkipDestroyDependencies: false, - SkipDestroyComponentUnderTest: false, - }, - expected: true, - }, - { - name: "SkipDestroyDependencies true", - ts: &TestSuite{ - SkipTeardownTestSuite: false, - SkipDestroyDependencies: true, - SkipDestroyComponentUnderTest: false, - }, - expected: true, - }, - { - name: "SkipDestroyComponentUnderTest true", - ts: &TestSuite{ - SkipTeardownTestSuite: false, - SkipDestroyDependencies: false, - SkipDestroyComponentUnderTest: true, - }, - expected: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result := skipTeardownTestSuite(tt.ts) - assert.Equal(t, tt.expected, result) - }) - } -} - -func TestSkipNukeTestAccount(t *testing.T) { - tests := []struct { - name string - ts *TestSuite - expected bool - }{ - { - name: "all flags false", - ts: &TestSuite{ - SkipNukeTestAccount: false, - SkipTeardownTestSuite: false, - SkipDestroyDependencies: false, - SkipDestroyComponentUnderTest: false, - }, - expected: false, - }, - { - name: "SkipNukeTestAccount true", - ts: &TestSuite{ - SkipNukeTestAccount: true, - SkipTeardownTestSuite: false, - SkipDestroyDependencies: false, - SkipDestroyComponentUnderTest: false, - }, - expected: true, - }, - { - name: "SkipTeardownTestSuite true", - ts: &TestSuite{ - SkipNukeTestAccount: false, - SkipTeardownTestSuite: true, - SkipDestroyDependencies: false, - SkipDestroyComponentUnderTest: false, - }, - expected: true, - }, - { - name: "SkipDestroyDependencies true", - ts: &TestSuite{ - SkipNukeTestAccount: false, - SkipTeardownTestSuite: false, - SkipDestroyDependencies: true, - SkipDestroyComponentUnderTest: false, - }, - expected: true, - }, - { - name: "SkipDestroyComponentUnderTest true", - ts: &TestSuite{ - SkipNukeTestAccount: false, - SkipTeardownTestSuite: false, - SkipDestroyDependencies: false, - SkipDestroyComponentUnderTest: true, - }, - expected: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result := skipNukeTestAccount(tt.ts) - assert.Equal(t, tt.expected, result) - }) - } -} +// +//import ( +// "flag" +// "os" +// "testing" +// +// "github.com/stretchr/testify/assert" +//) +// +//func TestParseCLIArgs(t *testing.T) { +// // Save original args and restore after test +// originalArgs := os.Args +// defer func() { os.Args = originalArgs }() +// +// tests := []struct { +// name string +// args []string +// initial *TestSuite +// expected *TestSuite +// }{ +// { +// name: "default values not changed when no flags provided", +// args: []string{"prog"}, +// initial: &TestSuite{ +// SkipNukeTestAccount: false, +// SkipDeployDependencies: false, +// SkipDestroyDependencies: false, +// SkipSetupComponentUnderTest: false, +// SkipDeployComponentUnderTest: false, +// SkipDestroyComponentUnderTest: false, +// SkipTeardownTestSuite: false, +// SkipVendorDependencies: false, +// SkipVerifyEnabledFlag: false, +// SkipTests: false, +// ForceNewSuite: false, +// Index: -1, +// }, +// expected: &TestSuite{ +// SkipNukeTestAccount: false, +// SkipDeployDependencies: false, +// SkipDestroyDependencies: false, +// SkipSetupComponentUnderTest: false, +// SkipDeployComponentUnderTest: false, +// SkipDestroyComponentUnderTest: false, +// SkipTeardownTestSuite: false, +// SkipVendorDependencies: false, +// SkipVerifyEnabledFlag: false, +// SkipTests: false, +// ForceNewSuite: false, +// Index: -1, +// }, +// }, +// { +// name: "all skip flags set to true", +// args: []string{"prog", +// "-skip-aws-nuke", +// "-skip-deploy-deps", +// "-skip-destroy-deps", +// "-skip-setup-cut", +// "-skip-deploy-cut", +// "-skip-destroy-cut", +// "-skip-teardown", +// "-skip-vendor", +// "-skip-verify-enabled-flag", +// "-skip-tests", +// }, +// initial: &TestSuite{}, +// expected: &TestSuite{ +// SkipNukeTestAccount: true, +// SkipDeployDependencies: true, +// SkipDestroyDependencies: true, +// SkipSetupComponentUnderTest: true, +// SkipDeployComponentUnderTest: true, +// SkipDestroyComponentUnderTest: true, +// SkipTeardownTestSuite: true, +// SkipVendorDependencies: true, +// SkipVerifyEnabledFlag: true, +// SkipTests: true, +// ForceNewSuite: false, +// Index: -1, +// }, +// }, +// { +// name: "force new suite and suite index", +// args: []string{"prog", +// "-force-new-suite", +// "-suite-index=5", +// }, +// initial: &TestSuite{}, +// expected: &TestSuite{ +// ForceNewSuite: true, +// Index: 5, +// }, +// }, +// { +// name: "initial values respected when not overridden", +// args: []string{"prog", +// "-skip-aws-nuke", +// "-skip-deploy-deps", +// }, +// initial: &TestSuite{ +// SkipDestroyDependencies: true, +// SkipSetupComponentUnderTest: true, +// SkipDeployComponentUnderTest: true, +// SkipDestroyComponentUnderTest: true, +// SkipTeardownTestSuite: true, +// SkipVendorDependencies: true, +// SkipVerifyEnabledFlag: true, +// SkipTests: true, +// }, +// expected: &TestSuite{ +// SkipNukeTestAccount: true, +// SkipDeployDependencies: true, +// SkipDestroyDependencies: true, +// SkipSetupComponentUnderTest: true, +// SkipDeployComponentUnderTest: true, +// SkipDestroyComponentUnderTest: true, +// SkipTeardownTestSuite: true, +// SkipVendorDependencies: true, +// SkipVerifyEnabledFlag: true, +// SkipTests: true, +// ForceNewSuite: false, +// Index: -1, +// }, +// }, +// } +// +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// // Reset flags for each test +// flag.CommandLine = flag.NewFlagSet(tt.args[0], flag.ExitOnError) +// os.Args = tt.args +// +// result := parseCLIArgs(tt.initial) +// assert.Equal(t, tt.expected, result) +// }) +// } +//} +// +//func TestSkipDestroyDependencies(t *testing.T) { +// tests := []struct { +// name string +// ts *TestSuite +// expected bool +// }{ +// { +// name: "both flags false", +// ts: &TestSuite{ +// SkipDestroyDependencies: false, +// SkipDestroyComponentUnderTest: false, +// }, +// expected: false, +// }, +// { +// name: "SkipDestroyDependencies true", +// ts: &TestSuite{ +// SkipDestroyDependencies: true, +// SkipDestroyComponentUnderTest: false, +// }, +// expected: true, +// }, +// { +// name: "SkipDestroyComponentUnderTest true", +// ts: &TestSuite{ +// SkipDestroyDependencies: false, +// SkipDestroyComponentUnderTest: true, +// }, +// expected: true, +// }, +// { +// name: "both flags true", +// ts: &TestSuite{ +// SkipDestroyDependencies: true, +// SkipDestroyComponentUnderTest: true, +// }, +// expected: true, +// }, +// } +// +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// result := skipDestroyDependencies(tt.ts) +// assert.Equal(t, tt.expected, result) +// }) +// } +//} +// +//func TestSkipTeardownTestSuite(t *testing.T) { +// tests := []struct { +// name string +// ts *TestSuite +// expected bool +// }{ +// { +// name: "all flags false", +// ts: &TestSuite{ +// SkipTeardownTestSuite: false, +// SkipDestroyDependencies: false, +// SkipDestroyComponentUnderTest: false, +// }, +// expected: false, +// }, +// { +// name: "SkipTeardownTestSuite true", +// ts: &TestSuite{ +// SkipTeardownTestSuite: true, +// SkipDestroyDependencies: false, +// SkipDestroyComponentUnderTest: false, +// }, +// expected: true, +// }, +// { +// name: "SkipDestroyDependencies true", +// ts: &TestSuite{ +// SkipTeardownTestSuite: false, +// SkipDestroyDependencies: true, +// SkipDestroyComponentUnderTest: false, +// }, +// expected: true, +// }, +// { +// name: "SkipDestroyComponentUnderTest true", +// ts: &TestSuite{ +// SkipTeardownTestSuite: false, +// SkipDestroyDependencies: false, +// SkipDestroyComponentUnderTest: true, +// }, +// expected: true, +// }, +// } +// +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// result := skipTeardownTestSuite(tt.ts) +// assert.Equal(t, tt.expected, result) +// }) +// } +//} +// +//func TestSkipNukeTestAccount(t *testing.T) { +// tests := []struct { +// name string +// ts *TestSuite +// expected bool +// }{ +// { +// name: "all flags false", +// ts: &TestSuite{ +// SkipNukeTestAccount: false, +// SkipTeardownTestSuite: false, +// SkipDestroyDependencies: false, +// SkipDestroyComponentUnderTest: false, +// }, +// expected: false, +// }, +// { +// name: "SkipNukeTestAccount true", +// ts: &TestSuite{ +// SkipNukeTestAccount: true, +// SkipTeardownTestSuite: false, +// SkipDestroyDependencies: false, +// SkipDestroyComponentUnderTest: false, +// }, +// expected: true, +// }, +// { +// name: "SkipTeardownTestSuite true", +// ts: &TestSuite{ +// SkipNukeTestAccount: false, +// SkipTeardownTestSuite: true, +// SkipDestroyDependencies: false, +// SkipDestroyComponentUnderTest: false, +// }, +// expected: true, +// }, +// { +// name: "SkipDestroyDependencies true", +// ts: &TestSuite{ +// SkipNukeTestAccount: false, +// SkipTeardownTestSuite: false, +// SkipDestroyDependencies: true, +// SkipDestroyComponentUnderTest: false, +// }, +// expected: true, +// }, +// { +// name: "SkipDestroyComponentUnderTest true", +// ts: &TestSuite{ +// SkipNukeTestAccount: false, +// SkipTeardownTestSuite: false, +// SkipDestroyDependencies: false, +// SkipDestroyComponentUnderTest: true, +// }, +// expected: true, +// }, +// } +// +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// result := skipNukeTestAccount(tt.ts) +// assert.Equal(t, tt.expected, result) +// }) +// } +//} diff --git a/pkg/atmos/aws-component-helper/setup_component.go b/pkg/atmos/aws-component-helper/setup_component.go index 7786259..664b948 100644 --- a/pkg/atmos/aws-component-helper/setup_component.go +++ b/pkg/atmos/aws-component-helper/setup_component.go @@ -1,41 +1,35 @@ package aws_component_helper -import ( - "fmt" - "os" - "path/filepath" -) +//func setupComponentUnderTest(ts *TestSuite) error { +// err := createComponentDir(ts) +// if err != nil { +// return err +// } +// +// err = copyComponentSrcToTempDir(ts) +// if err != nil { +// return err +// } +// return nil +//} -func setupComponentUnderTest(ts *TestSuite) error { - err := createComponentDir(ts) - if err != nil { - return err - } - - err = copyComponentSrcToTempDir(ts) - if err != nil { - return err - } - return nil -} - -func copyComponentSrcToTempDir(ts *TestSuite) error { - - destDir := filepath.Join(ts.TempDir, "components", "terraform", ts.ComponentName) - fmt.Println("copying contents of", ts.ComponentSrcPath, "to", destDir) - err := copyDirectoryRecursively(ts.ComponentSrcPath, destDir) - if err != nil { - return err - } - - return nil -} - -func createComponentDir(ts *TestSuite) error { - destDir := filepath.Join(ts.TempDir, "components", "terraform", ts.ComponentName) - err := os.MkdirAll(destDir, 0777) - if err != nil { - return err - } - return nil -} +//func copyComponentSrcToTempDir(ts *TestSuite) error { +// +// destDir := filepath.Join(ts.TempDir, "components", "terraform", ts.ComponentName) +// fmt.Println("copying contents of", ts.ComponentSrcPath, "to", destDir) +// err := copyDirectoryRecursively(ts.ComponentSrcPath, destDir) +// if err != nil { +// return err +// } +// +// return nil +//} +// +//func createComponentDir(ts *TestSuite) error { +// destDir := filepath.Join(ts.TempDir, "components", "terraform", ts.ComponentName) +// err := os.MkdirAll(destDir, 0777) +// if err != nil { +// return err +// } +// return nil +//} diff --git a/pkg/atmos/aws-component-helper/setup_component_test.go b/pkg/atmos/aws-component-helper/setup_component_test.go index 70079d6..1378dae 100644 --- a/pkg/atmos/aws-component-helper/setup_component_test.go +++ b/pkg/atmos/aws-component-helper/setup_component_test.go @@ -1,118 +1,112 @@ package aws_component_helper -import ( - "os" - "path/filepath" - "testing" -) - -func TestSetupComponentUnderTest(t *testing.T) { - // Create a temporary directory for testing - tempDir, err := os.MkdirTemp("", "test-*") - if err != nil { - t.Fatalf("Failed to create temp dir: %v", err) - } - defer os.RemoveAll(tempDir) - - // Create a test source directory with some content - srcDir, err := os.MkdirTemp("", "src-*") - if err != nil { - t.Fatalf("Failed to create source dir: %v", err) - } - defer os.RemoveAll(srcDir) - - // Create a test file in the source directory - testFile := filepath.Join(srcDir, "test.tf") - if err := os.WriteFile(testFile, []byte("test content"), 0666); err != nil { - t.Fatalf("Failed to create test file: %v", err) - } - - ts := &TestSuite{ - TempDir: tempDir, - ComponentName: "test-component", - ComponentSrcPath: srcDir, - } - - if err := setupComponentUnderTest(ts); err != nil { - t.Errorf("setupComponentUnderTest failed: %v", err) - } - - // Verify the component directory was created - expectedDir := filepath.Join(tempDir, "components", "terraform", "test-component") - if _, err := os.Stat(expectedDir); os.IsNotExist(err) { - t.Error("Component directory was not created") - } - - // Verify the test file was copied - expectedFile := filepath.Join(expectedDir, "test.tf") - if _, err := os.Stat(expectedFile); os.IsNotExist(err) { - t.Error("Test file was not copied") - } -} - -func TestCreateComponentDir(t *testing.T) { - tempDir, err := os.MkdirTemp("", "test-*") - if err != nil { - t.Fatalf("Failed to create temp dir: %v", err) - } - defer os.RemoveAll(tempDir) - - ts := &TestSuite{ - TempDir: tempDir, - ComponentName: "test-component", - } - - if err := createComponentDir(ts); err != nil { - t.Errorf("createComponentDir failed: %v", err) - } - - expectedDir := filepath.Join(tempDir, "components", "terraform", "test-component") - if _, err := os.Stat(expectedDir); os.IsNotExist(err) { - t.Error("Component directory was not created") - } -} - -func TestCopyComponentSrcToTempDir(t *testing.T) { - // Create a temporary directory for testing - tempDir, err := os.MkdirTemp("", "test-*") - if err != nil { - t.Fatalf("Failed to create temp dir: %v", err) - } - defer os.RemoveAll(tempDir) - - // Create a test source directory with some content - srcDir, err := os.MkdirTemp("", "src-*") - if err != nil { - t.Fatalf("Failed to create source dir: %v", err) - } - defer os.RemoveAll(srcDir) - - // Create a test file in the source directory - testFile := filepath.Join(srcDir, "test.tf") - if err := os.WriteFile(testFile, []byte("test content"), 0666); err != nil { - t.Fatalf("Failed to create test file: %v", err) - } - - // Create the test suite before trying to use it - ts := &TestSuite{ - TempDir: tempDir, - ComponentName: "test-component", - ComponentSrcPath: srcDir, - } - - // Create the component directory first - componentDir := filepath.Join(tempDir, "components", "terraform", "test-component") - if err := os.MkdirAll(componentDir, 0777); err != nil { - t.Fatalf("Failed to create component dir: %v", err) - } - - if err := copyComponentSrcToTempDir(ts); err != nil { - t.Errorf("copyComponentSrcToTempDir failed: %v", err) - } - - // Verify the test file was copied - expectedFile := filepath.Join(componentDir, "test.tf") - if _, err := os.Stat(expectedFile); os.IsNotExist(err) { - t.Error("Test file was not copied") - } -} +//func TestSetupComponentUnderTest(t *testing.T) { +// // Create a temporary directory for testing +// tempDir, err := os.MkdirTemp("", "test-*") +// if err != nil { +// t.Fatalf("Failed to create temp dir: %v", err) +// } +// defer os.RemoveAll(tempDir) +// +// // Create a test source directory with some content +// srcDir, err := os.MkdirTemp("", "src-*") +// if err != nil { +// t.Fatalf("Failed to create source dir: %v", err) +// } +// defer os.RemoveAll(srcDir) +// +// // Create a test file in the source directory +// testFile := filepath.Join(srcDir, "test.tf") +// if err := os.WriteFile(testFile, []byte("test content"), 0666); err != nil { +// t.Fatalf("Failed to create test file: %v", err) +// } +// +// ts := &TestSuite{ +// TempDir: tempDir, +// ComponentName: "test-component", +// ComponentSrcPath: srcDir, +// } +// +// if err := setupComponentUnderTest(ts); err != nil { +// t.Errorf("setupComponentUnderTest failed: %v", err) +// } +// +// // Verify the component directory was created +// expectedDir := filepath.Join(tempDir, "components", "terraform", "test-component") +// if _, err := os.Stat(expectedDir); os.IsNotExist(err) { +// t.Error("Subject directory was not created") +// } +// +// // Verify the test file was copied +// expectedFile := filepath.Join(expectedDir, "test.tf") +// if _, err := os.Stat(expectedFile); os.IsNotExist(err) { +// t.Error("Test file was not copied") +// } +//} + +//func TestCreateComponentDir(t *testing.T) { +// tempDir, err := os.MkdirTemp("", "test-*") +// if err != nil { +// t.Fatalf("Failed to create temp dir: %v", err) +// } +// defer os.RemoveAll(tempDir) +// +// ts := &TestSuite{ +// TempDir: tempDir, +// ComponentName: "test-component", +// } +// +// if err := createComponentDir(ts); err != nil { +// t.Errorf("createComponentDir failed: %v", err) +// } +// +// expectedDir := filepath.Join(tempDir, "components", "terraform", "test-component") +// if _, err := os.Stat(expectedDir); os.IsNotExist(err) { +// t.Error("Subject directory was not created") +// } +//} +// +//func TestCopyComponentSrcToTempDir(t *testing.T) { +// // Create a temporary directory for testing +// tempDir, err := os.MkdirTemp("", "test-*") +// if err != nil { +// t.Fatalf("Failed to create temp dir: %v", err) +// } +// defer os.RemoveAll(tempDir) +// +// // Create a test source directory with some content +// srcDir, err := os.MkdirTemp("", "src-*") +// if err != nil { +// t.Fatalf("Failed to create source dir: %v", err) +// } +// defer os.RemoveAll(srcDir) +// +// // Create a test file in the source directory +// testFile := filepath.Join(srcDir, "test.tf") +// if err := os.WriteFile(testFile, []byte("test content"), 0666); err != nil { +// t.Fatalf("Failed to create test file: %v", err) +// } +// +// // Create the test suite before trying to use it +// ts := &TestSuite{ +// TempDir: tempDir, +// ComponentName: "test-component", +// ComponentSrcPath: srcDir, +// } +// +// // Create the component directory first +// componentDir := filepath.Join(tempDir, "components", "terraform", "test-component") +// if err := os.MkdirAll(componentDir, 0777); err != nil { +// t.Fatalf("Failed to create component dir: %v", err) +// } +// +// if err := copyComponentSrcToTempDir(ts); err != nil { +// t.Errorf("copyComponentSrcToTempDir failed: %v", err) +// } +// +// // Verify the test file was copied +// expectedFile := filepath.Join(componentDir, "test.tf") +// if _, err := os.Stat(expectedFile); os.IsNotExist(err) { +// t.Error("Test file was not copied") +// } +//} diff --git a/pkg/atmos/aws-component-helper/setup_test_suite.go b/pkg/atmos/aws-component-helper/setup_test_suite.go index 694f502..1558dc6 100644 --- a/pkg/atmos/aws-component-helper/setup_test_suite.go +++ b/pkg/atmos/aws-component-helper/setup_test_suite.go @@ -2,36 +2,32 @@ package aws_component_helper import ( "context" - "encoding/json" "fmt" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/sts" "os" "path/filepath" "runtime" - "strings" - - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/service/sts" - "github.com/gruntwork-io/terratest/modules/random" ) -func setupTestSuite(ts *TestSuite) error { - err := createStateDir(ts.TempDir) - if err != nil { - return err - } - - err = createTerraformComponentsDir(ts.TempDir) - if err != nil { - return err - } - - err = copyDirectoryRecursively(ts.FixturesPath, ts.TempDir) - if err != nil { - return err - } - - return nil -} +//func setupTestSuite(ts *TestSuite) error { +// err := createStateDir(ts.TempDir) +// if err != nil { +// return err +// } +// +// err = createTerraformComponentsDir(ts.TempDir) +// if err != nil { +// return err +// } +// +// err = copyDirectoryRecursively(ts.FixturesPath, ts.TempDir) +// if err != nil { +// return err +// } +// +// return nil +//} func createStateDir(tempDir string) error { stateDir := filepath.Join(tempDir, "state") @@ -79,58 +75,56 @@ func getAwsAccountId() (string, error) { return *identity.Account, nil } -func readOrCreateTestSuiteFile(testSuite *TestSuite, testName string) (*TestSuite, error) { - // Initialize TestSuites structure - var testSuites TestSuites - - if data, err := os.ReadFile(testSuiteFile); err == nil { - // File exists, try to unmarshal existing test suites - if err := json.Unmarshal(data, &testSuites); err != nil { - return &TestSuite{}, fmt.Errorf("failed to parse test_suites.json: %s", err.Error()) - } - - if len(testSuites.Suites) > 1 && testSuite.Index < 0 { - return &TestSuite{}, fmt.Errorf("test suite index is required when multiple test suites are present") - } - - if testSuite.Index == -1 && len(testSuites.Suites) == 1 { - testSuite.Index = 0 - } - - if !testSuite.ForceNewSuite && len(testSuites.Suites) > 0 { - return testSuites.Suites[testSuite.Index], nil - } - } - - // If we get here, either the file doesn't exist or we didn't find a matching suite - fmt.Println("no matching test suite found for index", testSuite.Index, "creating new test suite") - randID := random.UniqueId() - testSuite.RandomIdentifier = strings.ToLower(randID) - testSuite.Index = len(testSuites.Suites) // Set index to current length - - var err error - testSuite.TempDir, err = os.MkdirTemp("", testName) - if err != nil { - return &TestSuite{}, err - } - fmt.Printf("running tests in %s\n", testSuite.TempDir) - - // Add new test suite to the collection - testSuites.Suites = append(testSuites.Suites, testSuite) - - // Write updated test suites to file - data, err := json.MarshalIndent(testSuites, "", " ") - if err != nil { - return &TestSuite{}, err - } - - if err := os.WriteFile(testSuiteFile, data, 0644); err != nil { - return &TestSuite{}, err - } - - os.Setenv("ATMOS_BASE_PATH", testSuite.TempDir) - os.Setenv("ATMOS_CLI_CONFIG_PATH", testSuite.TempDir) - os.Setenv("TEST_ACCOUNT_ID", testSuite.AwsAccountId) - - return testSuite, nil -} +//func readOrCreateTestSuiteFile(testSuite *TestSuite, testName string) (*TestSuite, error) { +// // Initialize TestSuites structure +// var testSuites TestSuites +// +// if data, err := os.ReadFile(testSuiteFile); err == nil { +// // File exists, try to unmarshal existing test suites +// if err := json.Unmarshal(data, &testSuites); err != nil { +// return &TestSuite{}, fmt.Errorf("failed to parse test_suites.json: %s", err.Error()) +// } +// +// if len(testSuites.Suites) > 1 && testSuite.Index < 0 { +// return &TestSuite{}, fmt.Errorf("test suite index is required when multiple test suites are present") +// } +// if testSuite.Index == -1 && len(testSuites.Suites) == 1 { +// testSuite.Index = 0 +// } +// if !testSuite.ForceNewSuite && len(testSuites.Suites) > 0 { +// return testSuites.Suites[testSuite.Index], nil +// } +// } +// +// // If we get here, either the file doesn't exist or we didn't find a matching suite +// fmt.Println("no matching test suite found for index", testSuite.Index, "creating new test suite") +// randID := random.UniqueId() +// testSuite.RandomIdentifier = strings.ToLower(randID) +// testSuite.Index = len(testSuites.Suites) // Set index to current length +// +// var err error +// testSuite.TempDir, err = os.MkdirTemp("", testName) +// if err != nil { +// return &TestSuite{}, err +// } +// fmt.Printf("running tests in %s\n", testSuite.TempDir) +// +// // Add new test suite to the collection +// testSuites.Suites = append(testSuites.Suites, testSuite) +// +// // Write updated test suites to file +// data, err := json.MarshalIndent(testSuites, "", " ") +// if err != nil { +// return &TestSuite{}, err +// } +// +// if err := os.WriteFile(testSuiteFile, data, 0644); err != nil { +// return &TestSuite{}, err +// } +// +// // os.Setenv("ATMOS_BASE_PATH", testSuite.WorkDir) +// os.Setenv("ATMOS_CLI_CONFIG_PATH", testSuite.TempDir) +// os.Setenv("TEST_ACCOUNT_ID", testSuite.AwsAccountId) +// +// return testSuite, nil +//} diff --git a/pkg/atmos/aws-component-helper/setup_test_suite_test.go b/pkg/atmos/aws-component-helper/setup_test_suite_test.go index fe03bd3..2682f85 100644 --- a/pkg/atmos/aws-component-helper/setup_test_suite_test.go +++ b/pkg/atmos/aws-component-helper/setup_test_suite_test.go @@ -1,37 +1,35 @@ package aws_component_helper import ( - "encoding/json" - "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" ) -func TestSetupTestSuite(t *testing.T) { - // Create a temporary test suite - ts := &TestSuite{ - TempDir: t.TempDir(), - FixturesPath: "testdata/fixtures", - } - - // Create test fixtures - err := os.MkdirAll(ts.FixturesPath, 0755) - assert.NoError(t, err) - defer os.RemoveAll(ts.FixturesPath) - - // Test setup - err = setupTestSuite(ts) - assert.NoError(t, err) - - // Verify directories were created - stateDir := filepath.Join(ts.TempDir, "state") - assert.DirExists(t, stateDir) - - componentsDir := filepath.Join(ts.TempDir, "components", "terraform") - assert.DirExists(t, componentsDir) -} +//func TestSetupTestSuite(t *testing.T) { +// // Create a temporary test suite +// ts := &TestSuite{ +// TempDir: t.TempDir(), +// FixturesPath: "testdata/fixtures", +// } +// +// // Create test fixtures +// err := os.MkdirAll(ts.FixturesPath, 0755) +// assert.NoError(t, err) +// defer os.RemoveAll(ts.FixturesPath) +// +// // Test setup +// err = setupTestSuite(ts) +// assert.NoError(t, err) +// +// // Verify directories were created +// stateDir := filepath.Join(ts.TempDir, "state") +// assert.DirExists(t, stateDir) +// +// componentsDir := filepath.Join(ts.TempDir, "components", "terraform") +// assert.DirExists(t, componentsDir) +//} func TestCreateStateDir(t *testing.T) { tempDir := t.TempDir() @@ -59,46 +57,50 @@ func TestGetTestName(t *testing.T) { assert.Contains(t, testName, "setup_test_suite_") } -func TestReadOrCreateTestSuiteFile(t *testing.T) { - t.Run("create new test suite file", func(t *testing.T) { - // Clean up any existing test suite file - os.Remove(testSuiteFile) - - ts := &TestSuite{} - testName := "test_" - - result, err := readOrCreateTestSuiteFile(ts, testName) - assert.NoError(t, err) - assert.NotEmpty(t, result.RandomIdentifier) - assert.NotEmpty(t, result.TempDir) - - // Verify file was created - assert.FileExists(t, testSuiteFile) - - // Clean up - os.Remove(testSuiteFile) - os.RemoveAll(result.TempDir) - }) - - t.Run("read existing test suite file", func(t *testing.T) { - // Create a test suite file - existingTS := &TestSuite{ - RandomIdentifier: "test-seed", - TempDir: "test-dir", - } - data, err := json.MarshalIndent(existingTS, "", " ") - assert.NoError(t, err) - err = os.WriteFile(testSuiteFile, data, 0644) - assert.NoError(t, err) - - // Test reading the file - ts := &TestSuite{} - result, err := readOrCreateTestSuiteFile(ts, "test_") - assert.NoError(t, err) - assert.Equal(t, existingTS.RandomIdentifier, result.RandomIdentifier) - assert.Equal(t, existingTS.TempDir, result.TempDir) - - // Clean up - os.Remove(testSuiteFile) - }) -} +//func TestReadOrCreateTestSuiteFile(t *testing.T) { +// t.Run("create new test suite file", func(t *testing.T) { +// // Clean up any existing test suite file +// os.Remove(testSuiteFile) +// +// ts := &TestSuite{} +// testName := "test_" +// +// result, err := readOrCreateTestSuiteFile(ts, testName) +// assert.NoError(t, err) +// assert.NotEmpty(t, result.RandomIdentifier) +// assert.NotEmpty(t, result.TempDir) +// +// // Verify file was created +// assert.FileExists(t, testSuiteFile) +// +// // Clean up +// os.Remove(testSuiteFile) +// os.RemoveAll(result.TempDir) +// }) +// +// t.Run("read existing test suite file", func(t *testing.T) { +// // Create a test suite file +// existingTS := &TestSuites{ +// Suites: []*TestSuite{ +// { +// RandomIdentifier: "test-seed", +// TempDir: "test-dir", +// }, +// }, +// } +// data, err := json.MarshalIndent(existingTS, "", " ") +// assert.NoError(t, err) +// err = os.WriteFile(testSuiteFile, data, 0644) +// assert.NoError(t, err) +// +// // Test reading the file +// ts := &TestSuite{} +// result, err := readOrCreateTestSuiteFile(ts, "test_") +// assert.NoError(t, err) +// assert.Equal(t, existingTS.Suites[0].RandomIdentifier, result.RandomIdentifier) +// assert.Equal(t, existingTS.Suites[0].TempDir, result.TempDir) +// +// // Clean up +// os.Remove(testSuiteFile) +// }) +//} diff --git a/pkg/atmos/aws-component-helper/shared.go b/pkg/atmos/aws-component-helper/shared.go index 5e738ef..898be64 100644 --- a/pkg/atmos/aws-component-helper/shared.go +++ b/pkg/atmos/aws-component-helper/shared.go @@ -1,11 +1,13 @@ package aws_component_helper import ( + "fmt" "os" "path/filepath" ) func copyDirectoryRecursively(srcDir string, destDir string) error { + fmt.Println("copying contents of", srcDir, "to", destDir) // Walk through all files and directories in srcDir and copy them to destDir return filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error { if err != nil { diff --git a/pkg/atmos/aws-component-helper/tear_down_suite.go b/pkg/atmos/aws-component-helper/tear_down_suite.go index 9dbf1f6..18f8df8 100644 --- a/pkg/atmos/aws-component-helper/tear_down_suite.go +++ b/pkg/atmos/aws-component-helper/tear_down_suite.go @@ -1,26 +1,21 @@ package aws_component_helper -import ( - "fmt" - "os" -) - -func tearDown(ts *TestSuite) error { - fmt.Println("tearing down test suite in", ts.TempDir) - err := os.RemoveAll(ts.TempDir) - if err != nil { - return err - } - - fmt.Println("removing test suite file", testSuiteFile) - err = os.Remove(testSuiteFile) - if err != nil { - return err - } - - defer os.Unsetenv("ATMOS_BASE_PATH") - defer os.Unsetenv("ATMOS_CLI_CONFIG_PATH") - defer os.Unsetenv("TEST_ACCOUNT_ID") - - return nil -} +//func tearDown(ts *TestSuite) error { +// fmt.Println("tearing down test suite in", ts.TempDir) +// err := os.RemoveAll(ts.TempDir) +// if err != nil { +// return err +// } +// +// fmt.Println("removing test suite file", testSuiteFile) +// err = os.Remove(testSuiteFile) +// if err != nil { +// return err +// } +// +// defer os.Unsetenv("ATMOS_BASE_PATH") +// defer os.Unsetenv("ATMOS_CLI_CONFIG_PATH") +// defer os.Unsetenv("TEST_ACCOUNT_ID") +// +// return nil +//} diff --git a/pkg/atmos/aws-component-helper/test_component.go b/pkg/atmos/aws-component-helper/test_component.go new file mode 100644 index 0000000..0995888 --- /dev/null +++ b/pkg/atmos/aws-component-helper/test_component.go @@ -0,0 +1,107 @@ +package aws_component_helper + +import ( + "dario.cat/mergo" + "fmt" + "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/stretchr/testify/assert" + "strings" + "testing" +) + +type ComponentTest struct { + RandomIdentifier string + setup []*AtmosComponent + Subject *AtmosComponent + assert []*AtmosComponent + VerifyEnabledFlag bool + AtmosOptions *atmos.Options +} + +func NewComponentTest(options *atmos.Options) *ComponentTest { + randID := random.UniqueId() + randomId := strings.ToLower(randID) + return &ComponentTest{ + RandomIdentifier: randomId, + setup: make([]*AtmosComponent, 0), + Subject: nil, + assert: make([]*AtmosComponent, 0), + VerifyEnabledFlag: true, + AtmosOptions: options, + } +} + +func (ct *ComponentTest) Run(t *testing.T) { + for _, component := range ct.setup { + componentOptions := component.getAtmosOptions(t, map[string]interface{}{}) + + atmosApply(t, componentOptions) + defer atmosDestroy(t, componentOptions) + } + + if ct.VerifyEnabledFlag { + fmt.Println("VerifyEnabledFlag") + ct.verifyEnabledFlag(t, ct.Subject) + } else { + fmt.Println("Skipping VerifyEnabledFlag") + } + + subjectOptions := ct.Subject.getAtmosOptions(t, map[string]interface{}{}) + atmosApply(t, subjectOptions) + defer atmosDestroy(t, subjectOptions) + + for _, component := range ct.assert { + componentOptions := component.getAtmosOptions(t, map[string]interface{}{}) + + atmosApply(t, componentOptions) + defer atmosDestroy(t, componentOptions) + } +} + +func (ct *ComponentTest) verifyEnabledFlag(t *testing.T, component *AtmosComponent) *atmos.Options { + vars := map[string]interface{}{ + "enabled": false, + } + options := component.getAtmosOptions(t, vars) + + exitCode, err := atmosPlanExitCodeE(t, options) + assert.NoError(t, err) + + if exitCode != 0 { + assert.Fail(t, "running atmos terraform plan with enabled flag set to false resulted in resource changes") + } + + return options +} + +func (ct *ComponentTest) getAtmosOptions() *atmos.Options { + result, _ := ct.AtmosOptions.Clone() + mergedVars := map[string]interface{}{ + "default_tags": map[string]string{ + "CreatedByAtmosTestSuiteTest": ct.RandomIdentifier, + }, + } + // Merge in any additional vars passed in + err := mergo.Merge(&result.Vars, mergedVars) + if err != nil { + return nil + } + //require.NoError(t, err) + + return result +} + +func (ct *ComponentTest) AddSetup(component string, stack string) { + item := NewAtmosComponent(component, stack, ct.getAtmosOptions()) + ct.setup = append(ct.setup, item) +} + +func (ct *ComponentTest) SetSubject(component string, stack string) { + ct.Subject = NewAtmosComponent(component, stack, ct.getAtmosOptions()) +} + +func (ct *ComponentTest) AddSAssert(component string, stack string) { + item := NewAtmosComponent(component, stack, ct.getAtmosOptions()) + ct.assert = append(ct.assert, item) +} diff --git a/pkg/atmos/aws-component-helper/test_component_test.go b/pkg/atmos/aws-component-helper/test_component_test.go new file mode 100644 index 0000000..79102c2 --- /dev/null +++ b/pkg/atmos/aws-component-helper/test_component_test.go @@ -0,0 +1,16 @@ +package aws_component_helper + +import ( + "github.com/cloudposse/test-helpers/pkg/atmos" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestComponentTestMinimum(t *testing.T) { + componentTest := NewComponentTest(&atmos.Options{}) + componentTest.SetSubject("vpc", "default-test") + + assert.Equal(t, componentTest.Subject.Component, "vpc") + assert.Equal(t, componentTest.Subject.Stack, "default-test") +} diff --git a/pkg/atmos/aws-component-helper/test_suite.go b/pkg/atmos/aws-component-helper/test_suite.go index 4e60199..1845cbc 100644 --- a/pkg/atmos/aws-component-helper/test_suite.go +++ b/pkg/atmos/aws-component-helper/test_suite.go @@ -1,273 +1,274 @@ package aws_component_helper -import ( - "fmt" - "testing" - - "github.com/cloudposse/test-helpers/pkg/atmos" -) - -type TestSuite struct { - AtmosOptions *atmos.Options - AwsAccountId string - AwsRegion string - ComponentName string - ComponentSrcPath string - Dependencies []*Dependency - FixturesPath string - ForceNewSuite bool - Index int - RandomIdentifier string - SkipSetupComponentUnderTest bool - SkipDeployDependencies bool - SkipDeployComponentUnderTest bool - SkipDestroyComponentUnderTest bool - SkipDestroyDependencies bool - SkipTeardownTestSuite bool - SkipTests bool - SkipVendorDependencies bool - SkipVerifyEnabledFlag bool - SkipNukeTestAccount bool - StackName string - TempDir string -} - -type TestSuites struct { - Suites []*TestSuite -} - -// Option type represents a configuration option -type TestSuiteOption func(*TestSuite) - -func (ts *TestSuite) AddDependencies(dependencies []string) { - for _, dependency := range dependencies { - ts.AddDependency(dependency) - } -} - -func (ts *TestSuite) AddCrossStackDependencies(dependencies []Dependency) { - for _, dependency := range dependencies { - ts.AddCrossStackDependency(dependency.ComponentName, dependency.StackName) - } -} - -func (ts *TestSuite) AddDependency(componentName string) { - ts.Dependencies = append(ts.Dependencies, NewDependency(componentName, ts.StackName)) -} - -func (ts *TestSuite) AddCrossStackDependency(componentName string, stackName string) { - ts.Dependencies = append(ts.Dependencies, NewDependency(componentName, stackName)) -} - -func (ts *TestSuite) SetupTestSuite(t *testing.T) error { - fmt.Println("SetupTestSuite") - err := setupTestSuite(ts) - return err -} - -func (ts *TestSuite) SetupComponentUnderTest(t *testing.T) error { - if !ts.SkipSetupComponentUnderTest { - fmt.Println("SetupComponentUnderTest") - err := setupComponentUnderTest(ts) - return err - } else { - fmt.Println("Skipping SetupComponentUnderTest") - } - return nil -} - -func (ts *TestSuite) VendorDependencies(t *testing.T) error { - if !ts.SkipVendorDependencies { - fmt.Println("VendorDependencies") - err := vendorDependencies(t, ts) - return err - } else { - fmt.Println("Skipping VendorDependencies") - } - return nil -} - -func (ts *TestSuite) DeployDependencies(t *testing.T) error { - if !ts.SkipDeployDependencies { - fmt.Println("DeployDependencies") - err := deployDependencies(t, ts) - return err - } else { - fmt.Println("Skipping DeployDependencies") - } - return nil -} - -func (ts *TestSuite) VerifyEnabledFlag(t *testing.T) error { - if !ts.SkipVerifyEnabledFlag { - fmt.Println("VerifyEnabledFlag") - _, err := verifyEnabledFlag(t, ts, ts.ComponentName, ts.StackName) - return err - } else { - fmt.Println("Skipping VerifyEnabledFlag") - } - return nil -} - -func (ts *TestSuite) DeployComponentUnderTest(t *testing.T, vars map[string]interface{}) (string, error) { - if !ts.SkipDeployComponentUnderTest { - fmt.Println("DeployComponentUnderTest") - options, out, err := deployComponent(t, ts, ts.ComponentName, ts.StackName, vars) - ts.AtmosOptions = options - - return out, err - } else { - fmt.Println("Skipping DeployComponentUnderTest") - return "", nil - } -} - -func (ts *TestSuite) DestroyComponentUnderTest(t *testing.T, vars map[string]interface{}) (string, error) { - if !ts.SkipDestroyComponentUnderTest { - fmt.Println("DestroyComponentUnderTest") - options, out, err := destroyComponent(t, ts, ts.ComponentName, ts.StackName, vars) - ts.AtmosOptions = options - - return out, err - } else { - fmt.Println("Skipping DestroyComponentUnderTest") - return "", nil - } -} - -func (ts *TestSuite) DestroyDependencies(t *testing.T) error { - if !skipDestroyDependencies(ts) { - fmt.Println("DestroyDependencies") - err := destroyDependencies(t, ts) - return err - } else { - fmt.Println("Skipping DestroyDependencies") - } - return nil -} - -func (ts *TestSuite) TearDownTestSuite(t *testing.T) error { - fmt.Println("TeardownTestSuite") - if !skipTeardownTestSuite(ts) { - err := tearDown(ts) - return err - } else { - fmt.Println("Skipping TeardownTestSuite") - } - return nil -} - -func (ts *TestSuite) NukeTestAccount(t *testing.T) error { - if !skipNukeTestAccount(ts) { - fmt.Println("NukeTestAccount") - //awsnuke.NukeTestAccountByTag(t, "CreatedByTerratestRun", ts.RandomSeed, []string{ts.AwsRegion}, false) - } else { - fmt.Println("Skipping NukeTestAccount") - } - - return nil -} - -func (ts *TestSuite) Setup(t *testing.T) error { - fmt.Println("=== RUN Test Suite Setup") - if err := ts.SetupTestSuite(t); err != nil { - return err - } - - if err := ts.SetupComponentUnderTest(t); err != nil { - return err - } - - if err := ts.VendorDependencies(t); err != nil { - return err - } - - if err := ts.DeployDependencies(t); err != nil { - return err - } - - if err := ts.VerifyEnabledFlag(t); err != nil { - return err - } - - return nil -} - -func (ts *TestSuite) TearDown(t *testing.T) error { - fmt.Println("=== RUN Test Suite TearDown") - if err := ts.DestroyDependencies(t); err != nil { - return err - } - - if err := ts.TearDownTestSuite(t); err != nil { - return err - } - - if err := ts.NukeTestAccount(t); err != nil { - return err - } - - return nil -} - -func NewTestSuite(awsRegion string, componentName string, stackName string, opts ...TestSuiteOption) (*TestSuite, error) { - awsAccountId, err := getAwsAccountId() - if err != nil { - return &TestSuite{}, err - } - - suite := &TestSuite{ - AtmosOptions: &atmos.Options{}, - AwsAccountId: awsAccountId, - AwsRegion: awsRegion, - ComponentName: componentName, - ComponentSrcPath: "../src", - FixturesPath: "fixtures", - StackName: stackName, - } - - testName, err := getTestName() - if err != nil { - return &TestSuite{}, err - } - - // Apply optional configurations - for _, opt := range opts { - opt(suite) - } - - // Parse the CLI args - suite = parseCLIArgs(suite) - - // Read or create the test suite file - suite, err = readOrCreateTestSuiteFile(suite, testName) - if err != nil { - panic("Failed to create test suite: " + err.Error()) - } - - return suite, nil -} - -func WithComponentSrcPath(componentSrcPath string) TestSuiteOption { - return func(a *TestSuite) { - a.ComponentSrcPath = componentSrcPath - } -} - -func WithFixturesPath(fixturesPath string) TestSuiteOption { - return func(a *TestSuite) { - a.FixturesPath = fixturesPath - } -} - -func WithDependency(dependency *Dependency) TestSuiteOption { - return func(a *TestSuite) { - a.Dependencies = append(a.Dependencies, dependency) - } -} - -func WithDependencies(dependencies []*Dependency) TestSuiteOption { - return func(a *TestSuite) { - a.Dependencies = append(a.Dependencies, dependencies...) - } -} +// +//import ( +// "fmt" +// "testing" +// +// "github.com/cloudposse/test-helpers/pkg/atmos" +//) +// +//type TestSuite struct { +// AtmosOptions *atmos.Options +// AwsAccountId string +// AwsRegion string +// ComponentName string +// ComponentSrcPath string +// Dependencies []*Dependency +// FixturesPath string +// ForceNewSuite bool +// Index int +// RandomIdentifier string +// SkipSetupComponentUnderTest bool +// SkipDeployDependencies bool +// SkipDeployComponentUnderTest bool +// SkipDestroyComponentUnderTest bool +// SkipDestroyDependencies bool +// SkipTeardownTestSuite bool +// SkipTests bool +// SkipVendorDependencies bool +// SkipVerifyEnabledFlag bool +// SkipNukeTestAccount bool +// StackName string +// TempDir string +//} +// +//type TestSuites struct { +// Suites []*TestSuite +//} +// +//// Option type represents a configuration option +//type TestSuiteOption func(*TestSuite) +// +////func (ts *TestSuite) AddDependencies(dependencies []string) { +//// for _, dependency := range dependencies { +//// ts.AddDependency(dependency) +//// } +////} +// +////func (ts *TestSuite) AddCrossStackDependencies(dependencies []Dependency) { +//// for _, dependency := range dependencies { +//// ts.AddCrossStackDependency(dependency.ComponentName, dependency.StackName) +//// } +////} +// +////func (ts *TestSuite) AddDependency(componentName string) { +//// ts.Dependencies = append(ts.Dependencies, NewDependency(componentName, ts.StackName)) +////} +// +////func (ts *TestSuite) AddCrossStackDependency(componentName string, stackName string) { +//// ts.Dependencies = append(ts.Dependencies, NewDependency(componentName, stackName)) +////} +// +////func (ts *TestSuite) SetupTestSuite(t *testing.T) error { +//// fmt.Println("SetupTestSuite") +//// err := setupTestSuite(ts) +//// return err +////} +// +////func (ts *TestSuite) SetupComponentUnderTest(t *testing.T) error { +//// if !ts.SkipSetupComponentUnderTest { +//// fmt.Println("SetupComponentUnderTest") +//// err := setupComponentUnderTest(ts) +//// return err +//// } else { +//// fmt.Println("Skipping SetupComponentUnderTest") +//// } +//// return nil +////} +// +////func (ts *TestSuite) VendorDependencies(t *testing.T) error { +//// if !ts.SkipVendorDependencies { +//// fmt.Println("VendorDependencies") +//// err := vendorDependencies(t, ts) +//// return err +//// } else { +//// fmt.Println("Skipping VendorDependencies") +//// } +//// return nil +////} +// +////func (ts *TestSuite) DeployDependencies(t *testing.T) error { +//// if !ts.SkipDeployDependencies { +//// fmt.Println("DeployDependencies") +//// err := deployDependencies(t, ts) +//// return err +//// } else { +//// fmt.Println("Skipping DeployDependencies") +//// } +//// return nil +////} +// +////func (ts *TestSuite) VerifyEnabledFlag(t *testing.T) error { +//// if !ts.SkipVerifyEnabledFlag { +//// fmt.Println("VerifyEnabledFlag") +//// _, err := verifyEnabledFlag(t, ts, ts.ComponentName, ts.StackName) +//// return err +//// } else { +//// fmt.Println("Skipping VerifyEnabledFlag") +//// } +//// return nil +////} +// +////func (ts *TestSuite) DeployComponentUnderTest(t *testing.T, vars map[string]interface{}) (string, error) { +//// if !ts.SkipDeployComponentUnderTest { +//// fmt.Println("DeployComponentUnderTest") +//// options, out, err := deployComponent(t, ts, ts.ComponentName, ts.StackName, vars) +//// ts.AtmosOptions = options +//// +//// return out, err +//// } else { +//// fmt.Println("Skipping DeployComponentUnderTest") +//// return "", nil +//// } +////} +// +////func (ts *TestSuite) DestroyComponentUnderTest(t *testing.T, vars map[string]interface{}) (string, error) { +//// if !ts.SkipDestroyComponentUnderTest { +//// fmt.Println("DestroyComponentUnderTest") +//// options, out, err := destroyComponent(t, ts, ts.ComponentName, ts.StackName, vars) +//// ts.AtmosOptions = options +//// +//// return out, err +//// } else { +//// fmt.Println("Skipping DestroyComponentUnderTest") +//// return "", nil +//// } +////} +// +//func (ts *TestSuite) DestroyDependencies(t *testing.T) error { +// if !skipDestroyDependencies(ts) { +// fmt.Println("DestroyDependencies") +// err := destroyDependencies(t, ts) +// return err +// } else { +// fmt.Println("Skipping DestroyDependencies") +// } +// return nil +//} +// +//func (ts *TestSuite) TearDownTestSuite(t *testing.T) error { +// fmt.Println("TeardownTestSuite") +// if !skipTeardownTestSuite(ts) { +// err := tearDown(ts) +// return err +// } else { +// fmt.Println("Skipping TeardownTestSuite") +// } +// return nil +//} +// +//func (ts *TestSuite) NukeTestAccount(t *testing.T) error { +// if !skipNukeTestAccount(ts) { +// fmt.Println("NukeTestAccount") +// //awsnuke.NukeTestAccountByTag(t, "CreatedByTerratestRun", ts.RandomSeed, []string{ts.AwsRegion}, false) +// } else { +// fmt.Println("Skipping NukeTestAccount") +// } +// +// return nil +//} +// +////func (ts *TestSuite) Setup(t *testing.T) error { +//// fmt.Println("=== RUN Test Suite Setup") +//// if err := ts.SetupTestSuite(t); err != nil { +//// return err +//// } +//// +//// if err := ts.SetupComponentUnderTest(t); err != nil { +//// return err +//// } +//// +//// if err := ts.VendorDependencies(t); err != nil { +//// return err +//// } +//// +//// if err := ts.DeployDependencies(t); err != nil { +//// return err +//// } +//// +//// if err := ts.VerifyEnabledFlag(t); err != nil { +//// return err +//// } +//// +//// return nil +////} +// +//func (ts *TestSuite) TearDown(t *testing.T) error { +// fmt.Println("=== RUN Test Suite TearDown") +// if err := ts.DestroyDependencies(t); err != nil { +// return err +// } +// +// if err := ts.TearDownTestSuite(t); err != nil { +// return err +// } +// +// if err := ts.NukeTestAccount(t); err != nil { +// return err +// } +// +// return nil +//} +// +//func NewTestSuite(awsRegion string, componentName string, stackName string, opts ...TestSuiteOption) (*TestSuite, error) { +// awsAccountId, err := getAwsAccountId() +// if err != nil { +// return &TestSuite{}, err +// } +// +// suite := &TestSuite{ +// AtmosOptions: &atmos.Options{}, +// AwsAccountId: awsAccountId, +// AwsRegion: awsRegion, +// ComponentName: componentName, +// ComponentSrcPath: "../src", +// FixturesPath: "fixtures", +// StackName: stackName, +// } +// +// testName, err := getTestName() +// if err != nil { +// return &TestSuite{}, err +// } +// +// // Apply optional configurations +// for _, opt := range opts { +// opt(suite) +// } +// +// // Parse the CLI args +// suite = parseCLIArgs(suite) +// +// // Read or create the test suite file +// suite, err = readOrCreateTestSuiteFile(suite, testName) +// if err != nil { +// panic("Failed to create test suite: " + err.Error()) +// } +// +// return suite, nil +//} +// +//func WithComponentSrcPath(componentSrcPath string) TestSuiteOption { +// return func(a *TestSuite) { +// a.ComponentSrcPath = componentSrcPath +// } +//} +// +//func WithFixturesPath(fixturesPath string) TestSuiteOption { +// return func(a *TestSuite) { +// a.FixturesPath = fixturesPath +// } +//} +// +//func WithDependency(dependency *Dependency) TestSuiteOption { +// return func(a *TestSuite) { +// a.Dependencies = append(a.Dependencies, dependency) +// } +//} +// +//func WithDependencies(dependencies []*Dependency) TestSuiteOption { +// return func(a *TestSuite) { +// a.Dependencies = append(a.Dependencies, dependencies...) +// } +//} diff --git a/pkg/atmos/aws-component-helper/x_test_suite.go b/pkg/atmos/aws-component-helper/x_test_suite.go new file mode 100644 index 0000000..6e1fa44 --- /dev/null +++ b/pkg/atmos/aws-component-helper/x_test_suite.go @@ -0,0 +1,75 @@ +package aws_component_helper + +import ( + "dario.cat/mergo" + "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/gruntwork-io/terratest/modules/random" + "strings" + "testing" +) + +type XTestSuite struct { + RandomIdentifier string + setup []*AtmosComponent + tests map[string]*ComponentTest + atmosOptions *atmos.Options +} + +func NewXTestSuite(options *atmos.Options) *XTestSuite { + randID := random.UniqueId() + randomId := strings.ToLower(randID) + return &XTestSuite{ + RandomIdentifier: randomId, + setup: make([]*AtmosComponent, 0), + tests: make(map[string]*ComponentTest), + atmosOptions: options, + } +} + +func (ts *XTestSuite) getAtmosOptions() *atmos.Options { + result, _ := ts.atmosOptions.Clone() + + vars := map[string]interface{}{ + "attributes": []string{ts.RandomIdentifier}, + "default_tags": map[string]string{ + "CreatedByAtmosTestSuite": ts.RandomIdentifier, + }, + } + + err := mergo.Merge(&result.Vars, vars) + if err != nil { + return nil + } + return result +} + +func (ts *XTestSuite) AddSetup(component string, stack string) { + item := NewAtmosComponent(component, stack, ts.getAtmosOptions()) + ts.setup = append(ts.setup, item) +} + +func (ts *XTestSuite) GetOrCreateTest(name string) *ComponentTest { + if _, ok := ts.tests[name]; !ok { + ts.tests[name] = NewComponentTest(ts.getAtmosOptions()) + } + return ts.tests[name] +} + +func (ts *XTestSuite) Tests() map[string]*ComponentTest { + return ts.tests +} + +func (ts *XTestSuite) Run(t *testing.T) { + for _, component := range ts.setup { + componentOptions := component.getAtmosOptions(t, map[string]interface{}{}) + atmosApply(t, componentOptions) + defer atmosDestroy(t, componentOptions) + } + + //t.Parallel() + for name, item := range ts.tests { + t.Run(name, func(t *testing.T) { + item.Run(t) + }) + } +} diff --git a/pkg/atmos/aws-component-helper/x_test_suite_test.go b/pkg/atmos/aws-component-helper/x_test_suite_test.go new file mode 100644 index 0000000..039715c --- /dev/null +++ b/pkg/atmos/aws-component-helper/x_test_suite_test.go @@ -0,0 +1,18 @@ +package aws_component_helper + +import ( + "github.com/cloudposse/test-helpers/pkg/atmos" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestComponentTestSuiteMinimum(t *testing.T) { + componentTestSuite := NewXTestSuite(&atmos.Options{}) + test := componentTestSuite.GetOrCreateTest("test") + test.SetSubject("vpc", "default-test") + + assert.Equal(t, test.Subject.Component, "vpc") + assert.Equal(t, componentTestSuite.tests["test"].Subject.Component, "vpc") + assert.Equal(t, componentTestSuite.tests["test"].Subject.Stack, "default-test") +} diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go new file mode 100644 index 0000000..c9889a3 --- /dev/null +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -0,0 +1,145 @@ +package aws_component_helper + +import ( + "fmt" + "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/stretchr/testify/assert" + "os" + "path/filepath" + "slices" + "strings" + "testing" +) + +type XTestSuites struct { + RandomIdentifier string + AtmosOptions *atmos.Options + AwsAccountId string + AwsRegion string + SourceDir string + FixturesPath string + WorkDir string + suites map[string]*XTestSuite +} + +func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, f func() (string, error), fixturesDir string) (*XTestSuites, error) { + awsAccountId, err := f() + if err != nil { + return &XTestSuites{}, err + } + + randID := random.UniqueId() + randomId := strings.ToLower(randID) + workdir := filepath.Join(os.TempDir(), "test-suites-"+randomId) + suitesOptions := &atmos.Options{ + AtmosBasePath: filepath.Join(workdir, fixturesDir), + NoColor: true, + Vars: map[string]interface{}{ + "region": awsRegion, + }, + } + + suites := &XTestSuites{ + RandomIdentifier: randomId, + SourceDir: sourceDir, + FixturesPath: fixturesDir, + WorkDir: workdir, + AwsAccountId: awsAccountId, + AwsRegion: awsRegion, + AtmosOptions: suitesOptions, + suites: map[string]*XTestSuite{}, + } + + describeStacksConfigs, err := atmos.DescribeStacksE(t, &atmos.Options{ + AtmosBasePath: filepath.Join(suites.SourceDir, fixturesDir), + Vars: map[string]interface{}{}, + }) + + if err != nil { + return suites, err + } + + for stackName, stack := range describeStacksConfigs.Stacks { + for componentName, component := range stack.Components.Terraform { + if component.Settings.Test != nil { + if component.Settings.Test.Suite == "" { + return &XTestSuites{}, fmt.Errorf("settings.test.suite is required for component %s in stack %s", componentName, stackName) + } + + suiteName := component.Settings.Test.Suite + + validStages := []string{"testSuiteSetUp", "testSetUp", "subjectUnderTest", "assert"} + + if component.Settings.Test.Stage == "" { + return &XTestSuites{}, fmt.Errorf("settings.test.stage is required for component %s in stack %s", componentName, stackName) + } else if !slices.Contains(validStages, component.Settings.Test.Stage) { + message := "settings.test.stage should be one of \"testSuiteSetUp\", \"testSetUp\", \"subjectUnderTest\", \"assert\" for component %s in stack %s" + return &XTestSuites{}, fmt.Errorf(message, componentName, stackName) + } + + stage := component.Settings.Test.Stage + + if stage != "testSuiteSetUp" && component.Settings.Test.Test == "" { + return &XTestSuites{}, fmt.Errorf("settings.test.test is required for component %s in stack %s", componentName, stackName) + } + + testName := component.Settings.Test.Test + + suite := suites.GetOrCreateSuite(suiteName) + + switch stage { + case "testSuiteSetUp": + suite.AddSetup(componentName, stackName) + case "testSetUp": + suite.GetOrCreateTest(testName).AddSetup(componentName, stackName) + case "subjectUnderTest": + suite.GetOrCreateTest(testName).SetSubject(componentName, stackName) + case "assert": + suite.GetOrCreateTest(testName).AddSAssert(componentName, stackName) + } + } + } + } + + //for _, opt := range opts { + // opt(suite) + //} + + return suites, nil +} + +func (ts *XTestSuites) Run(t *testing.T) { + fmt.Printf("create TMP dir: %s \n", ts.WorkDir) + + err := os.Mkdir(ts.WorkDir, 0777) + assert.NoError(t, err) + defer os.RemoveAll(ts.WorkDir) + + err = copyDirectoryRecursively(ts.SourceDir, ts.WorkDir) + assert.NoError(t, err) + + atmos.VendorPull(t, ts.AtmosOptions) + + err = createStateDir(ts.WorkDir) + assert.NoError(t, err) + + // t.Parallel() + for name, suite := range ts.suites { + t.Run(name, func(t *testing.T) { + suite.Run(t) + }) + } +} + +func (ts *XTestSuites) GetOrCreateSuite(name string) *XTestSuite { + if _, ok := ts.suites[name]; !ok { + ts.suites[name] = NewXTestSuite(ts.AtmosOptions) + } + return ts.suites[name] + +} + +func (ts *XTestSuites) SetSuite(name string, item *XTestSuite) { + ts.suites[name] = item +} diff --git a/pkg/atmos/aws-component-helper/x_test_suites_test.go b/pkg/atmos/aws-component-helper/x_test_suites_test.go new file mode 100644 index 0000000..2c08582 --- /dev/null +++ b/pkg/atmos/aws-component-helper/x_test_suites_test.go @@ -0,0 +1,130 @@ +package aws_component_helper + +import ( + "fmt" + "github.com/cloudposse/test-helpers/pkg/atmos" + tt "github.com/cloudposse/test-helpers/pkg/testing" + "github.com/gruntwork-io/terratest/modules/files" + "github.com/stretchr/testify/require" + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +const atmosExamplePath = "test/fixtures/aws-component-helper" + +func mockAtmos() { + atmosApply = func(t tt.TestingT, options *atmos.Options) string { + options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "apply", "-input=false", "-auto-approve")...) + description := fmt.Sprintf("%s %v", options.AtmosBinary, args) + fmt.Println(description) + return "" + } + + atmosDestroy = func(t tt.TestingT, options *atmos.Options) string { + options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "destroy", "-input=false", "-auto-approve")...) + description := fmt.Sprintf("%s %v", options.AtmosBinary, args) + fmt.Println(description) + return "" + } + + atmosPlanExitCodeE = func(t tt.TestingT, options *atmos.Options) (int, error) { + options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "plan", "-input=false", "-detailed-exitcode")...) + description := fmt.Sprintf("%s %v", options.AtmosBinary, args) + fmt.Println(description) + return 0, nil + } +} + +func TestComponentTestSuitesMinimum(t *testing.T) { + componentTestSuites := &XTestSuites{ + FixturesPath: "testdata/fixtures", + WorkDir: "testdata/tmp", + AwsAccountId: "123456789012", + AwsRegion: "us-west-2", + AtmosOptions: &atmos.Options{}, + suites: map[string]*XTestSuite{ + "default": { + tests: map[string]*ComponentTest{ + "test": { + Subject: &AtmosComponent{ + Component: "vpc", + Stack: "default-test", + }, + }, + }, + }, + }, + } + assert.Equal(t, componentTestSuites.FixturesPath, "testdata/fixtures") + assert.Equal(t, componentTestSuites.WorkDir, "testdata/tmp") + assert.Equal(t, componentTestSuites.AwsAccountId, "123456789012") + assert.Equal(t, componentTestSuites.AwsRegion, "us-west-2") + // assert.Equal(t, componentTestSuites.AtmosOptions, "us-west-2") + assert.Equal(t, componentTestSuites.suites["default"].tests["test"].Subject.Component, "vpc") + assert.Equal(t, componentTestSuites.suites["default"].tests["test"].Subject.Stack, "default-test") +} + +func TestComponentTestSuitesCreate(t *testing.T) { + getAwsAccountIdMock := func() (string, error) { + return "123456789012", nil + } + + testFolder, err := files.CopyTerraformFolderToTemp("../../../", t.Name()) + require.NoError(t, err) + defer os.RemoveAll(testFolder) + + fmt.Printf("running in %s\n", testFolder) + + componentTestSuites, err := NewTestSuites(t, testFolder, "us-west-2", getAwsAccountIdMock, atmosExamplePath) + + assert.NoError(t, err) + + assert.Equal(t, componentTestSuites.SourceDir, testFolder) + + // There is one testSuite + assert.NotEmpty(t, componentTestSuites.suites) + assert.NotNil(t, componentTestSuites.suites["default"]) + + // testSuite does not have setup steps + assert.Empty(t, componentTestSuites.suites["default"].setup) + + // testSuite has one test + assert.NotEmpty(t, componentTestSuites.suites["default"].tests) + assert.NotNil(t, componentTestSuites.suites["default"].tests["two-private-subnets"]) + + // test has no setup step + assert.Empty(t, componentTestSuites.suites["default"].tests["two-private-subnets"].setup) + + // test has subject + assert.NotNil(t, componentTestSuites.suites["default"].tests["two-private-subnets"].Subject) + assert.Equal(t, componentTestSuites.suites["default"].tests["two-private-subnets"].Subject.Component, "vpc") + assert.Equal(t, componentTestSuites.suites["default"].tests["two-private-subnets"].Subject.Stack, "default-test") + + // test has one assert + assert.NotEmpty(t, componentTestSuites.suites["default"].tests["two-private-subnets"].assert) + assert.NotNil(t, componentTestSuites.suites["default"].tests["two-private-subnets"].assert[0]) + assert.Equal(t, componentTestSuites.suites["default"].tests["two-private-subnets"].assert[0].Component, "assert") + assert.Equal(t, componentTestSuites.suites["default"].tests["two-private-subnets"].assert[0].Stack, "default-test") +} + +func TestComponentTestSuitesRun(t *testing.T) { + getAwsAccountIdMock := func() (string, error) { + return "123456789012", nil + } + + mockAtmos() + + testFolder, err := files.CopyFolderToTemp("../../../", t.Name(), func(path string) bool { return true }) + require.NoError(t, err) + defer os.RemoveAll(testFolder) + + fmt.Printf("running in %s\n", testFolder) + + componentTestSuites, err := NewTestSuites(t, testFolder, "us-west-2", getAwsAccountIdMock, atmosExamplePath) + + assert.NoError(t, err) + + componentTestSuites.Run(t) +} diff --git a/pkg/atmos/describe_stacks.go b/pkg/atmos/describe_stacks.go index e99a50d..26e2bea 100644 --- a/pkg/atmos/describe_stacks.go +++ b/pkg/atmos/describe_stacks.go @@ -1,22 +1,38 @@ package atmos +import ( + "encoding/json" + "github.com/cloudposse/test-helpers/pkg/testing" + "github.com/stretchr/testify/require" +) + type DescribeStacksTerraformComponent struct { - AtmosComponent string `json:"atmos_component"` - AtmosStack string `json:"atmos_stack"` - AtmosStackFile string `json:"atmos_stack_file"` - Backend interface{} `json:"backend"` - BackendType string `json:"backend_type"` - Command string `json:"command"` - Component string `json:"component"` - Env interface{} `json:"env"` - Inheritance interface{} `json:"inheritance"` - Metadata interface{} `json:"metadata"` - Overrides interface{} `json:"overrides"` - RemoteStateBackend interface{} `json:"remote_state_backend"` - RemoteStateBackendType string `json:"remote_state_backend_type"` - Settings interface{} `json:"settings"` - Vars interface{} `json:"vars"` - Workspace string `json:"workspace"` + AtmosComponent string `json:"atmos_component"` + AtmosStack string `json:"atmos_stack"` + AtmosStackFile string `json:"atmos_stack_file"` + Backend interface{} `json:"backend"` + BackendType string `json:"backend_type"` + Command string `json:"command"` + Component string `json:"component"` + Env interface{} `json:"env"` + Inheritance interface{} `json:"inheritance"` + Metadata interface{} `json:"metadata"` + Overrides interface{} `json:"overrides"` + RemoteStateBackend interface{} `json:"remote_state_backend"` + RemoteStateBackendType string `json:"remote_state_backend_type"` + Settings *DescribeStacksTerraformComponentSettings `json:"settings"` + Vars interface{} `json:"vars"` + Workspace string `json:"workspace"` +} + +type DescribeStacksTerraformComponentSettings struct { + Test *DescribeStacksTerraformComponentSettingsTest `json:"test, omitempty"` +} + +type DescribeStacksTerraformComponentSettingsTest struct { + Suite string `json:"suite"` + Test string `json:"test"` + Stage string `json:"stage"` } type DescribeStacksTerraform struct { @@ -24,9 +40,25 @@ type DescribeStacksTerraform struct { } type DescribeStacksComponent struct { - Component map[string]any `json:"component"` + Components DescribeStacksTerraform `json:"components"` } type DescribeStacksOutput struct { Stacks map[string]DescribeStacksComponent } + +func DescribeStacks(t testing.TestingT, options *Options) DescribeStacksOutput { + out, err := DescribeStacksE(t, options) + require.NoError(t, err) + return out +} + +func DescribeStacksE(t testing.TestingT, options *Options) (DescribeStacksOutput, error) { + result := DescribeStacksOutput{} + output, err := RunAtmosCommandAndGetStdoutE(t, options, FormatArgs(options, "describe", "stacks", "--component-types=terraform", "--format=json")...) + if err != nil { + return result, err + } + err = json.Unmarshal([]byte(output), &result.Stacks) + return result, err +} diff --git a/pkg/atmos/describe_stacks_test.go b/pkg/atmos/describe_stacks_test.go new file mode 100644 index 0000000..74babb9 --- /dev/null +++ b/pkg/atmos/describe_stacks_test.go @@ -0,0 +1,29 @@ +package atmos + +import ( + "fmt" + "github.com/gruntwork-io/terratest/modules/files" + "github.com/stretchr/testify/require" + "os" + "testing" +) + +func TestDescribeStacksNoError(t *testing.T) { + t.Parallel() + + testFolder, err := files.CopyTerraformFolderToTemp(atmosExamplePath, t.Name()) + require.NoError(t, err) + defer os.RemoveAll(testFolder) + + fmt.Printf("running in %s\n", testFolder) + + options := WithDefaultRetryableErrors(t, &Options{ + AtmosBasePath: testFolder, + NoColor: true, + }) + + out := DescribeStacks(t, options) + + workspace := out.Stacks["test-test-test"].Components.Terraform["terraform-no-error"].Workspace + require.Equal(t, workspace, "test-test-test") +} diff --git a/pkg/atmos/format.go b/pkg/atmos/format.go index 4837c2f..eda9811 100644 --- a/pkg/atmos/format.go +++ b/pkg/atmos/format.go @@ -11,6 +11,8 @@ import ( const terraformCmd = "terraform" const vendorCmd = "vendor" +const describeCmd = "describe" + // TerraformCommandsWithPlanFileSupport is a list of all the Terraform commands that support interacting with plan // files. var TerraformCommandsWithPlanFileSupport = []string{ @@ -120,10 +122,25 @@ func FormatAtmosVendorArgs(options *Options, args ...string) []string { return vendorArgs } +func FormatAtmosDescribeArgs(options *Options, args ...string) []string { + var describeArgs []string + commandType := args[0] + + describeArgs = append(describeArgs, "describe", commandType) + + describeArgs = append(describeArgs, args[1:]...) + + return describeArgs +} + func FormatArgs(options *Options, args ...string) []string { var atmosArgs []string commandType := args[0] + if commandType == describeCmd { + atmosArgs = append(atmosArgs, FormatAtmosDescribeArgs(options, args[1:]...)...) + } + if commandType == terraformCmd { atmosArgs = append(atmosArgs, FormatAtmosTerraformArgs(options, args[1:]...)...) } diff --git a/pkg/awsnuke/awsnuke.go b/pkg/awsnuke/awsnuke.go deleted file mode 100644 index 17ee887..0000000 --- a/pkg/awsnuke/awsnuke.go +++ /dev/null @@ -1,152 +0,0 @@ -package awsnuke - -import ( - "fmt" - "os" - "sort" - - "github.com/aws/aws-sdk-go/aws/endpoints" - tt "github.com/cloudposse/test-helpers/pkg/testing" - "github.com/gruntwork-io/terratest/modules/aws" - "github.com/gruntwork-io/terratest/modules/testing" - "github.com/rebuy-de/aws-nuke/v2/cmd" - "github.com/rebuy-de/aws-nuke/v2/pkg/awsutil" - nukeconfig "github.com/rebuy-de/aws-nuke/v2/pkg/config" - "github.com/rebuy-de/aws-nuke/v2/resources" - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" -) - -type GenerateAwsNukeConfigConfig struct { - AllRegions bool - AccountId string - Regions []string - TagName string - TagValue string -} - -type RunAwsNukeParams struct { - Config nukeconfig.Nuke - Creds awsutil.Credentials - DefaultRegion string - Params cmd.NukeParameters - Verbose bool -} - -func getAwsNukeSupportedResources() []string { - names := resources.GetListerNames() - sort.Strings(names) - - return names -} - -// GenerateAwsNukeConfigWithTagFilter generates an aws-nuke config object and adds a tag-based filter to every aws-nuke -// supported resource type -func GenerateAwsNukeConfigWithTagFilter(config GenerateAwsNukeConfigConfig) nukeconfig.Nuke { - filters := nukeconfig.Filters{} - for _, resource := range getAwsNukeSupportedResources() { - filter := nukeconfig.Filters{ - resource: []nukeconfig.Filter{ - { - Property: fmt.Sprintf("tag:%s", config.TagName), - Type: "exact", - Value: config.TagValue, - Invert: "true"}, - }, - } - filters.Merge(filter) - } - - nukeCfg := nukeconfig.Nuke{ - Accounts: map[string]nukeconfig.Account{ - config.AccountId: { - Filters: filters, - }, - }, - AccountBlocklist: []string{"999999999999"}, - Regions: config.Regions, - } - - return nukeCfg -} - -// RunAwsNukeExe runs the aws-nuke as a library with the given config -func RunAwsNukeE(params RunAwsNukeParams) error { - var err error - - err = params.Params.Validate() - if err != nil { - return err - } - - if !params.Creds.HasKeys() && !params.Creds.HasProfile() && params.DefaultRegion != "" { - params.Creds.AccessKeyID = os.Getenv("AWS_ACCESS_KEY_ID") - params.Creds.SecretAccessKey = os.Getenv("AWS_SECRET_ACCESS_KEY") - - sessionToken := os.Getenv("AWS_SESSION_TOKEN") - if sessionToken != "" { - params.Creds.SessionToken = sessionToken - } - } - - err = params.Creds.Validate() - if err != nil { - return err - } - - if params.DefaultRegion != "" { - awsutil.DefaultRegionID = params.DefaultRegion - switch params.DefaultRegion { - case endpoints.UsEast1RegionID, endpoints.UsEast2RegionID, endpoints.UsWest1RegionID, endpoints.UsWest2RegionID: - awsutil.DefaultAWSPartitionID = endpoints.AwsPartitionID - case endpoints.UsGovEast1RegionID, endpoints.UsGovWest1RegionID: - awsutil.DefaultAWSPartitionID = endpoints.AwsUsGovPartitionID - default: - if params.Config.CustomEndpoints.GetRegion(params.DefaultRegion) == nil { - err = fmt.Errorf("the custom region '%s' must be specified in the configuration 'endpoints'", params.DefaultRegion) - log.Error(err.Error()) - return err - } - } - } - - account, err := awsutil.NewAccount(params.Creds, params.Config.CustomEndpoints) - if err != nil { - return err - } - - n := cmd.NewNuke(params.Params, *account) - - n.Config = ¶ms.Config - - return n.Run() -} - -func NukeTestAccountByTag(t tt.TestingT, tagName string, tagValue string, regions []string, dryRun bool) { - accountID, err := aws.GetAccountIdE(t.(testing.TestingT)) - assert.NoError(t, err) - - // run sts.getcalleridentity - generateConfig := GenerateAwsNukeConfigConfig{ - AccountId: accountID, - Regions: regions, - TagName: tagName, - TagValue: tagValue, - } - config := GenerateAwsNukeConfigWithTagFilter(generateConfig) - - nukeParams := RunAwsNukeParams{ - Config: config, - Creds: awsutil.Credentials{}, - DefaultRegion: "", - Params: cmd.NukeParameters{ - ConfigPath: "GeneratedConfig", - NoDryRun: !dryRun, - Force: true, - ForceSleep: 3, - }, - } - - err = RunAwsNukeE(nukeParams) - assert.NoError(t, err) -} diff --git a/pkg/awsnuke/awsnuke.go.bk b/pkg/awsnuke/awsnuke.go.bk new file mode 100644 index 0000000..427ea54 --- /dev/null +++ b/pkg/awsnuke/awsnuke.go.bk @@ -0,0 +1,152 @@ +//package awsnuke +// +//import ( +// "fmt" +// "os" +// "sort" +// +// "github.com/aws/aws-sdk-go/aws/endpoints" +// tt "github.com/cloudposse/test-helpers/pkg/testing" +// "github.com/gruntwork-io/terratest/modules/aws" +// "github.com/gruntwork-io/terratest/modules/testing" +// "github.com/rebuy-de/aws-nuke/v2/cmd" +// "github.com/rebuy-de/aws-nuke/v2/pkg/awsutil" +// nukeconfig "github.com/rebuy-de/aws-nuke/v2/pkg/config" +// "github.com/rebuy-de/aws-nuke/v2/resources" +// log "github.com/sirupsen/logrus" +// "github.com/stretchr/testify/assert" +//) +// +//type GenerateAwsNukeConfigConfig struct { +// AllRegions bool +// AccountId string +// Regions []string +// TagName string +// TagValue string +//} +// +//type RunAwsNukeParams struct { +// Config nukeconfig.Nuke +// Creds awsutil.Credentials +// DefaultRegion string +// Params cmd.NukeParameters +// Verbose bool +//} +// +//func getAwsNukeSupportedResources() []string { +// names := resources.GetListerNames() +// sort.Strings(names) +// +// return names +//} +// +//// GenerateAwsNukeConfigWithTagFilter generates an aws-nuke config object and adds a tag-based filter to every aws-nuke +//// supported resource type +//func GenerateAwsNukeConfigWithTagFilter(config GenerateAwsNukeConfigConfig) nukeconfig.Nuke { +// filters := nukeconfig.Filters{} +// for _, resource := range getAwsNukeSupportedResources() { +// filter := nukeconfig.Filters{ +// resource: []nukeconfig.Filter{ +// { +// Property: fmt.Sprintf("tag:%s", config.TagName), +// Type: "exact", +// Value: config.TagValue, +// Invert: "true"}, +// }, +// } +// filters.Merge(filter) +// } +// +// nukeCfg := nukeconfig.Nuke{ +// Accounts: map[string]nukeconfig.Account{ +// config.AccountId: { +// Filters: filters, +// }, +// }, +// AccountBlocklist: []string{"999999999999"}, +// Regions: config.Regions, +// } +// +// return nukeCfg +//} +// +//// RunAwsNukeExe runs the aws-nuke as a library with the given config +//func RunAwsNukeE(params RunAwsNukeParams) error { +// var err error +// +// err = params.Params.Validate() +// if err != nil { +// return err +// } +// +// if !params.Creds.HasKeys() && !params.Creds.HasProfile() && params.DefaultRegion != "" { +// params.Creds.AccessKeyID = os.Getenv("AWS_ACCESS_KEY_ID") +// params.Creds.SecretAccessKey = os.Getenv("AWS_SECRET_ACCESS_KEY") +// +// sessionToken := os.Getenv("AWS_SESSION_TOKEN") +// if sessionToken != "" { +// params.Creds.SessionToken = sessionToken +// } +// } +// +// err = params.Creds.Validate() +// if err != nil { +// return err +// } +// +// if params.DefaultRegion != "" { +// awsutil.DefaultRegionID = params.DefaultRegion +// switch params.DefaultRegion { +// case endpoints.UsEast1RegionID, endpoints.UsEast2RegionID, endpoints.UsWest1RegionID, endpoints.UsWest2RegionID: +// awsutil.DefaultAWSPartitionID = endpoints.AwsPartitionID +// case endpoints.UsGovEast1RegionID, endpoints.UsGovWest1RegionID: +// awsutil.DefaultAWSPartitionID = endpoints.AwsUsGovPartitionID +// default: +// if params.Config.CustomEndpoints.GetRegion(params.DefaultRegion) == nil { +// err = fmt.Errorf("the custom region '%s' must be specified in the configuration 'endpoints'", params.DefaultRegion) +// log.Error(err.Error()) +// return err +// } +// } +// } +// +// account, err := awsutil.NewAccount(params.Creds, params.Config.CustomEndpoints) +// if err != nil { +// return err +// } +// +// n := cmd.NewNuke(params.Params, *account) +// +// n.Config = ¶ms.Config +// +// return n.Run() +//} +// +//func NukeTestAccountByTag(t tt.TestingT, tagName string, tagValue string, regions []string, dryRun bool) { +// accountID, err := aws.GetAccountIdE(t.(testing.TestingT)) +// assert.NoError(t, err) +// +// // run sts.getcalleridentity +// generateConfig := GenerateAwsNukeConfigConfig{ +// AccountId: accountID, +// Regions: regions, +// TagName: tagName, +// TagValue: tagValue, +// } +// config := GenerateAwsNukeConfigWithTagFilter(generateConfig) +// +// nukeParams := RunAwsNukeParams{ +// Config: config, +// Creds: awsutil.Credentials{}, +// DefaultRegion: "", +// Params: cmd.NukeParameters{ +// ConfigPath: "GeneratedConfig", +// NoDryRun: !dryRun, +// Force: true, +// ForceSleep: 3, +// }, +// } +// +// err = RunAwsNukeE(nukeParams) +// assert.NoError(t, err) +//} diff --git a/pkg/awsnuke/awsnuke.go.bk_test.go.bk b/pkg/awsnuke/awsnuke.go.bk_test.go.bk new file mode 100644 index 0000000..c571354 --- /dev/null +++ b/pkg/awsnuke/awsnuke.go.bk_test.go.bk @@ -0,0 +1,57 @@ +////go:build integration +// +//package awsnuke +// +//import ( +// "fmt" +// "os" +// "strings" +// "testing" +// +// "github.com/gruntwork-io/terratest/modules/aws" +// "github.com/gruntwork-io/terratest/modules/random" +// "github.com/gruntwork-io/terratest/modules/terraform" +// testStructure "github.com/gruntwork-io/terratest/modules/test-structure" +// "github.com/stretchr/testify/assert" +//) +// +//const testRegion string = "us-east-2" +//const terratestTagName string = "CreatedByTerratestRun" +// +//func TestAwsNuke(t *testing.T) { +// t.Parallel() +// randID := strings.ToLower(random.UniqueId()) +// +// rootFolder := "../../" +// terraformFolderRelativeToRoot := "examples/awsnuke-example" +// tempTestFolder := testStructure.CopyTerraformFolderToTemp(t, rootFolder, terraformFolderRelativeToRoot) +// defer os.RemoveAll(tempTestFolder) +// +// terraformOptions := &terraform.Options{ +// TerraformDir: tempTestFolder, +// Upgrade: true, +// VarFiles: []string{fmt.Sprintf("fixtures.%s.tfvars", testRegion)}, +// Vars: map[string]interface{}{ +// "attributes": []string{randID}, +// "default_tags": map[string]string{ +// terratestTagName: randID, +// }, +// }, +// } +// +// defer terraform.Destroy(t, terraformOptions) +// terraform.InitAndApply(t, terraformOptions) +// +// // Assert that the bucket has been created +// bucket, err := aws.FindS3BucketWithTagE(t, testRegion, terratestTagName, randID) +// assert.NoError(t, err) +// assert.Equal(t, bucket, fmt.Sprintf("eg-test-s3-bucket-test-%s", randID)) +// +// // Nuke the account with our config +// NukeTestAccountByTag(t, terratestTagName, randID, []string{testRegion}, false) +// +// // Assert that the bucket doesn't exist anymore +// bucket, err = aws.FindS3BucketWithTagE(t, testRegion, terratestTagName, randID) +// assert.NoError(t, err) +// assert.Empty(t, bucket) +//} diff --git a/pkg/awsnuke/awsnuke_test.go b/pkg/awsnuke/awsnuke_test.go deleted file mode 100644 index c8edb4d..0000000 --- a/pkg/awsnuke/awsnuke_test.go +++ /dev/null @@ -1,57 +0,0 @@ -//go:build integration - -package awsnuke - -import ( - "fmt" - "os" - "strings" - "testing" - - "github.com/gruntwork-io/terratest/modules/aws" - "github.com/gruntwork-io/terratest/modules/random" - "github.com/gruntwork-io/terratest/modules/terraform" - testStructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/assert" -) - -const testRegion string = "us-east-2" -const terratestTagName string = "CreatedByTerratestRun" - -func TestAwsNuke(t *testing.T) { - t.Parallel() - randID := strings.ToLower(random.UniqueId()) - - rootFolder := "../../" - terraformFolderRelativeToRoot := "examples/awsnuke-example" - tempTestFolder := testStructure.CopyTerraformFolderToTemp(t, rootFolder, terraformFolderRelativeToRoot) - defer os.RemoveAll(tempTestFolder) - - terraformOptions := &terraform.Options{ - TerraformDir: tempTestFolder, - Upgrade: true, - VarFiles: []string{fmt.Sprintf("fixtures.%s.tfvars", testRegion)}, - Vars: map[string]interface{}{ - "attributes": []string{randID}, - "default_tags": map[string]string{ - terratestTagName: randID, - }, - }, - } - - defer terraform.Destroy(t, terraformOptions) - terraform.InitAndApply(t, terraformOptions) - - // Assert that the bucket has been created - bucket, err := aws.FindS3BucketWithTagE(t, testRegion, terratestTagName, randID) - assert.NoError(t, err) - assert.Equal(t, bucket, fmt.Sprintf("eg-test-s3-bucket-test-%s", randID)) - - // Nuke the account with our config - NukeTestAccountByTag(t, terratestTagName, randID, []string{testRegion}, false) - - // Assert that the bucket doesn't exist anymore - bucket, err = aws.FindS3BucketWithTagE(t, testRegion, terratestTagName, randID) - assert.NoError(t, err) - assert.Empty(t, bucket) -} diff --git a/test/fixtures/atmos/atmos.yaml b/test/fixtures/atmos/atmos.yaml index 91645f8..0af99c4 100644 --- a/test/fixtures/atmos/atmos.yaml +++ b/test/fixtures/atmos/atmos.yaml @@ -320,28 +320,3 @@ integrations: apply: steps: - run: terraform apply $PLANFILE - -# Validation schemas (for validating atmos stacks and components) -schemas: - # https://json-schema.org - jsonschema: - # Can also be set using 'ATMOS_SCHEMAS_JSONSCHEMA_BASE_PATH' ENV var, or '--schemas-jsonschema-dir' command-line arguments - # Supports both absolute and relative paths - base_path: "stacks/schemas/jsonschema" - # https://www.openpolicyagent.org - opa: - # Can also be set using 'ATMOS_SCHEMAS_OPA_BASE_PATH' ENV var, or '--schemas-opa-dir' command-line arguments - # Supports both absolute and relative paths - base_path: "stacks/schemas/opa" - # JSON Schema to validate Atmos manifests - # https://atmos.tools/reference/schemas/ - # https://atmos.tools/cli/commands/validate/stacks/ - # https://atmos.tools/quick-start/configure-validation/ - # https://atmos.tools/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json - # https://json-schema.org/draft/2020-12/release-notes - # https://www.schemastore.org/json - # https://github.com/SchemaStore/schemastore - atmos: - # Can also be set using 'ATMOS_SCHEMAS_ATMOS_MANIFEST' ENV var, or '--schemas-atmos-manifest' command-line arguments - # Supports both absolute and relative paths (relative to the `base_path` setting in `atmos.yaml`) - manifest: "../quick-start/stacks/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json" diff --git a/test/fixtures/aws-component-helper/atmos.yaml b/test/fixtures/aws-component-helper/atmos.yaml new file mode 100644 index 0000000..4529e24 --- /dev/null +++ b/test/fixtures/aws-component-helper/atmos.yaml @@ -0,0 +1,86 @@ +# CLI config is loaded from the following locations (from lowest to highest priority): +# system dir (`/usr/local/etc/atmos` on Linux, `%LOCALAPPDATA%/atmos` on Windows) +# home dir (~/.atmos) +# current directory +# ENV vars +# Command-line arguments +# +# It supports POSIX-style Globs for file names/paths (double-star `**` is supported) +# https://en.wikipedia.org/wiki/Glob_(programming) + +# Base path for components, stacks and workflows configurations. +# Can also be set using `ATMOS_BASE_PATH` ENV var, or `--base-path` command-line argument. +# Supports both absolute and relative paths. +# If not provided or is an empty string, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path` +# are independent settings (supporting both absolute and relative paths). +# If `base_path` is provided, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path` +# are considered paths relative to `base_path`. +base_path: "" + +components: + terraform: + # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_BASE_PATH` ENV var, or `--terraform-dir` command-line argument + # Supports both absolute and relative paths + base_path: "components/terraform" + # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE` ENV var + apply_auto_approve: true + # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_DEPLOY_RUN_INIT` ENV var, or `--deploy-run-init` command-line argument + deploy_run_init: true + # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE` ENV var, or `--init-run-reconfigure` command-line argument + init_run_reconfigure: true + # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_AUTO_GENERATE_BACKEND_FILE` ENV var, or `--auto-generate-backend-file` command-line argument + auto_generate_backend_file: true + +stacks: + # Can also be set using `ATMOS_STACKS_BASE_PATH` ENV var, or `--config-dir` and `--stacks-dir` command-line arguments + # Supports both absolute and relative paths + base_path: "stacks" + # Can also be set using `ATMOS_STACKS_INCLUDED_PATHS` ENV var (comma-separated values string) + # Since we are distinguishing stacks based on namespace, and namespace is not part + # of the stack name, we have to set `included_paths` via the ENV var in the Dockerfile + included_paths: + - "orgs/**/*" + # Can also be set using `ATMOS_STACKS_EXCLUDED_PATHS` ENV var (comma-separated values string) + excluded_paths: + - "**/_defaults.yaml" + + # Can also be set using `ATMOS_STACKS_NAME_PATTERN` ENV var + name_pattern: "{tenant}-{stage}" + +workflows: + # Can also be set using `ATMOS_WORKFLOWS_BASE_PATH` ENV var, or `--workflows-dir` command-line arguments + # Supports both absolute and relative paths + base_path: "stacks/workflows" + +# https://github.com/cloudposse/atmos/releases/tag/v1.33.0 +logs: + file: "/dev/stdout" + # Supported log levels: Trace, Debug, Info, Warning, Off + level: Info + +settings: + # Can also be set using 'ATMOS_SETTINGS_LIST_MERGE_STRATEGY' environment variable, or '--settings-list-merge-strategy' command-line argument + list_merge_strategy: replace + +# `Go` templates in Atmos manifests +# https://atmos.tools/core-concepts/stacks/templating +# https://pkg.go.dev/text/template +templates: + settings: + enabled: true + # https://masterminds.github.io/sprig + sprig: + enabled: true + # https://docs.gomplate.ca + gomplate: + enabled: true + +commands: + - name: "test-components" + description: "List the Atmos virtual components configured for testing" + steps: + - > + atmos describe stacks --format json --sections=component,metadata --components=component -s sandbox + | jq '.[] | .components.terraform | to_entries | + map(select(.value.component == "component" and (.value.metadata.type != "abstract" or .value.metadata.type == null))) + | .[].key' diff --git a/test/fixtures/aws-component-helper/components/terraform/account-map/.gitkeep b/test/fixtures/aws-component-helper/components/terraform/account-map/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/fixtures/aws-component-helper/components/terraform/assert/.gitkeep b/test/fixtures/aws-component-helper/components/terraform/assert/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/fixtures/aws-component-helper/stacks/catalog/account-map.yaml b/test/fixtures/aws-component-helper/stacks/catalog/account-map.yaml new file mode 100644 index 0000000..904e69a --- /dev/null +++ b/test/fixtures/aws-component-helper/stacks/catalog/account-map.yaml @@ -0,0 +1,46 @@ +components: + terraform: + account-map: + metadata: + terraform_workspace: core-gbl-root + vars: + tenant: core + environment: gbl + stage: root + +# This remote state is only for Cloud Posse internal use. +# It references the Cloud Posse test organizations actual infrastructure. +# remote_state_backend: +# s3: +# bucket: cptest-core-ue2-root-tfstate-core +# dynamodb_table: cptest-core-ue2-root-tfstate-core-lock +# role_arn: arn:aws:iam::822777368227:role/cptest-core-gbl-root-tfstate-core-ro +# encrypt: true +# key: terraform.tfstate +# acl: bucket-owner-full-control +# region: us-east-2 + + remote_state_backend_type: static + remote_state_backend: + # This static backend is used for tests that only need to use the account map iam-roles module + # to find the role to assume for Terraform operations. It is configured to use whatever + # the current user's role is, but the environment variable `TEST_ACCOUNT_ID` must be set to + # the account ID of the account that the user is currently assuming a role in. + # + # For some components, this backend is missing important data, and those components + # will need that data added to the backend configuration in order to work properly. + static: + account_info_map: {} + all_accounts: [] + aws_partition: aws + full_account_map: {} + iam_role_arn_templates: {} + non_eks_accounts: [] + profiles_enabled: false + root_account_aws_name: root + terraform_access_map: {} + terraform_dynamic_role_enabled: true + terraform_role_name_map: + apply: terraform + plan: planner + terraform_roles: {} diff --git a/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml b/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml new file mode 100644 index 0000000..51f7679 --- /dev/null +++ b/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml @@ -0,0 +1,68 @@ +import: + - catalog/account-map + +terraform: + backend_type: local + backend: + local: + path: ../../../../state/{{ .component }}/terraform.tfstate + workspace_dir: ../../../../state/{{ .component }}/ + metadata: + terraform_workspace_pattern: "{component}-{environment}" + vars: + namespace: eg + tenant: default + environment: ue2 + region: us-east-2 + stage: test + label_order: + - namespace + - tenant + - environment + - stage + - name + - attributes + descriptor_formats: + account_name: + format: "%v-%v" + labels: + - tenant + - stage + stack: + format: "%v-%v-%v" + labels: + - tenant + - environment + - stage + +components: + terraform: + account-map: + remote_state_backend: + static: + account_info_map: + cptest-default: + account_email_format: aws+cptest-%s@example.com + eks: true + id: '{{ getenv "TEST_ACCOUNT_ID" | default "" }}' + ou: default + parent_ou: none + stage: test + tags: + eks: false + tenant: default + all_accounts: + - cptest-default + artifacts_account_account_name: cptest-default + audit_account_account_name: cptest-default + dns_account_account_name: cptest-default + eks_accounts: + - cptest-default + full_account_map: + cptest-default: '{{ getenv "TEST_ACCOUNT_ID" | default "" }}' + iam_role_arn_templates: + cptest-default: 'arn:aws:iam::{{ getenv "TEST_ACCOUNT_ID" | default "" }}:role/tester-%s' + identity_account_account_name: cptest-default + root_account_account_name: cptest-default + terraform_roles: + cptest-default: 'arn:aws:iam::{{ getenv "TEST_ACCOUNT_ID" | default "" }}:role/tester-terraform' diff --git a/test/fixtures/aws-component-helper/stacks/orgs/default/test/tests.yaml b/test/fixtures/aws-component-helper/stacks/orgs/default/test/tests.yaml new file mode 100644 index 0000000..8a0d9ce --- /dev/null +++ b/test/fixtures/aws-component-helper/stacks/orgs/default/test/tests.yaml @@ -0,0 +1,40 @@ +import: + - path: orgs/default/test/_defaults + # We need to define a context to enable template substitution + context: {} + +components: + terraform: + vpc: + settings: + test: + suite: default + test: two-private-subnets + stage: subjectUnderTest + vars: + name: "vpc" + availability_zones: + - "a" + - "b" + # If we want to do functional testing of the bastion, we need public subnets, + # internet gateway, and NAT gateway, but those are expensive and for now, + # we are just doing basic smoke testing, so we skip them. + # public_subnets_enabled: true + # max_nats: 1 + # nat_gateway_enabled: true + public_subnets_enabled: false + nat_gateway_enabled: false + nat_instance_enabled: false + subnet_type_tag_key: "eg.cptest.co/subnet/type" + max_subnet_count: 3 + vpc_flow_logs_enabled: false + ipv4_primary_cidr_block: "172.16.0.0/16" + + assert: + settings: + test: + suite: default + test: two-private-subnets + stage: assert + vars: + name: "assert" diff --git a/test/fixtures/aws-component-helper/vendor.yaml b/test/fixtures/aws-component-helper/vendor.yaml new file mode 100644 index 0000000..2c5489e --- /dev/null +++ b/test/fixtures/aws-component-helper/vendor.yaml @@ -0,0 +1,29 @@ +apiVersion: atmos/v1 +kind: AtmosVendorConfig +metadata: + name: fixtures + description: Atmos vendoring manifest +spec: + sources: + - component: "account-map" + source: github.com/cloudposse/terraform-aws-components.git//modules/account-map?ref={{.Version}} + version: 1.520.0 + targets: + - "components/terraform/account-map" + included_paths: + - "**/*.tf" + - "**/*.md" + - "**/*.tftmpl" + - "**/modules/**" + excluded_paths: [] + +# - component: "vpc" +# source: "../../src" +# targets: +# - "components/terraform/vpc" +# included_paths: +# - "**/*.tf" +# - "**/*.md" +# - "**/*.tftmpl" +# - "**/modules/**" +# excluded_paths: [] From df384c1a5c3ad86517355a04530df00db0107a32 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Sun, 22 Dec 2024 10:49:23 +0100 Subject: [PATCH 02/40] Fix aws get account id --- pkg/atmos/aws-component-helper/x_test_suites.go | 8 ++++++-- pkg/atmos/aws-component-helper/x_test_suites_test.go | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index c9889a3..7eebffe 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -12,6 +12,10 @@ import ( "testing" ) +var ( + getAwsAaccountIdCallback = getAwsAccountId +) + type XTestSuites struct { RandomIdentifier string AtmosOptions *atmos.Options @@ -23,8 +27,8 @@ type XTestSuites struct { suites map[string]*XTestSuite } -func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, f func() (string, error), fixturesDir string) (*XTestSuites, error) { - awsAccountId, err := f() +func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, fixturesDir string) (*XTestSuites, error) { + awsAccountId, err := getAwsAaccountIdCallback() if err != nil { return &XTestSuites{}, err } diff --git a/pkg/atmos/aws-component-helper/x_test_suites_test.go b/pkg/atmos/aws-component-helper/x_test_suites_test.go index 2c08582..dd2df62 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites_test.go +++ b/pkg/atmos/aws-component-helper/x_test_suites_test.go @@ -67,7 +67,7 @@ func TestComponentTestSuitesMinimum(t *testing.T) { } func TestComponentTestSuitesCreate(t *testing.T) { - getAwsAccountIdMock := func() (string, error) { + getAwsAaccountIdCallback = func() (string, error) { return "123456789012", nil } @@ -77,7 +77,7 @@ func TestComponentTestSuitesCreate(t *testing.T) { fmt.Printf("running in %s\n", testFolder) - componentTestSuites, err := NewTestSuites(t, testFolder, "us-west-2", getAwsAccountIdMock, atmosExamplePath) + componentTestSuites, err := NewTestSuites(t, testFolder, "us-west-2", atmosExamplePath) assert.NoError(t, err) @@ -110,7 +110,7 @@ func TestComponentTestSuitesCreate(t *testing.T) { } func TestComponentTestSuitesRun(t *testing.T) { - getAwsAccountIdMock := func() (string, error) { + getAwsAaccountIdCallback = func() (string, error) { return "123456789012", nil } @@ -122,7 +122,7 @@ func TestComponentTestSuitesRun(t *testing.T) { fmt.Printf("running in %s\n", testFolder) - componentTestSuites, err := NewTestSuites(t, testFolder, "us-west-2", getAwsAccountIdMock, atmosExamplePath) + componentTestSuites, err := NewTestSuites(t, testFolder, "us-west-2", atmosExamplePath) assert.NoError(t, err) From c6f5f557d1a8641c985aa451940cb58efd889323 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 23 Dec 2024 00:24:15 +0100 Subject: [PATCH 03/40] Make atmos options runtime configuration --- .../aws-component-helper/atmos_component.go | 21 +- .../atmos_component_test.go | 3 +- .../aws-component-helper/setup_test_suite.go | 2 +- .../aws-component-helper/test_component.go | 72 ++++--- .../test_component_test.go | 3 +- .../aws-component-helper/x_test_suite.go | 34 +-- .../aws-component-helper/x_test_suite_test.go | 3 +- .../aws-component-helper/x_test_suites.go | 197 +++++++++++------- .../x_test_suites_test.go | 15 +- 9 files changed, 195 insertions(+), 155 deletions(-) diff --git a/pkg/atmos/aws-component-helper/atmos_component.go b/pkg/atmos/aws-component-helper/atmos_component.go index ac2cf04..9b03f6b 100644 --- a/pkg/atmos/aws-component-helper/atmos_component.go +++ b/pkg/atmos/aws-component-helper/atmos_component.go @@ -8,28 +8,29 @@ import ( ) type AtmosComponent struct { - Component string - Stack string - atmosOptions *atmos.Options + Component string + Stack string } -func NewAtmosComponent(component string, stack string, options *atmos.Options) *AtmosComponent { +func NewAtmosComponent(component string, stack string) *AtmosComponent { return &AtmosComponent{ - Component: component, - Stack: stack, - atmosOptions: options, + Component: component, + Stack: stack, } } -func (ac *AtmosComponent) getAtmosOptions(t *testing.T, vars map[string]interface{}) *atmos.Options { - result, _ := ac.atmosOptions.Clone() +func (ac *AtmosComponent) getAtmosOptions(t *testing.T, options *atmos.Options, vars map[string]interface{}) *atmos.Options { + result := &atmos.Options{} + if options != nil { + result, _ = options.Clone() + } // Merge in any additional vars passed in err := mergo.Merge(&result.Vars, vars) require.NoError(t, err) result.Component = ac.Component - result.Stack = ac.Component + result.Stack = ac.Stack atmosOptions := atmos.WithDefaultRetryableErrors(t, result) return atmosOptions diff --git a/pkg/atmos/aws-component-helper/atmos_component_test.go b/pkg/atmos/aws-component-helper/atmos_component_test.go index dd36f44..0405019 100644 --- a/pkg/atmos/aws-component-helper/atmos_component_test.go +++ b/pkg/atmos/aws-component-helper/atmos_component_test.go @@ -1,7 +1,6 @@ package aws_component_helper import ( - "github.com/cloudposse/test-helpers/pkg/atmos" "testing" "github.com/stretchr/testify/assert" @@ -9,7 +8,7 @@ import ( func TestAtmosComponent(t *testing.T) { // Create a temporary atmos component - component := NewAtmosComponent("vpc", "default-test", &atmos.Options{}) + component := NewAtmosComponent("vpc", "default-test") assert.Equal(t, component.Component, "vpc") assert.Equal(t, component.Stack, "default-test") diff --git a/pkg/atmos/aws-component-helper/setup_test_suite.go b/pkg/atmos/aws-component-helper/setup_test_suite.go index 1558dc6..534dfac 100644 --- a/pkg/atmos/aws-component-helper/setup_test_suite.go +++ b/pkg/atmos/aws-component-helper/setup_test_suite.go @@ -122,7 +122,7 @@ func getAwsAccountId() (string, error) { // return &TestSuite{}, err // } // -// // os.Setenv("ATMOS_BASE_PATH", testSuite.WorkDir) +// // os.Setenv("ATMOS_BASE_PATH", testSuite.TempDir) // os.Setenv("ATMOS_CLI_CONFIG_PATH", testSuite.TempDir) // os.Setenv("TEST_ACCOUNT_ID", testSuite.AwsAccountId) // diff --git a/pkg/atmos/aws-component-helper/test_component.go b/pkg/atmos/aws-component-helper/test_component.go index 0995888..726d85f 100644 --- a/pkg/atmos/aws-component-helper/test_component.go +++ b/pkg/atmos/aws-component-helper/test_component.go @@ -5,103 +5,107 @@ import ( "fmt" "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "strings" "testing" ) type ComponentTest struct { - RandomIdentifier string - setup []*AtmosComponent - Subject *AtmosComponent - assert []*AtmosComponent - VerifyEnabledFlag bool - AtmosOptions *atmos.Options + RandomIdentifier string + setup []*AtmosComponent + Subject *AtmosComponent + assert []*AtmosComponent } -func NewComponentTest(options *atmos.Options) *ComponentTest { +func NewComponentTest() *ComponentTest { randID := random.UniqueId() randomId := strings.ToLower(randID) return &ComponentTest{ - RandomIdentifier: randomId, - setup: make([]*AtmosComponent, 0), - Subject: nil, - assert: make([]*AtmosComponent, 0), - VerifyEnabledFlag: true, - AtmosOptions: options, + RandomIdentifier: randomId, + setup: make([]*AtmosComponent, 0), + Subject: nil, + assert: make([]*AtmosComponent, 0), } } -func (ct *ComponentTest) Run(t *testing.T) { +func (ct *ComponentTest) Run(t *testing.T, options *atmos.Options) { + testOptions := ct.getAtmosOptions(t, options, map[string]interface{}{}) for _, component := range ct.setup { - componentOptions := component.getAtmosOptions(t, map[string]interface{}{}) + componentOptions := component.getAtmosOptions(t, testOptions, map[string]interface{}{}) atmosApply(t, componentOptions) defer atmosDestroy(t, componentOptions) } - if ct.VerifyEnabledFlag { + if !*skipVerifyEnabledFlag { fmt.Println("VerifyEnabledFlag") - ct.verifyEnabledFlag(t, ct.Subject) + ct.verifyEnabledFlag(t, ct.Subject, options) } else { fmt.Println("Skipping VerifyEnabledFlag") } - subjectOptions := ct.Subject.getAtmosOptions(t, map[string]interface{}{}) + subjectOptions := ct.Subject.getAtmosOptions(t, testOptions, map[string]interface{}{}) atmosApply(t, subjectOptions) defer atmosDestroy(t, subjectOptions) for _, component := range ct.assert { - componentOptions := component.getAtmosOptions(t, map[string]interface{}{}) + componentOptions := component.getAtmosOptions(t, testOptions, map[string]interface{}{}) atmosApply(t, componentOptions) defer atmosDestroy(t, componentOptions) } } -func (ct *ComponentTest) verifyEnabledFlag(t *testing.T, component *AtmosComponent) *atmos.Options { +func (ct *ComponentTest) verifyEnabledFlag(t *testing.T, component *AtmosComponent, options *atmos.Options) *atmos.Options { + testOptions := ct.getAtmosOptions(t, options, map[string]interface{}{}) vars := map[string]interface{}{ "enabled": false, } - options := component.getAtmosOptions(t, vars) - exitCode, err := atmosPlanExitCodeE(t, options) - assert.NoError(t, err) + componentOptions := component.getAtmosOptions(t, testOptions, vars) + + exitCode, err := atmosPlanExitCodeE(t, componentOptions) + require.NoError(t, err) if exitCode != 0 { - assert.Fail(t, "running atmos terraform plan with enabled flag set to false resulted in resource changes") + require.Fail(t, "running atmos terraform plan with enabled flag set to false resulted in resource changes") } return options } -func (ct *ComponentTest) getAtmosOptions() *atmos.Options { - result, _ := ct.AtmosOptions.Clone() +func (ct *ComponentTest) getAtmosOptions(t *testing.T, options *atmos.Options, vars map[string]interface{}) *atmos.Options { + result := &atmos.Options{} + if options != nil { + result, _ = options.Clone() + } + mergedVars := map[string]interface{}{ "default_tags": map[string]string{ "CreatedByAtmosTestSuiteTest": ct.RandomIdentifier, }, } + // Merge in any additional vars passed in err := mergo.Merge(&result.Vars, mergedVars) - if err != nil { - return nil - } - //require.NoError(t, err) + require.NoError(t, err) + + err = mergo.Merge(&result.Vars, vars) + require.NoError(t, err) return result } func (ct *ComponentTest) AddSetup(component string, stack string) { - item := NewAtmosComponent(component, stack, ct.getAtmosOptions()) + item := NewAtmosComponent(component, stack) ct.setup = append(ct.setup, item) } func (ct *ComponentTest) SetSubject(component string, stack string) { - ct.Subject = NewAtmosComponent(component, stack, ct.getAtmosOptions()) + ct.Subject = NewAtmosComponent(component, stack) } func (ct *ComponentTest) AddSAssert(component string, stack string) { - item := NewAtmosComponent(component, stack, ct.getAtmosOptions()) + item := NewAtmosComponent(component, stack) ct.assert = append(ct.assert, item) } diff --git a/pkg/atmos/aws-component-helper/test_component_test.go b/pkg/atmos/aws-component-helper/test_component_test.go index 79102c2..58b9b03 100644 --- a/pkg/atmos/aws-component-helper/test_component_test.go +++ b/pkg/atmos/aws-component-helper/test_component_test.go @@ -1,14 +1,13 @@ package aws_component_helper import ( - "github.com/cloudposse/test-helpers/pkg/atmos" "testing" "github.com/stretchr/testify/assert" ) func TestComponentTestMinimum(t *testing.T) { - componentTest := NewComponentTest(&atmos.Options{}) + componentTest := NewComponentTest() componentTest.SetSubject("vpc", "default-test") assert.Equal(t, componentTest.Subject.Component, "vpc") diff --git a/pkg/atmos/aws-component-helper/x_test_suite.go b/pkg/atmos/aws-component-helper/x_test_suite.go index 6e1fa44..0239cc7 100644 --- a/pkg/atmos/aws-component-helper/x_test_suite.go +++ b/pkg/atmos/aws-component-helper/x_test_suite.go @@ -4,6 +4,7 @@ import ( "dario.cat/mergo" "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" + "github.com/stretchr/testify/require" "strings" "testing" ) @@ -15,42 +16,46 @@ type XTestSuite struct { atmosOptions *atmos.Options } -func NewXTestSuite(options *atmos.Options) *XTestSuite { +func NewXTestSuite() *XTestSuite { randID := random.UniqueId() randomId := strings.ToLower(randID) + return &XTestSuite{ RandomIdentifier: randomId, setup: make([]*AtmosComponent, 0), tests: make(map[string]*ComponentTest), - atmosOptions: options, } } -func (ts *XTestSuite) getAtmosOptions() *atmos.Options { - result, _ := ts.atmosOptions.Clone() +func (ts *XTestSuite) getAtmosOptions(t *testing.T, options *atmos.Options, vars map[string]interface{}) *atmos.Options { + result := &atmos.Options{} + if options != nil { + result, _ = options.Clone() + } + + err := mergo.Merge(&result.Vars, vars) + require.NoError(t, err) - vars := map[string]interface{}{ + suiteVars := map[string]interface{}{ "attributes": []string{ts.RandomIdentifier}, "default_tags": map[string]string{ "CreatedByAtmosTestSuite": ts.RandomIdentifier, }, } - err := mergo.Merge(&result.Vars, vars) - if err != nil { - return nil - } + err = mergo.Merge(&result.Vars, suiteVars) + require.NoError(t, err) return result } func (ts *XTestSuite) AddSetup(component string, stack string) { - item := NewAtmosComponent(component, stack, ts.getAtmosOptions()) + item := NewAtmosComponent(component, stack) ts.setup = append(ts.setup, item) } func (ts *XTestSuite) GetOrCreateTest(name string) *ComponentTest { if _, ok := ts.tests[name]; !ok { - ts.tests[name] = NewComponentTest(ts.getAtmosOptions()) + ts.tests[name] = NewComponentTest() } return ts.tests[name] } @@ -59,9 +64,10 @@ func (ts *XTestSuite) Tests() map[string]*ComponentTest { return ts.tests } -func (ts *XTestSuite) Run(t *testing.T) { +func (ts *XTestSuite) Run(t *testing.T, options *atmos.Options) { + suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) for _, component := range ts.setup { - componentOptions := component.getAtmosOptions(t, map[string]interface{}{}) + componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) atmosApply(t, componentOptions) defer atmosDestroy(t, componentOptions) } @@ -69,7 +75,7 @@ func (ts *XTestSuite) Run(t *testing.T) { //t.Parallel() for name, item := range ts.tests { t.Run(name, func(t *testing.T) { - item.Run(t) + item.Run(t, suiteOptions) }) } } diff --git a/pkg/atmos/aws-component-helper/x_test_suite_test.go b/pkg/atmos/aws-component-helper/x_test_suite_test.go index 039715c..dee6b55 100644 --- a/pkg/atmos/aws-component-helper/x_test_suite_test.go +++ b/pkg/atmos/aws-component-helper/x_test_suite_test.go @@ -1,14 +1,13 @@ package aws_component_helper import ( - "github.com/cloudposse/test-helpers/pkg/atmos" "testing" "github.com/stretchr/testify/assert" ) func TestComponentTestSuiteMinimum(t *testing.T) { - componentTestSuite := NewXTestSuite(&atmos.Options{}) + componentTestSuite := NewXTestSuite() test := componentTestSuite.GetOrCreateTest("test") test.SetSubject("vpc", "default-test") diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index 7eebffe..86174e3 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -1,13 +1,15 @@ package aws_component_helper import ( + "dario.cat/mergo" + "flag" "fmt" "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "os" "path/filepath" - "slices" "strings" "testing" ) @@ -16,134 +18,169 @@ var ( getAwsAaccountIdCallback = getAwsAccountId ) +var ( + skipTmpDir = flag.Bool("cth.skip-tmp-dir", false, "Run in the current directory") + skipVendorDependencies = flag.Bool("cth.skip-vendor", false, "skip vendor dependencies") + forceNewSuite = flag.Bool("cth.force-new-suite", false, "force new suite") + suiteIndex = flag.Int("cth.suite-index", -1, "suite index") + skipAwsNuke = flag.Bool("cth.skip-aws-nuke", false, "skip aws nuke") + skipDeployDependencies = flag.Bool("cth.skip-deploy-deps", false, "skip deploy dependencies") + skipDestroyDependencies = flag.Bool("cth.skip-destroy-deps", false, "skip destroy dependencies") + skipSetupComponentUnderTest = flag.Bool("cth.skip-setup-cut", false, "skip setup component under test") + skipDeployComponentUnderTest = flag.Bool("cth.skip-deploy-cut", false, "skip deploy component under test") + skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") + skipTeardownTestSuite = flag.Bool("cth.skip-teardown", false, "skip test suite teardown") + + skipVerifyEnabledFlag = flag.Bool("cth.skip-verify-enabled-flag", true, "skip verify enabled flag") + skipTests = flag.Bool("cth.skip-tests", false, "skip tests") +) + type XTestSuites struct { RandomIdentifier string - AtmosOptions *atmos.Options AwsAccountId string AwsRegion string SourceDir string + TempDir string FixturesPath string - WorkDir string suites map[string]*XTestSuite } -func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, fixturesDir string) (*XTestSuites, error) { +func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, fixturesDir string) *XTestSuites { awsAccountId, err := getAwsAaccountIdCallback() - if err != nil { - return &XTestSuites{}, err - } + require.NoError(t, err) randID := random.UniqueId() randomId := strings.ToLower(randID) - workdir := filepath.Join(os.TempDir(), "test-suites-"+randomId) - suitesOptions := &atmos.Options{ - AtmosBasePath: filepath.Join(workdir, fixturesDir), - NoColor: true, - Vars: map[string]interface{}{ - "region": awsRegion, - }, - } - + tmpdir := filepath.Join(os.TempDir(), "test-suites-"+randomId) suites := &XTestSuites{ RandomIdentifier: randomId, SourceDir: sourceDir, + TempDir: tmpdir, FixturesPath: fixturesDir, - WorkDir: workdir, AwsAccountId: awsAccountId, AwsRegion: awsRegion, - AtmosOptions: suitesOptions, suites: map[string]*XTestSuite{}, } - describeStacksConfigs, err := atmos.DescribeStacksE(t, &atmos.Options{ - AtmosBasePath: filepath.Join(suites.SourceDir, fixturesDir), - Vars: map[string]interface{}{}, - }) + describeStacksOptions := suites.getAtmosOptions(t, &atmos.Options{}, map[string]interface{}{}) + describeStacksOptions.AtmosBasePath = filepath.Join(suites.SourceDir, suites.FixturesPath) + describeStacksOptions.EnvVars["ATMOS_BASE_PATH"] = describeStacksOptions.AtmosBasePath - if err != nil { - return suites, err - } + describeStacksConfigs, err := atmos.DescribeStacksE(t, describeStacksOptions) + require.NoError(t, err) for stackName, stack := range describeStacksConfigs.Stacks { for componentName, component := range stack.Components.Terraform { - if component.Settings.Test != nil { - if component.Settings.Test.Suite == "" { - return &XTestSuites{}, fmt.Errorf("settings.test.suite is required for component %s in stack %s", componentName, stackName) - } - - suiteName := component.Settings.Test.Suite - - validStages := []string{"testSuiteSetUp", "testSetUp", "subjectUnderTest", "assert"} - - if component.Settings.Test.Stage == "" { - return &XTestSuites{}, fmt.Errorf("settings.test.stage is required for component %s in stack %s", componentName, stackName) - } else if !slices.Contains(validStages, component.Settings.Test.Stage) { - message := "settings.test.stage should be one of \"testSuiteSetUp\", \"testSetUp\", \"subjectUnderTest\", \"assert\" for component %s in stack %s" - return &XTestSuites{}, fmt.Errorf(message, componentName, stackName) - } - - stage := component.Settings.Test.Stage - - if stage != "testSuiteSetUp" && component.Settings.Test.Test == "" { - return &XTestSuites{}, fmt.Errorf("settings.test.test is required for component %s in stack %s", componentName, stackName) - } - - testName := component.Settings.Test.Test - - suite := suites.GetOrCreateSuite(suiteName) - - switch stage { - case "testSuiteSetUp": - suite.AddSetup(componentName, stackName) - case "testSetUp": - suite.GetOrCreateTest(testName).AddSetup(componentName, stackName) - case "subjectUnderTest": - suite.GetOrCreateTest(testName).SetSubject(componentName, stackName) - case "assert": - suite.GetOrCreateTest(testName).AddSAssert(componentName, stackName) - } + if component.Settings.Test == nil { + // Skip components that are not part of tests + continue + } + + suiteName := component.Settings.Test.Suite + require.NotEmptyf(t, suiteName, "settings.test.suite is required for component %s in stack %s", componentName, stackName) + + validStages := []string{"testSuiteSetUp", "testSetUp", "subjectUnderTest", "assert"} + stage := component.Settings.Test.Stage + + require.NotEmptyf(t, stage, "settings.test.stage is required for component %s in stack %s", componentName, stackName) + require.Containsf(t, validStages, stage, "settings.test.stage should be one of %v for component %s in stack %s", validStages, componentName, stackName) + + testName := component.Settings.Test.Test + require.False(t, stage != "testSuiteSetUp" && testName == "", "settings.test.test is required for component %s in stack %s", componentName, stackName) + + suite := suites.GetOrCreateSuite(suiteName) + + switch stage { + case "testSuiteSetUp": + suite.AddSetup(componentName, stackName) + case "testSetUp": + suite.GetOrCreateTest(testName).AddSetup(componentName, stackName) + case "subjectUnderTest": + suite.GetOrCreateTest(testName).SetSubject(componentName, stackName) + case "assert": + suite.GetOrCreateTest(testName).AddSAssert(componentName, stackName) } } } - //for _, opt := range opts { - // opt(suite) - //} + return suites +} - return suites, nil +func (ts *XTestSuites) WorkDir() string { + if !*skipTmpDir { + return filepath.Join(ts.TempDir, ts.FixturesPath) + } else { + return filepath.Join(ts.SourceDir, ts.FixturesPath) + } } -func (ts *XTestSuites) Run(t *testing.T) { - fmt.Printf("create TMP dir: %s \n", ts.WorkDir) +func (ts *XTestSuites) Run(t *testing.T, options *atmos.Options) { + suitesOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) + if !*skipTmpDir { + fmt.Printf("create TMP dir: %s \n", ts.TempDir) - err := os.Mkdir(ts.WorkDir, 0777) - assert.NoError(t, err) - defer os.RemoveAll(ts.WorkDir) + err := os.Mkdir(ts.TempDir, 0777) + assert.NoError(t, err) + defer os.RemoveAll(ts.TempDir) - err = copyDirectoryRecursively(ts.SourceDir, ts.WorkDir) - assert.NoError(t, err) + err = copyDirectoryRecursively(ts.SourceDir, ts.TempDir) + assert.NoError(t, err) + } else { + fmt.Printf("Skip TMP dir: %t \n", *skipTmpDir) + } - atmos.VendorPull(t, ts.AtmosOptions) + if !*skipVendorDependencies { + atmos.VendorPull(t, suitesOptions) + } else { + fmt.Println("Skip Vendor Pull") + } - err = createStateDir(ts.WorkDir) + err := createStateDir(ts.TempDir) assert.NoError(t, err) // t.Parallel() for name, suite := range ts.suites { t.Run(name, func(t *testing.T) { - suite.Run(t) + suite.Run(t, suitesOptions) }) } } +func (ts *XTestSuites) getAtmosOptions(t *testing.T, options *atmos.Options, vars map[string]interface{}) *atmos.Options { + result := &atmos.Options{} + if options != nil { + result, _ = options.Clone() + } + + result.AtmosBasePath = ts.WorkDir() + result.NoColor = true + + envvars := map[string]string{ + "TEST_ACCOUNT_ID": ts.AwsAccountId, + "ATMOS_BASE_PATH": result.AtmosBasePath, + "ATMOS_CLI_CONFIG_PATH": result.AtmosBasePath, + } + + err := mergo.Merge(&result.EnvVars, envvars) + require.NoError(t, err) + + suiteVars := map[string]interface{}{ + "region": ts.AwsRegion, + } + + err = mergo.Merge(&result.Vars, suiteVars) + require.NoError(t, err) + + err = mergo.Merge(&result.Vars, vars) + require.NoError(t, err) + + return result +} + func (ts *XTestSuites) GetOrCreateSuite(name string) *XTestSuite { if _, ok := ts.suites[name]; !ok { - ts.suites[name] = NewXTestSuite(ts.AtmosOptions) + ts.suites[name] = NewXTestSuite() } return ts.suites[name] } - -func (ts *XTestSuites) SetSuite(name string, item *XTestSuite) { - ts.suites[name] = item -} diff --git a/pkg/atmos/aws-component-helper/x_test_suites_test.go b/pkg/atmos/aws-component-helper/x_test_suites_test.go index dd2df62..e37fe03 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites_test.go +++ b/pkg/atmos/aws-component-helper/x_test_suites_test.go @@ -40,10 +40,9 @@ func mockAtmos() { func TestComponentTestSuitesMinimum(t *testing.T) { componentTestSuites := &XTestSuites{ FixturesPath: "testdata/fixtures", - WorkDir: "testdata/tmp", + TempDir: "testdata/tmp", AwsAccountId: "123456789012", AwsRegion: "us-west-2", - AtmosOptions: &atmos.Options{}, suites: map[string]*XTestSuite{ "default": { tests: map[string]*ComponentTest{ @@ -58,7 +57,7 @@ func TestComponentTestSuitesMinimum(t *testing.T) { }, } assert.Equal(t, componentTestSuites.FixturesPath, "testdata/fixtures") - assert.Equal(t, componentTestSuites.WorkDir, "testdata/tmp") + assert.Equal(t, componentTestSuites.TempDir, "testdata/tmp") assert.Equal(t, componentTestSuites.AwsAccountId, "123456789012") assert.Equal(t, componentTestSuites.AwsRegion, "us-west-2") // assert.Equal(t, componentTestSuites.AtmosOptions, "us-west-2") @@ -77,9 +76,7 @@ func TestComponentTestSuitesCreate(t *testing.T) { fmt.Printf("running in %s\n", testFolder) - componentTestSuites, err := NewTestSuites(t, testFolder, "us-west-2", atmosExamplePath) - - assert.NoError(t, err) + componentTestSuites := NewTestSuites(t, testFolder, "us-west-2", atmosExamplePath) assert.Equal(t, componentTestSuites.SourceDir, testFolder) @@ -122,9 +119,7 @@ func TestComponentTestSuitesRun(t *testing.T) { fmt.Printf("running in %s\n", testFolder) - componentTestSuites, err := NewTestSuites(t, testFolder, "us-west-2", atmosExamplePath) - - assert.NoError(t, err) + componentTestSuites := NewTestSuites(t, testFolder, "us-west-2", atmosExamplePath) - componentTestSuites.Run(t) + componentTestSuites.Run(t, &atmos.Options{}) } From 2930f94f32b753c2800570fc0aab935b9245ff3e Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 23 Dec 2024 01:11:20 +0100 Subject: [PATCH 04/40] Added flags --- pkg/atmos/aws-component-helper/atmos.go | 6 +-- pkg/atmos/aws-component-helper/dependency.go | 23 +++++------ .../aws-component-helper/test_component.go | 39 +++++++++++++++---- .../aws-component-helper/x_test_suite.go | 14 ++++++- .../aws-component-helper/x_test_suites.go | 35 ++++++++--------- .../x_test_suites_test.go | 7 ++++ 6 files changed, 83 insertions(+), 41 deletions(-) diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index 3f45c3e..8ebc909 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -5,10 +5,10 @@ import ( ) var ( - atmosApply = atmos.Apply - atmosDestroy = atmos.Destroy - + atmosApply = atmos.Apply + atmosDestroy = atmos.Destroy atmosPlanExitCodeE = atmos.PlanExitCodeE + atmosVendorPull = atmos.VendorPull ) //func GetAtmosOptions(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) *atmos.Options { diff --git a/pkg/atmos/aws-component-helper/dependency.go b/pkg/atmos/aws-component-helper/dependency.go index 159a64b..5c272de 100644 --- a/pkg/atmos/aws-component-helper/dependency.go +++ b/pkg/atmos/aws-component-helper/dependency.go @@ -1,13 +1,14 @@ package aws_component_helper -type Dependency struct { - ComponentName string - StackName string -} - -func NewDependency(componentName string, stackName string) *Dependency { - return &Dependency{ - ComponentName: componentName, - StackName: stackName, - } -} +// +//type Dependency struct { +// ComponentName string +// StackName string +//} +// +//func NewDependency(componentName string, stackName string) *Dependency { +// return &Dependency{ +// ComponentName: componentName, +// StackName: stackName, +// } +//} diff --git a/pkg/atmos/aws-component-helper/test_component.go b/pkg/atmos/aws-component-helper/test_component.go index 726d85f..4b2f647 100644 --- a/pkg/atmos/aws-component-helper/test_component.go +++ b/pkg/atmos/aws-component-helper/test_component.go @@ -2,6 +2,7 @@ package aws_component_helper import ( "dario.cat/mergo" + "flag" "fmt" "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" @@ -10,6 +11,19 @@ import ( "testing" ) +var ( + skipVerifyEnabledFlag = flag.Bool("cth.skip-verify-enabled-flag", true, "skip verify enabled flag") + + skipDeployTestDependencies = flag.Bool("cth.skip-deploy-test-deps", false, "skip deploy test deps") + skipDestroyTestDependencies = flag.Bool("cth.skip-destroy-test-deps-teardown", false, "skip destroy test deps") + + skipDeployComponentUnderTest = flag.Bool("cth.skip-deploy-cut", false, "skip deploy component under test") + skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") + + skipDeployAsserts = flag.Bool("cth.skip-deploy-asserts", false, "skip deploy component under test") + skipDestroyAsserts = flag.Bool("cth.skip-destroy-asserts", false, "skip destroy component under test") +) + type ComponentTest struct { RandomIdentifier string setup []*AtmosComponent @@ -32,9 +46,12 @@ func (ct *ComponentTest) Run(t *testing.T, options *atmos.Options) { testOptions := ct.getAtmosOptions(t, options, map[string]interface{}{}) for _, component := range ct.setup { componentOptions := component.getAtmosOptions(t, testOptions, map[string]interface{}{}) - - atmosApply(t, componentOptions) - defer atmosDestroy(t, componentOptions) + if !*skipDeployTestDependencies { + atmosApply(t, componentOptions) + } + if !*skipDeployTestDependencies && !*skipDestroyTestDependencies { + defer atmosDestroy(t, componentOptions) + } } if !*skipVerifyEnabledFlag { @@ -45,14 +62,22 @@ func (ct *ComponentTest) Run(t *testing.T, options *atmos.Options) { } subjectOptions := ct.Subject.getAtmosOptions(t, testOptions, map[string]interface{}{}) - atmosApply(t, subjectOptions) - defer atmosDestroy(t, subjectOptions) + if !*skipDeployComponentUnderTest { + atmosApply(t, subjectOptions) + } + if !*skipDeployComponentUnderTest && !*skipDestroyComponentUnderTest { + defer atmosDestroy(t, subjectOptions) + } for _, component := range ct.assert { componentOptions := component.getAtmosOptions(t, testOptions, map[string]interface{}{}) - atmosApply(t, componentOptions) - defer atmosDestroy(t, componentOptions) + if !*skipDeployAsserts { + atmosApply(t, componentOptions) + } + if !*skipDeployAsserts && !*skipDestroyAsserts { + defer atmosDestroy(t, componentOptions) + } } } diff --git a/pkg/atmos/aws-component-helper/x_test_suite.go b/pkg/atmos/aws-component-helper/x_test_suite.go index 0239cc7..3fa3ad5 100644 --- a/pkg/atmos/aws-component-helper/x_test_suite.go +++ b/pkg/atmos/aws-component-helper/x_test_suite.go @@ -2,6 +2,7 @@ package aws_component_helper import ( "dario.cat/mergo" + "flag" "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" "github.com/stretchr/testify/require" @@ -9,6 +10,11 @@ import ( "testing" ) +var ( + skipDeploySuiteDependencies = flag.Bool("cth.skip-suite-deps", false, "skip deploy suite deps") + skipDestroySuiteDependencies = flag.Bool("cth.skip-suite-deps-teardown", false, "skip destroy suite deps") +) + type XTestSuite struct { RandomIdentifier string setup []*AtmosComponent @@ -68,8 +74,12 @@ func (ts *XTestSuite) Run(t *testing.T, options *atmos.Options) { suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) for _, component := range ts.setup { componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) - atmosApply(t, componentOptions) - defer atmosDestroy(t, componentOptions) + if !*skipDeploySuiteDependencies { + atmosApply(t, componentOptions) + } + if !*skipDeploySuiteDependencies && !*skipDestroySuiteDependencies { + defer atmosDestroy(t, componentOptions) + } } //t.Parallel() diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index 86174e3..700d672 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -19,20 +19,16 @@ var ( ) var ( - skipTmpDir = flag.Bool("cth.skip-tmp-dir", false, "Run in the current directory") - skipVendorDependencies = flag.Bool("cth.skip-vendor", false, "skip vendor dependencies") - forceNewSuite = flag.Bool("cth.force-new-suite", false, "force new suite") - suiteIndex = flag.Int("cth.suite-index", -1, "suite index") - skipAwsNuke = flag.Bool("cth.skip-aws-nuke", false, "skip aws nuke") - skipDeployDependencies = flag.Bool("cth.skip-deploy-deps", false, "skip deploy dependencies") - skipDestroyDependencies = flag.Bool("cth.skip-destroy-deps", false, "skip destroy dependencies") - skipSetupComponentUnderTest = flag.Bool("cth.skip-setup-cut", false, "skip setup component under test") - skipDeployComponentUnderTest = flag.Bool("cth.skip-deploy-cut", false, "skip deploy component under test") - skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") - skipTeardownTestSuite = flag.Bool("cth.skip-teardown", false, "skip test suite teardown") - - skipVerifyEnabledFlag = flag.Bool("cth.skip-verify-enabled-flag", true, "skip verify enabled flag") - skipTests = flag.Bool("cth.skip-tests", false, "skip tests") + skipTmpDir = flag.Bool("cth.skip-tmp-dir", false, "Run in the current directory") + skipVendorDependencies = flag.Bool("cth.skip-vendor", false, "skip vendor dependencies") + forceNewSuite = flag.Bool("cth.force-new-suite", false, "force new suite") + suiteIndex = flag.Int("cth.suite-index", -1, "suite index") + skipAwsNuke = flag.Bool("cth.skip-aws-nuke", false, "skip aws nuke") + skipDeployDependencies = flag.Bool("cth.skip-deploy-deps", false, "skip deploy dependencies") + skipDestroyDependencies = flag.Bool("cth.skip-destroy-deps", false, "skip destroy dependencies") + skipTeardownTestSuite = flag.Bool("cth.skip-teardown", false, "skip test suite teardown") + + skipTests = flag.Bool("cth.skip-tests", false, "skip tests") ) type XTestSuites struct { @@ -52,9 +48,11 @@ func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, fixturesDir randID := random.UniqueId() randomId := strings.ToLower(randID) tmpdir := filepath.Join(os.TempDir(), "test-suites-"+randomId) + realSourcePath, err := filepath.Abs(sourceDir) + require.NoError(t, err) suites := &XTestSuites{ RandomIdentifier: randomId, - SourceDir: sourceDir, + SourceDir: realSourcePath, TempDir: tmpdir, FixturesPath: fixturesDir, AwsAccountId: awsAccountId, @@ -65,6 +63,7 @@ func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, fixturesDir describeStacksOptions := suites.getAtmosOptions(t, &atmos.Options{}, map[string]interface{}{}) describeStacksOptions.AtmosBasePath = filepath.Join(suites.SourceDir, suites.FixturesPath) describeStacksOptions.EnvVars["ATMOS_BASE_PATH"] = describeStacksOptions.AtmosBasePath + describeStacksOptions.EnvVars["ATMOS_CLI_CONFIG_PATH"] = describeStacksOptions.AtmosBasePath describeStacksConfigs, err := atmos.DescribeStacksE(t, describeStacksOptions) require.NoError(t, err) @@ -117,7 +116,7 @@ func (ts *XTestSuites) WorkDir() string { func (ts *XTestSuites) Run(t *testing.T, options *atmos.Options) { suitesOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) if !*skipTmpDir { - fmt.Printf("create TMP dir: %s \n", ts.TempDir) + fmt.Printf("Create TMP dir: %s \n", ts.TempDir) err := os.Mkdir(ts.TempDir, 0777) assert.NoError(t, err) @@ -126,11 +125,11 @@ func (ts *XTestSuites) Run(t *testing.T, options *atmos.Options) { err = copyDirectoryRecursively(ts.SourceDir, ts.TempDir) assert.NoError(t, err) } else { - fmt.Printf("Skip TMP dir: %t \n", *skipTmpDir) + fmt.Printf("Use source dir: %s \n", ts.SourceDir) } if !*skipVendorDependencies { - atmos.VendorPull(t, suitesOptions) + atmosVendorPull(t, suitesOptions) } else { fmt.Println("Skip Vendor Pull") } diff --git a/pkg/atmos/aws-component-helper/x_test_suites_test.go b/pkg/atmos/aws-component-helper/x_test_suites_test.go index e37fe03..9a6444c 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites_test.go +++ b/pkg/atmos/aws-component-helper/x_test_suites_test.go @@ -35,6 +35,13 @@ func mockAtmos() { fmt.Println(description) return 0, nil } + + atmosVendorPull = func(t tt.TestingT, options *atmos.Options) string { + options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "vendor", "pull")...) + description := fmt.Sprintf("%s %v", options.AtmosBinary, args) + fmt.Println(description) + return "" + } } func TestComponentTestSuitesMinimum(t *testing.T) { From b9dd0b113c9c7fcd6512383388ca1e4858da58e3 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 23 Dec 2024 13:21:42 +0100 Subject: [PATCH 05/40] Support parrallel mode --- pkg/atmos/aws-component-helper/x_test_suite.go | 10 +++++++--- pkg/atmos/aws-component-helper/x_test_suites.go | 6 +++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pkg/atmos/aws-component-helper/x_test_suite.go b/pkg/atmos/aws-component-helper/x_test_suite.go index 3fa3ad5..4b3e5d5 100644 --- a/pkg/atmos/aws-component-helper/x_test_suite.go +++ b/pkg/atmos/aws-component-helper/x_test_suite.go @@ -3,6 +3,7 @@ package aws_component_helper import ( "dario.cat/mergo" "flag" + "fmt" "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" "github.com/stretchr/testify/require" @@ -11,8 +12,8 @@ import ( ) var ( - skipDeploySuiteDependencies = flag.Bool("cth.skip-suite-deps", false, "skip deploy suite deps") - skipDestroySuiteDependencies = flag.Bool("cth.skip-suite-deps-teardown", false, "skip destroy suite deps") + skipDeploySuiteDependencies = flag.Bool("cth.skip-deploy-suite-deps", false, "skip deploy suite deps") + skipDestroySuiteDependencies = flag.Bool("cth.skip-destroy-suite-deps", false, "skip destroy suite deps") ) type XTestSuite struct { @@ -82,7 +83,10 @@ func (ts *XTestSuite) Run(t *testing.T, options *atmos.Options) { } } - //t.Parallel() + if *runParallel { + fmt.Println("Run tests in parallel mode") + t.Parallel() + } for name, item := range ts.tests { t.Run(name, func(t *testing.T) { item.Run(t, suiteOptions) diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index 700d672..e01731a 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -21,6 +21,7 @@ var ( var ( skipTmpDir = flag.Bool("cth.skip-tmp-dir", false, "Run in the current directory") skipVendorDependencies = flag.Bool("cth.skip-vendor", false, "skip vendor dependencies") + runParallel = flag.Bool("cth.parallel", false, "Run parallel") forceNewSuite = flag.Bool("cth.force-new-suite", false, "force new suite") suiteIndex = flag.Int("cth.suite-index", -1, "suite index") skipAwsNuke = flag.Bool("cth.skip-aws-nuke", false, "skip aws nuke") @@ -137,7 +138,10 @@ func (ts *XTestSuites) Run(t *testing.T, options *atmos.Options) { err := createStateDir(ts.TempDir) assert.NoError(t, err) - // t.Parallel() + if *runParallel { + fmt.Println("Run suites in parallel mode") + t.Parallel() + } for name, suite := range ts.suites { t.Run(name, func(t *testing.T) { suite.Run(t, suitesOptions) From 88e2b782a08b422470910b42f40eca7603434a36 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 23 Dec 2024 14:58:28 +0100 Subject: [PATCH 06/40] Added data dir for concurrent calls --- pkg/atmos/aws-component-helper/test_component.go | 16 +++++++++++++++- pkg/atmos/aws-component-helper/x_test_suite.go | 16 +++++++++++++++- pkg/atmos/aws-component-helper/x_test_suites.go | 2 ++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/pkg/atmos/aws-component-helper/test_component.go b/pkg/atmos/aws-component-helper/test_component.go index 4b2f647..df481b7 100644 --- a/pkg/atmos/aws-component-helper/test_component.go +++ b/pkg/atmos/aws-component-helper/test_component.go @@ -7,6 +7,7 @@ import ( "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" "github.com/stretchr/testify/require" + "path/filepath" "strings" "testing" ) @@ -105,6 +106,19 @@ func (ct *ComponentTest) getAtmosOptions(t *testing.T, options *atmos.Options, v result, _ = options.Clone() } + currentTFDataDir := ".terraform" + if value, ok := options.EnvVars["TF_DATA_DIR"]; ok { + currentTFDataDir = value + } + + envvars := map[string]string{ + // We need to split the TF_DATA_DIR for parallel suites mode + "TF_DATA_DIR": filepath.Join(currentTFDataDir, fmt.Sprintf("test-%s", ct.RandomIdentifier)), + } + + err := mergo.Merge(&result.EnvVars, envvars) + require.NoError(t, err) + mergedVars := map[string]interface{}{ "default_tags": map[string]string{ "CreatedByAtmosTestSuiteTest": ct.RandomIdentifier, @@ -112,7 +126,7 @@ func (ct *ComponentTest) getAtmosOptions(t *testing.T, options *atmos.Options, v } // Merge in any additional vars passed in - err := mergo.Merge(&result.Vars, mergedVars) + err = mergo.Merge(&result.Vars, mergedVars) require.NoError(t, err) err = mergo.Merge(&result.Vars, vars) diff --git a/pkg/atmos/aws-component-helper/x_test_suite.go b/pkg/atmos/aws-component-helper/x_test_suite.go index 4b3e5d5..7aa3816 100644 --- a/pkg/atmos/aws-component-helper/x_test_suite.go +++ b/pkg/atmos/aws-component-helper/x_test_suite.go @@ -7,6 +7,7 @@ import ( "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" "github.com/stretchr/testify/require" + "path/filepath" "strings" "testing" ) @@ -40,7 +41,20 @@ func (ts *XTestSuite) getAtmosOptions(t *testing.T, options *atmos.Options, vars result, _ = options.Clone() } - err := mergo.Merge(&result.Vars, vars) + currentTFDataDir := ".terraform" + if value, ok := options.EnvVars["TF_DATA_DIR"]; ok { + currentTFDataDir = value + } + + envvars := map[string]string{ + // We need to split the TF_DATA_DIR for parallel suites mode + "TF_DATA_DIR": filepath.Join(currentTFDataDir, fmt.Sprintf("suite-%s", ts.RandomIdentifier)), + } + + err := mergo.Merge(&result.EnvVars, envvars) + require.NoError(t, err) + + err = mergo.Merge(&result.Vars, vars) require.NoError(t, err) suiteVars := map[string]interface{}{ diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index e01731a..20373f1 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -157,6 +157,8 @@ func (ts *XTestSuites) getAtmosOptions(t *testing.T, options *atmos.Options, var result.AtmosBasePath = ts.WorkDir() result.NoColor = true + result.Lock = false + result.Upgrade = true envvars := map[string]string{ "TEST_ACCOUNT_ID": ts.AwsAccountId, From 7d2d3d97be2b877140974d213524401b86e93546 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 23 Dec 2024 21:24:52 +0100 Subject: [PATCH 07/40] Added flags to skip tests --- pkg/atmos/aws-component-helper/test_component.go | 14 +++++++------- pkg/atmos/aws-component-helper/x_test_suite.go | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/atmos/aws-component-helper/test_component.go b/pkg/atmos/aws-component-helper/test_component.go index df481b7..fcba3c3 100644 --- a/pkg/atmos/aws-component-helper/test_component.go +++ b/pkg/atmos/aws-component-helper/test_component.go @@ -47,15 +47,15 @@ func (ct *ComponentTest) Run(t *testing.T, options *atmos.Options) { testOptions := ct.getAtmosOptions(t, options, map[string]interface{}{}) for _, component := range ct.setup { componentOptions := component.getAtmosOptions(t, testOptions, map[string]interface{}{}) - if !*skipDeployTestDependencies { + if !*skipDeployTestDependencies && !*skipDeployDependencies { atmosApply(t, componentOptions) } - if !*skipDeployTestDependencies && !*skipDestroyTestDependencies { + if !*skipDeployTestDependencies && !*skipDestroyTestDependencies && !*skipDeployDependencies && !*skipDestroyDependencies { defer atmosDestroy(t, componentOptions) } } - if !*skipVerifyEnabledFlag { + if !*skipVerifyEnabledFlag && !*skipTests { fmt.Println("VerifyEnabledFlag") ct.verifyEnabledFlag(t, ct.Subject, options) } else { @@ -63,20 +63,20 @@ func (ct *ComponentTest) Run(t *testing.T, options *atmos.Options) { } subjectOptions := ct.Subject.getAtmosOptions(t, testOptions, map[string]interface{}{}) - if !*skipDeployComponentUnderTest { + if !*skipDeployComponentUnderTest && !*skipTests { atmosApply(t, subjectOptions) } - if !*skipDeployComponentUnderTest && !*skipDestroyComponentUnderTest { + if !*skipDeployComponentUnderTest && !*skipDestroyComponentUnderTest && !*skipTests { defer atmosDestroy(t, subjectOptions) } for _, component := range ct.assert { componentOptions := component.getAtmosOptions(t, testOptions, map[string]interface{}{}) - if !*skipDeployAsserts { + if !*skipDeployAsserts && !*skipTests { atmosApply(t, componentOptions) } - if !*skipDeployAsserts && !*skipDestroyAsserts { + if !*skipDeployAsserts && !*skipDestroyAsserts && !*skipTests { defer atmosDestroy(t, componentOptions) } } diff --git a/pkg/atmos/aws-component-helper/x_test_suite.go b/pkg/atmos/aws-component-helper/x_test_suite.go index 7aa3816..de98647 100644 --- a/pkg/atmos/aws-component-helper/x_test_suite.go +++ b/pkg/atmos/aws-component-helper/x_test_suite.go @@ -89,10 +89,10 @@ func (ts *XTestSuite) Run(t *testing.T, options *atmos.Options) { suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) for _, component := range ts.setup { componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) - if !*skipDeploySuiteDependencies { + if !*skipDeploySuiteDependencies && !*skipDeployDependencies { atmosApply(t, componentOptions) } - if !*skipDeploySuiteDependencies && !*skipDestroySuiteDependencies { + if !*skipDeploySuiteDependencies && !*skipDestroySuiteDependencies && !*skipDeployDependencies && !*skipDestroyDependencies { defer atmosDestroy(t, componentOptions) } } From c124a53aa1f309d413015122e09be21e0b29546a Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Tue, 24 Dec 2024 00:34:44 +0100 Subject: [PATCH 08/40] Always create state dir --- pkg/atmos/aws-component-helper/x_test_suites.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index 20373f1..02ce4e1 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -135,8 +135,13 @@ func (ts *XTestSuites) Run(t *testing.T, options *atmos.Options) { fmt.Println("Skip Vendor Pull") } - err := createStateDir(ts.TempDir) - assert.NoError(t, err) + if !*skipTmpDir { + err := createStateDir(ts.TempDir) + assert.NoError(t, err) + } else { + err := createStateDir(ts.SourceDir) + assert.NoError(t, err) + } if *runParallel { fmt.Println("Run suites in parallel mode") From 0392b9f5b235d541191f787439d8badacf894d53 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Thu, 26 Dec 2024 17:28:05 +0100 Subject: [PATCH 09/40] Get rid of asserts --- pkg/atmos/aws-component-helper/atmos.go | 12 +- .../aws-component-helper/atmos_component.go | 37 ++- .../atmos_component_test.go | 4 +- pkg/atmos/aws-component-helper/dependency.go | 14 - .../aws-component-helper/test_component.go | 57 +--- .../test_component_test.go | 4 +- pkg/atmos/aws-component-helper/test_suite.go | 244 +++++++++--------- .../aws-component-helper/x_test_suite.go | 39 --- .../aws-component-helper/x_test_suite_test.go | 6 +- .../aws-component-helper/x_test_suites.go | 118 ++++----- .../x_test_suites_test.go | 56 ++-- pkg/atmos/terraform_plan.go | 4 +- .../stacks/orgs/default/test/_defaults.yaml | 2 - 13 files changed, 240 insertions(+), 357 deletions(-) delete mode 100644 pkg/atmos/aws-component-helper/dependency.go diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index 8ebc909..cf5e9d3 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -35,8 +35,8 @@ var ( // // atmosOptions := atmos.WithDefaultRetryableErrors(t, &atmos.Options{ // AtmosBasePath: suite.TempDir, -// Component: componentName, -// Stack: stackName, +// ComponentName: componentName, +// StackName: stackName, // NoColor: true, // BackendConfig: map[string]interface{}{ // "workspace_key_prefix": strings.Join([]string{suite.RandomIdentifier, stackName}, "-"), @@ -48,7 +48,7 @@ var ( // //func deployDependencies(t *testing.T, suite *TestSuite) error { // for _, dependency := range suite.Dependencies { -// _, _, err := deployComponent(t, suite, dependency.ComponentName, dependency.StackName, map[string]interface{}{}) +// _, _, err := DeployComponent(t, suite, dependency.ComponentName, dependency.StackName, map[string]interface{}{}) // if err != nil { // return err // } @@ -60,7 +60,7 @@ var ( //func destroyDependencies(t *testing.T, suite *TestSuite) error { // // iterate over dependencies in reverse order and destroy them // for i := len(suite.Dependencies) - 1; i >= 0; i-- { -// _, _, err := destroyComponent(t, suite, suite.Dependencies[i].ComponentName, suite.Dependencies[i].StackName, map[string]interface{}{}) +// _, _, err := DestroyComponent(t, suite, suite.Dependencies[i].ComponentName, suite.Dependencies[i].StackName, map[string]interface{}{}) // if err != nil { // return err // } @@ -68,7 +68,7 @@ var ( // return nil //} // -//func deployComponent(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) (*atmos.Options, string, error) { +//func DeployComponent(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) (*atmos.Options, string, error) { // options := GetAtmosOptions(t, suite, componentName, stackName, vars) // out, err := atmos.ApplyE(t, options) // @@ -94,7 +94,7 @@ var ( // return options, nil //} -//func destroyComponent(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) (*atmos.Options, string, error) { +//func DestroyComponent(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) (*atmos.Options, string, error) { // options := GetAtmosOptions(t, suite, componentName, stackName, vars) // out, err := atmos.DestroyE(t, options) // diff --git a/pkg/atmos/aws-component-helper/atmos_component.go b/pkg/atmos/aws-component-helper/atmos_component.go index 9b03f6b..3badf13 100644 --- a/pkg/atmos/aws-component-helper/atmos_component.go +++ b/pkg/atmos/aws-component-helper/atmos_component.go @@ -2,20 +2,28 @@ package aws_component_helper import ( "dario.cat/mergo" + "fmt" "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/gruntwork-io/terratest/modules/random" "github.com/stretchr/testify/require" + "path/filepath" + "strings" "testing" ) type AtmosComponent struct { - Component string - Stack string + RandomIdentifier string + ComponentName string + StackName string } func NewAtmosComponent(component string, stack string) *AtmosComponent { + randID := random.UniqueId() + randomId := strings.ToLower(randID) return &AtmosComponent{ - Component: component, - Stack: stack, + RandomIdentifier: randomId, + ComponentName: component, + StackName: stack, } } @@ -25,12 +33,27 @@ func (ac *AtmosComponent) getAtmosOptions(t *testing.T, options *atmos.Options, result, _ = options.Clone() } + currentTFDataDir := ".terraform" + if value, ok := options.EnvVars["TF_DATA_DIR"]; ok { + currentTFDataDir = value + } + stack := strings.Replace(ac.StackName, "/", "-", -1) + name := strings.Replace(ac.ComponentName, "/", "-", -1) + envvars := map[string]string{ + // We need to split the TF_DATA_DIR for parallel suites mode + "TF_DATA_DIR": filepath.Join(currentTFDataDir, fmt.Sprintf("component-%s", ac.RandomIdentifier)), + "TEST_WORKSPACE_TEMPLATE": fmt.Sprintf("%s-%s-%s", stack, name, ac.RandomIdentifier), + } + + err := mergo.Merge(&result.EnvVars, envvars) + require.NoError(t, err) + // Merge in any additional vars passed in - err := mergo.Merge(&result.Vars, vars) + err = mergo.Merge(&result.Vars, vars) require.NoError(t, err) - result.Component = ac.Component - result.Stack = ac.Stack + result.Component = ac.ComponentName + result.Stack = ac.StackName atmosOptions := atmos.WithDefaultRetryableErrors(t, result) return atmosOptions diff --git a/pkg/atmos/aws-component-helper/atmos_component_test.go b/pkg/atmos/aws-component-helper/atmos_component_test.go index 0405019..884b5d3 100644 --- a/pkg/atmos/aws-component-helper/atmos_component_test.go +++ b/pkg/atmos/aws-component-helper/atmos_component_test.go @@ -10,6 +10,6 @@ func TestAtmosComponent(t *testing.T) { // Create a temporary atmos component component := NewAtmosComponent("vpc", "default-test") - assert.Equal(t, component.Component, "vpc") - assert.Equal(t, component.Stack, "default-test") + assert.Equal(t, component.ComponentName, "vpc") + assert.Equal(t, component.StackName, "default-test") } diff --git a/pkg/atmos/aws-component-helper/dependency.go b/pkg/atmos/aws-component-helper/dependency.go deleted file mode 100644 index 5c272de..0000000 --- a/pkg/atmos/aws-component-helper/dependency.go +++ /dev/null @@ -1,14 +0,0 @@ -package aws_component_helper - -// -//type Dependency struct { -// ComponentName string -// StackName string -//} -// -//func NewDependency(componentName string, stackName string) *Dependency { -// return &Dependency{ -// ComponentName: componentName, -// StackName: stackName, -// } -//} diff --git a/pkg/atmos/aws-component-helper/test_component.go b/pkg/atmos/aws-component-helper/test_component.go index fcba3c3..4548277 100644 --- a/pkg/atmos/aws-component-helper/test_component.go +++ b/pkg/atmos/aws-component-helper/test_component.go @@ -14,22 +14,13 @@ import ( var ( skipVerifyEnabledFlag = flag.Bool("cth.skip-verify-enabled-flag", true, "skip verify enabled flag") - - skipDeployTestDependencies = flag.Bool("cth.skip-deploy-test-deps", false, "skip deploy test deps") - skipDestroyTestDependencies = flag.Bool("cth.skip-destroy-test-deps-teardown", false, "skip destroy test deps") - - skipDeployComponentUnderTest = flag.Bool("cth.skip-deploy-cut", false, "skip deploy component under test") - skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") - - skipDeployAsserts = flag.Bool("cth.skip-deploy-asserts", false, "skip deploy component under test") - skipDestroyAsserts = flag.Bool("cth.skip-destroy-asserts", false, "skip destroy component under test") ) type ComponentTest struct { RandomIdentifier string setup []*AtmosComponent Subject *AtmosComponent - assert []*AtmosComponent + assert map[string]func(t *testing.T, ct *ComponentTest) } func NewComponentTest() *ComponentTest { @@ -39,46 +30,7 @@ func NewComponentTest() *ComponentTest { RandomIdentifier: randomId, setup: make([]*AtmosComponent, 0), Subject: nil, - assert: make([]*AtmosComponent, 0), - } -} - -func (ct *ComponentTest) Run(t *testing.T, options *atmos.Options) { - testOptions := ct.getAtmosOptions(t, options, map[string]interface{}{}) - for _, component := range ct.setup { - componentOptions := component.getAtmosOptions(t, testOptions, map[string]interface{}{}) - if !*skipDeployTestDependencies && !*skipDeployDependencies { - atmosApply(t, componentOptions) - } - if !*skipDeployTestDependencies && !*skipDestroyTestDependencies && !*skipDeployDependencies && !*skipDestroyDependencies { - defer atmosDestroy(t, componentOptions) - } - } - - if !*skipVerifyEnabledFlag && !*skipTests { - fmt.Println("VerifyEnabledFlag") - ct.verifyEnabledFlag(t, ct.Subject, options) - } else { - fmt.Println("Skipping VerifyEnabledFlag") - } - - subjectOptions := ct.Subject.getAtmosOptions(t, testOptions, map[string]interface{}{}) - if !*skipDeployComponentUnderTest && !*skipTests { - atmosApply(t, subjectOptions) - } - if !*skipDeployComponentUnderTest && !*skipDestroyComponentUnderTest && !*skipTests { - defer atmosDestroy(t, subjectOptions) - } - - for _, component := range ct.assert { - componentOptions := component.getAtmosOptions(t, testOptions, map[string]interface{}{}) - - if !*skipDeployAsserts && !*skipTests { - atmosApply(t, componentOptions) - } - if !*skipDeployAsserts && !*skipDestroyAsserts && !*skipTests { - defer atmosDestroy(t, componentOptions) - } + assert: map[string]func(t *testing.T, ct *ComponentTest){}, } } @@ -144,7 +96,6 @@ func (ct *ComponentTest) SetSubject(component string, stack string) { ct.Subject = NewAtmosComponent(component, stack) } -func (ct *ComponentTest) AddSAssert(component string, stack string) { - item := NewAtmosComponent(component, stack) - ct.assert = append(ct.assert, item) +func (ct *ComponentTest) AddSAssert(name string, callback func(t *testing.T, ct *ComponentTest)) { + ct.assert[name] = callback } diff --git a/pkg/atmos/aws-component-helper/test_component_test.go b/pkg/atmos/aws-component-helper/test_component_test.go index 58b9b03..842140b 100644 --- a/pkg/atmos/aws-component-helper/test_component_test.go +++ b/pkg/atmos/aws-component-helper/test_component_test.go @@ -10,6 +10,6 @@ func TestComponentTestMinimum(t *testing.T) { componentTest := NewComponentTest() componentTest.SetSubject("vpc", "default-test") - assert.Equal(t, componentTest.Subject.Component, "vpc") - assert.Equal(t, componentTest.Subject.Stack, "default-test") + assert.Equal(t, componentTest.Subject.ComponentName, "vpc") + assert.Equal(t, componentTest.Subject.StackName, "default-test") } diff --git a/pkg/atmos/aws-component-helper/test_suite.go b/pkg/atmos/aws-component-helper/test_suite.go index 1845cbc..590c599 100644 --- a/pkg/atmos/aws-component-helper/test_suite.go +++ b/pkg/atmos/aws-component-helper/test_suite.go @@ -14,7 +14,7 @@ package aws_component_helper // AwsRegion string // ComponentName string // ComponentSrcPath string -// Dependencies []*Dependency +// Dependencies []*AtmosComponent // FixturesPath string // ForceNewSuite bool // Index int @@ -40,101 +40,101 @@ package aws_component_helper //// Option type represents a configuration option //type TestSuiteOption func(*TestSuite) // -////func (ts *TestSuite) AddDependencies(dependencies []string) { -//// for _, dependency := range dependencies { -//// ts.AddDependency(dependency) -//// } -////} -// -////func (ts *TestSuite) AddCrossStackDependencies(dependencies []Dependency) { -//// for _, dependency := range dependencies { -//// ts.AddCrossStackDependency(dependency.ComponentName, dependency.StackName) -//// } -////} -// -////func (ts *TestSuite) AddDependency(componentName string) { -//// ts.Dependencies = append(ts.Dependencies, NewDependency(componentName, ts.StackName)) -////} -// -////func (ts *TestSuite) AddCrossStackDependency(componentName string, stackName string) { -//// ts.Dependencies = append(ts.Dependencies, NewDependency(componentName, stackName)) -////} -// -////func (ts *TestSuite) SetupTestSuite(t *testing.T) error { -//// fmt.Println("SetupTestSuite") -//// err := setupTestSuite(ts) -//// return err -////} -// -////func (ts *TestSuite) SetupComponentUnderTest(t *testing.T) error { -//// if !ts.SkipSetupComponentUnderTest { -//// fmt.Println("SetupComponentUnderTest") -//// err := setupComponentUnderTest(ts) -//// return err -//// } else { -//// fmt.Println("Skipping SetupComponentUnderTest") -//// } -//// return nil -////} -// -////func (ts *TestSuite) VendorDependencies(t *testing.T) error { -//// if !ts.SkipVendorDependencies { -//// fmt.Println("VendorDependencies") -//// err := vendorDependencies(t, ts) -//// return err -//// } else { -//// fmt.Println("Skipping VendorDependencies") -//// } -//// return nil -////} -// -////func (ts *TestSuite) DeployDependencies(t *testing.T) error { -//// if !ts.SkipDeployDependencies { -//// fmt.Println("DeployDependencies") -//// err := deployDependencies(t, ts) -//// return err -//// } else { -//// fmt.Println("Skipping DeployDependencies") -//// } -//// return nil -////} -// -////func (ts *TestSuite) VerifyEnabledFlag(t *testing.T) error { -//// if !ts.SkipVerifyEnabledFlag { -//// fmt.Println("VerifyEnabledFlag") -//// _, err := verifyEnabledFlag(t, ts, ts.ComponentName, ts.StackName) -//// return err -//// } else { -//// fmt.Println("Skipping VerifyEnabledFlag") -//// } -//// return nil -////} -// -////func (ts *TestSuite) DeployComponentUnderTest(t *testing.T, vars map[string]interface{}) (string, error) { -//// if !ts.SkipDeployComponentUnderTest { -//// fmt.Println("DeployComponentUnderTest") -//// options, out, err := deployComponent(t, ts, ts.ComponentName, ts.StackName, vars) -//// ts.AtmosOptions = options -//// -//// return out, err -//// } else { -//// fmt.Println("Skipping DeployComponentUnderTest") -//// return "", nil -//// } -////} -// -////func (ts *TestSuite) DestroyComponentUnderTest(t *testing.T, vars map[string]interface{}) (string, error) { -//// if !ts.SkipDestroyComponentUnderTest { -//// fmt.Println("DestroyComponentUnderTest") -//// options, out, err := destroyComponent(t, ts, ts.ComponentName, ts.StackName, vars) -//// ts.AtmosOptions = options -//// -//// return out, err -//// } else { -//// fmt.Println("Skipping DestroyComponentUnderTest") -//// return "", nil -//// } -////} +//func (ts *TestSuite) AddDependencies(dependencies []string) { +// for _, dependency := range dependencies { +// ts.AddDependency(dependency) +// } +//} +// +//func (ts *TestSuite) AddCrossStackDependencies(dependencies []AtmosComponent) { +// for _, dependency := range dependencies { +// ts.AddCrossStackDependency(dependency.ComponentName, dependency.StackName) +// } +//} +// +//func (ts *TestSuite) AddDependency(componentName string) { +// ts.Dependencies = append(ts.Dependencies, NewAtmosComponent(componentName, ts.StackName)) +//} +// +//func (ts *TestSuite) AddCrossStackDependency(componentName string, stackName string) { +// ts.Dependencies = append(ts.Dependencies, NewAtmosComponent(componentName, stackName)) +//} +// +//func (ts *TestSuite) SetupTestSuite(t *testing.T) error { +// fmt.Println("SetupTestSuite") +// err := setupTestSuite(ts) +// return err +//} +// +//func (ts *TestSuite) SetupComponentUnderTest(t *testing.T) error { +// if !ts.SkipSetupComponentUnderTest { +// fmt.Println("SetupComponentUnderTest") +// err := setupComponentUnderTest(ts) +// return err +// } else { +// fmt.Println("Skipping SetupComponentUnderTest") +// } +// return nil +//} +// +//func (ts *TestSuite) VendorDependencies(t *testing.T) error { +// if !ts.SkipVendorDependencies { +// fmt.Println("VendorDependencies") +// err := vendorDependencies(t, ts) +// return err +// } else { +// fmt.Println("Skipping VendorDependencies") +// } +// return nil +//} +// +//func (ts *TestSuite) DeployDependencies(t *testing.T) error { +// if !ts.SkipDeployDependencies { +// fmt.Println("DeployDependencies") +// err := deployDependencies(t, ts) +// return err +// } else { +// fmt.Println("Skipping DeployDependencies") +// } +// return nil +//} +// +//func (ts *TestSuite) VerifyEnabledFlag(t *testing.T) error { +// if !ts.SkipVerifyEnabledFlag { +// fmt.Println("VerifyEnabledFlag") +// _, err := verifyEnabledFlag(t, ts, ts.ComponentName, ts.StackName) +// return err +// } else { +// fmt.Println("Skipping VerifyEnabledFlag") +// } +// return nil +//} +// +//func (ts *TestSuite) DeployComponentUnderTest(t *testing.T, vars map[string]interface{}) (string, error) { +// if !ts.SkipDeployComponentUnderTest { +// fmt.Println("DeployComponentUnderTest") +// options, out, err := DeployComponent(t, ts, ts.ComponentName, ts.StackName, vars) +// ts.AtmosOptions = options +// +// return out, err +// } else { +// fmt.Println("Skipping DeployComponentUnderTest") +// return "", nil +// } +//} +// +//func (ts *TestSuite) DestroyComponentUnderTest(t *testing.T, vars map[string]interface{}) (string, error) { +// if !ts.SkipDestroyComponentUnderTest { +// fmt.Println("DestroyComponentUnderTest") +// options, out, err := DestroyComponent(t, ts, ts.ComponentName, ts.StackName, vars) +// ts.AtmosOptions = options +// +// return out, err +// } else { +// fmt.Println("Skipping DestroyComponentUnderTest") +// return "", nil +// } +//} // //func (ts *TestSuite) DestroyDependencies(t *testing.T) error { // if !skipDestroyDependencies(ts) { @@ -169,30 +169,30 @@ package aws_component_helper // return nil //} // -////func (ts *TestSuite) Setup(t *testing.T) error { -//// fmt.Println("=== RUN Test Suite Setup") -//// if err := ts.SetupTestSuite(t); err != nil { -//// return err -//// } -//// -//// if err := ts.SetupComponentUnderTest(t); err != nil { -//// return err -//// } -//// -//// if err := ts.VendorDependencies(t); err != nil { -//// return err -//// } -//// -//// if err := ts.DeployDependencies(t); err != nil { -//// return err -//// } -//// -//// if err := ts.VerifyEnabledFlag(t); err != nil { -//// return err -//// } -//// -//// return nil -////} +//func (ts *TestSuite) Setup(t *testing.T) error { +// fmt.Println("=== RUN Test Suite Setup") +// if err := ts.SetupTestSuite(t); err != nil { +// return err +// } +// +// if err := ts.SetupComponentUnderTest(t); err != nil { +// return err +// } +// +// if err := ts.VendorDependencies(t); err != nil { +// return err +// } +// +// if err := ts.DeployDependencies(t); err != nil { +// return err +// } +// +// if err := ts.VerifyEnabledFlag(t); err != nil { +// return err +// } +// +// return nil +//} // //func (ts *TestSuite) TearDown(t *testing.T) error { // fmt.Println("=== RUN Test Suite TearDown") @@ -261,13 +261,13 @@ package aws_component_helper // } //} // -//func WithDependency(dependency *Dependency) TestSuiteOption { +//func WithDependency(dependency *AtmosComponent) TestSuiteOption { // return func(a *TestSuite) { // a.Dependencies = append(a.Dependencies, dependency) // } //} // -//func WithDependencies(dependencies []*Dependency) TestSuiteOption { +//func WithDependencies(dependencies []*AtmosComponent) TestSuiteOption { // return func(a *TestSuite) { // a.Dependencies = append(a.Dependencies, dependencies...) // } diff --git a/pkg/atmos/aws-component-helper/x_test_suite.go b/pkg/atmos/aws-component-helper/x_test_suite.go index de98647..c67a5a4 100644 --- a/pkg/atmos/aws-component-helper/x_test_suite.go +++ b/pkg/atmos/aws-component-helper/x_test_suite.go @@ -68,42 +68,3 @@ func (ts *XTestSuite) getAtmosOptions(t *testing.T, options *atmos.Options, vars require.NoError(t, err) return result } - -func (ts *XTestSuite) AddSetup(component string, stack string) { - item := NewAtmosComponent(component, stack) - ts.setup = append(ts.setup, item) -} - -func (ts *XTestSuite) GetOrCreateTest(name string) *ComponentTest { - if _, ok := ts.tests[name]; !ok { - ts.tests[name] = NewComponentTest() - } - return ts.tests[name] -} - -func (ts *XTestSuite) Tests() map[string]*ComponentTest { - return ts.tests -} - -func (ts *XTestSuite) Run(t *testing.T, options *atmos.Options) { - suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) - for _, component := range ts.setup { - componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) - if !*skipDeploySuiteDependencies && !*skipDeployDependencies { - atmosApply(t, componentOptions) - } - if !*skipDeploySuiteDependencies && !*skipDestroySuiteDependencies && !*skipDeployDependencies && !*skipDestroyDependencies { - defer atmosDestroy(t, componentOptions) - } - } - - if *runParallel { - fmt.Println("Run tests in parallel mode") - t.Parallel() - } - for name, item := range ts.tests { - t.Run(name, func(t *testing.T) { - item.Run(t, suiteOptions) - }) - } -} diff --git a/pkg/atmos/aws-component-helper/x_test_suite_test.go b/pkg/atmos/aws-component-helper/x_test_suite_test.go index dee6b55..915d810 100644 --- a/pkg/atmos/aws-component-helper/x_test_suite_test.go +++ b/pkg/atmos/aws-component-helper/x_test_suite_test.go @@ -11,7 +11,7 @@ func TestComponentTestSuiteMinimum(t *testing.T) { test := componentTestSuite.GetOrCreateTest("test") test.SetSubject("vpc", "default-test") - assert.Equal(t, test.Subject.Component, "vpc") - assert.Equal(t, componentTestSuite.tests["test"].Subject.Component, "vpc") - assert.Equal(t, componentTestSuite.tests["test"].Subject.Stack, "default-test") + assert.Equal(t, test.Subject.ComponentName, "vpc") + assert.Equal(t, componentTestSuite.tests["test"].Subject.ComponentName, "vpc") + assert.Equal(t, componentTestSuite.tests["test"].Subject.StackName, "default-test") } diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index 02ce4e1..e860a9c 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -6,7 +6,6 @@ import ( "fmt" "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "os" "path/filepath" @@ -28,8 +27,10 @@ var ( skipDeployDependencies = flag.Bool("cth.skip-deploy-deps", false, "skip deploy dependencies") skipDestroyDependencies = flag.Bool("cth.skip-destroy-deps", false, "skip destroy dependencies") skipTeardownTestSuite = flag.Bool("cth.skip-teardown", false, "skip test suite teardown") + skipTests = flag.Bool("cth.skip-tests", false, "skip tests") - skipTests = flag.Bool("cth.skip-tests", false, "skip tests") + skipDeployComponentUnderTest = flag.Bool("cth.skip-deploy-cut", false, "skip deploy component under test") + skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") ) type XTestSuites struct { @@ -39,7 +40,6 @@ type XTestSuites struct { SourceDir string TempDir string FixturesPath string - suites map[string]*XTestSuite } func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, fixturesDir string) *XTestSuites { @@ -58,49 +58,6 @@ func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, fixturesDir FixturesPath: fixturesDir, AwsAccountId: awsAccountId, AwsRegion: awsRegion, - suites: map[string]*XTestSuite{}, - } - - describeStacksOptions := suites.getAtmosOptions(t, &atmos.Options{}, map[string]interface{}{}) - describeStacksOptions.AtmosBasePath = filepath.Join(suites.SourceDir, suites.FixturesPath) - describeStacksOptions.EnvVars["ATMOS_BASE_PATH"] = describeStacksOptions.AtmosBasePath - describeStacksOptions.EnvVars["ATMOS_CLI_CONFIG_PATH"] = describeStacksOptions.AtmosBasePath - - describeStacksConfigs, err := atmos.DescribeStacksE(t, describeStacksOptions) - require.NoError(t, err) - - for stackName, stack := range describeStacksConfigs.Stacks { - for componentName, component := range stack.Components.Terraform { - if component.Settings.Test == nil { - // Skip components that are not part of tests - continue - } - - suiteName := component.Settings.Test.Suite - require.NotEmptyf(t, suiteName, "settings.test.suite is required for component %s in stack %s", componentName, stackName) - - validStages := []string{"testSuiteSetUp", "testSetUp", "subjectUnderTest", "assert"} - stage := component.Settings.Test.Stage - - require.NotEmptyf(t, stage, "settings.test.stage is required for component %s in stack %s", componentName, stackName) - require.Containsf(t, validStages, stage, "settings.test.stage should be one of %v for component %s in stack %s", validStages, componentName, stackName) - - testName := component.Settings.Test.Test - require.False(t, stage != "testSuiteSetUp" && testName == "", "settings.test.test is required for component %s in stack %s", componentName, stackName) - - suite := suites.GetOrCreateSuite(suiteName) - - switch stage { - case "testSuiteSetUp": - suite.AddSetup(componentName, stackName) - case "testSetUp": - suite.GetOrCreateTest(testName).AddSetup(componentName, stackName) - case "subjectUnderTest": - suite.GetOrCreateTest(testName).SetSubject(componentName, stackName) - case "assert": - suite.GetOrCreateTest(testName).AddSAssert(componentName, stackName) - } - } } return suites @@ -114,17 +71,16 @@ func (ts *XTestSuites) WorkDir() string { } } -func (ts *XTestSuites) Run(t *testing.T, options *atmos.Options) { +func (ts *XTestSuites) SetUp(t *testing.T, options *atmos.Options) { suitesOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) if !*skipTmpDir { fmt.Printf("Create TMP dir: %s \n", ts.TempDir) err := os.Mkdir(ts.TempDir, 0777) - assert.NoError(t, err) - defer os.RemoveAll(ts.TempDir) + require.NoError(t, err) err = copyDirectoryRecursively(ts.SourceDir, ts.TempDir) - assert.NoError(t, err) + require.NoError(t, err) } else { fmt.Printf("Use source dir: %s \n", ts.SourceDir) } @@ -137,20 +93,17 @@ func (ts *XTestSuites) Run(t *testing.T, options *atmos.Options) { if !*skipTmpDir { err := createStateDir(ts.TempDir) - assert.NoError(t, err) + require.NoError(t, err) } else { err := createStateDir(ts.SourceDir) - assert.NoError(t, err) + require.NoError(t, err) } +} - if *runParallel { - fmt.Println("Run suites in parallel mode") - t.Parallel() - } - for name, suite := range ts.suites { - t.Run(name, func(t *testing.T) { - suite.Run(t, suitesOptions) - }) +func (ts *XTestSuites) TearDown(t *testing.T) { + if !*skipTmpDir { + err := os.RemoveAll(ts.TempDir) + require.NoError(t, err) } } @@ -187,10 +140,47 @@ func (ts *XTestSuites) getAtmosOptions(t *testing.T, options *atmos.Options, var return result } -func (ts *XTestSuites) GetOrCreateSuite(name string) *XTestSuite { - if _, ok := ts.suites[name]; !ok { - ts.suites[name] = NewXTestSuite() +func (ts *XTestSuites) DeployComponent(t *testing.T, component *AtmosComponent, options *atmos.Options) { + if !*skipDeployComponentUnderTest { + suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) + componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) + atmosApply(t, componentOptions) + } +} + +func (ts *XTestSuites) DestroyComponent(t *testing.T, component *AtmosComponent, options *atmos.Options) { + if !*skipDeployComponentUnderTest && !*skipDestroyComponentUnderTest { + suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) + componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) + atmosDestroy(t, componentOptions) } - return ts.suites[name] +} + +func (ts *XTestSuites) DeployDependency(t *testing.T, component *AtmosComponent, options *atmos.Options) { + if !*skipDeployDependencies { + suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) + componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) + atmosApply(t, componentOptions) + } +} + +func (ts *XTestSuites) DestroyDependency(t *testing.T, component *AtmosComponent, options *atmos.Options) { + if !*skipDeployDependencies && !*skipDestroyDependencies { + suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) + + componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) + atmosDestroy(t, componentOptions) + } +} + +func (ts *XTestSuites) CreateAndDeployDependency(t *testing.T, componentName string, stackName string, options *atmos.Options) *AtmosComponent { + component := NewAtmosComponent(componentName, stackName) + ts.DeployDependency(t, component, options) + return component +} +func (ts *XTestSuites) CreateAndDeployComponent(t *testing.T, componentName string, stackName string, options *atmos.Options) *AtmosComponent { + component := NewAtmosComponent(componentName, stackName) + ts.DeployComponent(t, component, options) + return component } diff --git a/pkg/atmos/aws-component-helper/x_test_suites_test.go b/pkg/atmos/aws-component-helper/x_test_suites_test.go index 9a6444c..055439c 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites_test.go +++ b/pkg/atmos/aws-component-helper/x_test_suites_test.go @@ -50,26 +50,11 @@ func TestComponentTestSuitesMinimum(t *testing.T) { TempDir: "testdata/tmp", AwsAccountId: "123456789012", AwsRegion: "us-west-2", - suites: map[string]*XTestSuite{ - "default": { - tests: map[string]*ComponentTest{ - "test": { - Subject: &AtmosComponent{ - Component: "vpc", - Stack: "default-test", - }, - }, - }, - }, - }, } assert.Equal(t, componentTestSuites.FixturesPath, "testdata/fixtures") assert.Equal(t, componentTestSuites.TempDir, "testdata/tmp") assert.Equal(t, componentTestSuites.AwsAccountId, "123456789012") assert.Equal(t, componentTestSuites.AwsRegion, "us-west-2") - // assert.Equal(t, componentTestSuites.AtmosOptions, "us-west-2") - assert.Equal(t, componentTestSuites.suites["default"].tests["test"].Subject.Component, "vpc") - assert.Equal(t, componentTestSuites.suites["default"].tests["test"].Subject.Stack, "default-test") } func TestComponentTestSuitesCreate(t *testing.T) { @@ -86,31 +71,6 @@ func TestComponentTestSuitesCreate(t *testing.T) { componentTestSuites := NewTestSuites(t, testFolder, "us-west-2", atmosExamplePath) assert.Equal(t, componentTestSuites.SourceDir, testFolder) - - // There is one testSuite - assert.NotEmpty(t, componentTestSuites.suites) - assert.NotNil(t, componentTestSuites.suites["default"]) - - // testSuite does not have setup steps - assert.Empty(t, componentTestSuites.suites["default"].setup) - - // testSuite has one test - assert.NotEmpty(t, componentTestSuites.suites["default"].tests) - assert.NotNil(t, componentTestSuites.suites["default"].tests["two-private-subnets"]) - - // test has no setup step - assert.Empty(t, componentTestSuites.suites["default"].tests["two-private-subnets"].setup) - - // test has subject - assert.NotNil(t, componentTestSuites.suites["default"].tests["two-private-subnets"].Subject) - assert.Equal(t, componentTestSuites.suites["default"].tests["two-private-subnets"].Subject.Component, "vpc") - assert.Equal(t, componentTestSuites.suites["default"].tests["two-private-subnets"].Subject.Stack, "default-test") - - // test has one assert - assert.NotEmpty(t, componentTestSuites.suites["default"].tests["two-private-subnets"].assert) - assert.NotNil(t, componentTestSuites.suites["default"].tests["two-private-subnets"].assert[0]) - assert.Equal(t, componentTestSuites.suites["default"].tests["two-private-subnets"].assert[0].Component, "assert") - assert.Equal(t, componentTestSuites.suites["default"].tests["two-private-subnets"].assert[0].Stack, "default-test") } func TestComponentTestSuitesRun(t *testing.T) { @@ -128,5 +88,19 @@ func TestComponentTestSuitesRun(t *testing.T) { componentTestSuites := NewTestSuites(t, testFolder, "us-west-2", atmosExamplePath) - componentTestSuites.Run(t, &atmos.Options{}) + componentTestSuites.SetUp(t, &atmos.Options{}) + defer componentTestSuites.TearDown(t) + + component := componentTestSuites.CreateAndDeployDependency(t, "vpc", "default-test", &atmos.Options{}) + defer componentTestSuites.DestroyDependency(t, component, &atmos.Options{}) + + t.Run("two-private-subnets", func(t *testing.T) { + component := componentTestSuites.CreateAndDeployComponent(t, "vpc/private-only", "default-test", &atmos.Options{}) + defer componentTestSuites.DestroyComponent(t, component, &atmos.Options{}) + }) + + t.Run("public-subnets", func(t *testing.T) { + component := componentTestSuites.CreateAndDeployComponent(t, "vpc/full", "default-test", &atmos.Options{}) + defer componentTestSuites.DestroyComponent(t, component, &atmos.Options{}) + }) } diff --git a/pkg/atmos/terraform_plan.go b/pkg/atmos/terraform_plan.go index 6d94918..1042845 100644 --- a/pkg/atmos/terraform_plan.go +++ b/pkg/atmos/terraform_plan.go @@ -42,7 +42,7 @@ func PlanExitCodeE(t testing.TestingT, options *Options) (int, error) { // Custom errors var ( - ErrorComponentRequired = fmt.Errorf("you must set Component on options struct to use this function") + ErrorComponentRequired = fmt.Errorf("you must set ComponentName on options struct to use this function") ErrorPlanFilePathRequired = fmt.Errorf("you must set PlanFilePath on options struct to use this function") - ErrorStackRequired = fmt.Errorf("you must set Stack on options struct to use this function") + ErrorStackRequired = fmt.Errorf("you must set StackName on options struct to use this function") ) diff --git a/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml b/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml index 51f7679..514828e 100644 --- a/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml +++ b/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml @@ -7,8 +7,6 @@ terraform: local: path: ../../../../state/{{ .component }}/terraform.tfstate workspace_dir: ../../../../state/{{ .component }}/ - metadata: - terraform_workspace_pattern: "{component}-{environment}" vars: namespace: eg tenant: default From 5a0f353392b08679c10ddc4cf95e8a85d2a62444 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Thu, 26 Dec 2024 17:40:31 +0100 Subject: [PATCH 10/40] Get output --- .../aws-component-helper/x_test_suite_test.go | 17 ----------------- pkg/atmos/aws-component-helper/x_test_suites.go | 6 ++++++ 2 files changed, 6 insertions(+), 17 deletions(-) delete mode 100644 pkg/atmos/aws-component-helper/x_test_suite_test.go diff --git a/pkg/atmos/aws-component-helper/x_test_suite_test.go b/pkg/atmos/aws-component-helper/x_test_suite_test.go deleted file mode 100644 index 915d810..0000000 --- a/pkg/atmos/aws-component-helper/x_test_suite_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package aws_component_helper - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestComponentTestSuiteMinimum(t *testing.T) { - componentTestSuite := NewXTestSuite() - test := componentTestSuite.GetOrCreateTest("test") - test.SetSubject("vpc", "default-test") - - assert.Equal(t, test.Subject.ComponentName, "vpc") - assert.Equal(t, componentTestSuite.tests["test"].Subject.ComponentName, "vpc") - assert.Equal(t, componentTestSuite.tests["test"].Subject.StackName, "default-test") -} diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index e860a9c..580c2f8 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -173,6 +173,12 @@ func (ts *XTestSuites) DestroyDependency(t *testing.T, component *AtmosComponent } } +func (ts *XTestSuites) Output(t *testing.T, component *AtmosComponent, name string) string { + suiteOptions := ts.getAtmosOptions(t, &atmos.Options{}, map[string]interface{}{}) + componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) + return atmos.Output(t, componentOptions, name) +} + func (ts *XTestSuites) CreateAndDeployDependency(t *testing.T, componentName string, stackName string, options *atmos.Options) *AtmosComponent { component := NewAtmosComponent(componentName, stackName) ts.DeployDependency(t, component, options) From 084425b1f8e7bd07699b5c528ea35f0360d9985f Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Thu, 26 Dec 2024 21:03:34 +0100 Subject: [PATCH 11/40] Run subtests --- pkg/atmos/aws-component-helper/test_suite.go | 8 +-- .../aws-component-helper/x_test_suite.go | 70 ------------------- .../aws-component-helper/x_test_suites.go | 6 ++ .../x_test_suites_test.go | 4 +- 4 files changed, 12 insertions(+), 76 deletions(-) delete mode 100644 pkg/atmos/aws-component-helper/x_test_suite.go diff --git a/pkg/atmos/aws-component-helper/test_suite.go b/pkg/atmos/aws-component-helper/test_suite.go index 590c599..75e0fb4 100644 --- a/pkg/atmos/aws-component-helper/test_suite.go +++ b/pkg/atmos/aws-component-helper/test_suite.go @@ -14,7 +14,7 @@ package aws_component_helper // AwsRegion string // ComponentName string // ComponentSrcPath string -// Dependencies []*AtmosComponent +// Dependencies []*ComponentDeployment // FixturesPath string // ForceNewSuite bool // Index int @@ -46,7 +46,7 @@ package aws_component_helper // } //} // -//func (ts *TestSuite) AddCrossStackDependencies(dependencies []AtmosComponent) { +//func (ts *TestSuite) AddCrossStackDependencies(dependencies []ComponentDeployment) { // for _, dependency := range dependencies { // ts.AddCrossStackDependency(dependency.ComponentName, dependency.StackName) // } @@ -261,13 +261,13 @@ package aws_component_helper // } //} // -//func WithDependency(dependency *AtmosComponent) TestSuiteOption { +//func WithDependency(dependency *ComponentDeployment) TestSuiteOption { // return func(a *TestSuite) { // a.Dependencies = append(a.Dependencies, dependency) // } //} // -//func WithDependencies(dependencies []*AtmosComponent) TestSuiteOption { +//func WithDependencies(dependencies []*ComponentDeployment) TestSuiteOption { // return func(a *TestSuite) { // a.Dependencies = append(a.Dependencies, dependencies...) // } diff --git a/pkg/atmos/aws-component-helper/x_test_suite.go b/pkg/atmos/aws-component-helper/x_test_suite.go deleted file mode 100644 index c67a5a4..0000000 --- a/pkg/atmos/aws-component-helper/x_test_suite.go +++ /dev/null @@ -1,70 +0,0 @@ -package aws_component_helper - -import ( - "dario.cat/mergo" - "flag" - "fmt" - "github.com/cloudposse/test-helpers/pkg/atmos" - "github.com/gruntwork-io/terratest/modules/random" - "github.com/stretchr/testify/require" - "path/filepath" - "strings" - "testing" -) - -var ( - skipDeploySuiteDependencies = flag.Bool("cth.skip-deploy-suite-deps", false, "skip deploy suite deps") - skipDestroySuiteDependencies = flag.Bool("cth.skip-destroy-suite-deps", false, "skip destroy suite deps") -) - -type XTestSuite struct { - RandomIdentifier string - setup []*AtmosComponent - tests map[string]*ComponentTest - atmosOptions *atmos.Options -} - -func NewXTestSuite() *XTestSuite { - randID := random.UniqueId() - randomId := strings.ToLower(randID) - - return &XTestSuite{ - RandomIdentifier: randomId, - setup: make([]*AtmosComponent, 0), - tests: make(map[string]*ComponentTest), - } -} - -func (ts *XTestSuite) getAtmosOptions(t *testing.T, options *atmos.Options, vars map[string]interface{}) *atmos.Options { - result := &atmos.Options{} - if options != nil { - result, _ = options.Clone() - } - - currentTFDataDir := ".terraform" - if value, ok := options.EnvVars["TF_DATA_DIR"]; ok { - currentTFDataDir = value - } - - envvars := map[string]string{ - // We need to split the TF_DATA_DIR for parallel suites mode - "TF_DATA_DIR": filepath.Join(currentTFDataDir, fmt.Sprintf("suite-%s", ts.RandomIdentifier)), - } - - err := mergo.Merge(&result.EnvVars, envvars) - require.NoError(t, err) - - err = mergo.Merge(&result.Vars, vars) - require.NoError(t, err) - - suiteVars := map[string]interface{}{ - "attributes": []string{ts.RandomIdentifier}, - "default_tags": map[string]string{ - "CreatedByAtmosTestSuite": ts.RandomIdentifier, - }, - } - - err = mergo.Merge(&result.Vars, suiteVars) - require.NoError(t, err) - return result -} diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index 580c2f8..6eb6fb5 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -190,3 +190,9 @@ func (ts *XTestSuites) CreateAndDeployComponent(t *testing.T, componentName stri ts.DeployComponent(t, component, options) return component } + +func (ts *XTestSuites) Test(t *testing.T, name string, f func(t *testing.T)) { + if !*skipTests { + t.Run(name, f) + } +} diff --git a/pkg/atmos/aws-component-helper/x_test_suites_test.go b/pkg/atmos/aws-component-helper/x_test_suites_test.go index 055439c..3d40bff 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites_test.go +++ b/pkg/atmos/aws-component-helper/x_test_suites_test.go @@ -94,12 +94,12 @@ func TestComponentTestSuitesRun(t *testing.T) { component := componentTestSuites.CreateAndDeployDependency(t, "vpc", "default-test", &atmos.Options{}) defer componentTestSuites.DestroyDependency(t, component, &atmos.Options{}) - t.Run("two-private-subnets", func(t *testing.T) { + componentTestSuites.Test(t, "two-private-subnets", func(t *testing.T) { component := componentTestSuites.CreateAndDeployComponent(t, "vpc/private-only", "default-test", &atmos.Options{}) defer componentTestSuites.DestroyComponent(t, component, &atmos.Options{}) }) - t.Run("public-subnets", func(t *testing.T) { + componentTestSuites.Test(t, "public-subnets", func(t *testing.T) { component := componentTestSuites.CreateAndDeployComponent(t, "vpc/full", "default-test", &atmos.Options{}) defer componentTestSuites.DestroyComponent(t, component, &atmos.Options{}) }) From 2a3250503d6809edd9088773ab259385cc44eaff Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Thu, 26 Dec 2024 23:38:20 +0100 Subject: [PATCH 12/40] Added GetOptions --- pkg/atmos/aws-component-helper/x_test_suites.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index 6eb6fb5..813c051 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -173,10 +173,9 @@ func (ts *XTestSuites) DestroyDependency(t *testing.T, component *AtmosComponent } } -func (ts *XTestSuites) Output(t *testing.T, component *AtmosComponent, name string) string { +func (ts *XTestSuites) GetOptions(t *testing.T, component *AtmosComponent, name string) *atmos.Options { suiteOptions := ts.getAtmosOptions(t, &atmos.Options{}, map[string]interface{}{}) - componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) - return atmos.Output(t, componentOptions, name) + return component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) } func (ts *XTestSuites) CreateAndDeployDependency(t *testing.T, componentName string, stackName string, options *atmos.Options) *AtmosComponent { From 7aa4e74347c5ffacf4f0bd4fab658909bdc041ca Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Fri, 27 Dec 2024 14:03:38 +0100 Subject: [PATCH 13/40] Added GetOptions --- pkg/atmos/aws-component-helper/x_test_suites.go | 2 +- pkg/atmos/terraform_output.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index 813c051..b4d9a03 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -173,7 +173,7 @@ func (ts *XTestSuites) DestroyDependency(t *testing.T, component *AtmosComponent } } -func (ts *XTestSuites) GetOptions(t *testing.T, component *AtmosComponent, name string) *atmos.Options { +func (ts *XTestSuites) GetOptions(t *testing.T, component *AtmosComponent) *atmos.Options { suiteOptions := ts.getAtmosOptions(t, &atmos.Options{}, map[string]interface{}{}) return component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) } diff --git a/pkg/atmos/terraform_output.go b/pkg/atmos/terraform_output.go index 63b6627..ed1e3a9 100644 --- a/pkg/atmos/terraform_output.go +++ b/pkg/atmos/terraform_output.go @@ -275,7 +275,7 @@ func OutputJson(t testing.TestingT, options *Options, key string) string { // result as the json string. // If key is an empty string, it will return all the output variables. func OutputJsonE(t testing.TestingT, options *Options, key string) (string, error) { - args := []string{"terraform", "output", options.Component, "--skip-init", "-json", "-s", options.Stack} + args := []string{"terraform", "output", options.Component, "--skip-init", "--json", "-s", options.Stack} if key != "" { args = append(args, key) } From 18fcf395b72e40600176f8ac65cc46f204077ef9 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Fri, 27 Dec 2024 14:22:44 +0100 Subject: [PATCH 14/40] Fix atmos output --- pkg/atmos/terraform_output.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/atmos/terraform_output.go b/pkg/atmos/terraform_output.go index ed1e3a9..0694213 100644 --- a/pkg/atmos/terraform_output.go +++ b/pkg/atmos/terraform_output.go @@ -275,7 +275,7 @@ func OutputJson(t testing.TestingT, options *Options, key string) string { // result as the json string. // If key is an empty string, it will return all the output variables. func OutputJsonE(t testing.TestingT, options *Options, key string) (string, error) { - args := []string{"terraform", "output", options.Component, "--skip-init", "--json", "-s", options.Stack} + args := []string{"terraform", "output", options.Component, "--skip-init", "-s", options.Stack, "--json"} if key != "" { args = append(args, key) } From 87e18b426e40ab1974761ad8eefb5def9389af20 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Fri, 27 Dec 2024 22:24:05 +0100 Subject: [PATCH 15/40] Added cache dir --- .../aws-component-helper/atmos_component.go | 9 +++--- .../aws-component-helper/setup_test_suite.go | 19 ++++++++--- .../aws-component-helper/x_test_suites.go | 32 +++++++++++-------- .../x_test_suites_test.go | 13 ++++---- 4 files changed, 44 insertions(+), 29 deletions(-) diff --git a/pkg/atmos/aws-component-helper/atmos_component.go b/pkg/atmos/aws-component-helper/atmos_component.go index 3badf13..39df226 100644 --- a/pkg/atmos/aws-component-helper/atmos_component.go +++ b/pkg/atmos/aws-component-helper/atmos_component.go @@ -1,14 +1,15 @@ package aws_component_helper import ( - "dario.cat/mergo" "fmt" - "github.com/cloudposse/test-helpers/pkg/atmos" - "github.com/gruntwork-io/terratest/modules/random" - "github.com/stretchr/testify/require" "path/filepath" "strings" "testing" + + "dario.cat/mergo" + "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/stretchr/testify/require" ) type AtmosComponent struct { diff --git a/pkg/atmos/aws-component-helper/setup_test_suite.go b/pkg/atmos/aws-component-helper/setup_test_suite.go index 534dfac..c09eb49 100644 --- a/pkg/atmos/aws-component-helper/setup_test_suite.go +++ b/pkg/atmos/aws-component-helper/setup_test_suite.go @@ -3,11 +3,12 @@ package aws_component_helper import ( "context" "fmt" - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/service/sts" "os" "path/filepath" "runtime" + + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/sts" ) //func setupTestSuite(ts *TestSuite) error { @@ -30,9 +31,17 @@ import ( //} func createStateDir(tempDir string) error { - stateDir := filepath.Join(tempDir, "state") - if _, err := os.Stat(stateDir); os.IsNotExist(err) { - err := os.MkdirAll(stateDir, 0777) + return createDir(tempDir, "state") +} + +func createCacheDir(tempDir string) error { + return createDir(tempDir, ".cache") +} + +func createDir(tempDir string, name string) error { + dir := filepath.Join(tempDir, name) + if _, err := os.Stat(dir); os.IsNotExist(err) { + err := os.MkdirAll(dir, 0777) return err } diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/x_test_suites.go index b4d9a03..e55fdba 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/x_test_suites.go @@ -1,16 +1,17 @@ package aws_component_helper import ( - "dario.cat/mergo" "flag" "fmt" - "github.com/cloudposse/test-helpers/pkg/atmos" - "github.com/gruntwork-io/terratest/modules/random" - "github.com/stretchr/testify/require" "os" "path/filepath" "strings" "testing" + + "dario.cat/mergo" + "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/stretchr/testify/require" ) var ( @@ -65,12 +66,16 @@ func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, fixturesDir func (ts *XTestSuites) WorkDir() string { if !*skipTmpDir { - return filepath.Join(ts.TempDir, ts.FixturesPath) + return ts.TempDir } else { - return filepath.Join(ts.SourceDir, ts.FixturesPath) + return ts.SourceDir } } +func (ts *XTestSuites) FixtureDir() string { + return filepath.Join(ts.WorkDir(), ts.FixturesPath) +} + func (ts *XTestSuites) SetUp(t *testing.T, options *atmos.Options) { suitesOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) if !*skipTmpDir { @@ -91,13 +96,11 @@ func (ts *XTestSuites) SetUp(t *testing.T, options *atmos.Options) { fmt.Println("Skip Vendor Pull") } - if !*skipTmpDir { - err := createStateDir(ts.TempDir) - require.NoError(t, err) - } else { - err := createStateDir(ts.SourceDir) - require.NoError(t, err) - } + err := createStateDir(ts.WorkDir()) + require.NoError(t, err) + + err = createCacheDir(ts.WorkDir()) + require.NoError(t, err) } func (ts *XTestSuites) TearDown(t *testing.T) { @@ -113,7 +116,7 @@ func (ts *XTestSuites) getAtmosOptions(t *testing.T, options *atmos.Options, var result, _ = options.Clone() } - result.AtmosBasePath = ts.WorkDir() + result.AtmosBasePath = ts.FixtureDir() result.NoColor = true result.Lock = false result.Upgrade = true @@ -122,6 +125,7 @@ func (ts *XTestSuites) getAtmosOptions(t *testing.T, options *atmos.Options, var "TEST_ACCOUNT_ID": ts.AwsAccountId, "ATMOS_BASE_PATH": result.AtmosBasePath, "ATMOS_CLI_CONFIG_PATH": result.AtmosBasePath, + "TF_PLUGIN_CACHE_DIR": filepath.Join(ts.WorkDir(), ".cache"), } err := mergo.Merge(&result.EnvVars, envvars) diff --git a/pkg/atmos/aws-component-helper/x_test_suites_test.go b/pkg/atmos/aws-component-helper/x_test_suites_test.go index 3d40bff..5e846e0 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites_test.go +++ b/pkg/atmos/aws-component-helper/x_test_suites_test.go @@ -2,12 +2,13 @@ package aws_component_helper import ( "fmt" + "os" + "testing" + "github.com/cloudposse/test-helpers/pkg/atmos" tt "github.com/cloudposse/test-helpers/pkg/testing" "github.com/gruntwork-io/terratest/modules/files" "github.com/stretchr/testify/require" - "os" - "testing" "github.com/stretchr/testify/assert" ) @@ -15,28 +16,28 @@ import ( const atmosExamplePath = "test/fixtures/aws-component-helper" func mockAtmos() { - atmosApply = func(t tt.TestingT, options *atmos.Options) string { + atmosApply = func(_ tt.TestingT, options *atmos.Options) string { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "apply", "-input=false", "-auto-approve")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) fmt.Println(description) return "" } - atmosDestroy = func(t tt.TestingT, options *atmos.Options) string { + atmosDestroy = func(_ tt.TestingT, options *atmos.Options) string { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "destroy", "-input=false", "-auto-approve")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) fmt.Println(description) return "" } - atmosPlanExitCodeE = func(t tt.TestingT, options *atmos.Options) (int, error) { + atmosPlanExitCodeE = func(_ tt.TestingT, options *atmos.Options) (int, error) { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "plan", "-input=false", "-detailed-exitcode")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) fmt.Println(description) return 0, nil } - atmosVendorPull = func(t tt.TestingT, options *atmos.Options) string { + atmosVendorPull = func(_ tt.TestingT, options *atmos.Options) string { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "vendor", "pull")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) fmt.Println(description) From 9f35cdab365b4a52cac3fe7bbd66c81d61a0009a Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Sat, 28 Dec 2024 03:50:46 +0100 Subject: [PATCH 16/40] Added suites stricture --- pkg/atmos/aws-component-helper/atmos.go | 71 ++++++++++ .../{x_test_suites.go => fixture.go} | 120 +++++++---------- ...{x_test_suites_test.go => fixture_test.go} | 46 ++++--- .../aws-component-helper/setup_test_suite.go | 8 -- .../setup_test_suite_test.go | 2 +- pkg/atmos/aws-component-helper/suite.go | 126 ++++++++++++++++++ test/aws-component-helper/test/basic_test.go | 2 +- 7 files changed, 274 insertions(+), 101 deletions(-) rename pkg/atmos/aws-component-helper/{x_test_suites.go => fixture.go} (50%) rename pkg/atmos/aws-component-helper/{x_test_suites_test.go => fixture_test.go} (69%) create mode 100644 pkg/atmos/aws-component-helper/suite.go diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index cf5e9d3..02333f2 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -1,7 +1,16 @@ package aws_component_helper import ( + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "dario.cat/mergo" "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/stretchr/testify/require" ) var ( @@ -11,6 +20,68 @@ var ( atmosVendorPull = atmos.VendorPull ) +type Atmos struct { + t *testing.T + options *atmos.Options +} + +func NewAtmos(t *testing.T, options *atmos.Options) *Atmos { + return &Atmos{ + t: t, + options: options, + } +} + +func (ts *Atmos) GetAndDeploy(t *testing.T, componentName string, stackName string) *AtmosComponent { + component := NewAtmosComponent(componentName, stackName) + ts.Deploy(t, component) + return component +} + +func (ts *Atmos) Deploy(t *testing.T, component *AtmosComponent) { + options := ts.getAtmosOptions() + options.Component = component.ComponentName + options.Stack = component.StackName + defer os.RemoveAll(options.AtmosBasePath) + copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) + atmosApply(t, options) +} + +func (ts *Atmos) Destroy(t *testing.T, component *AtmosComponent) { + options := ts.getAtmosOptions() + options.Component = component.ComponentName + options.Stack = component.StackName + defer os.RemoveAll(options.AtmosBasePath) + copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) + atmosDestroy(t, options) +} + +func (ts *Atmos) getAtmosOptions() *atmos.Options { + result, err := ts.options.Clone() + require.NoError(ts.t, err) + + randID := random.UniqueId() + randomId := strings.ToLower(randID) + + basePath := filepath.Dir(filepath.Clean(ts.options.AtmosBasePath)) + dirName := filepath.Base(ts.options.AtmosBasePath) + tmpDir := filepath.Join(basePath, fmt.Sprintf(".%s-%s", dirName, randomId)) + + result.AtmosBasePath = tmpDir + resultEnvVars := result.EnvVars + envvars := map[string]string{ + "ATMOS_BASE_PATH": result.AtmosBasePath, + "ATMOS_CLI_CONFIG_PATH": result.AtmosBasePath, + } + + err = mergo.Merge(&envvars, resultEnvVars) + require.NoError(t, err) + + result.EnvVars = envvars + + return result +} + //func GetAtmosOptions(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) *atmos.Options { // mergedVars := map[string]interface{}{ // "attributes": []string{suite.RandomIdentifier}, diff --git a/pkg/atmos/aws-component-helper/x_test_suites.go b/pkg/atmos/aws-component-helper/fixture.go similarity index 50% rename from pkg/atmos/aws-component-helper/x_test_suites.go rename to pkg/atmos/aws-component-helper/fixture.go index e55fdba..a54d243 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites.go +++ b/pkg/atmos/aws-component-helper/fixture.go @@ -34,37 +34,46 @@ var ( skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") ) -type XTestSuites struct { +type Fixture struct { + t *testing.T RandomIdentifier string AwsAccountId string AwsRegion string SourceDir string TempDir string FixturesPath string + suites []*Suite + suitesNames []string } -func NewTestSuites(t *testing.T, sourceDir string, awsRegion string, fixturesDir string) *XTestSuites { +func NewFixture(t *testing.T, sourceDir string, awsRegion string, fixturesDir string) *Fixture { awsAccountId, err := getAwsAaccountIdCallback() require.NoError(t, err) randID := random.UniqueId() randomId := strings.ToLower(randID) + tmpdir := filepath.Join(os.TempDir(), "test-suites-"+randomId) + realSourcePath, err := filepath.Abs(sourceDir) require.NoError(t, err) - suites := &XTestSuites{ + + suites := &Fixture{ + t: t, RandomIdentifier: randomId, SourceDir: realSourcePath, TempDir: tmpdir, FixturesPath: fixturesDir, AwsAccountId: awsAccountId, AwsRegion: awsRegion, + suites: []*Suite{}, + suitesNames: []string{}, } return suites } -func (ts *XTestSuites) WorkDir() string { +func (ts *Fixture) WorkDir() string { if !*skipTmpDir { return ts.TempDir } else { @@ -72,45 +81,56 @@ func (ts *XTestSuites) WorkDir() string { } } -func (ts *XTestSuites) FixtureDir() string { +func (ts *Fixture) FixtureDir() string { return filepath.Join(ts.WorkDir(), ts.FixturesPath) } -func (ts *XTestSuites) SetUp(t *testing.T, options *atmos.Options) { - suitesOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) +func (ts *Fixture) StateDir() string { + return "" +} + +func (ts *Fixture) GlobalStateDir() string { + return filepath.Join(ts.WorkDir(), "state") +} + +func (ts *Fixture) SetUp(options *atmos.Options) { + suitesOptions := ts.getAtmosOptions(options, map[string]interface{}{}) if !*skipTmpDir { fmt.Printf("Create TMP dir: %s \n", ts.TempDir) err := os.Mkdir(ts.TempDir, 0777) - require.NoError(t, err) + require.NoError(ts.t, err) err = copyDirectoryRecursively(ts.SourceDir, ts.TempDir) - require.NoError(t, err) + require.NoError(ts.t, err) } else { fmt.Printf("Use source dir: %s \n", ts.SourceDir) } if !*skipVendorDependencies { - atmosVendorPull(t, suitesOptions) + atmosVendorPull(ts.t, suitesOptions) } else { fmt.Println("Skip Vendor Pull") } - err := createStateDir(ts.WorkDir()) - require.NoError(t, err) + err := createDir(ts.WorkDir(), "state") + require.NoError(ts.t, err) - err = createCacheDir(ts.WorkDir()) - require.NoError(t, err) + err = createDir(ts.WorkDir(), ".cache") + require.NoError(ts.t, err) } -func (ts *XTestSuites) TearDown(t *testing.T) { +func (ts *Fixture) TearDown() { + for i := len(ts.suites) - 1; i >= 0; i-- { + ts.suites[i].runTeardown(ts.t) + } if !*skipTmpDir { err := os.RemoveAll(ts.TempDir) - require.NoError(t, err) + require.NoError(ts.t, err) } } -func (ts *XTestSuites) getAtmosOptions(t *testing.T, options *atmos.Options, vars map[string]interface{}) *atmos.Options { +func (ts *Fixture) getAtmosOptions(options *atmos.Options, vars map[string]interface{}) *atmos.Options { result := &atmos.Options{} if options != nil { result, _ = options.Clone() @@ -129,73 +149,25 @@ func (ts *XTestSuites) getAtmosOptions(t *testing.T, options *atmos.Options, var } err := mergo.Merge(&result.EnvVars, envvars) - require.NoError(t, err) + require.NoError(ts.t, err) suiteVars := map[string]interface{}{ "region": ts.AwsRegion, } err = mergo.Merge(&result.Vars, suiteVars) - require.NoError(t, err) + require.NoError(ts.t, err) err = mergo.Merge(&result.Vars, vars) - require.NoError(t, err) + require.NoError(ts.t, err) return result } -func (ts *XTestSuites) DeployComponent(t *testing.T, component *AtmosComponent, options *atmos.Options) { - if !*skipDeployComponentUnderTest { - suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) - componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) - atmosApply(t, componentOptions) - } -} - -func (ts *XTestSuites) DestroyComponent(t *testing.T, component *AtmosComponent, options *atmos.Options) { - if !*skipDeployComponentUnderTest && !*skipDestroyComponentUnderTest { - suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) - componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) - atmosDestroy(t, componentOptions) - } -} - -func (ts *XTestSuites) DeployDependency(t *testing.T, component *AtmosComponent, options *atmos.Options) { - if !*skipDeployDependencies { - suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) - componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) - atmosApply(t, componentOptions) - } -} - -func (ts *XTestSuites) DestroyDependency(t *testing.T, component *AtmosComponent, options *atmos.Options) { - if !*skipDeployDependencies && !*skipDestroyDependencies { - suiteOptions := ts.getAtmosOptions(t, options, map[string]interface{}{}) - - componentOptions := component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) - atmosDestroy(t, componentOptions) - } -} - -func (ts *XTestSuites) GetOptions(t *testing.T, component *AtmosComponent) *atmos.Options { - suiteOptions := ts.getAtmosOptions(t, &atmos.Options{}, map[string]interface{}{}) - return component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) -} - -func (ts *XTestSuites) CreateAndDeployDependency(t *testing.T, componentName string, stackName string, options *atmos.Options) *AtmosComponent { - component := NewAtmosComponent(componentName, stackName) - ts.DeployDependency(t, component, options) - return component -} - -func (ts *XTestSuites) CreateAndDeployComponent(t *testing.T, componentName string, stackName string, options *atmos.Options) *AtmosComponent { - component := NewAtmosComponent(componentName, stackName) - ts.DeployComponent(t, component, options) - return component -} - -func (ts *XTestSuites) Test(t *testing.T, name string, f func(t *testing.T)) { - if !*skipTests { - t.Run(name, f) - } +func (ts *Fixture) Suite(name string, f func(t *testing.T, suite *Suite)) { + require.NotContains(ts.t, ts.suitesNames, name, "Suite %s already exists", name) + suite := NewSuite(ts.t, name, ts) + ts.suites = append(ts.suites, suite) + ts.suitesNames = append(ts.suitesNames, name) + f(ts.t, suite) } diff --git a/pkg/atmos/aws-component-helper/x_test_suites_test.go b/pkg/atmos/aws-component-helper/fixture_test.go similarity index 69% rename from pkg/atmos/aws-component-helper/x_test_suites_test.go rename to pkg/atmos/aws-component-helper/fixture_test.go index 5e846e0..52fa5fa 100644 --- a/pkg/atmos/aws-component-helper/x_test_suites_test.go +++ b/pkg/atmos/aws-component-helper/fixture_test.go @@ -45,8 +45,8 @@ func mockAtmos() { } } -func TestComponentTestSuitesMinimum(t *testing.T) { - componentTestSuites := &XTestSuites{ +func TestFixtureMinimum(t *testing.T) { + componentTestSuites := &Fixture{ FixturesPath: "testdata/fixtures", TempDir: "testdata/tmp", AwsAccountId: "123456789012", @@ -58,7 +58,7 @@ func TestComponentTestSuitesMinimum(t *testing.T) { assert.Equal(t, componentTestSuites.AwsRegion, "us-west-2") } -func TestComponentTestSuitesCreate(t *testing.T) { +func TestFixtureCreate(t *testing.T) { getAwsAaccountIdCallback = func() (string, error) { return "123456789012", nil } @@ -69,12 +69,12 @@ func TestComponentTestSuitesCreate(t *testing.T) { fmt.Printf("running in %s\n", testFolder) - componentTestSuites := NewTestSuites(t, testFolder, "us-west-2", atmosExamplePath) + componentTestSuites := NewFixture(t, testFolder, "us-west-2", atmosExamplePath) assert.Equal(t, componentTestSuites.SourceDir, testFolder) } -func TestComponentTestSuitesRun(t *testing.T) { +func TestFixtureSuitesRun(t *testing.T) { getAwsAaccountIdCallback = func() (string, error) { return "123456789012", nil } @@ -87,21 +87,33 @@ func TestComponentTestSuitesRun(t *testing.T) { fmt.Printf("running in %s\n", testFolder) - componentTestSuites := NewTestSuites(t, testFolder, "us-west-2", atmosExamplePath) + fixture := NewFixture(t, testFolder, "us-west-2", atmosExamplePath) - componentTestSuites.SetUp(t, &atmos.Options{}) - defer componentTestSuites.TearDown(t) + fixture.SetUp(&atmos.Options{}) + defer fixture.TearDown() - component := componentTestSuites.CreateAndDeployDependency(t, "vpc", "default-test", &atmos.Options{}) - defer componentTestSuites.DestroyDependency(t, component, &atmos.Options{}) + fixture.Suite("default", func(t *testing.T, suite *Suite) { + // suite.AddDependency(t, "vpc", "default-test") - componentTestSuites.Test(t, "two-private-subnets", func(t *testing.T) { - component := componentTestSuites.CreateAndDeployComponent(t, "vpc/private-only", "default-test", &atmos.Options{}) - defer componentTestSuites.DestroyComponent(t, component, &atmos.Options{}) - }) + // var deps *AtmosComponent + + // suite.Setup(t, func(t *testing.T, atm *Atmos) { + // deps = atm.GetAndDeploy(t, "vpc/deps", "default-test") + // }) + + // suite.Test(t, "two-private-subnets", func(t *testing.T, atm *Atmos) { + // component := atm.GetAndDeploy(t, "vpc/private-only", "default-test") + // defer atm.Destroy(t, component) + // }) - componentTestSuites.Test(t, "public-subnets", func(t *testing.T) { - component := componentTestSuites.CreateAndDeployComponent(t, "vpc/full", "default-test", &atmos.Options{}) - defer componentTestSuites.DestroyComponent(t, component, &atmos.Options{}) + // suite.Test(t, "public-subnets", func(t *testing.T, atm *Atmos) { + // component := atm.GetAndDeploy(t, "vpc/full", "default-test") + // defer atm.Destroy(t, component) + // }) + + // suite.TearDown(t, func(t *testing.T, atm *Atmos) { + // atm.Destroy(t, deps) + // }) }) + } diff --git a/pkg/atmos/aws-component-helper/setup_test_suite.go b/pkg/atmos/aws-component-helper/setup_test_suite.go index c09eb49..eae774e 100644 --- a/pkg/atmos/aws-component-helper/setup_test_suite.go +++ b/pkg/atmos/aws-component-helper/setup_test_suite.go @@ -30,14 +30,6 @@ import ( // return nil //} -func createStateDir(tempDir string) error { - return createDir(tempDir, "state") -} - -func createCacheDir(tempDir string) error { - return createDir(tempDir, ".cache") -} - func createDir(tempDir string, name string) error { dir := filepath.Join(tempDir, name) if _, err := os.Stat(dir); os.IsNotExist(err) { diff --git a/pkg/atmos/aws-component-helper/setup_test_suite_test.go b/pkg/atmos/aws-component-helper/setup_test_suite_test.go index 2682f85..aecd027 100644 --- a/pkg/atmos/aws-component-helper/setup_test_suite_test.go +++ b/pkg/atmos/aws-component-helper/setup_test_suite_test.go @@ -34,7 +34,7 @@ import ( func TestCreateStateDir(t *testing.T) { tempDir := t.TempDir() - err := createStateDir(tempDir) + err := createDir(tempDir, "state") assert.NoError(t, err) stateDir := filepath.Join(tempDir, "state") diff --git a/pkg/atmos/aws-component-helper/suite.go b/pkg/atmos/aws-component-helper/suite.go new file mode 100644 index 0000000..3101285 --- /dev/null +++ b/pkg/atmos/aws-component-helper/suite.go @@ -0,0 +1,126 @@ +package aws_component_helper + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "dario.cat/mergo" + "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/stretchr/testify/require" +) + +type teadDown struct { + component *AtmosComponent + callback *func(t *testing.T, atm *Atmos) +} + +type Suite struct { + t *testing.T + randomIdentifier string + name string + stateDir string + globalStateDir string + dependencies []*AtmosComponent + teardown []*teadDown + options *atmos.Options +} + +func NewSuite(t *testing.T, name string, fixture *Fixture) *Suite { + randID := random.UniqueId() + randomId := strings.ToLower(randID) + stateNamespace := fmt.Sprintf("suite-%s", name) + suite := &Suite{ + t: t, + name: name, + randomIdentifier: randomId, + dependencies: []*AtmosComponent{}, + stateDir: filepath.Join(fixture.GlobalStateDir(), stateNamespace), + globalStateDir: fixture.GlobalStateDir(), + teardown: []*teadDown{}, + options: fixture.getAtmosOptions(&atmos.Options{}, map[string]interface{}{}), + } + + if fixture.StateDir() != "" { + copyDirectoryRecursively(fixture.StateDir(), suite.stateDir) + } else { + err := createDir(fixture.GlobalStateDir(), stateNamespace) + require.NoError(t, err) + } + + return suite +} + +func (ts *Suite) AddDependency(componentName string, stackName string) { + component := NewAtmosComponent(componentName, stackName) + ts.dependencies = append(ts.dependencies, component) + ts.teardown = append(ts.teardown, &teadDown{component: component, callback: nil}) + ts.getAtmos(ts.t).Deploy(ts.t, component) +} + +func (ts *Suite) getAtmos(t *testing.T) *Atmos { + return &Atmos{} +} + +func (ts *Suite) getTestAtmos(t *testing.T) *Atmos { + return &Atmos{} +} + +func (ts *Suite) runTeardown(t *testing.T) { + atm := ts.getAtmos(t) + var f *teadDown + for i := len(ts.teardown) - 1; i >= 0; i-- { + f = ts.teardown[i] + if f.callback != nil { + (*f.callback)(t, atm) + } + if f.component != nil { + atm.Destroy(t, f.component) + } + } + err := os.RemoveAll(ts.stateDir) + require.NoError(ts.t, err) +} + +func (ts *Suite) Setup(t *testing.T, f func(t *testing.T, atm *Atmos)) { + atm := &Atmos{} + f(t, atm) +} + +func (ts *Suite) TearDown(t *testing.T, f func(t *testing.T, atm *Atmos)) { + ts.teardown = append(ts.teardown, &teadDown{component: nil, callback: &f}) +} + +func (ts *Suite) Test(t *testing.T, name string, f func(t *testing.T, atm *Atmos)) { + if !*skipTests { + atm := ts.getTestAtmos(ts.t) + t.Run(name, func(t *testing.T) { + f(t, atm) + }) + } +} + +func (ts *Suite) getAtmosOptions(vars map[string]interface{}) *atmos.Options { + result, err := ts.options.Clone() + require.NoError(ts.t, err) + + envvars := map[string]string{ + "TEST_SUITE_NAME": ts.name, + } + + err = mergo.Merge(&result.EnvVars, envvars) + require.NoError(ts.t, err) + + err = mergo.Merge(&result.Vars, vars) + require.NoError(ts.t, err) + + return result +} + +// func (ts *Suite) GetOptions(t *testing.T, component *AtmosComponent) *atmos.Options { +// suiteOptions := ts.getAtmosOptions(t, &atmos.Options{}, map[string]interface{}{}) +// return component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) +// } diff --git a/test/aws-component-helper/test/basic_test.go b/test/aws-component-helper/test/basic_test.go index cd57a28..7506de5 100644 --- a/test/aws-component-helper/test/basic_test.go +++ b/test/aws-component-helper/test/basic_test.go @@ -11,7 +11,7 @@ import ( //"github.com/stretchr/testify/require" ) -var suite *helper.TestSuite +var suite *helper.Suite // TestMain is the entry point for the test suite. It initializes the test // suite and runs the tests. From 5e418e957a818fa908d6e41c8b86220ea1696027 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Sat, 28 Dec 2024 21:04:00 +0100 Subject: [PATCH 17/40] Added better suites --- .../aws-component-helper/acceptance_test.go | 54 +++++++++++ pkg/atmos/aws-component-helper/atmos.go | 88 +++++++++++++++--- .../aws-component-helper/atmos_component.go | 78 ++++++++-------- .../atmos_component_test.go | 2 +- pkg/atmos/aws-component-helper/fixture.go | 41 +++++---- .../aws-component-helper/fixture_test.go | 59 +++++++----- pkg/atmos/aws-component-helper/shared.go | 11 +++ pkg/atmos/aws-component-helper/suite.go | 91 ++++++++++++++----- .../aws-component-helper/test_component.go | 20 ++-- pkg/atmos/terraform_output.go | 12 +-- .../components/terraform/assert/.gitkeep | 0 .../terraform-basic-configuration/main.tf | 7 ++ .../terraform/terraform-no-error/main.tf | 11 +++ .../terraform-not-idempotent/main.tf | 7 ++ .../terraform/terraform-parallelism/main.tf | 16 ++++ .../terraform/terraform-with-error/main.tf | 8 ++ .../terraform-with-plan-error/main.tf | 5 + .../stacks/orgs/default/test/_defaults.yaml | 9 +- .../stacks/orgs/default/test/tests.yaml | 45 +++------ 19 files changed, 398 insertions(+), 166 deletions(-) create mode 100644 pkg/atmos/aws-component-helper/acceptance_test.go delete mode 100644 test/fixtures/aws-component-helper/components/terraform/assert/.gitkeep create mode 100644 test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/main.tf create mode 100644 test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf create mode 100644 test/fixtures/aws-component-helper/components/terraform/terraform-not-idempotent/main.tf create mode 100644 test/fixtures/aws-component-helper/components/terraform/terraform-parallelism/main.tf create mode 100644 test/fixtures/aws-component-helper/components/terraform/terraform-with-error/main.tf create mode 100644 test/fixtures/aws-component-helper/components/terraform/terraform-with-plan-error/main.tf diff --git a/pkg/atmos/aws-component-helper/acceptance_test.go b/pkg/atmos/aws-component-helper/acceptance_test.go new file mode 100644 index 0000000..53b518c --- /dev/null +++ b/pkg/atmos/aws-component-helper/acceptance_test.go @@ -0,0 +1,54 @@ +package aws_component_helper + +import ( + "fmt" + "os" + "testing" + + "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/gruntwork-io/terratest/modules/files" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestAcceptance(t *testing.T) { + getAwsAaccountIdCallback = func() (string, error) { + return "123456789012", nil + } + + testFolder, err := files.CopyFolderToTemp("../../../", t.Name(), func(path string) bool { return true }) + require.NoError(t, err) + defer os.RemoveAll(testFolder) + + fmt.Printf("running in %s\n", testFolder) + + fixture := NewFixture(t, testFolder, "us-west-2", "test/fixtures/aws-component-helper") + + fixture.SetUp(&atmos.Options{}) + defer fixture.TearDown() + + fixture.Suite("default", func(t *testing.T, suite *Suite) { + suite.Test(t, "basic", func(t *testing.T, atm *Atmos) { + inputs := map[string]interface{}{ + "cnt": 2, + } + defer atm.GetAndDestroy("terraform-basic-configuration", "default-test", inputs) + atm.GetAndDeploy("terraform-basic-configuration", "default-test", inputs) + + }) + + suite.Test(t, "no-error", func(t *testing.T, atm *Atmos) { + defer atm.GetAndDestroy("terraform-no-error", "default-test", nil) + component := atm.GetAndDeploy("terraform-no-error", "default-test", nil) + + assert.Equal(t, atm.Output(component, "test"), "Hello, World") + assert.Equal(t, atm.OutputList(component, "test_list"), []string{"a", "b", "c"}) + }) + + // suite.Test(t, "public-subnets", func(t *testing.T, atm *Atmos) { + // component := atm.GetAndDeploy("vpc/full", "default-test", nil) + // defer atm.Destroy(component) + // }) + }) + +} diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index 02333f2..6f4eb2b 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "reflect" "strings" "testing" @@ -18,6 +19,7 @@ var ( atmosDestroy = atmos.Destroy atmosPlanExitCodeE = atmos.PlanExitCodeE atmosVendorPull = atmos.VendorPull + atmosOutputAll = atmos.OutputStruct ) type Atmos struct { @@ -32,31 +34,85 @@ func NewAtmos(t *testing.T, options *atmos.Options) *Atmos { } } -func (ts *Atmos) GetAndDeploy(t *testing.T, componentName string, stackName string) *AtmosComponent { - component := NewAtmosComponent(componentName, stackName) - ts.Deploy(t, component) +func (ts *Atmos) GetAndDeploy(componentName string, stackName string, vars map[string]interface{}) *AtmosComponent { + component := NewAtmosComponent(componentName, stackName, vars) + ts.Deploy(component) return component } -func (ts *Atmos) Deploy(t *testing.T, component *AtmosComponent) { - options := ts.getAtmosOptions() +func (ts *Atmos) GetAndDestroy(componentName string, stackName string, vars map[string]interface{}) *AtmosComponent { + component := NewAtmosComponent(componentName, stackName, vars) + ts.Destroy(component) + return component +} + +func (ts *Atmos) Deploy(component *AtmosComponent) { + options := ts.getAtmosOptions(component.Vars) options.Component = component.ComponentName options.Stack = component.StackName defer os.RemoveAll(options.AtmosBasePath) - copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) - atmosApply(t, options) + err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) + require.NoError(ts.t, err) + atmosApply(ts.t, options) + atmosOutputAll(ts.t, options, "", &component.output) } -func (ts *Atmos) Destroy(t *testing.T, component *AtmosComponent) { - options := ts.getAtmosOptions() +func (ts *Atmos) Destroy(component *AtmosComponent) { + options := ts.getAtmosOptions(component.Vars) options.Component = component.ComponentName options.Stack = component.StackName defer os.RemoveAll(options.AtmosBasePath) - copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) - atmosDestroy(t, options) + err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) + require.NoError(ts.t, err) + atmosDestroy(ts.t, options) } -func (ts *Atmos) getAtmosOptions() *atmos.Options { +func (ts *Atmos) loadOutputAll(component *AtmosComponent) { + if component.output != nil { + return + } + options := ts.getAtmosOptions(nil) + options.Component = component.ComponentName + options.Stack = component.StackName + defer os.RemoveAll(options.AtmosBasePath) + err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) + require.NoError(ts.t, err) + atmosOutputAll(ts.t, options, "", &component.output) +} + +func (ts *Atmos) OutputAll(component *AtmosComponent) map[string]Output { + ts.loadOutputAll(component) + return component.output +} + +func (ts *Atmos) Output(component *AtmosComponent, key string) string { + ts.loadOutputAll(component) + + if value, ok := component.output[key]; ok { + return value.Value.(string) + } + require.Fail(ts.t, fmt.Sprintf("Output key %s not found", key)) + return "" +} + +func (ts *Atmos) OutputList(component *AtmosComponent, key string) []string { + ts.loadOutputAll(component) + if value, ok := component.output[key]; ok { + if outputList, isList := value.Value.([]interface{}); isList { + result, err := parseListOutputTerraform(outputList, key) + require.NoError(ts.t, err) + return result + } + error := atmos.UnexpectedOutputType{Key: key, ExpectedType: "map or list", ActualType: reflect.TypeOf(value).String()} + require.Fail(ts.t, error.Error()) + + } else { + require.Fail(ts.t, fmt.Sprintf("Output key %s not found", key)) + } + return []string{} +} + +func (ts *Atmos) getAtmosOptions(vars map[string]interface{}) *atmos.Options { result, err := ts.options.Clone() require.NoError(ts.t, err) @@ -75,10 +131,16 @@ func (ts *Atmos) getAtmosOptions() *atmos.Options { } err = mergo.Merge(&envvars, resultEnvVars) - require.NoError(t, err) + require.NoError(ts.t, err) result.EnvVars = envvars + if vars != nil { + err = mergo.Merge(&result.Vars, vars) + require.NoError(ts.t, err) + + } + return result } diff --git a/pkg/atmos/aws-component-helper/atmos_component.go b/pkg/atmos/aws-component-helper/atmos_component.go index 39df226..29e4d77 100644 --- a/pkg/atmos/aws-component-helper/atmos_component.go +++ b/pkg/atmos/aws-component-helper/atmos_component.go @@ -1,61 +1,63 @@ package aws_component_helper import ( - "fmt" - "path/filepath" "strings" - "testing" - "dario.cat/mergo" - "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" - "github.com/stretchr/testify/require" ) +type Output struct { + Sensitive bool `json:"sensitive"` + Value interface{} `json:"value"` +} + type AtmosComponent struct { RandomIdentifier string ComponentName string StackName string + Vars map[string]interface{} + output map[string]Output } -func NewAtmosComponent(component string, stack string) *AtmosComponent { +func NewAtmosComponent(component string, stack string, vars map[string]interface{}) *AtmosComponent { randID := random.UniqueId() randomId := strings.ToLower(randID) return &AtmosComponent{ RandomIdentifier: randomId, ComponentName: component, StackName: stack, + Vars: vars, } } -func (ac *AtmosComponent) getAtmosOptions(t *testing.T, options *atmos.Options, vars map[string]interface{}) *atmos.Options { - result := &atmos.Options{} - if options != nil { - result, _ = options.Clone() - } - - currentTFDataDir := ".terraform" - if value, ok := options.EnvVars["TF_DATA_DIR"]; ok { - currentTFDataDir = value - } - stack := strings.Replace(ac.StackName, "/", "-", -1) - name := strings.Replace(ac.ComponentName, "/", "-", -1) - envvars := map[string]string{ - // We need to split the TF_DATA_DIR for parallel suites mode - "TF_DATA_DIR": filepath.Join(currentTFDataDir, fmt.Sprintf("component-%s", ac.RandomIdentifier)), - "TEST_WORKSPACE_TEMPLATE": fmt.Sprintf("%s-%s-%s", stack, name, ac.RandomIdentifier), - } - - err := mergo.Merge(&result.EnvVars, envvars) - require.NoError(t, err) - - // Merge in any additional vars passed in - err = mergo.Merge(&result.Vars, vars) - require.NoError(t, err) - - result.Component = ac.ComponentName - result.Stack = ac.StackName - - atmosOptions := atmos.WithDefaultRetryableErrors(t, result) - return atmosOptions -} +// func (ac *AtmosComponent) getAtmosOptions(options *atmos.Options, vars map[string]interface{}) *atmos.Options { +// result := &atmos.Options{} +// if options != nil { +// result, _ = options.Clone() +// } + +// // currentTFDataDir := ".terraform" +// // if value, ok := options.EnvVars["TF_DATA_DIR"]; ok { +// // currentTFDataDir = value +// // } +// // stack := strings.Replace(ac.StackName, "/", "-", -1) +// // name := strings.Replace(ac.ComponentName, "/", "-", -1) +// // envvars := map[string]string{ +// // // We need to split the TF_DATA_DIR for parallel suites mode +// // "TF_DATA_DIR": filepath.Join(currentTFDataDir, fmt.Sprintf("component-%s", ac.RandomIdentifier)), +// // "TEST_WORKSPACE_TEMPLATE": fmt.Sprintf("%s-%s-%s", stack, name, ac.RandomIdentifier), +// // } + +// // err := mergo.Merge(&result.Vars, ac.vars) +// // require.NoError(t, err) + +// // // Merge in any additional vars passed in +// // err = mergo.Merge(&result.Vars, vars) +// // require.NoError(t, err) + +// // result.Component = ac.ComponentName +// // result.Stack = ac.StackName + +// atmosOptions := atmos.WithDefaultRetryableErrors(, result) +// return atmosOptions +// } diff --git a/pkg/atmos/aws-component-helper/atmos_component_test.go b/pkg/atmos/aws-component-helper/atmos_component_test.go index 884b5d3..1307042 100644 --- a/pkg/atmos/aws-component-helper/atmos_component_test.go +++ b/pkg/atmos/aws-component-helper/atmos_component_test.go @@ -8,7 +8,7 @@ import ( func TestAtmosComponent(t *testing.T) { // Create a temporary atmos component - component := NewAtmosComponent("vpc", "default-test") + component := NewAtmosComponent("vpc", "default-test", nil) assert.Equal(t, component.ComponentName, "vpc") assert.Equal(t, component.StackName, "default-test") diff --git a/pkg/atmos/aws-component-helper/fixture.go b/pkg/atmos/aws-component-helper/fixture.go index a54d243..ece7db3 100644 --- a/pkg/atmos/aws-component-helper/fixture.go +++ b/pkg/atmos/aws-component-helper/fixture.go @@ -19,19 +19,24 @@ var ( ) var ( - skipTmpDir = flag.Bool("cth.skip-tmp-dir", false, "Run in the current directory") - skipVendorDependencies = flag.Bool("cth.skip-vendor", false, "skip vendor dependencies") - runParallel = flag.Bool("cth.parallel", false, "Run parallel") - forceNewSuite = flag.Bool("cth.force-new-suite", false, "force new suite") - suiteIndex = flag.Int("cth.suite-index", -1, "suite index") - skipAwsNuke = flag.Bool("cth.skip-aws-nuke", false, "skip aws nuke") - skipDeployDependencies = flag.Bool("cth.skip-deploy-deps", false, "skip deploy dependencies") - skipDestroyDependencies = flag.Bool("cth.skip-destroy-deps", false, "skip destroy dependencies") - skipTeardownTestSuite = flag.Bool("cth.skip-teardown", false, "skip test suite teardown") - skipTests = flag.Bool("cth.skip-tests", false, "skip tests") - - skipDeployComponentUnderTest = flag.Bool("cth.skip-deploy-cut", false, "skip deploy component under test") - skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") + skipTmpDir = flag.Bool("skip-tmp-dir", false, "Run in the current directory") + skipVendorDependencies = flag.Bool("skip-vendor", false, "skip vendor dependencies") + skipTeardownFixtures = flag.Bool("skip-fixtures-teardown", false, "skip fixtures teardown") + skipTeardown = flag.Bool("skip-teardown", false, "skip teardown") + // runParallel = flag.Bool("parallel", false, "Run parallel") + + // forceNewSuite = flag.Bool("cth.force-new-suite", false, "force new suite") + // suiteIndex = flag.Int("cth.suite-index", -1, "suite index") + // skipAwsNuke = flag.Bool("cth.skip-aws-nuke", false, "skip aws nuke") + + // skipDependencies = flag.Bool("cth.skip-deps", false, "skip deploy dependencies") + // skipDeployDependencies = flag.Bool("cth.skip-deps-deploy", false, "skip deploy dependencies") + // skipDestroyDependencies = flag.Bool("cth.skip-deps-destroy", false, "skip destroy dependencies") + // skipTeardownTestSuite = flag.Bool("skip-teardown", false, "skip test suite teardown") + // skipTests = flag.Bool("skip-tests", false, "skip tests") + + // skipDeployComponentUnderTest = flag.Bool("cth.skip-deploy-cut", false, "skip deploy component under test") + // skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") ) type Fixture struct { @@ -96,7 +101,7 @@ func (ts *Fixture) GlobalStateDir() string { func (ts *Fixture) SetUp(options *atmos.Options) { suitesOptions := ts.getAtmosOptions(options, map[string]interface{}{}) if !*skipTmpDir { - fmt.Printf("Create TMP dir: %s \n", ts.TempDir) + fmt.Printf("Create fixtures tmp dir: %s \n", ts.TempDir) err := os.Mkdir(ts.TempDir, 0777) require.NoError(ts.t, err) @@ -104,7 +109,7 @@ func (ts *Fixture) SetUp(options *atmos.Options) { err = copyDirectoryRecursively(ts.SourceDir, ts.TempDir) require.NoError(ts.t, err) } else { - fmt.Printf("Use source dir: %s \n", ts.SourceDir) + fmt.Printf("Use fixtures source dir: %s \n", ts.SourceDir) } if !*skipVendorDependencies { @@ -121,10 +126,14 @@ func (ts *Fixture) SetUp(options *atmos.Options) { } func (ts *Fixture) TearDown() { + if *skipTeardown { + fmt.Println("Skip teardown") + return + } for i := len(ts.suites) - 1; i >= 0; i-- { ts.suites[i].runTeardown(ts.t) } - if !*skipTmpDir { + if !*skipTmpDir && !*skipTeardownFixtures { err := os.RemoveAll(ts.TempDir) require.NoError(ts.t, err) } diff --git a/pkg/atmos/aws-component-helper/fixture_test.go b/pkg/atmos/aws-component-helper/fixture_test.go index 52fa5fa..3c06f73 100644 --- a/pkg/atmos/aws-component-helper/fixture_test.go +++ b/pkg/atmos/aws-component-helper/fixture_test.go @@ -43,6 +43,13 @@ func mockAtmos() { fmt.Println(description) return "" } + + atmosOutputAll = func(_ tt.TestingT, options *atmos.Options, key string, v interface{}) { + options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "output", "--skip-init", "--json")...) + description := fmt.Sprintf("%s %v", options.AtmosBinary, args) + fmt.Println(description) + } + } func TestFixtureMinimum(t *testing.T) { @@ -93,27 +100,37 @@ func TestFixtureSuitesRun(t *testing.T) { defer fixture.TearDown() fixture.Suite("default", func(t *testing.T, suite *Suite) { - // suite.AddDependency(t, "vpc", "default-test") - - // var deps *AtmosComponent - - // suite.Setup(t, func(t *testing.T, atm *Atmos) { - // deps = atm.GetAndDeploy(t, "vpc/deps", "default-test") - // }) - - // suite.Test(t, "two-private-subnets", func(t *testing.T, atm *Atmos) { - // component := atm.GetAndDeploy(t, "vpc/private-only", "default-test") - // defer atm.Destroy(t, component) - // }) - - // suite.Test(t, "public-subnets", func(t *testing.T, atm *Atmos) { - // component := atm.GetAndDeploy(t, "vpc/full", "default-test") - // defer atm.Destroy(t, component) - // }) - - // suite.TearDown(t, func(t *testing.T, atm *Atmos) { - // atm.Destroy(t, deps) - // }) + suite.AddDependency("vpc/deps", "default-test") + + suite.Setup(t, func(t *testing.T, atm *Atmos) { + atm.GetAndDeploy("vpc/manual-deps", "default-test", nil) + }) + + suite.Test(t, "two-private-subnets", func(t *testing.T, atm *Atmos) { + inputs := map[string]interface{}{ + "name": "vpc-terraform", + "availability_zones": []string{"a", "b"}, + "public_subnets_enabled": false, + "nat_gateway_enabled": false, + "nat_instance_enabled": false, + "subnet_type_tag_key": "eg.cptest.co/subnet/type", + "max_subnet_count": 3, + "vpc_flow_logs_enabled": false, + "ipv4_primary_cidr_block": "172.16.0.0/16", + } + + component := atm.GetAndDeploy("vpc/private-only", "default-test", inputs) + defer atm.Destroy(component) + }) + + suite.Test(t, "public-subnets", func(t *testing.T, atm *Atmos) { + component := atm.GetAndDeploy("vpc/full", "default-test", nil) + defer atm.Destroy(component) + }) + + suite.TearDown(t, func(t *testing.T, atm *Atmos) { + atm.GetAndDestroy("vpc/manual-deps", "default-test", nil) + }) }) } diff --git a/pkg/atmos/aws-component-helper/shared.go b/pkg/atmos/aws-component-helper/shared.go index 898be64..0d4279e 100644 --- a/pkg/atmos/aws-component-helper/shared.go +++ b/pkg/atmos/aws-component-helper/shared.go @@ -37,3 +37,14 @@ func copyDirectoryRecursively(srcDir string, destDir string) error { } }) } + +// Parse a list output in the format it is returned by Terraform 0.12 and newer versions +func parseListOutputTerraform(outputList []interface{}, key string) ([]string, error) { + list := []string{} + + for _, item := range outputList { + list = append(list, fmt.Sprintf("%v", item)) + } + + return list, nil +} diff --git a/pkg/atmos/aws-component-helper/suite.go b/pkg/atmos/aws-component-helper/suite.go index 3101285..55d0c5c 100644 --- a/pkg/atmos/aws-component-helper/suite.go +++ b/pkg/atmos/aws-component-helper/suite.go @@ -1,6 +1,7 @@ package aws_component_helper import ( + "flag" "fmt" "os" "path/filepath" @@ -13,6 +14,26 @@ import ( "github.com/stretchr/testify/require" ) +var ( + skipTests = flag.Bool("skip-tests", false, "skip tests") + skipSetup = flag.Bool("skip-setup", false, "skip setup") + preserveStates = flag.Bool("preserve-states", true, "preserve states") + + // runParallel = flag.Bool("parallel", false, "Run parallel") + + // forceNewSuite = flag.Bool("cth.force-new-suite", false, "force new suite") + // suiteIndex = flag.Int("cth.suite-index", -1, "suite index") + // skipAwsNuke = flag.Bool("cth.skip-aws-nuke", false, "skip aws nuke") + + // skipDependencies = flag.Bool("cth.skip-deps", false, "skip deploy dependencies") + // skipDeployDependencies = flag.Bool("cth.skip-deps-deploy", false, "skip deploy dependencies") + // skipDestroyDependencies = flag.Bool("cth.skip-deps-destroy", false, "skip destroy dependencies") + // skipTeardownTestSuite = flag.Bool("skip-teardown", false, "skip test suite teardown") + + // skipDeployComponentUnderTest = flag.Bool("cth.skip-deploy-cut", false, "skip deploy component under test") + // skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") +) + type teadDown struct { component *AtmosComponent callback *func(t *testing.T, atm *Atmos) @@ -22,7 +43,6 @@ type Suite struct { t *testing.T randomIdentifier string name string - stateDir string globalStateDir string dependencies []*AtmosComponent teardown []*teadDown @@ -32,44 +52,61 @@ type Suite struct { func NewSuite(t *testing.T, name string, fixture *Fixture) *Suite { randID := random.UniqueId() randomId := strings.ToLower(randID) - stateNamespace := fmt.Sprintf("suite-%s", name) + require.NotContains(t, name, "/") suite := &Suite{ t: t, name: name, randomIdentifier: randomId, dependencies: []*AtmosComponent{}, - stateDir: filepath.Join(fixture.GlobalStateDir(), stateNamespace), globalStateDir: fixture.GlobalStateDir(), teardown: []*teadDown{}, options: fixture.getAtmosOptions(&atmos.Options{}, map[string]interface{}{}), } if fixture.StateDir() != "" { - copyDirectoryRecursively(fixture.StateDir(), suite.stateDir) + copyDirectoryRecursively(fixture.StateDir(), suite.StateDir()) } else { - err := createDir(fixture.GlobalStateDir(), stateNamespace) + err := createDir(fixture.GlobalStateDir(), suite.stateNamespace()) require.NoError(t, err) } return suite } +func (ts *Suite) StateDir() string { + return filepath.Join(ts.globalStateDir, ts.stateNamespace()) +} + +func (ts *Suite) stateNamespace() string { + return fmt.Sprintf("suite-%s", ts.name) + +} + func (ts *Suite) AddDependency(componentName string, stackName string) { - component := NewAtmosComponent(componentName, stackName) + if *skipSetup { + fmt.Printf("Skip suite %s setup dependency component: %s stack: %s\n", ts.name, componentName, stackName) + return + } + component := NewAtmosComponent(componentName, stackName, nil) ts.dependencies = append(ts.dependencies, component) ts.teardown = append(ts.teardown, &teadDown{component: component, callback: nil}) - ts.getAtmos(ts.t).Deploy(ts.t, component) + ts.getAtmos(ts.t).Deploy(component) } func (ts *Suite) getAtmos(t *testing.T) *Atmos { - return &Atmos{} + return NewAtmos(ts.t, ts.getAtmosOptions(map[string]interface{}{})) } func (ts *Suite) getTestAtmos(t *testing.T) *Atmos { - return &Atmos{} + return ts.getAtmos(ts.t) } func (ts *Suite) runTeardown(t *testing.T) { + if *skipTeardown { + fmt.Printf("Skip teardown suite %s\n", ts.name) + fmt.Printf("Suite %s preserve states %s\n", ts.name, ts.StateDir()) + return + } atm := ts.getAtmos(t) var f *teadDown for i := len(ts.teardown) - 1; i >= 0; i-- { @@ -78,15 +115,24 @@ func (ts *Suite) runTeardown(t *testing.T) { (*f.callback)(t, atm) } if f.component != nil { - atm.Destroy(t, f.component) + atm.Destroy(f.component) } } - err := os.RemoveAll(ts.stateDir) - require.NoError(ts.t, err) + if *preserveStates { + fmt.Printf("Suite %s preserve states %s\n", ts.name, ts.StateDir()) + } else { + fmt.Printf("Suite %s drops states %s\n", ts.name, ts.StateDir()) + err := os.RemoveAll(ts.StateDir()) + require.NoError(ts.t, err) + } } func (ts *Suite) Setup(t *testing.T, f func(t *testing.T, atm *Atmos)) { - atm := &Atmos{} + if *skipSetup { + fmt.Printf("Skip suite %s setup callback\n", ts.name) + return + } + atm := ts.getAtmos(ts.t) f(t, atm) } @@ -95,12 +141,14 @@ func (ts *Suite) TearDown(t *testing.T, f func(t *testing.T, atm *Atmos)) { } func (ts *Suite) Test(t *testing.T, name string, f func(t *testing.T, atm *Atmos)) { - if !*skipTests { - atm := ts.getTestAtmos(ts.t) - t.Run(name, func(t *testing.T) { - f(t, atm) - }) + if *skipTests { + fmt.Printf("Skip test %s/%s\n", ts.name, name) + return } + atm := ts.getTestAtmos(ts.t) + t.Run(name, func(t *testing.T) { + f(t, atm) + }) } func (ts *Suite) getAtmosOptions(vars map[string]interface{}) *atmos.Options { @@ -108,7 +156,7 @@ func (ts *Suite) getAtmosOptions(vars map[string]interface{}) *atmos.Options { require.NoError(ts.t, err) envvars := map[string]string{ - "TEST_SUITE_NAME": ts.name, + "TEST_SUITE_NAME": ts.stateNamespace(), } err = mergo.Merge(&result.EnvVars, envvars) @@ -119,8 +167,3 @@ func (ts *Suite) getAtmosOptions(vars map[string]interface{}) *atmos.Options { return result } - -// func (ts *Suite) GetOptions(t *testing.T, component *AtmosComponent) *atmos.Options { -// suiteOptions := ts.getAtmosOptions(t, &atmos.Options{}, map[string]interface{}{}) -// return component.getAtmosOptions(t, suiteOptions, map[string]interface{}{}) -// } diff --git a/pkg/atmos/aws-component-helper/test_component.go b/pkg/atmos/aws-component-helper/test_component.go index 4548277..fca8dea 100644 --- a/pkg/atmos/aws-component-helper/test_component.go +++ b/pkg/atmos/aws-component-helper/test_component.go @@ -1,15 +1,16 @@ package aws_component_helper import ( - "dario.cat/mergo" "flag" "fmt" - "github.com/cloudposse/test-helpers/pkg/atmos" - "github.com/gruntwork-io/terratest/modules/random" - "github.com/stretchr/testify/require" "path/filepath" "strings" "testing" + + "dario.cat/mergo" + "github.com/cloudposse/test-helpers/pkg/atmos" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/stretchr/testify/require" ) var ( @@ -36,13 +37,8 @@ func NewComponentTest() *ComponentTest { func (ct *ComponentTest) verifyEnabledFlag(t *testing.T, component *AtmosComponent, options *atmos.Options) *atmos.Options { testOptions := ct.getAtmosOptions(t, options, map[string]interface{}{}) - vars := map[string]interface{}{ - "enabled": false, - } - - componentOptions := component.getAtmosOptions(t, testOptions, vars) - exitCode, err := atmosPlanExitCodeE(t, componentOptions) + exitCode, err := atmosPlanExitCodeE(t, testOptions) require.NoError(t, err) if exitCode != 0 { @@ -88,12 +84,12 @@ func (ct *ComponentTest) getAtmosOptions(t *testing.T, options *atmos.Options, v } func (ct *ComponentTest) AddSetup(component string, stack string) { - item := NewAtmosComponent(component, stack) + item := NewAtmosComponent(component, stack, nil) ct.setup = append(ct.setup, item) } func (ct *ComponentTest) SetSubject(component string, stack string) { - ct.Subject = NewAtmosComponent(component, stack) + ct.Subject = NewAtmosComponent(component, stack, nil) } func (ct *ComponentTest) AddSAssert(name string, callback func(t *testing.T, ct *ComponentTest)) { diff --git a/pkg/atmos/terraform_output.go b/pkg/atmos/terraform_output.go index 0694213..2ac5dba 100644 --- a/pkg/atmos/terraform_output.go +++ b/pkg/atmos/terraform_output.go @@ -64,7 +64,7 @@ func parseListOfMaps(l []interface{}) ([]map[string]interface{}, error) { return nil, err } - m, err := parseMap(asMap) + m, err := ParseMap(asMap) if err != nil { return nil, err @@ -76,7 +76,7 @@ func parseListOfMaps(l []interface{}) ([]map[string]interface{}, error) { } -// parseMap takes a map of interfaces and parses the types. +// ParseMap takes a map of interfaces and parses the types. // It is recursive which allows it to support complex nested structures. // At this time, this function uses https://golang.org/pkg/strconv/#ParseInt // to determine if a number should be a float or an int. For this reason, if you are @@ -87,14 +87,14 @@ func parseListOfMaps(l []interface{}) ([]map[string]interface{}, error) { // types. ie, if you are expecting a value of "1" you are implicitly expecting an int. // // This also allows the work to be executed recursively to support complex data types. -func parseMap(m map[string]interface{}) (map[string]interface{}, error) { +func ParseMap(m map[string]interface{}) (map[string]interface{}, error) { result := make(map[string]interface{}) for k, v := range m { switch vt := v.(type) { case map[string]interface{}: - nestedMap, err := parseMap(vt) + nestedMap, err := ParseMap(vt) if err != nil { return nil, err } @@ -145,7 +145,7 @@ func OutputMapOfObjectsE(t testing.TestingT, options *Options, key string) (map[ return nil, err } - return parseMap(output) + return ParseMap(output) } // OutputListOfObjects calls terraform output for the given variable and returns its value as a list of maps/lists. @@ -175,7 +175,7 @@ func OutputListOfObjectsE(t testing.TestingT, options *Options, key string) ([]m var result []map[string]interface{} for _, m := range output { - newMap, err := parseMap(m) + newMap, err := ParseMap(m) if err != nil { return nil, err diff --git a/test/fixtures/aws-component-helper/components/terraform/assert/.gitkeep b/test/fixtures/aws-component-helper/components/terraform/assert/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/main.tf b/test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/main.tf new file mode 100644 index 0000000..b9253b9 --- /dev/null +++ b/test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/main.tf @@ -0,0 +1,7 @@ +variable "cnt" {} + +variable "region" {} + +resource "null_resource" "test" { + count = var.cnt +} diff --git a/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf b/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf new file mode 100644 index 0000000..19b896b --- /dev/null +++ b/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf @@ -0,0 +1,11 @@ +variable "region" {} + +output "test" { + value = "Hello, World" +} + +output "test_list" { + value = [ "a", "b", "c"] +} + + diff --git a/test/fixtures/aws-component-helper/components/terraform/terraform-not-idempotent/main.tf b/test/fixtures/aws-component-helper/components/terraform/terraform-not-idempotent/main.tf new file mode 100644 index 0000000..6862191 --- /dev/null +++ b/test/fixtures/aws-component-helper/components/terraform/terraform-not-idempotent/main.tf @@ -0,0 +1,7 @@ +variable "region" {} + +resource "null_resource" "test" { + triggers = { + time = timestamp() + } +} diff --git a/test/fixtures/aws-component-helper/components/terraform/terraform-parallelism/main.tf b/test/fixtures/aws-component-helper/components/terraform/terraform-parallelism/main.tf new file mode 100644 index 0000000..f5c6545 --- /dev/null +++ b/test/fixtures/aws-component-helper/components/terraform/terraform-parallelism/main.tf @@ -0,0 +1,16 @@ +variable "region" {} + + +# This resource just waits for 5 seconds. If we run it with enough parallelism, the whole module should apply in about +# 5 seconds. If we set parallelism to 1, it should take at least 25 seconds. +resource "null_resource" "wait" { + count = 5 + + triggers = { + run_always = timestamp() + } + + provisioner "local-exec" { + command = "sleep 5" + } +} diff --git a/test/fixtures/aws-component-helper/components/terraform/terraform-with-error/main.tf b/test/fixtures/aws-component-helper/components/terraform/terraform-with-error/main.tf new file mode 100644 index 0000000..5a7d516 --- /dev/null +++ b/test/fixtures/aws-component-helper/components/terraform/terraform-with-error/main.tf @@ -0,0 +1,8 @@ +variable "region" {} + +resource "null_resource" "fail_on_first_run" { + provisioner "local-exec" { + command = "if [[ -f terraform.tfstate.backup ]]; then echo 'This is not the first run, so exiting successfully' && exit 0; else echo 'This is the first run, exiting with an error' && exit 1; fi" + interpreter = ["/bin/bash", "-c"] + } +} diff --git a/test/fixtures/aws-component-helper/components/terraform/terraform-with-plan-error/main.tf b/test/fixtures/aws-component-helper/components/terraform/terraform-with-plan-error/main.tf new file mode 100644 index 0000000..90b325f --- /dev/null +++ b/test/fixtures/aws-component-helper/components/terraform/terraform-with-plan-error/main.tf @@ -0,0 +1,5 @@ +variable "region" {} + +output "test" { + value = var.test +} diff --git a/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml b/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml index 514828e..f14f134 100644 --- a/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml +++ b/test/fixtures/aws-component-helper/stacks/orgs/default/test/_defaults.yaml @@ -5,8 +5,13 @@ terraform: backend_type: local backend: local: - path: ../../../../state/{{ .component }}/terraform.tfstate - workspace_dir: ../../../../state/{{ .component }}/ + path: ../../../../../state/{{ getenv "TEST_SUITE_NAME" | default "" }}/{{ .component }}/terraform.tfstate + workspace_dir: ../../../../../state/{{ getenv "TEST_SUITE_NAME" | default "" }}/{{ .component }}/ + remote_state_backend_type: local + remote_state_backend: + local: + path: ../../../../../state/{{ getenv "TEST_SUITE_NAME" | default "" }}/{{ .component }}/terraform.tfstate + workspace_dir: ../../../../../state/{{ getenv "TEST_SUITE_NAME" | default "" }}/{{ .component }}/ vars: namespace: eg tenant: default diff --git a/test/fixtures/aws-component-helper/stacks/orgs/default/test/tests.yaml b/test/fixtures/aws-component-helper/stacks/orgs/default/test/tests.yaml index 8a0d9ce..468cab1 100644 --- a/test/fixtures/aws-component-helper/stacks/orgs/default/test/tests.yaml +++ b/test/fixtures/aws-component-helper/stacks/orgs/default/test/tests.yaml @@ -5,36 +5,15 @@ import: components: terraform: - vpc: - settings: - test: - suite: default - test: two-private-subnets - stage: subjectUnderTest - vars: - name: "vpc" - availability_zones: - - "a" - - "b" - # If we want to do functional testing of the bastion, we need public subnets, - # internet gateway, and NAT gateway, but those are expensive and for now, - # we are just doing basic smoke testing, so we skip them. - # public_subnets_enabled: true - # max_nats: 1 - # nat_gateway_enabled: true - public_subnets_enabled: false - nat_gateway_enabled: false - nat_instance_enabled: false - subnet_type_tag_key: "eg.cptest.co/subnet/type" - max_subnet_count: 3 - vpc_flow_logs_enabled: false - ipv4_primary_cidr_block: "172.16.0.0/16" - - assert: - settings: - test: - suite: default - test: two-private-subnets - stage: assert - vars: - name: "assert" + terraform-basic-configuration: + vars: {} + terraform-no-error: + vars: {} + terraform-with-plan-error: + vars: {} + terraform-with-error: + vars: {} + terraform-not-idempotent: + vars: {} + terraform-parallelism: + vars: {} From 395b8adb6d4c209b9ad918367fb9819c7a86c1e7 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Sun, 29 Dec 2024 00:18:07 +0100 Subject: [PATCH 18/40] Added tests filters --- pkg/atmos/aws-component-helper/fixture.go | 11 +- pkg/atmos/aws-component-helper/shared.go | 28 +++++ pkg/atmos/aws-component-helper/shared_test.go | 107 ++++++++++++++++++ pkg/atmos/aws-component-helper/suite.go | 29 +++-- 4 files changed, 161 insertions(+), 14 deletions(-) create mode 100644 pkg/atmos/aws-component-helper/shared_test.go diff --git a/pkg/atmos/aws-component-helper/fixture.go b/pkg/atmos/aws-component-helper/fixture.go index ece7db3..8e625eb 100644 --- a/pkg/atmos/aws-component-helper/fixture.go +++ b/pkg/atmos/aws-component-helper/fixture.go @@ -23,6 +23,7 @@ var ( skipVendorDependencies = flag.Bool("skip-vendor", false, "skip vendor dependencies") skipTeardownFixtures = flag.Bool("skip-fixtures-teardown", false, "skip fixtures teardown") skipTeardown = flag.Bool("skip-teardown", false, "skip teardown") + matchSuiteAndTest = flag.String("match", "", "regular expression to select suite and tests to run") // runParallel = flag.Bool("parallel", false, "Run parallel") // forceNewSuite = flag.Bool("cth.force-new-suite", false, "force new suite") @@ -131,7 +132,7 @@ func (ts *Fixture) TearDown() { return } for i := len(ts.suites) - 1; i >= 0; i-- { - ts.suites[i].runTeardown(ts.t) + ts.suites[i].runTeardown() } if !*skipTmpDir && !*skipTeardownFixtures { err := os.RemoveAll(ts.TempDir) @@ -178,5 +179,11 @@ func (ts *Fixture) Suite(name string, f func(t *testing.T, suite *Suite)) { suite := NewSuite(ts.t, name, ts) ts.suites = append(ts.suites, suite) ts.suitesNames = append(ts.suitesNames, name) - f(ts.t, suite) + if ok, err := matchFilter(fmt.Sprintf("%s/%s", ts.t.Name(), suite.name)); ok { + ts.t.Run(name, func(t *testing.T) { + f(t, suite) + }) + } else { + require.NoError(ts.t, err) + } } diff --git a/pkg/atmos/aws-component-helper/shared.go b/pkg/atmos/aws-component-helper/shared.go index 0d4279e..daec2b6 100644 --- a/pkg/atmos/aws-component-helper/shared.go +++ b/pkg/atmos/aws-component-helper/shared.go @@ -4,6 +4,8 @@ import ( "fmt" "os" "path/filepath" + "regexp" + "strings" ) func copyDirectoryRecursively(srcDir string, destDir string) error { @@ -48,3 +50,29 @@ func parseListOutputTerraform(outputList []interface{}, key string) ([]string, e return list, nil } + +func matchFilter(name string) (bool, error) { + nameParts := strings.Split(name, "/") + + if len(nameParts) == 1 { + return false, fmt.Errorf("Invalid test name: %s. Should contains at least 1 '/'", name) + } + nameParts = nameParts[1:] + + matchParts := strings.Split(*matchSuiteAndTest, "/") + + partsCount := min(len(nameParts), len(matchParts)) + + for i := 0; i < partsCount; i++ { + fmt.Printf("Matching %s with %s\n", matchParts[i], nameParts[i]) + result, err := regexp.MatchString(matchParts[i], nameParts[i]) + if err != nil { + return false, err + } + if !result { + return false, nil + } + } + + return true, nil +} diff --git a/pkg/atmos/aws-component-helper/shared_test.go b/pkg/atmos/aws-component-helper/shared_test.go new file mode 100644 index 0000000..4207efd --- /dev/null +++ b/pkg/atmos/aws-component-helper/shared_test.go @@ -0,0 +1,107 @@ +package aws_component_helper + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMatchFilter(t *testing.T) { + t.Parallel() + t.Run("wrong", func(t *testing.T) { + matchRegexp := "" + matchSuiteAndTest = &matchRegexp + result, err := matchFilter("TestAcceptance") + assert.Error(t, err) + assert.False(t, result) + }) + + t.Run("default", func(t *testing.T) { + matchRegexp := "" + matchSuiteAndTest = &matchRegexp + result, err := matchFilter("TestAcceptance/default") + assert.NoError(t, err) + assert.True(t, result) + }) + + t.Run("suite", func(t *testing.T) { + matchRegexp := "default" + matchSuiteAndTest = &matchRegexp + result, err := matchFilter("TestAcceptance/default") + assert.NoError(t, err) + assert.True(t, result) + }) + + t.Run("all tests", func(t *testing.T) { + matchRegexp := "default" + matchSuiteAndTest = &matchRegexp + result, err := matchFilter("TestAcceptance/default/test1") + assert.NoError(t, err) + assert.True(t, result) + }) + + t.Run("one test tests", func(t *testing.T) { + matchRegexp := "default/test1" + matchSuiteAndTest = &matchRegexp + result, err := matchFilter("TestAcceptance/default/test1") + assert.NoError(t, err) + assert.True(t, result) + + result, err = matchFilter("TestAcceptance/default/test2") + assert.NoError(t, err) + assert.False(t, result) + }) + + t.Run("multilevel subtests", func(t *testing.T) { + matchRegexp := "default/test1" + matchSuiteAndTest = &matchRegexp + result, err := matchFilter("TestAcceptance/default/test1/subtest1") + assert.NoError(t, err) + assert.True(t, result) + + result, err = matchFilter("TestAcceptance/default/test1/subtest2") + assert.NoError(t, err) + assert.True(t, result) + + result, err = matchFilter("TestAcceptance/default/test2/subtest1") + assert.NoError(t, err) + assert.False(t, result) + + result, err = matchFilter("TestAcceptance/default/test2/subtest2") + assert.NoError(t, err) + assert.False(t, result) + }) + + t.Run("filter longer then test", func(t *testing.T) { + matchRegexp := "default/test1/subtest1" + matchSuiteAndTest = &matchRegexp + result, err := matchFilter("TestAcceptance/default/test1") + assert.NoError(t, err) + assert.True(t, result) + + result, err = matchFilter("TestAcceptance/default/test2/subtest1") + assert.NoError(t, err) + assert.False(t, result) + }) + + t.Run("regexp", func(t *testing.T) { + matchRegexp := "default/.*/subtest1" + matchSuiteAndTest = &matchRegexp + result, err := matchFilter("TestAcceptance/default/test1/subtest1") + assert.NoError(t, err) + assert.True(t, result) + + result, err = matchFilter("TestAcceptance/default/test1/subtest2") + assert.NoError(t, err) + assert.False(t, result) + + result, err = matchFilter("TestAcceptance/default/test2/subtest1") + assert.NoError(t, err) + assert.True(t, result) + + result, err = matchFilter("TestAcceptance/default/test2/subtest2") + assert.NoError(t, err) + assert.False(t, result) + }) + +} diff --git a/pkg/atmos/aws-component-helper/suite.go b/pkg/atmos/aws-component-helper/suite.go index 55d0c5c..6132953 100644 --- a/pkg/atmos/aws-component-helper/suite.go +++ b/pkg/atmos/aws-component-helper/suite.go @@ -90,29 +90,29 @@ func (ts *Suite) AddDependency(componentName string, stackName string) { component := NewAtmosComponent(componentName, stackName, nil) ts.dependencies = append(ts.dependencies, component) ts.teardown = append(ts.teardown, &teadDown{component: component, callback: nil}) - ts.getAtmos(ts.t).Deploy(component) + ts.getAtmos().Deploy(component) } -func (ts *Suite) getAtmos(t *testing.T) *Atmos { +func (ts *Suite) getAtmos() *Atmos { return NewAtmos(ts.t, ts.getAtmosOptions(map[string]interface{}{})) } -func (ts *Suite) getTestAtmos(t *testing.T) *Atmos { - return ts.getAtmos(ts.t) +func (ts *Suite) getTestAtmos() *Atmos { + return ts.getAtmos() } -func (ts *Suite) runTeardown(t *testing.T) { +func (ts *Suite) runTeardown() { if *skipTeardown { fmt.Printf("Skip teardown suite %s\n", ts.name) fmt.Printf("Suite %s preserve states %s\n", ts.name, ts.StateDir()) return } - atm := ts.getAtmos(t) + atm := ts.getAtmos() var f *teadDown for i := len(ts.teardown) - 1; i >= 0; i-- { f = ts.teardown[i] if f.callback != nil { - (*f.callback)(t, atm) + (*f.callback)(ts.t, atm) } if f.component != nil { atm.Destroy(f.component) @@ -132,7 +132,7 @@ func (ts *Suite) Setup(t *testing.T, f func(t *testing.T, atm *Atmos)) { fmt.Printf("Skip suite %s setup callback\n", ts.name) return } - atm := ts.getAtmos(ts.t) + atm := ts.getAtmos() f(t, atm) } @@ -145,10 +145,15 @@ func (ts *Suite) Test(t *testing.T, name string, f func(t *testing.T, atm *Atmos fmt.Printf("Skip test %s/%s\n", ts.name, name) return } - atm := ts.getTestAtmos(ts.t) - t.Run(name, func(t *testing.T) { - f(t, atm) - }) + atm := ts.getTestAtmos() + testRunName := fmt.Sprintf("%s/%s", t.Name(), name) + if ok, err := matchFilter(testRunName); ok { + t.Run(name, func(t *testing.T) { + f(t, atm) + }) + } else { + require.NoError(t, err) + } } func (ts *Suite) getAtmosOptions(vars map[string]interface{}) *atmos.Options { From 2605182e7226cb7e35796cc7dfe2cde654c8b4b3 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 30 Dec 2024 02:32:01 +0100 Subject: [PATCH 19/40] Clenup testing framework --- .../aws-component-helper/acceptance_test.go | 6 - pkg/atmos/aws-component-helper/atmos.go | 136 ++------ .../aws-component-helper/atmos_component.go | 33 +- pkg/atmos/aws-component-helper/cli.go | 44 --- pkg/atmos/aws-component-helper/cli_test.go | 306 ------------------ pkg/atmos/aws-component-helper/const.go | 3 - pkg/atmos/aws-component-helper/fixture.go | 29 +- .../aws-component-helper/fixture_test.go | 3 + .../aws-component-helper/setup_component.go | 35 -- .../setup_component_test.go | 112 ------- .../aws-component-helper/setup_test_suite.go | 131 -------- .../setup_test_suite_test.go | 106 ------ pkg/atmos/aws-component-helper/shared.go | 52 ++- pkg/atmos/aws-component-helper/shared_test.go | 27 ++ pkg/atmos/aws-component-helper/state.go | 70 ++++ pkg/atmos/aws-component-helper/state_test.go | 82 +++++ pkg/atmos/aws-component-helper/suite.go | 77 ++--- .../aws-component-helper/tear_down_suite.go | 21 -- .../aws-component-helper/test_component.go | 97 ------ .../test_component_test.go | 15 - pkg/atmos/aws-component-helper/test_suite.go | 274 ---------------- .../test/fixtures/stacks/orgs/test/main.yaml | 4 +- .../foo.planfile | Bin 0 -> 2086 bytes .../terraform-basic-configuration/main.tf | 5 + .../terraform/terraform-no-error/main.tf | 5 + 25 files changed, 312 insertions(+), 1361 deletions(-) delete mode 100644 pkg/atmos/aws-component-helper/cli.go delete mode 100644 pkg/atmos/aws-component-helper/cli_test.go delete mode 100644 pkg/atmos/aws-component-helper/const.go delete mode 100644 pkg/atmos/aws-component-helper/setup_component.go delete mode 100644 pkg/atmos/aws-component-helper/setup_component_test.go delete mode 100644 pkg/atmos/aws-component-helper/setup_test_suite.go delete mode 100644 pkg/atmos/aws-component-helper/setup_test_suite_test.go create mode 100644 pkg/atmos/aws-component-helper/state.go create mode 100644 pkg/atmos/aws-component-helper/state_test.go delete mode 100644 pkg/atmos/aws-component-helper/tear_down_suite.go delete mode 100644 pkg/atmos/aws-component-helper/test_component.go delete mode 100644 pkg/atmos/aws-component-helper/test_component_test.go delete mode 100644 pkg/atmos/aws-component-helper/test_suite.go create mode 100644 test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/foo.planfile diff --git a/pkg/atmos/aws-component-helper/acceptance_test.go b/pkg/atmos/aws-component-helper/acceptance_test.go index 53b518c..bba8e4a 100644 --- a/pkg/atmos/aws-component-helper/acceptance_test.go +++ b/pkg/atmos/aws-component-helper/acceptance_test.go @@ -44,11 +44,5 @@ func TestAcceptance(t *testing.T) { assert.Equal(t, atm.Output(component, "test"), "Hello, World") assert.Equal(t, atm.OutputList(component, "test_list"), []string{"a", "b", "c"}) }) - - // suite.Test(t, "public-subnets", func(t *testing.T, atm *Atmos) { - // component := atm.GetAndDeploy("vpc/full", "default-test", nil) - // defer atm.Destroy(component) - // }) }) - } diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index 6f4eb2b..53f948a 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -11,6 +11,7 @@ import ( "dario.cat/mergo" "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -25,12 +26,14 @@ var ( type Atmos struct { t *testing.T options *atmos.Options + state *State } -func NewAtmos(t *testing.T, options *atmos.Options) *Atmos { +func NewAtmos(t *testing.T, state *State, options *atmos.Options) *Atmos { return &Atmos{ t: t, options: options, + state: state, } } @@ -47,9 +50,7 @@ func (ts *Atmos) GetAndDestroy(componentName string, stackName string, vars map[ } func (ts *Atmos) Deploy(component *AtmosComponent) { - options := ts.getAtmosOptions(component.Vars) - options.Component = component.ComponentName - options.Stack = component.StackName + options := ts.getAtmosOptions(component) defer os.RemoveAll(options.AtmosBasePath) err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) require.NoError(ts.t, err) @@ -58,12 +59,10 @@ func (ts *Atmos) Deploy(component *AtmosComponent) { } func (ts *Atmos) Destroy(component *AtmosComponent) { - options := ts.getAtmosOptions(component.Vars) - options.Component = component.ComponentName - options.Stack = component.StackName + options := ts.getAtmosOptions(component) defer os.RemoveAll(options.AtmosBasePath) err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) - require.NoError(ts.t, err) + assert.NoError(ts.t, err) atmosDestroy(ts.t, options) } @@ -71,9 +70,7 @@ func (ts *Atmos) loadOutputAll(component *AtmosComponent) { if component.output != nil { return } - options := ts.getAtmosOptions(nil) - options.Component = component.ComponentName - options.Stack = component.StackName + options := ts.getAtmosOptions(component) defer os.RemoveAll(options.AtmosBasePath) err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) require.NoError(ts.t, err) @@ -112,10 +109,13 @@ func (ts *Atmos) OutputList(component *AtmosComponent, key string) []string { return []string{} } -func (ts *Atmos) getAtmosOptions(vars map[string]interface{}) *atmos.Options { +func (ts *Atmos) getAtmosOptions(component *AtmosComponent) *atmos.Options { result, err := ts.options.Clone() require.NoError(ts.t, err) + result.Component = component.ComponentName + result.Stack = component.StackName + randID := random.UniqueId() randomId := strings.ToLower(randID) @@ -128,6 +128,8 @@ func (ts *Atmos) getAtmosOptions(vars map[string]interface{}) *atmos.Options { envvars := map[string]string{ "ATMOS_BASE_PATH": result.AtmosBasePath, "ATMOS_CLI_CONFIG_PATH": result.AtmosBasePath, + "TEST_SUITE_NAME": ts.state.NamespaceDir(), + "TEST_STATE_DIR": ts.state.BaseDir(), } err = mergo.Merge(&envvars, resultEnvVars) @@ -135,108 +137,16 @@ func (ts *Atmos) getAtmosOptions(vars map[string]interface{}) *atmos.Options { result.EnvVars = envvars - if vars != nil { - err = mergo.Merge(&result.Vars, vars) - require.NoError(ts.t, err) + if _, ok := result.Vars["attributes"]; !ok { + result.Vars["attributes"] = []string{component.RandomIdentifier} + } + if component.Vars != nil { + err = mergo.Merge(&result.Vars, component.Vars) + require.NoError(ts.t, err) } - return result -} + atmosOptions := atmos.WithDefaultRetryableErrors(ts.t, result) -//func GetAtmosOptions(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) *atmos.Options { -// mergedVars := map[string]interface{}{ -// "attributes": []string{suite.RandomIdentifier}, -// "region": suite.AwsRegion, -// } -// -// // If we are not skipping the nuking of the test account, add the default tags -// if !suite.SkipNukeTestAccount { -// nukeVars := map[string]interface{}{ -// "default_tags": map[string]string{ -// "CreatedByTerratestRun": suite.RandomIdentifier, -// }, -// } -// -// err := mergo.Merge(&mergedVars, nukeVars) -// require.NoError(t, err) -// } -// -// // Merge in any additional vars passed in -// err := mergo.Merge(&mergedVars, vars) -// require.NoError(t, err) -// -// atmosOptions := atmos.WithDefaultRetryableErrors(t, &atmos.Options{ -// AtmosBasePath: suite.TempDir, -// ComponentName: componentName, -// StackName: stackName, -// NoColor: true, -// BackendConfig: map[string]interface{}{ -// "workspace_key_prefix": strings.Join([]string{suite.RandomIdentifier, stackName}, "-"), -// }, -// Vars: mergedVars, -// }) -// return atmosOptions -//} -// -//func deployDependencies(t *testing.T, suite *TestSuite) error { -// for _, dependency := range suite.Dependencies { -// _, _, err := DeployComponent(t, suite, dependency.ComponentName, dependency.StackName, map[string]interface{}{}) -// if err != nil { -// return err -// } -// } -// -// return nil -//} -// -//func destroyDependencies(t *testing.T, suite *TestSuite) error { -// // iterate over dependencies in reverse order and destroy them -// for i := len(suite.Dependencies) - 1; i >= 0; i-- { -// _, _, err := DestroyComponent(t, suite, suite.Dependencies[i].ComponentName, suite.Dependencies[i].StackName, map[string]interface{}{}) -// if err != nil { -// return err -// } -// } -// return nil -//} -// -//func DeployComponent(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) (*atmos.Options, string, error) { -// options := GetAtmosOptions(t, suite, componentName, stackName, vars) -// out, err := atmos.ApplyE(t, options) -// -// return options, out, err -//} - -//func verifyEnabledFlag(t *testing.T, suite *TestSuite, componentName string, stackName string) (*atmos.Options, error) { -// vars := map[string]interface{}{ -// "enabled": false, -// } -// options := GetAtmosOptions(t, suite, componentName, stackName, vars) -// -// exitCode, err := atmos.PlanExitCodeE(t, options) -// -// if err != nil { -// return options, err -// } -// -// if exitCode != 0 { -// return options, fmt.Errorf("running atmos terraform plan with enabled flag set to false resulted in resource changes") -// } -// -// return options, nil -//} - -//func DestroyComponent(t *testing.T, suite *TestSuite, componentName string, stackName string, vars map[string]interface{}) (*atmos.Options, string, error) { -// options := GetAtmosOptions(t, suite, componentName, stackName, vars) -// out, err := atmos.DestroyE(t, options) -// -// return options, out, err -//} -// -//func vendorDependencies(t *testing.T, suite *TestSuite) error { -// options := GetAtmosOptions(t, suite, "", "", map[string]interface{}{}) -// _, err := atmos.VendorPullE(t, options) -// -// return err -//} + return atmosOptions +} diff --git a/pkg/atmos/aws-component-helper/atmos_component.go b/pkg/atmos/aws-component-helper/atmos_component.go index 29e4d77..ca9f694 100644 --- a/pkg/atmos/aws-component-helper/atmos_component.go +++ b/pkg/atmos/aws-component-helper/atmos_component.go @@ -22,6 +22,7 @@ type AtmosComponent struct { func NewAtmosComponent(component string, stack string, vars map[string]interface{}) *AtmosComponent { randID := random.UniqueId() randomId := strings.ToLower(randID) + return &AtmosComponent{ RandomIdentifier: randomId, ComponentName: component, @@ -29,35 +30,3 @@ func NewAtmosComponent(component string, stack string, vars map[string]interface Vars: vars, } } - -// func (ac *AtmosComponent) getAtmosOptions(options *atmos.Options, vars map[string]interface{}) *atmos.Options { -// result := &atmos.Options{} -// if options != nil { -// result, _ = options.Clone() -// } - -// // currentTFDataDir := ".terraform" -// // if value, ok := options.EnvVars["TF_DATA_DIR"]; ok { -// // currentTFDataDir = value -// // } -// // stack := strings.Replace(ac.StackName, "/", "-", -1) -// // name := strings.Replace(ac.ComponentName, "/", "-", -1) -// // envvars := map[string]string{ -// // // We need to split the TF_DATA_DIR for parallel suites mode -// // "TF_DATA_DIR": filepath.Join(currentTFDataDir, fmt.Sprintf("component-%s", ac.RandomIdentifier)), -// // "TEST_WORKSPACE_TEMPLATE": fmt.Sprintf("%s-%s-%s", stack, name, ac.RandomIdentifier), -// // } - -// // err := mergo.Merge(&result.Vars, ac.vars) -// // require.NoError(t, err) - -// // // Merge in any additional vars passed in -// // err = mergo.Merge(&result.Vars, vars) -// // require.NoError(t, err) - -// // result.Component = ac.ComponentName -// // result.Stack = ac.StackName - -// atmosOptions := atmos.WithDefaultRetryableErrors(, result) -// return atmosOptions -// } diff --git a/pkg/atmos/aws-component-helper/cli.go b/pkg/atmos/aws-component-helper/cli.go deleted file mode 100644 index 8ba0d74..0000000 --- a/pkg/atmos/aws-component-helper/cli.go +++ /dev/null @@ -1,44 +0,0 @@ -package aws_component_helper - -//func parseCLIArgs(ts *TestSuite) *TestSuite { -// forceNewSuite := flag.Bool("force-new-suite", false, "force new suite") -// suiteIndex := flag.Int("suite-index", -1, "suite index") -// skipAwsNuke := flag.Bool("skip-aws-nuke", ts.SkipNukeTestAccount, "skip aws nuke") -// skipDeployDependencies := flag.Bool("skip-deploy-deps", ts.SkipDeployDependencies, "skip deploy dependencies") -// skipDestroyDependencies := flag.Bool("skip-destroy-deps", ts.SkipDestroyDependencies, "skip destroy dependencies") -// skipSetupComponentUnderTest := flag.Bool("skip-setup-cut", ts.SkipSetupComponentUnderTest, "skip setup component under test") -// skipDeployComponentUnderTest := flag.Bool("skip-deploy-cut", ts.SkipDeployComponentUnderTest, "skip deploy component under test") -// skipDestroyComponentUnderTest := flag.Bool("skip-destroy-cut", ts.SkipDestroyComponentUnderTest, "skip destroy component under test") -// skipTeardownTestSuite := flag.Bool("skip-teardown", ts.SkipTeardownTestSuite, "skip test suite teardown") -// skipVendorDependencies := flag.Bool("skip-vendor", ts.SkipVendorDependencies, "skip vendor dependencies") -// skipVerifyEnabledFlag := flag.Bool("skip-verify-enabled-flag", ts.SkipVerifyEnabledFlag, "skip verify enabled flag") -// skipTests := flag.Bool("skip-tests", ts.SkipTests, "skip tests") -// -// flag.Parse() -// -// ts.ForceNewSuite = *forceNewSuite -// ts.Index = *suiteIndex -// ts.SkipNukeTestAccount = *skipAwsNuke -// ts.SkipDeployDependencies = *skipDeployDependencies -// ts.SkipDestroyDependencies = *skipDestroyDependencies -// ts.SkipSetupComponentUnderTest = *skipSetupComponentUnderTest -// ts.SkipDeployComponentUnderTest = *skipDeployComponentUnderTest -// ts.SkipDestroyComponentUnderTest = *skipDestroyComponentUnderTest -// ts.SkipTeardownTestSuite = *skipTeardownTestSuite -// ts.SkipVendorDependencies = *skipVendorDependencies -// ts.SkipVerifyEnabledFlag = *skipVerifyEnabledFlag -// ts.SkipTests = *skipTests -// return ts -//} -// -//func skipDestroyDependencies(ts *TestSuite) bool { -// return ts.SkipDestroyDependencies || ts.SkipDestroyComponentUnderTest -//} -// -//func skipTeardownTestSuite(ts *TestSuite) bool { -// return ts.SkipTeardownTestSuite || skipDestroyDependencies(ts) -//} -// -//func skipNukeTestAccount(ts *TestSuite) bool { -// return ts.SkipNukeTestAccount || skipTeardownTestSuite(ts) -//} diff --git a/pkg/atmos/aws-component-helper/cli_test.go b/pkg/atmos/aws-component-helper/cli_test.go deleted file mode 100644 index a290961..0000000 --- a/pkg/atmos/aws-component-helper/cli_test.go +++ /dev/null @@ -1,306 +0,0 @@ -package aws_component_helper - -// -//import ( -// "flag" -// "os" -// "testing" -// -// "github.com/stretchr/testify/assert" -//) -// -//func TestParseCLIArgs(t *testing.T) { -// // Save original args and restore after test -// originalArgs := os.Args -// defer func() { os.Args = originalArgs }() -// -// tests := []struct { -// name string -// args []string -// initial *TestSuite -// expected *TestSuite -// }{ -// { -// name: "default values not changed when no flags provided", -// args: []string{"prog"}, -// initial: &TestSuite{ -// SkipNukeTestAccount: false, -// SkipDeployDependencies: false, -// SkipDestroyDependencies: false, -// SkipSetupComponentUnderTest: false, -// SkipDeployComponentUnderTest: false, -// SkipDestroyComponentUnderTest: false, -// SkipTeardownTestSuite: false, -// SkipVendorDependencies: false, -// SkipVerifyEnabledFlag: false, -// SkipTests: false, -// ForceNewSuite: false, -// Index: -1, -// }, -// expected: &TestSuite{ -// SkipNukeTestAccount: false, -// SkipDeployDependencies: false, -// SkipDestroyDependencies: false, -// SkipSetupComponentUnderTest: false, -// SkipDeployComponentUnderTest: false, -// SkipDestroyComponentUnderTest: false, -// SkipTeardownTestSuite: false, -// SkipVendorDependencies: false, -// SkipVerifyEnabledFlag: false, -// SkipTests: false, -// ForceNewSuite: false, -// Index: -1, -// }, -// }, -// { -// name: "all skip flags set to true", -// args: []string{"prog", -// "-skip-aws-nuke", -// "-skip-deploy-deps", -// "-skip-destroy-deps", -// "-skip-setup-cut", -// "-skip-deploy-cut", -// "-skip-destroy-cut", -// "-skip-teardown", -// "-skip-vendor", -// "-skip-verify-enabled-flag", -// "-skip-tests", -// }, -// initial: &TestSuite{}, -// expected: &TestSuite{ -// SkipNukeTestAccount: true, -// SkipDeployDependencies: true, -// SkipDestroyDependencies: true, -// SkipSetupComponentUnderTest: true, -// SkipDeployComponentUnderTest: true, -// SkipDestroyComponentUnderTest: true, -// SkipTeardownTestSuite: true, -// SkipVendorDependencies: true, -// SkipVerifyEnabledFlag: true, -// SkipTests: true, -// ForceNewSuite: false, -// Index: -1, -// }, -// }, -// { -// name: "force new suite and suite index", -// args: []string{"prog", -// "-force-new-suite", -// "-suite-index=5", -// }, -// initial: &TestSuite{}, -// expected: &TestSuite{ -// ForceNewSuite: true, -// Index: 5, -// }, -// }, -// { -// name: "initial values respected when not overridden", -// args: []string{"prog", -// "-skip-aws-nuke", -// "-skip-deploy-deps", -// }, -// initial: &TestSuite{ -// SkipDestroyDependencies: true, -// SkipSetupComponentUnderTest: true, -// SkipDeployComponentUnderTest: true, -// SkipDestroyComponentUnderTest: true, -// SkipTeardownTestSuite: true, -// SkipVendorDependencies: true, -// SkipVerifyEnabledFlag: true, -// SkipTests: true, -// }, -// expected: &TestSuite{ -// SkipNukeTestAccount: true, -// SkipDeployDependencies: true, -// SkipDestroyDependencies: true, -// SkipSetupComponentUnderTest: true, -// SkipDeployComponentUnderTest: true, -// SkipDestroyComponentUnderTest: true, -// SkipTeardownTestSuite: true, -// SkipVendorDependencies: true, -// SkipVerifyEnabledFlag: true, -// SkipTests: true, -// ForceNewSuite: false, -// Index: -1, -// }, -// }, -// } -// -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// // Reset flags for each test -// flag.CommandLine = flag.NewFlagSet(tt.args[0], flag.ExitOnError) -// os.Args = tt.args -// -// result := parseCLIArgs(tt.initial) -// assert.Equal(t, tt.expected, result) -// }) -// } -//} -// -//func TestSkipDestroyDependencies(t *testing.T) { -// tests := []struct { -// name string -// ts *TestSuite -// expected bool -// }{ -// { -// name: "both flags false", -// ts: &TestSuite{ -// SkipDestroyDependencies: false, -// SkipDestroyComponentUnderTest: false, -// }, -// expected: false, -// }, -// { -// name: "SkipDestroyDependencies true", -// ts: &TestSuite{ -// SkipDestroyDependencies: true, -// SkipDestroyComponentUnderTest: false, -// }, -// expected: true, -// }, -// { -// name: "SkipDestroyComponentUnderTest true", -// ts: &TestSuite{ -// SkipDestroyDependencies: false, -// SkipDestroyComponentUnderTest: true, -// }, -// expected: true, -// }, -// { -// name: "both flags true", -// ts: &TestSuite{ -// SkipDestroyDependencies: true, -// SkipDestroyComponentUnderTest: true, -// }, -// expected: true, -// }, -// } -// -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// result := skipDestroyDependencies(tt.ts) -// assert.Equal(t, tt.expected, result) -// }) -// } -//} -// -//func TestSkipTeardownTestSuite(t *testing.T) { -// tests := []struct { -// name string -// ts *TestSuite -// expected bool -// }{ -// { -// name: "all flags false", -// ts: &TestSuite{ -// SkipTeardownTestSuite: false, -// SkipDestroyDependencies: false, -// SkipDestroyComponentUnderTest: false, -// }, -// expected: false, -// }, -// { -// name: "SkipTeardownTestSuite true", -// ts: &TestSuite{ -// SkipTeardownTestSuite: true, -// SkipDestroyDependencies: false, -// SkipDestroyComponentUnderTest: false, -// }, -// expected: true, -// }, -// { -// name: "SkipDestroyDependencies true", -// ts: &TestSuite{ -// SkipTeardownTestSuite: false, -// SkipDestroyDependencies: true, -// SkipDestroyComponentUnderTest: false, -// }, -// expected: true, -// }, -// { -// name: "SkipDestroyComponentUnderTest true", -// ts: &TestSuite{ -// SkipTeardownTestSuite: false, -// SkipDestroyDependencies: false, -// SkipDestroyComponentUnderTest: true, -// }, -// expected: true, -// }, -// } -// -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// result := skipTeardownTestSuite(tt.ts) -// assert.Equal(t, tt.expected, result) -// }) -// } -//} -// -//func TestSkipNukeTestAccount(t *testing.T) { -// tests := []struct { -// name string -// ts *TestSuite -// expected bool -// }{ -// { -// name: "all flags false", -// ts: &TestSuite{ -// SkipNukeTestAccount: false, -// SkipTeardownTestSuite: false, -// SkipDestroyDependencies: false, -// SkipDestroyComponentUnderTest: false, -// }, -// expected: false, -// }, -// { -// name: "SkipNukeTestAccount true", -// ts: &TestSuite{ -// SkipNukeTestAccount: true, -// SkipTeardownTestSuite: false, -// SkipDestroyDependencies: false, -// SkipDestroyComponentUnderTest: false, -// }, -// expected: true, -// }, -// { -// name: "SkipTeardownTestSuite true", -// ts: &TestSuite{ -// SkipNukeTestAccount: false, -// SkipTeardownTestSuite: true, -// SkipDestroyDependencies: false, -// SkipDestroyComponentUnderTest: false, -// }, -// expected: true, -// }, -// { -// name: "SkipDestroyDependencies true", -// ts: &TestSuite{ -// SkipNukeTestAccount: false, -// SkipTeardownTestSuite: false, -// SkipDestroyDependencies: true, -// SkipDestroyComponentUnderTest: false, -// }, -// expected: true, -// }, -// { -// name: "SkipDestroyComponentUnderTest true", -// ts: &TestSuite{ -// SkipNukeTestAccount: false, -// SkipTeardownTestSuite: false, -// SkipDestroyDependencies: false, -// SkipDestroyComponentUnderTest: true, -// }, -// expected: true, -// }, -// } -// -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// result := skipNukeTestAccount(tt.ts) -// assert.Equal(t, tt.expected, result) -// }) -// } -//} diff --git a/pkg/atmos/aws-component-helper/const.go b/pkg/atmos/aws-component-helper/const.go deleted file mode 100644 index 9ab49d1..0000000 --- a/pkg/atmos/aws-component-helper/const.go +++ /dev/null @@ -1,3 +0,0 @@ -package aws_component_helper - -const testSuiteFile = "test_suite.json" diff --git a/pkg/atmos/aws-component-helper/fixture.go b/pkg/atmos/aws-component-helper/fixture.go index 8e625eb..5649e21 100644 --- a/pkg/atmos/aws-component-helper/fixture.go +++ b/pkg/atmos/aws-component-helper/fixture.go @@ -48,6 +48,7 @@ type Fixture struct { SourceDir string TempDir string FixturesPath string + State *State suites []*Suite suitesNames []string } @@ -59,11 +60,14 @@ func NewFixture(t *testing.T, sourceDir string, awsRegion string, fixturesDir st randID := random.UniqueId() randomId := strings.ToLower(randID) - tmpdir := filepath.Join(os.TempDir(), "test-suites-"+randomId) + tmpdir := filepath.Join(os.TempDir(), "fixtures-"+randomId) realSourcePath, err := filepath.Abs(sourceDir) require.NoError(t, err) + state_namespace := strings.ReplaceAll(filepath.Join(t.Name(), fixturesDir), "/", "-") + state := NewState(state_namespace, filepath.Join(realSourcePath, "state")) + suites := &Fixture{ t: t, RandomIdentifier: randomId, @@ -74,6 +78,7 @@ func NewFixture(t *testing.T, sourceDir string, awsRegion string, fixturesDir st AwsRegion: awsRegion, suites: []*Suite{}, suitesNames: []string{}, + State: state, } return suites @@ -91,14 +96,6 @@ func (ts *Fixture) FixtureDir() string { return filepath.Join(ts.WorkDir(), ts.FixturesPath) } -func (ts *Fixture) StateDir() string { - return "" -} - -func (ts *Fixture) GlobalStateDir() string { - return filepath.Join(ts.WorkDir(), "state") -} - func (ts *Fixture) SetUp(options *atmos.Options) { suitesOptions := ts.getAtmosOptions(options, map[string]interface{}{}) if !*skipTmpDir { @@ -119,7 +116,7 @@ func (ts *Fixture) SetUp(options *atmos.Options) { fmt.Println("Skip Vendor Pull") } - err := createDir(ts.WorkDir(), "state") + err := ts.State.SetUp() require.NoError(ts.t, err) err = createDir(ts.WorkDir(), ".cache") @@ -138,6 +135,8 @@ func (ts *Fixture) TearDown() { err := os.RemoveAll(ts.TempDir) require.NoError(ts.t, err) } + err := ts.State.Teardown() + require.NoError(ts.t, err) } func (ts *Fixture) getAtmosOptions(options *atmos.Options, vars map[string]interface{}) *atmos.Options { @@ -161,11 +160,11 @@ func (ts *Fixture) getAtmosOptions(options *atmos.Options, vars map[string]inter err := mergo.Merge(&result.EnvVars, envvars) require.NoError(ts.t, err) - suiteVars := map[string]interface{}{ + fixtureVars := map[string]interface{}{ "region": ts.AwsRegion, } - err = mergo.Merge(&result.Vars, suiteVars) + err = mergo.Merge(&result.Vars, fixtureVars) require.NoError(ts.t, err) err = mergo.Merge(&result.Vars, vars) @@ -176,10 +175,14 @@ func (ts *Fixture) getAtmosOptions(options *atmos.Options, vars map[string]inter func (ts *Fixture) Suite(name string, f func(t *testing.T, suite *Suite)) { require.NotContains(ts.t, ts.suitesNames, name, "Suite %s already exists", name) + suite := NewSuite(ts.t, name, ts) + ts.suites = append(ts.suites, suite) ts.suitesNames = append(ts.suitesNames, name) - if ok, err := matchFilter(fmt.Sprintf("%s/%s", ts.t.Name(), suite.name)); ok { + + suiteRunName := fmt.Sprintf("%s/%s", ts.t.Name(), suite.name) + if ok, err := matchFilter(suiteRunName); ok { ts.t.Run(name, func(t *testing.T) { f(t, suite) }) diff --git a/pkg/atmos/aws-component-helper/fixture_test.go b/pkg/atmos/aws-component-helper/fixture_test.go index 3c06f73..99e57d8 100644 --- a/pkg/atmos/aws-component-helper/fixture_test.go +++ b/pkg/atmos/aws-component-helper/fixture_test.go @@ -79,6 +79,9 @@ func TestFixtureCreate(t *testing.T) { componentTestSuites := NewFixture(t, testFolder, "us-west-2", atmosExamplePath) assert.Equal(t, componentTestSuites.SourceDir, testFolder) + + defer componentTestSuites.TearDown() + componentTestSuites.SetUp(&atmos.Options{}) } func TestFixtureSuitesRun(t *testing.T) { diff --git a/pkg/atmos/aws-component-helper/setup_component.go b/pkg/atmos/aws-component-helper/setup_component.go deleted file mode 100644 index 664b948..0000000 --- a/pkg/atmos/aws-component-helper/setup_component.go +++ /dev/null @@ -1,35 +0,0 @@ -package aws_component_helper - -//func setupComponentUnderTest(ts *TestSuite) error { -// err := createComponentDir(ts) -// if err != nil { -// return err -// } -// -// err = copyComponentSrcToTempDir(ts) -// if err != nil { -// return err -// } -// return nil -//} - -//func copyComponentSrcToTempDir(ts *TestSuite) error { -// -// destDir := filepath.Join(ts.TempDir, "components", "terraform", ts.ComponentName) -// fmt.Println("copying contents of", ts.ComponentSrcPath, "to", destDir) -// err := copyDirectoryRecursively(ts.ComponentSrcPath, destDir) -// if err != nil { -// return err -// } -// -// return nil -//} -// -//func createComponentDir(ts *TestSuite) error { -// destDir := filepath.Join(ts.TempDir, "components", "terraform", ts.ComponentName) -// err := os.MkdirAll(destDir, 0777) -// if err != nil { -// return err -// } -// return nil -//} diff --git a/pkg/atmos/aws-component-helper/setup_component_test.go b/pkg/atmos/aws-component-helper/setup_component_test.go deleted file mode 100644 index 1378dae..0000000 --- a/pkg/atmos/aws-component-helper/setup_component_test.go +++ /dev/null @@ -1,112 +0,0 @@ -package aws_component_helper - -//func TestSetupComponentUnderTest(t *testing.T) { -// // Create a temporary directory for testing -// tempDir, err := os.MkdirTemp("", "test-*") -// if err != nil { -// t.Fatalf("Failed to create temp dir: %v", err) -// } -// defer os.RemoveAll(tempDir) -// -// // Create a test source directory with some content -// srcDir, err := os.MkdirTemp("", "src-*") -// if err != nil { -// t.Fatalf("Failed to create source dir: %v", err) -// } -// defer os.RemoveAll(srcDir) -// -// // Create a test file in the source directory -// testFile := filepath.Join(srcDir, "test.tf") -// if err := os.WriteFile(testFile, []byte("test content"), 0666); err != nil { -// t.Fatalf("Failed to create test file: %v", err) -// } -// -// ts := &TestSuite{ -// TempDir: tempDir, -// ComponentName: "test-component", -// ComponentSrcPath: srcDir, -// } -// -// if err := setupComponentUnderTest(ts); err != nil { -// t.Errorf("setupComponentUnderTest failed: %v", err) -// } -// -// // Verify the component directory was created -// expectedDir := filepath.Join(tempDir, "components", "terraform", "test-component") -// if _, err := os.Stat(expectedDir); os.IsNotExist(err) { -// t.Error("Subject directory was not created") -// } -// -// // Verify the test file was copied -// expectedFile := filepath.Join(expectedDir, "test.tf") -// if _, err := os.Stat(expectedFile); os.IsNotExist(err) { -// t.Error("Test file was not copied") -// } -//} - -//func TestCreateComponentDir(t *testing.T) { -// tempDir, err := os.MkdirTemp("", "test-*") -// if err != nil { -// t.Fatalf("Failed to create temp dir: %v", err) -// } -// defer os.RemoveAll(tempDir) -// -// ts := &TestSuite{ -// TempDir: tempDir, -// ComponentName: "test-component", -// } -// -// if err := createComponentDir(ts); err != nil { -// t.Errorf("createComponentDir failed: %v", err) -// } -// -// expectedDir := filepath.Join(tempDir, "components", "terraform", "test-component") -// if _, err := os.Stat(expectedDir); os.IsNotExist(err) { -// t.Error("Subject directory was not created") -// } -//} -// -//func TestCopyComponentSrcToTempDir(t *testing.T) { -// // Create a temporary directory for testing -// tempDir, err := os.MkdirTemp("", "test-*") -// if err != nil { -// t.Fatalf("Failed to create temp dir: %v", err) -// } -// defer os.RemoveAll(tempDir) -// -// // Create a test source directory with some content -// srcDir, err := os.MkdirTemp("", "src-*") -// if err != nil { -// t.Fatalf("Failed to create source dir: %v", err) -// } -// defer os.RemoveAll(srcDir) -// -// // Create a test file in the source directory -// testFile := filepath.Join(srcDir, "test.tf") -// if err := os.WriteFile(testFile, []byte("test content"), 0666); err != nil { -// t.Fatalf("Failed to create test file: %v", err) -// } -// -// // Create the test suite before trying to use it -// ts := &TestSuite{ -// TempDir: tempDir, -// ComponentName: "test-component", -// ComponentSrcPath: srcDir, -// } -// -// // Create the component directory first -// componentDir := filepath.Join(tempDir, "components", "terraform", "test-component") -// if err := os.MkdirAll(componentDir, 0777); err != nil { -// t.Fatalf("Failed to create component dir: %v", err) -// } -// -// if err := copyComponentSrcToTempDir(ts); err != nil { -// t.Errorf("copyComponentSrcToTempDir failed: %v", err) -// } -// -// // Verify the test file was copied -// expectedFile := filepath.Join(componentDir, "test.tf") -// if _, err := os.Stat(expectedFile); os.IsNotExist(err) { -// t.Error("Test file was not copied") -// } -//} diff --git a/pkg/atmos/aws-component-helper/setup_test_suite.go b/pkg/atmos/aws-component-helper/setup_test_suite.go deleted file mode 100644 index eae774e..0000000 --- a/pkg/atmos/aws-component-helper/setup_test_suite.go +++ /dev/null @@ -1,131 +0,0 @@ -package aws_component_helper - -import ( - "context" - "fmt" - "os" - "path/filepath" - "runtime" - - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/service/sts" -) - -//func setupTestSuite(ts *TestSuite) error { -// err := createStateDir(ts.TempDir) -// if err != nil { -// return err -// } -// -// err = createTerraformComponentsDir(ts.TempDir) -// if err != nil { -// return err -// } -// -// err = copyDirectoryRecursively(ts.FixturesPath, ts.TempDir) -// if err != nil { -// return err -// } -// -// return nil -//} - -func createDir(tempDir string, name string) error { - dir := filepath.Join(tempDir, name) - if _, err := os.Stat(dir); os.IsNotExist(err) { - err := os.MkdirAll(dir, 0777) - return err - } - - return nil -} - -func createTerraformComponentsDir(tempDir string) error { - stateDir := filepath.Join(tempDir, "components", "terraform") - if _, err := os.Stat(stateDir); os.IsNotExist(err) { - err := os.MkdirAll(stateDir, 0777) - return err - } - - return nil -} - -func getTestName() (string, error) { - _, filename, _, ok := runtime.Caller(0) - - if !ok { - return "", fmt.Errorf("unable to get the test file name") - } - - testName := filepath.Base(filename[:len(filename)-3]) + "_" - return testName, nil -} - -func getAwsAccountId() (string, error) { - ctx := context.Background() - cfg, err := config.LoadDefaultConfig(ctx) - if err != nil { - return "", err - } - stsClient := sts.NewFromConfig(cfg) - identity, err := stsClient.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{}) - if err != nil { - return "", err - } - - return *identity.Account, nil -} - -//func readOrCreateTestSuiteFile(testSuite *TestSuite, testName string) (*TestSuite, error) { -// // Initialize TestSuites structure -// var testSuites TestSuites -// -// if data, err := os.ReadFile(testSuiteFile); err == nil { -// // File exists, try to unmarshal existing test suites -// if err := json.Unmarshal(data, &testSuites); err != nil { -// return &TestSuite{}, fmt.Errorf("failed to parse test_suites.json: %s", err.Error()) -// } -// -// if len(testSuites.Suites) > 1 && testSuite.Index < 0 { -// return &TestSuite{}, fmt.Errorf("test suite index is required when multiple test suites are present") -// } -// if testSuite.Index == -1 && len(testSuites.Suites) == 1 { -// testSuite.Index = 0 -// } -// if !testSuite.ForceNewSuite && len(testSuites.Suites) > 0 { -// return testSuites.Suites[testSuite.Index], nil -// } -// } -// -// // If we get here, either the file doesn't exist or we didn't find a matching suite -// fmt.Println("no matching test suite found for index", testSuite.Index, "creating new test suite") -// randID := random.UniqueId() -// testSuite.RandomIdentifier = strings.ToLower(randID) -// testSuite.Index = len(testSuites.Suites) // Set index to current length -// -// var err error -// testSuite.TempDir, err = os.MkdirTemp("", testName) -// if err != nil { -// return &TestSuite{}, err -// } -// fmt.Printf("running tests in %s\n", testSuite.TempDir) -// -// // Add new test suite to the collection -// testSuites.Suites = append(testSuites.Suites, testSuite) -// -// // Write updated test suites to file -// data, err := json.MarshalIndent(testSuites, "", " ") -// if err != nil { -// return &TestSuite{}, err -// } -// -// if err := os.WriteFile(testSuiteFile, data, 0644); err != nil { -// return &TestSuite{}, err -// } -// -// // os.Setenv("ATMOS_BASE_PATH", testSuite.TempDir) -// os.Setenv("ATMOS_CLI_CONFIG_PATH", testSuite.TempDir) -// os.Setenv("TEST_ACCOUNT_ID", testSuite.AwsAccountId) -// -// return testSuite, nil -//} diff --git a/pkg/atmos/aws-component-helper/setup_test_suite_test.go b/pkg/atmos/aws-component-helper/setup_test_suite_test.go deleted file mode 100644 index aecd027..0000000 --- a/pkg/atmos/aws-component-helper/setup_test_suite_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package aws_component_helper - -import ( - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" -) - -//func TestSetupTestSuite(t *testing.T) { -// // Create a temporary test suite -// ts := &TestSuite{ -// TempDir: t.TempDir(), -// FixturesPath: "testdata/fixtures", -// } -// -// // Create test fixtures -// err := os.MkdirAll(ts.FixturesPath, 0755) -// assert.NoError(t, err) -// defer os.RemoveAll(ts.FixturesPath) -// -// // Test setup -// err = setupTestSuite(ts) -// assert.NoError(t, err) -// -// // Verify directories were created -// stateDir := filepath.Join(ts.TempDir, "state") -// assert.DirExists(t, stateDir) -// -// componentsDir := filepath.Join(ts.TempDir, "components", "terraform") -// assert.DirExists(t, componentsDir) -//} - -func TestCreateStateDir(t *testing.T) { - tempDir := t.TempDir() - - err := createDir(tempDir, "state") - assert.NoError(t, err) - - stateDir := filepath.Join(tempDir, "state") - assert.DirExists(t, stateDir) -} - -func TestCreateTerraformComponentsDir(t *testing.T) { - tempDir := t.TempDir() - - err := createTerraformComponentsDir(tempDir) - assert.NoError(t, err) - - componentsDir := filepath.Join(tempDir, "components", "terraform") - assert.DirExists(t, componentsDir) -} - -func TestGetTestName(t *testing.T) { - testName, err := getTestName() - assert.NoError(t, err) - assert.Contains(t, testName, "setup_test_suite_") -} - -//func TestReadOrCreateTestSuiteFile(t *testing.T) { -// t.Run("create new test suite file", func(t *testing.T) { -// // Clean up any existing test suite file -// os.Remove(testSuiteFile) -// -// ts := &TestSuite{} -// testName := "test_" -// -// result, err := readOrCreateTestSuiteFile(ts, testName) -// assert.NoError(t, err) -// assert.NotEmpty(t, result.RandomIdentifier) -// assert.NotEmpty(t, result.TempDir) -// -// // Verify file was created -// assert.FileExists(t, testSuiteFile) -// -// // Clean up -// os.Remove(testSuiteFile) -// os.RemoveAll(result.TempDir) -// }) -// -// t.Run("read existing test suite file", func(t *testing.T) { -// // Create a test suite file -// existingTS := &TestSuites{ -// Suites: []*TestSuite{ -// { -// RandomIdentifier: "test-seed", -// TempDir: "test-dir", -// }, -// }, -// } -// data, err := json.MarshalIndent(existingTS, "", " ") -// assert.NoError(t, err) -// err = os.WriteFile(testSuiteFile, data, 0644) -// assert.NoError(t, err) -// -// // Test reading the file -// ts := &TestSuite{} -// result, err := readOrCreateTestSuiteFile(ts, "test_") -// assert.NoError(t, err) -// assert.Equal(t, existingTS.Suites[0].RandomIdentifier, result.RandomIdentifier) -// assert.Equal(t, existingTS.Suites[0].TempDir, result.TempDir) -// -// // Clean up -// os.Remove(testSuiteFile) -// }) -//} diff --git a/pkg/atmos/aws-component-helper/shared.go b/pkg/atmos/aws-component-helper/shared.go index daec2b6..832fa80 100644 --- a/pkg/atmos/aws-component-helper/shared.go +++ b/pkg/atmos/aws-component-helper/shared.go @@ -1,11 +1,16 @@ package aws_component_helper import ( + "context" "fmt" "os" "path/filepath" "regexp" + "runtime" "strings" + + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/sts" ) func copyDirectoryRecursively(srcDir string, destDir string) error { @@ -64,7 +69,6 @@ func matchFilter(name string) (bool, error) { partsCount := min(len(nameParts), len(matchParts)) for i := 0; i < partsCount; i++ { - fmt.Printf("Matching %s with %s\n", matchParts[i], nameParts[i]) result, err := regexp.MatchString(matchParts[i], nameParts[i]) if err != nil { return false, err @@ -76,3 +80,49 @@ func matchFilter(name string) (bool, error) { return true, nil } + +func createDir(tempDir string, name string) error { + dir := filepath.Join(tempDir, name) + if _, err := os.Stat(dir); os.IsNotExist(err) { + err := os.MkdirAll(dir, 0777) + return err + } + + return nil +} + +func createTerraformComponentsDir(tempDir string) error { + stateDir := filepath.Join(tempDir, "components", "terraform") + if _, err := os.Stat(stateDir); os.IsNotExist(err) { + err := os.MkdirAll(stateDir, 0777) + return err + } + + return nil +} + +func getTestName() (string, error) { + _, filename, _, ok := runtime.Caller(0) + + if !ok { + return "", fmt.Errorf("unable to get the test file name") + } + + testName := filepath.Base(filename[:len(filename)-3]) + "_" + return testName, nil +} + +func getAwsAccountId() (string, error) { + ctx := context.Background() + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + return "", err + } + stsClient := sts.NewFromConfig(cfg) + identity, err := stsClient.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{}) + if err != nil { + return "", err + } + + return *identity.Account, nil +} diff --git a/pkg/atmos/aws-component-helper/shared_test.go b/pkg/atmos/aws-component-helper/shared_test.go index 4207efd..17f5d65 100644 --- a/pkg/atmos/aws-component-helper/shared_test.go +++ b/pkg/atmos/aws-component-helper/shared_test.go @@ -1,6 +1,7 @@ package aws_component_helper import ( + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -105,3 +106,29 @@ func TestMatchFilter(t *testing.T) { }) } + +func TestCreateStateDir(t *testing.T) { + tempDir := t.TempDir() + + err := createDir(tempDir, "state") + assert.NoError(t, err) + + stateDir := filepath.Join(tempDir, "state") + assert.DirExists(t, stateDir) +} + +func TestCreateTerraformComponentsDir(t *testing.T) { + tempDir := t.TempDir() + + err := createTerraformComponentsDir(tempDir) + assert.NoError(t, err) + + componentsDir := filepath.Join(tempDir, "components", "terraform") + assert.DirExists(t, componentsDir) +} + +func TestGetTestName(t *testing.T) { + testName, err := getTestName() + assert.NoError(t, err) + assert.Contains(t, testName, "shared_") +} diff --git a/pkg/atmos/aws-component-helper/state.go b/pkg/atmos/aws-component-helper/state.go new file mode 100644 index 0000000..4725edf --- /dev/null +++ b/pkg/atmos/aws-component-helper/state.go @@ -0,0 +1,70 @@ +package aws_component_helper + +import ( + "flag" + "fmt" + "os" + "path/filepath" + "strings" +) + +var ( + preserveStates = flag.Bool("preserve-states", true, "preserve states") +) + +type State struct { + basepath string + namespace string +} + +func NewState(name, rootDir string) *State { + basePath := rootDir + return &State{ + basepath: basePath, + namespace: strings.ToLower(name), + } +} + +func (s *State) Fork(name string) (*State, error) { + namespace := fmt.Sprintf("%s.%s", s.namespace, name) + result := NewState(namespace, s.basepath) + if err := result.SetUp(); err != nil { + return nil, err + } + if err := copyDirectoryRecursively(s.CurrentDir(), result.CurrentDir()); err != nil { + return nil, err + } + return result, nil +} + +func (s *State) SetUp() error { + if err := createDir(s.basepath, ""); err != nil { + return err + } + + if err := createDir(s.CurrentDir(), ""); err != nil { + return err + } + return nil +} + +func (s *State) Teardown() error { + if *preserveStates { + fmt.Printf("Preserve states %s\n", s.namespace) + return nil + } else { + return os.RemoveAll(s.CurrentDir()) + } +} + +func (s *State) CurrentDir() string { + return filepath.Join(s.basepath, s.NamespaceDir()) +} + +func (s *State) NamespaceDir() string { + return fmt.Sprintf(".%s", s.namespace) +} + +func (s *State) BaseDir() string { + return s.basepath +} diff --git a/pkg/atmos/aws-component-helper/state_test.go b/pkg/atmos/aws-component-helper/state_test.go new file mode 100644 index 0000000..e31aff7 --- /dev/null +++ b/pkg/atmos/aws-component-helper/state_test.go @@ -0,0 +1,82 @@ +package aws_component_helper + +import ( + "os" + "path/filepath" + "strings" + "testing" + + "github.com/gruntwork-io/terratest/modules/files" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestState(t *testing.T) { + t.Parallel() + + t.Run("basic", func(t *testing.T) { + *preserveStates = false + + testFolder, err := files.CopyFolderToTemp("../../../", strings.Replace(t.Name(), "/", "-", -1), func(path string) bool { return true }) + require.NoError(t, err) + defer os.RemoveAll(testFolder) + + state := NewState("default", testFolder) + + assert.Equal(t, state.basepath, testFolder) + assert.Equal(t, state.namespace, "default") + + err = state.SetUp() + assert.NoError(t, err) + + assert.DirExists(t, state.basepath) + assert.DirExists(t, state.CurrentDir()) + + state.Teardown() + assert.NoDirExists(t, state.CurrentDir()) + assert.DirExists(t, state.basepath) + }) + + t.Run("fork", func(t *testing.T) { + *preserveStates = false + + testFolder, err := files.CopyFolderToTemp("../../../", strings.Replace(t.Name(), "/", "-", -1), func(path string) bool { return true }) + require.NoError(t, err) + defer os.RemoveAll(testFolder) + + state := NewState("default", testFolder) + + assert.Equal(t, state.basepath, testFolder) + assert.Equal(t, state.namespace, "default") + + err = state.SetUp() + assert.NoError(t, err) + + assert.DirExists(t, state.basepath) + assert.DirExists(t, state.CurrentDir()) + + file, err := os.CreateTemp(state.CurrentDir(), "tmpfile") + assert.FileExists(t, file.Name()) + + fileName := filepath.Base(file.Name()) + + forkState, err := state.Fork("fork") + require.NoError(t, err) + assert.NotEqual(t, forkState.CurrentDir(), state.CurrentDir()) + assert.DirExists(t, forkState.CurrentDir()) + assert.FileExists(t, filepath.Join(forkState.CurrentDir(), fileName)) + + assert.DirExists(t, state.basepath) + assert.DirExists(t, state.CurrentDir()) + state.Teardown() + assert.NoDirExists(t, state.CurrentDir()) + assert.DirExists(t, state.basepath) + + assert.DirExists(t, forkState.CurrentDir()) + assert.FileExists(t, filepath.Join(forkState.CurrentDir(), fileName)) + forkState.Teardown() + assert.NoDirExists(t, forkState.CurrentDir()) + assert.DirExists(t, forkState.basepath) + }) + +} diff --git a/pkg/atmos/aws-component-helper/suite.go b/pkg/atmos/aws-component-helper/suite.go index 6132953..a2fcb73 100644 --- a/pkg/atmos/aws-component-helper/suite.go +++ b/pkg/atmos/aws-component-helper/suite.go @@ -3,21 +3,19 @@ package aws_component_helper import ( "flag" "fmt" - "os" - "path/filepath" "strings" "testing" "dario.cat/mergo" "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) var ( - skipTests = flag.Bool("skip-tests", false, "skip tests") - skipSetup = flag.Bool("skip-setup", false, "skip setup") - preserveStates = flag.Bool("preserve-states", true, "preserve states") + skipTests = flag.Bool("skip-tests", false, "skip tests") + skipSetup = flag.Bool("skip-setup", false, "skip setup") // runParallel = flag.Bool("parallel", false, "Run parallel") @@ -43,71 +41,57 @@ type Suite struct { t *testing.T randomIdentifier string name string - globalStateDir string dependencies []*AtmosComponent teardown []*teadDown options *atmos.Options + State *State } func NewSuite(t *testing.T, name string, fixture *Fixture) *Suite { randID := random.UniqueId() randomId := strings.ToLower(randID) require.NotContains(t, name, "/") + suiteState, err := fixture.State.Fork(name) + require.NoError(t, err) suite := &Suite{ t: t, name: name, randomIdentifier: randomId, dependencies: []*AtmosComponent{}, - globalStateDir: fixture.GlobalStateDir(), + State: suiteState, teardown: []*teadDown{}, options: fixture.getAtmosOptions(&atmos.Options{}, map[string]interface{}{}), } - - if fixture.StateDir() != "" { - copyDirectoryRecursively(fixture.StateDir(), suite.StateDir()) - } else { - err := createDir(fixture.GlobalStateDir(), suite.stateNamespace()) - require.NoError(t, err) - } - return suite } -func (ts *Suite) StateDir() string { - return filepath.Join(ts.globalStateDir, ts.stateNamespace()) -} - -func (ts *Suite) stateNamespace() string { - return fmt.Sprintf("suite-%s", ts.name) - -} - func (ts *Suite) AddDependency(componentName string, stackName string) { + component := NewAtmosComponent(componentName, stackName, nil) + ts.dependencies = append(ts.dependencies, component) + ts.teardown = append(ts.teardown, &teadDown{component: component, callback: nil}) if *skipSetup { fmt.Printf("Skip suite %s setup dependency component: %s stack: %s\n", ts.name, componentName, stackName) return } - component := NewAtmosComponent(componentName, stackName, nil) - ts.dependencies = append(ts.dependencies, component) - ts.teardown = append(ts.teardown, &teadDown{component: component, callback: nil}) - ts.getAtmos().Deploy(component) + ts.getAtmos(ts.State).Deploy(component) } -func (ts *Suite) getAtmos() *Atmos { - return NewAtmos(ts.t, ts.getAtmosOptions(map[string]interface{}{})) +func (ts *Suite) getAtmos(state *State) *Atmos { + return NewAtmos(ts.t, state, ts.getAtmosOptions(map[string]interface{}{ + "attributes": []string{ts.randomIdentifier}, + })) } -func (ts *Suite) getTestAtmos() *Atmos { - return ts.getAtmos() +func (ts *Suite) getTestAtmos(state *State) *Atmos { + return NewAtmos(ts.t, state, ts.getAtmosOptions(map[string]interface{}{})) } func (ts *Suite) runTeardown() { if *skipTeardown { fmt.Printf("Skip teardown suite %s\n", ts.name) - fmt.Printf("Suite %s preserve states %s\n", ts.name, ts.StateDir()) return } - atm := ts.getAtmos() + atm := ts.getAtmos(ts.State) var f *teadDown for i := len(ts.teardown) - 1; i >= 0; i-- { f = ts.teardown[i] @@ -118,13 +102,8 @@ func (ts *Suite) runTeardown() { atm.Destroy(f.component) } } - if *preserveStates { - fmt.Printf("Suite %s preserve states %s\n", ts.name, ts.StateDir()) - } else { - fmt.Printf("Suite %s drops states %s\n", ts.name, ts.StateDir()) - err := os.RemoveAll(ts.StateDir()) - require.NoError(ts.t, err) - } + err := ts.State.Teardown() + assert.NoError(ts.t, err) } func (ts *Suite) Setup(t *testing.T, f func(t *testing.T, atm *Atmos)) { @@ -132,7 +111,7 @@ func (ts *Suite) Setup(t *testing.T, f func(t *testing.T, atm *Atmos)) { fmt.Printf("Skip suite %s setup callback\n", ts.name) return } - atm := ts.getAtmos() + atm := ts.getAtmos(ts.State) f(t, atm) } @@ -145,7 +124,12 @@ func (ts *Suite) Test(t *testing.T, name string, f func(t *testing.T, atm *Atmos fmt.Printf("Skip test %s/%s\n", ts.name, name) return } - atm := ts.getTestAtmos() + + testState, err := ts.State.Fork(name) + require.NoError(t, err) + defer testState.Teardown() + + atm := ts.getTestAtmos(testState) testRunName := fmt.Sprintf("%s/%s", t.Name(), name) if ok, err := matchFilter(testRunName); ok { t.Run(name, func(t *testing.T) { @@ -160,13 +144,6 @@ func (ts *Suite) getAtmosOptions(vars map[string]interface{}) *atmos.Options { result, err := ts.options.Clone() require.NoError(ts.t, err) - envvars := map[string]string{ - "TEST_SUITE_NAME": ts.stateNamespace(), - } - - err = mergo.Merge(&result.EnvVars, envvars) - require.NoError(ts.t, err) - err = mergo.Merge(&result.Vars, vars) require.NoError(ts.t, err) diff --git a/pkg/atmos/aws-component-helper/tear_down_suite.go b/pkg/atmos/aws-component-helper/tear_down_suite.go deleted file mode 100644 index 18f8df8..0000000 --- a/pkg/atmos/aws-component-helper/tear_down_suite.go +++ /dev/null @@ -1,21 +0,0 @@ -package aws_component_helper - -//func tearDown(ts *TestSuite) error { -// fmt.Println("tearing down test suite in", ts.TempDir) -// err := os.RemoveAll(ts.TempDir) -// if err != nil { -// return err -// } -// -// fmt.Println("removing test suite file", testSuiteFile) -// err = os.Remove(testSuiteFile) -// if err != nil { -// return err -// } -// -// defer os.Unsetenv("ATMOS_BASE_PATH") -// defer os.Unsetenv("ATMOS_CLI_CONFIG_PATH") -// defer os.Unsetenv("TEST_ACCOUNT_ID") -// -// return nil -//} diff --git a/pkg/atmos/aws-component-helper/test_component.go b/pkg/atmos/aws-component-helper/test_component.go deleted file mode 100644 index fca8dea..0000000 --- a/pkg/atmos/aws-component-helper/test_component.go +++ /dev/null @@ -1,97 +0,0 @@ -package aws_component_helper - -import ( - "flag" - "fmt" - "path/filepath" - "strings" - "testing" - - "dario.cat/mergo" - "github.com/cloudposse/test-helpers/pkg/atmos" - "github.com/gruntwork-io/terratest/modules/random" - "github.com/stretchr/testify/require" -) - -var ( - skipVerifyEnabledFlag = flag.Bool("cth.skip-verify-enabled-flag", true, "skip verify enabled flag") -) - -type ComponentTest struct { - RandomIdentifier string - setup []*AtmosComponent - Subject *AtmosComponent - assert map[string]func(t *testing.T, ct *ComponentTest) -} - -func NewComponentTest() *ComponentTest { - randID := random.UniqueId() - randomId := strings.ToLower(randID) - return &ComponentTest{ - RandomIdentifier: randomId, - setup: make([]*AtmosComponent, 0), - Subject: nil, - assert: map[string]func(t *testing.T, ct *ComponentTest){}, - } -} - -func (ct *ComponentTest) verifyEnabledFlag(t *testing.T, component *AtmosComponent, options *atmos.Options) *atmos.Options { - testOptions := ct.getAtmosOptions(t, options, map[string]interface{}{}) - - exitCode, err := atmosPlanExitCodeE(t, testOptions) - require.NoError(t, err) - - if exitCode != 0 { - require.Fail(t, "running atmos terraform plan with enabled flag set to false resulted in resource changes") - } - - return options -} - -func (ct *ComponentTest) getAtmosOptions(t *testing.T, options *atmos.Options, vars map[string]interface{}) *atmos.Options { - result := &atmos.Options{} - if options != nil { - result, _ = options.Clone() - } - - currentTFDataDir := ".terraform" - if value, ok := options.EnvVars["TF_DATA_DIR"]; ok { - currentTFDataDir = value - } - - envvars := map[string]string{ - // We need to split the TF_DATA_DIR for parallel suites mode - "TF_DATA_DIR": filepath.Join(currentTFDataDir, fmt.Sprintf("test-%s", ct.RandomIdentifier)), - } - - err := mergo.Merge(&result.EnvVars, envvars) - require.NoError(t, err) - - mergedVars := map[string]interface{}{ - "default_tags": map[string]string{ - "CreatedByAtmosTestSuiteTest": ct.RandomIdentifier, - }, - } - - // Merge in any additional vars passed in - err = mergo.Merge(&result.Vars, mergedVars) - require.NoError(t, err) - - err = mergo.Merge(&result.Vars, vars) - require.NoError(t, err) - - return result -} - -func (ct *ComponentTest) AddSetup(component string, stack string) { - item := NewAtmosComponent(component, stack, nil) - ct.setup = append(ct.setup, item) -} - -func (ct *ComponentTest) SetSubject(component string, stack string) { - ct.Subject = NewAtmosComponent(component, stack, nil) -} - -func (ct *ComponentTest) AddSAssert(name string, callback func(t *testing.T, ct *ComponentTest)) { - ct.assert[name] = callback -} diff --git a/pkg/atmos/aws-component-helper/test_component_test.go b/pkg/atmos/aws-component-helper/test_component_test.go deleted file mode 100644 index 842140b..0000000 --- a/pkg/atmos/aws-component-helper/test_component_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package aws_component_helper - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestComponentTestMinimum(t *testing.T) { - componentTest := NewComponentTest() - componentTest.SetSubject("vpc", "default-test") - - assert.Equal(t, componentTest.Subject.ComponentName, "vpc") - assert.Equal(t, componentTest.Subject.StackName, "default-test") -} diff --git a/pkg/atmos/aws-component-helper/test_suite.go b/pkg/atmos/aws-component-helper/test_suite.go deleted file mode 100644 index 75e0fb4..0000000 --- a/pkg/atmos/aws-component-helper/test_suite.go +++ /dev/null @@ -1,274 +0,0 @@ -package aws_component_helper - -// -//import ( -// "fmt" -// "testing" -// -// "github.com/cloudposse/test-helpers/pkg/atmos" -//) -// -//type TestSuite struct { -// AtmosOptions *atmos.Options -// AwsAccountId string -// AwsRegion string -// ComponentName string -// ComponentSrcPath string -// Dependencies []*ComponentDeployment -// FixturesPath string -// ForceNewSuite bool -// Index int -// RandomIdentifier string -// SkipSetupComponentUnderTest bool -// SkipDeployDependencies bool -// SkipDeployComponentUnderTest bool -// SkipDestroyComponentUnderTest bool -// SkipDestroyDependencies bool -// SkipTeardownTestSuite bool -// SkipTests bool -// SkipVendorDependencies bool -// SkipVerifyEnabledFlag bool -// SkipNukeTestAccount bool -// StackName string -// TempDir string -//} -// -//type TestSuites struct { -// Suites []*TestSuite -//} -// -//// Option type represents a configuration option -//type TestSuiteOption func(*TestSuite) -// -//func (ts *TestSuite) AddDependencies(dependencies []string) { -// for _, dependency := range dependencies { -// ts.AddDependency(dependency) -// } -//} -// -//func (ts *TestSuite) AddCrossStackDependencies(dependencies []ComponentDeployment) { -// for _, dependency := range dependencies { -// ts.AddCrossStackDependency(dependency.ComponentName, dependency.StackName) -// } -//} -// -//func (ts *TestSuite) AddDependency(componentName string) { -// ts.Dependencies = append(ts.Dependencies, NewAtmosComponent(componentName, ts.StackName)) -//} -// -//func (ts *TestSuite) AddCrossStackDependency(componentName string, stackName string) { -// ts.Dependencies = append(ts.Dependencies, NewAtmosComponent(componentName, stackName)) -//} -// -//func (ts *TestSuite) SetupTestSuite(t *testing.T) error { -// fmt.Println("SetupTestSuite") -// err := setupTestSuite(ts) -// return err -//} -// -//func (ts *TestSuite) SetupComponentUnderTest(t *testing.T) error { -// if !ts.SkipSetupComponentUnderTest { -// fmt.Println("SetupComponentUnderTest") -// err := setupComponentUnderTest(ts) -// return err -// } else { -// fmt.Println("Skipping SetupComponentUnderTest") -// } -// return nil -//} -// -//func (ts *TestSuite) VendorDependencies(t *testing.T) error { -// if !ts.SkipVendorDependencies { -// fmt.Println("VendorDependencies") -// err := vendorDependencies(t, ts) -// return err -// } else { -// fmt.Println("Skipping VendorDependencies") -// } -// return nil -//} -// -//func (ts *TestSuite) DeployDependencies(t *testing.T) error { -// if !ts.SkipDeployDependencies { -// fmt.Println("DeployDependencies") -// err := deployDependencies(t, ts) -// return err -// } else { -// fmt.Println("Skipping DeployDependencies") -// } -// return nil -//} -// -//func (ts *TestSuite) VerifyEnabledFlag(t *testing.T) error { -// if !ts.SkipVerifyEnabledFlag { -// fmt.Println("VerifyEnabledFlag") -// _, err := verifyEnabledFlag(t, ts, ts.ComponentName, ts.StackName) -// return err -// } else { -// fmt.Println("Skipping VerifyEnabledFlag") -// } -// return nil -//} -// -//func (ts *TestSuite) DeployComponentUnderTest(t *testing.T, vars map[string]interface{}) (string, error) { -// if !ts.SkipDeployComponentUnderTest { -// fmt.Println("DeployComponentUnderTest") -// options, out, err := DeployComponent(t, ts, ts.ComponentName, ts.StackName, vars) -// ts.AtmosOptions = options -// -// return out, err -// } else { -// fmt.Println("Skipping DeployComponentUnderTest") -// return "", nil -// } -//} -// -//func (ts *TestSuite) DestroyComponentUnderTest(t *testing.T, vars map[string]interface{}) (string, error) { -// if !ts.SkipDestroyComponentUnderTest { -// fmt.Println("DestroyComponentUnderTest") -// options, out, err := DestroyComponent(t, ts, ts.ComponentName, ts.StackName, vars) -// ts.AtmosOptions = options -// -// return out, err -// } else { -// fmt.Println("Skipping DestroyComponentUnderTest") -// return "", nil -// } -//} -// -//func (ts *TestSuite) DestroyDependencies(t *testing.T) error { -// if !skipDestroyDependencies(ts) { -// fmt.Println("DestroyDependencies") -// err := destroyDependencies(t, ts) -// return err -// } else { -// fmt.Println("Skipping DestroyDependencies") -// } -// return nil -//} -// -//func (ts *TestSuite) TearDownTestSuite(t *testing.T) error { -// fmt.Println("TeardownTestSuite") -// if !skipTeardownTestSuite(ts) { -// err := tearDown(ts) -// return err -// } else { -// fmt.Println("Skipping TeardownTestSuite") -// } -// return nil -//} -// -//func (ts *TestSuite) NukeTestAccount(t *testing.T) error { -// if !skipNukeTestAccount(ts) { -// fmt.Println("NukeTestAccount") -// //awsnuke.NukeTestAccountByTag(t, "CreatedByTerratestRun", ts.RandomSeed, []string{ts.AwsRegion}, false) -// } else { -// fmt.Println("Skipping NukeTestAccount") -// } -// -// return nil -//} -// -//func (ts *TestSuite) Setup(t *testing.T) error { -// fmt.Println("=== RUN Test Suite Setup") -// if err := ts.SetupTestSuite(t); err != nil { -// return err -// } -// -// if err := ts.SetupComponentUnderTest(t); err != nil { -// return err -// } -// -// if err := ts.VendorDependencies(t); err != nil { -// return err -// } -// -// if err := ts.DeployDependencies(t); err != nil { -// return err -// } -// -// if err := ts.VerifyEnabledFlag(t); err != nil { -// return err -// } -// -// return nil -//} -// -//func (ts *TestSuite) TearDown(t *testing.T) error { -// fmt.Println("=== RUN Test Suite TearDown") -// if err := ts.DestroyDependencies(t); err != nil { -// return err -// } -// -// if err := ts.TearDownTestSuite(t); err != nil { -// return err -// } -// -// if err := ts.NukeTestAccount(t); err != nil { -// return err -// } -// -// return nil -//} -// -//func NewTestSuite(awsRegion string, componentName string, stackName string, opts ...TestSuiteOption) (*TestSuite, error) { -// awsAccountId, err := getAwsAccountId() -// if err != nil { -// return &TestSuite{}, err -// } -// -// suite := &TestSuite{ -// AtmosOptions: &atmos.Options{}, -// AwsAccountId: awsAccountId, -// AwsRegion: awsRegion, -// ComponentName: componentName, -// ComponentSrcPath: "../src", -// FixturesPath: "fixtures", -// StackName: stackName, -// } -// -// testName, err := getTestName() -// if err != nil { -// return &TestSuite{}, err -// } -// -// // Apply optional configurations -// for _, opt := range opts { -// opt(suite) -// } -// -// // Parse the CLI args -// suite = parseCLIArgs(suite) -// -// // Read or create the test suite file -// suite, err = readOrCreateTestSuiteFile(suite, testName) -// if err != nil { -// panic("Failed to create test suite: " + err.Error()) -// } -// -// return suite, nil -//} -// -//func WithComponentSrcPath(componentSrcPath string) TestSuiteOption { -// return func(a *TestSuite) { -// a.ComponentSrcPath = componentSrcPath -// } -//} -// -//func WithFixturesPath(fixturesPath string) TestSuiteOption { -// return func(a *TestSuite) { -// a.FixturesPath = fixturesPath -// } -//} -// -//func WithDependency(dependency *ComponentDeployment) TestSuiteOption { -// return func(a *TestSuite) { -// a.Dependencies = append(a.Dependencies, dependency) -// } -//} -// -//func WithDependencies(dependencies []*ComponentDeployment) TestSuiteOption { -// return func(a *TestSuite) { -// a.Dependencies = append(a.Dependencies, dependencies...) -// } -//} diff --git a/test/aws-component-helper/test/fixtures/stacks/orgs/test/main.yaml b/test/aws-component-helper/test/fixtures/stacks/orgs/test/main.yaml index b27b933..24e5976 100644 --- a/test/aws-component-helper/test/fixtures/stacks/orgs/test/main.yaml +++ b/test/aws-component-helper/test/fixtures/stacks/orgs/test/main.yaml @@ -9,8 +9,8 @@ terraform: backend_type: local backend: local: - path: ../../../state/{{ .component }}/terraform.tfstate - workspace_dir: ../../../state/{{ .component }}/ + path: ../../../state/{{ getenv "TEST_SUITE_NAME" | default "" }}/{{ .component }}/terraform.tfstate + workspace_dir: ../../../state/{{ getenv "TEST_SUITE_NAME" | default "" }}/{{ .component }}/ settings: {} vars: label_order: diff --git a/test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/foo.planfile b/test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/foo.planfile new file mode 100644 index 0000000000000000000000000000000000000000..72653a4a3a20e35d3745ee22f0b15dafbd3b6d75 GIT binary patch literal 2086 zcmWIWW@Zs#-~hs_J#G;UNPvxjlc6N7ASW>|G=!Cb@za(=sgDxGgdQjPozoV4^!(A> zk{0KcJC&Ip;To^KGvZG^QU1XY9R^XPPz^tmYLeIdZah_R$fk{zyf$QSZ_SLy1 z6}qJr)de=z#bx^S1+AHG!M=Ec!Ssa7i_T2Z=Hb!y>N2`~Ik>xvKc%xtnKuh4D{CinYYQ*dZ~%Jq|Nj7Qc8-q%+uoi7 z@=gG80M4Lb2M0xQNn%MVJS<$gY`L5ac^baYQ%afE-lX(JOQ}C-kyx^}=i^T=?k+7X z_*1uyp+R0qcWqM3D?-P1=}Ub^S>b-nyT15Rn5 zJ=xh_I8|hdS5UWO)(#PoNuRwxdx_+To)YT*GU>C|j;x&wjIaQlAGu(IJ23D(@dltM zii7e~N^??+^|Ffd5xJo2Sx~?VAO?a@errQE1qB3MYAlE~>UM~+Rn=o{janDs0JH*< zz~(N^memCEKp1xd1BHTKNorA1Vp@Jtu3k=la<*PZat=HcLN54r-*FW<{_*#ouC$`5 zzTxGe<>3nKoh+_RTv~x21Nz^|s~Mj@lXJ+e=KUs?ls)0KKR(t5*6q8mr@GyF%G)5j z6J>i&mGS6*s<5q{@H(x?!bY@K>v#5?^OKf;Zr>!k{q?`R?~C?Ke!N)5>ql8_U7eQH z(}G=9qn!byYk2uHV0Z?B`kOd-v*_KL4IySH1WDtJAli{|?{#P^eRp zw<484dhW)9pS)g)+%V}7-d!>?thA|DFwFM#rGtk5-8DNnBGzBnTb}K4!ZwiY;R1ow zH_j6;NQbV-HG9X)a&el*Y2B?##cb!amhC9&*|+M9UdrV=&kd4OlSQZ9oRDk8yiQeW zZR!_kuC=O5TzWJ)MJG>6W|Fvc#OKQ~@1PXUZB}7dv%H=JUuEmH%F}SVadbSOIO!-hHCTGtyQra5FQ86UjR)zc}wP`fPn zndx$i^D67*?)F;U54xzGa@;fcIBWi; zC4t+og{?csyP)4^iY60N@l6x%LuI?YTC@eWC-Pm{Ffn`GLxopa!lsMaR+QvB@6KNC z^&t3WOR-s}wAa>0PnL?hIW#D*zA0ljD==JY+qB+y%CpnIY?bnGJ7m(LX!@XS)3w)! z7;@)6`;w7+C2!{BC;{i_ee*8Q*eY?JHRjIrry?sRF~o=c-T6EHdp Date: Mon, 30 Dec 2024 11:12:02 +0100 Subject: [PATCH 20/40] Added skip-destroy and skip-deploy flags. useful for tests development --- pkg/atmos/aws-component-helper/atmos.go | 17 +++++++++++++---- pkg/atmos/aws-component-helper/fixture_test.go | 2 +- pkg/atmos/aws-component-helper/shared.go | 2 +- pkg/atmos/terraform_output.go | 12 ++++++------ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index 53f948a..069f6a5 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -1,6 +1,7 @@ package aws_component_helper import ( + "flag" "fmt" "os" "path/filepath" @@ -22,6 +23,10 @@ var ( atmosVendorPull = atmos.VendorPull atmosOutputAll = atmos.OutputStruct ) +var ( + skipDeploy = flag.Bool("skip-deploy", false, "skip all deployments") + skipDestroy = flag.Bool("skip-destroy", false, "skip all destroy") +) type Atmos struct { t *testing.T @@ -54,8 +59,10 @@ func (ts *Atmos) Deploy(component *AtmosComponent) { defer os.RemoveAll(options.AtmosBasePath) err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) require.NoError(ts.t, err) - atmosApply(ts.t, options) - atmosOutputAll(ts.t, options, "", &component.output) + if !*skipDeploy { + atmosApply(ts.t, options) + atmosOutputAll(ts.t, options, "", &component.output) + } } func (ts *Atmos) Destroy(component *AtmosComponent) { @@ -63,7 +70,9 @@ func (ts *Atmos) Destroy(component *AtmosComponent) { defer os.RemoveAll(options.AtmosBasePath) err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) assert.NoError(ts.t, err) - atmosDestroy(ts.t, options) + if !*skipDestroy { + atmosDestroy(ts.t, options) + } } func (ts *Atmos) loadOutputAll(component *AtmosComponent) { @@ -96,7 +105,7 @@ func (ts *Atmos) OutputList(component *AtmosComponent, key string) []string { ts.loadOutputAll(component) if value, ok := component.output[key]; ok { if outputList, isList := value.Value.([]interface{}); isList { - result, err := parseListOutputTerraform(outputList, key) + result, err := parseListOutputTerraform(outputList) require.NoError(ts.t, err) return result } diff --git a/pkg/atmos/aws-component-helper/fixture_test.go b/pkg/atmos/aws-component-helper/fixture_test.go index 99e57d8..3a0553e 100644 --- a/pkg/atmos/aws-component-helper/fixture_test.go +++ b/pkg/atmos/aws-component-helper/fixture_test.go @@ -44,7 +44,7 @@ func mockAtmos() { return "" } - atmosOutputAll = func(_ tt.TestingT, options *atmos.Options, key string, v interface{}) { + atmosOutputAll = func(_ tt.TestingT, options *atmos.Options, _ string, _ interface{}) { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "output", "--skip-init", "--json")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) fmt.Println(description) diff --git a/pkg/atmos/aws-component-helper/shared.go b/pkg/atmos/aws-component-helper/shared.go index 832fa80..4452ee7 100644 --- a/pkg/atmos/aws-component-helper/shared.go +++ b/pkg/atmos/aws-component-helper/shared.go @@ -46,7 +46,7 @@ func copyDirectoryRecursively(srcDir string, destDir string) error { } // Parse a list output in the format it is returned by Terraform 0.12 and newer versions -func parseListOutputTerraform(outputList []interface{}, key string) ([]string, error) { +func parseListOutputTerraform(outputList []interface{}) ([]string, error) { list := []string{} for _, item := range outputList { diff --git a/pkg/atmos/terraform_output.go b/pkg/atmos/terraform_output.go index 2ac5dba..0694213 100644 --- a/pkg/atmos/terraform_output.go +++ b/pkg/atmos/terraform_output.go @@ -64,7 +64,7 @@ func parseListOfMaps(l []interface{}) ([]map[string]interface{}, error) { return nil, err } - m, err := ParseMap(asMap) + m, err := parseMap(asMap) if err != nil { return nil, err @@ -76,7 +76,7 @@ func parseListOfMaps(l []interface{}) ([]map[string]interface{}, error) { } -// ParseMap takes a map of interfaces and parses the types. +// parseMap takes a map of interfaces and parses the types. // It is recursive which allows it to support complex nested structures. // At this time, this function uses https://golang.org/pkg/strconv/#ParseInt // to determine if a number should be a float or an int. For this reason, if you are @@ -87,14 +87,14 @@ func parseListOfMaps(l []interface{}) ([]map[string]interface{}, error) { // types. ie, if you are expecting a value of "1" you are implicitly expecting an int. // // This also allows the work to be executed recursively to support complex data types. -func ParseMap(m map[string]interface{}) (map[string]interface{}, error) { +func parseMap(m map[string]interface{}) (map[string]interface{}, error) { result := make(map[string]interface{}) for k, v := range m { switch vt := v.(type) { case map[string]interface{}: - nestedMap, err := ParseMap(vt) + nestedMap, err := parseMap(vt) if err != nil { return nil, err } @@ -145,7 +145,7 @@ func OutputMapOfObjectsE(t testing.TestingT, options *Options, key string) (map[ return nil, err } - return ParseMap(output) + return parseMap(output) } // OutputListOfObjects calls terraform output for the given variable and returns its value as a list of maps/lists. @@ -175,7 +175,7 @@ func OutputListOfObjectsE(t testing.TestingT, options *Options, key string) ([]m var result []map[string]interface{} for _, m := range output { - newMap, err := ParseMap(m) + newMap, err := parseMap(m) if err != nil { return nil, err From 9ea15dd1bd780a77e9bc4653ffc8c35119cbc96a Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 30 Dec 2024 15:10:51 +0100 Subject: [PATCH 21/40] Allow public get suite random Indentifier --- pkg/atmos/aws-component-helper/atmos.go | 2 +- .../aws-component-helper/atmos_component.go | 8 ++++++-- pkg/atmos/aws-component-helper/suite.go | 18 +++++++++++------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index 069f6a5..e6a57e7 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -147,7 +147,7 @@ func (ts *Atmos) getAtmosOptions(component *AtmosComponent) *atmos.Options { result.EnvVars = envvars if _, ok := result.Vars["attributes"]; !ok { - result.Vars["attributes"] = []string{component.RandomIdentifier} + result.Vars["attributes"] = []string{component.randomIdentifier} } if component.Vars != nil { diff --git a/pkg/atmos/aws-component-helper/atmos_component.go b/pkg/atmos/aws-component-helper/atmos_component.go index ca9f694..2801369 100644 --- a/pkg/atmos/aws-component-helper/atmos_component.go +++ b/pkg/atmos/aws-component-helper/atmos_component.go @@ -12,7 +12,7 @@ type Output struct { } type AtmosComponent struct { - RandomIdentifier string + randomIdentifier string ComponentName string StackName string Vars map[string]interface{} @@ -24,9 +24,13 @@ func NewAtmosComponent(component string, stack string, vars map[string]interface randomId := strings.ToLower(randID) return &AtmosComponent{ - RandomIdentifier: randomId, + randomIdentifier: randomId, ComponentName: component, StackName: stack, Vars: vars, } } + +func (ts *AtmosComponent) GetRandomIdentifier() string { + return ts.randomIdentifier +} diff --git a/pkg/atmos/aws-component-helper/suite.go b/pkg/atmos/aws-component-helper/suite.go index a2fcb73..73f820a 100644 --- a/pkg/atmos/aws-component-helper/suite.go +++ b/pkg/atmos/aws-component-helper/suite.go @@ -44,7 +44,7 @@ type Suite struct { dependencies []*AtmosComponent teardown []*teadDown options *atmos.Options - State *State + state *State } func NewSuite(t *testing.T, name string, fixture *Fixture) *Suite { @@ -58,7 +58,7 @@ func NewSuite(t *testing.T, name string, fixture *Fixture) *Suite { name: name, randomIdentifier: randomId, dependencies: []*AtmosComponent{}, - State: suiteState, + state: suiteState, teardown: []*teadDown{}, options: fixture.getAtmosOptions(&atmos.Options{}, map[string]interface{}{}), } @@ -73,7 +73,7 @@ func (ts *Suite) AddDependency(componentName string, stackName string) { fmt.Printf("Skip suite %s setup dependency component: %s stack: %s\n", ts.name, componentName, stackName) return } - ts.getAtmos(ts.State).Deploy(component) + ts.getAtmos(ts.state).Deploy(component) } func (ts *Suite) getAtmos(state *State) *Atmos { @@ -91,7 +91,7 @@ func (ts *Suite) runTeardown() { fmt.Printf("Skip teardown suite %s\n", ts.name) return } - atm := ts.getAtmos(ts.State) + atm := ts.getAtmos(ts.state) var f *teadDown for i := len(ts.teardown) - 1; i >= 0; i-- { f = ts.teardown[i] @@ -102,7 +102,7 @@ func (ts *Suite) runTeardown() { atm.Destroy(f.component) } } - err := ts.State.Teardown() + err := ts.state.Teardown() assert.NoError(ts.t, err) } @@ -111,7 +111,7 @@ func (ts *Suite) Setup(t *testing.T, f func(t *testing.T, atm *Atmos)) { fmt.Printf("Skip suite %s setup callback\n", ts.name) return } - atm := ts.getAtmos(ts.State) + atm := ts.getAtmos(ts.state) f(t, atm) } @@ -125,7 +125,7 @@ func (ts *Suite) Test(t *testing.T, name string, f func(t *testing.T, atm *Atmos return } - testState, err := ts.State.Fork(name) + testState, err := ts.state.Fork(name) require.NoError(t, err) defer testState.Teardown() @@ -149,3 +149,7 @@ func (ts *Suite) getAtmosOptions(vars map[string]interface{}) *atmos.Options { return result } + +func (ts *Suite) GetRandomIdentifier() string { + return ts.randomIdentifier +} From 5c270d517f3a2bf379200c09924ced1e747e5302 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Tue, 31 Dec 2024 00:48:52 +0100 Subject: [PATCH 22/40] Added output struct --- .../aws-component-helper/acceptance_test.go | 32 ++++- pkg/atmos/aws-component-helper/atmos.go | 120 +++++++++++++++++- pkg/atmos/aws-component-helper/fixture.go | 12 +- .../aws-component-helper/fixture_test.go | 4 +- .../terraform/terraform-no-error/main.tf | 10 ++ 5 files changed, 168 insertions(+), 10 deletions(-) diff --git a/pkg/atmos/aws-component-helper/acceptance_test.go b/pkg/atmos/aws-component-helper/acceptance_test.go index bba8e4a..1b76fd2 100644 --- a/pkg/atmos/aws-component-helper/acceptance_test.go +++ b/pkg/atmos/aws-component-helper/acceptance_test.go @@ -41,8 +41,36 @@ func TestAcceptance(t *testing.T) { defer atm.GetAndDestroy("terraform-no-error", "default-test", nil) component := atm.GetAndDeploy("terraform-no-error", "default-test", nil) - assert.Equal(t, atm.Output(component, "test"), "Hello, World") - assert.Equal(t, atm.OutputList(component, "test_list"), []string{"a", "b", "c"}) + mapOfObjects := map[string]interface{}{ + "a": map[string]interface{}{"b": "c"}, + "d": map[string]interface{}{"e": "f"}, + } + + assert.Equal(t, "Hello, World", atm.Output(component, "test")) + assert.Equal(t, []string{"a", "b", "c"}, atm.OutputList(component, "test_list")) + assert.Equal(t, mapOfObjects, atm.OutputMapOfObjects(component, "test_map_of_objects")) + + type structValue1 struct { + B string + } + + type structValue2 struct { + E string + } + + type structValue struct { + A structValue1 + D structValue2 + } + + structResult := structValue{} + structExpected := structValue{ + A: structValue1{B: "c"}, + D: structValue2{E: "f"}, + } + + atm.OutputStruct(component, "test_map_of_objects", &structResult) + assert.Equal(t, structExpected, structResult) }) }) } diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index e6a57e7..c594c9a 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -1,11 +1,14 @@ package aws_component_helper import ( + "encoding/json" + "errors" "flag" "fmt" "os" "path/filepath" "reflect" + "strconv" "strings" "testing" @@ -21,7 +24,7 @@ var ( atmosDestroy = atmos.Destroy atmosPlanExitCodeE = atmos.PlanExitCodeE atmosVendorPull = atmos.VendorPull - atmosOutputAll = atmos.OutputStruct + atmosOutputAllE = atmos.OutputStructE ) var ( skipDeploy = flag.Bool("skip-deploy", false, "skip all deployments") @@ -61,7 +64,8 @@ func (ts *Atmos) Deploy(component *AtmosComponent) { require.NoError(ts.t, err) if !*skipDeploy { atmosApply(ts.t, options) - atmosOutputAll(ts.t, options, "", &component.output) + err := atmosOutputAllE(ts.t, options, "", &component.output) + require.NoError(ts.t, err) } } @@ -83,7 +87,16 @@ func (ts *Atmos) loadOutputAll(component *AtmosComponent) { defer os.RemoveAll(options.AtmosBasePath) err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) require.NoError(ts.t, err) - atmosOutputAll(ts.t, options, "", &component.output) + + err = atmosOutputAllE(ts.t, options, "", &component.output) + if err != nil && strings.Contains(err.Error(), "Backend initialization required") { + // Run 'terraform workspace' instead of 'terraform init' as it also select the workspace + // So terraform output will not fail with "Switch to workspace" json parse error + _, err := atmos.RunAtmosCommandE(ts.t, options, atmos.FormatArgs(options, "terraform", "workspace")...) + require.NoError(ts.t, err) + err = atmosOutputAllE(ts.t, options, "", &component.output) + require.NoError(ts.t, err) + } } func (ts *Atmos) OutputAll(component *AtmosComponent) map[string]Output { @@ -118,6 +131,34 @@ func (ts *Atmos) OutputList(component *AtmosComponent, key string) []string { return []string{} } +func (ts *Atmos) OutputMapOfObjects(component *AtmosComponent, key string) map[string]interface{} { + ts.loadOutputAll(component) + if value, ok := component.output[key]; ok { + if outputMap, isMap := value.Value.(map[string]interface{}); isMap { + return outputMap + } + error := atmos.UnexpectedOutputType{Key: key, ExpectedType: "map of objects", ActualType: reflect.TypeOf(value).String()} + require.Fail(ts.t, error.Error()) + + } else { + require.Fail(ts.t, fmt.Sprintf("Output key %s not found", key)) + } + return map[string]interface{}{} +} + +func (ts *Atmos) OutputStruct(component *AtmosComponent, key string, v any) { + ts.loadOutputAll(component) + if value, ok := component.output[key]; ok { + jsonByte, err := json.Marshal(value.Value) + require.NoError(ts.t, err) + jsonString := cleanOutput(string(jsonByte)) + err = json.Unmarshal([]byte(jsonString), &v) + require.NoError(ts.t, err) + } else { + require.Fail(ts.t, fmt.Sprintf("Output key %s not found", key)) + } +} + func (ts *Atmos) getAtmosOptions(component *AtmosComponent) *atmos.Options { result, err := ts.options.Clone() require.NoError(ts.t, err) @@ -159,3 +200,76 @@ func (ts *Atmos) getAtmosOptions(component *AtmosComponent) *atmos.Options { return atmosOptions } + +func parseMap(m map[string]interface{}) (map[string]interface{}, error) { + + result := make(map[string]interface{}) + + for k, v := range m { + switch vt := v.(type) { + case map[string]interface{}: + nestedMap, err := parseMap(vt) + if err != nil { + return nil, err + } + result[k] = nestedMap + case []interface{}: + nestedList, err := parseListOfMaps(vt) + if err != nil { + return nil, err + } + result[k] = nestedList + case float64: + testInt, err := strconv.ParseInt((fmt.Sprintf("%v", vt)), 10, 0) + if err == nil { + result[k] = int(testInt) + } else { + result[k] = vt + } + default: + result[k] = vt + } + + } + return result, nil +} + +// parseListOfMaps takes a list of maps and parses the types. +// It is mainly a wrapper for parseMap to support lists. +func parseListOfMaps(l []interface{}) ([]map[string]interface{}, error) { + var result []map[string]interface{} + + for _, v := range l { + + asMap, isMap := v.(map[string]interface{}) + if !isMap { + err := errors.New("Type switching to map[string]interface{} failed.") + return nil, err + } + + m, err := parseMap(asMap) + + if err != nil { + return nil, err + } + result = append(result, m) + } + + return result, nil + +} + +func cleanOutput(out string) string { + var result []rune + for _, line := range strings.Split(out, "\n") { + if strings.Contains(line, "INFO") { + continue + } + for _, r := range line { + if r >= 32 && r < 127 { // Keep printable ASCII characters only + result = append(result, r) + } + } + } + return string(result) +} diff --git a/pkg/atmos/aws-component-helper/fixture.go b/pkg/atmos/aws-component-helper/fixture.go index 5649e21..040b355 100644 --- a/pkg/atmos/aws-component-helper/fixture.go +++ b/pkg/atmos/aws-component-helper/fixture.go @@ -23,6 +23,7 @@ var ( skipVendorDependencies = flag.Bool("skip-vendor", false, "skip vendor dependencies") skipTeardownFixtures = flag.Bool("skip-fixtures-teardown", false, "skip fixtures teardown") skipTeardown = flag.Bool("skip-teardown", false, "skip teardown") + useCache = flag.Bool("cache", false, "use cache for terraform plugins") matchSuiteAndTest = flag.String("match", "", "regular expression to select suite and tests to run") // runParallel = flag.Bool("parallel", false, "Run parallel") @@ -119,8 +120,10 @@ func (ts *Fixture) SetUp(options *atmos.Options) { err := ts.State.SetUp() require.NoError(ts.t, err) - err = createDir(ts.WorkDir(), ".cache") - require.NoError(ts.t, err) + if *useCache { + err = createDir(ts.WorkDir(), ".cache") + require.NoError(ts.t, err) + } } func (ts *Fixture) TearDown() { @@ -154,7 +157,10 @@ func (ts *Fixture) getAtmosOptions(options *atmos.Options, vars map[string]inter "TEST_ACCOUNT_ID": ts.AwsAccountId, "ATMOS_BASE_PATH": result.AtmosBasePath, "ATMOS_CLI_CONFIG_PATH": result.AtmosBasePath, - "TF_PLUGIN_CACHE_DIR": filepath.Join(ts.WorkDir(), ".cache"), + } + + if *useCache { + envvars["TF_PLUGIN_CACHE_DIR"] = filepath.Join(ts.WorkDir(), ".cache") } err := mergo.Merge(&result.EnvVars, envvars) diff --git a/pkg/atmos/aws-component-helper/fixture_test.go b/pkg/atmos/aws-component-helper/fixture_test.go index 3a0553e..19320b3 100644 --- a/pkg/atmos/aws-component-helper/fixture_test.go +++ b/pkg/atmos/aws-component-helper/fixture_test.go @@ -44,12 +44,12 @@ func mockAtmos() { return "" } - atmosOutputAll = func(_ tt.TestingT, options *atmos.Options, _ string, _ interface{}) { + atmosOutputAllE = func(_ tt.TestingT, options *atmos.Options, _ string, _ interface{}) error { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "output", "--skip-init", "--json")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) fmt.Println(description) + return nil } - } func TestFixtureMinimum(t *testing.T) { diff --git a/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf b/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf index 8daf248..3e7b276 100644 --- a/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf +++ b/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf @@ -13,4 +13,14 @@ output "test_list" { value = [ "a", "b", "c"] } +output "test_map_of_objects" { + value = { + a = { + b = "c" + }, + d = { + e = "f" + } + } +} From 1987461476fd6e54a40370668004dd006b8719cc Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Thu, 2 Jan 2025 18:09:07 +0100 Subject: [PATCH 23/40] Added messages on skip deploy and destroy --- pkg/atmos/aws-component-helper/atmos.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index c594c9a..d749a88 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -66,6 +66,8 @@ func (ts *Atmos) Deploy(component *AtmosComponent) { atmosApply(ts.t, options) err := atmosOutputAllE(ts.t, options, "", &component.output) require.NoError(ts.t, err) + } else { + fmt.Printf("Skip deploy component %s stack %s\n", component.ComponentName, component.StackName) } } @@ -76,7 +78,10 @@ func (ts *Atmos) Destroy(component *AtmosComponent) { assert.NoError(ts.t, err) if !*skipDestroy { atmosDestroy(ts.t, options) + } else { + fmt.Printf("Skip destroy component %s stack %s\n", component.ComponentName, component.StackName) } + } func (ts *Atmos) loadOutputAll(component *AtmosComponent) { From 34916c8522b25a22e2c0a9de2a2da800f46d4154 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 22:29:46 +0300 Subject: [PATCH 24/40] Apply suggestions from code review Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- pkg/atmos/aws-component-helper/acceptance_test.go | 6 +++++- pkg/atmos/aws-component-helper/shared.go | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/atmos/aws-component-helper/acceptance_test.go b/pkg/atmos/aws-component-helper/acceptance_test.go index 1b76fd2..9b6c4b6 100644 --- a/pkg/atmos/aws-component-helper/acceptance_test.go +++ b/pkg/atmos/aws-component-helper/acceptance_test.go @@ -18,7 +18,11 @@ func TestAcceptance(t *testing.T) { testFolder, err := files.CopyFolderToTemp("../../../", t.Name(), func(path string) bool { return true }) require.NoError(t, err) - defer os.RemoveAll(testFolder) + defer func() { + if err := os.RemoveAll(testFolder); err != nil { + t.Errorf("failed to cleanup test folder: %v", err) + } + }() fmt.Printf("running in %s\n", testFolder) diff --git a/pkg/atmos/aws-component-helper/shared.go b/pkg/atmos/aws-component-helper/shared.go index 4452ee7..5442d23 100644 --- a/pkg/atmos/aws-component-helper/shared.go +++ b/pkg/atmos/aws-component-helper/shared.go @@ -118,6 +118,10 @@ func getAwsAccountId() (string, error) { if err != nil { return "", err } + // Add retries for better reliability + cfg.RetryMode = aws.RetryModeAdaptive + cfg.RetryMaxAttempts = 3 + stsClient := sts.NewFromConfig(cfg) identity, err := stsClient.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{}) if err != nil { From 95c3125eff999c762503c5cd040f618c17c580ad Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 22:50:31 +0300 Subject: [PATCH 25/40] Apply suggestions from code review Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../terraform-basic-configuration/main.tf | 23 +++++++++++++++---- .../terraform/terraform-no-error/main.tf | 3 ++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/main.tf b/test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/main.tf index 3431ff0..682caf8 100644 --- a/test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/main.tf +++ b/test/fixtures/aws-component-helper/components/terraform/terraform-basic-configuration/main.tf @@ -1,10 +1,25 @@ -variable "cnt" {} +variable "cnt" { + type = number + description = "Number of null_resource instances to create" + validation { + condition = var.cnt > 0 + error_message = "Count must be greater than 0" + } +} -variable "region" {} +variable "region" { + type = string + description = "AWS region for the resources" + validation { + condition = can(regex("^[a-z]{2}(-[a-z]+)?-[1-2]$", var.region)) + error_message = "Region must be a valid AWS region name (e.g., us-west-2)" + } +} variable "attributes" { - type = list - default = [] + type = list(string) + default = [] + description = "Additional attributes to add to the resources" } resource "null_resource" "test" { diff --git a/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf b/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf index 3e7b276..45a20a3 100644 --- a/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf +++ b/test/fixtures/aws-component-helper/components/terraform/terraform-no-error/main.tf @@ -1,7 +1,8 @@ variable "region" {} variable "attributes" { - type = list + type = list(string) + description = "Additional attributes for resource naming" default = [] } From d1970e53fc9143e223606ee02d9c4860e43b1bc1 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 20:51:23 +0100 Subject: [PATCH 26/40] Address comments --- pkg/atmos/aws-component-helper/fixture.go | 14 - pkg/atmos/aws-component-helper/shared_test.go | 1 - pkg/atmos/aws-component-helper/suite.go | 14 - pkg/awsnuke/awsnuke.go | 152 ++++++++++ pkg/awsnuke/awsnuke.go.bk | 152 ---------- pkg/awsnuke/awsnuke.go.bk_test.go.bk | 57 ---- pkg/awsnuke/awsnuke_test.go | 57 ++++ test/aws-component-helper/src/context.tf | 279 ------------------ test/aws-component-helper/src/main.tf | 24 -- test/aws-component-helper/test/basic_test.go | 60 ---- .../test/fixtures/stacks/orgs/test/main.yaml | 50 ---- .../test/fixtures/vendor.yaml | 32 -- test/fixtures/aws-component-helper/atmos.yaml | 10 - .../stacks/catalog/account-map.yaml | 12 - .../fixtures/aws-component-helper/vendor.yaml | 11 - 15 files changed, 209 insertions(+), 716 deletions(-) create mode 100644 pkg/awsnuke/awsnuke.go delete mode 100644 pkg/awsnuke/awsnuke.go.bk delete mode 100644 pkg/awsnuke/awsnuke.go.bk_test.go.bk create mode 100644 pkg/awsnuke/awsnuke_test.go delete mode 100644 test/aws-component-helper/src/context.tf delete mode 100644 test/aws-component-helper/src/main.tf delete mode 100644 test/aws-component-helper/test/basic_test.go delete mode 100644 test/aws-component-helper/test/fixtures/stacks/orgs/test/main.yaml delete mode 100644 test/aws-component-helper/test/fixtures/vendor.yaml diff --git a/pkg/atmos/aws-component-helper/fixture.go b/pkg/atmos/aws-component-helper/fixture.go index 040b355..84bed8f 100644 --- a/pkg/atmos/aws-component-helper/fixture.go +++ b/pkg/atmos/aws-component-helper/fixture.go @@ -25,20 +25,6 @@ var ( skipTeardown = flag.Bool("skip-teardown", false, "skip teardown") useCache = flag.Bool("cache", false, "use cache for terraform plugins") matchSuiteAndTest = flag.String("match", "", "regular expression to select suite and tests to run") - // runParallel = flag.Bool("parallel", false, "Run parallel") - - // forceNewSuite = flag.Bool("cth.force-new-suite", false, "force new suite") - // suiteIndex = flag.Int("cth.suite-index", -1, "suite index") - // skipAwsNuke = flag.Bool("cth.skip-aws-nuke", false, "skip aws nuke") - - // skipDependencies = flag.Bool("cth.skip-deps", false, "skip deploy dependencies") - // skipDeployDependencies = flag.Bool("cth.skip-deps-deploy", false, "skip deploy dependencies") - // skipDestroyDependencies = flag.Bool("cth.skip-deps-destroy", false, "skip destroy dependencies") - // skipTeardownTestSuite = flag.Bool("skip-teardown", false, "skip test suite teardown") - // skipTests = flag.Bool("skip-tests", false, "skip tests") - - // skipDeployComponentUnderTest = flag.Bool("cth.skip-deploy-cut", false, "skip deploy component under test") - // skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") ) type Fixture struct { diff --git a/pkg/atmos/aws-component-helper/shared_test.go b/pkg/atmos/aws-component-helper/shared_test.go index 17f5d65..4c139a9 100644 --- a/pkg/atmos/aws-component-helper/shared_test.go +++ b/pkg/atmos/aws-component-helper/shared_test.go @@ -8,7 +8,6 @@ import ( ) func TestMatchFilter(t *testing.T) { - t.Parallel() t.Run("wrong", func(t *testing.T) { matchRegexp := "" matchSuiteAndTest = &matchRegexp diff --git a/pkg/atmos/aws-component-helper/suite.go b/pkg/atmos/aws-component-helper/suite.go index 73f820a..7dad9ba 100644 --- a/pkg/atmos/aws-component-helper/suite.go +++ b/pkg/atmos/aws-component-helper/suite.go @@ -16,20 +16,6 @@ import ( var ( skipTests = flag.Bool("skip-tests", false, "skip tests") skipSetup = flag.Bool("skip-setup", false, "skip setup") - - // runParallel = flag.Bool("parallel", false, "Run parallel") - - // forceNewSuite = flag.Bool("cth.force-new-suite", false, "force new suite") - // suiteIndex = flag.Int("cth.suite-index", -1, "suite index") - // skipAwsNuke = flag.Bool("cth.skip-aws-nuke", false, "skip aws nuke") - - // skipDependencies = flag.Bool("cth.skip-deps", false, "skip deploy dependencies") - // skipDeployDependencies = flag.Bool("cth.skip-deps-deploy", false, "skip deploy dependencies") - // skipDestroyDependencies = flag.Bool("cth.skip-deps-destroy", false, "skip destroy dependencies") - // skipTeardownTestSuite = flag.Bool("skip-teardown", false, "skip test suite teardown") - - // skipDeployComponentUnderTest = flag.Bool("cth.skip-deploy-cut", false, "skip deploy component under test") - // skipDestroyComponentUnderTest = flag.Bool("cth.skip-destroy-cut", false, "skip destroy component under test") ) type teadDown struct { diff --git a/pkg/awsnuke/awsnuke.go b/pkg/awsnuke/awsnuke.go new file mode 100644 index 0000000..17ee887 --- /dev/null +++ b/pkg/awsnuke/awsnuke.go @@ -0,0 +1,152 @@ +package awsnuke + +import ( + "fmt" + "os" + "sort" + + "github.com/aws/aws-sdk-go/aws/endpoints" + tt "github.com/cloudposse/test-helpers/pkg/testing" + "github.com/gruntwork-io/terratest/modules/aws" + "github.com/gruntwork-io/terratest/modules/testing" + "github.com/rebuy-de/aws-nuke/v2/cmd" + "github.com/rebuy-de/aws-nuke/v2/pkg/awsutil" + nukeconfig "github.com/rebuy-de/aws-nuke/v2/pkg/config" + "github.com/rebuy-de/aws-nuke/v2/resources" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" +) + +type GenerateAwsNukeConfigConfig struct { + AllRegions bool + AccountId string + Regions []string + TagName string + TagValue string +} + +type RunAwsNukeParams struct { + Config nukeconfig.Nuke + Creds awsutil.Credentials + DefaultRegion string + Params cmd.NukeParameters + Verbose bool +} + +func getAwsNukeSupportedResources() []string { + names := resources.GetListerNames() + sort.Strings(names) + + return names +} + +// GenerateAwsNukeConfigWithTagFilter generates an aws-nuke config object and adds a tag-based filter to every aws-nuke +// supported resource type +func GenerateAwsNukeConfigWithTagFilter(config GenerateAwsNukeConfigConfig) nukeconfig.Nuke { + filters := nukeconfig.Filters{} + for _, resource := range getAwsNukeSupportedResources() { + filter := nukeconfig.Filters{ + resource: []nukeconfig.Filter{ + { + Property: fmt.Sprintf("tag:%s", config.TagName), + Type: "exact", + Value: config.TagValue, + Invert: "true"}, + }, + } + filters.Merge(filter) + } + + nukeCfg := nukeconfig.Nuke{ + Accounts: map[string]nukeconfig.Account{ + config.AccountId: { + Filters: filters, + }, + }, + AccountBlocklist: []string{"999999999999"}, + Regions: config.Regions, + } + + return nukeCfg +} + +// RunAwsNukeExe runs the aws-nuke as a library with the given config +func RunAwsNukeE(params RunAwsNukeParams) error { + var err error + + err = params.Params.Validate() + if err != nil { + return err + } + + if !params.Creds.HasKeys() && !params.Creds.HasProfile() && params.DefaultRegion != "" { + params.Creds.AccessKeyID = os.Getenv("AWS_ACCESS_KEY_ID") + params.Creds.SecretAccessKey = os.Getenv("AWS_SECRET_ACCESS_KEY") + + sessionToken := os.Getenv("AWS_SESSION_TOKEN") + if sessionToken != "" { + params.Creds.SessionToken = sessionToken + } + } + + err = params.Creds.Validate() + if err != nil { + return err + } + + if params.DefaultRegion != "" { + awsutil.DefaultRegionID = params.DefaultRegion + switch params.DefaultRegion { + case endpoints.UsEast1RegionID, endpoints.UsEast2RegionID, endpoints.UsWest1RegionID, endpoints.UsWest2RegionID: + awsutil.DefaultAWSPartitionID = endpoints.AwsPartitionID + case endpoints.UsGovEast1RegionID, endpoints.UsGovWest1RegionID: + awsutil.DefaultAWSPartitionID = endpoints.AwsUsGovPartitionID + default: + if params.Config.CustomEndpoints.GetRegion(params.DefaultRegion) == nil { + err = fmt.Errorf("the custom region '%s' must be specified in the configuration 'endpoints'", params.DefaultRegion) + log.Error(err.Error()) + return err + } + } + } + + account, err := awsutil.NewAccount(params.Creds, params.Config.CustomEndpoints) + if err != nil { + return err + } + + n := cmd.NewNuke(params.Params, *account) + + n.Config = ¶ms.Config + + return n.Run() +} + +func NukeTestAccountByTag(t tt.TestingT, tagName string, tagValue string, regions []string, dryRun bool) { + accountID, err := aws.GetAccountIdE(t.(testing.TestingT)) + assert.NoError(t, err) + + // run sts.getcalleridentity + generateConfig := GenerateAwsNukeConfigConfig{ + AccountId: accountID, + Regions: regions, + TagName: tagName, + TagValue: tagValue, + } + config := GenerateAwsNukeConfigWithTagFilter(generateConfig) + + nukeParams := RunAwsNukeParams{ + Config: config, + Creds: awsutil.Credentials{}, + DefaultRegion: "", + Params: cmd.NukeParameters{ + ConfigPath: "GeneratedConfig", + NoDryRun: !dryRun, + Force: true, + ForceSleep: 3, + }, + } + + err = RunAwsNukeE(nukeParams) + assert.NoError(t, err) +} diff --git a/pkg/awsnuke/awsnuke.go.bk b/pkg/awsnuke/awsnuke.go.bk deleted file mode 100644 index 427ea54..0000000 --- a/pkg/awsnuke/awsnuke.go.bk +++ /dev/null @@ -1,152 +0,0 @@ -//package awsnuke -// -//import ( -// "fmt" -// "os" -// "sort" -// -// "github.com/aws/aws-sdk-go/aws/endpoints" -// tt "github.com/cloudposse/test-helpers/pkg/testing" -// "github.com/gruntwork-io/terratest/modules/aws" -// "github.com/gruntwork-io/terratest/modules/testing" -// "github.com/rebuy-de/aws-nuke/v2/cmd" -// "github.com/rebuy-de/aws-nuke/v2/pkg/awsutil" -// nukeconfig "github.com/rebuy-de/aws-nuke/v2/pkg/config" -// "github.com/rebuy-de/aws-nuke/v2/resources" -// log "github.com/sirupsen/logrus" -// "github.com/stretchr/testify/assert" -//) -// -//type GenerateAwsNukeConfigConfig struct { -// AllRegions bool -// AccountId string -// Regions []string -// TagName string -// TagValue string -//} -// -//type RunAwsNukeParams struct { -// Config nukeconfig.Nuke -// Creds awsutil.Credentials -// DefaultRegion string -// Params cmd.NukeParameters -// Verbose bool -//} -// -//func getAwsNukeSupportedResources() []string { -// names := resources.GetListerNames() -// sort.Strings(names) -// -// return names -//} -// -//// GenerateAwsNukeConfigWithTagFilter generates an aws-nuke config object and adds a tag-based filter to every aws-nuke -//// supported resource type -//func GenerateAwsNukeConfigWithTagFilter(config GenerateAwsNukeConfigConfig) nukeconfig.Nuke { -// filters := nukeconfig.Filters{} -// for _, resource := range getAwsNukeSupportedResources() { -// filter := nukeconfig.Filters{ -// resource: []nukeconfig.Filter{ -// { -// Property: fmt.Sprintf("tag:%s", config.TagName), -// Type: "exact", -// Value: config.TagValue, -// Invert: "true"}, -// }, -// } -// filters.Merge(filter) -// } -// -// nukeCfg := nukeconfig.Nuke{ -// Accounts: map[string]nukeconfig.Account{ -// config.AccountId: { -// Filters: filters, -// }, -// }, -// AccountBlocklist: []string{"999999999999"}, -// Regions: config.Regions, -// } -// -// return nukeCfg -//} -// -//// RunAwsNukeExe runs the aws-nuke as a library with the given config -//func RunAwsNukeE(params RunAwsNukeParams) error { -// var err error -// -// err = params.Params.Validate() -// if err != nil { -// return err -// } -// -// if !params.Creds.HasKeys() && !params.Creds.HasProfile() && params.DefaultRegion != "" { -// params.Creds.AccessKeyID = os.Getenv("AWS_ACCESS_KEY_ID") -// params.Creds.SecretAccessKey = os.Getenv("AWS_SECRET_ACCESS_KEY") -// -// sessionToken := os.Getenv("AWS_SESSION_TOKEN") -// if sessionToken != "" { -// params.Creds.SessionToken = sessionToken -// } -// } -// -// err = params.Creds.Validate() -// if err != nil { -// return err -// } -// -// if params.DefaultRegion != "" { -// awsutil.DefaultRegionID = params.DefaultRegion -// switch params.DefaultRegion { -// case endpoints.UsEast1RegionID, endpoints.UsEast2RegionID, endpoints.UsWest1RegionID, endpoints.UsWest2RegionID: -// awsutil.DefaultAWSPartitionID = endpoints.AwsPartitionID -// case endpoints.UsGovEast1RegionID, endpoints.UsGovWest1RegionID: -// awsutil.DefaultAWSPartitionID = endpoints.AwsUsGovPartitionID -// default: -// if params.Config.CustomEndpoints.GetRegion(params.DefaultRegion) == nil { -// err = fmt.Errorf("the custom region '%s' must be specified in the configuration 'endpoints'", params.DefaultRegion) -// log.Error(err.Error()) -// return err -// } -// } -// } -// -// account, err := awsutil.NewAccount(params.Creds, params.Config.CustomEndpoints) -// if err != nil { -// return err -// } -// -// n := cmd.NewNuke(params.Params, *account) -// -// n.Config = ¶ms.Config -// -// return n.Run() -//} -// -//func NukeTestAccountByTag(t tt.TestingT, tagName string, tagValue string, regions []string, dryRun bool) { -// accountID, err := aws.GetAccountIdE(t.(testing.TestingT)) -// assert.NoError(t, err) -// -// // run sts.getcalleridentity -// generateConfig := GenerateAwsNukeConfigConfig{ -// AccountId: accountID, -// Regions: regions, -// TagName: tagName, -// TagValue: tagValue, -// } -// config := GenerateAwsNukeConfigWithTagFilter(generateConfig) -// -// nukeParams := RunAwsNukeParams{ -// Config: config, -// Creds: awsutil.Credentials{}, -// DefaultRegion: "", -// Params: cmd.NukeParameters{ -// ConfigPath: "GeneratedConfig", -// NoDryRun: !dryRun, -// Force: true, -// ForceSleep: 3, -// }, -// } -// -// err = RunAwsNukeE(nukeParams) -// assert.NoError(t, err) -//} diff --git a/pkg/awsnuke/awsnuke.go.bk_test.go.bk b/pkg/awsnuke/awsnuke.go.bk_test.go.bk deleted file mode 100644 index c571354..0000000 --- a/pkg/awsnuke/awsnuke.go.bk_test.go.bk +++ /dev/null @@ -1,57 +0,0 @@ -////go:build integration -// -//package awsnuke -// -//import ( -// "fmt" -// "os" -// "strings" -// "testing" -// -// "github.com/gruntwork-io/terratest/modules/aws" -// "github.com/gruntwork-io/terratest/modules/random" -// "github.com/gruntwork-io/terratest/modules/terraform" -// testStructure "github.com/gruntwork-io/terratest/modules/test-structure" -// "github.com/stretchr/testify/assert" -//) -// -//const testRegion string = "us-east-2" -//const terratestTagName string = "CreatedByTerratestRun" -// -//func TestAwsNuke(t *testing.T) { -// t.Parallel() -// randID := strings.ToLower(random.UniqueId()) -// -// rootFolder := "../../" -// terraformFolderRelativeToRoot := "examples/awsnuke-example" -// tempTestFolder := testStructure.CopyTerraformFolderToTemp(t, rootFolder, terraformFolderRelativeToRoot) -// defer os.RemoveAll(tempTestFolder) -// -// terraformOptions := &terraform.Options{ -// TerraformDir: tempTestFolder, -// Upgrade: true, -// VarFiles: []string{fmt.Sprintf("fixtures.%s.tfvars", testRegion)}, -// Vars: map[string]interface{}{ -// "attributes": []string{randID}, -// "default_tags": map[string]string{ -// terratestTagName: randID, -// }, -// }, -// } -// -// defer terraform.Destroy(t, terraformOptions) -// terraform.InitAndApply(t, terraformOptions) -// -// // Assert that the bucket has been created -// bucket, err := aws.FindS3BucketWithTagE(t, testRegion, terratestTagName, randID) -// assert.NoError(t, err) -// assert.Equal(t, bucket, fmt.Sprintf("eg-test-s3-bucket-test-%s", randID)) -// -// // Nuke the account with our config -// NukeTestAccountByTag(t, terratestTagName, randID, []string{testRegion}, false) -// -// // Assert that the bucket doesn't exist anymore -// bucket, err = aws.FindS3BucketWithTagE(t, testRegion, terratestTagName, randID) -// assert.NoError(t, err) -// assert.Empty(t, bucket) -//} diff --git a/pkg/awsnuke/awsnuke_test.go b/pkg/awsnuke/awsnuke_test.go new file mode 100644 index 0000000..c8edb4d --- /dev/null +++ b/pkg/awsnuke/awsnuke_test.go @@ -0,0 +1,57 @@ +//go:build integration + +package awsnuke + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/gruntwork-io/terratest/modules/aws" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/gruntwork-io/terratest/modules/terraform" + testStructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/assert" +) + +const testRegion string = "us-east-2" +const terratestTagName string = "CreatedByTerratestRun" + +func TestAwsNuke(t *testing.T) { + t.Parallel() + randID := strings.ToLower(random.UniqueId()) + + rootFolder := "../../" + terraformFolderRelativeToRoot := "examples/awsnuke-example" + tempTestFolder := testStructure.CopyTerraformFolderToTemp(t, rootFolder, terraformFolderRelativeToRoot) + defer os.RemoveAll(tempTestFolder) + + terraformOptions := &terraform.Options{ + TerraformDir: tempTestFolder, + Upgrade: true, + VarFiles: []string{fmt.Sprintf("fixtures.%s.tfvars", testRegion)}, + Vars: map[string]interface{}{ + "attributes": []string{randID}, + "default_tags": map[string]string{ + terratestTagName: randID, + }, + }, + } + + defer terraform.Destroy(t, terraformOptions) + terraform.InitAndApply(t, terraformOptions) + + // Assert that the bucket has been created + bucket, err := aws.FindS3BucketWithTagE(t, testRegion, terratestTagName, randID) + assert.NoError(t, err) + assert.Equal(t, bucket, fmt.Sprintf("eg-test-s3-bucket-test-%s", randID)) + + // Nuke the account with our config + NukeTestAccountByTag(t, terratestTagName, randID, []string{testRegion}, false) + + // Assert that the bucket doesn't exist anymore + bucket, err = aws.FindS3BucketWithTagE(t, testRegion, terratestTagName, randID) + assert.NoError(t, err) + assert.Empty(t, bucket) +} diff --git a/test/aws-component-helper/src/context.tf b/test/aws-component-helper/src/context.tf deleted file mode 100644 index 5e0ef88..0000000 --- a/test/aws-component-helper/src/context.tf +++ /dev/null @@ -1,279 +0,0 @@ -# -# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label -# All other instances of this file should be a copy of that one -# -# -# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf -# and then place it in your Terraform module to automatically get -# Cloud Posse's standard configuration inputs suitable for passing -# to Cloud Posse modules. -# -# curl -sL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf -o context.tf -# -# Modules should access the whole context as `module.this.context` -# to get the input variables with nulls for defaults, -# for example `context = module.this.context`, -# and access individual variables as `module.this.`, -# with final values filled in. -# -# For example, when using defaults, `module.this.context.delimiter` -# will be null, and `module.this.delimiter` will be `-` (hyphen). -# - -module "this" { - source = "cloudposse/label/null" - version = "0.25.0" # requires Terraform >= 0.13.0 - - enabled = var.enabled - namespace = var.namespace - tenant = var.tenant - environment = var.environment - stage = var.stage - name = var.name - delimiter = var.delimiter - attributes = var.attributes - tags = var.tags - additional_tag_map = var.additional_tag_map - label_order = var.label_order - regex_replace_chars = var.regex_replace_chars - id_length_limit = var.id_length_limit - label_key_case = var.label_key_case - label_value_case = var.label_value_case - descriptor_formats = var.descriptor_formats - labels_as_tags = var.labels_as_tags - - context = var.context -} - -# Copy contents of cloudposse/terraform-null-label/variables.tf here - -variable "context" { - type = any - default = { - enabled = true - namespace = null - tenant = null - environment = null - stage = null - name = null - delimiter = null - attributes = [] - tags = {} - additional_tag_map = {} - regex_replace_chars = null - label_order = [] - id_length_limit = null - label_key_case = null - label_value_case = null - descriptor_formats = {} - # Note: we have to use [] instead of null for unset lists due to - # https://github.com/hashicorp/terraform/issues/28137 - # which was not fixed until Terraform 1.0.0, - # but we want the default to be all the labels in `label_order` - # and we want users to be able to prevent all tag generation - # by setting `labels_as_tags` to `[]`, so we need - # a different sentinel to indicate "default" - labels_as_tags = ["unset"] - } - description = <<-EOT - Single object for setting entire context at once. - See description of individual variables for details. - Leave string and numeric variables as `null` to use default value. - Individual variable settings (non-null) override settings in context object, - except for attributes, tags, and additional_tag_map, which are merged. - EOT - - validation { - condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"]) - error_message = "Allowed values: `lower`, `title`, `upper`." - } - - validation { - condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"]) - error_message = "Allowed values: `lower`, `title`, `upper`, `none`." - } -} - -variable "enabled" { - type = bool - default = null - description = "Set to false to prevent the module from creating any resources" -} - -variable "namespace" { - type = string - default = null - description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" -} - -variable "tenant" { - type = string - default = null - description = "ID element _(Rarely used, not included by default)_. A customer identifier, indicating who this instance of a resource is for" -} - -variable "environment" { - type = string - default = null - description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" -} - -variable "stage" { - type = string - default = null - description = "ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release'" -} - -variable "name" { - type = string - default = null - description = <<-EOT - ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'. - This is the only ID element not also included as a `tag`. - The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. - EOT -} - -variable "delimiter" { - type = string - default = null - description = <<-EOT - Delimiter to be used between ID elements. - Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. - EOT -} - -variable "attributes" { - type = list(string) - default = [] - description = <<-EOT - ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`, - in the order they appear in the list. New attributes are appended to the - end of the list. The elements of the list are joined by the `delimiter` - and treated as a single ID element. - EOT -} - -variable "labels_as_tags" { - type = set(string) - default = ["default"] - description = <<-EOT - Set of labels (ID elements) to include as tags in the `tags` output. - Default is to include all labels. - Tags with empty values will not be included in the `tags` output. - Set to `[]` to suppress all generated tags. - **Notes:** - The value of the `name` tag, if included, will be the `id`, not the `name`. - Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be - changed in later chained modules. Attempts to change it will be silently ignored. - EOT -} - -variable "tags" { - type = map(string) - default = {} - description = <<-EOT - Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`). - Neither the tag keys nor the tag values will be modified by this module. - EOT -} - -variable "additional_tag_map" { - type = map(string) - default = {} - description = <<-EOT - Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`. - This is for some rare cases where resources want additional configuration of tags - and therefore take a list of maps with tag key, value, and additional configuration. - EOT -} - -variable "label_order" { - type = list(string) - default = null - description = <<-EOT - The order in which the labels (ID elements) appear in the `id`. - Defaults to ["namespace", "environment", "stage", "name", "attributes"]. - You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. - EOT -} - -variable "regex_replace_chars" { - type = string - default = null - description = <<-EOT - Terraform regular expression (regex) string. - Characters matching the regex will be removed from the ID elements. - If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. - EOT -} - -variable "id_length_limit" { - type = number - default = null - description = <<-EOT - Limit `id` to this many characters (minimum 6). - Set to `0` for unlimited length. - Set to `null` for keep the existing setting, which defaults to `0`. - Does not affect `id_full`. - EOT - validation { - condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0 - error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length." - } -} - -variable "label_key_case" { - type = string - default = null - description = <<-EOT - Controls the letter case of the `tags` keys (label names) for tags generated by this module. - Does not affect keys of tags passed in via the `tags` input. - Possible values: `lower`, `title`, `upper`. - Default value: `title`. - EOT - - validation { - condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case) - error_message = "Allowed values: `lower`, `title`, `upper`." - } -} - -variable "label_value_case" { - type = string - default = null - description = <<-EOT - Controls the letter case of ID elements (labels) as included in `id`, - set as tag values, and output by this module individually. - Does not affect values of tags passed in via the `tags` input. - Possible values: `lower`, `title`, `upper` and `none` (no transformation). - Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs. - Default value: `lower`. - EOT - - validation { - condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case) - error_message = "Allowed values: `lower`, `title`, `upper`, `none`." - } -} - -variable "descriptor_formats" { - type = any - default = {} - description = <<-EOT - Describe additional descriptors to be output in the `descriptors` output map. - Map of maps. Keys are names of descriptors. Values are maps of the form - `{ - format = string - labels = list(string) - }` - (Type is `any` so the map values can later be enhanced to provide additional options.) - `format` is a Terraform format string to be passed to the `format()` function. - `labels` is a list of labels, in order, to pass to `format()` function. - Label values will be normalized before being passed to `format()` so they will be - identical to how they appear in `id`. - Default is `{}` (`descriptors` output will be empty). - EOT -} - -#### End of copy of cloudposse/terraform-null-label/variables.tf diff --git a/test/aws-component-helper/src/main.tf b/test/aws-component-helper/src/main.tf deleted file mode 100644 index bd84792..0000000 --- a/test/aws-component-helper/src/main.tf +++ /dev/null @@ -1,24 +0,0 @@ -variable "default_tags" { - type = map(string) - default = {} -} - -variable "region" { -} - -variable "revision" { - type = string -} - -locals { - revision = join("-", concat(module.this.attributes, [var.revision])) -} - -resource "terraform_data" "replacement" { - count = module.this.enabled ? 1 : 0 - input = local.revision -} - -output "revision" { - value = module.this.enabled ? local.revision : null -} diff --git a/test/aws-component-helper/test/basic_test.go b/test/aws-component-helper/test/basic_test.go deleted file mode 100644 index 7506de5..0000000 --- a/test/aws-component-helper/test/basic_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package test - -import ( - "fmt" - "strings" - "testing" - - "github.com/cloudposse/test-helpers/pkg/atmos" - helper "github.com/cloudposse/test-helpers/pkg/atmos/aws-component-helper" - "github.com/stretchr/testify/require" - //"github.com/stretchr/testify/require" -) - -var suite *helper.Suite - -// TestMain is the entry point for the test suite. It initializes the test -// suite and runs the tests. -func TestMain(m *testing.M) { - var err error - - // Configure the test suite - suite, err = helper.NewTestSuite("us-east-2", "basic", "test-use2-sandbox") - if err != nil { - panic(err) - } - - // Add dependencies for the component under test in the same stack. If you - // want to add dependencies in different stacks, use AddDependenciesWithStacks. - // - // Dependencies are deployed in serial in the order they are added. - suite.AddDependencies([]string{"dep1", "dep2"}) - - // Create a new testing object since TestMain doesn't have one and we need - // one to call the Setup and Teardown functions - t := &testing.T{} - - defer suite.TearDown(t) - err = suite.Setup(t) - if err != nil { - panic(err) - } - - if !suite.SkipTests { - m.Run() - } -} - -func TestBasic(t *testing.T) { - additionalVars := map[string]interface{}{ - "revision": "fromTest", - } - defer suite.DestroyComponentUnderTest(t, additionalVars) - - _, err := suite.DeployComponentUnderTest(t, additionalVars) - require.NoError(t, err) - - revision := atmos.Output(t, suite.AtmosOptions, "revision") - expected := fmt.Sprintf("%s-%s", strings.ToLower(suite.RandomIdentifier), additionalVars["revision"]) - require.Equal(t, expected, revision) -} diff --git a/test/aws-component-helper/test/fixtures/stacks/orgs/test/main.yaml b/test/aws-component-helper/test/fixtures/stacks/orgs/test/main.yaml deleted file mode 100644 index 24e5976..0000000 --- a/test/aws-component-helper/test/fixtures/stacks/orgs/test/main.yaml +++ /dev/null @@ -1,50 +0,0 @@ -vars: - namespace: cptest - tenant: test - environment: use2 - stage: sandbox - -# This should be moved to the catalog -terraform: - backend_type: local - backend: - local: - path: ../../../state/{{ getenv "TEST_SUITE_NAME" | default "" }}/{{ .component }}/terraform.tfstate - workspace_dir: ../../../state/{{ getenv "TEST_SUITE_NAME" | default "" }}/{{ .component }}/ - settings: {} - vars: - label_order: - - namespace - - tenant - - environment - - stage - - name - - attributes - descriptor_formats: - account_name: - format: "%v-%v" - labels: - - tenant - - stage - stack: - format: "%v-%v-%v" - labels: - - tenant - - environment - - stage - -components: - terraform: - dep1: - metadata: - component: basic - vars: - revision: 21 - dep2: - metadata: - component: basic - vars: - revision: 22 - basic: - vars: - revision: 1 diff --git a/test/aws-component-helper/test/fixtures/vendor.yaml b/test/aws-component-helper/test/fixtures/vendor.yaml deleted file mode 100644 index 95044dd..0000000 --- a/test/aws-component-helper/test/fixtures/vendor.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: atmos/v1 -kind: AtmosVendorConfig -metadata: - name: test-vendor-config - description: Atmos vendoring manifest for testing -spec: - # `imports` or `sources` (or both) must be defined in a vendoring manifest - imports: [] - - sources: - - component: "vpc" - source: "github.com/cloudposse/terraform-aws-components.git//modules/vpc?ref={{.Version}}" - version: "1.398.0" - targets: - - "components/terraform/vpc" - included_paths: - - "**/*.tf" - excluded_paths: - - "**/providers.tf" - tags: - - networking - - component: "vpc-flow-logs-bucket" - source: "github.com/cloudposse/terraform-aws-components.git//modules/vpc-flow-logs-bucket?ref={{.Version}}" - version: "1.398.0" - targets: - - "components/terraform/vpc-flow-logs-bucket" - included_paths: - - "**/*.tf" - excluded_paths: - - "**/providers.tf" - tags: - - storage diff --git a/test/fixtures/aws-component-helper/atmos.yaml b/test/fixtures/aws-component-helper/atmos.yaml index 4529e24..eb253be 100644 --- a/test/fixtures/aws-component-helper/atmos.yaml +++ b/test/fixtures/aws-component-helper/atmos.yaml @@ -74,13 +74,3 @@ templates: # https://docs.gomplate.ca gomplate: enabled: true - -commands: - - name: "test-components" - description: "List the Atmos virtual components configured for testing" - steps: - - > - atmos describe stacks --format json --sections=component,metadata --components=component -s sandbox - | jq '.[] | .components.terraform | to_entries | - map(select(.value.component == "component" and (.value.metadata.type != "abstract" or .value.metadata.type == null))) - | .[].key' diff --git a/test/fixtures/aws-component-helper/stacks/catalog/account-map.yaml b/test/fixtures/aws-component-helper/stacks/catalog/account-map.yaml index 904e69a..3735838 100644 --- a/test/fixtures/aws-component-helper/stacks/catalog/account-map.yaml +++ b/test/fixtures/aws-component-helper/stacks/catalog/account-map.yaml @@ -8,18 +8,6 @@ components: environment: gbl stage: root -# This remote state is only for Cloud Posse internal use. -# It references the Cloud Posse test organizations actual infrastructure. -# remote_state_backend: -# s3: -# bucket: cptest-core-ue2-root-tfstate-core -# dynamodb_table: cptest-core-ue2-root-tfstate-core-lock -# role_arn: arn:aws:iam::822777368227:role/cptest-core-gbl-root-tfstate-core-ro -# encrypt: true -# key: terraform.tfstate -# acl: bucket-owner-full-control -# region: us-east-2 - remote_state_backend_type: static remote_state_backend: # This static backend is used for tests that only need to use the account map iam-roles module diff --git a/test/fixtures/aws-component-helper/vendor.yaml b/test/fixtures/aws-component-helper/vendor.yaml index 2c5489e..c5ec0ee 100644 --- a/test/fixtures/aws-component-helper/vendor.yaml +++ b/test/fixtures/aws-component-helper/vendor.yaml @@ -16,14 +16,3 @@ spec: - "**/*.tftmpl" - "**/modules/**" excluded_paths: [] - -# - component: "vpc" -# source: "../../src" -# targets: -# - "components/terraform/vpc" -# included_paths: -# - "**/*.tf" -# - "**/*.md" -# - "**/*.tftmpl" -# - "**/modules/**" -# excluded_paths: [] From 9575b76a8d6c4afc1c6e618c5ae4f8895b32eb60 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 21:20:44 +0100 Subject: [PATCH 27/40] Added comments --- pkg/atmos/aws-component-helper/fixture.go | 67 +++++++++++++++------- pkg/atmos/aws-component-helper/shared.go | 1 + pkg/atmos/aws-component-helper/suite.go | 69 +++++++++++++++++------ 3 files changed, 99 insertions(+), 38 deletions(-) diff --git a/pkg/atmos/aws-component-helper/fixture.go b/pkg/atmos/aws-component-helper/fixture.go index 84bed8f..eae0097 100644 --- a/pkg/atmos/aws-component-helper/fixture.go +++ b/pkg/atmos/aws-component-helper/fixture.go @@ -14,10 +14,12 @@ import ( "github.com/stretchr/testify/require" ) +// Define global callback function to retrieve AWS account ID var ( getAwsAaccountIdCallback = getAwsAccountId ) +// Define global flags for configuring test behavior var ( skipTmpDir = flag.Bool("skip-tmp-dir", false, "Run in the current directory") skipVendorDependencies = flag.Bool("skip-vendor", false, "skip vendor dependencies") @@ -27,35 +29,40 @@ var ( matchSuiteAndTest = flag.String("match", "", "regular expression to select suite and tests to run") ) +// Fixture struct holds test-specific configurations and state type Fixture struct { - t *testing.T - RandomIdentifier string - AwsAccountId string - AwsRegion string - SourceDir string - TempDir string - FixturesPath string - State *State - suites []*Suite - suitesNames []string + t *testing.T // Testing object + RandomIdentifier string // Unique identifier for the fixture + AwsAccountId string // AWS Account ID + AwsRegion string // AWS Region + SourceDir string // Source directory for the fixture + TempDir string // Temporary directory for the fixture + FixturesPath string // Path to the fixture directory + State *State // State management object + suites []*Suite // List of test suites + suitesNames []string // Names of test suites } +// NewFixture initializes a new Fixture instance func NewFixture(t *testing.T, sourceDir string, awsRegion string, fixturesDir string) *Fixture { awsAccountId, err := getAwsAaccountIdCallback() - require.NoError(t, err) + require.NoError(t, err) // Ensure AWS account ID retrieval succeeded randID := random.UniqueId() randomId := strings.ToLower(randID) + // Create a temporary directory path for the fixture tmpdir := filepath.Join(os.TempDir(), "fixtures-"+randomId) realSourcePath, err := filepath.Abs(sourceDir) - require.NoError(t, err) + require.NoError(t, err) // Ensure source directory resolution succeeded + // Initialize state with namespace and state directory state_namespace := strings.ReplaceAll(filepath.Join(t.Name(), fixturesDir), "/", "-") state := NewState(state_namespace, filepath.Join(realSourcePath, "state")) - suites := &Fixture{ + // Return initialized Fixture instance + return &Fixture{ t: t, RandomIdentifier: randomId, SourceDir: realSourcePath, @@ -67,10 +74,9 @@ func NewFixture(t *testing.T, sourceDir string, awsRegion string, fixturesDir st suitesNames: []string{}, State: state, } - - return suites } +// WorkDir returns the working directory based on the skipTmpDir flag func (ts *Fixture) WorkDir() string { if !*skipTmpDir { return ts.TempDir @@ -79,79 +85,98 @@ func (ts *Fixture) WorkDir() string { } } +// FixtureDir returns the path to the fixture directory func (ts *Fixture) FixtureDir() string { return filepath.Join(ts.WorkDir(), ts.FixturesPath) } +// SetUp prepares the fixture for use func (ts *Fixture) SetUp(options *atmos.Options) { suitesOptions := ts.getAtmosOptions(options, map[string]interface{}{}) + + // Create temporary directory if skipTmpDir flag is not set if !*skipTmpDir { fmt.Printf("Create fixtures tmp dir: %s \n", ts.TempDir) err := os.Mkdir(ts.TempDir, 0777) - require.NoError(ts.t, err) + require.NoError(ts.t, err) // Ensure directory creation succeeded err = copyDirectoryRecursively(ts.SourceDir, ts.TempDir) - require.NoError(ts.t, err) + require.NoError(ts.t, err) // Ensure directory copy succeeded } else { fmt.Printf("Use fixtures source dir: %s \n", ts.SourceDir) } + // Handle vendor dependencies based on skipVendorDependencies flag if !*skipVendorDependencies { atmosVendorPull(ts.t, suitesOptions) } else { fmt.Println("Skip Vendor Pull") } + // Set up state err := ts.State.SetUp() require.NoError(ts.t, err) + // Create cache directory if useCache flag is set if *useCache { err = createDir(ts.WorkDir(), ".cache") require.NoError(ts.t, err) } } +// TearDown cleans up resources created by the fixture func (ts *Fixture) TearDown() { if *skipTeardown { fmt.Println("Skip teardown") return } + + // Run teardown for all suites for i := len(ts.suites) - 1; i >= 0; i-- { ts.suites[i].runTeardown() } + + // Remove temporary directory if skipTmpDir and skipTeardownFixtures flags are not set if !*skipTmpDir && !*skipTeardownFixtures { err := os.RemoveAll(ts.TempDir) require.NoError(ts.t, err) } + + // Tear down state err := ts.State.Teardown() require.NoError(ts.t, err) } +// getAtmosOptions generates options for Atmos CLI with environment variables and state func (ts *Fixture) getAtmosOptions(options *atmos.Options, vars map[string]interface{}) *atmos.Options { result := &atmos.Options{} if options != nil { - result, _ = options.Clone() + result, _ = options.Clone() // Clone existing options } + // Configure Atmos options result.AtmosBasePath = ts.FixtureDir() result.NoColor = true result.Lock = false result.Upgrade = true + // Define environment variables envvars := map[string]string{ "TEST_ACCOUNT_ID": ts.AwsAccountId, "ATMOS_BASE_PATH": result.AtmosBasePath, "ATMOS_CLI_CONFIG_PATH": result.AtmosBasePath, } + // Add cache directory if useCache flag is set if *useCache { envvars["TF_PLUGIN_CACHE_DIR"] = filepath.Join(ts.WorkDir(), ".cache") } - err := mergo.Merge(&result.EnvVars, envvars) + err := mergo.Merge(&result.EnvVars, envvars) // Merge environment variables require.NoError(ts.t, err) + // Define and merge fixture-specific variables fixtureVars := map[string]interface{}{ "region": ts.AwsRegion, } @@ -165,14 +190,16 @@ func (ts *Fixture) getAtmosOptions(options *atmos.Options, vars map[string]inter return result } +// Suite adds a test suite to the Fixture func (ts *Fixture) Suite(name string, f func(t *testing.T, suite *Suite)) { require.NotContains(ts.t, ts.suitesNames, name, "Suite %s already exists", name) - suite := NewSuite(ts.t, name, ts) + suite := NewSuite(ts.t, name, ts) // Create new suite ts.suites = append(ts.suites, suite) ts.suitesNames = append(ts.suitesNames, name) + // Run the suite if it matches the filter suiteRunName := fmt.Sprintf("%s/%s", ts.t.Name(), suite.name) if ok, err := matchFilter(suiteRunName); ok { ts.t.Run(name, func(t *testing.T) { diff --git a/pkg/atmos/aws-component-helper/shared.go b/pkg/atmos/aws-component-helper/shared.go index 5442d23..f20c78e 100644 --- a/pkg/atmos/aws-component-helper/shared.go +++ b/pkg/atmos/aws-component-helper/shared.go @@ -9,6 +9,7 @@ import ( "runtime" "strings" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/sts" ) diff --git a/pkg/atmos/aws-component-helper/suite.go b/pkg/atmos/aws-component-helper/suite.go index 7dad9ba..9587f16 100644 --- a/pkg/atmos/aws-component-helper/suite.go +++ b/pkg/atmos/aws-component-helper/suite.go @@ -13,33 +13,43 @@ import ( "github.com/stretchr/testify/require" ) +// Flags for controlling test behavior var ( skipTests = flag.Bool("skip-tests", false, "skip tests") skipSetup = flag.Bool("skip-setup", false, "skip setup") ) +// Structure to define a teardown step type teadDown struct { - component *AtmosComponent - callback *func(t *testing.T, atm *Atmos) + component *AtmosComponent // The component to be torn down + callback *func(t *testing.T, atm *Atmos) // Optional teardown callback } +// Suite represents a test suite and its associated configurations, state, and dependencies type Suite struct { - t *testing.T - randomIdentifier string - name string - dependencies []*AtmosComponent - teardown []*teadDown - options *atmos.Options - state *State + t *testing.T // Testing object + randomIdentifier string // Unique identifier for the suite + name string // Suite name + dependencies []*AtmosComponent // Dependencies for the suite + teardown []*teadDown // Teardown steps + options *atmos.Options // Atmos options for the suite + state *State // State associated with the suite } +// NewSuite initializes a new Suite instance func NewSuite(t *testing.T, name string, fixture *Fixture) *Suite { randID := random.UniqueId() randomId := strings.ToLower(randID) + + // Ensure suite name does not contain invalid characters require.NotContains(t, name, "/") + + // Fork the state for the suite suiteState, err := fixture.State.Fork(name) require.NoError(t, err) - suite := &Suite{ + + // Initialize and return the Suite + return &Suite{ t: t, name: name, randomIdentifier: randomId, @@ -48,74 +58,94 @@ func NewSuite(t *testing.T, name string, fixture *Fixture) *Suite { teardown: []*teadDown{}, options: fixture.getAtmosOptions(&atmos.Options{}, map[string]interface{}{}), } - return suite } +// AddDependency adds a component dependency to the suite and deploys it func (ts *Suite) AddDependency(componentName string, stackName string) { component := NewAtmosComponent(componentName, stackName, nil) ts.dependencies = append(ts.dependencies, component) ts.teardown = append(ts.teardown, &teadDown{component: component, callback: nil}) + if *skipSetup { fmt.Printf("Skip suite %s setup dependency component: %s stack: %s\n", ts.name, componentName, stackName) return } + + // Deploy the component using Atmos with suite TF state ts.getAtmos(ts.state).Deploy(component) } +// getAtmos returns an Atmos instance configured for the suite's state func (ts *Suite) getAtmos(state *State) *Atmos { return NewAtmos(ts.t, state, ts.getAtmosOptions(map[string]interface{}{ "attributes": []string{ts.randomIdentifier}, })) } +// getTestAtmos returns an Atmos instance for test-specific purposes func (ts *Suite) getTestAtmos(state *State) *Atmos { return NewAtmos(ts.t, state, ts.getAtmosOptions(map[string]interface{}{})) } +// runTeardown executes all teardown steps for the suite func (ts *Suite) runTeardown() { if *skipTeardown { fmt.Printf("Skip teardown suite %s\n", ts.name) return } + atm := ts.getAtmos(ts.state) - var f *teadDown for i := len(ts.teardown) - 1; i >= 0; i-- { - f = ts.teardown[i] - if f.callback != nil { - (*f.callback)(ts.t, atm) + step := ts.teardown[i] + + // Execute the callback, if provided + if step.callback != nil { + (*step.callback)(ts.t, atm) } - if f.component != nil { - atm.Destroy(f.component) + + // Destroy the component, if applicable + if step.component != nil { + atm.Destroy(step.component) } } + + // Teardown the suite's state err := ts.state.Teardown() assert.NoError(ts.t, err) } +// Setup executes a setup callback for the suite func (ts *Suite) Setup(t *testing.T, f func(t *testing.T, atm *Atmos)) { if *skipSetup { fmt.Printf("Skip suite %s setup callback\n", ts.name) return } + // Get Atmos with suite TF state atm := ts.getAtmos(ts.state) f(t, atm) } +// TearDown adds a custom teardown callback to the suite func (ts *Suite) TearDown(t *testing.T, f func(t *testing.T, atm *Atmos)) { ts.teardown = append(ts.teardown, &teadDown{component: nil, callback: &f}) } +// Test runs a test within the suite func (ts *Suite) Test(t *testing.T, name string, f func(t *testing.T, atm *Atmos)) { if *skipTests { fmt.Printf("Skip test %s/%s\n", ts.name, name) return } + // Fork the state for the test testState, err := ts.state.Fork(name) require.NoError(t, err) - defer testState.Teardown() + defer testState.Teardown() // Ensure test state is torn down after execution + // Get Atmos with test TF state atm := ts.getTestAtmos(testState) + + // Run the test if it matches the filter testRunName := fmt.Sprintf("%s/%s", t.Name(), name) if ok, err := matchFilter(testRunName); ok { t.Run(name, func(t *testing.T) { @@ -126,16 +156,19 @@ func (ts *Suite) Test(t *testing.T, name string, f func(t *testing.T, atm *Atmos } } +// getAtmosOptions generates Atmos options for the suite with additional variables func (ts *Suite) getAtmosOptions(vars map[string]interface{}) *atmos.Options { result, err := ts.options.Clone() require.NoError(ts.t, err) + // Merge the provided variables into the options err = mergo.Merge(&result.Vars, vars) require.NoError(ts.t, err) return result } +// GetRandomIdentifier returns the suite's unique random identifier func (ts *Suite) GetRandomIdentifier() string { return ts.randomIdentifier } From f187ceefabea134730dee39c3c1647726875f173 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 21:22:35 +0100 Subject: [PATCH 28/40] Added comments --- pkg/atmos/aws-component-helper/state.go | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/pkg/atmos/aws-component-helper/state.go b/pkg/atmos/aws-component-helper/state.go index 4725edf..6f0fb23 100644 --- a/pkg/atmos/aws-component-helper/state.go +++ b/pkg/atmos/aws-component-helper/state.go @@ -8,63 +8,82 @@ import ( "strings" ) +// Global flag to determine whether to preserve state files during teardown var ( preserveStates = flag.Bool("preserve-states", true, "preserve states") ) +// State represents the file-based state for a component, including its base directory and namespace type State struct { - basepath string - namespace string + basepath string // Base directory for the state + namespace string // Namespace identifier for the state } +// NewState initializes a new State instance with the given namespace and root directory func NewState(name, rootDir string) *State { basePath := rootDir return &State{ basepath: basePath, - namespace: strings.ToLower(name), + namespace: strings.ToLower(name), // Namespace is converted to lowercase for consistency } } +// Fork creates a new State as a "child" of the current state, copying the contents of the current state directory func (s *State) Fork(name string) (*State, error) { + // Create a new namespace by appending the child name to the current namespace namespace := fmt.Sprintf("%s.%s", s.namespace, name) result := NewState(namespace, s.basepath) + + // Set up the new state directory if err := result.SetUp(); err != nil { return nil, err } + + // Copy the current state directory to the new state directory if err := copyDirectoryRecursively(s.CurrentDir(), result.CurrentDir()); err != nil { return nil, err } + return result, nil } +// SetUp creates the necessary directories for the state func (s *State) SetUp() error { + // Create the base directory if it doesn't exist if err := createDir(s.basepath, ""); err != nil { return err } + // Create the namespace-specific directory within the base directory if err := createDir(s.CurrentDir(), ""); err != nil { return err } return nil } +// Teardown removes the state directory unless the preserveStates flag is set func (s *State) Teardown() error { if *preserveStates { + // If preserving states, log the action and skip directory removal fmt.Printf("Preserve states %s\n", s.namespace) return nil } else { + // Otherwise, remove the state directory return os.RemoveAll(s.CurrentDir()) } } +// CurrentDir returns the full path to the namespace-specific state directory func (s *State) CurrentDir() string { return filepath.Join(s.basepath, s.NamespaceDir()) } +// NamespaceDir returns the directory name for the namespace (prefixed with a dot) func (s *State) NamespaceDir() string { return fmt.Sprintf(".%s", s.namespace) } +// BaseDir returns the base directory for the state func (s *State) BaseDir() string { return s.basepath } From 7e8103838391408bf5c04bcabc4f17c59bfc1c15 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 21:25:04 +0100 Subject: [PATCH 29/40] Added comments --- pkg/atmos/aws-component-helper/state_test.go | 60 +++++++++++++------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/pkg/atmos/aws-component-helper/state_test.go b/pkg/atmos/aws-component-helper/state_test.go index e31aff7..635ea05 100644 --- a/pkg/atmos/aws-component-helper/state_test.go +++ b/pkg/atmos/aws-component-helper/state_test.go @@ -11,72 +11,92 @@ import ( "github.com/stretchr/testify/require" ) +// TestState contains tests for the State struct and its methods func TestState(t *testing.T) { - t.Parallel() - + // Test the basic functionality of the State struct t.Run("basic", func(t *testing.T) { - *preserveStates = false + *preserveStates = false // Disable state preservation for this test + // Copy a folder to a temporary test folder testFolder, err := files.CopyFolderToTemp("../../../", strings.Replace(t.Name(), "/", "-", -1), func(path string) bool { return true }) require.NoError(t, err) - defer os.RemoveAll(testFolder) + defer os.RemoveAll(testFolder) // Ensure test folder is removed after the test + // Create a new State instance state := NewState("default", testFolder) + // Validate initial state attributes assert.Equal(t, state.basepath, testFolder) assert.Equal(t, state.namespace, "default") + // Set up the state (create necessary directories) err = state.SetUp() assert.NoError(t, err) + // Ensure directories exist assert.DirExists(t, state.basepath) assert.DirExists(t, state.CurrentDir()) + // Teardown the state (remove namespace-specific directory) state.Teardown() - assert.NoDirExists(t, state.CurrentDir()) - assert.DirExists(t, state.basepath) + assert.NoDirExists(t, state.CurrentDir()) // Namespace directory should no longer exist + assert.DirExists(t, state.basepath) // Base directory should still exist }) + // Test the Fork method of the State struct t.Run("fork", func(t *testing.T) { - *preserveStates = false + *preserveStates = false // Disable state preservation for this test + // Copy a folder to a temporary test folder testFolder, err := files.CopyFolderToTemp("../../../", strings.Replace(t.Name(), "/", "-", -1), func(path string) bool { return true }) require.NoError(t, err) - defer os.RemoveAll(testFolder) + defer os.RemoveAll(testFolder) // Ensure test folder is removed after the test + // Create a new State instance state := NewState("default", testFolder) + // Validate initial state attributes assert.Equal(t, state.basepath, testFolder) assert.Equal(t, state.namespace, "default") + // Set up the state err = state.SetUp() assert.NoError(t, err) + // Ensure directories exist assert.DirExists(t, state.basepath) assert.DirExists(t, state.CurrentDir()) + // Create a temporary file in the current state directory file, err := os.CreateTemp(state.CurrentDir(), "tmpfile") assert.FileExists(t, file.Name()) + fileName := filepath.Base(file.Name()) // Store the file name for verification later - fileName := filepath.Base(file.Name()) - + // Fork the state to create a child state forkState, err := state.Fork("fork") require.NoError(t, err) - assert.NotEqual(t, forkState.CurrentDir(), state.CurrentDir()) - assert.DirExists(t, forkState.CurrentDir()) - assert.FileExists(t, filepath.Join(forkState.CurrentDir(), fileName)) + // Validate forked state attributes + assert.NotEqual(t, forkState.CurrentDir(), state.CurrentDir()) // Forked state should have a different directory + assert.DirExists(t, forkState.CurrentDir()) // Forked directory should exist + assert.FileExists(t, filepath.Join(forkState.CurrentDir(), fileName)) // Forked directory should contain the copied file + + // Validate parent state directories assert.DirExists(t, state.basepath) assert.DirExists(t, state.CurrentDir()) + + // Teardown the parent state state.Teardown() - assert.NoDirExists(t, state.CurrentDir()) - assert.DirExists(t, state.basepath) + assert.NoDirExists(t, state.CurrentDir()) // Parent namespace directory should no longer exist + assert.DirExists(t, state.basepath) // Base directory should still exist - assert.DirExists(t, forkState.CurrentDir()) - assert.FileExists(t, filepath.Join(forkState.CurrentDir(), fileName)) + // Validate forked state directories + assert.DirExists(t, forkState.CurrentDir()) // Forked directory should still exist + assert.FileExists(t, filepath.Join(forkState.CurrentDir(), fileName)) // File should still exist in the forked directory + + // Teardown the forked state forkState.Teardown() - assert.NoDirExists(t, forkState.CurrentDir()) - assert.DirExists(t, forkState.basepath) + assert.NoDirExists(t, forkState.CurrentDir()) // Forked namespace directory should no longer exist + assert.DirExists(t, forkState.basepath) // Base directory should still exist }) - } From e8a8df2f57f8a645bdee1bfdf14aa2f080a77e0e Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 21:27:15 +0100 Subject: [PATCH 30/40] Added comments --- pkg/atmos/aws-component-helper/shared.go | 40 +++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/pkg/atmos/aws-component-helper/shared.go b/pkg/atmos/aws-component-helper/shared.go index f20c78e..fa9fdd0 100644 --- a/pkg/atmos/aws-component-helper/shared.go +++ b/pkg/atmos/aws-component-helper/shared.go @@ -14,9 +14,11 @@ import ( "github.com/aws/aws-sdk-go-v2/service/sts" ) +// copyDirectoryRecursively copies all contents of the source directory (srcDir) to the destination directory (destDir). func copyDirectoryRecursively(srcDir string, destDir string) error { fmt.Println("copying contents of", srcDir, "to", destDir) - // Walk through all files and directories in srcDir and copy them to destDir + + // Walk through all files and directories in the source directory return filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error { if err != nil { return err @@ -28,28 +30,30 @@ func copyDirectoryRecursively(srcDir string, destDir string) error { return err } - // Calculate destination path in destDir + // Create the corresponding destination path destPath := filepath.Join(destDir, relPath) if info.IsDir() { - // Create directory in destination + // Create the directory at the destination return os.MkdirAll(destPath, info.Mode()) } else { - // Copy file content + // Read the file contents content, err := os.ReadFile(path) if err != nil { return err } + // Write the file contents to the destination return os.WriteFile(destPath, content, info.Mode()) } }) } -// Parse a list output in the format it is returned by Terraform 0.12 and newer versions +// parseListOutputTerraform converts a list of interface{} (as returned by Terraform outputs) to a list of strings. func parseListOutputTerraform(outputList []interface{}) ([]string, error) { list := []string{} + // Convert each item to a string for _, item := range outputList { list = append(list, fmt.Sprintf("%v", item)) } @@ -57,16 +61,21 @@ func parseListOutputTerraform(outputList []interface{}) ([]string, error) { return list, nil } +// matchFilter checks if a test name matches a filter (defined in *matchSuiteAndTest). +// The filter is split into parts and matched against the name using regex. func matchFilter(name string) (bool, error) { nameParts := strings.Split(name, "/") + // Validate that the name has at least one '/' if len(nameParts) == 1 { return false, fmt.Errorf("Invalid test name: %s. Should contains at least 1 '/'", name) } - nameParts = nameParts[1:] + nameParts = nameParts[1:] // Exclude the first part of the name + // Split the filter into parts matchParts := strings.Split(*matchSuiteAndTest, "/") + // Match only up to the smallest number of parts partsCount := min(len(nameParts), len(matchParts)) for i := 0; i < partsCount; i++ { @@ -82,8 +91,11 @@ func matchFilter(name string) (bool, error) { return true, nil } +// createDir creates a directory (and any necessary parent directories) at the specified location. func createDir(tempDir string, name string) error { dir := filepath.Join(tempDir, name) + + // Check if the directory exists; create it if it doesn't if _, err := os.Stat(dir); os.IsNotExist(err) { err := os.MkdirAll(dir, 0777) return err @@ -92,8 +104,11 @@ func createDir(tempDir string, name string) error { return nil } +// createTerraformComponentsDir creates the directory structure for Terraform components under the given tempDir. func createTerraformComponentsDir(tempDir string) error { stateDir := filepath.Join(tempDir, "components", "terraform") + + // Check if the directory exists; create it if it doesn't if _, err := os.Stat(stateDir); os.IsNotExist(err) { err := os.MkdirAll(stateDir, 0777) return err @@ -102,32 +117,41 @@ func createTerraformComponentsDir(tempDir string) error { return nil } +// getTestName retrieves the name of the current test file (without the extension) and appends an underscore. func getTestName() (string, error) { _, filename, _, ok := runtime.Caller(0) - if !ok { return "", fmt.Errorf("unable to get the test file name") } + // Remove the file extension and append an underscore testName := filepath.Base(filename[:len(filename)-3]) + "_" return testName, nil } +// getAwsAccountId retrieves the AWS account ID of the caller using the AWS STS service. func getAwsAccountId() (string, error) { ctx := context.Background() + + // Load AWS configuration cfg, err := config.LoadDefaultConfig(ctx) if err != nil { return "", err } - // Add retries for better reliability + + // Configure retries for reliability cfg.RetryMode = aws.RetryModeAdaptive cfg.RetryMaxAttempts = 3 + // Create an STS client stsClient := sts.NewFromConfig(cfg) + + // Get the caller's identity identity, err := stsClient.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{}) if err != nil { return "", err } + // Return the AWS account ID return *identity.Account, nil } From 89add67c9e6bcfffd4628e5829980f239b94b45d Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 21:33:08 +0100 Subject: [PATCH 31/40] Added comments --- .../aws-component-helper/fixture_test.go | 32 ++++++++-- pkg/atmos/aws-component-helper/shared_test.go | 60 +++++++++++++------ 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/pkg/atmos/aws-component-helper/fixture_test.go b/pkg/atmos/aws-component-helper/fixture_test.go index 19320b3..551cc12 100644 --- a/pkg/atmos/aws-component-helper/fixture_test.go +++ b/pkg/atmos/aws-component-helper/fixture_test.go @@ -8,14 +8,15 @@ import ( "github.com/cloudposse/test-helpers/pkg/atmos" tt "github.com/cloudposse/test-helpers/pkg/testing" "github.com/gruntwork-io/terratest/modules/files" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const atmosExamplePath = "test/fixtures/aws-component-helper" +// mockAtmos provides mock implementations for Atmos commands used in the tests func mockAtmos() { + // Mock the "apply" command atmosApply = func(_ tt.TestingT, options *atmos.Options) string { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "apply", "-input=false", "-auto-approve")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) @@ -23,6 +24,7 @@ func mockAtmos() { return "" } + // Mock the "destroy" command atmosDestroy = func(_ tt.TestingT, options *atmos.Options) string { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "destroy", "-input=false", "-auto-approve")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) @@ -30,6 +32,7 @@ func mockAtmos() { return "" } + // Mock the "plan" command with exit code atmosPlanExitCodeE = func(_ tt.TestingT, options *atmos.Options) (int, error) { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "plan", "-input=false", "-detailed-exitcode")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) @@ -37,6 +40,7 @@ func mockAtmos() { return 0, nil } + // Mock the "vendor pull" command atmosVendorPull = func(_ tt.TestingT, options *atmos.Options) string { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "vendor", "pull")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) @@ -44,6 +48,7 @@ func mockAtmos() { return "" } + // Mock the "output all" command atmosOutputAllE = func(_ tt.TestingT, options *atmos.Options, _ string, _ interface{}) error { options, args := atmos.GetCommonOptions(options, atmos.FormatArgs(options, "terraform", "output", "--skip-init", "--json")...) description := fmt.Sprintf("%s %v", options.AtmosBinary, args) @@ -52,6 +57,7 @@ func mockAtmos() { } } +// TestFixtureMinimum validates the minimal initialization of a Fixture func TestFixtureMinimum(t *testing.T) { componentTestSuites := &Fixture{ FixturesPath: "testdata/fixtures", @@ -59,56 +65,71 @@ func TestFixtureMinimum(t *testing.T) { AwsAccountId: "123456789012", AwsRegion: "us-west-2", } + + // Assert that the Fixture fields are correctly initialized assert.Equal(t, componentTestSuites.FixturesPath, "testdata/fixtures") assert.Equal(t, componentTestSuites.TempDir, "testdata/tmp") assert.Equal(t, componentTestSuites.AwsAccountId, "123456789012") assert.Equal(t, componentTestSuites.AwsRegion, "us-west-2") } +// TestFixtureCreate validates the setup of a Fixture with a temporary folder func TestFixtureCreate(t *testing.T) { + // Mock AWS Account ID retrieval getAwsAaccountIdCallback = func() (string, error) { return "123456789012", nil } + // Create a temporary folder for the test testFolder, err := files.CopyTerraformFolderToTemp("../../../", t.Name()) require.NoError(t, err) defer os.RemoveAll(testFolder) fmt.Printf("running in %s\n", testFolder) + // Create a new Fixture componentTestSuites := NewFixture(t, testFolder, "us-west-2", atmosExamplePath) assert.Equal(t, componentTestSuites.SourceDir, testFolder) - defer componentTestSuites.TearDown() + defer componentTestSuites.TearDown() // Ensure cleanup componentTestSuites.SetUp(&atmos.Options{}) } +// TestFixtureSuitesRun validates the execution of test suites within a Fixture func TestFixtureSuitesRun(t *testing.T) { + // Mock AWS Account ID retrieval getAwsAaccountIdCallback = func() (string, error) { return "123456789012", nil } + // Mock Atmos commands mockAtmos() + // Create a temporary folder for the test testFolder, err := files.CopyFolderToTemp("../../../", t.Name(), func(path string) bool { return true }) require.NoError(t, err) defer os.RemoveAll(testFolder) fmt.Printf("running in %s\n", testFolder) + // Initialize the Fixture fixture := NewFixture(t, testFolder, "us-west-2", atmosExamplePath) fixture.SetUp(&atmos.Options{}) - defer fixture.TearDown() + defer fixture.TearDown() // Ensure cleanup + // Define a test suite fixture.Suite("default", func(t *testing.T, suite *Suite) { + // Add a dependency suite.AddDependency("vpc/deps", "default-test") + // Setup step suite.Setup(t, func(t *testing.T, atm *Atmos) { atm.GetAndDeploy("vpc/manual-deps", "default-test", nil) }) + // First test case suite.Test(t, "two-private-subnets", func(t *testing.T, atm *Atmos) { inputs := map[string]interface{}{ "name": "vpc-terraform", @@ -126,14 +147,15 @@ func TestFixtureSuitesRun(t *testing.T) { defer atm.Destroy(component) }) + // Second test case suite.Test(t, "public-subnets", func(t *testing.T, atm *Atmos) { component := atm.GetAndDeploy("vpc/full", "default-test", nil) defer atm.Destroy(component) }) + // Teardown step suite.TearDown(t, func(t *testing.T, atm *Atmos) { atm.GetAndDestroy("vpc/manual-deps", "default-test", nil) }) }) - } diff --git a/pkg/atmos/aws-component-helper/shared_test.go b/pkg/atmos/aws-component-helper/shared_test.go index 4c139a9..f62a5df 100644 --- a/pkg/atmos/aws-component-helper/shared_test.go +++ b/pkg/atmos/aws-component-helper/shared_test.go @@ -7,54 +7,63 @@ import ( "github.com/stretchr/testify/assert" ) +// TestMatchFilter tests the matchFilter function under various input scenarios func TestMatchFilter(t *testing.T) { + // Case: Invalid test name without a '/' (should return an error) t.Run("wrong", func(t *testing.T) { matchRegexp := "" matchSuiteAndTest = &matchRegexp result, err := matchFilter("TestAcceptance") - assert.Error(t, err) - assert.False(t, result) + assert.Error(t, err) // Expect an error due to invalid format + assert.False(t, result) // Result should be false }) + // Case: Match the default suite t.Run("default", func(t *testing.T) { matchRegexp := "" matchSuiteAndTest = &matchRegexp result, err := matchFilter("TestAcceptance/default") - assert.NoError(t, err) - assert.True(t, result) + assert.NoError(t, err) // No error expected + assert.True(t, result) // Should match the default suite }) + // Case: Match a specific suite t.Run("suite", func(t *testing.T) { matchRegexp := "default" matchSuiteAndTest = &matchRegexp result, err := matchFilter("TestAcceptance/default") - assert.NoError(t, err) - assert.True(t, result) + assert.NoError(t, err) // No error expected + assert.True(t, result) // Should match the suite }) + // Case: Match all tests within a suite t.Run("all tests", func(t *testing.T) { matchRegexp := "default" matchSuiteAndTest = &matchRegexp result, err := matchFilter("TestAcceptance/default/test1") - assert.NoError(t, err) - assert.True(t, result) + assert.NoError(t, err) // No error expected + assert.True(t, result) // Should match all tests under "default" }) + // Case: Match a specific test within a suite t.Run("one test tests", func(t *testing.T) { matchRegexp := "default/test1" matchSuiteAndTest = &matchRegexp result, err := matchFilter("TestAcceptance/default/test1") - assert.NoError(t, err) - assert.True(t, result) + assert.NoError(t, err) // No error expected + assert.True(t, result) // Should match "test1" result, err = matchFilter("TestAcceptance/default/test2") - assert.NoError(t, err) - assert.False(t, result) + assert.NoError(t, err) // No error expected + assert.False(t, result) // Should not match "test2" }) + // Case: Match multilevel subtests t.Run("multilevel subtests", func(t *testing.T) { matchRegexp := "default/test1" matchSuiteAndTest = &matchRegexp + + // Matches subtests under "test1" result, err := matchFilter("TestAcceptance/default/test1/subtest1") assert.NoError(t, err) assert.True(t, result) @@ -63,6 +72,7 @@ func TestMatchFilter(t *testing.T) { assert.NoError(t, err) assert.True(t, result) + // Does not match subtests under "test2" result, err = matchFilter("TestAcceptance/default/test2/subtest1") assert.NoError(t, err) assert.False(t, result) @@ -72,21 +82,28 @@ func TestMatchFilter(t *testing.T) { assert.False(t, result) }) + // Case: Filter longer than the test hierarchy t.Run("filter longer then test", func(t *testing.T) { matchRegexp := "default/test1/subtest1" matchSuiteAndTest = &matchRegexp + + // Matches as filter is more specific than the test path result, err := matchFilter("TestAcceptance/default/test1") assert.NoError(t, err) assert.True(t, result) + // Does not match unrelated paths result, err = matchFilter("TestAcceptance/default/test2/subtest1") assert.NoError(t, err) assert.False(t, result) }) + // Case: Use regex for matching t.Run("regexp", func(t *testing.T) { matchRegexp := "default/.*/subtest1" matchSuiteAndTest = &matchRegexp + + // Matches "subtest1" in various hierarchies result, err := matchFilter("TestAcceptance/default/test1/subtest1") assert.NoError(t, err) assert.True(t, result) @@ -103,31 +120,40 @@ func TestMatchFilter(t *testing.T) { assert.NoError(t, err) assert.False(t, result) }) - } +// TestCreateStateDir tests the creation of a state directory func TestCreateStateDir(t *testing.T) { + // Create a temporary directory tempDir := t.TempDir() + // Attempt to create a "state" subdirectory err := createDir(tempDir, "state") - assert.NoError(t, err) + assert.NoError(t, err) // Ensure no errors occurred + // Verify that the directory exists stateDir := filepath.Join(tempDir, "state") assert.DirExists(t, stateDir) } +// TestCreateTerraformComponentsDir tests the creation of Terraform components directory structure func TestCreateTerraformComponentsDir(t *testing.T) { + // Create a temporary directory tempDir := t.TempDir() + // Attempt to create the Terraform components directory structure err := createTerraformComponentsDir(tempDir) - assert.NoError(t, err) + assert.NoError(t, err) // Ensure no errors occurred + // Verify that the directory structure exists componentsDir := filepath.Join(tempDir, "components", "terraform") assert.DirExists(t, componentsDir) } +// TestGetTestName tests the retrieval of the current test's name func TestGetTestName(t *testing.T) { + // Attempt to retrieve the test name testName, err := getTestName() - assert.NoError(t, err) - assert.Contains(t, testName, "shared_") + assert.NoError(t, err) // Ensure no errors occurred + assert.Contains(t, testName, "shared_") // Validate that the name includes the expected pattern } From d08990b5bc69d7968d8bf6251e24cf5b592f8af2 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 21:48:13 +0100 Subject: [PATCH 32/40] Added comments --- pkg/atmos/aws-component-helper/atmos.go | 45 +++++++++++++------------ 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index d749a88..554dfc4 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -19,6 +19,7 @@ import ( "github.com/stretchr/testify/require" ) +// Atmos package variables for easier testing var ( atmosApply = atmos.Apply atmosDestroy = atmos.Destroy @@ -26,17 +27,21 @@ var ( atmosVendorPull = atmos.VendorPull atmosOutputAllE = atmos.OutputStructE ) + +// Command-line flags to skip deploy and destroy operations var ( skipDeploy = flag.Bool("skip-deploy", false, "skip all deployments") skipDestroy = flag.Bool("skip-destroy", false, "skip all destroy") ) +// Atmos struct encapsulates testing information and options type Atmos struct { t *testing.T options *atmos.Options state *State } +// Constructor for Atmos func NewAtmos(t *testing.T, state *State, options *atmos.Options) *Atmos { return &Atmos{ t: t, @@ -45,25 +50,28 @@ func NewAtmos(t *testing.T, state *State, options *atmos.Options) *Atmos { } } +// Get and deploy a component with given variables func (ts *Atmos) GetAndDeploy(componentName string, stackName string, vars map[string]interface{}) *AtmosComponent { component := NewAtmosComponent(componentName, stackName, vars) ts.Deploy(component) return component } +// Get and destroy a component with given variables func (ts *Atmos) GetAndDestroy(componentName string, stackName string, vars map[string]interface{}) *AtmosComponent { component := NewAtmosComponent(componentName, stackName, vars) ts.Destroy(component) return component } +// Deploy a component using Atmos func (ts *Atmos) Deploy(component *AtmosComponent) { options := ts.getAtmosOptions(component) - defer os.RemoveAll(options.AtmosBasePath) + defer os.RemoveAll(options.AtmosBasePath) // Clean up temporary directories err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) require.NoError(ts.t, err) if !*skipDeploy { - atmosApply(ts.t, options) + atmosApply(ts.t, options) // Apply the deployment err := atmosOutputAllE(ts.t, options, "", &component.output) require.NoError(ts.t, err) } else { @@ -71,19 +79,20 @@ func (ts *Atmos) Deploy(component *AtmosComponent) { } } +// Destroy a component using Atmos func (ts *Atmos) Destroy(component *AtmosComponent) { options := ts.getAtmosOptions(component) - defer os.RemoveAll(options.AtmosBasePath) + defer os.RemoveAll(options.AtmosBasePath) // Clean up temporary directories err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) assert.NoError(ts.t, err) if !*skipDestroy { - atmosDestroy(ts.t, options) + atmosDestroy(ts.t, options) // Destroy the deployment } else { fmt.Printf("Skip destroy component %s stack %s\n", component.ComponentName, component.StackName) } - } +// Load all outputs for a given component func (ts *Atmos) loadOutputAll(component *AtmosComponent) { if component.output != nil { return @@ -104,14 +113,15 @@ func (ts *Atmos) loadOutputAll(component *AtmosComponent) { } } +// Get all outputs for a component func (ts *Atmos) OutputAll(component *AtmosComponent) map[string]Output { ts.loadOutputAll(component) return component.output } +// Get a specific output by key as a string func (ts *Atmos) Output(component *AtmosComponent, key string) string { ts.loadOutputAll(component) - if value, ok := component.output[key]; ok { return value.Value.(string) } @@ -119,6 +129,7 @@ func (ts *Atmos) Output(component *AtmosComponent, key string) string { return "" } +// Get a list output by key func (ts *Atmos) OutputList(component *AtmosComponent, key string) []string { ts.loadOutputAll(component) if value, ok := component.output[key]; ok { @@ -129,13 +140,13 @@ func (ts *Atmos) OutputList(component *AtmosComponent, key string) []string { } error := atmos.UnexpectedOutputType{Key: key, ExpectedType: "map or list", ActualType: reflect.TypeOf(value).String()} require.Fail(ts.t, error.Error()) - } else { require.Fail(ts.t, fmt.Sprintf("Output key %s not found", key)) } return []string{} } +// Get a map of objects output by key func (ts *Atmos) OutputMapOfObjects(component *AtmosComponent, key string) map[string]interface{} { ts.loadOutputAll(component) if value, ok := component.output[key]; ok { @@ -144,13 +155,13 @@ func (ts *Atmos) OutputMapOfObjects(component *AtmosComponent, key string) map[s } error := atmos.UnexpectedOutputType{Key: key, ExpectedType: "map of objects", ActualType: reflect.TypeOf(value).String()} require.Fail(ts.t, error.Error()) - } else { require.Fail(ts.t, fmt.Sprintf("Output key %s not found", key)) } return map[string]interface{}{} } +// Deserialize a specific output key into a given struct func (ts *Atmos) OutputStruct(component *AtmosComponent, key string, v any) { ts.loadOutputAll(component) if value, ok := component.output[key]; ok { @@ -164,6 +175,7 @@ func (ts *Atmos) OutputStruct(component *AtmosComponent, key string, v any) { } } +// Generate Atmos options for a component func (ts *Atmos) getAtmosOptions(component *AtmosComponent) *atmos.Options { result, err := ts.options.Clone() require.NoError(ts.t, err) @@ -206,10 +218,9 @@ func (ts *Atmos) getAtmosOptions(component *AtmosComponent) *atmos.Options { return atmosOptions } +// Helper to parse a map recursively func parseMap(m map[string]interface{}) (map[string]interface{}, error) { - result := make(map[string]interface{}) - for k, v := range m { switch vt := v.(type) { case map[string]interface{}: @@ -234,36 +245,28 @@ func parseMap(m map[string]interface{}) (map[string]interface{}, error) { default: result[k] = vt } - } return result, nil } -// parseListOfMaps takes a list of maps and parses the types. -// It is mainly a wrapper for parseMap to support lists. +// Helper to parse a list of maps func parseListOfMaps(l []interface{}) ([]map[string]interface{}, error) { var result []map[string]interface{} - for _, v := range l { - asMap, isMap := v.(map[string]interface{}) if !isMap { - err := errors.New("Type switching to map[string]interface{} failed.") - return nil, err + return nil, errors.New("Type switching to map[string]interface{} failed.") } - m, err := parseMap(asMap) - if err != nil { return nil, err } result = append(result, m) } - return result, nil - } +// Clean output by removing non func cleanOutput(out string) string { var result []rune for _, line := range strings.Split(out, "\n") { From a135d28ca119324acd2503adb6879a8b16ebf1fa Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 21:49:16 +0100 Subject: [PATCH 33/40] Added comments --- .../aws-component-helper/atmos_component.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/pkg/atmos/aws-component-helper/atmos_component.go b/pkg/atmos/aws-component-helper/atmos_component.go index 2801369..90a0e55 100644 --- a/pkg/atmos/aws-component-helper/atmos_component.go +++ b/pkg/atmos/aws-component-helper/atmos_component.go @@ -6,20 +6,24 @@ import ( "github.com/gruntwork-io/terratest/modules/random" ) +// Output represents the structure of a Terraform output with optional sensitivity type Output struct { - Sensitive bool `json:"sensitive"` - Value interface{} `json:"value"` + Sensitive bool `json:"sensitive"` // Indicates if the output is sensitive + Value interface{} `json:"value"` // The actual value of the output } +// AtmosComponent represents a Terraform component managed by Atmos type AtmosComponent struct { - randomIdentifier string - ComponentName string - StackName string - Vars map[string]interface{} - output map[string]Output + randomIdentifier string // A unique identifier for the component + ComponentName string // Name of the Terraform component + StackName string // Name of the stack in which the component resides + Vars map[string]interface{} // Variables specific to the component + output map[string]Output // Holds Terraform outputs for the component } +// Constructor for AtmosComponent func NewAtmosComponent(component string, stack string, vars map[string]interface{}) *AtmosComponent { + // Generate a unique random identifier for the component randID := random.UniqueId() randomId := strings.ToLower(randID) @@ -31,6 +35,7 @@ func NewAtmosComponent(component string, stack string, vars map[string]interface } } +// GetRandomIdentifier retrieves the unique identifier of the component func (ts *AtmosComponent) GetRandomIdentifier() string { return ts.randomIdentifier } From 80b914062e67adf2d69811daf4fb92b3df40ca3c Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 21:49:46 +0100 Subject: [PATCH 34/40] Added comments --- pkg/atmos/aws-component-helper/atmos_component_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/atmos/aws-component-helper/atmos_component_test.go b/pkg/atmos/aws-component-helper/atmos_component_test.go index 1307042..aabc210 100644 --- a/pkg/atmos/aws-component-helper/atmos_component_test.go +++ b/pkg/atmos/aws-component-helper/atmos_component_test.go @@ -6,10 +6,15 @@ import ( "github.com/stretchr/testify/assert" ) +// TestAtmosComponent tests the creation and properties of an AtmosComponent func TestAtmosComponent(t *testing.T) { - // Create a temporary atmos component + // Create a temporary AtmosComponent with name "vpc" and stack "default-test" + // Passing 'nil' for vars as no specific variables are required for this test component := NewAtmosComponent("vpc", "default-test", nil) + // Assert that the ComponentName is correctly set to "vpc" assert.Equal(t, component.ComponentName, "vpc") + + // Assert that the StackName is correctly set to "default-test" assert.Equal(t, component.StackName, "default-test") } From 77c931ef22e969f655ca36040cfcb7f52bfd3860 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Mon, 6 Jan 2025 21:59:50 +0100 Subject: [PATCH 35/40] Added comments --- .../aws-component-helper/acceptance_test.go | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/pkg/atmos/aws-component-helper/acceptance_test.go b/pkg/atmos/aws-component-helper/acceptance_test.go index 9b6c4b6..cbe4e0b 100644 --- a/pkg/atmos/aws-component-helper/acceptance_test.go +++ b/pkg/atmos/aws-component-helper/acceptance_test.go @@ -11,14 +11,18 @@ import ( "github.com/stretchr/testify/require" ) +// TestAcceptance is an end-to-end acceptance test for AWS component helper functionality. func TestAcceptance(t *testing.T) { + // Mock AWS account ID retrieval callback getAwsAaccountIdCallback = func() (string, error) { return "123456789012", nil } + // Copy the test folder to a temporary location for isolation testFolder, err := files.CopyFolderToTemp("../../../", t.Name(), func(path string) bool { return true }) require.NoError(t, err) defer func() { + // Clean up the temporary test folder if err := os.RemoveAll(testFolder); err != nil { t.Errorf("failed to cleanup test folder: %v", err) } @@ -26,34 +30,45 @@ func TestAcceptance(t *testing.T) { fmt.Printf("running in %s\n", testFolder) + // Initialize a new test fixture for the acceptance test fixture := NewFixture(t, testFolder, "us-west-2", "test/fixtures/aws-component-helper") + // Set up and tear down the test environment fixture.SetUp(&atmos.Options{}) defer fixture.TearDown() + // Run a suite of tests within the "default" group fixture.Suite("default", func(t *testing.T, suite *Suite) { + // Test case: "basic" suite.Test(t, "basic", func(t *testing.T, atm *Atmos) { inputs := map[string]interface{}{ - "cnt": 2, + "cnt": 2, // Input variable for the Terraform configuration } + // Ensure proper cleanup by destroying resources after the test defer atm.GetAndDestroy("terraform-basic-configuration", "default-test", inputs) + // Deploy the Terraform component atm.GetAndDeploy("terraform-basic-configuration", "default-test", inputs) - }) + // Test case: "no-error" suite.Test(t, "no-error", func(t *testing.T, atm *Atmos) { + // Ensure proper cleanup by destroying resources after the test defer atm.GetAndDestroy("terraform-no-error", "default-test", nil) + // Deploy the Terraform component component := atm.GetAndDeploy("terraform-no-error", "default-test", nil) + // Expected outputs from the Terraform component mapOfObjects := map[string]interface{}{ "a": map[string]interface{}{"b": "c"}, "d": map[string]interface{}{"e": "f"}, } + // Assert outputs against expected values assert.Equal(t, "Hello, World", atm.Output(component, "test")) assert.Equal(t, []string{"a", "b", "c"}, atm.OutputList(component, "test_list")) assert.Equal(t, mapOfObjects, atm.OutputMapOfObjects(component, "test_map_of_objects")) + // Struct definitions for complex outputs type structValue1 struct { B string } @@ -67,12 +82,14 @@ func TestAcceptance(t *testing.T) { D structValue2 } + // Parse and validate structured output structResult := structValue{} structExpected := structValue{ A: structValue1{B: "c"}, D: structValue2{E: "f"}, } + // Assert that the parsed struct matches the expected structure atm.OutputStruct(component, "test_map_of_objects", &structResult) assert.Equal(t, structExpected, structResult) }) From bd59777b4b3523780ecbafdbfc7e4e6ed7bbf336 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Tue, 7 Jan 2025 01:49:00 +0100 Subject: [PATCH 36/40] Mock AWS nuke cloudformationiface mock --- go.mod | 66 +- go.sum | 149 +- .../mocks/mock_cloudformationiface/go.mod | 10 + .../mocks/mock_cloudformationiface/go.sum | 39 + .../mock_cloudformationiface.go | 5061 +++++++++++++++++ 5 files changed, 5303 insertions(+), 22 deletions(-) create mode 100644 pkg/awsnuke/mocks/mock_cloudformationiface/go.mod create mode 100644 pkg/awsnuke/mocks/mock_cloudformationiface/go.sum create mode 100644 pkg/awsnuke/mocks/mock_cloudformationiface/mock_cloudformationiface.go diff --git a/go.mod b/go.mod index af14c11..443f5cb 100644 --- a/go.mod +++ b/go.mod @@ -1,19 +1,21 @@ module github.com/cloudposse/test-helpers -go 1.23 - -toolchain go1.23.0 +go 1.23.0 require ( dario.cat/mergo v1.0.1 + github.com/aws/aws-sdk-go v1.54.0 + github.com/aws/aws-sdk-go-v2 v1.16.7 github.com/aws/aws-sdk-go-v2/config v1.15.13 github.com/aws/aws-sdk-go-v2/service/sts v1.16.9 github.com/gruntwork-io/terratest v0.47.0 github.com/jinzhu/copier v0.4.0 + github.com/rebuy-de/aws-nuke/v2 v2.25.0 + github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 ) -// replace github.com/rebuy-de/aws-nuke/v2/mocks => github.com/ekristen/aws-nuke/v3 v3.29.0 +replace github.com/rebuy-de/aws-nuke/v2/mocks/mock_cloudformationiface => ./pkg/awsnuke/mocks/mock_cloudformationiface require ( cloud.google.com/go v0.110.10 // indirect @@ -23,7 +25,6 @@ require ( cloud.google.com/go/storage v1.35.1 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect - github.com/aws/aws-sdk-go-v2 v1.16.7 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.12.8 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.8 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.14 // indirect @@ -31,7 +32,7 @@ require ( github.com/aws/aws-sdk-go-v2/internal/ini v1.3.15 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.8 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.11.11 // indirect - github.com/aws/smithy-go v1.12.0 // indirect + github.com/aws/smithy-go v1.20.2 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -48,7 +49,6 @@ require ( github.com/hashicorp/hcl/v2 v2.19.1 // indirect github.com/hashicorp/terraform-json v0.22.1 // indirect github.com/klauspost/compress v1.17.0 // indirect - github.com/kr/pretty v0.3.1 // indirect github.com/mattn/go-zglob v0.0.3 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect @@ -59,8 +59,8 @@ require ( github.com/ulikunitz/xz v0.5.11 // indirect github.com/zclconf/go-cty v1.14.4 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/net v0.23.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/oauth2 v0.15.0 // indirect golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.5.0 // indirect @@ -72,14 +72,58 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect google.golang.org/grpc v1.60.1 // indirect google.golang.org/protobuf v1.33.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( - github.com/aws/aws-sdk-go v1.54.20 // indirect + github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/fatih/color v1.15.0 // indirect + github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-sql-driver/mysql v1.4.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gruntwork-io/go-commons v0.8.0 // indirect + github.com/imdario/mergo v0.3.11 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pquerna/otp v1.2.0 // indirect + github.com/rebuy-de/aws-nuke/v2/mocks/mock_cloudformationiface v0.0.0-00010101000000-000000000000 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/spf13/cobra v1.7.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/urfave/cli v1.22.2 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/api v0.28.4 // indirect + k8s.io/apimachinery v0.28.4 // indirect + k8s.io/client-go v0.28.4 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index 16be344..508316f 100644 --- a/go.sum +++ b/go.sum @@ -199,9 +199,11 @@ github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/ github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.54.20 h1:FZ2UcXya7bUkvkpf7TaPmiL7EubK0go1nlXGLRwEsoo= -github.com/aws/aws-sdk-go v1.54.20/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go v1.54.0 h1:tGCQ6YS2TepzKtbl+ddXnLIoV8XvWdxMKtuMxdrsa4U= +github.com/aws/aws-sdk-go v1.54.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.16.7 h1:zfBwXus3u14OszRxGcqCDS4MfMCv10e8SMJ2r8Xm0Ns= github.com/aws/aws-sdk-go-v2 v1.16.7/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= github.com/aws/aws-sdk-go-v2/config v1.15.13 h1:CJH9zn/Enst7lDiGpoguVt0lZr5HcpNVlRJWbJ6qreo= @@ -222,10 +224,14 @@ github.com/aws/aws-sdk-go-v2/service/sso v1.11.11 h1:XOJWXNFXJyapJqQuCIPfftsOf0X github.com/aws/aws-sdk-go-v2/service/sso v1.11.11/go.mod h1:MO4qguFjs3wPGcCSpQ7kOFTwRvb+eu+fn+1vKleGHUk= github.com/aws/aws-sdk-go-v2/service/sts v1.16.9 h1:yOfILxyjmtr2ubRkRJldlHDFBhf5vw4CzhbwWIBmimQ= github.com/aws/aws-sdk-go-v2/service/sts v1.16.9/go.mod h1:O1IvkYxr+39hRf960Us6j0x1P8pDqhTX+oXM5kQNl/Y= -github.com/aws/smithy-go v1.12.0 h1:gXpeZel/jPoWQ7OEmLIgCUnhkFftqNfwWUwAHSlp1v0= github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= +github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= +github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -243,11 +249,16 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -259,13 +270,34 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 h1:skJKxRtNmevLqnayafdLe2AsenqRupVmzZSqrvb5caU= +github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -280,6 +312,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -304,6 +337,8 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -321,6 +356,9 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -341,6 +379,7 @@ github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= @@ -366,7 +405,10 @@ github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMd github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/gruntwork-io/go-commons v0.8.0 h1:k/yypwrPqSeYHevLlEDmvmgQzcyTwrlZGRaxEM6G0ro= +github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78= github.com/gruntwork-io/terratest v0.47.0 h1:xIy1pT7NbGVlMLDZEHl3+3iSnvffh8tN2pL6idn448c= github.com/gruntwork-io/terratest v0.47.0/go.mod h1:oywHw1cFKXSYvKPm27U7quZVzDUlA22H2xUrKCe26xM= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -391,18 +433,28 @@ github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7 github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -414,11 +466,24 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/go-zglob v0.0.3 h1:6Ry4EYsScDyt5di4OI6xw1bYhOqfE5S33Z1OPy+d+To= github.com/mattn/go-zglob v0.0.3/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= +github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 h1:NK3O7S5FRD/wj7ORQ5C3Mx1STpyEMuFe+/F0Lakd1Nk= +github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4/go.mod h1:FqD3ES5hx6zpzDainDaHgkTIqrPaI9uX4CVWqYZoQjY= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= @@ -426,24 +491,53 @@ github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= +github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rebuy-de/aws-nuke/v2 v2.25.0 h1:uM/KoDOOIau1Gcx++D3oDFL1vlLPj9uuzQKtNVZxrHs= +github.com/rebuy-de/aws-nuke/v2 v2.25.0/go.mod h1:2TTX8eMpEsFZPYCK1QaAb9uPYtdO9MeLQPKM9GQfY/w= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -458,6 +552,8 @@ github.com/tmccombs/hcl2json v0.3.4/go.mod h1:l3Aq9eUyhC+0v26BH08BZHeyWEtOYcFtbu github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= @@ -490,8 +586,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -576,8 +672,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -623,8 +719,10 @@ golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -632,6 +730,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -682,16 +781,19 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -747,6 +849,7 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -755,6 +858,7 @@ golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -762,6 +866,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -998,9 +1104,12 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -1013,6 +1122,24 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= +k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= +k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= +k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= +k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= +k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/pkg/awsnuke/mocks/mock_cloudformationiface/go.mod b/pkg/awsnuke/mocks/mock_cloudformationiface/go.mod new file mode 100644 index 0000000..37a9ae8 --- /dev/null +++ b/pkg/awsnuke/mocks/mock_cloudformationiface/go.mod @@ -0,0 +1,10 @@ +module mock_cloudformationiface + +go 1.23.0 + +require ( + github.com/aws/aws-sdk-go v1.54.0 + github.com/golang/mock v1.6.0 +) + +require github.com/jmespath/go-jmespath v0.4.0 // indirect diff --git a/pkg/awsnuke/mocks/mock_cloudformationiface/go.sum b/pkg/awsnuke/mocks/mock_cloudformationiface/go.sum new file mode 100644 index 0000000..a833ab7 --- /dev/null +++ b/pkg/awsnuke/mocks/mock_cloudformationiface/go.sum @@ -0,0 +1,39 @@ +github.com/aws/aws-sdk-go v1.54.0 h1:tGCQ6YS2TepzKtbl+ddXnLIoV8XvWdxMKtuMxdrsa4U= +github.com/aws/aws-sdk-go v1.54.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/awsnuke/mocks/mock_cloudformationiface/mock_cloudformationiface.go b/pkg/awsnuke/mocks/mock_cloudformationiface/mock_cloudformationiface.go new file mode 100644 index 0000000..084a6da --- /dev/null +++ b/pkg/awsnuke/mocks/mock_cloudformationiface/mock_cloudformationiface.go @@ -0,0 +1,5061 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: /Users/goruha/go/pkg/mod/github.com/aws/aws-sdk-go@v1.54.20/service/cloudformation/cloudformationiface/interface.go + +// Package mock_cloudformationiface is a generated GoMock package. +package mock_cloudformationiface + +import ( + reflect "reflect" + + aws "github.com/aws/aws-sdk-go/aws" + request "github.com/aws/aws-sdk-go/aws/request" + cloudformation "github.com/aws/aws-sdk-go/service/cloudformation" + gomock "github.com/golang/mock/gomock" +) + +// MockCloudFormationAPI is a mock of CloudFormationAPI interface. +type MockCloudFormationAPI struct { + ctrl *gomock.Controller + recorder *MockCloudFormationAPIMockRecorder +} + +// MockCloudFormationAPIMockRecorder is the mock recorder for MockCloudFormationAPI. +type MockCloudFormationAPIMockRecorder struct { + mock *MockCloudFormationAPI +} + +// NewMockCloudFormationAPI creates a new mock instance. +func NewMockCloudFormationAPI(ctrl *gomock.Controller) *MockCloudFormationAPI { + mock := &MockCloudFormationAPI{ctrl: ctrl} + mock.recorder = &MockCloudFormationAPIMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCloudFormationAPI) EXPECT() *MockCloudFormationAPIMockRecorder { + return m.recorder +} + +// ActivateOrganizationsAccess mocks base method. +func (m *MockCloudFormationAPI) ActivateOrganizationsAccess(arg0 *cloudformation.ActivateOrganizationsAccessInput) (*cloudformation.ActivateOrganizationsAccessOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ActivateOrganizationsAccess", arg0) + ret0, _ := ret[0].(*cloudformation.ActivateOrganizationsAccessOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ActivateOrganizationsAccess indicates an expected call of ActivateOrganizationsAccess. +func (mr *MockCloudFormationAPIMockRecorder) ActivateOrganizationsAccess(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateOrganizationsAccess", reflect.TypeOf((*MockCloudFormationAPI)(nil).ActivateOrganizationsAccess), arg0) +} + +// ActivateOrganizationsAccessRequest mocks base method. +func (m *MockCloudFormationAPI) ActivateOrganizationsAccessRequest(arg0 *cloudformation.ActivateOrganizationsAccessInput) (*request.Request, *cloudformation.ActivateOrganizationsAccessOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ActivateOrganizationsAccessRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ActivateOrganizationsAccessOutput) + return ret0, ret1 +} + +// ActivateOrganizationsAccessRequest indicates an expected call of ActivateOrganizationsAccessRequest. +func (mr *MockCloudFormationAPIMockRecorder) ActivateOrganizationsAccessRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateOrganizationsAccessRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ActivateOrganizationsAccessRequest), arg0) +} + +// ActivateOrganizationsAccessWithContext mocks base method. +func (m *MockCloudFormationAPI) ActivateOrganizationsAccessWithContext(arg0 aws.Context, arg1 *cloudformation.ActivateOrganizationsAccessInput, arg2 ...request.Option) (*cloudformation.ActivateOrganizationsAccessOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ActivateOrganizationsAccessWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ActivateOrganizationsAccessOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ActivateOrganizationsAccessWithContext indicates an expected call of ActivateOrganizationsAccessWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ActivateOrganizationsAccessWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateOrganizationsAccessWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ActivateOrganizationsAccessWithContext), varargs...) +} + +// ActivateType mocks base method. +func (m *MockCloudFormationAPI) ActivateType(arg0 *cloudformation.ActivateTypeInput) (*cloudformation.ActivateTypeOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ActivateType", arg0) + ret0, _ := ret[0].(*cloudformation.ActivateTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ActivateType indicates an expected call of ActivateType. +func (mr *MockCloudFormationAPIMockRecorder) ActivateType(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateType", reflect.TypeOf((*MockCloudFormationAPI)(nil).ActivateType), arg0) +} + +// ActivateTypeRequest mocks base method. +func (m *MockCloudFormationAPI) ActivateTypeRequest(arg0 *cloudformation.ActivateTypeInput) (*request.Request, *cloudformation.ActivateTypeOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ActivateTypeRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ActivateTypeOutput) + return ret0, ret1 +} + +// ActivateTypeRequest indicates an expected call of ActivateTypeRequest. +func (mr *MockCloudFormationAPIMockRecorder) ActivateTypeRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateTypeRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ActivateTypeRequest), arg0) +} + +// ActivateTypeWithContext mocks base method. +func (m *MockCloudFormationAPI) ActivateTypeWithContext(arg0 aws.Context, arg1 *cloudformation.ActivateTypeInput, arg2 ...request.Option) (*cloudformation.ActivateTypeOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ActivateTypeWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ActivateTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ActivateTypeWithContext indicates an expected call of ActivateTypeWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ActivateTypeWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateTypeWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ActivateTypeWithContext), varargs...) +} + +// BatchDescribeTypeConfigurations mocks base method. +func (m *MockCloudFormationAPI) BatchDescribeTypeConfigurations(arg0 *cloudformation.BatchDescribeTypeConfigurationsInput) (*cloudformation.BatchDescribeTypeConfigurationsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BatchDescribeTypeConfigurations", arg0) + ret0, _ := ret[0].(*cloudformation.BatchDescribeTypeConfigurationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BatchDescribeTypeConfigurations indicates an expected call of BatchDescribeTypeConfigurations. +func (mr *MockCloudFormationAPIMockRecorder) BatchDescribeTypeConfigurations(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchDescribeTypeConfigurations", reflect.TypeOf((*MockCloudFormationAPI)(nil).BatchDescribeTypeConfigurations), arg0) +} + +// BatchDescribeTypeConfigurationsRequest mocks base method. +func (m *MockCloudFormationAPI) BatchDescribeTypeConfigurationsRequest(arg0 *cloudformation.BatchDescribeTypeConfigurationsInput) (*request.Request, *cloudformation.BatchDescribeTypeConfigurationsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BatchDescribeTypeConfigurationsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.BatchDescribeTypeConfigurationsOutput) + return ret0, ret1 +} + +// BatchDescribeTypeConfigurationsRequest indicates an expected call of BatchDescribeTypeConfigurationsRequest. +func (mr *MockCloudFormationAPIMockRecorder) BatchDescribeTypeConfigurationsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchDescribeTypeConfigurationsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).BatchDescribeTypeConfigurationsRequest), arg0) +} + +// BatchDescribeTypeConfigurationsWithContext mocks base method. +func (m *MockCloudFormationAPI) BatchDescribeTypeConfigurationsWithContext(arg0 aws.Context, arg1 *cloudformation.BatchDescribeTypeConfigurationsInput, arg2 ...request.Option) (*cloudformation.BatchDescribeTypeConfigurationsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "BatchDescribeTypeConfigurationsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.BatchDescribeTypeConfigurationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BatchDescribeTypeConfigurationsWithContext indicates an expected call of BatchDescribeTypeConfigurationsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) BatchDescribeTypeConfigurationsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchDescribeTypeConfigurationsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).BatchDescribeTypeConfigurationsWithContext), varargs...) +} + +// CancelUpdateStack mocks base method. +func (m *MockCloudFormationAPI) CancelUpdateStack(arg0 *cloudformation.CancelUpdateStackInput) (*cloudformation.CancelUpdateStackOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CancelUpdateStack", arg0) + ret0, _ := ret[0].(*cloudformation.CancelUpdateStackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CancelUpdateStack indicates an expected call of CancelUpdateStack. +func (mr *MockCloudFormationAPIMockRecorder) CancelUpdateStack(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelUpdateStack", reflect.TypeOf((*MockCloudFormationAPI)(nil).CancelUpdateStack), arg0) +} + +// CancelUpdateStackRequest mocks base method. +func (m *MockCloudFormationAPI) CancelUpdateStackRequest(arg0 *cloudformation.CancelUpdateStackInput) (*request.Request, *cloudformation.CancelUpdateStackOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CancelUpdateStackRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.CancelUpdateStackOutput) + return ret0, ret1 +} + +// CancelUpdateStackRequest indicates an expected call of CancelUpdateStackRequest. +func (mr *MockCloudFormationAPIMockRecorder) CancelUpdateStackRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelUpdateStackRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).CancelUpdateStackRequest), arg0) +} + +// CancelUpdateStackWithContext mocks base method. +func (m *MockCloudFormationAPI) CancelUpdateStackWithContext(arg0 aws.Context, arg1 *cloudformation.CancelUpdateStackInput, arg2 ...request.Option) (*cloudformation.CancelUpdateStackOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CancelUpdateStackWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.CancelUpdateStackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CancelUpdateStackWithContext indicates an expected call of CancelUpdateStackWithContext. +func (mr *MockCloudFormationAPIMockRecorder) CancelUpdateStackWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelUpdateStackWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).CancelUpdateStackWithContext), varargs...) +} + +// ContinueUpdateRollback mocks base method. +func (m *MockCloudFormationAPI) ContinueUpdateRollback(arg0 *cloudformation.ContinueUpdateRollbackInput) (*cloudformation.ContinueUpdateRollbackOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContinueUpdateRollback", arg0) + ret0, _ := ret[0].(*cloudformation.ContinueUpdateRollbackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContinueUpdateRollback indicates an expected call of ContinueUpdateRollback. +func (mr *MockCloudFormationAPIMockRecorder) ContinueUpdateRollback(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContinueUpdateRollback", reflect.TypeOf((*MockCloudFormationAPI)(nil).ContinueUpdateRollback), arg0) +} + +// ContinueUpdateRollbackRequest mocks base method. +func (m *MockCloudFormationAPI) ContinueUpdateRollbackRequest(arg0 *cloudformation.ContinueUpdateRollbackInput) (*request.Request, *cloudformation.ContinueUpdateRollbackOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContinueUpdateRollbackRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ContinueUpdateRollbackOutput) + return ret0, ret1 +} + +// ContinueUpdateRollbackRequest indicates an expected call of ContinueUpdateRollbackRequest. +func (mr *MockCloudFormationAPIMockRecorder) ContinueUpdateRollbackRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContinueUpdateRollbackRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ContinueUpdateRollbackRequest), arg0) +} + +// ContinueUpdateRollbackWithContext mocks base method. +func (m *MockCloudFormationAPI) ContinueUpdateRollbackWithContext(arg0 aws.Context, arg1 *cloudformation.ContinueUpdateRollbackInput, arg2 ...request.Option) (*cloudformation.ContinueUpdateRollbackOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ContinueUpdateRollbackWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ContinueUpdateRollbackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContinueUpdateRollbackWithContext indicates an expected call of ContinueUpdateRollbackWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ContinueUpdateRollbackWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContinueUpdateRollbackWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ContinueUpdateRollbackWithContext), varargs...) +} + +// CreateChangeSet mocks base method. +func (m *MockCloudFormationAPI) CreateChangeSet(arg0 *cloudformation.CreateChangeSetInput) (*cloudformation.CreateChangeSetOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateChangeSet", arg0) + ret0, _ := ret[0].(*cloudformation.CreateChangeSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateChangeSet indicates an expected call of CreateChangeSet. +func (mr *MockCloudFormationAPIMockRecorder) CreateChangeSet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateChangeSet", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateChangeSet), arg0) +} + +// CreateChangeSetRequest mocks base method. +func (m *MockCloudFormationAPI) CreateChangeSetRequest(arg0 *cloudformation.CreateChangeSetInput) (*request.Request, *cloudformation.CreateChangeSetOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateChangeSetRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.CreateChangeSetOutput) + return ret0, ret1 +} + +// CreateChangeSetRequest indicates an expected call of CreateChangeSetRequest. +func (mr *MockCloudFormationAPIMockRecorder) CreateChangeSetRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateChangeSetRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateChangeSetRequest), arg0) +} + +// CreateChangeSetWithContext mocks base method. +func (m *MockCloudFormationAPI) CreateChangeSetWithContext(arg0 aws.Context, arg1 *cloudformation.CreateChangeSetInput, arg2 ...request.Option) (*cloudformation.CreateChangeSetOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateChangeSetWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.CreateChangeSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateChangeSetWithContext indicates an expected call of CreateChangeSetWithContext. +func (mr *MockCloudFormationAPIMockRecorder) CreateChangeSetWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateChangeSetWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateChangeSetWithContext), varargs...) +} + +// CreateGeneratedTemplate mocks base method. +func (m *MockCloudFormationAPI) CreateGeneratedTemplate(arg0 *cloudformation.CreateGeneratedTemplateInput) (*cloudformation.CreateGeneratedTemplateOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateGeneratedTemplate", arg0) + ret0, _ := ret[0].(*cloudformation.CreateGeneratedTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateGeneratedTemplate indicates an expected call of CreateGeneratedTemplate. +func (mr *MockCloudFormationAPIMockRecorder) CreateGeneratedTemplate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateGeneratedTemplate", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateGeneratedTemplate), arg0) +} + +// CreateGeneratedTemplateRequest mocks base method. +func (m *MockCloudFormationAPI) CreateGeneratedTemplateRequest(arg0 *cloudformation.CreateGeneratedTemplateInput) (*request.Request, *cloudformation.CreateGeneratedTemplateOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateGeneratedTemplateRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.CreateGeneratedTemplateOutput) + return ret0, ret1 +} + +// CreateGeneratedTemplateRequest indicates an expected call of CreateGeneratedTemplateRequest. +func (mr *MockCloudFormationAPIMockRecorder) CreateGeneratedTemplateRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateGeneratedTemplateRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateGeneratedTemplateRequest), arg0) +} + +// CreateGeneratedTemplateWithContext mocks base method. +func (m *MockCloudFormationAPI) CreateGeneratedTemplateWithContext(arg0 aws.Context, arg1 *cloudformation.CreateGeneratedTemplateInput, arg2 ...request.Option) (*cloudformation.CreateGeneratedTemplateOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateGeneratedTemplateWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.CreateGeneratedTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateGeneratedTemplateWithContext indicates an expected call of CreateGeneratedTemplateWithContext. +func (mr *MockCloudFormationAPIMockRecorder) CreateGeneratedTemplateWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateGeneratedTemplateWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateGeneratedTemplateWithContext), varargs...) +} + +// CreateStack mocks base method. +func (m *MockCloudFormationAPI) CreateStack(arg0 *cloudformation.CreateStackInput) (*cloudformation.CreateStackOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateStack", arg0) + ret0, _ := ret[0].(*cloudformation.CreateStackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateStack indicates an expected call of CreateStack. +func (mr *MockCloudFormationAPIMockRecorder) CreateStack(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStack", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateStack), arg0) +} + +// CreateStackInstances mocks base method. +func (m *MockCloudFormationAPI) CreateStackInstances(arg0 *cloudformation.CreateStackInstancesInput) (*cloudformation.CreateStackInstancesOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateStackInstances", arg0) + ret0, _ := ret[0].(*cloudformation.CreateStackInstancesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateStackInstances indicates an expected call of CreateStackInstances. +func (mr *MockCloudFormationAPIMockRecorder) CreateStackInstances(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStackInstances", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateStackInstances), arg0) +} + +// CreateStackInstancesRequest mocks base method. +func (m *MockCloudFormationAPI) CreateStackInstancesRequest(arg0 *cloudformation.CreateStackInstancesInput) (*request.Request, *cloudformation.CreateStackInstancesOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateStackInstancesRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.CreateStackInstancesOutput) + return ret0, ret1 +} + +// CreateStackInstancesRequest indicates an expected call of CreateStackInstancesRequest. +func (mr *MockCloudFormationAPIMockRecorder) CreateStackInstancesRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStackInstancesRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateStackInstancesRequest), arg0) +} + +// CreateStackInstancesWithContext mocks base method. +func (m *MockCloudFormationAPI) CreateStackInstancesWithContext(arg0 aws.Context, arg1 *cloudformation.CreateStackInstancesInput, arg2 ...request.Option) (*cloudformation.CreateStackInstancesOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateStackInstancesWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.CreateStackInstancesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateStackInstancesWithContext indicates an expected call of CreateStackInstancesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) CreateStackInstancesWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStackInstancesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateStackInstancesWithContext), varargs...) +} + +// CreateStackRequest mocks base method. +func (m *MockCloudFormationAPI) CreateStackRequest(arg0 *cloudformation.CreateStackInput) (*request.Request, *cloudformation.CreateStackOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateStackRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.CreateStackOutput) + return ret0, ret1 +} + +// CreateStackRequest indicates an expected call of CreateStackRequest. +func (mr *MockCloudFormationAPIMockRecorder) CreateStackRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStackRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateStackRequest), arg0) +} + +// CreateStackSet mocks base method. +func (m *MockCloudFormationAPI) CreateStackSet(arg0 *cloudformation.CreateStackSetInput) (*cloudformation.CreateStackSetOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateStackSet", arg0) + ret0, _ := ret[0].(*cloudformation.CreateStackSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateStackSet indicates an expected call of CreateStackSet. +func (mr *MockCloudFormationAPIMockRecorder) CreateStackSet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStackSet", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateStackSet), arg0) +} + +// CreateStackSetRequest mocks base method. +func (m *MockCloudFormationAPI) CreateStackSetRequest(arg0 *cloudformation.CreateStackSetInput) (*request.Request, *cloudformation.CreateStackSetOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateStackSetRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.CreateStackSetOutput) + return ret0, ret1 +} + +// CreateStackSetRequest indicates an expected call of CreateStackSetRequest. +func (mr *MockCloudFormationAPIMockRecorder) CreateStackSetRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStackSetRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateStackSetRequest), arg0) +} + +// CreateStackSetWithContext mocks base method. +func (m *MockCloudFormationAPI) CreateStackSetWithContext(arg0 aws.Context, arg1 *cloudformation.CreateStackSetInput, arg2 ...request.Option) (*cloudformation.CreateStackSetOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateStackSetWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.CreateStackSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateStackSetWithContext indicates an expected call of CreateStackSetWithContext. +func (mr *MockCloudFormationAPIMockRecorder) CreateStackSetWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStackSetWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateStackSetWithContext), varargs...) +} + +// CreateStackWithContext mocks base method. +func (m *MockCloudFormationAPI) CreateStackWithContext(arg0 aws.Context, arg1 *cloudformation.CreateStackInput, arg2 ...request.Option) (*cloudformation.CreateStackOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateStackWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.CreateStackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateStackWithContext indicates an expected call of CreateStackWithContext. +func (mr *MockCloudFormationAPIMockRecorder) CreateStackWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStackWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).CreateStackWithContext), varargs...) +} + +// DeactivateOrganizationsAccess mocks base method. +func (m *MockCloudFormationAPI) DeactivateOrganizationsAccess(arg0 *cloudformation.DeactivateOrganizationsAccessInput) (*cloudformation.DeactivateOrganizationsAccessOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeactivateOrganizationsAccess", arg0) + ret0, _ := ret[0].(*cloudformation.DeactivateOrganizationsAccessOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeactivateOrganizationsAccess indicates an expected call of DeactivateOrganizationsAccess. +func (mr *MockCloudFormationAPIMockRecorder) DeactivateOrganizationsAccess(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeactivateOrganizationsAccess", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeactivateOrganizationsAccess), arg0) +} + +// DeactivateOrganizationsAccessRequest mocks base method. +func (m *MockCloudFormationAPI) DeactivateOrganizationsAccessRequest(arg0 *cloudformation.DeactivateOrganizationsAccessInput) (*request.Request, *cloudformation.DeactivateOrganizationsAccessOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeactivateOrganizationsAccessRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DeactivateOrganizationsAccessOutput) + return ret0, ret1 +} + +// DeactivateOrganizationsAccessRequest indicates an expected call of DeactivateOrganizationsAccessRequest. +func (mr *MockCloudFormationAPIMockRecorder) DeactivateOrganizationsAccessRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeactivateOrganizationsAccessRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeactivateOrganizationsAccessRequest), arg0) +} + +// DeactivateOrganizationsAccessWithContext mocks base method. +func (m *MockCloudFormationAPI) DeactivateOrganizationsAccessWithContext(arg0 aws.Context, arg1 *cloudformation.DeactivateOrganizationsAccessInput, arg2 ...request.Option) (*cloudformation.DeactivateOrganizationsAccessOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeactivateOrganizationsAccessWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DeactivateOrganizationsAccessOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeactivateOrganizationsAccessWithContext indicates an expected call of DeactivateOrganizationsAccessWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DeactivateOrganizationsAccessWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeactivateOrganizationsAccessWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeactivateOrganizationsAccessWithContext), varargs...) +} + +// DeactivateType mocks base method. +func (m *MockCloudFormationAPI) DeactivateType(arg0 *cloudformation.DeactivateTypeInput) (*cloudformation.DeactivateTypeOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeactivateType", arg0) + ret0, _ := ret[0].(*cloudformation.DeactivateTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeactivateType indicates an expected call of DeactivateType. +func (mr *MockCloudFormationAPIMockRecorder) DeactivateType(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeactivateType", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeactivateType), arg0) +} + +// DeactivateTypeRequest mocks base method. +func (m *MockCloudFormationAPI) DeactivateTypeRequest(arg0 *cloudformation.DeactivateTypeInput) (*request.Request, *cloudformation.DeactivateTypeOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeactivateTypeRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DeactivateTypeOutput) + return ret0, ret1 +} + +// DeactivateTypeRequest indicates an expected call of DeactivateTypeRequest. +func (mr *MockCloudFormationAPIMockRecorder) DeactivateTypeRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeactivateTypeRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeactivateTypeRequest), arg0) +} + +// DeactivateTypeWithContext mocks base method. +func (m *MockCloudFormationAPI) DeactivateTypeWithContext(arg0 aws.Context, arg1 *cloudformation.DeactivateTypeInput, arg2 ...request.Option) (*cloudformation.DeactivateTypeOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeactivateTypeWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DeactivateTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeactivateTypeWithContext indicates an expected call of DeactivateTypeWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DeactivateTypeWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeactivateTypeWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeactivateTypeWithContext), varargs...) +} + +// DeleteChangeSet mocks base method. +func (m *MockCloudFormationAPI) DeleteChangeSet(arg0 *cloudformation.DeleteChangeSetInput) (*cloudformation.DeleteChangeSetOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteChangeSet", arg0) + ret0, _ := ret[0].(*cloudformation.DeleteChangeSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteChangeSet indicates an expected call of DeleteChangeSet. +func (mr *MockCloudFormationAPIMockRecorder) DeleteChangeSet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteChangeSet", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteChangeSet), arg0) +} + +// DeleteChangeSetRequest mocks base method. +func (m *MockCloudFormationAPI) DeleteChangeSetRequest(arg0 *cloudformation.DeleteChangeSetInput) (*request.Request, *cloudformation.DeleteChangeSetOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteChangeSetRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DeleteChangeSetOutput) + return ret0, ret1 +} + +// DeleteChangeSetRequest indicates an expected call of DeleteChangeSetRequest. +func (mr *MockCloudFormationAPIMockRecorder) DeleteChangeSetRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteChangeSetRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteChangeSetRequest), arg0) +} + +// DeleteChangeSetWithContext mocks base method. +func (m *MockCloudFormationAPI) DeleteChangeSetWithContext(arg0 aws.Context, arg1 *cloudformation.DeleteChangeSetInput, arg2 ...request.Option) (*cloudformation.DeleteChangeSetOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteChangeSetWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DeleteChangeSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteChangeSetWithContext indicates an expected call of DeleteChangeSetWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DeleteChangeSetWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteChangeSetWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteChangeSetWithContext), varargs...) +} + +// DeleteGeneratedTemplate mocks base method. +func (m *MockCloudFormationAPI) DeleteGeneratedTemplate(arg0 *cloudformation.DeleteGeneratedTemplateInput) (*cloudformation.DeleteGeneratedTemplateOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteGeneratedTemplate", arg0) + ret0, _ := ret[0].(*cloudformation.DeleteGeneratedTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteGeneratedTemplate indicates an expected call of DeleteGeneratedTemplate. +func (mr *MockCloudFormationAPIMockRecorder) DeleteGeneratedTemplate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteGeneratedTemplate", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteGeneratedTemplate), arg0) +} + +// DeleteGeneratedTemplateRequest mocks base method. +func (m *MockCloudFormationAPI) DeleteGeneratedTemplateRequest(arg0 *cloudformation.DeleteGeneratedTemplateInput) (*request.Request, *cloudformation.DeleteGeneratedTemplateOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteGeneratedTemplateRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DeleteGeneratedTemplateOutput) + return ret0, ret1 +} + +// DeleteGeneratedTemplateRequest indicates an expected call of DeleteGeneratedTemplateRequest. +func (mr *MockCloudFormationAPIMockRecorder) DeleteGeneratedTemplateRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteGeneratedTemplateRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteGeneratedTemplateRequest), arg0) +} + +// DeleteGeneratedTemplateWithContext mocks base method. +func (m *MockCloudFormationAPI) DeleteGeneratedTemplateWithContext(arg0 aws.Context, arg1 *cloudformation.DeleteGeneratedTemplateInput, arg2 ...request.Option) (*cloudformation.DeleteGeneratedTemplateOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteGeneratedTemplateWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DeleteGeneratedTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteGeneratedTemplateWithContext indicates an expected call of DeleteGeneratedTemplateWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DeleteGeneratedTemplateWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteGeneratedTemplateWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteGeneratedTemplateWithContext), varargs...) +} + +// DeleteStack mocks base method. +func (m *MockCloudFormationAPI) DeleteStack(arg0 *cloudformation.DeleteStackInput) (*cloudformation.DeleteStackOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteStack", arg0) + ret0, _ := ret[0].(*cloudformation.DeleteStackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteStack indicates an expected call of DeleteStack. +func (mr *MockCloudFormationAPIMockRecorder) DeleteStack(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStack", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteStack), arg0) +} + +// DeleteStackInstances mocks base method. +func (m *MockCloudFormationAPI) DeleteStackInstances(arg0 *cloudformation.DeleteStackInstancesInput) (*cloudformation.DeleteStackInstancesOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteStackInstances", arg0) + ret0, _ := ret[0].(*cloudformation.DeleteStackInstancesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteStackInstances indicates an expected call of DeleteStackInstances. +func (mr *MockCloudFormationAPIMockRecorder) DeleteStackInstances(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStackInstances", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteStackInstances), arg0) +} + +// DeleteStackInstancesRequest mocks base method. +func (m *MockCloudFormationAPI) DeleteStackInstancesRequest(arg0 *cloudformation.DeleteStackInstancesInput) (*request.Request, *cloudformation.DeleteStackInstancesOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteStackInstancesRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DeleteStackInstancesOutput) + return ret0, ret1 +} + +// DeleteStackInstancesRequest indicates an expected call of DeleteStackInstancesRequest. +func (mr *MockCloudFormationAPIMockRecorder) DeleteStackInstancesRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStackInstancesRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteStackInstancesRequest), arg0) +} + +// DeleteStackInstancesWithContext mocks base method. +func (m *MockCloudFormationAPI) DeleteStackInstancesWithContext(arg0 aws.Context, arg1 *cloudformation.DeleteStackInstancesInput, arg2 ...request.Option) (*cloudformation.DeleteStackInstancesOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteStackInstancesWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DeleteStackInstancesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteStackInstancesWithContext indicates an expected call of DeleteStackInstancesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DeleteStackInstancesWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStackInstancesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteStackInstancesWithContext), varargs...) +} + +// DeleteStackRequest mocks base method. +func (m *MockCloudFormationAPI) DeleteStackRequest(arg0 *cloudformation.DeleteStackInput) (*request.Request, *cloudformation.DeleteStackOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteStackRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DeleteStackOutput) + return ret0, ret1 +} + +// DeleteStackRequest indicates an expected call of DeleteStackRequest. +func (mr *MockCloudFormationAPIMockRecorder) DeleteStackRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStackRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteStackRequest), arg0) +} + +// DeleteStackSet mocks base method. +func (m *MockCloudFormationAPI) DeleteStackSet(arg0 *cloudformation.DeleteStackSetInput) (*cloudformation.DeleteStackSetOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteStackSet", arg0) + ret0, _ := ret[0].(*cloudformation.DeleteStackSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteStackSet indicates an expected call of DeleteStackSet. +func (mr *MockCloudFormationAPIMockRecorder) DeleteStackSet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStackSet", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteStackSet), arg0) +} + +// DeleteStackSetRequest mocks base method. +func (m *MockCloudFormationAPI) DeleteStackSetRequest(arg0 *cloudformation.DeleteStackSetInput) (*request.Request, *cloudformation.DeleteStackSetOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteStackSetRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DeleteStackSetOutput) + return ret0, ret1 +} + +// DeleteStackSetRequest indicates an expected call of DeleteStackSetRequest. +func (mr *MockCloudFormationAPIMockRecorder) DeleteStackSetRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStackSetRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteStackSetRequest), arg0) +} + +// DeleteStackSetWithContext mocks base method. +func (m *MockCloudFormationAPI) DeleteStackSetWithContext(arg0 aws.Context, arg1 *cloudformation.DeleteStackSetInput, arg2 ...request.Option) (*cloudformation.DeleteStackSetOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteStackSetWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DeleteStackSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteStackSetWithContext indicates an expected call of DeleteStackSetWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DeleteStackSetWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStackSetWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteStackSetWithContext), varargs...) +} + +// DeleteStackWithContext mocks base method. +func (m *MockCloudFormationAPI) DeleteStackWithContext(arg0 aws.Context, arg1 *cloudformation.DeleteStackInput, arg2 ...request.Option) (*cloudformation.DeleteStackOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteStackWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DeleteStackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteStackWithContext indicates an expected call of DeleteStackWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DeleteStackWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStackWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeleteStackWithContext), varargs...) +} + +// DeregisterType mocks base method. +func (m *MockCloudFormationAPI) DeregisterType(arg0 *cloudformation.DeregisterTypeInput) (*cloudformation.DeregisterTypeOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeregisterType", arg0) + ret0, _ := ret[0].(*cloudformation.DeregisterTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeregisterType indicates an expected call of DeregisterType. +func (mr *MockCloudFormationAPIMockRecorder) DeregisterType(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeregisterType", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeregisterType), arg0) +} + +// DeregisterTypeRequest mocks base method. +func (m *MockCloudFormationAPI) DeregisterTypeRequest(arg0 *cloudformation.DeregisterTypeInput) (*request.Request, *cloudformation.DeregisterTypeOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeregisterTypeRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DeregisterTypeOutput) + return ret0, ret1 +} + +// DeregisterTypeRequest indicates an expected call of DeregisterTypeRequest. +func (mr *MockCloudFormationAPIMockRecorder) DeregisterTypeRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeregisterTypeRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeregisterTypeRequest), arg0) +} + +// DeregisterTypeWithContext mocks base method. +func (m *MockCloudFormationAPI) DeregisterTypeWithContext(arg0 aws.Context, arg1 *cloudformation.DeregisterTypeInput, arg2 ...request.Option) (*cloudformation.DeregisterTypeOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeregisterTypeWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DeregisterTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeregisterTypeWithContext indicates an expected call of DeregisterTypeWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DeregisterTypeWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeregisterTypeWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DeregisterTypeWithContext), varargs...) +} + +// DescribeAccountLimits mocks base method. +func (m *MockCloudFormationAPI) DescribeAccountLimits(arg0 *cloudformation.DescribeAccountLimitsInput) (*cloudformation.DescribeAccountLimitsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeAccountLimits", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeAccountLimitsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeAccountLimits indicates an expected call of DescribeAccountLimits. +func (mr *MockCloudFormationAPIMockRecorder) DescribeAccountLimits(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeAccountLimits", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeAccountLimits), arg0) +} + +// DescribeAccountLimitsPages mocks base method. +func (m *MockCloudFormationAPI) DescribeAccountLimitsPages(arg0 *cloudformation.DescribeAccountLimitsInput, arg1 func(*cloudformation.DescribeAccountLimitsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeAccountLimitsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// DescribeAccountLimitsPages indicates an expected call of DescribeAccountLimitsPages. +func (mr *MockCloudFormationAPIMockRecorder) DescribeAccountLimitsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeAccountLimitsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeAccountLimitsPages), arg0, arg1) +} + +// DescribeAccountLimitsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeAccountLimitsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeAccountLimitsInput, arg2 func(*cloudformation.DescribeAccountLimitsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeAccountLimitsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// DescribeAccountLimitsPagesWithContext indicates an expected call of DescribeAccountLimitsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeAccountLimitsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeAccountLimitsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeAccountLimitsPagesWithContext), varargs...) +} + +// DescribeAccountLimitsRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeAccountLimitsRequest(arg0 *cloudformation.DescribeAccountLimitsInput) (*request.Request, *cloudformation.DescribeAccountLimitsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeAccountLimitsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeAccountLimitsOutput) + return ret0, ret1 +} + +// DescribeAccountLimitsRequest indicates an expected call of DescribeAccountLimitsRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeAccountLimitsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeAccountLimitsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeAccountLimitsRequest), arg0) +} + +// DescribeAccountLimitsWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeAccountLimitsWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeAccountLimitsInput, arg2 ...request.Option) (*cloudformation.DescribeAccountLimitsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeAccountLimitsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeAccountLimitsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeAccountLimitsWithContext indicates an expected call of DescribeAccountLimitsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeAccountLimitsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeAccountLimitsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeAccountLimitsWithContext), varargs...) +} + +// DescribeChangeSet mocks base method. +func (m *MockCloudFormationAPI) DescribeChangeSet(arg0 *cloudformation.DescribeChangeSetInput) (*cloudformation.DescribeChangeSetOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeChangeSet", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeChangeSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeChangeSet indicates an expected call of DescribeChangeSet. +func (mr *MockCloudFormationAPIMockRecorder) DescribeChangeSet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeChangeSet", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeChangeSet), arg0) +} + +// DescribeChangeSetHooks mocks base method. +func (m *MockCloudFormationAPI) DescribeChangeSetHooks(arg0 *cloudformation.DescribeChangeSetHooksInput) (*cloudformation.DescribeChangeSetHooksOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeChangeSetHooks", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeChangeSetHooksOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeChangeSetHooks indicates an expected call of DescribeChangeSetHooks. +func (mr *MockCloudFormationAPIMockRecorder) DescribeChangeSetHooks(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeChangeSetHooks", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeChangeSetHooks), arg0) +} + +// DescribeChangeSetHooksRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeChangeSetHooksRequest(arg0 *cloudformation.DescribeChangeSetHooksInput) (*request.Request, *cloudformation.DescribeChangeSetHooksOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeChangeSetHooksRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeChangeSetHooksOutput) + return ret0, ret1 +} + +// DescribeChangeSetHooksRequest indicates an expected call of DescribeChangeSetHooksRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeChangeSetHooksRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeChangeSetHooksRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeChangeSetHooksRequest), arg0) +} + +// DescribeChangeSetHooksWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeChangeSetHooksWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeChangeSetHooksInput, arg2 ...request.Option) (*cloudformation.DescribeChangeSetHooksOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeChangeSetHooksWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeChangeSetHooksOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeChangeSetHooksWithContext indicates an expected call of DescribeChangeSetHooksWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeChangeSetHooksWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeChangeSetHooksWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeChangeSetHooksWithContext), varargs...) +} + +// DescribeChangeSetRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeChangeSetRequest(arg0 *cloudformation.DescribeChangeSetInput) (*request.Request, *cloudformation.DescribeChangeSetOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeChangeSetRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeChangeSetOutput) + return ret0, ret1 +} + +// DescribeChangeSetRequest indicates an expected call of DescribeChangeSetRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeChangeSetRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeChangeSetRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeChangeSetRequest), arg0) +} + +// DescribeChangeSetWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeChangeSetWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeChangeSetInput, arg2 ...request.Option) (*cloudformation.DescribeChangeSetOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeChangeSetWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeChangeSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeChangeSetWithContext indicates an expected call of DescribeChangeSetWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeChangeSetWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeChangeSetWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeChangeSetWithContext), varargs...) +} + +// DescribeGeneratedTemplate mocks base method. +func (m *MockCloudFormationAPI) DescribeGeneratedTemplate(arg0 *cloudformation.DescribeGeneratedTemplateInput) (*cloudformation.DescribeGeneratedTemplateOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeGeneratedTemplate", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeGeneratedTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeGeneratedTemplate indicates an expected call of DescribeGeneratedTemplate. +func (mr *MockCloudFormationAPIMockRecorder) DescribeGeneratedTemplate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeGeneratedTemplate", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeGeneratedTemplate), arg0) +} + +// DescribeGeneratedTemplateRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeGeneratedTemplateRequest(arg0 *cloudformation.DescribeGeneratedTemplateInput) (*request.Request, *cloudformation.DescribeGeneratedTemplateOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeGeneratedTemplateRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeGeneratedTemplateOutput) + return ret0, ret1 +} + +// DescribeGeneratedTemplateRequest indicates an expected call of DescribeGeneratedTemplateRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeGeneratedTemplateRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeGeneratedTemplateRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeGeneratedTemplateRequest), arg0) +} + +// DescribeGeneratedTemplateWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeGeneratedTemplateWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeGeneratedTemplateInput, arg2 ...request.Option) (*cloudformation.DescribeGeneratedTemplateOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeGeneratedTemplateWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeGeneratedTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeGeneratedTemplateWithContext indicates an expected call of DescribeGeneratedTemplateWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeGeneratedTemplateWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeGeneratedTemplateWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeGeneratedTemplateWithContext), varargs...) +} + +// DescribeOrganizationsAccess mocks base method. +func (m *MockCloudFormationAPI) DescribeOrganizationsAccess(arg0 *cloudformation.DescribeOrganizationsAccessInput) (*cloudformation.DescribeOrganizationsAccessOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeOrganizationsAccess", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeOrganizationsAccessOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeOrganizationsAccess indicates an expected call of DescribeOrganizationsAccess. +func (mr *MockCloudFormationAPIMockRecorder) DescribeOrganizationsAccess(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeOrganizationsAccess", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeOrganizationsAccess), arg0) +} + +// DescribeOrganizationsAccessRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeOrganizationsAccessRequest(arg0 *cloudformation.DescribeOrganizationsAccessInput) (*request.Request, *cloudformation.DescribeOrganizationsAccessOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeOrganizationsAccessRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeOrganizationsAccessOutput) + return ret0, ret1 +} + +// DescribeOrganizationsAccessRequest indicates an expected call of DescribeOrganizationsAccessRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeOrganizationsAccessRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeOrganizationsAccessRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeOrganizationsAccessRequest), arg0) +} + +// DescribeOrganizationsAccessWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeOrganizationsAccessWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeOrganizationsAccessInput, arg2 ...request.Option) (*cloudformation.DescribeOrganizationsAccessOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeOrganizationsAccessWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeOrganizationsAccessOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeOrganizationsAccessWithContext indicates an expected call of DescribeOrganizationsAccessWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeOrganizationsAccessWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeOrganizationsAccessWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeOrganizationsAccessWithContext), varargs...) +} + +// DescribePublisher mocks base method. +func (m *MockCloudFormationAPI) DescribePublisher(arg0 *cloudformation.DescribePublisherInput) (*cloudformation.DescribePublisherOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribePublisher", arg0) + ret0, _ := ret[0].(*cloudformation.DescribePublisherOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribePublisher indicates an expected call of DescribePublisher. +func (mr *MockCloudFormationAPIMockRecorder) DescribePublisher(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribePublisher", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribePublisher), arg0) +} + +// DescribePublisherRequest mocks base method. +func (m *MockCloudFormationAPI) DescribePublisherRequest(arg0 *cloudformation.DescribePublisherInput) (*request.Request, *cloudformation.DescribePublisherOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribePublisherRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribePublisherOutput) + return ret0, ret1 +} + +// DescribePublisherRequest indicates an expected call of DescribePublisherRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribePublisherRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribePublisherRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribePublisherRequest), arg0) +} + +// DescribePublisherWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribePublisherWithContext(arg0 aws.Context, arg1 *cloudformation.DescribePublisherInput, arg2 ...request.Option) (*cloudformation.DescribePublisherOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribePublisherWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribePublisherOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribePublisherWithContext indicates an expected call of DescribePublisherWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribePublisherWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribePublisherWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribePublisherWithContext), varargs...) +} + +// DescribeResourceScan mocks base method. +func (m *MockCloudFormationAPI) DescribeResourceScan(arg0 *cloudformation.DescribeResourceScanInput) (*cloudformation.DescribeResourceScanOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeResourceScan", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeResourceScanOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeResourceScan indicates an expected call of DescribeResourceScan. +func (mr *MockCloudFormationAPIMockRecorder) DescribeResourceScan(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeResourceScan", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeResourceScan), arg0) +} + +// DescribeResourceScanRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeResourceScanRequest(arg0 *cloudformation.DescribeResourceScanInput) (*request.Request, *cloudformation.DescribeResourceScanOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeResourceScanRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeResourceScanOutput) + return ret0, ret1 +} + +// DescribeResourceScanRequest indicates an expected call of DescribeResourceScanRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeResourceScanRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeResourceScanRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeResourceScanRequest), arg0) +} + +// DescribeResourceScanWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeResourceScanWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeResourceScanInput, arg2 ...request.Option) (*cloudformation.DescribeResourceScanOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeResourceScanWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeResourceScanOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeResourceScanWithContext indicates an expected call of DescribeResourceScanWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeResourceScanWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeResourceScanWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeResourceScanWithContext), varargs...) +} + +// DescribeStackDriftDetectionStatus mocks base method. +func (m *MockCloudFormationAPI) DescribeStackDriftDetectionStatus(arg0 *cloudformation.DescribeStackDriftDetectionStatusInput) (*cloudformation.DescribeStackDriftDetectionStatusOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackDriftDetectionStatus", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeStackDriftDetectionStatusOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackDriftDetectionStatus indicates an expected call of DescribeStackDriftDetectionStatus. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackDriftDetectionStatus(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackDriftDetectionStatus", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackDriftDetectionStatus), arg0) +} + +// DescribeStackDriftDetectionStatusRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeStackDriftDetectionStatusRequest(arg0 *cloudformation.DescribeStackDriftDetectionStatusInput) (*request.Request, *cloudformation.DescribeStackDriftDetectionStatusOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackDriftDetectionStatusRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeStackDriftDetectionStatusOutput) + return ret0, ret1 +} + +// DescribeStackDriftDetectionStatusRequest indicates an expected call of DescribeStackDriftDetectionStatusRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackDriftDetectionStatusRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackDriftDetectionStatusRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackDriftDetectionStatusRequest), arg0) +} + +// DescribeStackDriftDetectionStatusWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStackDriftDetectionStatusWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStackDriftDetectionStatusInput, arg2 ...request.Option) (*cloudformation.DescribeStackDriftDetectionStatusOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStackDriftDetectionStatusWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeStackDriftDetectionStatusOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackDriftDetectionStatusWithContext indicates an expected call of DescribeStackDriftDetectionStatusWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackDriftDetectionStatusWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackDriftDetectionStatusWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackDriftDetectionStatusWithContext), varargs...) +} + +// DescribeStackEvents mocks base method. +func (m *MockCloudFormationAPI) DescribeStackEvents(arg0 *cloudformation.DescribeStackEventsInput) (*cloudformation.DescribeStackEventsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackEvents", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeStackEventsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackEvents indicates an expected call of DescribeStackEvents. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackEvents(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackEvents", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackEvents), arg0) +} + +// DescribeStackEventsPages mocks base method. +func (m *MockCloudFormationAPI) DescribeStackEventsPages(arg0 *cloudformation.DescribeStackEventsInput, arg1 func(*cloudformation.DescribeStackEventsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackEventsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// DescribeStackEventsPages indicates an expected call of DescribeStackEventsPages. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackEventsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackEventsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackEventsPages), arg0, arg1) +} + +// DescribeStackEventsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStackEventsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStackEventsInput, arg2 func(*cloudformation.DescribeStackEventsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStackEventsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// DescribeStackEventsPagesWithContext indicates an expected call of DescribeStackEventsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackEventsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackEventsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackEventsPagesWithContext), varargs...) +} + +// DescribeStackEventsRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeStackEventsRequest(arg0 *cloudformation.DescribeStackEventsInput) (*request.Request, *cloudformation.DescribeStackEventsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackEventsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeStackEventsOutput) + return ret0, ret1 +} + +// DescribeStackEventsRequest indicates an expected call of DescribeStackEventsRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackEventsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackEventsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackEventsRequest), arg0) +} + +// DescribeStackEventsWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStackEventsWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStackEventsInput, arg2 ...request.Option) (*cloudformation.DescribeStackEventsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStackEventsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeStackEventsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackEventsWithContext indicates an expected call of DescribeStackEventsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackEventsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackEventsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackEventsWithContext), varargs...) +} + +// DescribeStackInstance mocks base method. +func (m *MockCloudFormationAPI) DescribeStackInstance(arg0 *cloudformation.DescribeStackInstanceInput) (*cloudformation.DescribeStackInstanceOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackInstance", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeStackInstanceOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackInstance indicates an expected call of DescribeStackInstance. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackInstance(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackInstance", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackInstance), arg0) +} + +// DescribeStackInstanceRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeStackInstanceRequest(arg0 *cloudformation.DescribeStackInstanceInput) (*request.Request, *cloudformation.DescribeStackInstanceOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackInstanceRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeStackInstanceOutput) + return ret0, ret1 +} + +// DescribeStackInstanceRequest indicates an expected call of DescribeStackInstanceRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackInstanceRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackInstanceRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackInstanceRequest), arg0) +} + +// DescribeStackInstanceWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStackInstanceWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStackInstanceInput, arg2 ...request.Option) (*cloudformation.DescribeStackInstanceOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStackInstanceWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeStackInstanceOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackInstanceWithContext indicates an expected call of DescribeStackInstanceWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackInstanceWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackInstanceWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackInstanceWithContext), varargs...) +} + +// DescribeStackResource mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResource(arg0 *cloudformation.DescribeStackResourceInput) (*cloudformation.DescribeStackResourceOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackResource", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeStackResourceOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackResource indicates an expected call of DescribeStackResource. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResource(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResource", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResource), arg0) +} + +// DescribeStackResourceDrifts mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResourceDrifts(arg0 *cloudformation.DescribeStackResourceDriftsInput) (*cloudformation.DescribeStackResourceDriftsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackResourceDrifts", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeStackResourceDriftsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackResourceDrifts indicates an expected call of DescribeStackResourceDrifts. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResourceDrifts(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResourceDrifts", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResourceDrifts), arg0) +} + +// DescribeStackResourceDriftsPages mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResourceDriftsPages(arg0 *cloudformation.DescribeStackResourceDriftsInput, arg1 func(*cloudformation.DescribeStackResourceDriftsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackResourceDriftsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// DescribeStackResourceDriftsPages indicates an expected call of DescribeStackResourceDriftsPages. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResourceDriftsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResourceDriftsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResourceDriftsPages), arg0, arg1) +} + +// DescribeStackResourceDriftsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResourceDriftsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStackResourceDriftsInput, arg2 func(*cloudformation.DescribeStackResourceDriftsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStackResourceDriftsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// DescribeStackResourceDriftsPagesWithContext indicates an expected call of DescribeStackResourceDriftsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResourceDriftsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResourceDriftsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResourceDriftsPagesWithContext), varargs...) +} + +// DescribeStackResourceDriftsRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResourceDriftsRequest(arg0 *cloudformation.DescribeStackResourceDriftsInput) (*request.Request, *cloudformation.DescribeStackResourceDriftsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackResourceDriftsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeStackResourceDriftsOutput) + return ret0, ret1 +} + +// DescribeStackResourceDriftsRequest indicates an expected call of DescribeStackResourceDriftsRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResourceDriftsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResourceDriftsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResourceDriftsRequest), arg0) +} + +// DescribeStackResourceDriftsWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResourceDriftsWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStackResourceDriftsInput, arg2 ...request.Option) (*cloudformation.DescribeStackResourceDriftsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStackResourceDriftsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeStackResourceDriftsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackResourceDriftsWithContext indicates an expected call of DescribeStackResourceDriftsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResourceDriftsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResourceDriftsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResourceDriftsWithContext), varargs...) +} + +// DescribeStackResourceRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResourceRequest(arg0 *cloudformation.DescribeStackResourceInput) (*request.Request, *cloudformation.DescribeStackResourceOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackResourceRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeStackResourceOutput) + return ret0, ret1 +} + +// DescribeStackResourceRequest indicates an expected call of DescribeStackResourceRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResourceRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResourceRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResourceRequest), arg0) +} + +// DescribeStackResourceWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResourceWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStackResourceInput, arg2 ...request.Option) (*cloudformation.DescribeStackResourceOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStackResourceWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeStackResourceOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackResourceWithContext indicates an expected call of DescribeStackResourceWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResourceWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResourceWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResourceWithContext), varargs...) +} + +// DescribeStackResources mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResources(arg0 *cloudformation.DescribeStackResourcesInput) (*cloudformation.DescribeStackResourcesOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackResources", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeStackResourcesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackResources indicates an expected call of DescribeStackResources. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResources(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResources", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResources), arg0) +} + +// DescribeStackResourcesRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResourcesRequest(arg0 *cloudformation.DescribeStackResourcesInput) (*request.Request, *cloudformation.DescribeStackResourcesOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackResourcesRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeStackResourcesOutput) + return ret0, ret1 +} + +// DescribeStackResourcesRequest indicates an expected call of DescribeStackResourcesRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResourcesRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResourcesRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResourcesRequest), arg0) +} + +// DescribeStackResourcesWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStackResourcesWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStackResourcesInput, arg2 ...request.Option) (*cloudformation.DescribeStackResourcesOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStackResourcesWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeStackResourcesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackResourcesWithContext indicates an expected call of DescribeStackResourcesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackResourcesWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackResourcesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackResourcesWithContext), varargs...) +} + +// DescribeStackSet mocks base method. +func (m *MockCloudFormationAPI) DescribeStackSet(arg0 *cloudformation.DescribeStackSetInput) (*cloudformation.DescribeStackSetOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackSet", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeStackSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackSet indicates an expected call of DescribeStackSet. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackSet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackSet", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackSet), arg0) +} + +// DescribeStackSetOperation mocks base method. +func (m *MockCloudFormationAPI) DescribeStackSetOperation(arg0 *cloudformation.DescribeStackSetOperationInput) (*cloudformation.DescribeStackSetOperationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackSetOperation", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeStackSetOperationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackSetOperation indicates an expected call of DescribeStackSetOperation. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackSetOperation(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackSetOperation", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackSetOperation), arg0) +} + +// DescribeStackSetOperationRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeStackSetOperationRequest(arg0 *cloudformation.DescribeStackSetOperationInput) (*request.Request, *cloudformation.DescribeStackSetOperationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackSetOperationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeStackSetOperationOutput) + return ret0, ret1 +} + +// DescribeStackSetOperationRequest indicates an expected call of DescribeStackSetOperationRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackSetOperationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackSetOperationRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackSetOperationRequest), arg0) +} + +// DescribeStackSetOperationWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStackSetOperationWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStackSetOperationInput, arg2 ...request.Option) (*cloudformation.DescribeStackSetOperationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStackSetOperationWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeStackSetOperationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackSetOperationWithContext indicates an expected call of DescribeStackSetOperationWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackSetOperationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackSetOperationWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackSetOperationWithContext), varargs...) +} + +// DescribeStackSetRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeStackSetRequest(arg0 *cloudformation.DescribeStackSetInput) (*request.Request, *cloudformation.DescribeStackSetOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStackSetRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeStackSetOutput) + return ret0, ret1 +} + +// DescribeStackSetRequest indicates an expected call of DescribeStackSetRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackSetRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackSetRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackSetRequest), arg0) +} + +// DescribeStackSetWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStackSetWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStackSetInput, arg2 ...request.Option) (*cloudformation.DescribeStackSetOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStackSetWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeStackSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStackSetWithContext indicates an expected call of DescribeStackSetWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStackSetWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStackSetWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStackSetWithContext), varargs...) +} + +// DescribeStacks mocks base method. +func (m *MockCloudFormationAPI) DescribeStacks(arg0 *cloudformation.DescribeStacksInput) (*cloudformation.DescribeStacksOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStacks", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeStacksOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStacks indicates an expected call of DescribeStacks. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStacks(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStacks", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStacks), arg0) +} + +// DescribeStacksPages mocks base method. +func (m *MockCloudFormationAPI) DescribeStacksPages(arg0 *cloudformation.DescribeStacksInput, arg1 func(*cloudformation.DescribeStacksOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStacksPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// DescribeStacksPages indicates an expected call of DescribeStacksPages. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStacksPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStacksPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStacksPages), arg0, arg1) +} + +// DescribeStacksPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStacksPagesWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStacksInput, arg2 func(*cloudformation.DescribeStacksOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStacksPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// DescribeStacksPagesWithContext indicates an expected call of DescribeStacksPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStacksPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStacksPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStacksPagesWithContext), varargs...) +} + +// DescribeStacksRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeStacksRequest(arg0 *cloudformation.DescribeStacksInput) (*request.Request, *cloudformation.DescribeStacksOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeStacksRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeStacksOutput) + return ret0, ret1 +} + +// DescribeStacksRequest indicates an expected call of DescribeStacksRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStacksRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStacksRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStacksRequest), arg0) +} + +// DescribeStacksWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeStacksWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStacksInput, arg2 ...request.Option) (*cloudformation.DescribeStacksOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeStacksWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeStacksOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeStacksWithContext indicates an expected call of DescribeStacksWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeStacksWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeStacksWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeStacksWithContext), varargs...) +} + +// DescribeType mocks base method. +func (m *MockCloudFormationAPI) DescribeType(arg0 *cloudformation.DescribeTypeInput) (*cloudformation.DescribeTypeOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeType", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeType indicates an expected call of DescribeType. +func (mr *MockCloudFormationAPIMockRecorder) DescribeType(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeType", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeType), arg0) +} + +// DescribeTypeRegistration mocks base method. +func (m *MockCloudFormationAPI) DescribeTypeRegistration(arg0 *cloudformation.DescribeTypeRegistrationInput) (*cloudformation.DescribeTypeRegistrationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeTypeRegistration", arg0) + ret0, _ := ret[0].(*cloudformation.DescribeTypeRegistrationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeTypeRegistration indicates an expected call of DescribeTypeRegistration. +func (mr *MockCloudFormationAPIMockRecorder) DescribeTypeRegistration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeTypeRegistration", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeTypeRegistration), arg0) +} + +// DescribeTypeRegistrationRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeTypeRegistrationRequest(arg0 *cloudformation.DescribeTypeRegistrationInput) (*request.Request, *cloudformation.DescribeTypeRegistrationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeTypeRegistrationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeTypeRegistrationOutput) + return ret0, ret1 +} + +// DescribeTypeRegistrationRequest indicates an expected call of DescribeTypeRegistrationRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeTypeRegistrationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeTypeRegistrationRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeTypeRegistrationRequest), arg0) +} + +// DescribeTypeRegistrationWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeTypeRegistrationWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeTypeRegistrationInput, arg2 ...request.Option) (*cloudformation.DescribeTypeRegistrationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeTypeRegistrationWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeTypeRegistrationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeTypeRegistrationWithContext indicates an expected call of DescribeTypeRegistrationWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeTypeRegistrationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeTypeRegistrationWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeTypeRegistrationWithContext), varargs...) +} + +// DescribeTypeRequest mocks base method. +func (m *MockCloudFormationAPI) DescribeTypeRequest(arg0 *cloudformation.DescribeTypeInput) (*request.Request, *cloudformation.DescribeTypeOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DescribeTypeRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DescribeTypeOutput) + return ret0, ret1 +} + +// DescribeTypeRequest indicates an expected call of DescribeTypeRequest. +func (mr *MockCloudFormationAPIMockRecorder) DescribeTypeRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeTypeRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeTypeRequest), arg0) +} + +// DescribeTypeWithContext mocks base method. +func (m *MockCloudFormationAPI) DescribeTypeWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeTypeInput, arg2 ...request.Option) (*cloudformation.DescribeTypeOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DescribeTypeWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DescribeTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DescribeTypeWithContext indicates an expected call of DescribeTypeWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DescribeTypeWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeTypeWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DescribeTypeWithContext), varargs...) +} + +// DetectStackDrift mocks base method. +func (m *MockCloudFormationAPI) DetectStackDrift(arg0 *cloudformation.DetectStackDriftInput) (*cloudformation.DetectStackDriftOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DetectStackDrift", arg0) + ret0, _ := ret[0].(*cloudformation.DetectStackDriftOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DetectStackDrift indicates an expected call of DetectStackDrift. +func (mr *MockCloudFormationAPIMockRecorder) DetectStackDrift(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetectStackDrift", reflect.TypeOf((*MockCloudFormationAPI)(nil).DetectStackDrift), arg0) +} + +// DetectStackDriftRequest mocks base method. +func (m *MockCloudFormationAPI) DetectStackDriftRequest(arg0 *cloudformation.DetectStackDriftInput) (*request.Request, *cloudformation.DetectStackDriftOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DetectStackDriftRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DetectStackDriftOutput) + return ret0, ret1 +} + +// DetectStackDriftRequest indicates an expected call of DetectStackDriftRequest. +func (mr *MockCloudFormationAPIMockRecorder) DetectStackDriftRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetectStackDriftRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DetectStackDriftRequest), arg0) +} + +// DetectStackDriftWithContext mocks base method. +func (m *MockCloudFormationAPI) DetectStackDriftWithContext(arg0 aws.Context, arg1 *cloudformation.DetectStackDriftInput, arg2 ...request.Option) (*cloudformation.DetectStackDriftOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DetectStackDriftWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DetectStackDriftOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DetectStackDriftWithContext indicates an expected call of DetectStackDriftWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DetectStackDriftWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetectStackDriftWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DetectStackDriftWithContext), varargs...) +} + +// DetectStackResourceDrift mocks base method. +func (m *MockCloudFormationAPI) DetectStackResourceDrift(arg0 *cloudformation.DetectStackResourceDriftInput) (*cloudformation.DetectStackResourceDriftOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DetectStackResourceDrift", arg0) + ret0, _ := ret[0].(*cloudformation.DetectStackResourceDriftOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DetectStackResourceDrift indicates an expected call of DetectStackResourceDrift. +func (mr *MockCloudFormationAPIMockRecorder) DetectStackResourceDrift(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetectStackResourceDrift", reflect.TypeOf((*MockCloudFormationAPI)(nil).DetectStackResourceDrift), arg0) +} + +// DetectStackResourceDriftRequest mocks base method. +func (m *MockCloudFormationAPI) DetectStackResourceDriftRequest(arg0 *cloudformation.DetectStackResourceDriftInput) (*request.Request, *cloudformation.DetectStackResourceDriftOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DetectStackResourceDriftRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DetectStackResourceDriftOutput) + return ret0, ret1 +} + +// DetectStackResourceDriftRequest indicates an expected call of DetectStackResourceDriftRequest. +func (mr *MockCloudFormationAPIMockRecorder) DetectStackResourceDriftRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetectStackResourceDriftRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DetectStackResourceDriftRequest), arg0) +} + +// DetectStackResourceDriftWithContext mocks base method. +func (m *MockCloudFormationAPI) DetectStackResourceDriftWithContext(arg0 aws.Context, arg1 *cloudformation.DetectStackResourceDriftInput, arg2 ...request.Option) (*cloudformation.DetectStackResourceDriftOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DetectStackResourceDriftWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DetectStackResourceDriftOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DetectStackResourceDriftWithContext indicates an expected call of DetectStackResourceDriftWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DetectStackResourceDriftWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetectStackResourceDriftWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DetectStackResourceDriftWithContext), varargs...) +} + +// DetectStackSetDrift mocks base method. +func (m *MockCloudFormationAPI) DetectStackSetDrift(arg0 *cloudformation.DetectStackSetDriftInput) (*cloudformation.DetectStackSetDriftOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DetectStackSetDrift", arg0) + ret0, _ := ret[0].(*cloudformation.DetectStackSetDriftOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DetectStackSetDrift indicates an expected call of DetectStackSetDrift. +func (mr *MockCloudFormationAPIMockRecorder) DetectStackSetDrift(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetectStackSetDrift", reflect.TypeOf((*MockCloudFormationAPI)(nil).DetectStackSetDrift), arg0) +} + +// DetectStackSetDriftRequest mocks base method. +func (m *MockCloudFormationAPI) DetectStackSetDriftRequest(arg0 *cloudformation.DetectStackSetDriftInput) (*request.Request, *cloudformation.DetectStackSetDriftOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DetectStackSetDriftRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.DetectStackSetDriftOutput) + return ret0, ret1 +} + +// DetectStackSetDriftRequest indicates an expected call of DetectStackSetDriftRequest. +func (mr *MockCloudFormationAPIMockRecorder) DetectStackSetDriftRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetectStackSetDriftRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).DetectStackSetDriftRequest), arg0) +} + +// DetectStackSetDriftWithContext mocks base method. +func (m *MockCloudFormationAPI) DetectStackSetDriftWithContext(arg0 aws.Context, arg1 *cloudformation.DetectStackSetDriftInput, arg2 ...request.Option) (*cloudformation.DetectStackSetDriftOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DetectStackSetDriftWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.DetectStackSetDriftOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DetectStackSetDriftWithContext indicates an expected call of DetectStackSetDriftWithContext. +func (mr *MockCloudFormationAPIMockRecorder) DetectStackSetDriftWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetectStackSetDriftWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).DetectStackSetDriftWithContext), varargs...) +} + +// EstimateTemplateCost mocks base method. +func (m *MockCloudFormationAPI) EstimateTemplateCost(arg0 *cloudformation.EstimateTemplateCostInput) (*cloudformation.EstimateTemplateCostOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EstimateTemplateCost", arg0) + ret0, _ := ret[0].(*cloudformation.EstimateTemplateCostOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EstimateTemplateCost indicates an expected call of EstimateTemplateCost. +func (mr *MockCloudFormationAPIMockRecorder) EstimateTemplateCost(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimateTemplateCost", reflect.TypeOf((*MockCloudFormationAPI)(nil).EstimateTemplateCost), arg0) +} + +// EstimateTemplateCostRequest mocks base method. +func (m *MockCloudFormationAPI) EstimateTemplateCostRequest(arg0 *cloudformation.EstimateTemplateCostInput) (*request.Request, *cloudformation.EstimateTemplateCostOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EstimateTemplateCostRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.EstimateTemplateCostOutput) + return ret0, ret1 +} + +// EstimateTemplateCostRequest indicates an expected call of EstimateTemplateCostRequest. +func (mr *MockCloudFormationAPIMockRecorder) EstimateTemplateCostRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimateTemplateCostRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).EstimateTemplateCostRequest), arg0) +} + +// EstimateTemplateCostWithContext mocks base method. +func (m *MockCloudFormationAPI) EstimateTemplateCostWithContext(arg0 aws.Context, arg1 *cloudformation.EstimateTemplateCostInput, arg2 ...request.Option) (*cloudformation.EstimateTemplateCostOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "EstimateTemplateCostWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.EstimateTemplateCostOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EstimateTemplateCostWithContext indicates an expected call of EstimateTemplateCostWithContext. +func (mr *MockCloudFormationAPIMockRecorder) EstimateTemplateCostWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimateTemplateCostWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).EstimateTemplateCostWithContext), varargs...) +} + +// ExecuteChangeSet mocks base method. +func (m *MockCloudFormationAPI) ExecuteChangeSet(arg0 *cloudformation.ExecuteChangeSetInput) (*cloudformation.ExecuteChangeSetOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExecuteChangeSet", arg0) + ret0, _ := ret[0].(*cloudformation.ExecuteChangeSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExecuteChangeSet indicates an expected call of ExecuteChangeSet. +func (mr *MockCloudFormationAPIMockRecorder) ExecuteChangeSet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecuteChangeSet", reflect.TypeOf((*MockCloudFormationAPI)(nil).ExecuteChangeSet), arg0) +} + +// ExecuteChangeSetRequest mocks base method. +func (m *MockCloudFormationAPI) ExecuteChangeSetRequest(arg0 *cloudformation.ExecuteChangeSetInput) (*request.Request, *cloudformation.ExecuteChangeSetOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExecuteChangeSetRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ExecuteChangeSetOutput) + return ret0, ret1 +} + +// ExecuteChangeSetRequest indicates an expected call of ExecuteChangeSetRequest. +func (mr *MockCloudFormationAPIMockRecorder) ExecuteChangeSetRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecuteChangeSetRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ExecuteChangeSetRequest), arg0) +} + +// ExecuteChangeSetWithContext mocks base method. +func (m *MockCloudFormationAPI) ExecuteChangeSetWithContext(arg0 aws.Context, arg1 *cloudformation.ExecuteChangeSetInput, arg2 ...request.Option) (*cloudformation.ExecuteChangeSetOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ExecuteChangeSetWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ExecuteChangeSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExecuteChangeSetWithContext indicates an expected call of ExecuteChangeSetWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ExecuteChangeSetWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecuteChangeSetWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ExecuteChangeSetWithContext), varargs...) +} + +// GetGeneratedTemplate mocks base method. +func (m *MockCloudFormationAPI) GetGeneratedTemplate(arg0 *cloudformation.GetGeneratedTemplateInput) (*cloudformation.GetGeneratedTemplateOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetGeneratedTemplate", arg0) + ret0, _ := ret[0].(*cloudformation.GetGeneratedTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetGeneratedTemplate indicates an expected call of GetGeneratedTemplate. +func (mr *MockCloudFormationAPIMockRecorder) GetGeneratedTemplate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGeneratedTemplate", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetGeneratedTemplate), arg0) +} + +// GetGeneratedTemplateRequest mocks base method. +func (m *MockCloudFormationAPI) GetGeneratedTemplateRequest(arg0 *cloudformation.GetGeneratedTemplateInput) (*request.Request, *cloudformation.GetGeneratedTemplateOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetGeneratedTemplateRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.GetGeneratedTemplateOutput) + return ret0, ret1 +} + +// GetGeneratedTemplateRequest indicates an expected call of GetGeneratedTemplateRequest. +func (mr *MockCloudFormationAPIMockRecorder) GetGeneratedTemplateRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGeneratedTemplateRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetGeneratedTemplateRequest), arg0) +} + +// GetGeneratedTemplateWithContext mocks base method. +func (m *MockCloudFormationAPI) GetGeneratedTemplateWithContext(arg0 aws.Context, arg1 *cloudformation.GetGeneratedTemplateInput, arg2 ...request.Option) (*cloudformation.GetGeneratedTemplateOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetGeneratedTemplateWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.GetGeneratedTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetGeneratedTemplateWithContext indicates an expected call of GetGeneratedTemplateWithContext. +func (mr *MockCloudFormationAPIMockRecorder) GetGeneratedTemplateWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGeneratedTemplateWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetGeneratedTemplateWithContext), varargs...) +} + +// GetStackPolicy mocks base method. +func (m *MockCloudFormationAPI) GetStackPolicy(arg0 *cloudformation.GetStackPolicyInput) (*cloudformation.GetStackPolicyOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStackPolicy", arg0) + ret0, _ := ret[0].(*cloudformation.GetStackPolicyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStackPolicy indicates an expected call of GetStackPolicy. +func (mr *MockCloudFormationAPIMockRecorder) GetStackPolicy(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStackPolicy", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetStackPolicy), arg0) +} + +// GetStackPolicyRequest mocks base method. +func (m *MockCloudFormationAPI) GetStackPolicyRequest(arg0 *cloudformation.GetStackPolicyInput) (*request.Request, *cloudformation.GetStackPolicyOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStackPolicyRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.GetStackPolicyOutput) + return ret0, ret1 +} + +// GetStackPolicyRequest indicates an expected call of GetStackPolicyRequest. +func (mr *MockCloudFormationAPIMockRecorder) GetStackPolicyRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStackPolicyRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetStackPolicyRequest), arg0) +} + +// GetStackPolicyWithContext mocks base method. +func (m *MockCloudFormationAPI) GetStackPolicyWithContext(arg0 aws.Context, arg1 *cloudformation.GetStackPolicyInput, arg2 ...request.Option) (*cloudformation.GetStackPolicyOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetStackPolicyWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.GetStackPolicyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStackPolicyWithContext indicates an expected call of GetStackPolicyWithContext. +func (mr *MockCloudFormationAPIMockRecorder) GetStackPolicyWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStackPolicyWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetStackPolicyWithContext), varargs...) +} + +// GetTemplate mocks base method. +func (m *MockCloudFormationAPI) GetTemplate(arg0 *cloudformation.GetTemplateInput) (*cloudformation.GetTemplateOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTemplate", arg0) + ret0, _ := ret[0].(*cloudformation.GetTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTemplate indicates an expected call of GetTemplate. +func (mr *MockCloudFormationAPIMockRecorder) GetTemplate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTemplate", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetTemplate), arg0) +} + +// GetTemplateRequest mocks base method. +func (m *MockCloudFormationAPI) GetTemplateRequest(arg0 *cloudformation.GetTemplateInput) (*request.Request, *cloudformation.GetTemplateOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTemplateRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.GetTemplateOutput) + return ret0, ret1 +} + +// GetTemplateRequest indicates an expected call of GetTemplateRequest. +func (mr *MockCloudFormationAPIMockRecorder) GetTemplateRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTemplateRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetTemplateRequest), arg0) +} + +// GetTemplateSummary mocks base method. +func (m *MockCloudFormationAPI) GetTemplateSummary(arg0 *cloudformation.GetTemplateSummaryInput) (*cloudformation.GetTemplateSummaryOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTemplateSummary", arg0) + ret0, _ := ret[0].(*cloudformation.GetTemplateSummaryOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTemplateSummary indicates an expected call of GetTemplateSummary. +func (mr *MockCloudFormationAPIMockRecorder) GetTemplateSummary(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTemplateSummary", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetTemplateSummary), arg0) +} + +// GetTemplateSummaryRequest mocks base method. +func (m *MockCloudFormationAPI) GetTemplateSummaryRequest(arg0 *cloudformation.GetTemplateSummaryInput) (*request.Request, *cloudformation.GetTemplateSummaryOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTemplateSummaryRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.GetTemplateSummaryOutput) + return ret0, ret1 +} + +// GetTemplateSummaryRequest indicates an expected call of GetTemplateSummaryRequest. +func (mr *MockCloudFormationAPIMockRecorder) GetTemplateSummaryRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTemplateSummaryRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetTemplateSummaryRequest), arg0) +} + +// GetTemplateSummaryWithContext mocks base method. +func (m *MockCloudFormationAPI) GetTemplateSummaryWithContext(arg0 aws.Context, arg1 *cloudformation.GetTemplateSummaryInput, arg2 ...request.Option) (*cloudformation.GetTemplateSummaryOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetTemplateSummaryWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.GetTemplateSummaryOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTemplateSummaryWithContext indicates an expected call of GetTemplateSummaryWithContext. +func (mr *MockCloudFormationAPIMockRecorder) GetTemplateSummaryWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTemplateSummaryWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetTemplateSummaryWithContext), varargs...) +} + +// GetTemplateWithContext mocks base method. +func (m *MockCloudFormationAPI) GetTemplateWithContext(arg0 aws.Context, arg1 *cloudformation.GetTemplateInput, arg2 ...request.Option) (*cloudformation.GetTemplateOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetTemplateWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.GetTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTemplateWithContext indicates an expected call of GetTemplateWithContext. +func (mr *MockCloudFormationAPIMockRecorder) GetTemplateWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTemplateWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).GetTemplateWithContext), varargs...) +} + +// ImportStacksToStackSet mocks base method. +func (m *MockCloudFormationAPI) ImportStacksToStackSet(arg0 *cloudformation.ImportStacksToStackSetInput) (*cloudformation.ImportStacksToStackSetOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImportStacksToStackSet", arg0) + ret0, _ := ret[0].(*cloudformation.ImportStacksToStackSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImportStacksToStackSet indicates an expected call of ImportStacksToStackSet. +func (mr *MockCloudFormationAPIMockRecorder) ImportStacksToStackSet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImportStacksToStackSet", reflect.TypeOf((*MockCloudFormationAPI)(nil).ImportStacksToStackSet), arg0) +} + +// ImportStacksToStackSetRequest mocks base method. +func (m *MockCloudFormationAPI) ImportStacksToStackSetRequest(arg0 *cloudformation.ImportStacksToStackSetInput) (*request.Request, *cloudformation.ImportStacksToStackSetOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImportStacksToStackSetRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ImportStacksToStackSetOutput) + return ret0, ret1 +} + +// ImportStacksToStackSetRequest indicates an expected call of ImportStacksToStackSetRequest. +func (mr *MockCloudFormationAPIMockRecorder) ImportStacksToStackSetRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImportStacksToStackSetRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ImportStacksToStackSetRequest), arg0) +} + +// ImportStacksToStackSetWithContext mocks base method. +func (m *MockCloudFormationAPI) ImportStacksToStackSetWithContext(arg0 aws.Context, arg1 *cloudformation.ImportStacksToStackSetInput, arg2 ...request.Option) (*cloudformation.ImportStacksToStackSetOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ImportStacksToStackSetWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ImportStacksToStackSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImportStacksToStackSetWithContext indicates an expected call of ImportStacksToStackSetWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ImportStacksToStackSetWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImportStacksToStackSetWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ImportStacksToStackSetWithContext), varargs...) +} + +// ListChangeSets mocks base method. +func (m *MockCloudFormationAPI) ListChangeSets(arg0 *cloudformation.ListChangeSetsInput) (*cloudformation.ListChangeSetsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListChangeSets", arg0) + ret0, _ := ret[0].(*cloudformation.ListChangeSetsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListChangeSets indicates an expected call of ListChangeSets. +func (mr *MockCloudFormationAPIMockRecorder) ListChangeSets(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListChangeSets", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListChangeSets), arg0) +} + +// ListChangeSetsPages mocks base method. +func (m *MockCloudFormationAPI) ListChangeSetsPages(arg0 *cloudformation.ListChangeSetsInput, arg1 func(*cloudformation.ListChangeSetsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListChangeSetsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListChangeSetsPages indicates an expected call of ListChangeSetsPages. +func (mr *MockCloudFormationAPIMockRecorder) ListChangeSetsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListChangeSetsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListChangeSetsPages), arg0, arg1) +} + +// ListChangeSetsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListChangeSetsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListChangeSetsInput, arg2 func(*cloudformation.ListChangeSetsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListChangeSetsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListChangeSetsPagesWithContext indicates an expected call of ListChangeSetsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListChangeSetsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListChangeSetsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListChangeSetsPagesWithContext), varargs...) +} + +// ListChangeSetsRequest mocks base method. +func (m *MockCloudFormationAPI) ListChangeSetsRequest(arg0 *cloudformation.ListChangeSetsInput) (*request.Request, *cloudformation.ListChangeSetsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListChangeSetsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListChangeSetsOutput) + return ret0, ret1 +} + +// ListChangeSetsRequest indicates an expected call of ListChangeSetsRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListChangeSetsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListChangeSetsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListChangeSetsRequest), arg0) +} + +// ListChangeSetsWithContext mocks base method. +func (m *MockCloudFormationAPI) ListChangeSetsWithContext(arg0 aws.Context, arg1 *cloudformation.ListChangeSetsInput, arg2 ...request.Option) (*cloudformation.ListChangeSetsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListChangeSetsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListChangeSetsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListChangeSetsWithContext indicates an expected call of ListChangeSetsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListChangeSetsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListChangeSetsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListChangeSetsWithContext), varargs...) +} + +// ListExports mocks base method. +func (m *MockCloudFormationAPI) ListExports(arg0 *cloudformation.ListExportsInput) (*cloudformation.ListExportsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListExports", arg0) + ret0, _ := ret[0].(*cloudformation.ListExportsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListExports indicates an expected call of ListExports. +func (mr *MockCloudFormationAPIMockRecorder) ListExports(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListExports", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListExports), arg0) +} + +// ListExportsPages mocks base method. +func (m *MockCloudFormationAPI) ListExportsPages(arg0 *cloudformation.ListExportsInput, arg1 func(*cloudformation.ListExportsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListExportsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListExportsPages indicates an expected call of ListExportsPages. +func (mr *MockCloudFormationAPIMockRecorder) ListExportsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListExportsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListExportsPages), arg0, arg1) +} + +// ListExportsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListExportsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListExportsInput, arg2 func(*cloudformation.ListExportsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListExportsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListExportsPagesWithContext indicates an expected call of ListExportsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListExportsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListExportsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListExportsPagesWithContext), varargs...) +} + +// ListExportsRequest mocks base method. +func (m *MockCloudFormationAPI) ListExportsRequest(arg0 *cloudformation.ListExportsInput) (*request.Request, *cloudformation.ListExportsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListExportsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListExportsOutput) + return ret0, ret1 +} + +// ListExportsRequest indicates an expected call of ListExportsRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListExportsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListExportsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListExportsRequest), arg0) +} + +// ListExportsWithContext mocks base method. +func (m *MockCloudFormationAPI) ListExportsWithContext(arg0 aws.Context, arg1 *cloudformation.ListExportsInput, arg2 ...request.Option) (*cloudformation.ListExportsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListExportsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListExportsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListExportsWithContext indicates an expected call of ListExportsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListExportsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListExportsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListExportsWithContext), varargs...) +} + +// ListGeneratedTemplates mocks base method. +func (m *MockCloudFormationAPI) ListGeneratedTemplates(arg0 *cloudformation.ListGeneratedTemplatesInput) (*cloudformation.ListGeneratedTemplatesOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListGeneratedTemplates", arg0) + ret0, _ := ret[0].(*cloudformation.ListGeneratedTemplatesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListGeneratedTemplates indicates an expected call of ListGeneratedTemplates. +func (mr *MockCloudFormationAPIMockRecorder) ListGeneratedTemplates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGeneratedTemplates", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListGeneratedTemplates), arg0) +} + +// ListGeneratedTemplatesPages mocks base method. +func (m *MockCloudFormationAPI) ListGeneratedTemplatesPages(arg0 *cloudformation.ListGeneratedTemplatesInput, arg1 func(*cloudformation.ListGeneratedTemplatesOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListGeneratedTemplatesPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListGeneratedTemplatesPages indicates an expected call of ListGeneratedTemplatesPages. +func (mr *MockCloudFormationAPIMockRecorder) ListGeneratedTemplatesPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGeneratedTemplatesPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListGeneratedTemplatesPages), arg0, arg1) +} + +// ListGeneratedTemplatesPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListGeneratedTemplatesPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListGeneratedTemplatesInput, arg2 func(*cloudformation.ListGeneratedTemplatesOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListGeneratedTemplatesPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListGeneratedTemplatesPagesWithContext indicates an expected call of ListGeneratedTemplatesPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListGeneratedTemplatesPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGeneratedTemplatesPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListGeneratedTemplatesPagesWithContext), varargs...) +} + +// ListGeneratedTemplatesRequest mocks base method. +func (m *MockCloudFormationAPI) ListGeneratedTemplatesRequest(arg0 *cloudformation.ListGeneratedTemplatesInput) (*request.Request, *cloudformation.ListGeneratedTemplatesOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListGeneratedTemplatesRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListGeneratedTemplatesOutput) + return ret0, ret1 +} + +// ListGeneratedTemplatesRequest indicates an expected call of ListGeneratedTemplatesRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListGeneratedTemplatesRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGeneratedTemplatesRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListGeneratedTemplatesRequest), arg0) +} + +// ListGeneratedTemplatesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListGeneratedTemplatesWithContext(arg0 aws.Context, arg1 *cloudformation.ListGeneratedTemplatesInput, arg2 ...request.Option) (*cloudformation.ListGeneratedTemplatesOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListGeneratedTemplatesWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListGeneratedTemplatesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListGeneratedTemplatesWithContext indicates an expected call of ListGeneratedTemplatesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListGeneratedTemplatesWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGeneratedTemplatesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListGeneratedTemplatesWithContext), varargs...) +} + +// ListImports mocks base method. +func (m *MockCloudFormationAPI) ListImports(arg0 *cloudformation.ListImportsInput) (*cloudformation.ListImportsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListImports", arg0) + ret0, _ := ret[0].(*cloudformation.ListImportsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListImports indicates an expected call of ListImports. +func (mr *MockCloudFormationAPIMockRecorder) ListImports(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImports", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListImports), arg0) +} + +// ListImportsPages mocks base method. +func (m *MockCloudFormationAPI) ListImportsPages(arg0 *cloudformation.ListImportsInput, arg1 func(*cloudformation.ListImportsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListImportsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListImportsPages indicates an expected call of ListImportsPages. +func (mr *MockCloudFormationAPIMockRecorder) ListImportsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImportsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListImportsPages), arg0, arg1) +} + +// ListImportsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListImportsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListImportsInput, arg2 func(*cloudformation.ListImportsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListImportsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListImportsPagesWithContext indicates an expected call of ListImportsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListImportsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImportsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListImportsPagesWithContext), varargs...) +} + +// ListImportsRequest mocks base method. +func (m *MockCloudFormationAPI) ListImportsRequest(arg0 *cloudformation.ListImportsInput) (*request.Request, *cloudformation.ListImportsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListImportsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListImportsOutput) + return ret0, ret1 +} + +// ListImportsRequest indicates an expected call of ListImportsRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListImportsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImportsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListImportsRequest), arg0) +} + +// ListImportsWithContext mocks base method. +func (m *MockCloudFormationAPI) ListImportsWithContext(arg0 aws.Context, arg1 *cloudformation.ListImportsInput, arg2 ...request.Option) (*cloudformation.ListImportsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListImportsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListImportsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListImportsWithContext indicates an expected call of ListImportsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListImportsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImportsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListImportsWithContext), varargs...) +} + +// ListResourceScanRelatedResources mocks base method. +func (m *MockCloudFormationAPI) ListResourceScanRelatedResources(arg0 *cloudformation.ListResourceScanRelatedResourcesInput) (*cloudformation.ListResourceScanRelatedResourcesOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResourceScanRelatedResources", arg0) + ret0, _ := ret[0].(*cloudformation.ListResourceScanRelatedResourcesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListResourceScanRelatedResources indicates an expected call of ListResourceScanRelatedResources. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScanRelatedResources(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScanRelatedResources", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScanRelatedResources), arg0) +} + +// ListResourceScanRelatedResourcesPages mocks base method. +func (m *MockCloudFormationAPI) ListResourceScanRelatedResourcesPages(arg0 *cloudformation.ListResourceScanRelatedResourcesInput, arg1 func(*cloudformation.ListResourceScanRelatedResourcesOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResourceScanRelatedResourcesPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListResourceScanRelatedResourcesPages indicates an expected call of ListResourceScanRelatedResourcesPages. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScanRelatedResourcesPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScanRelatedResourcesPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScanRelatedResourcesPages), arg0, arg1) +} + +// ListResourceScanRelatedResourcesPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListResourceScanRelatedResourcesPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListResourceScanRelatedResourcesInput, arg2 func(*cloudformation.ListResourceScanRelatedResourcesOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListResourceScanRelatedResourcesPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListResourceScanRelatedResourcesPagesWithContext indicates an expected call of ListResourceScanRelatedResourcesPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScanRelatedResourcesPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScanRelatedResourcesPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScanRelatedResourcesPagesWithContext), varargs...) +} + +// ListResourceScanRelatedResourcesRequest mocks base method. +func (m *MockCloudFormationAPI) ListResourceScanRelatedResourcesRequest(arg0 *cloudformation.ListResourceScanRelatedResourcesInput) (*request.Request, *cloudformation.ListResourceScanRelatedResourcesOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResourceScanRelatedResourcesRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListResourceScanRelatedResourcesOutput) + return ret0, ret1 +} + +// ListResourceScanRelatedResourcesRequest indicates an expected call of ListResourceScanRelatedResourcesRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScanRelatedResourcesRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScanRelatedResourcesRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScanRelatedResourcesRequest), arg0) +} + +// ListResourceScanRelatedResourcesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListResourceScanRelatedResourcesWithContext(arg0 aws.Context, arg1 *cloudformation.ListResourceScanRelatedResourcesInput, arg2 ...request.Option) (*cloudformation.ListResourceScanRelatedResourcesOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListResourceScanRelatedResourcesWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListResourceScanRelatedResourcesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListResourceScanRelatedResourcesWithContext indicates an expected call of ListResourceScanRelatedResourcesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScanRelatedResourcesWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScanRelatedResourcesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScanRelatedResourcesWithContext), varargs...) +} + +// ListResourceScanResources mocks base method. +func (m *MockCloudFormationAPI) ListResourceScanResources(arg0 *cloudformation.ListResourceScanResourcesInput) (*cloudformation.ListResourceScanResourcesOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResourceScanResources", arg0) + ret0, _ := ret[0].(*cloudformation.ListResourceScanResourcesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListResourceScanResources indicates an expected call of ListResourceScanResources. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScanResources(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScanResources", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScanResources), arg0) +} + +// ListResourceScanResourcesPages mocks base method. +func (m *MockCloudFormationAPI) ListResourceScanResourcesPages(arg0 *cloudformation.ListResourceScanResourcesInput, arg1 func(*cloudformation.ListResourceScanResourcesOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResourceScanResourcesPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListResourceScanResourcesPages indicates an expected call of ListResourceScanResourcesPages. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScanResourcesPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScanResourcesPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScanResourcesPages), arg0, arg1) +} + +// ListResourceScanResourcesPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListResourceScanResourcesPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListResourceScanResourcesInput, arg2 func(*cloudformation.ListResourceScanResourcesOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListResourceScanResourcesPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListResourceScanResourcesPagesWithContext indicates an expected call of ListResourceScanResourcesPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScanResourcesPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScanResourcesPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScanResourcesPagesWithContext), varargs...) +} + +// ListResourceScanResourcesRequest mocks base method. +func (m *MockCloudFormationAPI) ListResourceScanResourcesRequest(arg0 *cloudformation.ListResourceScanResourcesInput) (*request.Request, *cloudformation.ListResourceScanResourcesOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResourceScanResourcesRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListResourceScanResourcesOutput) + return ret0, ret1 +} + +// ListResourceScanResourcesRequest indicates an expected call of ListResourceScanResourcesRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScanResourcesRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScanResourcesRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScanResourcesRequest), arg0) +} + +// ListResourceScanResourcesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListResourceScanResourcesWithContext(arg0 aws.Context, arg1 *cloudformation.ListResourceScanResourcesInput, arg2 ...request.Option) (*cloudformation.ListResourceScanResourcesOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListResourceScanResourcesWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListResourceScanResourcesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListResourceScanResourcesWithContext indicates an expected call of ListResourceScanResourcesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScanResourcesWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScanResourcesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScanResourcesWithContext), varargs...) +} + +// ListResourceScans mocks base method. +func (m *MockCloudFormationAPI) ListResourceScans(arg0 *cloudformation.ListResourceScansInput) (*cloudformation.ListResourceScansOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResourceScans", arg0) + ret0, _ := ret[0].(*cloudformation.ListResourceScansOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListResourceScans indicates an expected call of ListResourceScans. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScans(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScans", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScans), arg0) +} + +// ListResourceScansPages mocks base method. +func (m *MockCloudFormationAPI) ListResourceScansPages(arg0 *cloudformation.ListResourceScansInput, arg1 func(*cloudformation.ListResourceScansOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResourceScansPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListResourceScansPages indicates an expected call of ListResourceScansPages. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScansPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScansPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScansPages), arg0, arg1) +} + +// ListResourceScansPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListResourceScansPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListResourceScansInput, arg2 func(*cloudformation.ListResourceScansOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListResourceScansPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListResourceScansPagesWithContext indicates an expected call of ListResourceScansPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScansPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScansPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScansPagesWithContext), varargs...) +} + +// ListResourceScansRequest mocks base method. +func (m *MockCloudFormationAPI) ListResourceScansRequest(arg0 *cloudformation.ListResourceScansInput) (*request.Request, *cloudformation.ListResourceScansOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResourceScansRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListResourceScansOutput) + return ret0, ret1 +} + +// ListResourceScansRequest indicates an expected call of ListResourceScansRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScansRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScansRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScansRequest), arg0) +} + +// ListResourceScansWithContext mocks base method. +func (m *MockCloudFormationAPI) ListResourceScansWithContext(arg0 aws.Context, arg1 *cloudformation.ListResourceScansInput, arg2 ...request.Option) (*cloudformation.ListResourceScansOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListResourceScansWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListResourceScansOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListResourceScansWithContext indicates an expected call of ListResourceScansWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListResourceScansWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceScansWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListResourceScansWithContext), varargs...) +} + +// ListStackInstanceResourceDrifts mocks base method. +func (m *MockCloudFormationAPI) ListStackInstanceResourceDrifts(arg0 *cloudformation.ListStackInstanceResourceDriftsInput) (*cloudformation.ListStackInstanceResourceDriftsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackInstanceResourceDrifts", arg0) + ret0, _ := ret[0].(*cloudformation.ListStackInstanceResourceDriftsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackInstanceResourceDrifts indicates an expected call of ListStackInstanceResourceDrifts. +func (mr *MockCloudFormationAPIMockRecorder) ListStackInstanceResourceDrifts(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackInstanceResourceDrifts", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackInstanceResourceDrifts), arg0) +} + +// ListStackInstanceResourceDriftsRequest mocks base method. +func (m *MockCloudFormationAPI) ListStackInstanceResourceDriftsRequest(arg0 *cloudformation.ListStackInstanceResourceDriftsInput) (*request.Request, *cloudformation.ListStackInstanceResourceDriftsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackInstanceResourceDriftsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListStackInstanceResourceDriftsOutput) + return ret0, ret1 +} + +// ListStackInstanceResourceDriftsRequest indicates an expected call of ListStackInstanceResourceDriftsRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListStackInstanceResourceDriftsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackInstanceResourceDriftsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackInstanceResourceDriftsRequest), arg0) +} + +// ListStackInstanceResourceDriftsWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackInstanceResourceDriftsWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackInstanceResourceDriftsInput, arg2 ...request.Option) (*cloudformation.ListStackInstanceResourceDriftsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackInstanceResourceDriftsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListStackInstanceResourceDriftsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackInstanceResourceDriftsWithContext indicates an expected call of ListStackInstanceResourceDriftsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackInstanceResourceDriftsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackInstanceResourceDriftsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackInstanceResourceDriftsWithContext), varargs...) +} + +// ListStackInstances mocks base method. +func (m *MockCloudFormationAPI) ListStackInstances(arg0 *cloudformation.ListStackInstancesInput) (*cloudformation.ListStackInstancesOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackInstances", arg0) + ret0, _ := ret[0].(*cloudformation.ListStackInstancesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackInstances indicates an expected call of ListStackInstances. +func (mr *MockCloudFormationAPIMockRecorder) ListStackInstances(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackInstances", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackInstances), arg0) +} + +// ListStackInstancesPages mocks base method. +func (m *MockCloudFormationAPI) ListStackInstancesPages(arg0 *cloudformation.ListStackInstancesInput, arg1 func(*cloudformation.ListStackInstancesOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackInstancesPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStackInstancesPages indicates an expected call of ListStackInstancesPages. +func (mr *MockCloudFormationAPIMockRecorder) ListStackInstancesPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackInstancesPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackInstancesPages), arg0, arg1) +} + +// ListStackInstancesPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackInstancesPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackInstancesInput, arg2 func(*cloudformation.ListStackInstancesOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackInstancesPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStackInstancesPagesWithContext indicates an expected call of ListStackInstancesPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackInstancesPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackInstancesPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackInstancesPagesWithContext), varargs...) +} + +// ListStackInstancesRequest mocks base method. +func (m *MockCloudFormationAPI) ListStackInstancesRequest(arg0 *cloudformation.ListStackInstancesInput) (*request.Request, *cloudformation.ListStackInstancesOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackInstancesRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListStackInstancesOutput) + return ret0, ret1 +} + +// ListStackInstancesRequest indicates an expected call of ListStackInstancesRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListStackInstancesRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackInstancesRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackInstancesRequest), arg0) +} + +// ListStackInstancesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackInstancesWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackInstancesInput, arg2 ...request.Option) (*cloudformation.ListStackInstancesOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackInstancesWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListStackInstancesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackInstancesWithContext indicates an expected call of ListStackInstancesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackInstancesWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackInstancesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackInstancesWithContext), varargs...) +} + +// ListStackResources mocks base method. +func (m *MockCloudFormationAPI) ListStackResources(arg0 *cloudformation.ListStackResourcesInput) (*cloudformation.ListStackResourcesOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackResources", arg0) + ret0, _ := ret[0].(*cloudformation.ListStackResourcesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackResources indicates an expected call of ListStackResources. +func (mr *MockCloudFormationAPIMockRecorder) ListStackResources(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackResources", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackResources), arg0) +} + +// ListStackResourcesPages mocks base method. +func (m *MockCloudFormationAPI) ListStackResourcesPages(arg0 *cloudformation.ListStackResourcesInput, arg1 func(*cloudformation.ListStackResourcesOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackResourcesPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStackResourcesPages indicates an expected call of ListStackResourcesPages. +func (mr *MockCloudFormationAPIMockRecorder) ListStackResourcesPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackResourcesPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackResourcesPages), arg0, arg1) +} + +// ListStackResourcesPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackResourcesPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackResourcesInput, arg2 func(*cloudformation.ListStackResourcesOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackResourcesPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStackResourcesPagesWithContext indicates an expected call of ListStackResourcesPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackResourcesPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackResourcesPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackResourcesPagesWithContext), varargs...) +} + +// ListStackResourcesRequest mocks base method. +func (m *MockCloudFormationAPI) ListStackResourcesRequest(arg0 *cloudformation.ListStackResourcesInput) (*request.Request, *cloudformation.ListStackResourcesOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackResourcesRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListStackResourcesOutput) + return ret0, ret1 +} + +// ListStackResourcesRequest indicates an expected call of ListStackResourcesRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListStackResourcesRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackResourcesRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackResourcesRequest), arg0) +} + +// ListStackResourcesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackResourcesWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackResourcesInput, arg2 ...request.Option) (*cloudformation.ListStackResourcesOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackResourcesWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListStackResourcesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackResourcesWithContext indicates an expected call of ListStackResourcesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackResourcesWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackResourcesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackResourcesWithContext), varargs...) +} + +// ListStackSetAutoDeploymentTargets mocks base method. +func (m *MockCloudFormationAPI) ListStackSetAutoDeploymentTargets(arg0 *cloudformation.ListStackSetAutoDeploymentTargetsInput) (*cloudformation.ListStackSetAutoDeploymentTargetsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSetAutoDeploymentTargets", arg0) + ret0, _ := ret[0].(*cloudformation.ListStackSetAutoDeploymentTargetsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackSetAutoDeploymentTargets indicates an expected call of ListStackSetAutoDeploymentTargets. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetAutoDeploymentTargets(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetAutoDeploymentTargets", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetAutoDeploymentTargets), arg0) +} + +// ListStackSetAutoDeploymentTargetsRequest mocks base method. +func (m *MockCloudFormationAPI) ListStackSetAutoDeploymentTargetsRequest(arg0 *cloudformation.ListStackSetAutoDeploymentTargetsInput) (*request.Request, *cloudformation.ListStackSetAutoDeploymentTargetsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSetAutoDeploymentTargetsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListStackSetAutoDeploymentTargetsOutput) + return ret0, ret1 +} + +// ListStackSetAutoDeploymentTargetsRequest indicates an expected call of ListStackSetAutoDeploymentTargetsRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetAutoDeploymentTargetsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetAutoDeploymentTargetsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetAutoDeploymentTargetsRequest), arg0) +} + +// ListStackSetAutoDeploymentTargetsWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackSetAutoDeploymentTargetsWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackSetAutoDeploymentTargetsInput, arg2 ...request.Option) (*cloudformation.ListStackSetAutoDeploymentTargetsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackSetAutoDeploymentTargetsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListStackSetAutoDeploymentTargetsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackSetAutoDeploymentTargetsWithContext indicates an expected call of ListStackSetAutoDeploymentTargetsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetAutoDeploymentTargetsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetAutoDeploymentTargetsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetAutoDeploymentTargetsWithContext), varargs...) +} + +// ListStackSetOperationResults mocks base method. +func (m *MockCloudFormationAPI) ListStackSetOperationResults(arg0 *cloudformation.ListStackSetOperationResultsInput) (*cloudformation.ListStackSetOperationResultsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSetOperationResults", arg0) + ret0, _ := ret[0].(*cloudformation.ListStackSetOperationResultsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackSetOperationResults indicates an expected call of ListStackSetOperationResults. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetOperationResults(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetOperationResults", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetOperationResults), arg0) +} + +// ListStackSetOperationResultsPages mocks base method. +func (m *MockCloudFormationAPI) ListStackSetOperationResultsPages(arg0 *cloudformation.ListStackSetOperationResultsInput, arg1 func(*cloudformation.ListStackSetOperationResultsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSetOperationResultsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStackSetOperationResultsPages indicates an expected call of ListStackSetOperationResultsPages. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetOperationResultsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetOperationResultsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetOperationResultsPages), arg0, arg1) +} + +// ListStackSetOperationResultsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackSetOperationResultsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackSetOperationResultsInput, arg2 func(*cloudformation.ListStackSetOperationResultsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackSetOperationResultsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStackSetOperationResultsPagesWithContext indicates an expected call of ListStackSetOperationResultsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetOperationResultsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetOperationResultsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetOperationResultsPagesWithContext), varargs...) +} + +// ListStackSetOperationResultsRequest mocks base method. +func (m *MockCloudFormationAPI) ListStackSetOperationResultsRequest(arg0 *cloudformation.ListStackSetOperationResultsInput) (*request.Request, *cloudformation.ListStackSetOperationResultsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSetOperationResultsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListStackSetOperationResultsOutput) + return ret0, ret1 +} + +// ListStackSetOperationResultsRequest indicates an expected call of ListStackSetOperationResultsRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetOperationResultsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetOperationResultsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetOperationResultsRequest), arg0) +} + +// ListStackSetOperationResultsWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackSetOperationResultsWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackSetOperationResultsInput, arg2 ...request.Option) (*cloudformation.ListStackSetOperationResultsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackSetOperationResultsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListStackSetOperationResultsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackSetOperationResultsWithContext indicates an expected call of ListStackSetOperationResultsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetOperationResultsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetOperationResultsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetOperationResultsWithContext), varargs...) +} + +// ListStackSetOperations mocks base method. +func (m *MockCloudFormationAPI) ListStackSetOperations(arg0 *cloudformation.ListStackSetOperationsInput) (*cloudformation.ListStackSetOperationsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSetOperations", arg0) + ret0, _ := ret[0].(*cloudformation.ListStackSetOperationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackSetOperations indicates an expected call of ListStackSetOperations. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetOperations(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetOperations", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetOperations), arg0) +} + +// ListStackSetOperationsPages mocks base method. +func (m *MockCloudFormationAPI) ListStackSetOperationsPages(arg0 *cloudformation.ListStackSetOperationsInput, arg1 func(*cloudformation.ListStackSetOperationsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSetOperationsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStackSetOperationsPages indicates an expected call of ListStackSetOperationsPages. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetOperationsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetOperationsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetOperationsPages), arg0, arg1) +} + +// ListStackSetOperationsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackSetOperationsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackSetOperationsInput, arg2 func(*cloudformation.ListStackSetOperationsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackSetOperationsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStackSetOperationsPagesWithContext indicates an expected call of ListStackSetOperationsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetOperationsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetOperationsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetOperationsPagesWithContext), varargs...) +} + +// ListStackSetOperationsRequest mocks base method. +func (m *MockCloudFormationAPI) ListStackSetOperationsRequest(arg0 *cloudformation.ListStackSetOperationsInput) (*request.Request, *cloudformation.ListStackSetOperationsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSetOperationsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListStackSetOperationsOutput) + return ret0, ret1 +} + +// ListStackSetOperationsRequest indicates an expected call of ListStackSetOperationsRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetOperationsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetOperationsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetOperationsRequest), arg0) +} + +// ListStackSetOperationsWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackSetOperationsWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackSetOperationsInput, arg2 ...request.Option) (*cloudformation.ListStackSetOperationsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackSetOperationsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListStackSetOperationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackSetOperationsWithContext indicates an expected call of ListStackSetOperationsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetOperationsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetOperationsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetOperationsWithContext), varargs...) +} + +// ListStackSets mocks base method. +func (m *MockCloudFormationAPI) ListStackSets(arg0 *cloudformation.ListStackSetsInput) (*cloudformation.ListStackSetsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSets", arg0) + ret0, _ := ret[0].(*cloudformation.ListStackSetsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackSets indicates an expected call of ListStackSets. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSets(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSets", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSets), arg0) +} + +// ListStackSetsPages mocks base method. +func (m *MockCloudFormationAPI) ListStackSetsPages(arg0 *cloudformation.ListStackSetsInput, arg1 func(*cloudformation.ListStackSetsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSetsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStackSetsPages indicates an expected call of ListStackSetsPages. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetsPages), arg0, arg1) +} + +// ListStackSetsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackSetsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackSetsInput, arg2 func(*cloudformation.ListStackSetsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackSetsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStackSetsPagesWithContext indicates an expected call of ListStackSetsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetsPagesWithContext), varargs...) +} + +// ListStackSetsRequest mocks base method. +func (m *MockCloudFormationAPI) ListStackSetsRequest(arg0 *cloudformation.ListStackSetsInput) (*request.Request, *cloudformation.ListStackSetsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStackSetsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListStackSetsOutput) + return ret0, ret1 +} + +// ListStackSetsRequest indicates an expected call of ListStackSetsRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetsRequest), arg0) +} + +// ListStackSetsWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStackSetsWithContext(arg0 aws.Context, arg1 *cloudformation.ListStackSetsInput, arg2 ...request.Option) (*cloudformation.ListStackSetsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStackSetsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListStackSetsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStackSetsWithContext indicates an expected call of ListStackSetsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStackSetsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStackSetsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStackSetsWithContext), varargs...) +} + +// ListStacks mocks base method. +func (m *MockCloudFormationAPI) ListStacks(arg0 *cloudformation.ListStacksInput) (*cloudformation.ListStacksOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStacks", arg0) + ret0, _ := ret[0].(*cloudformation.ListStacksOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStacks indicates an expected call of ListStacks. +func (mr *MockCloudFormationAPIMockRecorder) ListStacks(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStacks", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStacks), arg0) +} + +// ListStacksPages mocks base method. +func (m *MockCloudFormationAPI) ListStacksPages(arg0 *cloudformation.ListStacksInput, arg1 func(*cloudformation.ListStacksOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStacksPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStacksPages indicates an expected call of ListStacksPages. +func (mr *MockCloudFormationAPIMockRecorder) ListStacksPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStacksPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStacksPages), arg0, arg1) +} + +// ListStacksPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStacksPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListStacksInput, arg2 func(*cloudformation.ListStacksOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStacksPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListStacksPagesWithContext indicates an expected call of ListStacksPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStacksPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStacksPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStacksPagesWithContext), varargs...) +} + +// ListStacksRequest mocks base method. +func (m *MockCloudFormationAPI) ListStacksRequest(arg0 *cloudformation.ListStacksInput) (*request.Request, *cloudformation.ListStacksOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListStacksRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListStacksOutput) + return ret0, ret1 +} + +// ListStacksRequest indicates an expected call of ListStacksRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListStacksRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStacksRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStacksRequest), arg0) +} + +// ListStacksWithContext mocks base method. +func (m *MockCloudFormationAPI) ListStacksWithContext(arg0 aws.Context, arg1 *cloudformation.ListStacksInput, arg2 ...request.Option) (*cloudformation.ListStacksOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListStacksWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListStacksOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListStacksWithContext indicates an expected call of ListStacksWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListStacksWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStacksWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListStacksWithContext), varargs...) +} + +// ListTypeRegistrations mocks base method. +func (m *MockCloudFormationAPI) ListTypeRegistrations(arg0 *cloudformation.ListTypeRegistrationsInput) (*cloudformation.ListTypeRegistrationsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTypeRegistrations", arg0) + ret0, _ := ret[0].(*cloudformation.ListTypeRegistrationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTypeRegistrations indicates an expected call of ListTypeRegistrations. +func (mr *MockCloudFormationAPIMockRecorder) ListTypeRegistrations(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypeRegistrations", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypeRegistrations), arg0) +} + +// ListTypeRegistrationsPages mocks base method. +func (m *MockCloudFormationAPI) ListTypeRegistrationsPages(arg0 *cloudformation.ListTypeRegistrationsInput, arg1 func(*cloudformation.ListTypeRegistrationsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTypeRegistrationsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListTypeRegistrationsPages indicates an expected call of ListTypeRegistrationsPages. +func (mr *MockCloudFormationAPIMockRecorder) ListTypeRegistrationsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypeRegistrationsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypeRegistrationsPages), arg0, arg1) +} + +// ListTypeRegistrationsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListTypeRegistrationsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListTypeRegistrationsInput, arg2 func(*cloudformation.ListTypeRegistrationsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListTypeRegistrationsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListTypeRegistrationsPagesWithContext indicates an expected call of ListTypeRegistrationsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListTypeRegistrationsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypeRegistrationsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypeRegistrationsPagesWithContext), varargs...) +} + +// ListTypeRegistrationsRequest mocks base method. +func (m *MockCloudFormationAPI) ListTypeRegistrationsRequest(arg0 *cloudformation.ListTypeRegistrationsInput) (*request.Request, *cloudformation.ListTypeRegistrationsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTypeRegistrationsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListTypeRegistrationsOutput) + return ret0, ret1 +} + +// ListTypeRegistrationsRequest indicates an expected call of ListTypeRegistrationsRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListTypeRegistrationsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypeRegistrationsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypeRegistrationsRequest), arg0) +} + +// ListTypeRegistrationsWithContext mocks base method. +func (m *MockCloudFormationAPI) ListTypeRegistrationsWithContext(arg0 aws.Context, arg1 *cloudformation.ListTypeRegistrationsInput, arg2 ...request.Option) (*cloudformation.ListTypeRegistrationsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListTypeRegistrationsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListTypeRegistrationsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTypeRegistrationsWithContext indicates an expected call of ListTypeRegistrationsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListTypeRegistrationsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypeRegistrationsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypeRegistrationsWithContext), varargs...) +} + +// ListTypeVersions mocks base method. +func (m *MockCloudFormationAPI) ListTypeVersions(arg0 *cloudformation.ListTypeVersionsInput) (*cloudformation.ListTypeVersionsOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTypeVersions", arg0) + ret0, _ := ret[0].(*cloudformation.ListTypeVersionsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTypeVersions indicates an expected call of ListTypeVersions. +func (mr *MockCloudFormationAPIMockRecorder) ListTypeVersions(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypeVersions", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypeVersions), arg0) +} + +// ListTypeVersionsPages mocks base method. +func (m *MockCloudFormationAPI) ListTypeVersionsPages(arg0 *cloudformation.ListTypeVersionsInput, arg1 func(*cloudformation.ListTypeVersionsOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTypeVersionsPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListTypeVersionsPages indicates an expected call of ListTypeVersionsPages. +func (mr *MockCloudFormationAPIMockRecorder) ListTypeVersionsPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypeVersionsPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypeVersionsPages), arg0, arg1) +} + +// ListTypeVersionsPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListTypeVersionsPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListTypeVersionsInput, arg2 func(*cloudformation.ListTypeVersionsOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListTypeVersionsPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListTypeVersionsPagesWithContext indicates an expected call of ListTypeVersionsPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListTypeVersionsPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypeVersionsPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypeVersionsPagesWithContext), varargs...) +} + +// ListTypeVersionsRequest mocks base method. +func (m *MockCloudFormationAPI) ListTypeVersionsRequest(arg0 *cloudformation.ListTypeVersionsInput) (*request.Request, *cloudformation.ListTypeVersionsOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTypeVersionsRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListTypeVersionsOutput) + return ret0, ret1 +} + +// ListTypeVersionsRequest indicates an expected call of ListTypeVersionsRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListTypeVersionsRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypeVersionsRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypeVersionsRequest), arg0) +} + +// ListTypeVersionsWithContext mocks base method. +func (m *MockCloudFormationAPI) ListTypeVersionsWithContext(arg0 aws.Context, arg1 *cloudformation.ListTypeVersionsInput, arg2 ...request.Option) (*cloudformation.ListTypeVersionsOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListTypeVersionsWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListTypeVersionsOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTypeVersionsWithContext indicates an expected call of ListTypeVersionsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListTypeVersionsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypeVersionsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypeVersionsWithContext), varargs...) +} + +// ListTypes mocks base method. +func (m *MockCloudFormationAPI) ListTypes(arg0 *cloudformation.ListTypesInput) (*cloudformation.ListTypesOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTypes", arg0) + ret0, _ := ret[0].(*cloudformation.ListTypesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTypes indicates an expected call of ListTypes. +func (mr *MockCloudFormationAPIMockRecorder) ListTypes(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypes", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypes), arg0) +} + +// ListTypesPages mocks base method. +func (m *MockCloudFormationAPI) ListTypesPages(arg0 *cloudformation.ListTypesInput, arg1 func(*cloudformation.ListTypesOutput, bool) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTypesPages", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListTypesPages indicates an expected call of ListTypesPages. +func (mr *MockCloudFormationAPIMockRecorder) ListTypesPages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypesPages", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypesPages), arg0, arg1) +} + +// ListTypesPagesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListTypesPagesWithContext(arg0 aws.Context, arg1 *cloudformation.ListTypesInput, arg2 func(*cloudformation.ListTypesOutput, bool) bool, arg3 ...request.Option) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListTypesPagesWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ListTypesPagesWithContext indicates an expected call of ListTypesPagesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListTypesPagesWithContext(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypesPagesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypesPagesWithContext), varargs...) +} + +// ListTypesRequest mocks base method. +func (m *MockCloudFormationAPI) ListTypesRequest(arg0 *cloudformation.ListTypesInput) (*request.Request, *cloudformation.ListTypesOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTypesRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ListTypesOutput) + return ret0, ret1 +} + +// ListTypesRequest indicates an expected call of ListTypesRequest. +func (mr *MockCloudFormationAPIMockRecorder) ListTypesRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypesRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypesRequest), arg0) +} + +// ListTypesWithContext mocks base method. +func (m *MockCloudFormationAPI) ListTypesWithContext(arg0 aws.Context, arg1 *cloudformation.ListTypesInput, arg2 ...request.Option) (*cloudformation.ListTypesOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListTypesWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ListTypesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTypesWithContext indicates an expected call of ListTypesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ListTypesWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTypesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ListTypesWithContext), varargs...) +} + +// PublishType mocks base method. +func (m *MockCloudFormationAPI) PublishType(arg0 *cloudformation.PublishTypeInput) (*cloudformation.PublishTypeOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PublishType", arg0) + ret0, _ := ret[0].(*cloudformation.PublishTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PublishType indicates an expected call of PublishType. +func (mr *MockCloudFormationAPIMockRecorder) PublishType(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublishType", reflect.TypeOf((*MockCloudFormationAPI)(nil).PublishType), arg0) +} + +// PublishTypeRequest mocks base method. +func (m *MockCloudFormationAPI) PublishTypeRequest(arg0 *cloudformation.PublishTypeInput) (*request.Request, *cloudformation.PublishTypeOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PublishTypeRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.PublishTypeOutput) + return ret0, ret1 +} + +// PublishTypeRequest indicates an expected call of PublishTypeRequest. +func (mr *MockCloudFormationAPIMockRecorder) PublishTypeRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublishTypeRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).PublishTypeRequest), arg0) +} + +// PublishTypeWithContext mocks base method. +func (m *MockCloudFormationAPI) PublishTypeWithContext(arg0 aws.Context, arg1 *cloudformation.PublishTypeInput, arg2 ...request.Option) (*cloudformation.PublishTypeOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "PublishTypeWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.PublishTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PublishTypeWithContext indicates an expected call of PublishTypeWithContext. +func (mr *MockCloudFormationAPIMockRecorder) PublishTypeWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublishTypeWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).PublishTypeWithContext), varargs...) +} + +// RecordHandlerProgress mocks base method. +func (m *MockCloudFormationAPI) RecordHandlerProgress(arg0 *cloudformation.RecordHandlerProgressInput) (*cloudformation.RecordHandlerProgressOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RecordHandlerProgress", arg0) + ret0, _ := ret[0].(*cloudformation.RecordHandlerProgressOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RecordHandlerProgress indicates an expected call of RecordHandlerProgress. +func (mr *MockCloudFormationAPIMockRecorder) RecordHandlerProgress(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordHandlerProgress", reflect.TypeOf((*MockCloudFormationAPI)(nil).RecordHandlerProgress), arg0) +} + +// RecordHandlerProgressRequest mocks base method. +func (m *MockCloudFormationAPI) RecordHandlerProgressRequest(arg0 *cloudformation.RecordHandlerProgressInput) (*request.Request, *cloudformation.RecordHandlerProgressOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RecordHandlerProgressRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.RecordHandlerProgressOutput) + return ret0, ret1 +} + +// RecordHandlerProgressRequest indicates an expected call of RecordHandlerProgressRequest. +func (mr *MockCloudFormationAPIMockRecorder) RecordHandlerProgressRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordHandlerProgressRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).RecordHandlerProgressRequest), arg0) +} + +// RecordHandlerProgressWithContext mocks base method. +func (m *MockCloudFormationAPI) RecordHandlerProgressWithContext(arg0 aws.Context, arg1 *cloudformation.RecordHandlerProgressInput, arg2 ...request.Option) (*cloudformation.RecordHandlerProgressOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "RecordHandlerProgressWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.RecordHandlerProgressOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RecordHandlerProgressWithContext indicates an expected call of RecordHandlerProgressWithContext. +func (mr *MockCloudFormationAPIMockRecorder) RecordHandlerProgressWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordHandlerProgressWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).RecordHandlerProgressWithContext), varargs...) +} + +// RegisterPublisher mocks base method. +func (m *MockCloudFormationAPI) RegisterPublisher(arg0 *cloudformation.RegisterPublisherInput) (*cloudformation.RegisterPublisherOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RegisterPublisher", arg0) + ret0, _ := ret[0].(*cloudformation.RegisterPublisherOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RegisterPublisher indicates an expected call of RegisterPublisher. +func (mr *MockCloudFormationAPIMockRecorder) RegisterPublisher(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterPublisher", reflect.TypeOf((*MockCloudFormationAPI)(nil).RegisterPublisher), arg0) +} + +// RegisterPublisherRequest mocks base method. +func (m *MockCloudFormationAPI) RegisterPublisherRequest(arg0 *cloudformation.RegisterPublisherInput) (*request.Request, *cloudformation.RegisterPublisherOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RegisterPublisherRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.RegisterPublisherOutput) + return ret0, ret1 +} + +// RegisterPublisherRequest indicates an expected call of RegisterPublisherRequest. +func (mr *MockCloudFormationAPIMockRecorder) RegisterPublisherRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterPublisherRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).RegisterPublisherRequest), arg0) +} + +// RegisterPublisherWithContext mocks base method. +func (m *MockCloudFormationAPI) RegisterPublisherWithContext(arg0 aws.Context, arg1 *cloudformation.RegisterPublisherInput, arg2 ...request.Option) (*cloudformation.RegisterPublisherOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "RegisterPublisherWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.RegisterPublisherOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RegisterPublisherWithContext indicates an expected call of RegisterPublisherWithContext. +func (mr *MockCloudFormationAPIMockRecorder) RegisterPublisherWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterPublisherWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).RegisterPublisherWithContext), varargs...) +} + +// RegisterType mocks base method. +func (m *MockCloudFormationAPI) RegisterType(arg0 *cloudformation.RegisterTypeInput) (*cloudformation.RegisterTypeOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RegisterType", arg0) + ret0, _ := ret[0].(*cloudformation.RegisterTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RegisterType indicates an expected call of RegisterType. +func (mr *MockCloudFormationAPIMockRecorder) RegisterType(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterType", reflect.TypeOf((*MockCloudFormationAPI)(nil).RegisterType), arg0) +} + +// RegisterTypeRequest mocks base method. +func (m *MockCloudFormationAPI) RegisterTypeRequest(arg0 *cloudformation.RegisterTypeInput) (*request.Request, *cloudformation.RegisterTypeOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RegisterTypeRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.RegisterTypeOutput) + return ret0, ret1 +} + +// RegisterTypeRequest indicates an expected call of RegisterTypeRequest. +func (mr *MockCloudFormationAPIMockRecorder) RegisterTypeRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterTypeRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).RegisterTypeRequest), arg0) +} + +// RegisterTypeWithContext mocks base method. +func (m *MockCloudFormationAPI) RegisterTypeWithContext(arg0 aws.Context, arg1 *cloudformation.RegisterTypeInput, arg2 ...request.Option) (*cloudformation.RegisterTypeOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "RegisterTypeWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.RegisterTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RegisterTypeWithContext indicates an expected call of RegisterTypeWithContext. +func (mr *MockCloudFormationAPIMockRecorder) RegisterTypeWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterTypeWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).RegisterTypeWithContext), varargs...) +} + +// RollbackStack mocks base method. +func (m *MockCloudFormationAPI) RollbackStack(arg0 *cloudformation.RollbackStackInput) (*cloudformation.RollbackStackOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RollbackStack", arg0) + ret0, _ := ret[0].(*cloudformation.RollbackStackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RollbackStack indicates an expected call of RollbackStack. +func (mr *MockCloudFormationAPIMockRecorder) RollbackStack(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackStack", reflect.TypeOf((*MockCloudFormationAPI)(nil).RollbackStack), arg0) +} + +// RollbackStackRequest mocks base method. +func (m *MockCloudFormationAPI) RollbackStackRequest(arg0 *cloudformation.RollbackStackInput) (*request.Request, *cloudformation.RollbackStackOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RollbackStackRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.RollbackStackOutput) + return ret0, ret1 +} + +// RollbackStackRequest indicates an expected call of RollbackStackRequest. +func (mr *MockCloudFormationAPIMockRecorder) RollbackStackRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackStackRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).RollbackStackRequest), arg0) +} + +// RollbackStackWithContext mocks base method. +func (m *MockCloudFormationAPI) RollbackStackWithContext(arg0 aws.Context, arg1 *cloudformation.RollbackStackInput, arg2 ...request.Option) (*cloudformation.RollbackStackOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "RollbackStackWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.RollbackStackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RollbackStackWithContext indicates an expected call of RollbackStackWithContext. +func (mr *MockCloudFormationAPIMockRecorder) RollbackStackWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackStackWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).RollbackStackWithContext), varargs...) +} + +// SetStackPolicy mocks base method. +func (m *MockCloudFormationAPI) SetStackPolicy(arg0 *cloudformation.SetStackPolicyInput) (*cloudformation.SetStackPolicyOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetStackPolicy", arg0) + ret0, _ := ret[0].(*cloudformation.SetStackPolicyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetStackPolicy indicates an expected call of SetStackPolicy. +func (mr *MockCloudFormationAPIMockRecorder) SetStackPolicy(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStackPolicy", reflect.TypeOf((*MockCloudFormationAPI)(nil).SetStackPolicy), arg0) +} + +// SetStackPolicyRequest mocks base method. +func (m *MockCloudFormationAPI) SetStackPolicyRequest(arg0 *cloudformation.SetStackPolicyInput) (*request.Request, *cloudformation.SetStackPolicyOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetStackPolicyRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.SetStackPolicyOutput) + return ret0, ret1 +} + +// SetStackPolicyRequest indicates an expected call of SetStackPolicyRequest. +func (mr *MockCloudFormationAPIMockRecorder) SetStackPolicyRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStackPolicyRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).SetStackPolicyRequest), arg0) +} + +// SetStackPolicyWithContext mocks base method. +func (m *MockCloudFormationAPI) SetStackPolicyWithContext(arg0 aws.Context, arg1 *cloudformation.SetStackPolicyInput, arg2 ...request.Option) (*cloudformation.SetStackPolicyOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SetStackPolicyWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.SetStackPolicyOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetStackPolicyWithContext indicates an expected call of SetStackPolicyWithContext. +func (mr *MockCloudFormationAPIMockRecorder) SetStackPolicyWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStackPolicyWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).SetStackPolicyWithContext), varargs...) +} + +// SetTypeConfiguration mocks base method. +func (m *MockCloudFormationAPI) SetTypeConfiguration(arg0 *cloudformation.SetTypeConfigurationInput) (*cloudformation.SetTypeConfigurationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetTypeConfiguration", arg0) + ret0, _ := ret[0].(*cloudformation.SetTypeConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetTypeConfiguration indicates an expected call of SetTypeConfiguration. +func (mr *MockCloudFormationAPIMockRecorder) SetTypeConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTypeConfiguration", reflect.TypeOf((*MockCloudFormationAPI)(nil).SetTypeConfiguration), arg0) +} + +// SetTypeConfigurationRequest mocks base method. +func (m *MockCloudFormationAPI) SetTypeConfigurationRequest(arg0 *cloudformation.SetTypeConfigurationInput) (*request.Request, *cloudformation.SetTypeConfigurationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetTypeConfigurationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.SetTypeConfigurationOutput) + return ret0, ret1 +} + +// SetTypeConfigurationRequest indicates an expected call of SetTypeConfigurationRequest. +func (mr *MockCloudFormationAPIMockRecorder) SetTypeConfigurationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTypeConfigurationRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).SetTypeConfigurationRequest), arg0) +} + +// SetTypeConfigurationWithContext mocks base method. +func (m *MockCloudFormationAPI) SetTypeConfigurationWithContext(arg0 aws.Context, arg1 *cloudformation.SetTypeConfigurationInput, arg2 ...request.Option) (*cloudformation.SetTypeConfigurationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SetTypeConfigurationWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.SetTypeConfigurationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetTypeConfigurationWithContext indicates an expected call of SetTypeConfigurationWithContext. +func (mr *MockCloudFormationAPIMockRecorder) SetTypeConfigurationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTypeConfigurationWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).SetTypeConfigurationWithContext), varargs...) +} + +// SetTypeDefaultVersion mocks base method. +func (m *MockCloudFormationAPI) SetTypeDefaultVersion(arg0 *cloudformation.SetTypeDefaultVersionInput) (*cloudformation.SetTypeDefaultVersionOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetTypeDefaultVersion", arg0) + ret0, _ := ret[0].(*cloudformation.SetTypeDefaultVersionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetTypeDefaultVersion indicates an expected call of SetTypeDefaultVersion. +func (mr *MockCloudFormationAPIMockRecorder) SetTypeDefaultVersion(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTypeDefaultVersion", reflect.TypeOf((*MockCloudFormationAPI)(nil).SetTypeDefaultVersion), arg0) +} + +// SetTypeDefaultVersionRequest mocks base method. +func (m *MockCloudFormationAPI) SetTypeDefaultVersionRequest(arg0 *cloudformation.SetTypeDefaultVersionInput) (*request.Request, *cloudformation.SetTypeDefaultVersionOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetTypeDefaultVersionRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.SetTypeDefaultVersionOutput) + return ret0, ret1 +} + +// SetTypeDefaultVersionRequest indicates an expected call of SetTypeDefaultVersionRequest. +func (mr *MockCloudFormationAPIMockRecorder) SetTypeDefaultVersionRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTypeDefaultVersionRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).SetTypeDefaultVersionRequest), arg0) +} + +// SetTypeDefaultVersionWithContext mocks base method. +func (m *MockCloudFormationAPI) SetTypeDefaultVersionWithContext(arg0 aws.Context, arg1 *cloudformation.SetTypeDefaultVersionInput, arg2 ...request.Option) (*cloudformation.SetTypeDefaultVersionOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SetTypeDefaultVersionWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.SetTypeDefaultVersionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetTypeDefaultVersionWithContext indicates an expected call of SetTypeDefaultVersionWithContext. +func (mr *MockCloudFormationAPIMockRecorder) SetTypeDefaultVersionWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTypeDefaultVersionWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).SetTypeDefaultVersionWithContext), varargs...) +} + +// SignalResource mocks base method. +func (m *MockCloudFormationAPI) SignalResource(arg0 *cloudformation.SignalResourceInput) (*cloudformation.SignalResourceOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SignalResource", arg0) + ret0, _ := ret[0].(*cloudformation.SignalResourceOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SignalResource indicates an expected call of SignalResource. +func (mr *MockCloudFormationAPIMockRecorder) SignalResource(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignalResource", reflect.TypeOf((*MockCloudFormationAPI)(nil).SignalResource), arg0) +} + +// SignalResourceRequest mocks base method. +func (m *MockCloudFormationAPI) SignalResourceRequest(arg0 *cloudformation.SignalResourceInput) (*request.Request, *cloudformation.SignalResourceOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SignalResourceRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.SignalResourceOutput) + return ret0, ret1 +} + +// SignalResourceRequest indicates an expected call of SignalResourceRequest. +func (mr *MockCloudFormationAPIMockRecorder) SignalResourceRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignalResourceRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).SignalResourceRequest), arg0) +} + +// SignalResourceWithContext mocks base method. +func (m *MockCloudFormationAPI) SignalResourceWithContext(arg0 aws.Context, arg1 *cloudformation.SignalResourceInput, arg2 ...request.Option) (*cloudformation.SignalResourceOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SignalResourceWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.SignalResourceOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SignalResourceWithContext indicates an expected call of SignalResourceWithContext. +func (mr *MockCloudFormationAPIMockRecorder) SignalResourceWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignalResourceWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).SignalResourceWithContext), varargs...) +} + +// StartResourceScan mocks base method. +func (m *MockCloudFormationAPI) StartResourceScan(arg0 *cloudformation.StartResourceScanInput) (*cloudformation.StartResourceScanOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StartResourceScan", arg0) + ret0, _ := ret[0].(*cloudformation.StartResourceScanOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StartResourceScan indicates an expected call of StartResourceScan. +func (mr *MockCloudFormationAPIMockRecorder) StartResourceScan(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartResourceScan", reflect.TypeOf((*MockCloudFormationAPI)(nil).StartResourceScan), arg0) +} + +// StartResourceScanRequest mocks base method. +func (m *MockCloudFormationAPI) StartResourceScanRequest(arg0 *cloudformation.StartResourceScanInput) (*request.Request, *cloudformation.StartResourceScanOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StartResourceScanRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.StartResourceScanOutput) + return ret0, ret1 +} + +// StartResourceScanRequest indicates an expected call of StartResourceScanRequest. +func (mr *MockCloudFormationAPIMockRecorder) StartResourceScanRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartResourceScanRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).StartResourceScanRequest), arg0) +} + +// StartResourceScanWithContext mocks base method. +func (m *MockCloudFormationAPI) StartResourceScanWithContext(arg0 aws.Context, arg1 *cloudformation.StartResourceScanInput, arg2 ...request.Option) (*cloudformation.StartResourceScanOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "StartResourceScanWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.StartResourceScanOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StartResourceScanWithContext indicates an expected call of StartResourceScanWithContext. +func (mr *MockCloudFormationAPIMockRecorder) StartResourceScanWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartResourceScanWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).StartResourceScanWithContext), varargs...) +} + +// StopStackSetOperation mocks base method. +func (m *MockCloudFormationAPI) StopStackSetOperation(arg0 *cloudformation.StopStackSetOperationInput) (*cloudformation.StopStackSetOperationOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StopStackSetOperation", arg0) + ret0, _ := ret[0].(*cloudformation.StopStackSetOperationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StopStackSetOperation indicates an expected call of StopStackSetOperation. +func (mr *MockCloudFormationAPIMockRecorder) StopStackSetOperation(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopStackSetOperation", reflect.TypeOf((*MockCloudFormationAPI)(nil).StopStackSetOperation), arg0) +} + +// StopStackSetOperationRequest mocks base method. +func (m *MockCloudFormationAPI) StopStackSetOperationRequest(arg0 *cloudformation.StopStackSetOperationInput) (*request.Request, *cloudformation.StopStackSetOperationOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StopStackSetOperationRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.StopStackSetOperationOutput) + return ret0, ret1 +} + +// StopStackSetOperationRequest indicates an expected call of StopStackSetOperationRequest. +func (mr *MockCloudFormationAPIMockRecorder) StopStackSetOperationRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopStackSetOperationRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).StopStackSetOperationRequest), arg0) +} + +// StopStackSetOperationWithContext mocks base method. +func (m *MockCloudFormationAPI) StopStackSetOperationWithContext(arg0 aws.Context, arg1 *cloudformation.StopStackSetOperationInput, arg2 ...request.Option) (*cloudformation.StopStackSetOperationOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "StopStackSetOperationWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.StopStackSetOperationOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StopStackSetOperationWithContext indicates an expected call of StopStackSetOperationWithContext. +func (mr *MockCloudFormationAPIMockRecorder) StopStackSetOperationWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopStackSetOperationWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).StopStackSetOperationWithContext), varargs...) +} + +// TestType mocks base method. +func (m *MockCloudFormationAPI) TestType(arg0 *cloudformation.TestTypeInput) (*cloudformation.TestTypeOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TestType", arg0) + ret0, _ := ret[0].(*cloudformation.TestTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TestType indicates an expected call of TestType. +func (mr *MockCloudFormationAPIMockRecorder) TestType(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TestType", reflect.TypeOf((*MockCloudFormationAPI)(nil).TestType), arg0) +} + +// TestTypeRequest mocks base method. +func (m *MockCloudFormationAPI) TestTypeRequest(arg0 *cloudformation.TestTypeInput) (*request.Request, *cloudformation.TestTypeOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TestTypeRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.TestTypeOutput) + return ret0, ret1 +} + +// TestTypeRequest indicates an expected call of TestTypeRequest. +func (mr *MockCloudFormationAPIMockRecorder) TestTypeRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TestTypeRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).TestTypeRequest), arg0) +} + +// TestTypeWithContext mocks base method. +func (m *MockCloudFormationAPI) TestTypeWithContext(arg0 aws.Context, arg1 *cloudformation.TestTypeInput, arg2 ...request.Option) (*cloudformation.TestTypeOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "TestTypeWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.TestTypeOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TestTypeWithContext indicates an expected call of TestTypeWithContext. +func (mr *MockCloudFormationAPIMockRecorder) TestTypeWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TestTypeWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).TestTypeWithContext), varargs...) +} + +// UpdateGeneratedTemplate mocks base method. +func (m *MockCloudFormationAPI) UpdateGeneratedTemplate(arg0 *cloudformation.UpdateGeneratedTemplateInput) (*cloudformation.UpdateGeneratedTemplateOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateGeneratedTemplate", arg0) + ret0, _ := ret[0].(*cloudformation.UpdateGeneratedTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateGeneratedTemplate indicates an expected call of UpdateGeneratedTemplate. +func (mr *MockCloudFormationAPIMockRecorder) UpdateGeneratedTemplate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateGeneratedTemplate", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateGeneratedTemplate), arg0) +} + +// UpdateGeneratedTemplateRequest mocks base method. +func (m *MockCloudFormationAPI) UpdateGeneratedTemplateRequest(arg0 *cloudformation.UpdateGeneratedTemplateInput) (*request.Request, *cloudformation.UpdateGeneratedTemplateOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateGeneratedTemplateRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.UpdateGeneratedTemplateOutput) + return ret0, ret1 +} + +// UpdateGeneratedTemplateRequest indicates an expected call of UpdateGeneratedTemplateRequest. +func (mr *MockCloudFormationAPIMockRecorder) UpdateGeneratedTemplateRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateGeneratedTemplateRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateGeneratedTemplateRequest), arg0) +} + +// UpdateGeneratedTemplateWithContext mocks base method. +func (m *MockCloudFormationAPI) UpdateGeneratedTemplateWithContext(arg0 aws.Context, arg1 *cloudformation.UpdateGeneratedTemplateInput, arg2 ...request.Option) (*cloudformation.UpdateGeneratedTemplateOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UpdateGeneratedTemplateWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.UpdateGeneratedTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateGeneratedTemplateWithContext indicates an expected call of UpdateGeneratedTemplateWithContext. +func (mr *MockCloudFormationAPIMockRecorder) UpdateGeneratedTemplateWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateGeneratedTemplateWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateGeneratedTemplateWithContext), varargs...) +} + +// UpdateStack mocks base method. +func (m *MockCloudFormationAPI) UpdateStack(arg0 *cloudformation.UpdateStackInput) (*cloudformation.UpdateStackOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStack", arg0) + ret0, _ := ret[0].(*cloudformation.UpdateStackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateStack indicates an expected call of UpdateStack. +func (mr *MockCloudFormationAPIMockRecorder) UpdateStack(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStack", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateStack), arg0) +} + +// UpdateStackInstances mocks base method. +func (m *MockCloudFormationAPI) UpdateStackInstances(arg0 *cloudformation.UpdateStackInstancesInput) (*cloudformation.UpdateStackInstancesOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStackInstances", arg0) + ret0, _ := ret[0].(*cloudformation.UpdateStackInstancesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateStackInstances indicates an expected call of UpdateStackInstances. +func (mr *MockCloudFormationAPIMockRecorder) UpdateStackInstances(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStackInstances", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateStackInstances), arg0) +} + +// UpdateStackInstancesRequest mocks base method. +func (m *MockCloudFormationAPI) UpdateStackInstancesRequest(arg0 *cloudformation.UpdateStackInstancesInput) (*request.Request, *cloudformation.UpdateStackInstancesOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStackInstancesRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.UpdateStackInstancesOutput) + return ret0, ret1 +} + +// UpdateStackInstancesRequest indicates an expected call of UpdateStackInstancesRequest. +func (mr *MockCloudFormationAPIMockRecorder) UpdateStackInstancesRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStackInstancesRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateStackInstancesRequest), arg0) +} + +// UpdateStackInstancesWithContext mocks base method. +func (m *MockCloudFormationAPI) UpdateStackInstancesWithContext(arg0 aws.Context, arg1 *cloudformation.UpdateStackInstancesInput, arg2 ...request.Option) (*cloudformation.UpdateStackInstancesOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UpdateStackInstancesWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.UpdateStackInstancesOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateStackInstancesWithContext indicates an expected call of UpdateStackInstancesWithContext. +func (mr *MockCloudFormationAPIMockRecorder) UpdateStackInstancesWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStackInstancesWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateStackInstancesWithContext), varargs...) +} + +// UpdateStackRequest mocks base method. +func (m *MockCloudFormationAPI) UpdateStackRequest(arg0 *cloudformation.UpdateStackInput) (*request.Request, *cloudformation.UpdateStackOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStackRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.UpdateStackOutput) + return ret0, ret1 +} + +// UpdateStackRequest indicates an expected call of UpdateStackRequest. +func (mr *MockCloudFormationAPIMockRecorder) UpdateStackRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStackRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateStackRequest), arg0) +} + +// UpdateStackSet mocks base method. +func (m *MockCloudFormationAPI) UpdateStackSet(arg0 *cloudformation.UpdateStackSetInput) (*cloudformation.UpdateStackSetOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStackSet", arg0) + ret0, _ := ret[0].(*cloudformation.UpdateStackSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateStackSet indicates an expected call of UpdateStackSet. +func (mr *MockCloudFormationAPIMockRecorder) UpdateStackSet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStackSet", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateStackSet), arg0) +} + +// UpdateStackSetRequest mocks base method. +func (m *MockCloudFormationAPI) UpdateStackSetRequest(arg0 *cloudformation.UpdateStackSetInput) (*request.Request, *cloudformation.UpdateStackSetOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStackSetRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.UpdateStackSetOutput) + return ret0, ret1 +} + +// UpdateStackSetRequest indicates an expected call of UpdateStackSetRequest. +func (mr *MockCloudFormationAPIMockRecorder) UpdateStackSetRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStackSetRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateStackSetRequest), arg0) +} + +// UpdateStackSetWithContext mocks base method. +func (m *MockCloudFormationAPI) UpdateStackSetWithContext(arg0 aws.Context, arg1 *cloudformation.UpdateStackSetInput, arg2 ...request.Option) (*cloudformation.UpdateStackSetOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UpdateStackSetWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.UpdateStackSetOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateStackSetWithContext indicates an expected call of UpdateStackSetWithContext. +func (mr *MockCloudFormationAPIMockRecorder) UpdateStackSetWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStackSetWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateStackSetWithContext), varargs...) +} + +// UpdateStackWithContext mocks base method. +func (m *MockCloudFormationAPI) UpdateStackWithContext(arg0 aws.Context, arg1 *cloudformation.UpdateStackInput, arg2 ...request.Option) (*cloudformation.UpdateStackOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UpdateStackWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.UpdateStackOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateStackWithContext indicates an expected call of UpdateStackWithContext. +func (mr *MockCloudFormationAPIMockRecorder) UpdateStackWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStackWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateStackWithContext), varargs...) +} + +// UpdateTerminationProtection mocks base method. +func (m *MockCloudFormationAPI) UpdateTerminationProtection(arg0 *cloudformation.UpdateTerminationProtectionInput) (*cloudformation.UpdateTerminationProtectionOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateTerminationProtection", arg0) + ret0, _ := ret[0].(*cloudformation.UpdateTerminationProtectionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateTerminationProtection indicates an expected call of UpdateTerminationProtection. +func (mr *MockCloudFormationAPIMockRecorder) UpdateTerminationProtection(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTerminationProtection", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateTerminationProtection), arg0) +} + +// UpdateTerminationProtectionRequest mocks base method. +func (m *MockCloudFormationAPI) UpdateTerminationProtectionRequest(arg0 *cloudformation.UpdateTerminationProtectionInput) (*request.Request, *cloudformation.UpdateTerminationProtectionOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateTerminationProtectionRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.UpdateTerminationProtectionOutput) + return ret0, ret1 +} + +// UpdateTerminationProtectionRequest indicates an expected call of UpdateTerminationProtectionRequest. +func (mr *MockCloudFormationAPIMockRecorder) UpdateTerminationProtectionRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTerminationProtectionRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateTerminationProtectionRequest), arg0) +} + +// UpdateTerminationProtectionWithContext mocks base method. +func (m *MockCloudFormationAPI) UpdateTerminationProtectionWithContext(arg0 aws.Context, arg1 *cloudformation.UpdateTerminationProtectionInput, arg2 ...request.Option) (*cloudformation.UpdateTerminationProtectionOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UpdateTerminationProtectionWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.UpdateTerminationProtectionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateTerminationProtectionWithContext indicates an expected call of UpdateTerminationProtectionWithContext. +func (mr *MockCloudFormationAPIMockRecorder) UpdateTerminationProtectionWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTerminationProtectionWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).UpdateTerminationProtectionWithContext), varargs...) +} + +// ValidateTemplate mocks base method. +func (m *MockCloudFormationAPI) ValidateTemplate(arg0 *cloudformation.ValidateTemplateInput) (*cloudformation.ValidateTemplateOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ValidateTemplate", arg0) + ret0, _ := ret[0].(*cloudformation.ValidateTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ValidateTemplate indicates an expected call of ValidateTemplate. +func (mr *MockCloudFormationAPIMockRecorder) ValidateTemplate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateTemplate", reflect.TypeOf((*MockCloudFormationAPI)(nil).ValidateTemplate), arg0) +} + +// ValidateTemplateRequest mocks base method. +func (m *MockCloudFormationAPI) ValidateTemplateRequest(arg0 *cloudformation.ValidateTemplateInput) (*request.Request, *cloudformation.ValidateTemplateOutput) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ValidateTemplateRequest", arg0) + ret0, _ := ret[0].(*request.Request) + ret1, _ := ret[1].(*cloudformation.ValidateTemplateOutput) + return ret0, ret1 +} + +// ValidateTemplateRequest indicates an expected call of ValidateTemplateRequest. +func (mr *MockCloudFormationAPIMockRecorder) ValidateTemplateRequest(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateTemplateRequest", reflect.TypeOf((*MockCloudFormationAPI)(nil).ValidateTemplateRequest), arg0) +} + +// ValidateTemplateWithContext mocks base method. +func (m *MockCloudFormationAPI) ValidateTemplateWithContext(arg0 aws.Context, arg1 *cloudformation.ValidateTemplateInput, arg2 ...request.Option) (*cloudformation.ValidateTemplateOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ValidateTemplateWithContext", varargs...) + ret0, _ := ret[0].(*cloudformation.ValidateTemplateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ValidateTemplateWithContext indicates an expected call of ValidateTemplateWithContext. +func (mr *MockCloudFormationAPIMockRecorder) ValidateTemplateWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateTemplateWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).ValidateTemplateWithContext), varargs...) +} + +// WaitUntilChangeSetCreateComplete mocks base method. +func (m *MockCloudFormationAPI) WaitUntilChangeSetCreateComplete(arg0 *cloudformation.DescribeChangeSetInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilChangeSetCreateComplete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilChangeSetCreateComplete indicates an expected call of WaitUntilChangeSetCreateComplete. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilChangeSetCreateComplete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilChangeSetCreateComplete", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilChangeSetCreateComplete), arg0) +} + +// WaitUntilChangeSetCreateCompleteWithContext mocks base method. +func (m *MockCloudFormationAPI) WaitUntilChangeSetCreateCompleteWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeChangeSetInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilChangeSetCreateCompleteWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilChangeSetCreateCompleteWithContext indicates an expected call of WaitUntilChangeSetCreateCompleteWithContext. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilChangeSetCreateCompleteWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilChangeSetCreateCompleteWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilChangeSetCreateCompleteWithContext), varargs...) +} + +// WaitUntilStackCreateComplete mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackCreateComplete(arg0 *cloudformation.DescribeStacksInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilStackCreateComplete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackCreateComplete indicates an expected call of WaitUntilStackCreateComplete. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackCreateComplete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackCreateComplete", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackCreateComplete), arg0) +} + +// WaitUntilStackCreateCompleteWithContext mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackCreateCompleteWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStacksInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilStackCreateCompleteWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackCreateCompleteWithContext indicates an expected call of WaitUntilStackCreateCompleteWithContext. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackCreateCompleteWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackCreateCompleteWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackCreateCompleteWithContext), varargs...) +} + +// WaitUntilStackDeleteComplete mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackDeleteComplete(arg0 *cloudformation.DescribeStacksInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilStackDeleteComplete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackDeleteComplete indicates an expected call of WaitUntilStackDeleteComplete. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackDeleteComplete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackDeleteComplete", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackDeleteComplete), arg0) +} + +// WaitUntilStackDeleteCompleteWithContext mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackDeleteCompleteWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStacksInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilStackDeleteCompleteWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackDeleteCompleteWithContext indicates an expected call of WaitUntilStackDeleteCompleteWithContext. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackDeleteCompleteWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackDeleteCompleteWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackDeleteCompleteWithContext), varargs...) +} + +// WaitUntilStackExists mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackExists(arg0 *cloudformation.DescribeStacksInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilStackExists", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackExists indicates an expected call of WaitUntilStackExists. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackExists(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackExists", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackExists), arg0) +} + +// WaitUntilStackExistsWithContext mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackExistsWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStacksInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilStackExistsWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackExistsWithContext indicates an expected call of WaitUntilStackExistsWithContext. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackExistsWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackExistsWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackExistsWithContext), varargs...) +} + +// WaitUntilStackImportComplete mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackImportComplete(arg0 *cloudformation.DescribeStacksInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilStackImportComplete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackImportComplete indicates an expected call of WaitUntilStackImportComplete. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackImportComplete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackImportComplete", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackImportComplete), arg0) +} + +// WaitUntilStackImportCompleteWithContext mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackImportCompleteWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStacksInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilStackImportCompleteWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackImportCompleteWithContext indicates an expected call of WaitUntilStackImportCompleteWithContext. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackImportCompleteWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackImportCompleteWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackImportCompleteWithContext), varargs...) +} + +// WaitUntilStackRollbackComplete mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackRollbackComplete(arg0 *cloudformation.DescribeStacksInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilStackRollbackComplete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackRollbackComplete indicates an expected call of WaitUntilStackRollbackComplete. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackRollbackComplete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackRollbackComplete", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackRollbackComplete), arg0) +} + +// WaitUntilStackRollbackCompleteWithContext mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackRollbackCompleteWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStacksInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilStackRollbackCompleteWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackRollbackCompleteWithContext indicates an expected call of WaitUntilStackRollbackCompleteWithContext. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackRollbackCompleteWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackRollbackCompleteWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackRollbackCompleteWithContext), varargs...) +} + +// WaitUntilStackUpdateComplete mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackUpdateComplete(arg0 *cloudformation.DescribeStacksInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilStackUpdateComplete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackUpdateComplete indicates an expected call of WaitUntilStackUpdateComplete. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackUpdateComplete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackUpdateComplete", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackUpdateComplete), arg0) +} + +// WaitUntilStackUpdateCompleteWithContext mocks base method. +func (m *MockCloudFormationAPI) WaitUntilStackUpdateCompleteWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeStacksInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilStackUpdateCompleteWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilStackUpdateCompleteWithContext indicates an expected call of WaitUntilStackUpdateCompleteWithContext. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilStackUpdateCompleteWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilStackUpdateCompleteWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilStackUpdateCompleteWithContext), varargs...) +} + +// WaitUntilTypeRegistrationComplete mocks base method. +func (m *MockCloudFormationAPI) WaitUntilTypeRegistrationComplete(arg0 *cloudformation.DescribeTypeRegistrationInput) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WaitUntilTypeRegistrationComplete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilTypeRegistrationComplete indicates an expected call of WaitUntilTypeRegistrationComplete. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilTypeRegistrationComplete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilTypeRegistrationComplete", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilTypeRegistrationComplete), arg0) +} + +// WaitUntilTypeRegistrationCompleteWithContext mocks base method. +func (m *MockCloudFormationAPI) WaitUntilTypeRegistrationCompleteWithContext(arg0 aws.Context, arg1 *cloudformation.DescribeTypeRegistrationInput, arg2 ...request.WaiterOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "WaitUntilTypeRegistrationCompleteWithContext", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// WaitUntilTypeRegistrationCompleteWithContext indicates an expected call of WaitUntilTypeRegistrationCompleteWithContext. +func (mr *MockCloudFormationAPIMockRecorder) WaitUntilTypeRegistrationCompleteWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitUntilTypeRegistrationCompleteWithContext", reflect.TypeOf((*MockCloudFormationAPI)(nil).WaitUntilTypeRegistrationCompleteWithContext), varargs...) +} From 40c1c8bf34de39f9dbdd8f00427c8e0771e80f59 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Tue, 7 Jan 2025 01:58:11 +0100 Subject: [PATCH 37/40] Update modules --- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 443f5cb..3550bd9 100644 --- a/go.mod +++ b/go.mod @@ -59,10 +59,10 @@ require ( github.com/ulikunitz/xz v0.5.11 // indirect github.com/zclconf/go-cty v1.14.4 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.153.0 // indirect @@ -112,9 +112,9 @@ require ( github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/urfave/cli v1.22.2 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/term v0.20.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/term v0.28.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/api v0.28.4 // indirect diff --git a/go.sum b/go.sum index 508316f..7845516 100644 --- a/go.sum +++ b/go.sum @@ -586,8 +586,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -672,8 +672,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -715,8 +715,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -787,13 +787,13 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -805,8 +805,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 3dab64b5b95ebf94f9b473b46344b905efa51f88 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Tue, 7 Jan 2025 02:03:47 +0100 Subject: [PATCH 38/40] Address comments --- pkg/atmos/aws-component-helper/acceptance_test.go | 2 +- pkg/atmos/aws-component-helper/fixture.go | 4 ++-- pkg/atmos/aws-component-helper/fixture_test.go | 4 ++-- pkg/atmos/aws-component-helper/state.go | 2 ++ pkg/atmos/aws-component-helper/state_test.go | 12 ++++++++++-- pkg/atmos/aws-component-helper/suite.go | 10 +++++----- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/pkg/atmos/aws-component-helper/acceptance_test.go b/pkg/atmos/aws-component-helper/acceptance_test.go index cbe4e0b..316c486 100644 --- a/pkg/atmos/aws-component-helper/acceptance_test.go +++ b/pkg/atmos/aws-component-helper/acceptance_test.go @@ -14,7 +14,7 @@ import ( // TestAcceptance is an end-to-end acceptance test for AWS component helper functionality. func TestAcceptance(t *testing.T) { // Mock AWS account ID retrieval callback - getAwsAaccountIdCallback = func() (string, error) { + getAwsAccountIdCallback = func() (string, error) { return "123456789012", nil } diff --git a/pkg/atmos/aws-component-helper/fixture.go b/pkg/atmos/aws-component-helper/fixture.go index eae0097..9829a58 100644 --- a/pkg/atmos/aws-component-helper/fixture.go +++ b/pkg/atmos/aws-component-helper/fixture.go @@ -16,7 +16,7 @@ import ( // Define global callback function to retrieve AWS account ID var ( - getAwsAaccountIdCallback = getAwsAccountId + getAwsAccountIdCallback = getAwsAccountId ) // Define global flags for configuring test behavior @@ -45,7 +45,7 @@ type Fixture struct { // NewFixture initializes a new Fixture instance func NewFixture(t *testing.T, sourceDir string, awsRegion string, fixturesDir string) *Fixture { - awsAccountId, err := getAwsAaccountIdCallback() + awsAccountId, err := getAwsAccountIdCallback() require.NoError(t, err) // Ensure AWS account ID retrieval succeeded randID := random.UniqueId() diff --git a/pkg/atmos/aws-component-helper/fixture_test.go b/pkg/atmos/aws-component-helper/fixture_test.go index 551cc12..b44e098 100644 --- a/pkg/atmos/aws-component-helper/fixture_test.go +++ b/pkg/atmos/aws-component-helper/fixture_test.go @@ -76,7 +76,7 @@ func TestFixtureMinimum(t *testing.T) { // TestFixtureCreate validates the setup of a Fixture with a temporary folder func TestFixtureCreate(t *testing.T) { // Mock AWS Account ID retrieval - getAwsAaccountIdCallback = func() (string, error) { + getAwsAccountIdCallback = func() (string, error) { return "123456789012", nil } @@ -99,7 +99,7 @@ func TestFixtureCreate(t *testing.T) { // TestFixtureSuitesRun validates the execution of test suites within a Fixture func TestFixtureSuitesRun(t *testing.T) { // Mock AWS Account ID retrieval - getAwsAaccountIdCallback = func() (string, error) { + getAwsAccountIdCallback = func() (string, error) { return "123456789012", nil } diff --git a/pkg/atmos/aws-component-helper/state.go b/pkg/atmos/aws-component-helper/state.go index 6f0fb23..b09b2d2 100644 --- a/pkg/atmos/aws-component-helper/state.go +++ b/pkg/atmos/aws-component-helper/state.go @@ -41,6 +41,8 @@ func (s *State) Fork(name string) (*State, error) { // Copy the current state directory to the new state directory if err := copyDirectoryRecursively(s.CurrentDir(), result.CurrentDir()); err != nil { + // Clean up the partially created state + _ = os.RemoveAll(result.CurrentDir()) return nil, err } diff --git a/pkg/atmos/aws-component-helper/state_test.go b/pkg/atmos/aws-component-helper/state_test.go index 635ea05..f59ae07 100644 --- a/pkg/atmos/aws-component-helper/state_test.go +++ b/pkg/atmos/aws-component-helper/state_test.go @@ -20,7 +20,11 @@ func TestState(t *testing.T) { // Copy a folder to a temporary test folder testFolder, err := files.CopyFolderToTemp("../../../", strings.Replace(t.Name(), "/", "-", -1), func(path string) bool { return true }) require.NoError(t, err) - defer os.RemoveAll(testFolder) // Ensure test folder is removed after the test + defer func() { // Ensure test folder is removed after the test + if err := os.RemoveAll(testFolder); err != nil { + t.Errorf("failed to cleanup test folder: %v", err) + } + }() // Create a new State instance state := NewState("default", testFolder) @@ -50,7 +54,11 @@ func TestState(t *testing.T) { // Copy a folder to a temporary test folder testFolder, err := files.CopyFolderToTemp("../../../", strings.Replace(t.Name(), "/", "-", -1), func(path string) bool { return true }) require.NoError(t, err) - defer os.RemoveAll(testFolder) // Ensure test folder is removed after the test + defer func() { // Ensure test folder is removed after the test + if err := os.RemoveAll(testFolder); err != nil { + t.Errorf("failed to cleanup test folder: %v", err) + } + }() // Create a new State instance state := NewState("default", testFolder) diff --git a/pkg/atmos/aws-component-helper/suite.go b/pkg/atmos/aws-component-helper/suite.go index 9587f16..62e5b32 100644 --- a/pkg/atmos/aws-component-helper/suite.go +++ b/pkg/atmos/aws-component-helper/suite.go @@ -20,7 +20,7 @@ var ( ) // Structure to define a teardown step -type teadDown struct { +type tearDown struct { component *AtmosComponent // The component to be torn down callback *func(t *testing.T, atm *Atmos) // Optional teardown callback } @@ -31,7 +31,7 @@ type Suite struct { randomIdentifier string // Unique identifier for the suite name string // Suite name dependencies []*AtmosComponent // Dependencies for the suite - teardown []*teadDown // Teardown steps + teardown []*tearDown // Teardown steps options *atmos.Options // Atmos options for the suite state *State // State associated with the suite } @@ -55,7 +55,7 @@ func NewSuite(t *testing.T, name string, fixture *Fixture) *Suite { randomIdentifier: randomId, dependencies: []*AtmosComponent{}, state: suiteState, - teardown: []*teadDown{}, + teardown: []*tearDown{}, options: fixture.getAtmosOptions(&atmos.Options{}, map[string]interface{}{}), } } @@ -64,7 +64,7 @@ func NewSuite(t *testing.T, name string, fixture *Fixture) *Suite { func (ts *Suite) AddDependency(componentName string, stackName string) { component := NewAtmosComponent(componentName, stackName, nil) ts.dependencies = append(ts.dependencies, component) - ts.teardown = append(ts.teardown, &teadDown{component: component, callback: nil}) + ts.teardown = append(ts.teardown, &tearDown{component: component, callback: nil}) if *skipSetup { fmt.Printf("Skip suite %s setup dependency component: %s stack: %s\n", ts.name, componentName, stackName) @@ -127,7 +127,7 @@ func (ts *Suite) Setup(t *testing.T, f func(t *testing.T, atm *Atmos)) { // TearDown adds a custom teardown callback to the suite func (ts *Suite) TearDown(t *testing.T, f func(t *testing.T, atm *Atmos)) { - ts.teardown = append(ts.teardown, &teadDown{component: nil, callback: &f}) + ts.teardown = append(ts.teardown, &tearDown{component: nil, callback: &f}) } // Test runs a test within the suite From 88f7ea358da5eec408107fe3e07ff6e8600c886d Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Tue, 7 Jan 2025 04:04:51 +0300 Subject: [PATCH 39/40] Update pkg/atmos/aws-component-helper/state_test.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- pkg/atmos/aws-component-helper/state_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/atmos/aws-component-helper/state_test.go b/pkg/atmos/aws-component-helper/state_test.go index f59ae07..885e294 100644 --- a/pkg/atmos/aws-component-helper/state_test.go +++ b/pkg/atmos/aws-component-helper/state_test.go @@ -77,6 +77,8 @@ func TestState(t *testing.T) { // Create a temporary file in the current state directory file, err := os.CreateTemp(state.CurrentDir(), "tmpfile") + require.NoError(t, err) + defer file.Close() assert.FileExists(t, file.Name()) fileName := filepath.Base(file.Name()) // Store the file name for verification later From 8593eb06ef6033d0c312b82b320be8da0ffd1f50 Mon Sep 17 00:00:00 2001 From: Igor Rodionov Date: Thu, 9 Jan 2025 04:10:49 +0100 Subject: [PATCH 40/40] Added -dev mode --- pkg/atmos/aws-component-helper/atmos.go | 46 +++++++++++-------- .../aws-component-helper/atmos_component.go | 8 ++++ pkg/atmos/aws-component-helper/fixture.go | 38 ++++++++------- pkg/atmos/aws-component-helper/state.go | 7 +++ pkg/atmos/aws-component-helper/suite.go | 5 +- 5 files changed, 64 insertions(+), 40 deletions(-) diff --git a/pkg/atmos/aws-component-helper/atmos.go b/pkg/atmos/aws-component-helper/atmos.go index 554dfc4..4644b54 100644 --- a/pkg/atmos/aws-component-helper/atmos.go +++ b/pkg/atmos/aws-component-helper/atmos.go @@ -15,7 +15,6 @@ import ( "dario.cat/mergo" "github.com/cloudposse/test-helpers/pkg/atmos" "github.com/gruntwork-io/terratest/modules/random" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -32,6 +31,7 @@ var ( var ( skipDeploy = flag.Bool("skip-deploy", false, "skip all deployments") skipDestroy = flag.Bool("skip-destroy", false, "skip all destroy") + devMode = flag.Bool("dev", false, "Development mode") ) // Atmos struct encapsulates testing information and options @@ -67,9 +67,11 @@ func (ts *Atmos) GetAndDestroy(componentName string, stackName string, vars map[ // Deploy a component using Atmos func (ts *Atmos) Deploy(component *AtmosComponent) { options := ts.getAtmosOptions(component) - defer os.RemoveAll(options.AtmosBasePath) // Clean up temporary directories - err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) - require.NoError(ts.t, err) + if ts.options.AtmosBasePath != options.AtmosBasePath { + defer os.RemoveAll(options.AtmosBasePath) // Clean up temporary directories + err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) + require.NoError(ts.t, err) + } if !*skipDeploy { atmosApply(ts.t, options) // Apply the deployment err := atmosOutputAllE(ts.t, options, "", &component.output) @@ -82,9 +84,11 @@ func (ts *Atmos) Deploy(component *AtmosComponent) { // Destroy a component using Atmos func (ts *Atmos) Destroy(component *AtmosComponent) { options := ts.getAtmosOptions(component) - defer os.RemoveAll(options.AtmosBasePath) // Clean up temporary directories - err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) - assert.NoError(ts.t, err) + if ts.options.AtmosBasePath != options.AtmosBasePath { + defer os.RemoveAll(options.AtmosBasePath) // Clean up temporary directories + err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) + require.NoError(ts.t, err) + } if !*skipDestroy { atmosDestroy(ts.t, options) // Destroy the deployment } else { @@ -98,11 +102,12 @@ func (ts *Atmos) loadOutputAll(component *AtmosComponent) { return } options := ts.getAtmosOptions(component) - defer os.RemoveAll(options.AtmosBasePath) - err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) - require.NoError(ts.t, err) - - err = atmosOutputAllE(ts.t, options, "", &component.output) + if ts.options.AtmosBasePath != options.AtmosBasePath { + defer os.RemoveAll(options.AtmosBasePath) // Clean up temporary directories + err := copyDirectoryRecursively(ts.options.AtmosBasePath, options.AtmosBasePath) + require.NoError(ts.t, err) + } + err := atmosOutputAllE(ts.t, options, "", &component.output) if err != nil && strings.Contains(err.Error(), "Backend initialization required") { // Run 'terraform workspace' instead of 'terraform init' as it also select the workspace // So terraform output will not fail with "Switch to workspace" json parse error @@ -183,20 +188,23 @@ func (ts *Atmos) getAtmosOptions(component *AtmosComponent) *atmos.Options { result.Component = component.ComponentName result.Stack = component.StackName - randID := random.UniqueId() - randomId := strings.ToLower(randID) + if !*devMode { + randID := random.UniqueId() + randomId := strings.ToLower(randID) - basePath := filepath.Dir(filepath.Clean(ts.options.AtmosBasePath)) - dirName := filepath.Base(ts.options.AtmosBasePath) - tmpDir := filepath.Join(basePath, fmt.Sprintf(".%s-%s", dirName, randomId)) + basePath := filepath.Dir(filepath.Clean(ts.options.AtmosBasePath)) + dirName := filepath.Base(ts.options.AtmosBasePath) + tmpDir := filepath.Join(basePath, fmt.Sprintf(".%s-%s", dirName, randomId)) + result.AtmosBasePath = tmpDir + } - result.AtmosBasePath = tmpDir resultEnvVars := result.EnvVars envvars := map[string]string{ "ATMOS_BASE_PATH": result.AtmosBasePath, "ATMOS_CLI_CONFIG_PATH": result.AtmosBasePath, "TEST_SUITE_NAME": ts.state.NamespaceDir(), "TEST_STATE_DIR": ts.state.BaseDir(), + "TF_DATA_DIR": fmt.Sprintf(".terraform/%s-%s", ts.state.GetIdentifier(), component.GetRandomIdentifier()), } err = mergo.Merge(&envvars, resultEnvVars) @@ -205,7 +213,7 @@ func (ts *Atmos) getAtmosOptions(component *AtmosComponent) *atmos.Options { result.EnvVars = envvars if _, ok := result.Vars["attributes"]; !ok { - result.Vars["attributes"] = []string{component.randomIdentifier} + result.Vars["attributes"] = []string{ts.state.GetIdentifier(), component.GetRandomIdentifier()} } if component.Vars != nil { diff --git a/pkg/atmos/aws-component-helper/atmos_component.go b/pkg/atmos/aws-component-helper/atmos_component.go index 90a0e55..58795d3 100644 --- a/pkg/atmos/aws-component-helper/atmos_component.go +++ b/pkg/atmos/aws-component-helper/atmos_component.go @@ -1,6 +1,9 @@ package aws_component_helper import ( + "crypto/md5" + "encoding/hex" + "fmt" "strings" "github.com/gruntwork-io/terratest/modules/random" @@ -37,5 +40,10 @@ func NewAtmosComponent(component string, stack string, vars map[string]interface // GetRandomIdentifier retrieves the unique identifier of the component func (ts *AtmosComponent) GetRandomIdentifier() string { + if *devMode { + name := fmt.Sprintf("%s-%s", ts.ComponentName, ts.StackName) + hash := md5.Sum([]byte(name)) + return hex.EncodeToString(hash[:])[:6] + } return ts.randomIdentifier } diff --git a/pkg/atmos/aws-component-helper/fixture.go b/pkg/atmos/aws-component-helper/fixture.go index 9829a58..f709a45 100644 --- a/pkg/atmos/aws-component-helper/fixture.go +++ b/pkg/atmos/aws-component-helper/fixture.go @@ -31,16 +31,15 @@ var ( // Fixture struct holds test-specific configurations and state type Fixture struct { - t *testing.T // Testing object - RandomIdentifier string // Unique identifier for the fixture - AwsAccountId string // AWS Account ID - AwsRegion string // AWS Region - SourceDir string // Source directory for the fixture - TempDir string // Temporary directory for the fixture - FixturesPath string // Path to the fixture directory - State *State // State management object - suites []*Suite // List of test suites - suitesNames []string // Names of test suites + t *testing.T // Testing object + AwsAccountId string // AWS Account ID + AwsRegion string // AWS Region + SourceDir string // Source directory for the fixture + TempDir string // Temporary directory for the fixture + FixturesPath string // Path to the fixture directory + State *State // State management object + suites []*Suite // List of test suites + suitesNames []string // Names of test suites } // NewFixture initializes a new Fixture instance @@ -63,16 +62,15 @@ func NewFixture(t *testing.T, sourceDir string, awsRegion string, fixturesDir st // Return initialized Fixture instance return &Fixture{ - t: t, - RandomIdentifier: randomId, - SourceDir: realSourcePath, - TempDir: tmpdir, - FixturesPath: fixturesDir, - AwsAccountId: awsAccountId, - AwsRegion: awsRegion, - suites: []*Suite{}, - suitesNames: []string{}, - State: state, + t: t, + SourceDir: realSourcePath, + TempDir: tmpdir, + FixturesPath: fixturesDir, + AwsAccountId: awsAccountId, + AwsRegion: awsRegion, + suites: []*Suite{}, + suitesNames: []string{}, + State: state, } } diff --git a/pkg/atmos/aws-component-helper/state.go b/pkg/atmos/aws-component-helper/state.go index b09b2d2..8882865 100644 --- a/pkg/atmos/aws-component-helper/state.go +++ b/pkg/atmos/aws-component-helper/state.go @@ -1,6 +1,8 @@ package aws_component_helper import ( + "crypto/md5" + "encoding/hex" "flag" "fmt" "os" @@ -19,6 +21,11 @@ type State struct { namespace string // Namespace identifier for the state } +func (s *State) GetIdentifier() string { + hash := md5.Sum([]byte(s.namespace)) + return hex.EncodeToString(hash[:])[:6] +} + // NewState initializes a new State instance with the given namespace and root directory func NewState(name, rootDir string) *State { basePath := rootDir diff --git a/pkg/atmos/aws-component-helper/suite.go b/pkg/atmos/aws-component-helper/suite.go index 62e5b32..e76a633 100644 --- a/pkg/atmos/aws-component-helper/suite.go +++ b/pkg/atmos/aws-component-helper/suite.go @@ -78,7 +78,7 @@ func (ts *Suite) AddDependency(componentName string, stackName string) { // getAtmos returns an Atmos instance configured for the suite's state func (ts *Suite) getAtmos(state *State) *Atmos { return NewAtmos(ts.t, state, ts.getAtmosOptions(map[string]interface{}{ - "attributes": []string{ts.randomIdentifier}, + "attributes": []string{ts.GetRandomIdentifier()}, })) } @@ -170,5 +170,8 @@ func (ts *Suite) getAtmosOptions(vars map[string]interface{}) *atmos.Options { // GetRandomIdentifier returns the suite's unique random identifier func (ts *Suite) GetRandomIdentifier() string { + if *devMode { + return ts.state.GetIdentifier() + } return ts.randomIdentifier }