Skip to content

Commit 3aab03a

Browse files
author
melvabout
committed
Add tests to confirm generated template structure is as expected in preparation for automation.
1 parent 623b5d0 commit 3aab03a

9 files changed

+10816
-1192
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ node_modules
66
# CDK asset staging directory
77
.cdk.staging
88
cdk.out
9+
10+
# unit tests outputs
11+
test-monitor
12+
test-activegate

cucumber/features/activegate.feature

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Feature: AgtiveGate Feature
2+
3+
Confirm the structure of the AgtiveGate template
4+
5+
Scenario: AgtiveGate Template
6+
Given That synth has run
7+
When the file DynatraceActivegateStack.template.json exists
8+
Then the AWS::EC2::VPC resource with the CIDR range 10.0.0.0/16 should exist
9+
And 2 AWS::EC2::Subnet should exist
10+
And 2 AWS::EC2::RouteTable should exist
11+
And 2 AWS::EC2::SubnetRouteTableAssociation should exist
12+
And 2 AWS::EC2::Route should exist
13+
And 1 AWS::EC2::EIP should exist
14+
And 1 AWS::EC2::NatGateway should exist

cucumber/features/monitoring.feature

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Feature: Monitoring Feature
2+
3+
Confirm the structure of the monitoring template
4+
5+
Scenario: Monitoring Template
6+
Given That synth has run
7+
When the file DynatraceMonitoringRoleStack.template.json exists
8+
Then the AWS::IAM::Role resource with the RoleName DynatraceMonitoringRole should exist
9+
And the AWS::IAM::Policy resource with the PolicyName like roleDefaultPolicy should exist
10+
And actions of AWS::IAM::Policy should match actions file

