github.phpd.cn/hashicorp/packer@v1.3.2/builder/alicloud/ecs/builder_acc_test.go (about) 1 package ecs 2 3 import ( 4 "os" 5 "testing" 6 7 "fmt" 8 9 "github.com/denverdino/aliyungo/common" 10 "github.com/denverdino/aliyungo/ecs" 11 builderT "github.com/hashicorp/packer/helper/builder/testing" 12 "github.com/hashicorp/packer/packer" 13 ) 14 15 func TestBuilderAcc_basic(t *testing.T) { 16 builderT.Test(t, builderT.TestCase{ 17 PreCheck: func() { 18 testAccPreCheck(t) 19 }, 20 Builder: &Builder{}, 21 Template: testBuilderAccBasic, 22 }) 23 } 24 25 //func TestBuilderAcc_windows(t *testing.T) { 26 // builderT.Test(t, builderT.TestCase{ 27 // PreCheck: func() { 28 // testAccPreCheck(t) 29 // }, 30 // Builder: &Builder{}, 31 // Template: testBuilderAccWindows, 32 // }) 33 //} 34 35 //func TestBuilderAcc_regionCopy(t *testing.T) { 36 // builderT.Test(t, builderT.TestCase{ 37 // PreCheck: func() { 38 // testAccPreCheck(t) 39 // }, 40 // Builder: &Builder{}, 41 // Template: testBuilderAccRegionCopy, 42 // Check: checkRegionCopy([]string{"cn-hangzhou", "cn-shenzhen"}), 43 // }) 44 //} 45 46 func TestBuilderAcc_forceDelete(t *testing.T) { 47 // Build the same alicloud image twice, with ecs_image_force_delete on the second run 48 builderT.Test(t, builderT.TestCase{ 49 PreCheck: func() { 50 testAccPreCheck(t) 51 }, 52 Builder: &Builder{}, 53 Template: buildForceDeregisterConfig("false", "delete"), 54 SkipArtifactTeardown: true, 55 }) 56 57 builderT.Test(t, builderT.TestCase{ 58 PreCheck: func() { 59 testAccPreCheck(t) 60 }, 61 Builder: &Builder{}, 62 Template: buildForceDeregisterConfig("true", "delete"), 63 }) 64 } 65 66 func TestBuilderAcc_ECSImageSharing(t *testing.T) { 67 builderT.Test(t, builderT.TestCase{ 68 PreCheck: func() { 69 testAccPreCheck(t) 70 }, 71 Builder: &Builder{}, 72 Template: testBuilderAccSharing, 73 Check: checkECSImageSharing("1309208528360047"), 74 }) 75 } 76 77 func TestBuilderAcc_forceDeleteSnapshot(t *testing.T) { 78 destImageName := "delete" 79 80 // Build the same alicloud image name twice, with force_delete_snapshot on the second run 81 builderT.Test(t, builderT.TestCase{ 82 PreCheck: func() { 83 testAccPreCheck(t) 84 }, 85 Builder: &Builder{}, 86 Template: buildForceDeleteSnapshotConfig("false", destImageName), 87 SkipArtifactTeardown: true, 88 }) 89 90 // Get image data by image image name 91 client, _ := testAliyunClient() 92 images, _, _ := client.DescribeImages(&ecs.DescribeImagesArgs{ 93 ImageName: "packer-test-" + destImageName, 94 RegionId: common.Region("cn-beijing")}) 95 96 image := images[0] 97 98 // Get snapshot ids for image 99 snapshotIds := []string{} 100 for _, device := range image.DiskDeviceMappings.DiskDeviceMapping { 101 if device.Device != "" && device.SnapshotId != "" { 102 snapshotIds = append(snapshotIds, device.SnapshotId) 103 } 104 } 105 106 builderT.Test(t, builderT.TestCase{ 107 PreCheck: func() { 108 testAccPreCheck(t) 109 }, 110 Builder: &Builder{}, 111 Template: buildForceDeleteSnapshotConfig("true", destImageName), 112 Check: checkSnapshotsDeleted(snapshotIds), 113 }) 114 } 115 116 func TestBuilderAcc_imageTags(t *testing.T) { 117 builderT.Test(t, builderT.TestCase{ 118 PreCheck: func() { 119 testAccPreCheck(t) 120 }, 121 Builder: &Builder{}, 122 Template: testBuilderAccImageTags, 123 Check: checkImageTags(), 124 }) 125 } 126 127 func checkSnapshotsDeleted(snapshotIds []string) builderT.TestCheckFunc { 128 return func(artifacts []packer.Artifact) error { 129 // Verify the snapshots are gone 130 client, _ := testAliyunClient() 131 snapshotResp, _, err := client.DescribeSnapshots( 132 &ecs.DescribeSnapshotsArgs{RegionId: common.Region("cn-beijing"), SnapshotIds: snapshotIds}, 133 ) 134 if err != nil { 135 return fmt.Errorf("Query snapshot failed %v", err) 136 } 137 if len(snapshotResp) > 0 { 138 return fmt.Errorf("Snapshots weren't successfully deleted by " + 139 "`ecs_image_force_delete_snapshots`") 140 } 141 return nil 142 } 143 } 144 145 func checkECSImageSharing(uid string) builderT.TestCheckFunc { 146 return func(artifacts []packer.Artifact) error { 147 if len(artifacts) > 1 { 148 return fmt.Errorf("more than 1 artifact") 149 } 150 151 // Get the actual *Artifact pointer so we can access the AMIs directly 152 artifactRaw := artifacts[0] 153 artifact, ok := artifactRaw.(*Artifact) 154 if !ok { 155 return fmt.Errorf("unknown artifact: %#v", artifactRaw) 156 } 157 158 // describe the image, get block devices with a snapshot 159 client, _ := testAliyunClient() 160 imageSharePermissionResponse, err := client.DescribeImageSharePermission( 161 &ecs.ModifyImageSharePermissionArgs{ 162 RegionId: "cn-beijing", 163 ImageId: artifact.AlicloudImages["cn-beijing"], 164 }) 165 166 if err != nil { 167 return fmt.Errorf("Error retrieving Image Attributes for ECS Image Artifact (%#v) "+ 168 "in ECS Image Sharing Test: %s", artifact, err) 169 } 170 171 if len(imageSharePermissionResponse.Accounts.Account) != 1 && 172 imageSharePermissionResponse.Accounts.Account[0].AliyunId != uid { 173 return fmt.Errorf("share account is incorrect %d", 174 len(imageSharePermissionResponse.Accounts.Account)) 175 } 176 177 return nil 178 } 179 } 180 181 func checkRegionCopy(regions []string) builderT.TestCheckFunc { 182 return func(artifacts []packer.Artifact) error { 183 if len(artifacts) > 1 { 184 return fmt.Errorf("more than 1 artifact") 185 } 186 187 // Get the actual *Artifact pointer so we can access the AMIs directly 188 artifactRaw := artifacts[0] 189 artifact, ok := artifactRaw.(*Artifact) 190 if !ok { 191 return fmt.Errorf("unknown artifact: %#v", artifactRaw) 192 } 193 194 // Verify that we copied to only the regions given 195 regionSet := make(map[string]struct{}) 196 for _, r := range regions { 197 regionSet[r] = struct{}{} 198 } 199 for r := range artifact.AlicloudImages { 200 if r == "cn-beijing" { 201 delete(regionSet, r) 202 continue 203 } 204 if _, ok := regionSet[r]; !ok { 205 return fmt.Errorf("unknown region: %s", r) 206 } 207 208 delete(regionSet, r) 209 } 210 if len(regionSet) > 0 { 211 return fmt.Errorf("didn't copy to: %#v", regionSet) 212 } 213 client, _ := testAliyunClient() 214 for key, value := range artifact.AlicloudImages { 215 client.WaitForImageReady(common.Region(key), value, 1800) 216 } 217 return nil 218 } 219 } 220 221 func checkImageTags() builderT.TestCheckFunc { 222 return func(artifacts []packer.Artifact) error { 223 if len(artifacts) > 1 { 224 return fmt.Errorf("more than 1 artifact") 225 } 226 // Get the actual *Artifact pointer so we can access the AMIs directly 227 artifactRaw := artifacts[0] 228 artifact, ok := artifactRaw.(*Artifact) 229 if !ok { 230 return fmt.Errorf("unknown artifact: %#v", artifactRaw) 231 } 232 // describe the image, get block devices with a snapshot 233 client, _ := testAliyunClient() 234 tags, _, err := client.DescribeTags( 235 &ecs.DescribeTagsArgs{ 236 RegionId: "cn-beijing", 237 ResourceType: ecs.TagResourceImage, 238 ResourceId: artifact.AlicloudImages["cn-beijing"], 239 }) 240 if err != nil { 241 return fmt.Errorf("Error retrieving Image Attributes for ECS Image Artifact (%#v) "+ 242 "in ECS Image Tags Test: %s", artifact, err) 243 } 244 failed := false 245 if len(tags) != 2 { 246 failed = true 247 } 248 if !failed { 249 for i := 0; i < len(tags); i++ { 250 if tags[i].TagKey == "TagKey1" && tags[i].TagValue != "TagValue1" { 251 failed = true 252 } else if tags[i].TagKey == "TagKey2" && tags[i].TagValue != "TagValue2" { 253 failed = true 254 } else if tags[i].TagKey != "TagKey1" && tags[i].TagKey != "TagKey2" { 255 failed = true 256 } 257 } 258 } 259 if failed { 260 return fmt.Errorf("tags is not correctly set %#v", tags) 261 } 262 return nil 263 } 264 } 265 266 func testAccPreCheck(t *testing.T) { 267 if v := os.Getenv("ALICLOUD_ACCESS_KEY"); v == "" { 268 t.Fatal("ALICLOUD_ACCESS_KEY must be set for acceptance tests") 269 } 270 271 if v := os.Getenv("ALICLOUD_SECRET_KEY"); v == "" { 272 t.Fatal("ALICLOUD_SECRET_KEY must be set for acceptance tests") 273 } 274 } 275 276 func testAliyunClient() (*ecs.Client, error) { 277 access := &AlicloudAccessConfig{AlicloudRegion: "cn-beijing"} 278 err := access.Config() 279 if err != nil { 280 return nil, err 281 } 282 client, err := access.Client() 283 if err != nil { 284 return nil, err 285 } 286 287 return client, nil 288 } 289 290 const testBuilderAccBasic = ` 291 { "builders": [{ 292 "type": "test", 293 "region": "cn-beijing", 294 "instance_type": "ecs.n1.tiny", 295 "source_image":"ubuntu_16_0402_64_20G_alibase_20180409.vhd", 296 "io_optimized":"true", 297 "ssh_username":"root", 298 "image_name": "packer-test_{{timestamp}}" 299 }] 300 }` 301 302 const testBuilderAccRegionCopy = ` 303 { 304 "builders": [{ 305 "type": "test", 306 "region": "cn-beijing", 307 "instance_type": "ecs.n1.tiny", 308 "source_image":"ubuntu_16_0402_64_40G_base_20170222.vhd", 309 "io_optimized":"true", 310 "ssh_username":"root", 311 "image_name": "packer-test_{{timestamp}}", 312 "image_copy_regions": ["cn-hangzhou", "cn-shenzhen"] 313 }] 314 } 315 ` 316 317 const testBuilderAccForceDelete = ` 318 { 319 "builders": [{ 320 "type": "test", 321 "region": "cn-beijing", 322 "instance_type": "ecs.n1.tiny", 323 "source_image":"ubuntu_16_0402_64_40G_base_20170222.vhd", 324 "io_optimized":"true", 325 "ssh_username":"root", 326 "image_force_delete": "%s", 327 "image_name": "packer-test_%s" 328 }] 329 } 330 ` 331 332 const testBuilderAccForceDeleteSnapshot = ` 333 { 334 "builders": [{ 335 "type": "test", 336 "region": "cn-beijing", 337 "instance_type": "ecs.n1.tiny", 338 "source_image":"ubuntu_16_0402_64_40G_base_20170222.vhd", 339 "io_optimized":"true", 340 "ssh_username":"root", 341 "image_force_delete_snapshots": "%s", 342 "image_force_delete": "%s", 343 "image_name": "packer-test-%s" 344 }] 345 } 346 ` 347 348 // share with catsby 349 const testBuilderAccSharing = ` 350 { 351 "builders": [{ 352 "type": "test", 353 "region": "cn-beijing", 354 "instance_type": "ecs.n1.tiny", 355 "source_image":"ubuntu_16_0402_64_40G_base_20170222.vhd", 356 "io_optimized":"true", 357 "ssh_username":"root", 358 "image_name": "packer-test_{{timestamp}}", 359 "image_share_account":["1309208528360047"] 360 }] 361 } 362 ` 363 364 const testBuilderAccImageTags = ` 365 { "builders": [{ 366 "type": "test", 367 "region": "cn-beijing", 368 "instance_type": "ecs.n1.tiny", 369 "source_image":"ubuntu_16_0402_64_20G_alibase_20180409.vhd", 370 "ssh_username": "root", 371 "io_optimized":"true", 372 "image_name": "packer-test_{{timestamp}}", 373 "tags": { 374 "TagKey1": "TagValue1", 375 "TagKey2": "TagValue2" 376 } 377 }] 378 }` 379 380 func buildForceDeregisterConfig(val, name string) string { 381 return fmt.Sprintf(testBuilderAccForceDelete, val, name) 382 } 383 384 func buildForceDeleteSnapshotConfig(val, name string) string { 385 return fmt.Sprintf(testBuilderAccForceDeleteSnapshot, val, val, name) 386 } 387 388 const testBuilderAccWindows = ` 389 { "builders": [{ 390 "type": "test", 391 "region": "cn-beijing", 392 "instance_type": "ecs.n1.tiny", 393 "source_image":"win2008_64_ent_r2_zh-cn_40G_alibase_20170301.vhd", 394 "io_optimized":"true", 395 "image_force_delete":"true", 396 "communicator": "winrm", 397 "winrm_port": 5985, 398 "winrm_username": "Administrator", 399 "winrm_password": "Test1234", 400 "image_name": "packer-test_{{timestamp}}" 401 }] 402 }`