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  }`