github.com/darmach/terratest@v0.34.8-0.20210517103231-80931f95e3ff/modules/aws/asg_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/service/autoscaling"
    10  	"github.com/aws/aws-sdk-go/service/ec2"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/gruntwork-io/terratest/modules/random"
    15  )
    16  
    17  func TestGetCapacityInfoForAsg(t *testing.T) {
    18  	t.Parallel()
    19  
    20  	uniqueID := random.UniqueId()
    21  	asgName := fmt.Sprintf("%s-%s", t.Name(), uniqueID)
    22  	region := GetRandomStableRegion(t, []string{}, []string{})
    23  
    24  	defer deleteAutoScalingGroup(t, asgName, region)
    25  	createTestAutoScalingGroup(t, asgName, region, 2)
    26  	WaitForCapacity(t, asgName, region, 40, 15*time.Second)
    27  
    28  	capacityInfo := GetCapacityInfoForAsg(t, asgName, region)
    29  	assert.Equal(t, capacityInfo.DesiredCapacity, int64(2))
    30  	assert.Equal(t, capacityInfo.CurrentCapacity, int64(2))
    31  	assert.Equal(t, capacityInfo.MinCapacity, int64(1))
    32  	assert.Equal(t, capacityInfo.MaxCapacity, int64(3))
    33  }
    34  
    35  func TestGetInstanceIdsForAsg(t *testing.T) {
    36  	t.Parallel()
    37  
    38  	uniqueID := random.UniqueId()
    39  	asgName := fmt.Sprintf("%s-%s", t.Name(), uniqueID)
    40  	region := GetRandomStableRegion(t, []string{}, []string{})
    41  
    42  	defer deleteAutoScalingGroup(t, asgName, region)
    43  	createTestAutoScalingGroup(t, asgName, region, 1)
    44  	WaitForCapacity(t, asgName, region, 40, 15*time.Second)
    45  
    46  	instanceIds := GetInstanceIdsForAsg(t, asgName, region)
    47  	assert.Equal(t, len(instanceIds), 1)
    48  }
    49  
    50  // The following functions were adapted from the tests for cloud-nuke
    51  
    52  func createTestAutoScalingGroup(t *testing.T, name string, region string, desiredCount int64) {
    53  	instance := createTestEC2Instance(t, region, name)
    54  
    55  	asgClient := NewAsgClient(t, region)
    56  	param := &autoscaling.CreateAutoScalingGroupInput{
    57  		AutoScalingGroupName: &name,
    58  		InstanceId:           instance.InstanceId,
    59  		DesiredCapacity:      aws.Int64(desiredCount),
    60  		MinSize:              aws.Int64(1),
    61  		MaxSize:              aws.Int64(3),
    62  	}
    63  	_, err := asgClient.CreateAutoScalingGroup(param)
    64  	require.NoError(t, err)
    65  
    66  	err = asgClient.WaitUntilGroupExists(&autoscaling.DescribeAutoScalingGroupsInput{
    67  		AutoScalingGroupNames: []*string{&name},
    68  	})
    69  	require.NoError(t, err)
    70  }
    71  
    72  func createTestEC2Instance(t *testing.T, region string, name string) ec2.Instance {
    73  	ec2Client := NewEc2Client(t, region)
    74  	imageID := GetAmazonLinuxAmi(t, region)
    75  	params := &ec2.RunInstancesInput{
    76  		ImageId:      aws.String(imageID),
    77  		InstanceType: aws.String("t2.micro"),
    78  		MinCount:     aws.Int64(1),
    79  		MaxCount:     aws.Int64(1),
    80  	}
    81  	runResult, err := ec2Client.RunInstances(params)
    82  	require.NoError(t, err)
    83  
    84  	require.NotEqual(t, len(runResult.Instances), 0)
    85  
    86  	err = ec2Client.WaitUntilInstanceExists(&ec2.DescribeInstancesInput{
    87  		Filters: []*ec2.Filter{
    88  			&ec2.Filter{
    89  				Name:   aws.String("instance-id"),
    90  				Values: []*string{runResult.Instances[0].InstanceId},
    91  			},
    92  		},
    93  	})
    94  	require.NoError(t, err)
    95  
    96  	// Add test tag to the created instance
    97  	_, err = ec2Client.CreateTags(&ec2.CreateTagsInput{
    98  		Resources: []*string{runResult.Instances[0].InstanceId},
    99  		Tags: []*ec2.Tag{
   100  			{
   101  				Key:   aws.String("Name"),
   102  				Value: aws.String(name),
   103  			},
   104  		},
   105  	})
   106  	require.NoError(t, err)
   107  
   108  	// EC2 Instance must be in a running before this function returns
   109  	err = ec2Client.WaitUntilInstanceRunning(&ec2.DescribeInstancesInput{
   110  		Filters: []*ec2.Filter{
   111  			&ec2.Filter{
   112  				Name:   aws.String("instance-id"),
   113  				Values: []*string{runResult.Instances[0].InstanceId},
   114  			},
   115  		},
   116  	})
   117  	require.NoError(t, err)
   118  
   119  	return *runResult.Instances[0]
   120  }
   121  
   122  func terminateEc2InstancesByName(t *testing.T, region string, names []string) {
   123  	for _, name := range names {
   124  		instanceIds := GetEc2InstanceIdsByTag(t, region, "Name", name)
   125  		for _, instanceId := range instanceIds {
   126  			TerminateInstance(t, region, instanceId)
   127  		}
   128  	}
   129  }
   130  
   131  func deleteAutoScalingGroup(t *testing.T, name string, region string) {
   132  	// We have to scale ASG down to 0 before we can delete it
   133  	scaleAsgToZero(t, name, region)
   134  
   135  	asgClient := NewAsgClient(t, region)
   136  	input := &autoscaling.DeleteAutoScalingGroupInput{AutoScalingGroupName: aws.String(name)}
   137  	_, err := asgClient.DeleteAutoScalingGroup(input)
   138  	require.NoError(t, err)
   139  	err = asgClient.WaitUntilGroupNotExists(&autoscaling.DescribeAutoScalingGroupsInput{
   140  		AutoScalingGroupNames: []*string{aws.String(name)},
   141  	})
   142  	require.NoError(t, err)
   143  }
   144  
   145  func scaleAsgToZero(t *testing.T, name string, region string) {
   146  	asgClient := NewAsgClient(t, region)
   147  	input := &autoscaling.UpdateAutoScalingGroupInput{
   148  		AutoScalingGroupName: aws.String(name),
   149  		DesiredCapacity:      aws.Int64(0),
   150  		MinSize:              aws.Int64(0),
   151  		MaxSize:              aws.Int64(0),
   152  	}
   153  	_, err := asgClient.UpdateAutoScalingGroup(input)
   154  	require.NoError(t, err)
   155  	WaitForCapacity(t, name, region, 40, 15*time.Second)
   156  
   157  	// There is an eventual consistency bug where even though the ASG is scaled down, AWS sometimes still views a
   158  	// scaling activity so we add a 5 second pause here to work around it.
   159  	time.Sleep(5 * time.Second)
   160  }