UNPKG

faastjs

Version:

Serverless batch computing made simple.

198 lines 25.4 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGltaXRzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0L2xpbWl0cy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHNEQUE2QztBQUM3QywrQkFBK0I7QUFDL0Isb0NBQXVGO0FBQ3ZGLG9FQUE4QztBQUM5QywwQ0FBd0M7QUFFeEM7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxLQUFLLFVBQVUsV0FBVyxDQUN0QixDQUFtQixFQUNuQixRQUFrQixFQUNsQixPQUFzQjtJQUV0QixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsYUFBSyxFQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUU7UUFDeEMsR0FBRyxPQUFPO1FBQ1YsT0FBTyxFQUFFLENBQUM7UUFDVixVQUFVLEVBQUUsQ0FBQztRQUNiLEVBQUUsRUFBRSxLQUFLO1FBQ1QsV0FBVyxFQUFFLENBQUMsQ0FBQyxLQUFLO0tBQ3ZCLENBQUMsQ0FBQztJQUNILENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDViwrQkFBK0I7SUFDL0IsSUFBSSxDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQ0QsTUFBTSxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzFDLENBQUM7UUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sU0FBUyxHQUFHLGtCQUFVLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLHVCQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDN0UsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLEdBQUcsSUFBQSxjQUFPLEVBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLENBQUM7SUFDTCxDQUFDO1lBQVMsQ0FBQztRQUNQLE1BQU0sTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzNCLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILEtBQUssVUFBVSxhQUFhLENB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RCxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUNyQyxJQUFBLGFBQUksRUFBQyxJQUFBLFlBQUssRUFBQyxRQUFRLEVBQUUsYUFBYSxFQUFFLE1BQU0sQ0FBQyxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUNELElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxXQUFXLENBQUMsRUFBRSxDQUFDO1FBQzFDLElBQUEsYUFBSSxFQUNBLElBQUEsWUFBSyxFQUFDLFFBQVEsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLENBQUMsRUFDNUMsYUFBYSxFQUNiLFFBQVEsRUFDUixNQUFNLENBQ1QsQ0FBQztJQUNOLENBQUM7SUFDRCxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssWUFBWSxDQUFDLEVBQUUsQ0FBQztRQUMzQyxJQUFBLGFBQUksRUFDQSxJQUFBLFlBQUssRUFBQyxRQUFRLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxDQUFDLEVBQzVDLGNBQWMsRUFDZCxRQUFRLEVBQ1IsTUFBTSxDQUNULENBQUM7SUFDTixDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0ZXN0LCB7IEV4ZWN1dGlvbkNvbnRleHQgfSBmcm9tIFwiYXZhXCI7XG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSBcInV0aWxcIjtcbmltcG9ydCB7IENvbW1vbk9wdGlvbnMsIGZhYXN0LCBGYWFzdEVycm9yLCBGYWFzdEVycm9yTmFtZXMsIFByb3ZpZGVyIH0gZnJvbSBcIi4uL2luZGV4XCI7XG5pbXBvcnQgKiBhcyBmdW5jcyBmcm9tIFwiLi9maXh0dXJlcy9mdW5jdGlvbnNcIjtcbmltcG9ydCB7IHRpdGxlIH0gZnJvbSBcIi4vZml4dHVyZXMvdXRpbFwiO1xuXG4vKipcbiAqIE5vdGUgdGhhdCB0aGVyZSBpcyBhbiBBV1MgTGFtYmRhIGJ1ZyB3aGVyZSB0aW1lb3V0cyBhcmUgbm90IGRlbGl2ZXJlZCBpZiB0aGVcbiAqIGZ1bmN0aW9uIGhhcyBhIHRpbWVvdXQgPj0gMzAwcywgYW5kIHRoZSBmdW5jdGlvbiBpcyBpbnZva2VkIGRpcmVjdGx5IHdpdGggdGhlXG4gKiBJbnZva2UgQVBJIChlLmcuIGluIGZhYXN0LmpzJyBcImh0dHBzXCIgbW9kZSwgd2hpY2ggaXMgdGhlIGRlZmF1bHQuKS4gSW4gdGhpc1xuICogY2FzZSBpZiBmYWFzdC5qcyBoYXMgY2hpbGRQcm9jZXNzIG1vZGUgb24gKHRoZSBkZWZhdWx0KSwgdGhlbiBpdCB3aWxsIHNldCBpdHNcbiAqIG93biB0aW1lb3V0LiBUaGlzIHNpdHVhdGlvbiBpcyBub3QgZXhwbGljaXRseSB0ZXN0ZWQgaGVyZSBiZWNhdXNlIGl0IHdvdWxkXG4gKiBtYWtlIHRoZSBlbnRpcmUgdGVzdHN1aXRlIHNsb3dlciBmb3IganVzdCBvbmUgdGVzdC4gVG8gdGVzdCB0aGlzIHNpdHVhdGlvblxuICogbWFudWFsbHksIGNoYW5nZSB0aGUgdGltZW91dCB0byAzMDAgb3IgbW9yZSwgYW5kIHJ1biBvbmUgb2YgdGhlc2UgdGVzdHM6XG4gKlxuICogICAgJCBhdmEgLS10aW1lb3V0PTEwbSAtbT1cInJlbW90ZSBhd3MgZ2VuZXJhdG9yIHRpbWVvdXQgeyBtb2RlOiAnaHR0cHMnLCBjaGlsZFByb2Nlc3M6IHRydWUgfVwiXG4gKiAgICAkIGF2YSAtLXRpbWVvdXQ9MTBtIC1tPVwicmVtb3RlIGF3cyB0aW1lb3V0IHsgbW9kZTogJ2h0dHBzJywgY2hpbGRQcm9jZXNzOiB0cnVlIH1cIlxuICovXG5hc3luYyBmdW5jdGlvbiB0ZXN0VGltZW91dChcbiAgICB0OiBFeGVjdXRpb25Db250ZXh0LFxuICAgIHByb3ZpZGVyOiBQcm92aWRlcixcbiAgICBvcHRpb25zOiBDb21tb25PcHRpb25zXG4pIHtcbiAgICBjb25zdCBsYW1iZGEgPSBhd2FpdCBmYWFzdChwcm92aWRlciwgZnVuY3MsIHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdGltZW91dDogNSxcbiAgICAgICAgbWF4UmV0cmllczogMCxcbiAgICAgICAgZ2M6IFwib2ZmXCIsXG4gICAgICAgIGRlc2NyaXB0aW9uOiB0LnRpdGxlXG4gICAgfSk7XG4gICAgdC5wbGFuKDEpO1xuICAgIC8vIHQubG9nKGAke2xhbWJkYS5sb2dVcmwoKX1gKTtcbiAgICB0cnkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgbGFtYmRhLmZ1bmN0aW9ucy5pbmZpbml0ZUxvb3AoKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzVGltZW91dCA9IEZhYXN0RXJyb3IuaGFzQ2F1c2VXaXRoTmFtZShlcnIsIEZhYXN0RXJyb3JOYW1lcy5FVElNRU9VVCk7XG4gICAgICAgICAgICB0LmlzKGlzVGltZW91dCwgdHJ1ZSwgYCR7aW5zcGVjdChlcnIpfWApO1xuICAgICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgbGFtYmRhLmNsZWFudXAoKTtcbiAgICB9XG59XG5cbi8qKlxuICogVGhlIHB1cnBvc2Ugb2YgdGhpcyB0ZXN0IGlzIHRvIHZlcmlmeSB0aGF0IGEgQ1BVIGhvZ2dpbmcgYXN5bmMgZ2VuZXJhdG9yXG4gKiBmdW5jdGlvbiB3b24ndCBzdGFydmUgdGhlIHNlbmRpbmcgbG9naWMsIHNvIHlpZWxkIG1lc3NhZ2VzIHByaW9yIHRvIHRoZSBDUFVcbiAqIGludGVuc2l2ZSB3b3JrIGFyZSBkZWxpdmVyZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHRlc3RHZW5lcmF0b3IoXG4gICAgdDogRXhlY3V0aW9uQ29udGV4dCxcbiAgICBwcm92aWRlcjogUHJvdmlkZXIsXG4gICAgb3B0aW9uczogQ29tbW9uT3B0aW9uc1xuKSB7XG4gICAgdC5wbGFuKDIpO1xuICAgIGNvbnN0IGxhbWJkYSA9IGF3YWl0IGZhYXN0KHByb3ZpZGVyLCBmdW5jcywge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICB0aW1lb3V0OiA1LFxuICAgICAgICBtYXhSZXRyaWVzOiAwLFxuICAgICAgICBnYzogXCJvZmZcIixcbiAgICAgICAgZGVzY3JpcHRpb246IHQudGl0bGVcbiAgICB9KTtcbiAgICAvLyB0LmxvZyhgJHtsYW1iZGEubG9nVXJsKCl9YCk7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYXJnID0gXCJoZWxsbywgZ2VuZXJhdG9yIVwiO1xuICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IHJlc3VsdCBvZiBsYW1iZGEuZnVuY3Rpb25zLmdlbmVyYXRlVGhlbkluZmluaXRlTG9vcChhcmcpKSB7XG4gICAgICAgICAgICB0LmlzKHJlc3VsdCwgYXJnKTtcbiAgICAgICAgfVxuICAgICAgICB0LmZhaWwoXCJEaWQgbm90IHRpbWVvdXRcIik7XG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgdC5pcyhGYWFzdEVycm9yLmhhc0NhdXNlV2l0aE5hbWUoZXJyLCBGYWFzdEVycm9yTmFtZXMuRVRJTUVPVVQpLCB0cnVlKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBsYW1iZGEuY2xlYW51cCgpO1xuICAgIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gbWVtb3J5TGltaXRPayhcbiAgICB0OiBFeGVjdXRpb25Db250ZXh0LFxuICAgIHByb3ZpZGVyOiBQcm92aWRlcixcbiAgICBvcHRpb25zOiBDb21tb25PcHRpb25zXG4pIHtcbiAgICBjb25zdCBsYW1iZGEgPSBhd2FpdCBmYWFzdChwcm92aWRlciwgZnVuY3MsIHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdGltZW91dDogMjAwLFxuICAgICAgICBtZW1vcnlTaXplOiA1MTIsXG4gICAgICAgIG1heFJldHJpZXM6IDAsXG4gICAgICAgIGdjOiBcIm9mZlwiLFxuICAgICAgICBkZXNjcmlwdGlvbjogdC50aXRsZVxuICAgIH0pO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYnl0ZXMgPSA2NCAqIDEwMjQgKiAxMDI0O1xuICAgICAgICBjb25zdCBydiA9IGF3YWl0IGxhbWJkYS5mdW5jdGlvbnMuYWxsb2NhdGUoYnl0ZXMpO1xuICAgICAgICB0LmlzKHJ2LmVsZW1zLCBieXRlcyAvIDgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGxhbWJkYS5jbGVhbnVwKCk7XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBtZW1vcnlMaW1pdEZhaWwoXG4gICAgdDogRXhlY3V0aW9uQ29udGV4dCxcbiAgICBwcm92aWRlcjogUHJvdmlkZXIsXG4gICAgb3B0aW9uczogQ29tbW9uT3B0aW9uc1xuKSB7XG4gICAgY29uc3QgbGFtYmRhID0gYXdhaXQgZmFhc3QocHJvdmlkZXIsIGZ1bmNzLCB7XG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIHRpbWVvdXQ6IDIwMCxcbiAgICAgICAgbWVtb3J5U2l6ZTogNTEyLFxuICAgICAgICBtYXhSZXRyaWVzOiAwLFxuICAgICAgICBnYzogXCJvZmZcIixcbiAgICAgICAgZGVzY3JpcHRpb246IHQudGl0bGVcbiAgICB9KTtcblxuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGJ5dGVzID0gNTEyICogMTAyNCAqIDEwMjQ7XG4gICAgICAgIGF3YWl0IHQudGhyb3dzQXN5bmMobGFtYmRhLmZ1bmN0aW9ucy5hbGxvY2F0ZShieXRlcyksIHsgbWVzc2FnZTogL21lbW9yeS9pIH0pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGxhbWJkYSAmJiAoYXdhaXQgbGFtYmRhLmNsZWFudXAoKSk7XG4gICAgfVxufVxuXG4vLyBOb3RlIHRoYXQgdGhpcyB0ZXN0IHRha2VzIDE4MHMgYnkgZGVmYXVsdC4gU2V0IHRoZSBhdmEgdGltZW91dCB0byAybSBvclxuLy8gbG9uZ2VyIG90aGVyd2lzZSBpdCB3aWxsIGZhaWwgd2l0aCBhIHRpbWVvdXQgZXJyb3IuXG5hc3luYyBmdW5jdGlvbiB0ZXN0TG9uZ0ludm9rZShcbiAgICB0OiBFeGVjdXRpb25Db250ZXh0LFxuICAgIHByb3ZpZGVyOiBQcm92aWRlcixcbiAgICBvcHRpb25zOiBDb21tb25PcHRpb25zXG4pIHtcbiAgICAvLyBUaGUgaHR0cCB0aW1lb3V0IGlzIDEyMHMgaW4gYXdzc2RrIGJ5IGRlZmF1bHQuIFVuY29tbWVudCB0aGUgZm9sbG93aW5nXG4gICAgLy8gbGluZSB0byBzaG9ydGVuIGl0IHRvIDIwcyBmb3IgZm9jdXNlZCB0ZXN0aW5nLiBOb3RlIHRoYXQgc2hvcnRlbmluZyBpdFxuICAgIC8vIGJlbG93IDIwcyBjYXVzZXMgKGhhcm1sZXNzKSB0aW1lb3V0IGVycm9yIG1lc3NhZ2VzIGZyb20gU1FTIG9uIHRoZSBsb25nXG4gICAgLy8gcG9sbGluZyByZXNwb25zZSBxdWV1ZS4gSWYgZmFhc3QuanMgaXMgd29ya2luZyBjb3JyZWN0bHksIHRoZSBzaG9ydGVuZWRcbiAgICAvLyB0aW1lb3V0IHNob3VsZCBub3QgY2F1c2UgYSB0ZXN0IGZhaWx1cmUuXG4gICAgLy9cbiAgICAvLyBjb25maWcudXBkYXRlKHsgaHR0cE9wdGlvbnM6IHsgdGltZW91dDogMjAwMDAgfSB9KTtcbiAgICBjb25zdCBvcHRzOiBDb21tb25PcHRpb25zID0ge1xuICAgICAgICB0aW1lb3V0OiA1MDAsXG4gICAgICAgIGdjOiBcIm9mZlwiLFxuICAgICAgICBkZXNjcmlwdGlvbjogdC50aXRsZSxcbiAgICAgICAgLi4ub3B0aW9uc1xuICAgIH07XG4gICAgY29uc3QgZmFhc3RNb2R1bGUgPSBhd2FpdCBmYWFzdChwcm92aWRlciwgZnVuY3MsIG9wdHMpO1xuICAgIGNvbnN0IHJlbW90ZSA9IGZhYXN0TW9kdWxlLmZ1bmN0aW9ucztcbiAgICB0cnkge1xuICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBbXCJhXCIsIFwiYlwiLCBcImNcIl07XG4gICAgICAgIC8vIFRoZSB1c2Ugb2YgYW4gYXN5bmMgZ2VuZXJhdG9yIGlzIHRvIG1pbWljayBhIHJlYWwgdXNlIGNhc2UgZnJvbSBhXG4gICAgICAgIC8vIGNsaWVudCBvZiBmYWFzdC5qcy4gVGhlIHByZXNlbmNlIG9mIGFuIGVycm9yIHNob3VsZCBhbHNvIGJlIHJldmVhbGVkXG4gICAgICAgIC8vIHdpdGggYSByZWd1bGFyIHJlbW90ZSBmdW5jdGlvbiBjYWxsLlxuICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IGFyZyBvZiByZW1vdGUuYXN5bmNHZW5lcmF0b3JEZWxheShhcmdzLCA2MDAwMCkpIHtcbiAgICAgICAgICAgIHQuaXMoYXJnLCBhcmdzW2krK10pO1xuICAgICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgZmFhc3RNb2R1bGUuY2xlYW51cCgpO1xuICAgIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gdGVzdFJldHVyblNpemUoXG4gICAgdDogRXhlY3V0aW9uQ29udGV4dCxcbiAgICBwcm92aWRlcjogUHJvdmlkZXIsXG4gICAgb3B0aW9uczogQ29tbW9uT3B0aW9uc1xuKSB7XG4gICAgY29uc3QgbGFtYmRhID0gYXdhaXQgZmFhc3QocHJvdmlkZXIsIGZ1bmNzLCB7XG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIHRpbWVvdXQ6IDIwLFxuICAgICAgICBtYXhSZXRyaWVzOiAwLFxuICAgICAgICBnYzogXCJvZmZcIixcbiAgICAgICAgbWVtb3J5U2l6ZTogMTAyNCxcbiAgICAgICAgZGVzY3JpcHRpb246IHQudGl0bGVcbiAgICB9KTtcbiAgICB0LnBsYW4oMSk7XG4gICAgdHJ5IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGxhbWJkYS5mdW5jdGlvbnMucmV0dXJuU2l6ZSgxMDAwMDAwMCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgICAgICBjb25zdCBpc1NpemVFcnJvciA9XG4gICAgICAgICAgICAgICAgZXJyLm1lc3NhZ2UuaW5jbHVkZXMoXCJieXRlc1wiKSB8fCBlcnIubWVzc2FnZS5pbmNsdWRlcyhcIlRvbyBMYXJnZVwiKTtcbiAgICAgICAgICAgIHQuaXMoaXNTaXplRXJyb3IsIHRydWUsIGAke2luc3BlY3QoZXJyKX1gKTtcbiAgICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGxhbWJkYS5jbGVhbnVwKCk7XG4gICAgfVxufVxuXG50eXBlIExpbWl0VHlwZSA9IFwibWVtb3J5XCIgfCBcInRpbWVvdXRcIiB8IFwiZ2VuZXJhdG9yXCIgfCBcImxvbmdcIiB8IFwicmV0dXJuU2l6ZVwiO1xuY29uc3QgYWxsTGltaXRzID0gW1wibWVtb3J5XCIsIFwidGltZW91dFwiLCBcImxvbmdcIiwgXCJnZW5lcmF0b3JcIiwgXCJyZXR1cm5TaXplXCJdIGFzIGNvbnN0O1xuXG5jb25zdCBjb25maWd1cmF0aW9uczogW1Byb3ZpZGVyLCBDb21tb25PcHRpb25zLCByZWFkb25seSBMaW1pdFR5cGVbXV1bXSA9IFtcbiAgICBbXCJhd3NcIiwgeyBtb2RlOiBcImh0dHBzXCIsIGNoaWxkUHJvY2VzczogdHJ1ZSB9LCBhbGxMaW1pdHNdLFxuICAgIFtcImF3c1wiLCB7IG1vZGU6IFwicXVldWVcIiwgY2hpbGRQcm9jZXNzOiB0cnVlIH0sIGFsbExpbWl0c10sXG4gICAgW1xuICAgICAgICBcImF3c1wiLFxuICAgICAgICB7IG1vZGU6IFwiaHR0cHNcIiwgY2hpbGRQcm9jZXNzOiBmYWxzZSB9LFxuICAgICAgICBbXCJtZW1vcnlcIiwgXCJ0aW1lb3V0XCIsIFwiZ2VuZXJhdG9yXCIsIFwicmV0dXJuU2l6ZVwiXVxuICAgIF0sXG4gICAgW1xuICAgICAgICBcImF3c1wiLFxuICAgICAgICB7IG1vZGU6IFwicXVldWVcIiwgY2hpbGRQcm9jZXNzOiBmYWxzZSB9LFxuICAgICAgICBbXCJtZW1vcnlcIiwgXCJ0aW1lb3V0XCIsIFwiZ2VuZXJhdG9yXCIsIFwicmV0dXJuU2l6ZVwiXVxuICAgIF0sXG4gICAgW1wibG9jYWxcIiwge30sIFtcInRpbWVvdXRcIl1dXG5dO1xuXG5mb3IgKGNvbnN0IFtwcm92aWRlciwgY29uZmlnLCBsaW1pdFR5cGVzXSBvZiBjb25maWd1cmF0aW9ucykge1xuICAgIGNvbnN0IG9wdHMgPSBpbnNwZWN0KGNvbmZpZyk7XG4gICAgaWYgKGxpbWl0VHlwZXMuZmluZCh0ID0+IHQgPT09IFwibWVtb3J5XCIpKSB7XG4gICAgICAgIHRlc3QoXG4gICAgICAgICAgICB0aXRsZShwcm92aWRlciwgYG1lbW9yeSB1bmRlciBsaW1pdCAke29wdHN9YCksXG4gICAgICAgICAgICBtZW1vcnlMaW1pdE9rLFxuICAgICAgICAgICAgcHJvdmlkZXIsXG4gICAgICAgICAgICBjb25maWdcbiAgICAgICAgKTtcbiAgICAgICAgdGVzdCh0aXRsZShwcm92aWRlciwgYG91dCBvZiBtZW1vcnlgLCBjb25maWcpLCBtZW1vcnlMaW1pdEZhaWwsIHByb3ZpZGVyLCBjb25maWcpO1xuICAgIH1cbiAgICBpZiAobGltaXRUeXBlcy5maW5kKHQgPT4gdCA9PT0gXCJ0aW1lb3V0XCIpKSB7XG4gICAgICAgIHRlc3QodGl0bGUocHJvdmlkZXIsIGB0aW1lb3V0YCwgY29uZmlnKSwgdGVzdFRpbWVvdXQsIHByb3ZpZGVyLCBjb25maWcpO1xuICAgIH1cbiAgICBpZiAobGltaXRUeXBlcy5maW5kKHQgPT4gdCA9PT0gXCJsb25nXCIpKSB7XG4gICAgICAgIHRlc3QodGl0bGUocHJvdmlkZXIsIGBsb25nIGludm9rZWAsIGNvbmZpZyksIHRlc3RMb25nSW52b2tlLCBwcm92aWRlciwgY29uZmlnKTtcbiAgICB9XG4gICAgaWYgKGxpbWl0VHlwZXMuZmluZCh0ID0+IHQgPT09IFwiZ2VuZXJhdG9yXCIpKSB7XG4gICAgICAgIHRlc3QoXG4gICAgICAgICAgICB0aXRsZShwcm92aWRlciwgYGdlbmVyYXRvciB0aW1lb3V0YCwgY29uZmlnKSxcbiAgICAgICAgICAgIHRlc3RHZW5lcmF0b3IsXG4gICAgICAgICAgICBwcm92aWRlcixcbiAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICApO1xuICAgIH1cbiAgICBpZiAobGltaXRUeXBlcy5maW5kKHQgPT4gdCA9PT0gXCJyZXR1cm5TaXplXCIpKSB7XG4gICAgICAgIHRlc3QoXG4gICAgICAgICAgICB0aXRsZShwcm92aWRlciwgYHJldHVybiBzaXplIGxpbWl0YCwgY29uZmlnKSxcbiAgICAgICAgICAgIHRlc3RSZXR1cm5TaXplLFxuICAgICAgICAgICAgcHJvdmlkZXIsXG4gICAgICAgICAgICBjb25maWdcbiAgICAgICAgKTtcbiAgICB9XG59XG4iXX0=