packer-cn/builder/amazon/common/block_device_test.go

402 lines
9.1 KiB
Go
Raw Normal View History

package common
import (
"testing"
2015-06-03 17:13:52 -04:00
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
2019-09-20 09:28:43 -04:00
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
)
func TestBlockDevice(t *testing.T) {
2014-09-04 00:27:43 -04:00
cases := []struct {
Config *BlockDevice
Result *ec2.BlockDeviceMapping
}{
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
SnapshotId: "snap-1234",
VolumeType: "standard",
VolumeSize: 8,
DeleteOnTermination: true,
},
Result: &ec2.BlockDeviceMapping{
2015-10-18 14:00:05 -04:00
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
SnapshotId: aws.String("snap-1234"),
VolumeType: aws.String("standard"),
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(true),
2015-06-09 12:56:40 -04:00
},
},
},
{
Config: &BlockDevice{
2015-06-17 23:23:04 -04:00
DeviceName: "/dev/sdb",
VolumeSize: 8,
},
Result: &ec2.BlockDeviceMapping{
2015-10-18 14:00:05 -04:00
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(false),
},
},
},
2015-06-09 12:56:40 -04:00
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io1",
VolumeSize: 8,
DeleteOnTermination: true,
IOPS: 1000,
},
Result: &ec2.BlockDeviceMapping{
2015-10-18 14:00:05 -04:00
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
2015-06-09 12:56:40 -04:00
VolumeType: aws.String("io1"),
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(true),
Iops: aws.Int64(1000),
},
2014-09-04 00:27:43 -04:00
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io2",
VolumeSize: 8,
DeleteOnTermination: true,
IOPS: 1000,
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeType: aws.String("io2"),
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(true),
Iops: aws.Int64(1000),
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp2",
VolumeSize: 8,
DeleteOnTermination: true,
Encrypted: config.TriTrue,
},
Result: &ec2.BlockDeviceMapping{
2015-10-18 14:00:05 -04:00
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeType: aws.String("gp2"),
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(true),
Encrypted: aws.Bool(true),
2015-10-18 16:04:41 -04:00
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp2",
VolumeSize: 8,
DeleteOnTermination: true,
Encrypted: config.TriTrue,
KmsKeyId: "2Fa48a521f-3aff-4b34-a159-376ac5d37812",
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeType: aws.String("gp2"),
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(true),
Encrypted: aws.Bool(true),
2019-09-20 09:28:43 -04:00
KmsKeyId: aws.String("2Fa48a521f-3aff-4b34-a159-376ac5d37812"),
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "standard",
DeleteOnTermination: true,
},
Result: &ec2.BlockDeviceMapping{
2015-10-18 16:04:41 -04:00
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeType: aws.String("standard"),
2015-10-18 16:04:41 -04:00
DeleteOnTermination: aws.Bool(true),
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VirtualName: "ephemeral0",
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
VirtualName: aws.String("ephemeral0"),
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
NoDevice: true,
},
Result: &ec2.BlockDeviceMapping{
2015-10-18 14:00:05 -04:00
DeviceName: aws.String("/dev/sdb"),
NoDevice: aws.String(""),
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp3",
VolumeSize: 8,
Throughput: 125,
IOPS: 3000,
DeleteOnTermination: true,
Encrypted: config.TriTrue,
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeType: aws.String("gp3"),
VolumeSize: aws.Int64(8),
Throughput: aws.Int64(125),
Iops: aws.Int64(3000),
DeleteOnTermination: aws.Bool(true),
Encrypted: aws.Bool(true),
},
},
},
}
2014-09-04 00:27:43 -04:00
for _, tc := range cases {
var amiBlockDevices BlockDevices = []BlockDevice{*tc.Config}
var launchBlockDevices BlockDevices = []BlockDevice{*tc.Config}
expected := []*ec2.BlockDeviceMapping{tc.Result}
amiResults := amiBlockDevices.BuildEC2BlockDeviceMappings()
2019-09-20 09:28:43 -04:00
if diff := cmp.Diff(expected, amiResults); diff != "" {
t.Fatalf("Bad block device: %s", diff)
2014-09-04 00:27:43 -04:00
}
launchResults := launchBlockDevices.BuildEC2BlockDeviceMappings()
2019-09-20 09:28:43 -04:00
if diff := cmp.Diff(expected, launchResults); diff != "" {
t.Fatalf("Bad block device: %s", diff)
2014-09-04 00:27:43 -04:00
}
}
}
2020-10-31 08:10:51 -04:00
func TestIOPSValidation(t *testing.T) {
cases := []struct {
device BlockDevice
ok bool
msg string
}{
// volume size unknown
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io1",
IOPS: 1000,
},
ok: true,
},
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io2",
IOPS: 1000,
},
ok: true,
},
// ratio requirement satisfied
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io1",
VolumeSize: 50,
IOPS: 1000,
},
ok: true,
},
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io2",
VolumeSize: 100,
IOPS: 1000,
},
ok: true,
},
// ratio requirement not satisfied
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io1",
VolumeSize: 10,
IOPS: 2000,
},
ok: false,
msg: "/dev/sdb: the maximum ratio of provisioned IOPS to requested volume size (in GiB) is 50:1 for io1 volumes",
2020-10-31 08:10:51 -04:00
},
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io2",
VolumeSize: 50,
IOPS: 30000,
},
ok: false,
msg: "/dev/sdb: the maximum ratio of provisioned IOPS to requested volume size (in GiB) is 500:1 for io2 volumes",
},
// exceed max iops
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io2",
VolumeSize: 500,
IOPS: 99999,
},
ok: false,
msg: "IOPS must be between 100 and 64000 for device /dev/sdb",
},
// lower than min iops
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io2",
VolumeSize: 50,
IOPS: 10,
},
ok: false,
msg: "IOPS must be between 100 and 64000 for device /dev/sdb",
2020-10-31 08:10:51 -04:00
},
// exceed max iops
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp3",
VolumeSize: 50,
Throughput: 125,
IOPS: 99999,
},
ok: false,
msg: "IOPS must be between 3000 and 16000 for device /dev/sdb",
},
// lower than min iops
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp3",
VolumeSize: 50,
Throughput: 125,
IOPS: 10,
},
ok: false,
msg: "IOPS must be between 3000 and 16000 for device /dev/sdb",
},
}
ctx := interpolate.Context{}
for _, testCase := range cases {
err := testCase.device.Prepare(&ctx)
if testCase.ok && err != nil {
t.Fatalf("should not error, but: %v", err)
}
if !testCase.ok {
if err == nil {
t.Fatalf("should error")
} else if err.Error() != testCase.msg {
t.Fatalf("wrong error: expected %s, found: %v", testCase.msg, err)
}
}
}
}
func TestThroughputValidation(t *testing.T) {
cases := []struct {
device BlockDevice
ok bool
msg string
}{
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp3",
Throughput: 125,
IOPS: 3000,
},
ok: true,
},
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp3",
Throughput: 1000,
IOPS: 3000,
},
ok: true,
},
// exceed max Throughput
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp3",
Throughput: 1001,
IOPS: 3000,
},
ok: false,
msg: "Throughput must be between 125 and 1000 for device /dev/sdb",
},
// lower than min Throughput
{
device: BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp3",
Throughput: 124,
IOPS: 3000,
},
ok: false,
msg: "Throughput must be between 125 and 1000 for device /dev/sdb",
},
2020-10-31 08:10:51 -04:00
}
ctx := interpolate.Context{}
for _, testCase := range cases {
err := testCase.device.Prepare(&ctx)
if testCase.ok && err != nil {
t.Fatalf("should not error, but: %v", err)
}
if !testCase.ok {
if err == nil {
t.Fatalf("should error")
} else if err.Error() != testCase.msg {
t.Fatalf("wrong error: expected %s, found: %v", testCase.msg, err)
}
}
}
}