Skip to content

Commit

Permalink
chore(ecr-assets): migrate image-asset.test.ts to use jest (#13115)
Browse files Browse the repository at this point in the history
Move image-asset.test.ts to use native jest APIs instead of
nodeunitshim.

Motivation
As part of the work for feature flags in v2, it's easier to inject
conditional testing using jest's native APIs than to work with
nodeunitshim.

Nevertheless, we should be using native jest APIs everywhere.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
Niranjan Jayakar authored Feb 17, 2021
1 parent 367a055 commit 33339e1
Showing 1 changed file with 109 additions and 110 deletions.
219 changes: 109 additions & 110 deletions packages/@aws-cdk/aws-ecr-assets/test/image-asset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import * as iam from '@aws-cdk/aws-iam';
import * as cxschema from '@aws-cdk/cloud-assembly-schema';
import { App, DefaultStackSynthesizer, IgnoreMode, Lazy, LegacyStackSynthesizer, Stack, Stage } from '@aws-cdk/core';
import * as cxapi from '@aws-cdk/cx-api';
import { nodeunitShim, Test } from 'nodeunit-shim';
import { DockerImageAsset } from '../lib';

/* eslint-disable quote-props */
Expand All @@ -24,8 +23,8 @@ beforeEach(() => {
stack = new Stack(app, 'Stack');
});

nodeunitShim({
'test instantiating Asset Image'(test: Test) {
describe('image asset', () => {
test('test instantiating Asset Image', () => {
// WHEN
new DockerImageAsset(stack, 'Image', {
directory: path.join(__dirname, 'demo-image'),
Expand All @@ -34,8 +33,8 @@ nodeunitShim({
// THEN
const asm = app.synth();
const artifact = asm.getStackArtifact(stack.artifactId);
test.deepEqual(artifact.template, {}, 'template is empty');
test.deepEqual(artifact.assets, [
expect(artifact.template).toEqual({});
expect(artifact.assets).toEqual([
{
repositoryName: 'aws-cdk/assets',
imageTag: 'b2c69bfbfe983b634456574587443159b3b7258849856a118ad3d2772238f1a5',
Expand All @@ -45,10 +44,10 @@ nodeunitShim({
sourceHash: 'b2c69bfbfe983b634456574587443159b3b7258849856a118ad3d2772238f1a5',
},
]);
test.done();
},

'with build args'(test: Test) {
});

test('with build args', () => {
// WHEN
new DockerImageAsset(stack, 'Image', {
directory: path.join(__dirname, 'demo-image'),
Expand All @@ -59,11 +58,11 @@ nodeunitShim({

// THEN
const assetMetadata = stack.node.metadata.find(({ type }) => type === cxschema.ArtifactMetadataEntryType.ASSET);
test.deepEqual(assetMetadata && (assetMetadata.data as cxschema.ContainerImageAssetMetadataEntry).buildArgs, { a: 'b' });
test.done();
},
expect(assetMetadata && (assetMetadata.data as cxschema.ContainerImageAssetMetadataEntry).buildArgs).toEqual({ a: 'b' });

'with target'(test: Test) {
});

test('with target', () => {
// WHEN
new DockerImageAsset(stack, 'Image', {
directory: path.join(__dirname, 'demo-image'),
Expand All @@ -75,11 +74,11 @@ nodeunitShim({

// THEN
const assetMetadata = stack.node.metadata.find(({ type }) => type === cxschema.ArtifactMetadataEntryType.ASSET);
test.deepEqual(assetMetadata && (assetMetadata.data as cxschema.ContainerImageAssetMetadataEntry).target, 'a-target');
test.done();
},
expect(assetMetadata && (assetMetadata.data as cxschema.ContainerImageAssetMetadataEntry).target).toEqual('a-target');

});

'with file'(test: Test) {
test('with file', () => {
// GIVEN
const directoryPath = path.join(__dirname, 'demo-image-custom-docker-file');
// WHEN
Expand All @@ -90,11 +89,11 @@ nodeunitShim({

// THEN
const assetMetadata = stack.node.metadata.find(({ type }) => type === cxschema.ArtifactMetadataEntryType.ASSET);
test.deepEqual(assetMetadata && (assetMetadata.data as cxschema.ContainerImageAssetMetadataEntry).file, 'Dockerfile.Custom');
test.done();
},
expect(assetMetadata && (assetMetadata.data as cxschema.ContainerImageAssetMetadataEntry).file).toEqual('Dockerfile.Custom');

});

'asset.repository.grantPull can be used to grant a principal permissions to use the image'(test: Test) {
test('asset.repository.grantPull can be used to grant a principal permissions to use the image', () => {
// GIVEN
const user = new iam.User(stack, 'MyUser');
const asset = new DockerImageAsset(stack, 'Image', {
Expand Down Expand Up @@ -152,123 +151,123 @@ nodeunitShim({
],
}));

test.done();
},

'fails if the directory does not exist'(test: Test) {
});

test('fails if the directory does not exist', () => {
// THEN
test.throws(() => {
expect(() => {
new DockerImageAsset(stack, 'MyAsset', {
directory: `/does/not/exist/${Math.floor(Math.random() * 9999)}`,
});
}, /Cannot find image directory at/);
test.done();
},
}).toThrow(/Cannot find image directory at/);

'fails if the directory does not contain a Dockerfile'(test: Test) {
});

test('fails if the directory does not contain a Dockerfile', () => {
// THEN
test.throws(() => {
expect(() => {
new DockerImageAsset(stack, 'Asset', {
directory: __dirname,
});
}, /Cannot find file at/);
test.done();
},
}).toThrow(/Cannot find file at/);

'fails if the file does not exist'(test: Test) {
});

test('fails if the file does not exist', () => {
// THEN
test.throws(() => {
expect(() => {
new DockerImageAsset(stack, 'Asset', {
directory: __dirname,
file: 'doesnt-exist',
});
}, /Cannot find file at/);
test.done();
},
}).toThrow(/Cannot find file at/);

'docker directory is staged if asset staging is enabled'(test: Test) {
});

test('docker directory is staged if asset staging is enabled', () => {
const image = new DockerImageAsset(stack, 'MyAsset', {
directory: path.join(__dirname, 'demo-image'),
});

const session = app.synth();

test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py')));
test.done();
},
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py'))).toBeDefined();

'docker directory is staged without files specified in .dockerignore'(test: Test) {
testDockerDirectoryIsStagedWithoutFilesSpecifiedInDockerignore(test);
},
});

'docker directory is staged without files specified in .dockerignore with IgnoreMode.GLOB'(test: Test) {
testDockerDirectoryIsStagedWithoutFilesSpecifiedInDockerignore(test, IgnoreMode.GLOB);
},
test('docker directory is staged without files specified in .dockerignore', () => {
testDockerDirectoryIsStagedWithoutFilesSpecifiedInDockerignore();
});

'docker directory is staged with whitelisted files specified in .dockerignore'(test: Test) {
test('docker directory is staged without files specified in .dockerignore with IgnoreMode.GLOB', () => {
testDockerDirectoryIsStagedWithoutFilesSpecifiedInDockerignore(IgnoreMode.GLOB);
});

test('docker directory is staged with whitelisted files specified in .dockerignore', () => {
const image = new DockerImageAsset(stack, 'MyAsset', {
directory: path.join(__dirname, 'whitelisted-image'),
});

const session = app.synth();

// Only the files exempted above should be included.
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, '.dockerignore')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'foobar.txt')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory', 'baz.txt')));
test.ok(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules')));
test.ok(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules', 'one')));
test.ok(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules', 'some_dep')));
test.ok(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules', 'some_dep', 'file')));

test.done();
},

'docker directory is staged without files specified in exclude option'(test: Test) {
testDockerDirectoryIsStagedWithoutFilesSpecifiedInExcludeOption(test);
},

'docker directory is staged without files specified in exclude option with IgnoreMode.GLOB'(test: Test) {
testDockerDirectoryIsStagedWithoutFilesSpecifiedInExcludeOption(test, IgnoreMode.GLOB);
},

'fails if using tokens in build args keys or values'(test: Test) {
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, '.dockerignore'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'foobar.txt'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory', 'baz.txt'))).toBeDefined();
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules'))).toBeDefined();
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules', 'one'))).toBeDefined();
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules', 'some_dep'))).toBeDefined();
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules', 'some_dep', 'file'))).toBeDefined();


});

test('docker directory is staged without files specified in exclude option', () => {
testDockerDirectoryIsStagedWithoutFilesSpecifiedInExcludeOption();
});

test('docker directory is staged without files specified in exclude option with IgnoreMode.GLOB', () => {
testDockerDirectoryIsStagedWithoutFilesSpecifiedInExcludeOption(IgnoreMode.GLOB);
});

test('fails if using tokens in build args keys or values', () => {
// GIVEN
const token = Lazy.string({ produce: () => 'foo' });
const expected = /Cannot use tokens in keys or values of "buildArgs" since they are needed before deployment/;

// THEN
test.throws(() => new DockerImageAsset(stack, 'MyAsset1', {
expect(() => new DockerImageAsset(stack, 'MyAsset1', {
directory: path.join(__dirname, 'demo-image'),
buildArgs: { [token]: 'value' },
}), expected);
})).toThrow(expected);

test.throws(() => new DockerImageAsset(stack, 'MyAsset2', {
expect(() => new DockerImageAsset(stack, 'MyAsset2', {
directory: path.join(__dirname, 'demo-image'),
buildArgs: { key: token },
}), expected);
})).toThrow(expected);

test.done();
},

'fails if using token as repositoryName'(test: Test) {
});

test('fails if using token as repositoryName', () => {
// GIVEN
const token = Lazy.string({ produce: () => 'foo' });

// THEN
test.throws(() => new DockerImageAsset(stack, 'MyAsset1', {
expect(() => new DockerImageAsset(stack, 'MyAsset1', {
directory: path.join(__dirname, 'demo-image'),
repositoryName: token,
}), /Cannot use Token as value of 'repositoryName'/);
})).toThrow(/Cannot use Token as value of 'repositoryName'/);

test.done();
},

'docker build options are included in the asset id'(test: Test) {
});

test('docker build options are included in the asset id', () => {
// GIVEN
const directory = path.join(__dirname, 'demo-image-custom-docker-file');

Expand All @@ -280,18 +279,18 @@ nodeunitShim({
const asset6 = new DockerImageAsset(stack, 'Asset6', { directory, extraHash: 'random-extra' });
const asset7 = new DockerImageAsset(stack, 'Asset7', { directory, repositoryName: 'foo' });

test.deepEqual(asset1.sourceHash, 'ab01ecd4419f59e1ec0ac9e57a60dbb653be68a29af0223fa8cb24b4b747bc73');
test.deepEqual(asset2.sourceHash, '7fb12f6148098e3f5c56c788a865d2af689125ead403b795fe6a262ec34384b3');
test.deepEqual(asset3.sourceHash, 'fc3b6d802ba198ba2ee55079dbef27682bcd1288d5849eb5bbd5cd69038359b3');
test.deepEqual(asset4.sourceHash, '30439ea6dfeb4ddfd9175097286895c78393ef52a78c68f92db08abc4513cad6');
test.deepEqual(asset5.sourceHash, '5775170880e26ba31799745241b90d4340c674bb3b1c01d758e416ee3f1c386f');
test.deepEqual(asset6.sourceHash, 'ba82fd351a4d3e3f5c5d948b9948e7e829badc3da90f97e00bb7724afbeacfd4');
test.deepEqual(asset7.sourceHash, '26ec194928431cab6ec5af24ea9f01af2cf7b20e361128b07b2a7405d2951f95');
test.done();
},
expect(asset1.sourceHash).toEqual('ab01ecd4419f59e1ec0ac9e57a60dbb653be68a29af0223fa8cb24b4b747bc73');
expect(asset2.sourceHash).toEqual('7fb12f6148098e3f5c56c788a865d2af689125ead403b795fe6a262ec34384b3');
expect(asset3.sourceHash).toEqual('fc3b6d802ba198ba2ee55079dbef27682bcd1288d5849eb5bbd5cd69038359b3');
expect(asset4.sourceHash).toEqual('30439ea6dfeb4ddfd9175097286895c78393ef52a78c68f92db08abc4513cad6');
expect(asset5.sourceHash).toEqual('5775170880e26ba31799745241b90d4340c674bb3b1c01d758e416ee3f1c386f');
expect(asset6.sourceHash).toEqual('ba82fd351a4d3e3f5c5d948b9948e7e829badc3da90f97e00bb7724afbeacfd4');
expect(asset7.sourceHash).toEqual('26ec194928431cab6ec5af24ea9f01af2cf7b20e361128b07b2a7405d2951f95');

});
});

function testDockerDirectoryIsStagedWithoutFilesSpecifiedInDockerignore(test: Test, ignoreMode?: IgnoreMode) {
function testDockerDirectoryIsStagedWithoutFilesSpecifiedInDockerignore(ignoreMode?: IgnoreMode) {
const image = new DockerImageAsset(stack, 'MyAsset', {
ignoreMode,
directory: path.join(__dirname, 'dockerignore-image'),
Expand All @@ -300,17 +299,17 @@ function testDockerDirectoryIsStagedWithoutFilesSpecifiedInDockerignore(test: Te
const session = app.synth();

// .dockerignore itself should be included in output to be processed during docker build
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, '.dockerignore')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py')));
test.ok(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'foobar.txt')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory', 'baz.txt')));

test.done();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, '.dockerignore'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py'))).toBeDefined();
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'foobar.txt'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory', 'baz.txt'))).toBeDefined();


}

function testDockerDirectoryIsStagedWithoutFilesSpecifiedInExcludeOption(test: Test, ignoreMode?: IgnoreMode) {
function testDockerDirectoryIsStagedWithoutFilesSpecifiedInExcludeOption(ignoreMode?: IgnoreMode) {
const image = new DockerImageAsset(stack, 'MyAsset', {
directory: path.join(__dirname, 'dockerignore-image'),
exclude: ['subdirectory'],
Expand All @@ -319,14 +318,14 @@ function testDockerDirectoryIsStagedWithoutFilesSpecifiedInExcludeOption(test: T

const session = app.synth();

test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, '.dockerignore')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile')));
test.ok(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py')));
test.ok(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'foobar.txt')));
test.ok(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory')));
test.ok(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory', 'baz.txt')));
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, '.dockerignore'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile'))).toBeDefined();
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py'))).toBeDefined();
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'foobar.txt'))).toBeDefined();
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory'))).toBeDefined();
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory', 'baz.txt'))).toBeDefined();


test.done();
}

test('nested assemblies share assets: legacy synth edition', () => {
Expand Down

0 comments on commit 33339e1

Please sign in to comment.