github.com/wata727/tflint@v0.12.2-0.20191013070026-96dd0d36f385/rules/awsrules/aws_instance_invalid_ami_test.go (about)

     1  package awsrules
     2  
     3  import (
     4  	"errors"
     5  	"testing"
     6  
     7  	"github.com/aws/aws-sdk-go/aws"
     8  	"github.com/aws/aws-sdk-go/aws/awserr"
     9  	"github.com/aws/aws-sdk-go/service/ec2"
    10  	"github.com/golang/mock/gomock"
    11  	hcl "github.com/hashicorp/hcl/v2"
    12  	"github.com/wata727/tflint/client"
    13  	"github.com/wata727/tflint/tflint"
    14  )
    15  
    16  func Test_AwsInstanceInvalidAMI_invalid(t *testing.T) {
    17  	content := `
    18  resource "aws_instance" "invalid" {
    19  	ami = "ami-1234abcd"
    20  }`
    21  	runner := tflint.TestRunner(t, map[string]string{"instances.tf": content})
    22  
    23  	ctrl := gomock.NewController(t)
    24  	defer ctrl.Finish()
    25  
    26  	ec2mock := client.NewMockEC2API(ctrl)
    27  	ec2mock.EXPECT().DescribeImages(&ec2.DescribeImagesInput{
    28  		ImageIds: aws.StringSlice([]string{"ami-1234abcd"}),
    29  	}).Return(&ec2.DescribeImagesOutput{
    30  		Images: []*ec2.Image{},
    31  	}, nil)
    32  	runner.AwsClient.EC2 = ec2mock
    33  
    34  	rule := NewAwsInstanceInvalidAMIRule()
    35  	if err := rule.Check(runner); err != nil {
    36  		t.Fatalf("Unexpected error occurred: %s", err)
    37  	}
    38  
    39  	expected := tflint.Issues{
    40  		{
    41  			Rule:    NewAwsInstanceInvalidAMIRule(),
    42  			Message: "\"ami-1234abcd\" is invalid AMI ID.",
    43  			Range: hcl.Range{
    44  				Filename: "instances.tf",
    45  				Start:    hcl.Pos{Line: 3, Column: 8},
    46  				End:      hcl.Pos{Line: 3, Column: 22},
    47  			},
    48  		},
    49  	}
    50  	tflint.AssertIssues(t, expected, runner.Issues)
    51  }
    52  
    53  func Test_AwsInstanceInvalidAMI_valid(t *testing.T) {
    54  	content := `
    55  resource "aws_instance" "valid" {
    56  	ami = "ami-9ad76sd1"
    57  }`
    58  	runner := tflint.TestRunner(t, map[string]string{"instances.tf": content})
    59  
    60  	ctrl := gomock.NewController(t)
    61  	defer ctrl.Finish()
    62  
    63  	ec2mock := client.NewMockEC2API(ctrl)
    64  	ec2mock.EXPECT().DescribeImages(&ec2.DescribeImagesInput{
    65  		ImageIds: aws.StringSlice([]string{"ami-9ad76sd1"}),
    66  	}).Return(&ec2.DescribeImagesOutput{
    67  		Images: []*ec2.Image{
    68  			{
    69  				ImageId: aws.String("ami-9ad76sd1"),
    70  			},
    71  		},
    72  	}, nil)
    73  	runner.AwsClient.EC2 = ec2mock
    74  
    75  	rule := NewAwsInstanceInvalidAMIRule()
    76  	if err := rule.Check(runner); err != nil {
    77  		t.Fatalf("Unexpected error occurred: %s", err)
    78  	}
    79  
    80  	expected := tflint.Issues{}
    81  	tflint.AssertIssues(t, expected, runner.Issues)
    82  }
    83  
    84  func Test_AwsInstanceInvalidAMI_error(t *testing.T) {
    85  	cases := []struct {
    86  		Name     string
    87  		Content  string
    88  		Request  *ec2.DescribeImagesInput
    89  		Response error
    90  		Error    tflint.Error
    91  	}{
    92  		{
    93  			Name: "AWS API error",
    94  			Content: `
    95  resource "aws_instance" "valid" {
    96    ami = "ami-9ad76sd1"
    97  }`,
    98  			Request: &ec2.DescribeImagesInput{
    99  				ImageIds: aws.StringSlice([]string{"ami-9ad76sd1"}),
   100  			},
   101  			Response: awserr.New(
   102  				"MissingRegion",
   103  				"could not find region configuration",
   104  				nil,
   105  			),
   106  			Error: tflint.Error{
   107  				Code:    tflint.ExternalAPIError,
   108  				Level:   tflint.ErrorLevel,
   109  				Message: "An error occurred while describing images; MissingRegion: could not find region configuration",
   110  			},
   111  		},
   112  		{
   113  			Name: "Unexpected error",
   114  			Content: `
   115  resource "aws_instance" "valid" {
   116    ami = "ami-9ad76sd1"
   117  }`,
   118  			Request: &ec2.DescribeImagesInput{
   119  				ImageIds: aws.StringSlice([]string{"ami-9ad76sd1"}),
   120  			},
   121  			Response: errors.New("Unexpected"),
   122  			Error: tflint.Error{
   123  				Code:    tflint.ExternalAPIError,
   124  				Level:   tflint.ErrorLevel,
   125  				Message: "An error occurred while describing images; Unexpected",
   126  			},
   127  		},
   128  	}
   129  
   130  	ctrl := gomock.NewController(t)
   131  	defer ctrl.Finish()
   132  
   133  	rule := NewAwsInstanceInvalidAMIRule()
   134  
   135  	for _, tc := range cases {
   136  		runner := tflint.TestRunner(t, map[string]string{"instances.tf": tc.Content})
   137  
   138  		ec2mock := client.NewMockEC2API(ctrl)
   139  		ec2mock.EXPECT().DescribeImages(tc.Request).Return(nil, tc.Response)
   140  		runner.AwsClient.EC2 = ec2mock
   141  
   142  		err := rule.Check(runner)
   143  		tflint.AssertAppError(t, tc.Error, err)
   144  	}
   145  }
   146  
   147  func Test_AwsInstanceInvalidAMI_AMIError(t *testing.T) {
   148  	cases := []struct {
   149  		Name     string
   150  		Content  string
   151  		Request  *ec2.DescribeImagesInput
   152  		Response error
   153  		Issues   tflint.Issues
   154  		Error    bool
   155  	}{
   156  		{
   157  			Name: "not found",
   158  			Content: `
   159  resource "aws_instance" "not_found" {
   160  	ami = "ami-9ad76sd1"
   161  }`,
   162  			Request: &ec2.DescribeImagesInput{
   163  				ImageIds: aws.StringSlice([]string{"ami-9ad76sd1"}),
   164  			},
   165  			Response: awserr.New(
   166  				"InvalidAMIID.NotFound",
   167  				"The image id '[ami-9ad76sd1]' does not exist",
   168  				nil,
   169  			),
   170  			Issues: tflint.Issues{
   171  				{
   172  					Rule:    NewAwsInstanceInvalidAMIRule(),
   173  					Message: "\"ami-9ad76sd1\" is invalid AMI ID.",
   174  					Range: hcl.Range{
   175  						Filename: "instances.tf",
   176  						Start:    hcl.Pos{Line: 3, Column: 8},
   177  						End:      hcl.Pos{Line: 3, Column: 22},
   178  					},
   179  				},
   180  			},
   181  			Error: false,
   182  		},
   183  		{
   184  			Name: "malformed",
   185  			Content: `
   186  resource "aws_instance" "malformed" {
   187  	ami = "image-9ad76sd1"
   188  }`,
   189  			Request: &ec2.DescribeImagesInput{
   190  				ImageIds: aws.StringSlice([]string{"image-9ad76sd1"}),
   191  			},
   192  			Response: awserr.New(
   193  				"InvalidAMIID.Malformed",
   194  				"Invalid id: \"image-9ad76sd1\" (expecting \"ami-...\")",
   195  				nil,
   196  			),
   197  			Issues: tflint.Issues{
   198  				{
   199  					Rule:    NewAwsInstanceInvalidAMIRule(),
   200  					Message: "\"image-9ad76sd1\" is invalid AMI ID.",
   201  					Range: hcl.Range{
   202  						Filename: "instances.tf",
   203  						Start:    hcl.Pos{Line: 3, Column: 8},
   204  						End:      hcl.Pos{Line: 3, Column: 24},
   205  					},
   206  				},
   207  			},
   208  			Error: false,
   209  		},
   210  		{
   211  			Name: "unavailable",
   212  			Content: `
   213  resource "aws_instance" "unavailable" {
   214  	ami = "ami-1234567"
   215  }`,
   216  			Request: &ec2.DescribeImagesInput{
   217  				ImageIds: aws.StringSlice([]string{"ami-1234567"}),
   218  			},
   219  			Response: awserr.New(
   220  				"InvalidAMIID.Unavailable",
   221  				"The image ID: 'ami-1234567' is no longer available",
   222  				nil,
   223  			),
   224  			Issues: tflint.Issues{
   225  				{
   226  					Rule:    NewAwsInstanceInvalidAMIRule(),
   227  					Message: "\"ami-1234567\" is invalid AMI ID.",
   228  					Range: hcl.Range{
   229  						Filename: "instances.tf",
   230  						Start:    hcl.Pos{Line: 3, Column: 8},
   231  						End:      hcl.Pos{Line: 3, Column: 21},
   232  					},
   233  				},
   234  			},
   235  			Error: false,
   236  		},
   237  	}
   238  
   239  	ctrl := gomock.NewController(t)
   240  	defer ctrl.Finish()
   241  
   242  	rule := NewAwsInstanceInvalidAMIRule()
   243  
   244  	for _, tc := range cases {
   245  		runner := tflint.TestRunner(t, map[string]string{"instances.tf": tc.Content})
   246  
   247  		ec2mock := client.NewMockEC2API(ctrl)
   248  		ec2mock.EXPECT().DescribeImages(tc.Request).Return(nil, tc.Response)
   249  		runner.AwsClient.EC2 = ec2mock
   250  
   251  		err := rule.Check(runner)
   252  		if err != nil && !tc.Error {
   253  			t.Fatalf("Failed `%s` test: unexpected error occurred: %s", tc.Name, err)
   254  		}
   255  		if err == nil && tc.Error {
   256  			t.Fatalf("Failed `%s` test: expected to return an error, but nothing occurred", tc.Name)
   257  		}
   258  
   259  		tflint.AssertIssues(t, tc.Issues, runner.Issues)
   260  	}
   261  }