Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
SankyRed committed Feb 8, 2024
1 parent 55ca09c commit 8f4b1ef
Showing 1 changed file with 182 additions and 35 deletions.
217 changes: 182 additions & 35 deletions packages/aws-cdk/test/workflows.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { instanceMockFrom, MockCloudExecutable, TestStackArtifact } from './util
import { MockSdkProvider } from './util/mock-sdk';
import { Bootstrapper } from '../lib/api/bootstrap';
import { Deployments } from '../lib/api/deployments';
import { CdkToolkit, Tag } from '../lib/cdk-toolkit';
import { CdkToolkit } from '../lib/cdk-toolkit';
import { listWorkflow } from '../lib/workflows';

let cloudExecutable: MockCloudExecutable;
Expand All @@ -24,16 +24,13 @@ beforeEach(() => {
});

describe('list', () => {
test('list stacks with no dependencies', async () => {
test('stacks with no dependencies', async () => {
// GIVEN
const toolkit = new CdkToolkit({
cloudExecutable,
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: new FakeCloudFormation({
'Test-Stack-A': { Foo: 'Bar' },
'Test-Stack-B': { Baz: 'Zinga!' },
}),
deployments: new Deployments({ sdkProvider: new MockSdkProvider() }),
});

// WHEN
Expand Down Expand Up @@ -62,7 +59,7 @@ describe('list', () => {
}]);
});

test('list stacks with dependent stacks', async () => {
test('stacks with dependent stacks', async () => {
// GIVEN
const toolkit = new CdkToolkit({
cloudExecutable: new MockCloudExecutable({
Expand All @@ -76,9 +73,6 @@ describe('list', () => {
'/Test-Stack-B': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
data: [
{ key: 'Baz', value: 'Zinga!' },
],
},
],
},
Expand All @@ -88,10 +82,7 @@ describe('list', () => {
}),
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: new FakeCloudFormation({
'Test-Stack-A': { Foo: 'Bar' },
'Test-Stack-B': { Baz: 'Zinga!' },
}),
deployments: new Deployments({ sdkProvider: new MockSdkProvider() }),
});

// WHEN
Expand Down Expand Up @@ -122,6 +113,162 @@ describe('list', () => {
}],
}]);
});

test('stacks with nested dependencies', async () => {
// GIVEN
const toolkit = new CdkToolkit({
cloudExecutable: new MockCloudExecutable({
stacks: [
MockStack.MOCK_STACK_A,
{
stackName: 'Test-Stack-B',
template: { Resources: { TemplateName: 'Test-Stack-B' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-B': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-A'],
},
{
stackName: 'Test-Stack-C',
template: { Resources: { TemplateName: 'Test-Stack-B' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-B': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-B'],
},
],
}),
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: new Deployments({ sdkProvider: new MockSdkProvider() }),
});

// WHEN
const workflow = await listWorkflow( toolkit, { selectors: ['Test-Stack-A', 'Test-Stack-B', 'Test-Stack-C'] });

// THEN
expect(JSON.parse(workflow)).toEqual([{
id: 'Test-Stack-A',
name: 'Test-Stack-A',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [],
},
{
id: 'Test-Stack-B',
name: 'Test-Stack-B',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [{
id: 'Test-Stack-A',
dependencies: [],
}],
},
{
id: 'Test-Stack-C',
name: 'Test-Stack-C',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [{
id: 'Test-Stack-B',
dependencies: [{
id: 'Test-Stack-A',
dependencies: [],
}],
}],
}]);
});

// In the context of stacks with cross-stack or cross-region references,
// the dependency mechanism is responsible for appropriately applying dependencies at the correct hierarchy level,
// typically at the top-level stacks.
// This involves handling the establishment of cross-references between stacks or nested stacks
// and generating assets for nested stack templates as necessary.
test('stacks with cross stack referencing', async () => {
// GIVEN
const toolkit = new CdkToolkit({
cloudExecutable: new MockCloudExecutable({
stacks: [
{
stackName: 'Test-Stack-A',
template: {
Resources: {
MyBucket1Reference: {
Type: 'AWS::CloudFormation::Stack',
Properties: {
TemplateURL: 'XXXXXXXXXXXXXXXXXXXXXXXXX',
Parameters: {
BucketName: { 'Fn::GetAtt': ['MyBucket1', 'Arn'] },
},
},
},
},
},
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-A': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-C'],
},
MockStack.MOCK_STACK_C,
],
}),
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: new Deployments({ sdkProvider: new MockSdkProvider() }),
});

// WHEN
const workflow = await listWorkflow( toolkit, { selectors: ['Test-Stack-A', 'Test-Stack-C'] });

// THEN
expect(JSON.parse(workflow)).toEqual([{
id: 'Test-Stack-C',
name: 'Test-Stack-C',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [],
},
{
id: 'Test-Stack-A',
name: 'Test-Stack-A',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [{
id: 'Test-Stack-C',
dependencies: [],
}],
}]);
});
});

class MockStack {
Expand All @@ -133,9 +280,6 @@ class MockStack {
'/Test-Stack-A': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
data: [
{ key: 'Foo', value: 'Bar' },
],
},
],
},
Expand All @@ -149,27 +293,30 @@ class MockStack {
'/Test-Stack-B': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
data: [
{ key: 'Baz', value: 'Zinga!' },
],
},
],
},
};
}

class FakeCloudFormation extends Deployments {
private readonly expectedTags: { [stackName: string]: Tag[] } = {};

constructor(
expectedTags: { [stackName: string]: { [key: string]: string } } = {},
) {
super({ sdkProvider: new MockSdkProvider() });

for (const [stackName, tags] of Object.entries(expectedTags)) {
this.expectedTags[stackName] =
Object.entries(tags).map(([Key, Value]) => ({ Key, Value }))
.sort((l, r) => l.Key.localeCompare(r.Key));
}
public static readonly MOCK_STACK_C: TestStackArtifact = {
stackName: 'Test-Stack-C',
template: {
Resources: {
MyBucket1: {
Type: 'AWS::S3::Bucket',
Properties: {
AccessControl: 'PublicRead',
},
DeletionPolicy: 'Retain',
},
},
},
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-C': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
}
}

0 comments on commit 8f4b1ef

Please sign in to comment.