github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/openstack/orchestration/v1/stacks/template_test.go (about) 1 package stacks 2 3 import ( 4 "strings" 5 "testing" 6 7 th "github.com/vnpaycloud-console/gophercloud/v2/testhelper" 8 ) 9 10 func TestTemplateValidation(t *testing.T) { 11 templateJSON := new(Template) 12 templateJSON.Bin = []byte(ValidJSONTemplate) 13 th.AssertNoErr(t, templateJSON.Validate()) 14 15 templateYAML := new(Template) 16 templateYAML.Bin = []byte(ValidYAMLTemplate) 17 th.AssertNoErr(t, templateYAML.Validate()) 18 19 templateInvalid := new(Template) 20 templateInvalid.Bin = []byte(InvalidTemplateNoVersion) 21 if err := templateInvalid.Validate(); err == nil { 22 t.Error("Template validation did not catch invalid template") 23 } 24 } 25 26 func TestTemplateParsing(t *testing.T) { 27 templateJSON := new(Template) 28 templateJSON.Bin = []byte(ValidJSONTemplate) 29 th.AssertNoErr(t, templateJSON.Parse()) 30 th.AssertDeepEquals(t, ValidJSONTemplateParsed, templateJSON.Parsed) 31 32 templateYAML := new(Template) 33 templateYAML.Bin = []byte(ValidJSONTemplate) 34 th.AssertNoErr(t, templateYAML.Parse()) 35 th.AssertDeepEquals(t, ValidJSONTemplateParsed, templateYAML.Parsed) 36 37 templateInvalid := new(Template) 38 templateInvalid.Bin = []byte("Keep Austin Weird") 39 err := templateInvalid.Parse() 40 if err == nil { 41 t.Error("Template parsing did not catch invalid template") 42 } 43 } 44 45 func TestIgnoreIfTemplate(t *testing.T) { 46 var keyValueTests = []struct { 47 key string 48 value any 49 out bool 50 }{ 51 {"not_get_file", "afksdf", true}, 52 {"not_type", "sdfd", true}, 53 {"get_file", "shdfuisd", false}, 54 {"type", "dfsdfsd", true}, 55 {"type", "sdfubsduf.yaml", false}, 56 {"type", "sdfsdufs.template", false}, 57 {"type", "sdfsdf.file", true}, 58 {"type", map[string]string{"key": "value"}, true}, 59 } 60 var result bool 61 for _, kv := range keyValueTests { 62 result = ignoreIfTemplate(kv.key, kv.value) 63 if result != kv.out { 64 t.Errorf("key: %v, value: %v expected: %v, actual: %v", kv.key, kv.value, result, kv.out) 65 } 66 } 67 } 68 69 const myNovaContent = `heat_template_version: 2014-10-16 70 parameters: 71 flavor: 72 type: string 73 description: Flavor for the server to be created 74 default: 4353 75 hidden: true 76 resources: 77 test_server: 78 type: "OS::Nova::Server" 79 properties: 80 name: test-server 81 flavor: 2 GB General Purpose v1 82 image: Debian 7 (Wheezy) (PVHVM) 83 networks: 84 - {uuid: 11111111-1111-1111-1111-111111111111}` 85 86 var myNovaExpected = map[string]any{ 87 "heat_template_version": "2014-10-16", 88 "parameters": map[string]any{ 89 "flavor": map[string]any{ 90 "type": "string", 91 "description": "Flavor for the server to be created", 92 "default": 4353, 93 "hidden": true, 94 }, 95 }, 96 "resources": map[string]any{ 97 "test_server": map[string]any{ 98 "type": "OS::Nova::Server", 99 "properties": map[string]any{ 100 "name": "test-server", 101 "flavor": "2 GB General Purpose v1", 102 "image": "Debian 7 (Wheezy) (PVHVM)", 103 "networks": []any{ 104 map[string]any{ 105 "uuid": "11111111-1111-1111-1111-111111111111", 106 }, 107 }, 108 }, 109 }, 110 }, 111 } 112 113 func TestGetFileContentsWithType(t *testing.T) { 114 th.SetupHTTP() 115 defer th.TeardownHTTP() 116 baseurl, err := getBasePath() 117 th.AssertNoErr(t, err) 118 119 fakeURL := th.ServeFile(t, baseurl, "my_nova.yaml", "application/json", myNovaContent) 120 121 client := fakeClient{BaseClient: getHTTPClient()} 122 te := new(Template) 123 te.Bin = []byte(`heat_template_version: 2015-04-30 124 resources: 125 my_server: 126 type: my_nova.yaml`) 127 te.client = client 128 129 th.AssertNoErr(t, te.Parse()) 130 th.AssertNoErr(t, te.getFileContents(te.Parsed, ignoreIfTemplate, true)) 131 132 // Now check template and referenced file 133 expectedParsed := map[string]any{ 134 "heat_template_version": "2015-04-30", 135 "resources": map[string]any{ 136 "my_server": map[string]any{ 137 "type": fakeURL, 138 }, 139 }, 140 } 141 th.AssertNoErr(t, te.Parse()) 142 th.AssertDeepEquals(t, expectedParsed, te.Parsed) 143 144 novaTe := new(Template) 145 novaTe.Bin = []byte(te.Files[fakeURL]) 146 th.AssertNoErr(t, novaTe.Parse()) 147 th.AssertDeepEquals(t, myNovaExpected, novaTe.Parsed) 148 } 149 150 func TestGetFileContentsWithFile(t *testing.T) { 151 th.SetupHTTP() 152 defer th.TeardownHTTP() 153 baseurl, err := getBasePath() 154 th.AssertNoErr(t, err) 155 156 somefile := `Welcome!` 157 fakeURL := th.ServeFile(t, baseurl, "somefile", "text/plain", somefile) 158 159 client := fakeClient{BaseClient: getHTTPClient()} 160 te := new(Template) 161 // Note: We include the path that should be replaced also as a not-to-be-replaced 162 // keyword ("path: somefile" below) to validate that no updates happen outside of 163 // the real local URLs (child templates (type:) or included files (get_file:)). 164 te.Bin = []byte(`heat_template_version: 2015-04-30 165 resources: 166 test_resource: 167 type: OS::Heat::TestResource 168 properties: 169 path: somefile 170 value: { get_file: somefile }`) 171 te.client = client 172 173 th.AssertNoErr(t, te.Parse()) 174 th.AssertNoErr(t, te.getFileContents(te.Parsed, ignoreIfTemplate, true)) 175 expectedFiles := map[string]string{ 176 "somefile": "Welcome!", 177 } 178 th.AssertEquals(t, expectedFiles["somefile"], te.Files[fakeURL]) 179 expectedParsed := map[string]any{ 180 "heat_template_version": "2015-04-30", 181 "resources": map[string]any{ 182 "test_resource": map[string]any{ 183 "type": "OS::Heat::TestResource", 184 "properties": map[string]any{ 185 "path": "somefile", 186 "value": map[string]any{ 187 "get_file": fakeURL, 188 }, 189 }, 190 }, 191 }, 192 } 193 th.AssertNoErr(t, te.Parse()) 194 th.AssertDeepEquals(t, expectedParsed, te.Parsed) 195 } 196 197 func TestGetFileContentsComposeRelativePath(t *testing.T) { 198 th.SetupHTTP() 199 defer th.TeardownHTTP() 200 baseurl, err := getBasePath() 201 th.AssertNoErr(t, err) 202 203 novaPath := strings.Join([]string{"templates", "my_nova.yaml"}, "/") 204 novaURL := th.ServeFile(t, baseurl, novaPath, "application/json", myNovaContent) 205 206 mySubStackContent := `heat_template_version: 2015-04-30 207 resources: 208 my_server: 209 type: ../templates/my_nova.yaml 210 my_backend: 211 type: "OS::Nova::Server" 212 properties: 213 name: test-backend 214 flavor: 4 GB General Purpose v1 215 image: Debian 7 (Wheezy) (PVHVM) 216 networks: 217 - {uuid: 11111111-1111-1111-1111-111111111111}` 218 mySubstrackExpected := map[string]any{ 219 "heat_template_version": "2015-04-30", 220 "resources": map[string]any{ 221 "my_server": map[string]any{ 222 "type": novaURL, 223 }, 224 "my_backend": map[string]any{ 225 "type": "OS::Nova::Server", 226 "properties": map[string]any{ 227 "name": "test-backend", 228 "flavor": "4 GB General Purpose v1", 229 "image": "Debian 7 (Wheezy) (PVHVM)", 230 "networks": []any{ 231 map[string]any{ 232 "uuid": "11111111-1111-1111-1111-111111111111", 233 }, 234 }, 235 }, 236 }, 237 }, 238 } 239 subStacksPath := strings.Join([]string{"substacks", "my_substack.yaml"}, "/") 240 subStackURL := th.ServeFile(t, baseurl, subStacksPath, "application/json", mySubStackContent) 241 242 client := fakeClient{BaseClient: getHTTPClient()} 243 te := new(Template) 244 te.Bin = []byte(`heat_template_version: 2015-04-30 245 resources: 246 my_stack: 247 type: substacks/my_substack.yaml`) 248 te.client = client 249 250 th.AssertNoErr(t, te.Parse()) 251 th.AssertNoErr(t, te.getFileContents(te.Parsed, ignoreIfTemplate, true)) 252 253 expectedParsed := map[string]any{ 254 "heat_template_version": "2015-04-30", 255 "resources": map[string]any{ 256 "my_stack": map[string]any{ 257 "type": subStackURL, 258 }, 259 }, 260 } 261 th.AssertNoErr(t, te.Parse()) 262 th.AssertDeepEquals(t, expectedParsed, te.Parsed) 263 264 expectedFiles := map[string]any{ 265 novaURL: myNovaExpected, 266 subStackURL: mySubstrackExpected, 267 } 268 for path, expected := range expectedFiles { 269 checkTe := new(Template) 270 checkTe.Bin = []byte(te.Files[path]) 271 th.AssertNoErr(t, checkTe.Parse()) 272 th.AssertDeepEquals(t, expected, checkTe.Parsed) 273 } 274 }