cucumber/files/actions

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
acm-pca:ListCertificateAuthorities,apigateway:GET,athena:ListWorkGroups,autoscaling:DescribeAutoScalingGroups,cloudfront:ListDistributions,cloudwatch:GetMetricData,cloudwatch:GetMetricStatistics,cloudwatch:ListMetrics,codebuild:ListProjects,dynamodb:ListTables,dynamodb:ListTagsOfResource,ec2:DescribeAvailabilityZones,ec2:DescribeInstances,ec2:DescribeVolumes,ecs:ListClusters,elasticache:DescribeCacheClusters,elasticloadbalancing:DescribeInstanceHealth,elasticloadbalancing:DescribeListeners,elasticloadbalancing:DescribeLoadBalancers,elasticloadbalancing:DescribeRules,elasticloadbalancing:DescribeTags,elasticloadbalancing:DescribeTargetHealth,events:ListEventBuses,glue:GetJobs,lambda:ListFunctions,lambda:ListTags,logs:DescribeLogGroups,rds:DescribeDBInstances,rds:DescribeEvents,rds:ListTagsForResource,route53:ListHostedZones,s3:ListAllMyBuckets,sns:ListTopics,sqs:ListQueues,sts:GetCallerIdentity,tag:GetResources,tag:GetTagKeys
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { loadFeature, defineFeature } from "jest-cucumber";
2+
import { execSync } from "child_process";
3+
import { existsSync, readFileSync, mkdirSync, rmSync } from "fs";
4+
import { Template } from '@aws-cdk/assertions';
5+
6+
7+
const feature = loadFeature("./cucumber/features/activegate.feature");
8+
9+
defineFeature(feature, (test) => {
10+
11+
beforeEach(() => {
12+
mkdirSync('./test-activegate/');
13+
});
14+
15+
afterEach(() => {
16+
rmSync('./test-activegate/', { recursive: true, force: true });
17+
});
18+
19+
test("AgtiveGate Template", ({ given, when, then }) => {
20+
21+
let template: Template;
22+
23+
given("That synth has run", () => {
24+
execSync("cdk synth --output ./test-activegate/");
25+
});
26+
27+
when(/^the file (.*) exists$/, (fileName: string) => {
28+
expect(existsSync(`./test-activegate/${fileName}`)).toBeTruthy();
29+
template = Template.fromString(readFileSync(`./test-activegate/${fileName}`, "utf-8"));
30+
});
31+
32+
then(/^the (.*) resource with the CIDR range (.*) should exist$/, (resourceType: string, cidrRange: string) => {
33+
34+
let props = {
35+
Properties: {
36+
CidrBlock: cidrRange
37+
}
38+
};
39+
40+
template.hasResource(resourceType, props);
41+
});
42+
43+
44+
then(/^(\d+) AWS::EC2::Subnet should exist$/, (resourceCount: number) => {
45+
expect(Object.values(template.findResources("AWS::EC2::Subnet")).length).toEqual(+resourceCount)
46+
});
47+
48+
then(/^(\d+) AWS::EC2::RouteTable should exist$/, (resourceCount: number) => {
49+
expect(Object.values(template.findResources("AWS::EC2::RouteTable")).length).toEqual(+resourceCount)
50+
})
51+
52+
then(/^(\d+) AWS::EC2::SubnetRouteTableAssociation should exist$/, (resourceCount: number) => {
53+
expect(Object.values(template.findResources("AWS::EC2::SubnetRouteTableAssociation")).length).toEqual(+resourceCount)
54+
});
55+
56+
then(/^(\d+) AWS::EC2::Route should exist$/, (resourceCount: number) => {
57+
expect(Object.values(template.findResources("AWS::EC2::Route")).length).toEqual(+resourceCount)
58+
});
59+
60+
then(/^(\d+) AWS::EC2::EIP should exist$/, (resourceCount: number) => {
61+
expect(Object.values(template.findResources("AWS::EC2::EIP")).length).toEqual(+resourceCount)
62+
});
63+
64+
then(/^(\d+) AWS::EC2::NatGateway should exist$/, (resourceCount: number) => {
65+
expect(Object.values(template.findResources("AWS::EC2::NatGateway")).length).toEqual(+resourceCount)
66+
});
67+
});
68+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { loadFeature, defineFeature } from "jest-cucumber";
2+
import { execSync } from "child_process";
3+
import { existsSync, readFileSync, mkdirSync, rmSync } from "fs";
4+
import { Template } from '@aws-cdk/assertions';
5+
6+
7+
const feature = loadFeature("./cucumber/features/monitoring.feature");
8+
9+
defineFeature(feature, (test) => {
10+
11+
beforeEach(() => {
12+
mkdirSync('./test-monitor/');
13+
});
14+
15+
afterEach(() => {
16+
rmSync('./test-monitor/', { recursive: true, force: true });
17+
});
18+
19+
test("Monitoring Template", ({ given, when, then }) => {
20+
21+
let template: Template;
22+
23+
given("That synth has run", () => {
24+
execSync("cdk synth --output ./test-monitor/");
25+
});
26+
27+
when(/^the file (.*) exists$/, (fileName: string) => {
28+
expect(existsSync(`./test-monitor/${fileName}`)).toBeTruthy();
29+
template = Template.fromString(readFileSync(`./test-monitor/${fileName}`, "utf-8"));
30+
});
31+
32+
then(/^the (.*) resource with the (.*) (.*) should exist$/, (resourceType: string, resourceNameKey: string, resourceNameValue: string) => {
33+
34+
let props = {
35+
Properties: {
36+
[resourceNameKey]: resourceNameValue
37+
}
38+
};
39+
40+
template.hasResource(resourceType, props);
41+
});
42+
43+
then(/^the (.*) resource with the (.*) like (.*) should exist$/, (resourceType: string, resourceNameKey: string, resourceNameValue: string) => {
44+
template.hasResource(resourceType , {})
45+
let valueKey = Object.values(template.findResources(resourceType))[0]["Properties"][resourceNameKey]
46+
expect(valueKey.startsWith(resourceNameValue)).toBeTruthy();
47+
});
48+
49+
then(/^actions of (.*) should match (.*) file$/, (resourceType, actionsFile: string) => {
50+
let actionsString = readFileSync(`./cucumber/files/${actionsFile}`, "utf-8")
51+
let actionsList = actionsString.split(",")
52+
let objectActionsA = Object.values(template.findResources(resourceType))[0]["Properties"]["PolicyDocument"]["Statement"][0]["Action"] as Array<string>
53+
expect(actionsList.sort().join(",")).toEqual(objectActionsA.sort().join(","))
54+
});
55+
56+
});
57+
});

jest.config.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
testEnvironment: 'node',
3+
roots: ['<rootDir>/cucumber'],
4+
testMatch: ['**/*.steps.ts'],
5+
transform: {
6+
'^.+\\.tsx?$': 'ts-jest'
7+
}
8+
};

0 commit comments

Comments
 (0)