|
66 | 66 | :name (or name (test/rand-stack-name)) |
67 | 67 | :template template})}})) |
68 | 68 |
|
| 69 | +(defn template-system [& {:as opts}] |
| 70 | + (assoc |
| 71 | + test/system-base |
| 72 | + ::ds/defs |
| 73 | + {:t |
| 74 | + {:template |
| 75 | + (cfn/template opts)}})) |
| 76 | + |
69 | 77 | (deftest test-blank-template-early-validation |
70 | 78 | (testing "Blank templates should fail validation" |
| 79 | + (testing "using template component" |
| 80 | + (is (thrown-with-msg? |
| 81 | + ExceptionInfo |
| 82 | + #"Template must be a map" |
| 83 | + (-> (template-system :lint? true :template nil) |
| 84 | + (ds/signal :salmon/early-validate) |
| 85 | + cause))) |
| 86 | + (is (thrown-with-msg? |
| 87 | + ExceptionInfo |
| 88 | + #"Template must not be empty" |
| 89 | + (-> (template-system :lint? true :template {}) |
| 90 | + (ds/signal :salmon/early-validate) |
| 91 | + cause)))) |
71 | 92 | (is (thrown-with-msg? |
72 | 93 | ExceptionInfo |
73 | 94 | #"Template must be a map" |
|
110 | 131 |
|
111 | 132 | (deftest test-early-validation-linting |
112 | 133 | (testing "cfn-lint works in :early-validate when there are no refs in the template" |
| 134 | + (is (thrown-with-msg? |
| 135 | + ExceptionInfo |
| 136 | + #"'Resources' is a required property" |
| 137 | + (-> (template-system :lint? true :template {:a 1}) |
| 138 | + (ds/signal :salmon/early-validate) |
| 139 | + cause))) |
113 | 140 | (is (thrown-with-msg? |
114 | 141 | ExceptionInfo |
115 | 142 | #"'Resources' is a required property" |
116 | 143 | (cause (ds/signal (system-a (stack-a :lint? true :template {:a 1})) |
117 | 144 | :salmon/early-validate))))) |
118 | 145 | (testing "cfn-lint doesn't run unless :lint? is true" |
| 146 | + (is (ds/signal (template-system :template {:a 1}) |
| 147 | + :salmon/early-validate)) |
119 | 148 | (is (ds/signal (system-a (stack-a :template {:a 1})) |
120 | 149 | :salmon/early-validate))) |
121 | 150 | (testing "cfn-lint works in :early-validate when all refs have been resolved" |
|
170 | 199 |
|
171 | 200 | (deftest test-validation-linting |
172 | 201 | (testing "ref templates are validated during :start" |
| 202 | + (testing "in template components" |
| 203 | + (is (thrown-with-msg? |
| 204 | + ExceptionInfo |
| 205 | + #"Template must not be empty" |
| 206 | + (-> (template-system :lint? true :template (ds/local-ref [:empty])) |
| 207 | + (assoc-in [::ds/defs :t :empty] {}) |
| 208 | + ds/start |
| 209 | + cause))) |
| 210 | + (testing "regions are considered during linting" |
| 211 | + (is (thrown-with-msg? |
| 212 | + ExceptionInfo |
| 213 | + #"Template must not be empty" |
| 214 | + (-> (template-system |
| 215 | + :lint? true |
| 216 | + :regions [:us-east-1] |
| 217 | + :template (ds/local-ref [:empty])) |
| 218 | + (assoc-in [::ds/defs :t :empty] {}) |
| 219 | + ds/start |
| 220 | + cause)) |
| 221 | + "one region") |
| 222 | + (is (thrown-with-msg? |
| 223 | + ExceptionInfo |
| 224 | + #"Template must not be empty" |
| 225 | + (-> (template-system |
| 226 | + :lint? true |
| 227 | + :regions [:us-east-1 :us-east-2 :us-west-2] |
| 228 | + :template (ds/local-ref [:empty])) |
| 229 | + (assoc-in [::ds/defs :t :empty] {}) |
| 230 | + ds/start |
| 231 | + cause)) |
| 232 | + "several regions") |
| 233 | + (let [sm-template |
| 234 | + #__ {:AWSTemplateFormatVersion "2010-09-09" |
| 235 | + :Resources |
| 236 | + {:Instance |
| 237 | + {:Type "AWS::SageMaker::NotebookInstance" |
| 238 | + :Properties |
| 239 | + {:InstanceType "ml.t2.medium" |
| 240 | + :RoleArn {"Fn::Sub" "arn:aws:iam::${AWS::AccountId}:role/SageMakerExecutionRole"}}}}}] |
| 241 | + (is (-> (template-system |
| 242 | + :lint? true |
| 243 | + :regions [:us-east-1] |
| 244 | + :template sm-template) |
| 245 | + ds/start)) |
| 246 | + (testing "Linting fails for a valid resource that is not supported in a region" |
| 247 | + (is (thrown-with-msg? |
| 248 | + ExceptionInfo |
| 249 | + #"Resource type.*AWS::SageMaker::NotebookInstance.*does not exist in" |
| 250 | + (-> (template-system |
| 251 | + :lint? true |
| 252 | + :regions [:ca-west-1] |
| 253 | + :template sm-template) |
| 254 | + ds/start |
| 255 | + cause)) |
| 256 | + "with one region") |
| 257 | + (is (thrown-with-msg? |
| 258 | + ExceptionInfo |
| 259 | + #"Resource type.*AWS::SageMaker::NotebookInstance.*does not exist in" |
| 260 | + (-> (template-system |
| 261 | + :lint? true |
| 262 | + :regions [:us-east-1 :ca-west-1 :us-east-2] |
| 263 | + :template sm-template) |
| 264 | + ds/start |
| 265 | + cause)) |
| 266 | + "with several regions, most of which are supported"))))) |
173 | 267 | (is (thrown-with-msg? |
174 | 268 | ExceptionInfo |
175 | 269 | #"Template must not be empty" |
|
203 | 297 | (def template-b |
204 | 298 | (assoc-in template-a [:Resources :OAI2] (oai "OAI2"))) |
205 | 299 |
|
| 300 | +(deftest test-stack-from-template |
| 301 | + (let [{:keys [regions]} (test/get-config) |
| 302 | + stack-name (test/rand-stack-name)] |
| 303 | + (doseq [region regions |
| 304 | + :let [system-def (-> (stack-a |
| 305 | + :name stack-name |
| 306 | + :region region |
| 307 | + :template (ds/local-ref [:template])) |
| 308 | + system-a |
| 309 | + (assoc-in [::ds/defs :services :template] |
| 310 | + (cfn/template :template template-a)))]] |
| 311 | + (test/with-system-delete [sys system-def] |
| 312 | + (let [{:keys [stack-a]} (-> @sys ::ds/instances :services)] |
| 313 | + (is (= "CREATE_COMPLETE" |
| 314 | + (-> stack-a :resources :OAI1 :ResourceStatus)) |
| 315 | + "A stack can sucessfully be created from a template component")))))) |
| 316 | + |
206 | 317 | (deftest test-lifecycle |
207 | 318 | (let [{:keys [regions]} (test/get-config) |
208 | 319 | stack-name (test/rand-stack-name)] |
|
706 | 817 | (let [{:keys [regions]} (test/get-config) |
707 | 818 | stack-name (test/rand-stack-name)] |
708 | 819 | (doseq [region regions |
709 | | - :let [system-def |
| 820 | + :let [system-def-no-template |
710 | 821 | #__ (assoc test/system-base |
711 | 822 | ::ds/defs |
712 | 823 | {:service |
|
720 | 831 | (cfn/stack |
721 | 832 | {:change-set (ds/local-ref [:change-set]) |
722 | 833 | :name stack-name |
723 | | - :region region})}})]] |
724 | | - (is (ds/signal system-def :salmon/early-validate) |
725 | | - "early-validate succeeds") |
726 | | - (test/with-system-delete [sys system-def] |
727 | | - (testing "A stack can be created from a change set" |
| 834 | + :region region})}}) |
| 835 | + system-def-template |
| 836 | + #__ (assoc test/system-base |
| 837 | + ::ds/defs |
| 838 | + {:service |
| 839 | + {:change-set |
| 840 | + (cfn/change-set |
| 841 | + {:name (test/rand-stack-name) |
| 842 | + :region region |
| 843 | + :stack-name stack-name |
| 844 | + :template (ds/local-ref [:template])}) |
| 845 | + :stack |
| 846 | + (cfn/stack |
| 847 | + {:change-set (ds/local-ref [:change-set]) |
| 848 | + :name stack-name |
| 849 | + :region region}) |
| 850 | + :template |
| 851 | + (cfn/template |
| 852 | + {:template template-a})}})]] |
| 853 | + (test/with-system-delete [sys system-def-no-template] |
| 854 | + (testing "A stack can be created from a change-set" |
| 855 | + (is (ds/signal system-def-no-template :salmon/early-validate) |
| 856 | + "early-validate succeeds") |
| 857 | + (let [{:keys [change-set stack]} (-> @sys ::ds/instances :service)] |
| 858 | + (is (->> (select-keys change-set [:id :name :stack-id :stack-name]) |
| 859 | + vals |
| 860 | + (every? string?)) |
| 861 | + "change-set returns expected names and IDs") |
| 862 | + (is (= (:stack-id change-set) |
| 863 | + (:stack-id stack))) |
| 864 | + (is (= "CREATE_COMPLETE" |
| 865 | + (-> stack :resources :OAI1 :ResourceStatus)))))) |
| 866 | + (test/with-system-delete [sys system-def-template] |
| 867 | + (testing "A change-set can be created from a template and applied to a stack" |
| 868 | + (is (ds/signal system-def-template :salmon/early-validate) |
| 869 | + "early-validate succeeds") |
728 | 870 | (let [{:keys [change-set stack]} (-> @sys ::ds/instances :service)] |
729 | 871 | (is (->> (select-keys change-set [:id :name :stack-id :stack-name]) |
730 | 872 | vals |
|
0 commit comments