aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
127 lines • 21.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable import/order */
const path = require("path");
const timers_1 = require("timers");
const util_1 = require("util");
const fs = require("fs-extra");
const os = require("os");
const sinon = require("sinon");
const logging = require("../../lib/logging");
const npm = require("../../lib/cli/util/npm");
const version_1 = require("../../lib/cli/version");
jest.setTimeout(10000);
const setTimeout = (0, util_1.promisify)(timers_1.setTimeout);
function tmpfile() {
return `/tmp/version-${Math.floor(Math.random() * 10000)}`;
}
beforeEach(() => {
process.chdir(os.tmpdir()); // Need a chdir because in the workspace 'npm view' will take a long time
});
afterEach(done => {
sinon.restore();
done();
});
test('initialization fails on unwritable directory', () => {
const cacheFile = tmpfile();
sinon.stub(fs, 'mkdirsSync').withArgs(path.dirname(cacheFile)).throws('Cannot make directory');
expect(() => new version_1.VersionCheckTTL(cacheFile)).toThrow(/not writable/);
});
test('cache file responds correctly when file is not present', async () => {
const cache = new version_1.VersionCheckTTL(tmpfile(), 1);
expect(await cache.hasExpired()).toBeTruthy();
});
test('cache file honours the specified TTL', async () => {
const cache = new version_1.VersionCheckTTL(tmpfile(), 1);
await cache.update();
expect(await cache.hasExpired()).toBeFalsy();
await setTimeout(1001); // Just above 1 sec in ms
expect(await cache.hasExpired()).toBeTruthy();
});
test('Skip version check if cache has not expired', async () => {
const cache = new version_1.VersionCheckTTL(tmpfile(), 100);
await cache.update();
expect(await (0, version_1.latestVersionIfHigher)('0.0.0', cache)).toBeNull();
});
test('Return later version when exists & skip recent re-check', async () => {
const cache = new version_1.VersionCheckTTL(tmpfile(), 100);
const result = await (0, version_1.latestVersionIfHigher)('0.0.0', cache);
expect(result).not.toBeNull();
expect(result.length).toBeGreaterThan(0);
const result2 = await (0, version_1.latestVersionIfHigher)('0.0.0', cache);
expect(result2).toBeNull();
});
test('Return null if version is higher than npm', async () => {
const cache = new version_1.VersionCheckTTL(tmpfile(), 100);
const result = await (0, version_1.latestVersionIfHigher)('100.100.100', cache);
expect(result).toBeNull();
});
test('Version specified is stored in the TTL file', async () => {
const cacheFile = tmpfile();
const cache = new version_1.VersionCheckTTL(cacheFile, 1);
await cache.update('1.1.1');
const storedVersion = fs.readFileSync(cacheFile, 'utf8');
expect(storedVersion).toBe('1.1.1');
});
test('No Version specified for storage in the TTL file', async () => {
const cacheFile = tmpfile();
const cache = new version_1.VersionCheckTTL(cacheFile, 1);
await cache.update();
const storedVersion = fs.readFileSync(cacheFile, 'utf8');
expect(storedVersion).toBe('');
});
test('Skip version check if environment variable is set', async () => {
sinon.stub(process, 'stdout').value({ ...process.stdout, isTTY: true });
sinon.stub(process, 'env').value({ ...process.env, CDK_DISABLE_VERSION_CHECK: '1' });
const printStub = sinon.stub(logging, 'info');
await (0, version_1.displayVersionMessage)();
expect(printStub.called).toEqual(false);
});
describe('version message', () => {
const previousIsTty = process.stdout.isTTY;
beforeAll(() => {
process.stdout.isTTY = true;
});
afterAll(() => {
process.stdout.isTTY = previousIsTty;
});
test('Prints a message when a new version is available', async () => {
// Given the current version is 1.0.0 and the latest version is 1.1.0
const currentVersion = '1.0.0';
jest.spyOn(npm, 'getLatestVersionFromNpm').mockResolvedValue('1.1.0');
const printSpy = jest.spyOn(logging, 'info');
// When displayVersionMessage is called
await (0, version_1.displayVersionMessage)(currentVersion, new version_1.VersionCheckTTL(tmpfile(), 0));
// Then the new version message is printed to stdout
expect(printSpy).toHaveBeenCalledWith(expect.stringContaining('1.1.0'));
});
test('Includes major upgrade documentation when available', async () => {
// Given the current version is 1.0.0 and the latest version is 2.0.0
const currentVersion = '1.0.0';
jest.spyOn(npm, 'getLatestVersionFromNpm').mockResolvedValue('2.0.0');
const printSpy = jest.spyOn(logging, 'info');
// When displayVersionMessage is called
await (0, version_1.displayVersionMessage)(currentVersion, new version_1.VersionCheckTTL(tmpfile(), 0));
// Then the V1 -> V2 documentation is printed
expect(printSpy).toHaveBeenCalledWith(expect.stringContaining('Information about upgrading from version 1.x to version 2.x is available here: https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html'));
});
test('Does not include major upgrade documentation when unavailable', async () => {
// Given current version is 99.0.0 and the latest version is 100.0.0
const currentVersion = '99.0.0';
jest.spyOn(npm, 'getLatestVersionFromNpm').mockResolvedValue('100.0.0');
const printSpy = jest.spyOn(logging, 'info');
// When displayVersionMessage is called
await (0, version_1.displayVersionMessage)(currentVersion, new version_1.VersionCheckTTL(tmpfile(), 0));
// Then no upgrade documentation is printed
expect(printSpy).toHaveBeenCalledWith(expect.stringContaining('100.0.0'));
expect(printSpy).not.toHaveBeenCalledWith(expect.stringContaining('Information about upgrading from 99.x to 100.x'));
});
});
test('isDeveloperBuild call does not throw an error', () => {
// To be frank: this is just to shut CodeCov up. It don't want to make an assertion
// that the value is `true` when running tests, because I won't want to make too
// many assumptions for no good reason.
(0, version_1.isDeveloperBuild)();
// THEN: should not explode
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidmVyc2lvbi50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaUNBQWlDO0FBQ2pDLDZCQUE2QjtBQUM3QixtQ0FBbUQ7QUFDbkQsK0JBQWlDO0FBQ2pDLCtCQUErQjtBQUMvQix5QkFBeUI7QUFDekIsK0JBQStCO0FBQy9CLDZDQUE2QztBQUM3Qyw4Q0FBOEM7QUFDOUMsbURBQXdIO0FBRXhILElBQUksQ0FBQyxVQUFVLENBQUMsS0FBTSxDQUFDLENBQUM7QUFFeEIsTUFBTSxVQUFVLEdBQUcsSUFBQSxnQkFBUyxFQUFDLG1CQUFXLENBQUMsQ0FBQztBQUUxQyxTQUFTLE9BQU87SUFDZCxPQUFPLGdCQUFnQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDO0FBQzdELENBQUM7QUFFRCxVQUFVLENBQUMsR0FBRyxFQUFFO0lBQ2QsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLHlFQUF5RTtBQUN2RyxDQUFDLENBQUMsQ0FBQztBQUVILFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRTtJQUNmLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNoQixJQUFJLEVBQUUsQ0FBQztBQUNULENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLDhDQUE4QyxFQUFFLEdBQUcsRUFBRTtJQUN4RCxNQUFNLFNBQVMsR0FBRyxPQUFPLEVBQUUsQ0FBQztJQUM1QixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQy9GLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLHlCQUFlLENB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QixHQUFFLENBQUM7SUFFbkIsMkJBQTJCO0FBQzdCLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L29yZGVyICovXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgc2V0VGltZW91dCBhcyBfc2V0VGltZW91dCB9IGZyb20gJ3RpbWVycyc7XG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICd1dGlsJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCAqIGFzIG9zIGZyb20gJ29zJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCAqIGFzIGxvZ2dpbmcgZnJvbSAnLi4vLi4vbGliL2xvZ2dpbmcnO1xuaW1wb3J0ICogYXMgbnBtIGZyb20gJy4uLy4uL2xpYi9jbGkvdXRpbC9ucG0nO1xuaW1wb3J0IHsgbGF0ZXN0VmVyc2lvbklmSGlnaGVyLCBWZXJzaW9uQ2hlY2tUVEwsIGRpc3BsYXlWZXJzaW9uTWVzc2FnZSwgaXNEZXZlbG9wZXJCdWlsZCB9IGZyb20gJy4uLy4uL2xpYi9jbGkvdmVyc2lvbic7XG5cbmplc3Quc2V0VGltZW91dCgxMF8wMDApO1xuXG5jb25zdCBzZXRUaW1lb3V0ID0gcHJvbWlzaWZ5KF9zZXRUaW1lb3V0KTtcblxuZnVuY3Rpb24gdG1wZmlsZSgpOiBzdHJpbmcge1xuICByZXR1cm4gYC90bXAvdmVyc2lvbi0ke01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEwMDAwKX1gO1xufVxuXG5iZWZvcmVFYWNoKCgpID0+IHtcbiAgcHJvY2Vzcy5jaGRpcihvcy50bXBkaXIoKSk7IC8vIE5lZWQgYSBjaGRpciBiZWNhdXNlIGluIHRoZSB3b3Jrc3BhY2UgJ25wbSB2aWV3JyB3aWxsIHRha2UgYSBsb25nIHRpbWVcbn0pO1xuXG5hZnRlckVhY2goZG9uZSA9PiB7XG4gIHNpbm9uLnJlc3RvcmUoKTtcbiAgZG9uZSgpO1xufSk7XG5cbnRlc3QoJ2luaXRpYWxpemF0aW9uIGZhaWxzIG9uIHVud3JpdGFibGUgZGlyZWN0b3J5JywgKCkgPT4ge1xuICBjb25zdCBjYWNoZUZpbGUgPSB0bXBmaWxlKCk7XG4gIHNpbm9uLnN0dWIoZnMsICdta2RpcnNTeW5jJykud2l0aEFyZ3MocGF0aC5kaXJuYW1lKGNhY2hlRmlsZSkpLnRocm93cygnQ2Fubm90IG1ha2UgZGlyZWN0b3J5Jyk7XG4gIGV4cGVjdCgoKSA9PiBuZXcgVmVyc2lvbkNoZWNrVFRMKGNhY2hlRmlsZSkpLnRvVGhyb3coL25vdCB3cml0YWJsZS8pO1xufSk7XG5cbnRlc3QoJ2NhY2hlIGZpbGUgcmVzcG9uZHMgY29ycmVjdGx5IHdoZW4gZmlsZSBpcyBub3QgcHJlc2VudCcsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgY2FjaGUgPSBuZXcgVmVyc2lvbkNoZWNrVFRMKHRtcGZpbGUoKSwgMSk7XG4gIGV4cGVjdChhd2FpdCBjYWNoZS5oYXNFeHBpcmVkKCkpLnRvQmVUcnV0aHkoKTtcbn0pO1xuXG50ZXN0KCdjYWNoZSBmaWxlIGhvbm91cnMgdGhlIHNwZWNpZmllZCBUVEwnLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IGNhY2hlID0gbmV3IFZlcnNpb25DaGVja1RUTCh0bXBmaWxlKCksIDEpO1xuICBhd2FpdCBjYWNoZS51cGRhdGUoKTtcbiAgZXhwZWN0KGF3YWl0IGNhY2hlLmhhc0V4cGlyZWQoKSkudG9CZUZhbHN5KCk7XG4gIGF3YWl0IHNldFRpbWVvdXQoMTAwMSk7IC8vIEp1c3QgYWJvdmUgMSBzZWMgaW4gbXNcbiAgZXhwZWN0KGF3YWl0IGNhY2hlLmhhc0V4cGlyZWQoKSkudG9CZVRydXRoeSgpO1xufSk7XG5cbnRlc3QoJ1NraXAgdmVyc2lvbiBjaGVjayBpZiBjYWNoZSBoYXMgbm90IGV4cGlyZWQnLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IGNhY2hlID0gbmV3IFZlcnNpb25DaGVja1RUTCh0bXBmaWxlKCksIDEwMCk7XG4gIGF3YWl0IGNhY2hlLnVwZGF0ZSgpO1xuICBleHBlY3QoYXdhaXQgbGF0ZXN0VmVyc2lvbklmSGlnaGVyKCcwLjAuMCcsIGNhY2hlKSkudG9CZU51bGwoKTtcbn0pO1xuXG50ZXN0KCdSZXR1cm4gbGF0ZXIgdmVyc2lvbiB3aGVuIGV4aXN0cyAmIHNraXAgcmVjZW50IHJlLWNoZWNrJywgYXN5bmMgKCkgPT4ge1xuICBjb25zdCBjYWNoZSA9IG5ldyBWZXJzaW9uQ2hlY2tUVEwodG1wZmlsZSgpLCAxMDApO1xuICBjb25zdCByZXN1bHQgPSBhd2FpdCBsYXRlc3RWZXJzaW9uSWZIaWdoZXIoJzAuMC4wJywgY2FjaGUpO1xuICBleHBlY3QocmVzdWx0KS5ub3QudG9CZU51bGwoKTtcbiAgZXhwZWN0KChyZXN1bHQgYXMgc3RyaW5nKS5sZW5ndGgpLnRvQmVHcmVhdGVyVGhhbigwKTtcblxuICBjb25zdCByZXN1bHQyID0gYXdhaXQgbGF0ZXN0VmVyc2lvbklmSGlnaGVyKCcwLjAuMCcsIGNhY2hlKTtcbiAgZXhwZWN0KHJlc3VsdDIpLnRvQmVOdWxsKCk7XG59KTtcblxudGVzdCgnUmV0dXJuIG51bGwgaWYgdmVyc2lvbiBpcyBoaWdoZXIgdGhhbiBucG0nLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IGNhY2hlID0gbmV3IFZlcnNpb25DaGVja1RUTCh0bXBmaWxlKCksIDEwMCk7XG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGxhdGVzdFZlcnNpb25JZkhpZ2hlcignMTAwLjEwMC4xMDAnLCBjYWNoZSk7XG4gIGV4cGVjdChyZXN1bHQpLnRvQmVOdWxsKCk7XG59KTtcblxudGVzdCgnVmVyc2lvbiBzcGVjaWZpZWQgaXMgc3RvcmVkIGluIHRoZSBUVEwgZmlsZScsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgY2FjaGVGaWxlID0gdG1wZmlsZSgpO1xuICBjb25zdCBjYWNoZSA9IG5ldyBWZXJzaW9uQ2hlY2tUVEwoY2FjaGVGaWxlLCAxKTtcbiAgYXdhaXQgY2FjaGUudXBkYXRlKCcxLjEuMScpO1xuICBjb25zdCBzdG9yZWRWZXJzaW9uID0gZnMucmVhZEZpbGVTeW5jKGNhY2hlRmlsZSwgJ3V0ZjgnKTtcbiAgZXhwZWN0KHN0b3JlZFZlcnNpb24pLnRvQmUoJzEuMS4xJyk7XG59KTtcblxudGVzdCgnTm8gVmVyc2lvbiBzcGVjaWZpZWQgZm9yIHN0b3JhZ2UgaW4gdGhlIFRUTCBmaWxlJywgYXN5bmMgKCkgPT4ge1xuICBjb25zdCBjYWNoZUZpbGUgPSB0bXBmaWxlKCk7XG4gIGNvbnN0IGNhY2hlID0gbmV3IFZlcnNpb25DaGVja1RUTChjYWNoZUZpbGUsIDEpO1xuICBhd2FpdCBjYWNoZS51cGRhdGUoKTtcbiAgY29uc3Qgc3RvcmVkVmVyc2lvbiA9IGZzLnJlYWRGaWxlU3luYyhjYWNoZUZpbGUsICd1dGY4Jyk7XG4gIGV4cGVjdChzdG9yZWRWZXJzaW9uKS50b0JlKCcnKTtcbn0pO1xuXG50ZXN0KCdTa2lwIHZlcnNpb24gY2hlY2sgaWYgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgc2V0JywgYXN5bmMgKCkgPT4ge1xuICBzaW5vbi5zdHViKHByb2Nlc3MsICdzdGRvdXQnKS52YWx1ZSh7IC4uLnByb2Nlc3Muc3Rkb3V0LCBpc1RUWTogdHJ1ZSB9KTtcbiAgc2lub24uc3R1Yihwcm9jZXNzLCAnZW52JykudmFsdWUoeyAuLi5wcm9jZXNzLmVudiwgQ0RLX0RJU0FCTEVfVkVSU0lPTl9DSEVDSzogJzEnIH0pO1xuICBjb25zdCBwcmludFN0dWIgPSBzaW5vbi5zdHViKGxvZ2dpbmcsICdpbmZvJyk7XG4gIGF3YWl0IGRpc3BsYXlWZXJzaW9uTWVzc2FnZSgpO1xuICBleHBlY3QocHJpbnRTdHViLmNhbGxlZCkudG9FcXVhbChmYWxzZSk7XG59KTtcblxuZGVzY3JpYmUoJ3ZlcnNpb24gbWVzc2FnZScsICgpID0+IHtcbiAgY29uc3QgcHJldmlvdXNJc1R0eSA9IHByb2Nlc3Muc3Rkb3V0LmlzVFRZO1xuICBiZWZvcmVBbGwoKCkgPT4ge1xuICAgIHByb2Nlc3Muc3Rkb3V0LmlzVFRZID0gdHJ1ZTtcbiAgfSk7XG5cbiAgYWZ0ZXJBbGwoKCkgPT4ge1xuICAgIHByb2Nlc3Muc3Rkb3V0LmlzVFRZID0gcHJldmlvdXNJc1R0eTtcbiAgfSk7XG5cbiAgdGVzdCgnUHJpbnRzIGEgbWVzc2FnZSB3aGVuIGEgbmV3IHZlcnNpb24gaXMgYXZhaWxhYmxlJywgYXN5bmMgKCkgPT4ge1xuICAgIC8vIEdpdmVuIHRoZSBjdXJyZW50IHZlcnNpb24gaXMgMS4wLjAgYW5kIHRoZSBsYXRlc3QgdmVyc2lvbiBpcyAxLjEuMFxuICAgIGNvbnN0IGN1cnJlbnRWZXJzaW9uID0gJzEuMC4wJztcbiAgICBqZXN0LnNweU9uKG5wbSwgJ2dldExhdGVzdFZlcnNpb25Gcm9tTnBtJykubW9ja1Jlc29sdmVkVmFsdWUoJzEuMS4wJyk7XG4gICAgY29uc3QgcHJpbnRTcHkgPSBqZXN0LnNweU9uKGxvZ2dpbmcsICdpbmZvJyk7XG5cbiAgICAvLyBXaGVuIGRpc3BsYXlWZXJzaW9uTWVzc2FnZSBpcyBjYWxsZWRcbiAgICBhd2FpdCBkaXNwbGF5VmVyc2lvbk1lc3NhZ2UoY3VycmVudFZlcnNpb24sIG5ldyBWZXJzaW9uQ2hlY2tUVEwodG1wZmlsZSgpLCAwKSk7XG5cbiAgICAvLyBUaGVuIHRoZSBuZXcgdmVyc2lvbiBtZXNzYWdlIGlzIHByaW50ZWQgdG8gc3Rkb3V0XG4gICAgZXhwZWN0KHByaW50U3B5KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChleHBlY3Quc3RyaW5nQ29udGFpbmluZygnMS4xLjAnKSk7XG4gIH0pO1xuXG4gIHRlc3QoJ0luY2x1ZGVzIG1ham9yIHVwZ3JhZGUgZG9jdW1lbnRhdGlvbiB3aGVuIGF2YWlsYWJsZScsIGFzeW5jKCkgPT4ge1xuICAgIC8vIEdpdmVuIHRoZSBjdXJyZW50IHZlcnNpb24gaXMgMS4wLjAgYW5kIHRoZSBsYXRlc3QgdmVyc2lvbiBpcyAyLjAuMFxuICAgIGNvbnN0IGN1cnJlbnRWZXJzaW9uID0gJzEuMC4wJztcbiAgICBqZXN0LnNweU9uKG5wbSwgJ2dldExhdGVzdFZlcnNpb25Gcm9tTnBtJykubW9ja1Jlc29sdmVkVmFsdWUoJzIuMC4wJyk7XG4gICAgY29uc3QgcHJpbnRTcHkgPSBqZXN0LnNweU9uKGxvZ2dpbmcsICdpbmZvJyk7XG5cbiAgICAvLyBXaGVuIGRpc3BsYXlWZXJzaW9uTWVzc2FnZSBpcyBjYWxsZWRcbiAgICBhd2FpdCBkaXNwbGF5VmVyc2lvbk1lc3NhZ2UoY3VycmVudFZlcnNpb24sIG5ldyBWZXJzaW9uQ2hlY2tUVEwodG1wZmlsZSgpLCAwKSk7XG5cbiAgICAvLyBUaGVuIHRoZSBWMSAtPiBWMiBkb2N1bWVudGF0aW9uIGlzIHByaW50ZWRcbiAgICBleHBlY3QocHJpbnRTcHkpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGV4cGVjdC5zdHJpbmdDb250YWluaW5nKCdJbmZvcm1hdGlvbiBhYm91dCB1cGdyYWRpbmcgZnJvbSB2ZXJzaW9uIDEueCB0byB2ZXJzaW9uIDIueCBpcyBhdmFpbGFibGUgaGVyZTogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nkay92Mi9ndWlkZS9taWdyYXRpbmctdjIuaHRtbCcpKTtcbiAgfSk7XG5cbiAgdGVzdCgnRG9lcyBub3QgaW5jbHVkZSBtYWpvciB1cGdyYWRlIGRvY3VtZW50YXRpb24gd2hlbiB1bmF2YWlsYWJsZScsIGFzeW5jKCkgPT4ge1xuICAgIC8vIEdpdmVuIGN1cnJlbnQgdmVyc2lvbiBpcyA5OS4wLjAgYW5kIHRoZSBsYXRlc3QgdmVyc2lvbiBpcyAxMDAuMC4wXG4gICAgY29uc3QgY3VycmVudFZlcnNpb24gPSAnOTkuMC4wJztcbiAgICBqZXN0LnNweU9uKG5wbSwgJ2dldExhdGVzdFZlcnNpb25Gcm9tTnBtJykubW9ja1Jlc29sdmVkVmFsdWUoJzEwMC4wLjAnKTtcbiAgICBjb25zdCBwcmludFNweSA9IGplc3Quc3B5T24obG9nZ2luZywgJ2luZm8nKTtcblxuICAgIC8vIFdoZW4gZGlzcGxheVZlcnNpb25NZXNzYWdlIGlzIGNhbGxlZFxuICAgIGF3YWl0IGRpc3BsYXlWZXJzaW9uTWVzc2FnZShjdXJyZW50VmVyc2lvbiwgbmV3IFZlcnNpb25DaGVja1RUTCh0bXBmaWxlKCksIDApKTtcblxuICAgIC8vIFRoZW4gbm8gdXBncmFkZSBkb2N1bWVudGF0aW9uIGlzIHByaW50ZWRcbiAgICBleHBlY3QocHJpbnRTcHkpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGV4cGVjdC5zdHJpbmdDb250YWluaW5nKCcxMDAuMC4wJykpO1xuICAgIGV4cGVjdChwcmludFNweSkubm90LnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGV4cGVjdC5zdHJpbmdDb250YWluaW5nKCdJbmZvcm1hdGlvbiBhYm91dCB1cGdyYWRpbmcgZnJvbSA5OS54IHRvIDEwMC54JykpO1xuICB9KTtcbn0pO1xuXG50ZXN0KCdpc0RldmVsb3BlckJ1aWxkIGNhbGwgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3InLCAoKSA9PiB7XG4gIC8vIFRvIGJlIGZyYW5rOiB0aGlzIGlzIGp1c3QgdG8gc2h1dCBDb2RlQ292IHVwLiBJdCBkb24ndCB3YW50IHRvIG1ha2UgYW4gYXNzZXJ0aW9uXG4gIC8vIHRoYXQgdGhlIHZhbHVlIGlzIGB0cnVlYCB3aGVuIHJ1bm5pbmcgdGVzdHMsIGJlY2F1c2UgSSB3b24ndCB3YW50IHRvIG1ha2UgdG9vXG4gIC8vIG1hbnkgYXNzdW1wdGlvbnMgZm9yIG5vIGdvb2QgcmVhc29uLlxuXG4gIGlzRGV2ZWxvcGVyQnVpbGQoKTtcblxuICAvLyBUSEVOOiBzaG91bGQgbm90IGV4cGxvZGVcbn0pO1xuIl19