github.com/aquasecurity/trivy-iac@v0.8.1-0.20240127024015-3d8e412cf0ab/test/count_test.go (about) 1 package test 2 3 import ( 4 "testing" 5 6 "github.com/aquasecurity/defsec/pkg/providers" 7 "github.com/aquasecurity/defsec/pkg/rules" 8 "github.com/aquasecurity/defsec/pkg/scan" 9 "github.com/aquasecurity/defsec/pkg/severity" 10 "github.com/aquasecurity/defsec/pkg/terraform" 11 "github.com/stretchr/testify/assert" 12 13 "github.com/aquasecurity/trivy-iac/test/testutil" 14 ) 15 16 func Test_ResourcesWithCount(t *testing.T) { 17 var tests = []struct { 18 name string 19 source string 20 expectedResults int 21 }{ 22 { 23 name: "unspecified count defaults to 1", 24 source: ` 25 resource "bad" "this" {} 26 `, 27 expectedResults: 1, 28 }, 29 { 30 name: "count is literal 1", 31 source: ` 32 resource "bad" "this" { 33 count = 1 34 } 35 `, 36 expectedResults: 1, 37 }, 38 { 39 name: "count is literal 99", 40 source: ` 41 resource "bad" "this" { 42 count = 99 43 } 44 `, 45 expectedResults: 99, 46 }, 47 { 48 name: "count is literal 0", 49 source: ` 50 resource "bad" "this" { 51 count = 0 52 } 53 `, 54 expectedResults: 0, 55 }, 56 { 57 name: "count is 0 from variable", 58 source: ` 59 variable "count" { 60 default = 0 61 } 62 resource "bad" "this" { 63 count = var.count 64 } 65 `, 66 expectedResults: 0, 67 }, 68 { 69 name: "count is 1 from variable", 70 source: ` 71 variable "count" { 72 default = 1 73 } 74 resource "bad" "this" { 75 count = var.count 76 } 77 `, 78 expectedResults: 1, 79 }, 80 { 81 name: "count is 1 from variable without default", 82 source: ` 83 variable "count" { 84 } 85 resource "bad" "this" { 86 count = var.count 87 } 88 `, 89 expectedResults: 1, 90 }, 91 { 92 name: "count is 0 from conditional", 93 source: ` 94 variable "enabled" { 95 default = false 96 } 97 resource "bad" "this" { 98 count = var.enabled ? 1 : 0 99 } 100 `, 101 expectedResults: 0, 102 }, 103 { 104 name: "count is 1 from conditional", 105 source: ` 106 variable "enabled" { 107 default = true 108 } 109 resource "bad" "this" { 110 count = var.enabled ? 1 : 0 111 } 112 `, 113 expectedResults: 1, 114 }, 115 { 116 name: "issue 962", 117 source: ` 118 resource "something" "else" { 119 count = 2 120 ok = true 121 } 122 123 resource "bad" "bad" { 124 secure = something.else[0].ok 125 } 126 `, 127 expectedResults: 0, 128 }, 129 { 130 name: "Test use of count.index", 131 source: ` 132 resource "bad" "thing" { 133 count = 1 134 secure = var.things[count.index]["ok"] 135 } 136 137 variable "things" { 138 description = "A list of maps that creates a number of sg" 139 type = list(map(string)) 140 141 default = [ 142 { 143 ok = true 144 } 145 ] 146 } 147 `, 148 expectedResults: 0, 149 }, 150 } 151 152 for _, test := range tests { 153 t.Run(test.name, func(t *testing.T) { 154 r1 := scan.Rule{ 155 Provider: providers.AWSProvider, 156 Service: "service", 157 ShortCode: "abc123", 158 Severity: severity.High, 159 CustomChecks: scan.CustomChecks{ 160 Terraform: &scan.TerraformCustomCheck{ 161 RequiredLabels: []string{"bad"}, 162 Check: func(resourceBlock *terraform.Block, _ *terraform.Module) (results scan.Results) { 163 if resourceBlock.GetAttribute("secure").IsTrue() { 164 return 165 } 166 results.Add( 167 "example problem", 168 resourceBlock, 169 ) 170 return 171 }, 172 }, 173 }, 174 } 175 reg := rules.Register(r1) 176 defer rules.Deregister(reg) 177 results := scanHCL(t, test.source) 178 var include string 179 var exclude string 180 if test.expectedResults > 0 { 181 include = r1.LongID() 182 } else { 183 exclude = r1.LongID() 184 } 185 assert.Equal(t, test.expectedResults, len(results.GetFailed())) 186 if include != "" { 187 testutil.AssertRuleFound(t, include, results, "false negative found") 188 } 189 if exclude != "" { 190 testutil.AssertRuleNotFound(t, exclude, results, "false positive found") 191 } 192 }) 193 } 194 }