|
1 | 1 | require 'spec_helper' |
2 | 2 | require 'json' |
3 | 3 | require 'yaml' |
4 | | -require 'fileutils' |
5 | 4 | require 'tmpdir' |
6 | 5 | require 'term/ansicolor' |
7 | 6 | require 'cfnguardian/log' |
|
181 | 180 | end |
182 | 181 |
|
183 | 182 | describe 'Validation' do |
| 183 | + def compile_config(config) |
| 184 | + Dir.mktmpdir do |tmpdir| |
| 185 | + fixture = File.join(tmpdir, 'test_alarms.yaml') |
| 186 | + File.write(fixture, config.to_yaml) |
| 187 | + compile = CfnGuardian::Compile.new(fixture, false) |
| 188 | + compile.get_resources |
| 189 | + compile |
| 190 | + end |
| 191 | + end |
| 192 | + |
184 | 193 | context 'when search expression alarm has no metric_name or namespace' do |
185 | 194 | it 'does not raise validation errors' do |
186 | | - Dir.mktmpdir do |tmpdir| |
187 | | - fixture = File.join(tmpdir, 'search_expression_alarms.yaml') |
188 | | - File.write(fixture, { |
| 195 | + result = compile_config({ |
| 196 | + 'Resources' => { |
| 197 | + 'AutoScalingGroup' => [{ 'Id' => 'my-app-AsgGroup-abc123' }] |
| 198 | + }, |
| 199 | + 'Templates' => { |
| 200 | + 'AutoScalingGroup' => { |
| 201 | + 'CPUUtilizationHighBase' => { |
| 202 | + 'SearchExpression' => "SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-app', 'Minimum', 60)", |
| 203 | + 'SearchAggregation' => 'MAX' |
| 204 | + }, |
| 205 | + 'StatusCheckFailed' => false |
| 206 | + } |
| 207 | + } |
| 208 | + }) |
| 209 | + |
| 210 | + search_alarms = result.alarms.select { |a| a.search_expression } |
| 211 | + expect(search_alarms.length).to eq(1) |
| 212 | + expect(search_alarms.first.search_expression).to include('SEARCH') |
| 213 | + end |
| 214 | + end |
| 215 | + |
| 216 | + context 'when search expression is blank' do |
| 217 | + it 'raises a validation error' do |
| 218 | + expect { |
| 219 | + compile_config({ |
189 | 220 | 'Resources' => { |
190 | 221 | 'AutoScalingGroup' => [{ 'Id' => 'my-app-AsgGroup-abc123' }] |
191 | 222 | }, |
192 | 223 | 'Templates' => { |
193 | 224 | 'AutoScalingGroup' => { |
194 | 225 | 'CPUUtilizationHighBase' => { |
195 | | - 'SearchExpression' => "SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-app', 'Minimum', 60)", |
| 226 | + 'SearchExpression' => ' ', |
| 227 | + 'SearchAggregation' => 'MAX' |
| 228 | + }, |
| 229 | + 'StatusCheckFailed' => false |
| 230 | + } |
| 231 | + } |
| 232 | + }) |
| 233 | + }.to raise_error(CfnGuardian::ValidationError, /invalid SearchExpression/) |
| 234 | + end |
| 235 | + end |
| 236 | + |
| 237 | + context 'when search expression is not a string' do |
| 238 | + it 'raises a validation error' do |
| 239 | + expect { |
| 240 | + compile_config({ |
| 241 | + 'Resources' => { |
| 242 | + 'AutoScalingGroup' => [{ 'Id' => 'my-app-AsgGroup-abc123' }] |
| 243 | + }, |
| 244 | + 'Templates' => { |
| 245 | + 'AutoScalingGroup' => { |
| 246 | + 'CPUUtilizationHighBase' => { |
| 247 | + 'SearchExpression' => ['not', 'a', 'string'], |
196 | 248 | 'SearchAggregation' => 'MAX' |
197 | 249 | }, |
198 | 250 | 'StatusCheckFailed' => false |
199 | 251 | } |
200 | 252 | } |
201 | | - }.to_yaml) |
202 | | - |
203 | | - compile = CfnGuardian::Compile.new(fixture, false) |
204 | | - compile.get_resources |
205 | | - search_alarms = compile.alarms.select { |a| a.search_expression } |
206 | | - expect(search_alarms.length).to eq(1) |
207 | | - expect(search_alarms.first.search_expression).to include('SEARCH') |
208 | | - end |
| 253 | + }) |
| 254 | + }.to raise_error(CfnGuardian::ValidationError, /invalid SearchExpression/) |
| 255 | + end |
| 256 | + end |
| 257 | + |
| 258 | + context 'when search aggregation is invalid' do |
| 259 | + it 'raises a validation error' do |
| 260 | + expect { |
| 261 | + compile_config({ |
| 262 | + 'Resources' => { |
| 263 | + 'AutoScalingGroup' => [{ 'Id' => 'my-app-AsgGroup-abc123' }] |
| 264 | + }, |
| 265 | + 'Templates' => { |
| 266 | + 'AutoScalingGroup' => { |
| 267 | + 'CPUUtilizationHighBase' => { |
| 268 | + 'SearchExpression' => "SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-app', 'Minimum', 60)", |
| 269 | + 'SearchAggregation' => 'MEDIAN' |
| 270 | + }, |
| 271 | + 'StatusCheckFailed' => false |
| 272 | + } |
| 273 | + } |
| 274 | + }) |
| 275 | + }.to raise_error(CfnGuardian::ValidationError, /invalid SearchAggregation/) |
| 276 | + end |
| 277 | + end |
| 278 | + |
| 279 | + context 'when search aggregation is lowercase' do |
| 280 | + it 'normalizes to uppercase' do |
| 281 | + result = compile_config({ |
| 282 | + 'Resources' => { |
| 283 | + 'AutoScalingGroup' => [{ 'Id' => 'my-app-AsgGroup-abc123' }] |
| 284 | + }, |
| 285 | + 'Templates' => { |
| 286 | + 'AutoScalingGroup' => { |
| 287 | + 'CPUUtilizationHighBase' => { |
| 288 | + 'SearchExpression' => "SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-app', 'Minimum', 60)", |
| 289 | + 'SearchAggregation' => 'avg' |
| 290 | + }, |
| 291 | + 'StatusCheckFailed' => false |
| 292 | + } |
| 293 | + } |
| 294 | + }) |
| 295 | + |
| 296 | + search_alarms = result.alarms.select { |a| a.search_expression } |
| 297 | + expect(search_alarms.first.search_aggregation).to eq('AVG') |
209 | 298 | end |
210 | 299 | end |
211 | 300 | end |
|
0 commit comments