aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
111 lines • 16.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable import/order */
const path = require("path");
const fs = require("fs-extra");
const util_1 = require("./util");
const account_cache_1 = require("../lib/api/aws-auth/account-cache");
async function makeCache() {
const dir = await fs.mkdtemp('/tmp/account-cache-test');
const file = path.join(dir, 'cache.json');
return {
cacheDir: dir,
cacheFile: file,
cache: new account_cache_1.AccountAccessKeyCache(file),
};
}
async function nukeCache(cacheDir) {
await fs.remove(cacheDir);
}
test('default account cache uses CDK_HOME', () => {
process.env.CDK_HOME = '/banana';
const cache = new account_cache_1.AccountAccessKeyCache();
expect(cache.cacheFile).toContain('/banana/');
});
test('account cache does not fail when given a nonwritable directory', async () => {
const accessError = new Error('Oh no');
accessError.code = 'EACCES';
return (0, util_1.withMocked)(fs, 'mkdirs', async (mkdirs) => {
// Have to do this because mkdirs has 2 overloads and it confuses TypeScript
mkdirs.mockRejectedValue(accessError);
const cache = new account_cache_1.AccountAccessKeyCache('/abc/xyz');
await cache.fetch('xyz', () => Promise.resolve({ accountId: 'asdf', partition: 'swa' }));
// No exception
});
});
test('get(k) when cache is empty', async () => {
const { cacheDir, cacheFile, cache } = await makeCache();
try {
expect(await cache.get('foo')).toBeUndefined();
expect(await fs.pathExists(cacheFile)).toBeFalsy();
}
finally {
await nukeCache(cacheDir);
}
});
test('put(k,v) and then get(k)', async () => {
const { cacheDir, cacheFile, cache } = await makeCache();
try {
await cache.put('key', { accountId: 'value', partition: 'aws' });
await cache.put('boo', { accountId: 'bar', partition: 'aws' });
expect(await cache.get('key')).toEqual({ accountId: 'value', partition: 'aws' });
// create another cache instance on the same file, should still work
const cache2 = new account_cache_1.AccountAccessKeyCache(cacheFile);
expect(await cache2.get('boo')).toEqual({ accountId: 'bar', partition: 'aws' });
// whitebox: read the file
expect(await fs.readJson(cacheFile)).toEqual({
key: { accountId: 'value', partition: 'aws' },
boo: { accountId: 'bar', partition: 'aws' },
});
}
finally {
await nukeCache(cacheDir);
}
});
test('fetch(k, resolver) can be used to "atomically" get + resolve + put', async () => {
const { cacheDir, cache } = await makeCache();
try {
expect(await cache.get('foo')).toBeUndefined();
expect(await cache.fetch('foo', async () => ({ accountId: 'bar', partition: 'aws' }))).toEqual({ accountId: 'bar', partition: 'aws' });
expect(await cache.get('foo')).toEqual({ accountId: 'bar', partition: 'aws' });
}
finally {
await nukeCache(cacheDir);
}
});
test(`cache is nuked if it exceeds ${account_cache_1.AccountAccessKeyCache.MAX_ENTRIES} entries`, async () => {
const { cacheDir, cacheFile, cache } = await makeCache();
try {
for (let i = 0; i < account_cache_1.AccountAccessKeyCache.MAX_ENTRIES; ++i) {
await cache.put(`key${i}`, { accountId: `value${i}`, partition: 'aws' });
}
// verify all values are on disk
const otherCache = new account_cache_1.AccountAccessKeyCache(cacheFile);
for (let i = 0; i < account_cache_1.AccountAccessKeyCache.MAX_ENTRIES; ++i) {
expect(await otherCache.get(`key${i}`)).toEqual({ accountId: `value${i}`, partition: 'aws' });
}
// add another value
await cache.put('nuke-me', { accountId: 'genesis', partition: 'aws' });
// now, we expect only `nuke-me` to exist on disk
expect(await otherCache.get('nuke-me')).toEqual({ accountId: 'genesis', partition: 'aws' });
for (let i = 0; i < account_cache_1.AccountAccessKeyCache.MAX_ENTRIES; ++i) {
expect(await otherCache.get(`key${i}`)).toBeUndefined();
}
}
finally {
await nukeCache(cacheDir);
}
},
// This makes a lot of promises, so it can queue for a while...
30000);
test('cache pretends to be empty if cache file does not contain JSON', async () => {
const { cacheDir, cacheFile, cache } = await makeCache();
try {
await fs.writeFile(cacheFile, '');
await expect(cache.get('abc')).resolves.toEqual(undefined);
}
finally {
await nukeCache(cacheDir);
}
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3VudC1jYWNoZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYWNjb3VudC1jYWNoZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaUNBQWlDO0FBQ2pDLDZCQUE2QjtBQUM3QiwrQkFBK0I7QUFDL0IsaUNBQW9DO0FBQ3BDLHFFQUEwRTtBQUUxRSxLQUFLLFVBQVUsU0FBUztJQUN0QixNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMseUJBQXlCLENBQUMsQ0FBQztJQUN4RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUMxQyxPQUFPO1FBQ0wsUUFBUSxFQUFFLEdBQUc7UUFDYixTQUFTLEVBQUUsSUFBSTtRQUNmLEtBQUssRUFBRSxJQUFJLHFDQUFxQixDQUFDLElBQUksQ0FBQztLQUN2QyxDQUFDO0FBQ0osQ0FBQztBQUVELEtBQUssVUFBVSxTQUFTLENBQUMsUUFBZ0I7SUFDdkMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFFRCxJQUFJLENBQUMscUNBQXFDLEVBQUUsR0FBRyxFQUFFO0lBQy9DLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQztJQUNqQyxNQUFNLEtBQUssR0FBRyxJQUFJLHFDQUFxQixFQUFFLENBQUM7SUFDMUMsTUFBTSxDQUFFLEtBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDekQsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsZ0VBQWdFLEVBQUUsS0FBSyxJQUFJLEVBQUU7SUFDaEYsTUFBTSxXQUFXLEdBQUcsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEMsV0FBbUIsQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDO0lBRXJDLE9BQU8sSUFBQSxpQkFB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QyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7S0FDNUQ7WUFBUztRQUNSLE1BQU0sU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0tBQzNCO0FBQ0gsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvb3JkZXIgKi9cbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgeyB3aXRoTW9ja2VkIH0gZnJvbSAnLi91dGlsJztcbmltcG9ydCB7IEFjY291bnRBY2Nlc3NLZXlDYWNoZSB9IGZyb20gJy4uL2xpYi9hcGkvYXdzLWF1dGgvYWNjb3VudC1jYWNoZSc7XG5cbmFzeW5jIGZ1bmN0aW9uIG1ha2VDYWNoZSgpIHtcbiAgY29uc3QgZGlyID0gYXdhaXQgZnMubWtkdGVtcCgnL3RtcC9hY2NvdW50LWNhY2hlLXRlc3QnKTtcbiAgY29uc3QgZmlsZSA9IHBhdGguam9pbihkaXIsICdjYWNoZS5qc29uJyk7XG4gIHJldHVybiB7XG4gICAgY2FjaGVEaXI6IGRpcixcbiAgICBjYWNoZUZpbGU6IGZpbGUsXG4gICAgY2FjaGU6IG5ldyBBY2NvdW50QWNjZXNzS2V5Q2FjaGUoZmlsZSksXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG51a2VDYWNoZShjYWNoZURpcjogc3RyaW5nKSB7XG4gIGF3YWl0IGZzLnJlbW92ZShjYWNoZURpcik7XG59XG5cbnRlc3QoJ2RlZmF1bHQgYWNjb3VudCBjYWNoZSB1c2VzIENES19IT01FJywgKCkgPT4ge1xuICBwcm9jZXNzLmVudi5DREtfSE9NRSA9ICcvYmFuYW5hJztcbiAgY29uc3QgY2FjaGUgPSBuZXcgQWNjb3VudEFjY2Vzc0tleUNhY2hlKCk7XG4gIGV4cGVjdCgoY2FjaGUgYXMgYW55KS5jYWNoZUZpbGUpLnRvQ29udGFpbignL2JhbmFuYS8nKTtcbn0pO1xuXG50ZXN0KCdhY2NvdW50IGNhY2hlIGRvZXMgbm90IGZhaWwgd2hlbiBnaXZlbiBhIG5vbndyaXRhYmxlIGRpcmVjdG9yeScsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgYWNjZXNzRXJyb3IgPSBuZXcgRXJyb3IoJ09oIG5vJyk7XG4gIChhY2Nlc3NFcnJvciBhcyBhbnkpLmNvZGUgPSAnRUFDQ0VTJztcblxuICByZXR1cm4gd2l0aE1vY2tlZChmcywgJ21rZGlycycsIGFzeW5jIChta2RpcnMpID0+IHtcbiAgICAvLyBIYXZlIHRvIGRvIHRoaXMgYmVjYXVzZSBta2RpcnMgaGFzIDIgb3ZlcmxvYWRzIGFuZCBpdCBjb25mdXNlcyBUeXBlU2NyaXB0XG4gICAgKG1rZGlycyBhcyB1bmtub3duIGFzIGplc3QuTW9jazxQcm9taXNlPHZvaWQ+LCBbYW55XT4pLm1vY2tSZWplY3RlZFZhbHVlKGFjY2Vzc0Vycm9yKTtcblxuICAgIGNvbnN0IGNhY2hlID0gbmV3IEFjY291bnRBY2Nlc3NLZXlDYWNoZSgnL2FiYy94eXonKTtcbiAgICBhd2FpdCBjYWNoZS5mZXRjaCgneHl6JywgKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHsgYWNjb3VudElkOiAnYXNkZicsIHBhcnRpdGlvbjogJ3N3YScgfSkpO1xuXG4gICAgLy8gTm8gZXhjZXB0aW9uXG4gIH0pO1xufSk7XG5cbnRlc3QoJ2dldChrKSB3aGVuIGNhY2hlIGlzIGVtcHR5JywgYXN5bmMgKCkgPT4ge1xuICBjb25zdCB7IGNhY2hlRGlyLCBjYWNoZUZpbGUsIGNhY2hlIH0gPSBhd2FpdCBtYWtlQ2FjaGUoKTtcbiAgdHJ5IHtcbiAgICBleHBlY3QoYXdhaXQgY2FjaGUuZ2V0KCdmb28nKSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIGV4cGVjdChhd2FpdCBmcy5wYXRoRXhpc3RzKGNhY2hlRmlsZSkpLnRvQmVGYWxzeSgpO1xuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IG51a2VDYWNoZShjYWNoZURpcik7XG4gIH1cbn0pO1xuXG50ZXN0KCdwdXQoayx2KSBhbmQgdGhlbiBnZXQoayknLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IHsgY2FjaGVEaXIsIGNhY2hlRmlsZSwgY2FjaGUgfSA9IGF3YWl0IG1ha2VDYWNoZSgpO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgY2FjaGUucHV0KCdrZXknLCB7IGFjY291bnRJZDogJ3ZhbHVlJywgcGFydGl0aW9uOiAnYXdzJyB9KTtcbiAgICBhd2FpdCBjYWNoZS5wdXQoJ2JvbycsIHsgYWNjb3VudElkOiAnYmFyJywgcGFydGl0aW9uOiAnYXdzJyB9KTtcbiAgICBleHBlY3QoYXdhaXQgY2FjaGUuZ2V0KCdrZXknKSkudG9FcXVhbCh7IGFjY291bnRJZDogJ3ZhbHVlJywgcGFydGl0aW9uOiAnYXdzJyB9KTtcblxuICAgIC8vIGNyZWF0ZSBhbm90aGVyIGNhY2hlIGluc3RhbmNlIG9uIHRoZSBzYW1lIGZpbGUsIHNob3VsZCBzdGlsbCB3b3JrXG4gICAgY29uc3QgY2FjaGUyID0gbmV3IEFjY291bnRBY2Nlc3NLZXlDYWNoZShjYWNoZUZpbGUpO1xuICAgIGV4cGVjdChhd2FpdCBjYWNoZTIuZ2V0KCdib28nKSkudG9FcXVhbCh7IGFjY291bnRJZDogJ2JhcicsIHBhcnRpdGlvbjogJ2F3cycgfSk7XG5cbiAgICAvLyB3aGl0ZWJveDogcmVhZCB0aGUgZmlsZVxuICAgIGV4cGVjdChhd2FpdCBmcy5yZWFkSnNvbihjYWNoZUZpbGUpKS50b0VxdWFsKHtcbiAgICAgIGtleTogeyBhY2NvdW50SWQ6ICd2YWx1ZScsIHBhcnRpdGlvbjogJ2F3cycgfSxcbiAgICAgIGJvbzogeyBhY2NvdW50SWQ6ICdiYXInLCBwYXJ0aXRpb246ICdhd3MnIH0sXG4gICAgfSk7XG4gIH0gZmluYWxseSB7XG4gICAgYXdhaXQgbnVrZUNhY2hlKGNhY2hlRGlyKTtcbiAgfVxufSk7XG5cbnRlc3QoJ2ZldGNoKGssIHJlc29sdmVyKSBjYW4gYmUgdXNlZCB0byBcImF0b21pY2FsbHlcIiBnZXQgKyByZXNvbHZlICsgcHV0JywgYXN5bmMgKCkgPT4ge1xuICBjb25zdCB7IGNhY2hlRGlyLCBjYWNoZSB9ID0gYXdhaXQgbWFrZUNhY2hlKCk7XG5cbiAgdHJ5IHtcbiAgICBleHBlY3QoYXdhaXQgY2FjaGUuZ2V0KCdmb28nKSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIGV4cGVjdChhd2FpdCBjYWNoZS5mZXRjaCgnZm9vJywgYXN5bmMgKCkgPT4gKHsgYWNjb3VudElkOiAnYmFyJywgcGFydGl0aW9uOiAnYXdzJyB9KSkpLnRvRXF1YWwoeyBhY2NvdW50SWQ6ICdiYXInLCBwYXJ0aXRpb246ICdhd3MnIH0pO1xuICAgIGV4cGVjdChhd2FpdCBjYWNoZS5nZXQoJ2ZvbycpKS50b0VxdWFsKHsgYWNjb3VudElkOiAnYmFyJywgcGFydGl0aW9uOiAnYXdzJyB9KTtcbiAgfSBmaW5hbGx5IHtcbiAgICBhd2FpdCBudWtlQ2FjaGUoY2FjaGVEaXIpO1xuICB9XG59KTtcblxudGVzdChgY2FjaGUgaXMgbnVrZWQgaWYgaXQgZXhjZWVkcyAke0FjY291bnRBY2Nlc3NLZXlDYWNoZS5NQVhfRU5UUklFU30gZW50cmllc2AsIGFzeW5jICgpID0+IHtcblxuICBjb25zdCB7IGNhY2hlRGlyLCBjYWNoZUZpbGUsIGNhY2hlIH0gPSBhd2FpdCBtYWtlQ2FjaGUoKTtcblxuICB0cnkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQWNjb3VudEFjY2Vzc0tleUNhY2hlLk1BWF9FTlRSSUVTOyArK2kpIHtcbiAgICAgIGF3YWl0IGNhY2hlLnB1dChga2V5JHtpfWAsIHsgYWNjb3VudElkOiBgdmFsdWUke2l9YCwgcGFydGl0aW9uOiAnYXdzJyB9KTtcbiAgICB9XG5cbiAgICAvLyB2ZXJpZnkgYWxsIHZhbHVlcyBhcmUgb24gZGlza1xuICAgIGNvbnN0IG90aGVyQ2FjaGUgPSBuZXcgQWNjb3VudEFjY2Vzc0tleUNhY2hlKGNhY2hlRmlsZSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBBY2NvdW50QWNjZXNzS2V5Q2FjaGUuTUFYX0VOVFJJRVM7ICsraSkge1xuICAgICAgZXhwZWN0KGF3YWl0IG90aGVyQ2FjaGUuZ2V0KGBrZXkke2l9YCkpLnRvRXF1YWwoeyBhY2NvdW50SWQ6IGB2YWx1ZSR7aX1gLCBwYXJ0aXRpb246ICdhd3MnIH0pO1xuICAgIH1cblxuICAgIC8vIGFkZCBhbm90aGVyIHZhbHVlXG4gICAgYXdhaXQgY2FjaGUucHV0KCdudWtlLW1lJywgeyBhY2NvdW50SWQ6ICdnZW5lc2lzJywgcGFydGl0aW9uOiAnYXdzJyB9KTtcblxuICAgIC8vIG5vdywgd2UgZXhwZWN0IG9ubHkgYG51a2UtbWVgIHRvIGV4aXN0IG9uIGRpc2tcbiAgICBleHBlY3QoYXdhaXQgb3RoZXJDYWNoZS5nZXQoJ251a2UtbWUnKSkudG9FcXVhbCh7IGFjY291bnRJZDogJ2dlbmVzaXMnLCBwYXJ0aXRpb246ICdhd3MnIH0pO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQWNjb3VudEFjY2Vzc0tleUNhY2hlLk1BWF9FTlRSSUVTOyArK2kpIHtcbiAgICAgIGV4cGVjdChhd2FpdCBvdGhlckNhY2hlLmdldChga2V5JHtpfWApKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IG51a2VDYWNoZShjYWNoZURpcik7XG4gIH1cbn0sXG4vLyBUaGlzIG1ha2VzIGEgbG90IG9mIHByb21pc2VzLCBzbyBpdCBjYW4gcXVldWUgZm9yIGEgd2hpbGUuLi5cbjMwXzAwMCk7XG5cbnRlc3QoJ2NhY2hlIHByZXRlbmRzIHRvIGJlIGVtcHR5IGlmIGNhY2hlIGZpbGUgZG9lcyBub3QgY29udGFpbiBKU09OJywgYXN5bmMoKSA9PiB7XG4gIGNvbnN0IHsgY2FjaGVEaXIsIGNhY2hlRmlsZSwgY2FjaGUgfSA9IGF3YWl0IG1ha2VDYWNoZSgpO1xuICB0cnkge1xuICAgIGF3YWl0IGZzLndyaXRlRmlsZShjYWNoZUZpbGUsICcnKTtcblxuICAgIGF3YWl0IGV4cGVjdChjYWNoZS5nZXQoJ2FiYycpKS5yZXNvbHZlcy50b0VxdWFsKHVuZGVmaW5lZCk7XG4gIH0gZmluYWxseSB7XG4gICAgYXdhaXQgbnVrZUNhY2hlKGNhY2hlRGlyKTtcbiAgfVxufSk7XG4iXX0=