UNPKG

faastjs

Version:

Serverless batch computing made simple.

198 lines 25.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const ava_1 = tslib_1.__importDefault(require("ava")); const util_1 = require("util"); const index_1 = require("../index"); const funcs = tslib_1.__importStar(require("./fixtures/functions")); const util_2 = require("./fixtures/util"); /** * Note that there is an AWS Lambda bug where timeouts are not delivered if the * function has a timeout >= 300s, and the function is invoked directly with the * Invoke API (e.g. in faast.js' "https" mode, which is the default.). In this * case if faast.js has childProcess mode on (the default), then it will set its * own timeout. This situation is not explicitly tested here because it would * make the entire testsuite slower for just one test. To test this situation * manually, change the timeout to 300 or more, and run one of these tests: * * $ ava --timeout=10m -m="remote aws generator timeout { mode: 'https', childProcess: true }" * $ ava --timeout=10m -m="remote aws timeout { mode: 'https', childProcess: true }" */ async function testTimeout(t, provider, options) { const lambda = await (0, index_1.faast)(provider, funcs, { ...options, timeout: 5, maxRetries: 0, gc: "off", description: t.title }); t.plan(1); // t.log(`${lambda.logUrl()}`); try { try { await lambda.functions.infiniteLoop(); } catch (err) { const isTimeout = index_1.FaastError.hasCauseWithName(err, index_1.FaastErrorNames.ETIMEOUT); t.is(isTimeout, true, `${(0, util_1.inspect)(err)}`); } } finally { await lambda.cleanup(); } } /** * The purpose of this test is to verify that a CPU hogging async generator * function won't starve the sending logic, so yield messages prior to the CPU * intensive work are delivered. */ async function testGenerator(t, provider, options) { t.plan(2); const lambda = await (0, index_1.faast)(provider, funcs, { ...options, timeout: 5, maxRetries: 0, gc: "off", description: t.title }); // t.log(`${lambda.logUrl()}`); try { const arg = "hello, generator!"; for await (const result of lambda.functions.generateThenInfiniteLoop(arg)) { t.is(result, arg); } t.fail("Did not timeout"); } catch (err) { t.is(index_1.FaastError.hasCauseWithName(err, index_1.FaastErrorNames.ETIMEOUT), true); } finally { await lambda.cleanup(); } } async function memoryLimitOk(t, provider, options) { const lambda = await (0, index_1.faast)(provider, funcs, { ...options, timeout: 200, memorySize: 512, maxRetries: 0, gc: "off", description: t.title }); try { const bytes = 64 * 1024 * 1024; const rv = await lambda.functions.allocate(bytes); t.is(rv.elems, bytes / 8); } finally { await lambda.cleanup(); } } async function memoryLimitFail(t, provider, options) { const lambda = await (0, index_1.faast)(provider, funcs, { ...options, timeout: 200, memorySize: 512, maxRetries: 0, gc: "off", description: t.title }); try { const bytes = 512 * 1024 * 1024; await t.throwsAsync(lambda.functions.allocate(bytes), { message: /memory/i }); } finally { lambda && (await lambda.cleanup()); } } // Note that this test takes 180s by default. Set the ava timeout to 2m or // longer otherwise it will fail with a timeout error. async function testLongInvoke(t, provider, options) { // The http timeout is 120s in awssdk by default. Uncomment the following // line to shorten it to 20s for focused testing. Note that shortening it // below 20s causes (harmless) timeout error messages from SQS on the long // polling response queue. If faast.js is working correctly, the shortened // timeout should not cause a test failure. // // config.update({ httpOptions: { timeout: 20000 } }); const opts = { timeout: 500, gc: "off", description: t.title, ...options }; const faastModule = await (0, index_1.faast)(provider, funcs, opts); const remote = faastModule.functions; try { let i = 0; const args = ["a", "b", "c"]; // The use of an async generator is to mimick a real use case from a // client of faast.js. The presence of an error should also be revealed // with a regular remote function call. for await (const arg of remote.asyncGeneratorDelay(args, 60000)) { t.is(arg, args[i++]); } } finally { await faastModule.cleanup(); } } async function testReturnSize(t, provider, options) { const lambda = await (0, index_1.faast)(provider, funcs, { ...options, timeout: 20, maxRetries: 0, gc: "off", memorySize: 1024, description: t.title }); t.plan(1); try { try { await lambda.functions.returnSize(10000000); } catch (err) { const isSizeError = err.message.includes("bytes") || err.message.includes("Too Large"); t.is(isSizeError, true, `${(0, util_1.inspect)(err)}`); } } finally { await lambda.cleanup(); } } const allLimits = ["memory", "timeout", "long", "generator", "returnSize"]; const configurations = [ ["aws", { mode: "https", childProcess: true }, allLimits], ["aws", { mode: "queue", childProcess: true }, allLimits], [ "aws", { mode: "https", childProcess: false }, ["memory", "timeout", "generator", "returnSize"] ], [ "aws", { mode: "queue", childProcess: false }, ["memory", "timeout", "generator", "returnSize"] ], ["local", {}, ["timeout"]] ]; for (const [provider, config, limitTypes] of configurations) { const opts = (0, util_1.inspect)(config); if (limitTypes.find(t => t === "memory")) { (0, ava_1.default)((0, util_2.title)(provider, `memory under limit ${opts}`), memoryLimitOk, provider, config); (0, ava_1.default)((0, util_2.title)(provider, `out of memory`, config), memoryLimitFail, provider, config); } if (limitTypes.find(t => t === "timeout")) { (0, ava_1.default)((0, util_2.title)(provider, `timeout`, config), testTimeout, provider, config); } if (limitTypes.find(t => t === "long")) { (0, ava_1.default)((0, util_2.title)(provider, `long invoke`, config), testLongInvoke, provider, config); } if (limitTypes.find(t => t === "generator")) { (0, ava_1.default)((0, util_2.title)(provider, `generator timeout`, config), testGenerator, provider, config); } if (limitTypes.find(t => t === "returnSize")) { (0, ava_1.default)((0, util_2.title)(provider, `return size limit`, config), testReturnSize, provider, config); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGltaXRzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0L2xpbWl0cy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHNEQUE2QztBQUM3QywrQkFBK0I7QUFDL0Isb0NBQXVGO0FBQ3ZGLG9FQUE4QztBQUM5QywwQ0FBd0M7QUFFeEM7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxLQUFLLFVBQVUsV0FBVyxDQUN0QixDQUFtQixFQUNuQixRQUFrQixFQUNsQixPQUFzQjtJQUV0QixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsYUFBSyxFQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUU7UUFDeEMsR0FBRyxPQUFPO1FBQ1YsT0FBTyxFQUFFLENBQUM7UUFDVixVQUFVLEVBQUUsQ0FBQztRQUNiLEVBQUUsRUFBRSxLQUFLO1FBQ1QsV0FBVyxFQUFFLENBQUMsQ0FBQyxLQUFLO0tBQ3ZCLENBQUMsQ0FBQztJQUNILENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDViwrQkFBK0I7SUFDL0IsSUFBSTtRQUNBLElBQUk7WUFDQSxNQUFNLE1BQU0sQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUM7U0FDekM7UUFBQyxPQUFPLEdBQVEsRUFBRTtZQUNmLE1BQU0sU0FBUyxHQUFHLGtCQUFVLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLHVCQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDN0UsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLEdBQUcsSUFBQSxjQUFPLEVBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQzVDO0tBQ0o7WUFBUztRQUNOLE1BQU0sTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO0tBQzFCO0FBQ0wsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxLQUFLLFVBQVUsYUFBYSxDQUN4QixDQUFtQixFQUNuQixRQUFrQixFQUNsQixPQUFzQjtJQUV0QixD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LENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxXQUFXLENBQUMsRUFBRTtRQUN6QyxJQUFBLGFBQUksRUFDQSxJQUFBLFlBQUssRUFBQyxRQUFRLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxDQUFDLEVBQzVDLGFBQWEsRUFDYixRQUFRLEVBQ1IsTUFBTSxDQUNULENBQUM7S0FDTDtJQUNELElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxZQUFZLENBQUMsRUFBRTtRQUMxQyxJQUFBLGFBQUksRUFDQSxJQUFBLFlBQUssRUFBQyxRQUFRLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxDQUFDLEVBQzVDLGNBQWMsRUFDZCxRQUFRLEVBQ1IsTUFBTSxDQUNULENBQUM7S0FDTDtDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHRlc3QsIHsgRXhlY3V0aW9uQ29udGV4dCB9IGZyb20gXCJhdmFcIjtcbmltcG9ydCB7IGluc3BlY3QgfSBmcm9tIFwidXRpbFwiO1xuaW1wb3J0IHsgQ29tbW9uT3B0aW9ucywgZmFhc3QsIEZhYXN0RXJyb3IsIEZhYXN0RXJyb3JOYW1lcywgUHJvdmlkZXIgfSBmcm9tIFwiLi4vaW5kZXhcIjtcbmltcG9ydCAqIGFzIGZ1bmNzIGZyb20gXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiO1xuaW1wb3J0IHsgdGl0bGUgfSBmcm9tIFwiLi9maXh0dXJlcy91dGlsXCI7XG5cbi8qKlxuICogTm90ZSB0aGF0IHRoZXJlIGlzIGFuIEFXUyBMYW1iZGEgYnVnIHdoZXJlIHRpbWVvdXRzIGFyZSBub3QgZGVsaXZlcmVkIGlmIHRoZVxuICogZnVuY3Rpb24gaGFzIGEgdGltZW91dCA+PSAzMDBzLCBhbmQgdGhlIGZ1bmN0aW9uIGlzIGludm9rZWQgZGlyZWN0bHkgd2l0aCB0aGVcbiAqIEludm9rZSBBUEkgKGUuZy4gaW4gZmFhc3QuanMnIFwiaHR0cHNcIiBtb2RlLCB3aGljaCBpcyB0aGUgZGVmYXVsdC4pLiBJbiB0aGlzXG4gKiBjYXNlIGlmIGZhYXN0LmpzIGhhcyBjaGlsZFByb2Nlc3MgbW9kZSBvbiAodGhlIGRlZmF1bHQpLCB0aGVuIGl0IHdpbGwgc2V0IGl0c1xuICogb3duIHRpbWVvdXQuIFRoaXMgc2l0dWF0aW9uIGlzIG5vdCBleHBsaWNpdGx5IHRlc3RlZCBoZXJlIGJlY2F1c2UgaXQgd291bGRcbiAqIG1ha2UgdGhlIGVudGlyZSB0ZXN0c3VpdGUgc2xvd2VyIGZvciBqdXN0IG9uZSB0ZXN0LiBUbyB0ZXN0IHRoaXMgc2l0dWF0aW9uXG4gKiBtYW51YWxseSwgY2hhbmdlIHRoZSB0aW1lb3V0IHRvIDMwMCBvciBtb3JlLCBhbmQgcnVuIG9uZSBvZiB0aGVzZSB0ZXN0czpcbiAqXG4gKiAgICAkIGF2YSAtLXRpbWVvdXQ9MTBtIC1tPVwicmVtb3RlIGF3cyBnZW5lcmF0b3IgdGltZW91dCB7IG1vZGU6ICdodHRwcycsIGNoaWxkUHJvY2VzczogdHJ1ZSB9XCJcbiAqICAgICQgYXZhIC0tdGltZW91dD0xMG0gLW09XCJyZW1vdGUgYXdzIHRpbWVvdXQgeyBtb2RlOiAnaHR0cHMnLCBjaGlsZFByb2Nlc3M6IHRydWUgfVwiXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHRlc3RUaW1lb3V0KFxuICAgIHQ6IEV4ZWN1dGlvbkNvbnRleHQsXG4gICAgcHJvdmlkZXI6IFByb3ZpZGVyLFxuICAgIG9wdGlvbnM6IENvbW1vbk9wdGlvbnNcbikge1xuICAgIGNvbnN0IGxhbWJkYSA9IGF3YWl0IGZhYXN0KHByb3ZpZGVyLCBmdW5jcywge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICB0aW1lb3V0OiA1LFxuICAgICAgICBtYXhSZXRyaWVzOiAwLFxuICAgICAgICBnYzogXCJvZmZcIixcbiAgICAgICAgZGVzY3JpcHRpb246IHQudGl0bGVcbiAgICB9KTtcbiAgICB0LnBsYW4oMSk7XG4gICAgLy8gdC5sb2coYCR7bGFtYmRhLmxvZ1VybCgpfWApO1xuICAgIHRyeSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBsYW1iZGEuZnVuY3Rpb25zLmluZmluaXRlTG9vcCgpO1xuICAgICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICAgICAgY29uc3QgaXNUaW1lb3V0ID0gRmFhc3RFcnJvci5oYXNDYXVzZVdpdGhOYW1lKGVyciwgRmFhc3RFcnJvck5hbWVzLkVUSU1FT1VUKTtcbiAgICAgICAgICAgIHQuaXMoaXNUaW1lb3V0LCB0cnVlLCBgJHtpbnNwZWN0KGVycil9YCk7XG4gICAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBsYW1iZGEuY2xlYW51cCgpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGUgcHVycG9zZSBvZiB0aGlzIHRlc3QgaXMgdG8gdmVyaWZ5IHRoYXQgYSBDUFUgaG9nZ2luZyBhc3luYyBnZW5lcmF0b3JcbiAqIGZ1bmN0aW9uIHdvbid0IHN0YXJ2ZSB0aGUgc2VuZGluZyBsb2dpYywgc28geWllbGQgbWVzc2FnZXMgcHJpb3IgdG8gdGhlIENQVVxuICogaW50ZW5zaXZlIHdvcmsgYXJlIGRlbGl2ZXJlZC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gdGVzdEdlbmVyYXRvcihcbiAgICB0OiBFeGVjdXRpb25Db250ZXh0LFxuICAgIHByb3ZpZGVyOiBQcm92aWRlcixcbiAgICBvcHRpb25zOiBDb21tb25PcHRpb25zXG4pIHtcbiAgICB0LnBsYW4oMik7XG4gICAgY29uc3QgbGFtYmRhID0gYXdhaXQgZmFhc3QocHJvdmlkZXIsIGZ1bmNzLCB7XG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIHRpbWVvdXQ6IDUsXG4gICAgICAgIG1heFJldHJpZXM6IDAsXG4gICAgICAgIGdjOiBcIm9mZlwiLFxuICAgICAgICBkZXNjcmlwdGlvbjogdC50aXRsZVxuICAgIH0pO1xuICAgIC8vIHQubG9nKGAke2xhbWJkYS5sb2dVcmwoKX1gKTtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBhcmcgPSBcImhlbGxvLCBnZW5lcmF0b3IhXCI7XG4gICAgICAgIGZvciBhd2FpdCAoY29uc3QgcmVzdWx0IG9mIGxhbWJkYS5mdW5jdGlvbnMuZ2VuZXJhdGVUaGVuSW5maW5pdGVMb29wKGFyZykpIHtcbiAgICAgICAgICAgIHQuaXMocmVzdWx0LCBhcmcpO1xuICAgICAgICB9XG4gICAgICAgIHQuZmFpbChcIkRpZCBub3QgdGltZW91dFwiKTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICB0LmlzKEZhYXN0RXJyb3IuaGFzQ2F1c2VXaXRoTmFtZShlcnIsIEZhYXN0RXJyb3JOYW1lcy5FVElNRU9VVCksIHRydWUpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGxhbWJkYS5jbGVhbnVwKCk7XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBtZW1vcnlMaW1pdE9rKFxuICAgIHQ6IEV4ZWN1dGlvbkNvbnRleHQsXG4gICAgcHJvdmlkZXI6IFByb3ZpZGVyLFxuICAgIG9wdGlvbnM6IENvbW1vbk9wdGlvbnNcbikge1xuICAgIGNvbnN0IGxhbWJkYSA9IGF3YWl0IGZhYXN0KHByb3ZpZGVyLCBmdW5jcywge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICB0aW1lb3V0OiAyMDAsXG4gICAgICAgIG1lbW9yeVNpemU6IDUxMixcbiAgICAgICAgbWF4UmV0cmllczogMCxcbiAgICAgICAgZ2M6IFwib2ZmXCIsXG4gICAgICAgIGRlc2NyaXB0aW9uOiB0LnRpdGxlXG4gICAgfSk7XG5cbiAgICB0cnkge1xuICAgICAgICBjb25zdCBieXRlcyA9IDY0ICogMTAyNCAqIDEwMjQ7XG4gICAgICAgIGNvbnN0IHJ2ID0gYXdhaXQgbGFtYmRhLmZ1bmN0aW9ucy5hbGxvY2F0ZShieXRlcyk7XG4gICAgICAgIHQuaXMocnYuZWxlbXMsIGJ5dGVzIC8gOCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgbGFtYmRhLmNsZWFudXAoKTtcbiAgICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1lbW9yeUxpbWl0RmFpbChcbiAgICB0OiBFeGVjdXRpb25Db250ZXh0LFxuICAgIHByb3ZpZGVyOiBQcm92aWRlcixcbiAgICBvcHRpb25zOiBDb21tb25PcHRpb25zXG4pIHtcbiAgICBjb25zdCBsYW1iZGEgPSBhd2FpdCBmYWFzdChwcm92aWRlciwgZnVuY3MsIHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdGltZW91dDogMjAwLFxuICAgICAgICBtZW1vcnlTaXplOiA1MTIsXG4gICAgICAgIG1heFJldHJpZXM6IDAsXG4gICAgICAgIGdjOiBcIm9mZlwiLFxuICAgICAgICBkZXNjcmlwdGlvbjogdC50aXRsZVxuICAgIH0pO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYnl0ZXMgPSA1MTIgKiAxMDI0ICogMTAyNDtcbiAgICAgICAgYXdhaXQgdC50aHJvd3NBc3luYyhsYW1iZGEuZnVuY3Rpb25zLmFsbG9jYXRlKGJ5dGVzKSwgeyBtZXNzYWdlOiAvbWVtb3J5L2kgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgbGFtYmRhICYmIChhd2FpdCBsYW1iZGEuY2xlYW51cCgpKTtcbiAgICB9XG59XG5cbi8vIE5vdGUgdGhhdCB0aGlzIHRlc3QgdGFrZXMgMTgwcyBieSBkZWZhdWx0LiBTZXQgdGhlIGF2YSB0aW1lb3V0IHRvIDJtIG9yXG4vLyBsb25nZXIgb3RoZXJ3aXNlIGl0IHdpbGwgZmFpbCB3aXRoIGEgdGltZW91dCBlcnJvci5cbmFzeW5jIGZ1bmN0aW9uIHRlc3RMb25nSW52b2tlKFxuICAgIHQ6IEV4ZWN1dGlvbkNvbnRleHQsXG4gICAgcHJvdmlkZXI6IFByb3ZpZGVyLFxuICAgIG9wdGlvbnM6IENvbW1vbk9wdGlvbnNcbikge1xuICAgIC8vIFRoZSBodHRwIHRpbWVvdXQgaXMgMTIwcyBpbiBhd3NzZGsgYnkgZGVmYXVsdC4gVW5jb21tZW50IHRoZSBmb2xsb3dpbmdcbiAgICAvLyBsaW5lIHRvIHNob3J0ZW4gaXQgdG8gMjBzIGZvciBmb2N1c2VkIHRlc3RpbmcuIE5vdGUgdGhhdCBzaG9ydGVuaW5nIGl0XG4gICAgLy8gYmVsb3cgMjBzIGNhdXNlcyAoaGFybWxlc3MpIHRpbWVvdXQgZXJyb3IgbWVzc2FnZXMgZnJvbSBTUVMgb24gdGhlIGxvbmdcbiAgICAvLyBwb2xsaW5nIHJlc3BvbnNlIHF1ZXVlLiBJZiBmYWFzdC5qcyBpcyB3b3JraW5nIGNvcnJlY3RseSwgdGhlIHNob3J0ZW5lZFxuICAgIC8vIHRpbWVvdXQgc2hvdWxkIG5vdCBjYXVzZSBhIHRlc3QgZmFpbHVyZS5cbiAgICAvL1xuICAgIC8vIGNvbmZpZy51cGRhdGUoeyBodHRwT3B0aW9uczogeyB0aW1lb3V0OiAyMDAwMCB9IH0pO1xuICAgIGNvbnN0IG9wdHM6IENvbW1vbk9wdGlvbnMgPSB7XG4gICAgICAgIHRpbWVvdXQ6IDUwMCxcbiAgICAgICAgZ2M6IFwib2ZmXCIsXG4gICAgICAgIGRlc2NyaXB0aW9uOiB0LnRpdGxlLFxuICAgICAgICAuLi5vcHRpb25zXG4gICAgfTtcbiAgICBjb25zdCBmYWFzdE1vZHVsZSA9IGF3YWl0IGZhYXN0KHByb3ZpZGVyLCBmdW5jcywgb3B0cyk7XG4gICAgY29uc3QgcmVtb3RlID0gZmFhc3RNb2R1bGUuZnVuY3Rpb25zO1xuICAgIHRyeSB7XG4gICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgY29uc3QgYXJncyA9IFtcImFcIiwgXCJiXCIsIFwiY1wiXTtcbiAgICAgICAgLy8gVGhlIHVzZSBvZiBhbiBhc3luYyBnZW5lcmF0b3IgaXMgdG8gbWltaWNrIGEgcmVhbCB1c2UgY2FzZSBmcm9tIGFcbiAgICAgICAgLy8gY2xpZW50IG9mIGZhYXN0LmpzLiBUaGUgcHJlc2VuY2Ugb2YgYW4gZXJyb3Igc2hvdWxkIGFsc28gYmUgcmV2ZWFsZWRcbiAgICAgICAgLy8gd2l0aCBhIHJlZ3VsYXIgcmVtb3RlIGZ1bmN0aW9uIGNhbGwuXG4gICAgICAgIGZvciBhd2FpdCAoY29uc3QgYXJnIG9mIHJlbW90ZS5hc3luY0dlbmVyYXRvckRlbGF5KGFyZ3MsIDYwMDAwKSkge1xuICAgICAgICAgICAgdC5pcyhhcmcsIGFyZ3NbaSsrXSk7XG4gICAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBmYWFzdE1vZHVsZS5jbGVhbnVwKCk7XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB0ZXN0UmV0dXJuU2l6ZShcbiAgICB0OiBFeGVjdXRpb25Db250ZXh0LFxuICAgIHByb3ZpZGVyOiBQcm92aWRlcixcbiAgICBvcHRpb25zOiBDb21tb25PcHRpb25zXG4pIHtcbiAgICBjb25zdCBsYW1iZGEgPSBhd2FpdCBmYWFzdChwcm92aWRlciwgZnVuY3MsIHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdGltZW91dDogMjAsXG4gICAgICAgIG1heFJldHJpZXM6IDAsXG4gICAgICAgIGdjOiBcIm9mZlwiLFxuICAgICAgICBtZW1vcnlTaXplOiAxMDI0LFxuICAgICAgICBkZXNjcmlwdGlvbjogdC50aXRsZVxuICAgIH0pO1xuICAgIHQucGxhbigxKTtcbiAgICB0cnkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgbGFtYmRhLmZ1bmN0aW9ucy5yZXR1cm5TaXplKDEwMDAwMDAwKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzU2l6ZUVycm9yID1cbiAgICAgICAgICAgICAgICBlcnIubWVzc2FnZS5pbmNsdWRlcyhcImJ5dGVzXCIpIHx8IGVyci5tZXNzYWdlLmluY2x1ZGVzKFwiVG9vIExhcmdlXCIpO1xuICAgICAgICAgICAgdC5pcyhpc1NpemVFcnJvciwgdHJ1ZSwgYCR7aW5zcGVjdChlcnIpfWApO1xuICAgICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgbGFtYmRhLmNsZWFudXAoKTtcbiAgICB9XG59XG5cbnR5cGUgTGltaXRUeXBlID0gXCJtZW1vcnlcIiB8IFwidGltZW91dFwiIHwgXCJnZW5lcmF0b3JcIiB8IFwibG9uZ1wiIHwgXCJyZXR1cm5TaXplXCI7XG5jb25zdCBhbGxMaW1pdHMgPSBbXCJtZW1vcnlcIiwgXCJ0aW1lb3V0XCIsIFwibG9uZ1wiLCBcImdlbmVyYXRvclwiLCBcInJldHVyblNpemVcIl0gYXMgY29uc3Q7XG5cbmNvbnN0IGNvbmZpZ3VyYXRpb25zOiBbUHJvdmlkZXIsIENvbW1vbk9wdGlvbnMsIHJlYWRvbmx5IExpbWl0VHlwZVtdXVtdID0gW1xuICAgIFtcImF3c1wiLCB7IG1vZGU6IFwiaHR0cHNcIiwgY2hpbGRQcm9jZXNzOiB0cnVlIH0sIGFsbExpbWl0c10sXG4gICAgW1wiYXdzXCIsIHsgbW9kZTogXCJxdWV1ZVwiLCBjaGlsZFByb2Nlc3M6IHRydWUgfSwgYWxsTGltaXRzXSxcbiAgICBbXG4gICAgICAgIFwiYXdzXCIsXG4gICAgICAgIHsgbW9kZTogXCJodHRwc1wiLCBjaGlsZFByb2Nlc3M6IGZhbHNlIH0sXG4gICAgICAgIFtcIm1lbW9yeVwiLCBcInRpbWVvdXRcIiwgXCJnZW5lcmF0b3JcIiwgXCJyZXR1cm5TaXplXCJdXG4gICAgXSxcbiAgICBbXG4gICAgICAgIFwiYXdzXCIsXG4gICAgICAgIHsgbW9kZTogXCJxdWV1ZVwiLCBjaGlsZFByb2Nlc3M6IGZhbHNlIH0sXG4gICAgICAgIFtcIm1lbW9yeVwiLCBcInRpbWVvdXRcIiwgXCJnZW5lcmF0b3JcIiwgXCJyZXR1cm5TaXplXCJdXG4gICAgXSxcbiAgICBbXCJsb2NhbFwiLCB7fSwgW1widGltZW91dFwiXV1cbl07XG5cbmZvciAoY29uc3QgW3Byb3ZpZGVyLCBjb25maWcsIGxpbWl0VHlwZXNdIG9mIGNvbmZpZ3VyYXRpb25zKSB7XG4gICAgY29uc3Qgb3B0cyA9IGluc3BlY3QoY29uZmlnKTtcbiAgICBpZiAobGltaXRUeXBlcy5maW5kKHQgPT4gdCA9PT0gXCJtZW1vcnlcIikpIHtcbiAgICAgICAgdGVzdChcbiAgICAgICAgICAgIHRpdGxlKHByb3ZpZGVyLCBgbWVtb3J5IHVuZGVyIGxpbWl0ICR7b3B0c31gKSxcbiAgICAgICAgICAgIG1lbW9yeUxpbWl0T2ssXG4gICAgICAgICAgICBwcm92aWRlcixcbiAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICApO1xuICAgICAgICB0ZXN0KHRpdGxlKHByb3ZpZGVyLCBgb3V0IG9mIG1lbW9yeWAsIGNvbmZpZyksIG1lbW9yeUxpbWl0RmFpbCwgcHJvdmlkZXIsIGNvbmZpZyk7XG4gICAgfVxuICAgIGlmIChsaW1pdFR5cGVzLmZpbmQodCA9PiB0ID09PSBcInRpbWVvdXRcIikpIHtcbiAgICAgICAgdGVzdCh0aXRsZShwcm92aWRlciwgYHRpbWVvdXRgLCBjb25maWcpLCB0ZXN0VGltZW91dCwgcHJvdmlkZXIsIGNvbmZpZyk7XG4gICAgfVxuICAgIGlmIChsaW1pdFR5cGVzLmZpbmQodCA9PiB0ID09PSBcImxvbmdcIikpIHtcbiAgICAgICAgdGVzdCh0aXRsZShwcm92aWRlciwgYGxvbmcgaW52b2tlYCwgY29uZmlnKSwgdGVzdExvbmdJbnZva2UsIHByb3ZpZGVyLCBjb25maWcpO1xuICAgIH1cbiAgICBpZiAobGltaXRUeXBlcy5maW5kKHQgPT4gdCA9PT0gXCJnZW5lcmF0b3JcIikpIHtcbiAgICAgICAgdGVzdChcbiAgICAgICAgICAgIHRpdGxlKHByb3ZpZGVyLCBgZ2VuZXJhdG9yIHRpbWVvdXRgLCBjb25maWcpLFxuICAgICAgICAgICAgdGVzdEdlbmVyYXRvcixcbiAgICAgICAgICAgIHByb3ZpZGVyLFxuICAgICAgICAgICAgY29uZmlnXG4gICAgICAgICk7XG4gICAgfVxuICAgIGlmIChsaW1pdFR5cGVzLmZpbmQodCA9PiB0ID09PSBcInJldHVyblNpemVcIikpIHtcbiAgICAgICAgdGVzdChcbiAgICAgICAgICAgIHRpdGxlKHByb3ZpZGVyLCBgcmV0dXJuIHNpemUgbGltaXRgLCBjb25maWcpLFxuICAgICAgICAgICAgdGVzdFJldHVyblNpemUsXG4gICAgICAgICAgICBwcm92aWRlcixcbiAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICApO1xuICAgIH1cbn1cbiJdfQ==