Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cloudformation-diff): DependsOn singleton arrays aren't equal to string values #9814

Merged
merged 71 commits into from
Aug 19, 2020
Merged
Show file tree
Hide file tree
Changes from 70 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
db60c27
doc: added slack link to readme
comcalvi Jun 4, 2020
5924f3b
Merge branch 'master' into master
comcalvi Jun 5, 2020
f0c85a3
Update README.md
comcalvi Jun 5, 2020
f37e60e
Merge branch 'master' into master
mergify[bot] Jun 5, 2020
83ed743
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 15, 2020
c6664af
added support for Fn::Select, Fn::FindInMap, Fn::Cidr, Fn::GetAZs, Fn…
comcalvi Jun 15, 2020
d0f64d2
added support for the 'Fn::Transform' cloudformation intrinsic function.
comcalvi Jun 16, 2020
d69e46d
added support for the Fn::Base64 Intrinsic Function
comcalvi Jun 16, 2020
df1446a
tested more complex combinations of conditional and non-conditional i…
comcalvi Jun 16, 2020
132cb4d
fixed linter issues
comcalvi Jun 16, 2020
ae7c570
implmented Adam's requests and fixed additional linter issues
comcalvi Jun 17, 2020
7ca707e
updated README to reflect the newly supported cloudformation functions
comcalvi Jun 17, 2020
63c27a7
removed quotes from the type of Transform's parameter argument, modif…
comcalvi Jun 17, 2020
4179271
fixed teseting issue related to Fn::Select
comcalvi Jun 18, 2020
117ae63
Merge branch 'master' into CfnFunctions
comcalvi Jun 18, 2020
dbb9ef8
fixing merge conflicts
comcalvi Jun 18, 2020
bdab761
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 18, 2020
d390580
Merge branch 'master' of https://github.com/aws/aws-cdk into CfnFunct…
comcalvi Jun 18, 2020
14a0d64
merge conflict resolution
comcalvi Jun 18, 2020
dfb42b9
Merge branch 'CfnFunctions' of github.com:comcalvi/aws-cdk into CfnFu…
comcalvi Jun 18, 2020
9f1b2d9
Merge branch 'master' of https://github.com/aws/aws-cdk into CfnFunct…
comcalvi Jun 18, 2020
4c9d1ec
fixed typo in condition name
comcalvi Jun 18, 2020
e15c187
Merge branch 'CfnFunctions'
comcalvi Jun 18, 2020
82c4317
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 18, 2020
42c0228
removed parameters from _toCloudFormation()
comcalvi Jun 18, 2020
6a2df1e
added support for parameters in templates
comcalvi Jun 19, 2020
43198b7
fixed merge conflict
comcalvi Jun 19, 2020
cd27ff6
updated documentation
comcalvi Jun 19, 2020
1e72465
updated readme
comcalvi Jun 19, 2020
070f902
incorporated adam's comments
comcalvi Jun 19, 2020
b10a1ed
fixed spacing
comcalvi Jun 19, 2020
68d2fbc
fixed merge conflicts
comcalvi Jun 22, 2020
225d1ce
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 25, 2020
badeae8
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 26, 2020
5bf4760
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 29, 2020
479931e
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 29, 2020
c3fa10e
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 2, 2020
685d57d
added outputs array
comcalvi Jun 29, 2020
e334814
added support for retrieving and modifying outputs
comcalvi Jun 30, 2020
34d5c34
fixed linter issues
comcalvi Jun 30, 2020
95badbe
updated README
comcalvi Jun 30, 2020
fa39d72
updated documentation
comcalvi Jun 30, 2020
a3940e3
removed unneeded line in tests
comcalvi Jun 30, 2020
fbf17f2
added newline
comcalvi Jun 30, 2020
c719e85
incorporated PR requests
comcalvi Jul 1, 2020
f05aae1
updated the example in the readme
comcalvi Jul 1, 2020
69223d2
added support for common-named outputs. Fixed a bug in the export nam…
comcalvi Jul 1, 2020
0c55180
added a negative test case and a new error message if an output refer…
comcalvi Jul 1, 2020
7557a00
incorporated changes to PR
comcalvi Jul 6, 2020
356fc8f
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 16, 2020
6c62755
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 17, 2020
783e1f4
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 17, 2020
0e59c33
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 19, 2020
98498d1
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 21, 2020
8d5deff
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 22, 2020
59abb94
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 23, 2020
3b902af
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 27, 2020
bdc9fd1
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 29, 2020
c86cc12
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 29, 2020
93509d3
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 30, 2020
32a241a
fixed the CfnOutput comment docs
comcalvi Jul 31, 2020
576c818
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 31, 2020
711d8dc
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 31, 2020
cfd58af
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Aug 3, 2020
94737a7
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Aug 3, 2020
7f6752c
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Aug 6, 2020
3bc1831
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Aug 6, 2020
f28f044
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Aug 7, 2020
0258f92
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Aug 18, 2020
02d907b
fixed DependsOn array comparison
comcalvi Aug 18, 2020
dc0fa65
Merge branch 'master' into depends-on-diff
mergify[bot] Aug 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion packages/@aws-cdk/cloudformation-diff/lib/diff/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export function deepEqual(lvalue: any, rvalue: any): boolean {
if (lvalue === rvalue) { return true; }
// allows a numeric 10 and a literal "10" to be equivalent;
// this is consistent with CloudFormation.
if (parseFloat(lvalue) === parseFloat(rvalue)) { return true; }
if (((typeof lvalue === 'string') || (typeof rvalue === 'string')) && (parseFloat(lvalue) === parseFloat(rvalue))) {
return true;
}
if (typeof lvalue !== typeof rvalue) { return false; }
if (Array.isArray(lvalue) !== Array.isArray(rvalue)) { return false; }
if (Array.isArray(lvalue) /* && Array.isArray(rvalue) */) {
Expand All @@ -36,6 +38,7 @@ export function deepEqual(lvalue: any, rvalue: any): boolean {
if (keys.length !== Object.keys(rvalue).length) { return false; }
for (const key of keys) {
if (!rvalue.hasOwnProperty(key)) { return false; }
if (key === 'DependsOn') { return dependsOnEqual(lvalue[key], rvalue[key]); }
if (!deepEqual(lvalue[key], rvalue[key])) { return false; }
}
return true;
Expand All @@ -45,6 +48,43 @@ export function deepEqual(lvalue: any, rvalue: any): boolean {
return false;
}

/**
* Compares two arguments to DependsOn for equality.
*
* @param lvalue the left operand of the equality comparison.
* @param rvalue the right operand of the equality comparison.
*
* @returns +true+ if both +lvalue+ and +rvalue+ are equivalent to each other.
*/
function dependsOnEqual(lvalue: any, rvalue: any): boolean {
// allows ['Value'] and 'Value' to be equal
if (Array.isArray(lvalue) !== Array.isArray(rvalue)) {
const array = Array.isArray(lvalue) ? lvalue : rvalue;
const nonArray = Array.isArray(lvalue) ? rvalue : lvalue;

if (array.length === 1 && deepEqual(array[0], nonArray)) {
return true;
}
return false;
}

// allows arrays passed to DependsOn to be equivalent irrespective of element order
if (Array.isArray(lvalue) && Array.isArray(rvalue)) {
if (lvalue.length !== rvalue.length) { return false; }
for (let i = 0 ; i < lvalue.length ; i++) {
for (let j = 0 ; j < lvalue.length ; j++) {
if ((!deepEqual(lvalue[i], rvalue[j])) && (j === lvalue.length - 1)) {
return false;
}
break;
}
}
return true;
}

return false;
}

/**
* Produce the differences between two maps, as a map, using a specified diff function.
*
Expand Down
113 changes: 113 additions & 0 deletions packages/@aws-cdk/cloudformation-diff/test/diff-template.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,116 @@ test('adding and removing quotes from a numeric property causes no changes', ()
differences = diffTemplate(newTemplate, currentTemplate);
expect(differences.resources.differenceCount).toBe(0);
});

test('single element arrays are equivalent to the single element in DependsOn expressions', () => {
// GIVEN
const currentTemplate = {
Resources: {
BucketResource: {
Type: 'AWS::S3::Bucket',
DependsOn: ['SomeResource'],
},
},
};

// WHEN
const newTemplate = {
Resources: {
BucketResource: {
Type: 'AWS::S3::Bucket',
DependsOn: 'SomeResource',
},
},
};

let differences = diffTemplate(currentTemplate, newTemplate);
expect(differences.resources.differenceCount).toBe(0);

differences = diffTemplate(newTemplate, currentTemplate);
expect(differences.resources.differenceCount).toBe(0);
});


test('array equivalence is independent of element order in DependsOn expressions', () => {
// GIVEN
const currentTemplate = {
Resources: {
BucketResource: {
Type: 'AWS::S3::Bucket',
DependsOn: ['SomeResource', 'AnotherResource'],
},
},
};

// WHEN
const newTemplate = {
Resources: {
BucketResource: {
Type: 'AWS::S3::Bucket',
DependsOn: ['AnotherResource', 'SomeResource'],
},
},
};

let differences = diffTemplate(currentTemplate, newTemplate);
expect(differences.resources.differenceCount).toBe(0);

differences = diffTemplate(newTemplate, currentTemplate);
expect(differences.resources.differenceCount).toBe(0);
});

test('arrays of different length are considered unequal in DependsOn expressions', () => {
// GIVEN
const currentTemplate = {
Resources: {
BucketResource: {
Type: 'AWS::S3::Bucket',
DependsOn: ['SomeResource', 'AnotherResource', 'LastResource'],
},
},
};

// WHEN
const newTemplate = {
Resources: {
BucketResource: {
Type: 'AWS::S3::Bucket',
DependsOn: ['AnotherResource', 'SomeResource'],
},
},
};

let differences = diffTemplate(currentTemplate, newTemplate);
expect(differences.resources.differenceCount).toBe(1);

differences = diffTemplate(newTemplate, currentTemplate);
expect(differences.resources.differenceCount).toBe(1);
});

test('arrays that differ only in element order are considered unequal outside of DependsOn expressions', () => {
// GIVEN
const currentTemplate = {
Resources: {
BucketResource: {
Type: 'AWS::S3::Bucket',
BucketName: { 'Fn::Select': [0, ['name1', 'name2']] },
},
},
};

// WHEN
const newTemplate = {
Resources: {
BucketResource: {
Type: 'AWS::S3::Bucket',
BucketName: { 'Fn::Select': [0, ['name2', 'name1']] },
},
},
};

let differences = diffTemplate(currentTemplate, newTemplate);
expect(differences.resources.differenceCount).toBe(1);

differences = diffTemplate(newTemplate, currentTemplate);
expect(differences.resources.differenceCount).toBe(1);
});