diff --git a/packages/@aws-cdk/assets/test/fs/test.fs-fingerprint.ts b/packages/@aws-cdk/assets/test/fs/test.fs-fingerprint.ts index 87cf001562055..8d4f76ce617d4 100644 --- a/packages/@aws-cdk/assets/test/fs/test.fs-fingerprint.ts +++ b/packages/@aws-cdk/assets/test/fs/test.fs-fingerprint.ts @@ -2,107 +2,157 @@ import fs = require('fs'); import { Test } from 'nodeunit'; import os = require('os'); import path = require('path'); -import { copyDirectory } from '../../lib/fs/copy'; -import { fingerprint } from '../../lib/fs/fingerprint'; +import libfs = require('../../lib/fs'); export = { - 'single file'(test: Test) { - // GIVEN - const workdir = fs.mkdtempSync(path.join(os.tmpdir(), 'hash-tests')); - const content = 'Hello, world!'; - const input1 = path.join(workdir, 'input1.txt'); - const input2 = path.join(workdir, 'input2.txt'); - const input3 = path.join(workdir, 'input3.txt'); - fs.writeFileSync(input1, content); - fs.writeFileSync(input2, content); - fs.writeFileSync(input3, content + '.'); // add one character, hash should be different - - // WHEN - const hash1 = fingerprint(input1); - const hash2 = fingerprint(input2); - const hash3 = fingerprint(input3); - - // THEN - test.deepEqual(hash1, hash2); - test.notDeepEqual(hash3, hash1); - test.done(); + files: { + 'does not change with the file name'(test: Test) { + // GIVEN + const workdir = fs.mkdtempSync(path.join(os.tmpdir(), 'hash-tests')); + const content = 'Hello, world!'; + const input1 = path.join(workdir, 'input1.txt'); + const input2 = path.join(workdir, 'input2.txt'); + const input3 = path.join(workdir, 'input3.txt'); + fs.writeFileSync(input1, content); + fs.writeFileSync(input2, content); + fs.writeFileSync(input3, content + '.'); // add one character, hash should be different + + // WHEN + const hash1 = libfs.fingerprint(input1); + const hash2 = libfs.fingerprint(input2); + const hash3 = libfs.fingerprint(input3); + + // THEN + test.deepEqual(hash1, hash2); + test.notDeepEqual(hash3, hash1); + test.done(); + }, + + 'works on empty files'(test: Test) { + // GIVEN + const workdir = fs.mkdtempSync(path.join(os.tmpdir(), 'hash-tests')); + const input1 = path.join(workdir, 'empty'); + const input2 = path.join(workdir, 'empty'); + fs.writeFileSync(input1, ''); + fs.writeFileSync(input2, ''); + + // WHEN + const hash1 = libfs.fingerprint(input1); + const hash2 = libfs.fingerprint(input2); + + // THEN + test.deepEqual(hash1, hash2); + test.done(); + }, }, - 'empty file'(test: Test) { - // GIVEN - const workdir = fs.mkdtempSync(path.join(os.tmpdir(), 'hash-tests')); - const input1 = path.join(workdir, 'empty'); - const input2 = path.join(workdir, 'empty'); - fs.writeFileSync(input1, ''); - fs.writeFileSync(input2, ''); - - // WHEN - const hash1 = fingerprint(input1); - const hash2 = fingerprint(input2); - - // THEN - test.deepEqual(hash1, hash2); - test.done(); + directories: { + 'works on directories'(test: Test) { + // GIVEN + const srcdir = path.join(__dirname, 'fixtures', 'symlinks'); + const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'copy-tests')); + libfs.copyDirectory(srcdir, outdir); + + // WHEN + const hashSrc = libfs.fingerprint(srcdir); + const hashCopy = libfs.fingerprint(outdir); + + // THEN + test.deepEqual(hashSrc, hashCopy); + test.done(); + }, + + 'ignores requested files'(test: Test) { + // GIVEN + const srcdir = path.join(__dirname, 'fixtures', 'symlinks'); + const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'copy-tests')); + libfs.copyDirectory(srcdir, outdir); + + // WHEN + const hashSrc = libfs.fingerprint(srcdir); + + fs.writeFileSync(path.join(outdir, `${hashSrc}.ignoreme`), 'Ignore me!'); + const hashCopy = libfs.fingerprint(outdir, { exclude: ['*.ignoreme'] }); + + // THEN + test.deepEqual(hashSrc, hashCopy); + test.done(); + }, + + 'changes with file names'(test: Test) { + // GIVEN + const srcdir = path.join(__dirname, 'fixtures', 'symlinks'); + const cpydir = fs.mkdtempSync(path.join(os.tmpdir(), 'fingerprint-tests')); + libfs.copyDirectory(srcdir, cpydir); + + // be careful not to break a symlink + fs.renameSync(path.join(cpydir, 'normal-dir', 'file-in-subdir.txt'), path.join(cpydir, 'move-me.txt')); + + // WHEN + const hashSrc = libfs.fingerprint(srcdir); + const hashCopy = libfs.fingerprint(cpydir); + + // THEN + test.notDeepEqual(hashSrc, hashCopy); + test.done(); + }, }, - 'directory'(test: Test) { - // GIVEN - const srcdir = path.join(__dirname, 'fixtures', 'symlinks'); - const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'copy-tests')); - copyDirectory(srcdir, outdir); - - // WHEN - const hashSrc = fingerprint(srcdir); - const hashCopy = fingerprint(outdir); - - // THEN - test.deepEqual(hashSrc, hashCopy); - test.done(); - }, - - 'directory, rename files (fingerprint should change)'(test: Test) { - // GIVEN - const srcdir = path.join(__dirname, 'fixtures', 'symlinks'); - const cpydir = fs.mkdtempSync(path.join(os.tmpdir(), 'fingerprint-tests')); - copyDirectory(srcdir, cpydir); - - // be careful not to break a symlink - fs.renameSync(path.join(cpydir, 'normal-dir', 'file-in-subdir.txt'), path.join(cpydir, 'move-me.txt')); - - // WHEN - const hashSrc = fingerprint(srcdir); - const hashCopy = fingerprint(cpydir); - - // THEN - test.notDeepEqual(hashSrc, hashCopy); - test.done(); - }, - - 'external symlink content changes (fingerprint should change)'(test: Test) { - // GIVEN - const dir1 = fs.mkdtempSync(path.join(os.tmpdir(), 'fingerprint-tests')); - const dir2 = fs.mkdtempSync(path.join(os.tmpdir(), 'fingerprint-tests')); - const target = path.join(dir1, 'boom.txt'); - const content = 'boom'; - fs.writeFileSync(target, content); - fs.symlinkSync(target, path.join(dir2, 'link-to-boom.txt')); - - // now dir2 contains a symlink to a file in dir1 - - // WHEN - const original = fingerprint(dir2); - - // now change the contents of the target - fs.writeFileSync(target, 'changning you!'); - const afterChange = fingerprint(dir2); - - // revert the content to original and expect hash to be reverted - fs.writeFileSync(target, content); - const afterRevert = fingerprint(dir2); - - // THEN - test.notDeepEqual(original, afterChange); - test.deepEqual(afterRevert, original); - test.done(); + symlinks: { + 'changes with the contents of followed symlink referent'(test: Test) { + // GIVEN + const dir1 = fs.mkdtempSync(path.join(os.tmpdir(), 'fingerprint-tests')); + const dir2 = fs.mkdtempSync(path.join(os.tmpdir(), 'fingerprint-tests')); + const target = path.join(dir1, 'boom.txt'); + const content = 'boom'; + fs.writeFileSync(target, content); + fs.symlinkSync(target, path.join(dir2, 'link-to-boom.txt')); + + // now dir2 contains a symlink to a file in dir1 + + // WHEN + const original = libfs.fingerprint(dir2); + + // now change the contents of the target + fs.writeFileSync(target, 'changning you!'); + const afterChange = libfs.fingerprint(dir2); + + // revert the content to original and expect hash to be reverted + fs.writeFileSync(target, content); + const afterRevert = libfs.fingerprint(dir2); + + // THEN + test.notDeepEqual(original, afterChange); + test.deepEqual(afterRevert, original); + test.done(); + }, + + 'does not change with the contents of un-followed symlink referent'(test: Test) { + // GIVEN + const dir1 = fs.mkdtempSync(path.join(os.tmpdir(), 'fingerprint-tests')); + const dir2 = fs.mkdtempSync(path.join(os.tmpdir(), 'fingerprint-tests')); + const target = path.join(dir1, 'boom.txt'); + const content = 'boom'; + fs.writeFileSync(target, content); + fs.symlinkSync(target, path.join(dir2, 'link-to-boom.txt')); + + // now dir2 contains a symlink to a file in dir1 + + // WHEN + const original = libfs.fingerprint(dir2, { follow: libfs.FollowMode.Never }); + + // now change the contents of the target + fs.writeFileSync(target, 'changning you!'); + const afterChange = libfs.fingerprint(dir2, { follow: libfs.FollowMode.Never }); + + // revert the content to original and expect hash to be reverted + fs.writeFileSync(target, content); + const afterRevert = libfs.fingerprint(dir2, { follow: libfs.FollowMode.Never }); + + // THEN + test.deepEqual(original, afterChange); + test.deepEqual(afterRevert, original); + test.done(); + } } }; diff --git a/packages/@aws-cdk/assets/test/fs/test.utils.ts b/packages/@aws-cdk/assets/test/fs/test.utils.ts new file mode 100644 index 0000000000000..ac42ea75ba29e --- /dev/null +++ b/packages/@aws-cdk/assets/test/fs/test.utils.ts @@ -0,0 +1,92 @@ +import { Test } from 'nodeunit'; +import path = require('path'); +import util = require('../../lib/fs/utils'); +import { FollowMode } from '../../lib/fs'; + +export = { + shouldExclude: { + 'excludes nothing by default'(test: Test) { + test.ok(!util.shouldExclude([], path.join('some', 'file', 'path'))); + test.done(); + }, + + 'excludes requested files'(test: Test) { + const exclusions = ['*.ignored']; + test.ok(util.shouldExclude(exclusions, path.join('some', 'file.ignored'))); + test.ok(!util.shouldExclude(exclusions, path.join('some', 'important', 'file'))); + test.done(); + }, + + 'does not exclude whitelisted files'(test: Test) { + const exclusions = ['*.ignored', '!important.*']; + test.ok(!util.shouldExclude(exclusions, path.join('some', 'important.ignored'))); + test.done(); + }, + }, + + shouldFollow: { + always: { + 'follows internal'(test: Test) { + const sourceRoot = path.join('source', 'root'); + const linkTarget = path.join(sourceRoot, 'referent'); + test.ok(util.shouldFollow(FollowMode.Always, sourceRoot, linkTarget)); + test.done(); + }, + + 'follows external'(test: Test) { + const sourceRoot = path.join('source', 'root'); + const linkTarget = path.join('alternate', 'referent'); + test.ok(util.shouldFollow(FollowMode.Always, sourceRoot, linkTarget)); + test.done(); + }, + }, + + external: { + 'does not follow internal'(test: Test) { + const sourceRoot = path.join('source', 'root'); + const linkTarget = path.join(sourceRoot, 'referent'); + test.ok(!util.shouldFollow(FollowMode.External, sourceRoot, linkTarget)); + test.done(); + }, + + 'follows external'(test: Test) { + const sourceRoot = path.join('source', 'root'); + const linkTarget = path.join('alternate', 'referent'); + test.ok(util.shouldFollow(FollowMode.External, sourceRoot, linkTarget)); + test.done(); + }, + }, + + blockExternal: { + 'follows internal'(test: Test) { + const sourceRoot = path.join('source', 'root'); + const linkTarget = path.join(sourceRoot, 'referent'); + test.ok(!util.shouldFollow(FollowMode.Never, sourceRoot, linkTarget)); + test.done(); + }, + + 'does not follow external'(test: Test) { + const sourceRoot = path.join('source', 'root'); + const linkTarget = path.join('alternate', 'referent'); + test.ok(!util.shouldFollow(FollowMode.BlockExternal, sourceRoot, linkTarget)); + test.done(); + }, + }, + + never: { + 'does not follow internal'(test: Test) { + const sourceRoot = path.join('source', 'root'); + const linkTarget = path.join(sourceRoot, 'referent'); + test.ok(!util.shouldFollow(FollowMode.Never, sourceRoot, linkTarget)); + test.done(); + }, + + 'does not follow external'(test: Test) { + const sourceRoot = path.join('source', 'root'); + const linkTarget = path.join('alternate', 'referent'); + test.ok(!util.shouldFollow(FollowMode.Never, sourceRoot, linkTarget)); + test.done(); + }, + } + }, +};