faastjs
Version:
Serverless batch computing made simple.
182 lines • 29.4 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const ava_1 = tslib_1.__importDefault(require("ava"));
const index_1 = require("../index");
const funcs = tslib_1.__importStar(require("./fixtures/functions"));
const util_1 = require("./fixtures/util");
function nodeMajorVersion() {
const match = process.version.match(/^v(\d+)\./);
if (match) {
return Number(match[1]);
}
return 0;
}
async function testBasic(t, provider, options) {
const opts = {
timeout: 60,
gc: "off",
description: t.title,
env: { faastEnvironmentVariable: "the_answer_is_42" },
...options
};
const faastModule = await (0, index_1.faast)(provider, funcs, opts);
const remote = faastModule.functions;
try {
t.is(await remote.hello("Andy"), "Hello Andy!");
t.is(await remote.identityString("你好"), "你好");
t.is(await remote.identityNum(42), 42);
t.is(await remote.identityNum(Infinity), Infinity);
t.is(await remote.identityNum(-Infinity), -Infinity);
if (nodeMajorVersion() >= 10) {
t.is(await remote.identityNum(NaN), NaN);
}
t.is(await remote.empty(), undefined);
t.is(await remote.arrow("arrow"), "arrow");
t.is(await remote.asyncArrow("asyncArrow"), "asyncArrow");
t.is(await remote.fact(5), 120);
t.is(await remote.concat("abc", "def"), "abcdef");
await t.throwsAsync(() => remote.error("hey"), {
message: /Expected error. Arg: hey/
});
t.is(await remote.noargs(), "called function with no args.");
t.is(await remote.async(), "async function: success");
t.is(typeof (await remote.path()), "string");
t.is(await remote.optionalArg(), "No arg");
t.is(await remote.optionalArg("has arg"), "has arg");
const date = new Date();
t.deepEqual(await remote.identityDate(date), date);
const buffer = Buffer.from("contents");
t.deepEqual(await remote.identityBuffer(buffer), buffer);
t.deepEqual(await remote.identityArrayNum([42, 8, 10]), [42, 8, 10]);
const inf = [Infinity, -Infinity];
t.deepEqual(await remote.identityArrayNum(inf), inf);
if (nodeMajorVersion() >= 10) {
t.deepEqual(await remote.identityArrayNum([NaN]), [NaN]);
}
t.deepEqual(await remote.identityArrayString(["a", "there"]), ["a", "there"]);
t.is(await remote.identityBool(true), true);
t.is(await remote.identityBool(false), false);
t.is(await remote.identityUndefined(undefined), undefined);
t.is(await remote.identityNull(null), null);
t.deepEqual(await remote.identityObject({}), {});
t.deepEqual(await remote.identityObject({ a: 42, b: "hello" }), {
a: 42,
b: "hello"
});
const int8 = Int8Array.of(0, -8, 42);
t.deepEqual(await remote.identityInt8(int8), int8);
const uint8 = Uint8Array.of(0, 8, 42);
t.deepEqual(await remote.identityUint8(uint8), uint8);
const uint8Clamped = Uint8ClampedArray.of(0, 8, 42);
t.deepEqual(await remote.identityUint8Clamped(uint8Clamped), uint8Clamped);
const int16 = Int16Array.of(0, 8, 42, -1);
t.deepEqual(await remote.identityInt16(int16), int16);
const uint16 = Uint16Array.of(0, 8, 42, -1);
t.deepEqual(await remote.identityUint16(uint16), uint16);
const int32 = Int32Array.of(0, 8, 42, -1);
t.deepEqual(await remote.identityInt32(int32), int32);
const uint32 = Uint32Array.of(0, 8, 42, -1);
t.deepEqual(await remote.identityUint32(uint32), uint32);
const float32 = Float32Array.of(0, 0.3, 100.042, -1);
t.deepEqual(await remote.identityFloat32(float32), float32);
const float64 = Float64Array.of(0, 0.3, 100.042, -1);
t.deepEqual(await remote.identityFloat64(float64), float64);
const m = new Map([
[1, 2],
[42, 10]
]);
t.deepEqual(await remote.identityMap(m), m);
const s = new Set([1, 42, 100]);
t.deepEqual(await remote.identitySet(s), s);
try {
await remote.emptyReject();
t.fail("remote.emptyReject() did not reject as expected");
}
catch (err) {
t.is(err, undefined);
}
try {
await remote.rejected();
t.fail("remote.rejected() did not reject as expected");
}
catch (err) {
t.is(err, "intentionally rejected");
}
try {
await remote.customError();
t.fail("remote.customError() did not reject as expected");
}
catch (err) {
t.true(err instanceof index_1.FaastError);
t.truthy(err.message.match(/^custom error message/));
t.is(index_1.FaastError.info(err).custom, "custom value");
}
t.is(await remote.getEnv("faastEnvironmentVariable"), "the_answer_is_42");
t.is(await remote.getEnv("faastNonexistent"), undefined);
t.deepEqual(await remote.returnsError(), funcs.returnsError());
const elements = ["bar", "baz"];
t.deepEqual(await (0, util_1.toArray)(remote.generator(elements)), elements);
t.deepEqual(await (0, util_1.toArray)(remote.asyncGenerator(elements)), elements);
try {
for await (const _ of remote.asyncGeneratorError("async generator failed")) {
// ignore
}
t.fail(`remote.asyncGeneratorError() did not reject as expected (2)`);
}
catch (err) {
t.true(err instanceof index_1.FaastError);
t.truthy(err.message.match(/^async generator failed/));
}
}
finally {
await faastModule.cleanup();
}
}
async function testBasicRequire(t, provider) {
const requiredFuncs = require("./fixtures/functions");
const opts = { timeout: 30, gc: "off", description: t.title };
const faastModule = await (0, index_1.faast)(provider, requiredFuncs, opts);
const remote = faastModule.functions;
try {
t.is(await remote.identityString("id"), "id");
t.is(await remote.arrow("arrow"), "arrow");
}
finally {
await faastModule.cleanup();
}
}
// async function testCpuMetrics(t: ExecutionContext, provider: Provider) {
// t.plan(4);
// const lambda = await faast(provider, funcs, {
// childProcess: true,
// timeout: 90,
// memorySize: 512,
// maxRetries: 0,
// gc: "off",
// description: t.title
// });
// try {
// const NSec = 4;
// await lambda.functions.spin(NSec * 1000);
// const usage = lambda.cpuUsage.get("spin");
// t.truthy(usage);
// t.true(usage!.size > 0);
// for (const [, instance] of usage!) {
// t.true(instance.stime instanceof Statistics);
// t.true(instance.utime instanceof Statistics);
// break;
// }
// } finally {
// await lambda.cleanup();
// }
// }
for (const provider of index_1.providers) {
for (const config of [...util_1.configs, ...util_1.noValidateConfigs]) {
ava_1.default.serial((0, util_1.title)(provider, `basic calls`, config), testBasic, provider, config);
}
// XXX Disable CPU metrics for now.
// test(title(provider, `cpu metrics are received`), testCpuMetrics, provider);
ava_1.default.serial((0, util_1.title)(provider, `basic calls with require`), testBasicRequire, provider);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzaWMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvYmFzaWMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxzREFBNkM7QUFDN0Msb0NBQWlGO0FBQ2pGLG9FQUE4QztBQUM5QywwQ0FBNkU7QUFFN0UsU0FBUyxnQkFBZ0I7SUFDckIsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDakQsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUNSLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFDRCxPQUFPLENBQUMsQ0FBQztBQUNiLENBQUM7QUFFRCxLQUFLLFVBQVUsU0FBUyxDQUNwQixDQUFtQixFQUNuQixRQUFrQixFQUNsQixPQUFzQjtJQUV0QixNQUFNLElBQUksR0FBa0I7UUFDeEIsT0FBTyxFQUFFLEVBQUU7UUFDWCxFQUFFLEVBQUUsS0FBSztRQUNULFdBQVcsRUFBRSxDQUFDLENBQUMsS0FBSztRQUNwQixHQUFHLEVBQUUsRUFBRSx3QkFBd0IsRUFBRSxrQkFBa0IsRUFBRTtRQUNyRCxHQUFHLE9BQU87S0FDYixDQUFDO0lBRUYsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFBLGFBQUssRUFBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxTQUFTLENBQUM7SUFFckMsSUFBSSxDQUFDO1FBQ0QsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDaEQsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDbkQsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JELElBQUksZ0JBQWdCLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUMzQixDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxLQUFLLEVBQUUsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN0QyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMzQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sTUFBTSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUMxRCxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNoQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDbEQsTUFBTSxDQUFDLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDM0MsT0FBTyxFQUFFLDBCQUEwQjtTQUN0QyxDQUFDLENBQUM7UUFDSCxD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LENBQUMsSUFBQSxZQUFLLEVBQUMsUUFBUSxFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3JGLENBQUM7SUFDRCxtQ0FBbUM7SUFDbkMsK0VBQStFO0lBQy9FLGFBQUksQ0FBQyxNQUFNLENBQUMsSUFBQSxZQUFLLEVBQUMsUUFBUSxFQUFFLDBCQUEwQixDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDekYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0ZXN0LCB7IEV4ZWN1dGlvbkNvbnRleHQgfSBmcm9tIFwiYXZhXCI7XG5pbXBvcnQgeyBDb21tb25PcHRpb25zLCBmYWFzdCwgRmFhc3RFcnJvciwgUHJvdmlkZXIsIHByb3ZpZGVycyB9IGZyb20gXCIuLi9pbmRleFwiO1xuaW1wb3J0ICogYXMgZnVuY3MgZnJvbSBcIi4vZml4dHVyZXMvZnVuY3Rpb25zXCI7XG5pbXBvcnQgeyBjb25maWdzLCBub1ZhbGlkYXRlQ29uZmlncywgdGl0bGUsIHRvQXJyYXkgfSBmcm9tIFwiLi9maXh0dXJlcy91dGlsXCI7XG5cbmZ1bmN0aW9uIG5vZGVNYWpvclZlcnNpb24oKSB7XG4gICAgY29uc3QgbWF0Y2ggPSBwcm9jZXNzLnZlcnNpb24ubWF0Y2goL152KFxcZCspXFwuLyk7XG4gICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIHJldHVybiBOdW1iZXIobWF0Y2hbMV0pO1xuICAgIH1cbiAgICByZXR1cm4gMDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdGVzdEJhc2ljKFxuICAgIHQ6IEV4ZWN1dGlvbkNvbnRleHQsXG4gICAgcHJvdmlkZXI6IFByb3ZpZGVyLFxuICAgIG9wdGlvbnM6IENvbW1vbk9wdGlvbnNcbikge1xuICAgIGNvbnN0IG9wdHM6IENvbW1vbk9wdGlvbnMgPSB7XG4gICAgICAgIHRpbWVvdXQ6IDYwLFxuICAgICAgICBnYzogXCJvZmZcIixcbiAgICAgICAgZGVzY3JpcHRpb246IHQudGl0bGUsXG4gICAgICAgIGVudjogeyBmYWFzdEVudmlyb25tZW50VmFyaWFibGU6IFwidGhlX2Fuc3dlcl9pc180MlwiIH0sXG4gICAgICAgIC4uLm9wdGlvbnNcbiAgICB9O1xuXG4gICAgY29uc3QgZmFhc3RNb2R1bGUgPSBhd2FpdCBmYWFzdChwcm92aWRlciwgZnVuY3MsIG9wdHMpO1xuICAgIGNvbnN0IHJlbW90ZSA9IGZhYXN0TW9kdWxlLmZ1bmN0aW9ucztcblxuICAgIHRyeSB7XG4gICAgICAgIHQuaXMoYXdhaXQgcmVtb3RlLmhlbGxvKFwiQW5keVwiKSwgXCJIZWxsbyBBbmR5IVwiKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuaWRlbnRpdHlTdHJpbmcoXCLkvaDlpb1cIiksIFwi5L2g5aW9XCIpO1xuICAgICAgICB0LmlzKGF3YWl0IHJlbW90ZS5pZGVudGl0eU51bSg0MiksIDQyKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuaWRlbnRpdHlOdW0oSW5maW5pdHkpLCBJbmZpbml0eSk7XG4gICAgICAgIHQuaXMoYXdhaXQgcmVtb3RlLmlkZW50aXR5TnVtKC1JbmZpbml0eSksIC1JbmZpbml0eSk7XG4gICAgICAgIGlmIChub2RlTWFqb3JWZXJzaW9uKCkgPj0gMTApIHtcbiAgICAgICAgICAgIHQuaXMoYXdhaXQgcmVtb3RlLmlkZW50aXR5TnVtKE5hTiksIE5hTik7XG4gICAgICAgIH1cbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuZW1wdHkoKSwgdW5kZWZpbmVkKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuYXJyb3coXCJhcnJvd1wiKSwgXCJhcnJvd1wiKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuYXN5bmNBcnJvdyhcImFzeW5jQXJyb3dcIiksIFwiYXN5bmNBcnJvd1wiKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuZmFjdCg1KSwgMTIwKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuY29uY2F0KFwiYWJjXCIsIFwiZGVmXCIpLCBcImFiY2RlZlwiKTtcbiAgICAgICAgYXdhaXQgdC50aHJvd3NBc3luYygoKSA9PiByZW1vdGUuZXJyb3IoXCJoZXlcIiksIHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IC9FeHBlY3RlZCBlcnJvci4gQXJnOiBoZXkvXG4gICAgICAgIH0pO1xuICAgICAgICB0LmlzKGF3YWl0IHJlbW90ZS5ub2FyZ3MoKSwgXCJjYWxsZWQgZnVuY3Rpb24gd2l0aCBubyBhcmdzLlwiKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuYXN5bmMoKSwgXCJhc3luYyBmdW5jdGlvbjogc3VjY2Vzc1wiKTtcbiAgICAgICAgdC5pcyh0eXBlb2YgKGF3YWl0IHJlbW90ZS5wYXRoKCkpLCBcInN0cmluZ1wiKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUub3B0aW9uYWxBcmcoKSwgXCJObyBhcmdcIik7XG4gICAgICAgIHQuaXMoYXdhaXQgcmVtb3RlLm9wdGlvbmFsQXJnKFwiaGFzIGFyZ1wiKSwgXCJoYXMgYXJnXCIpO1xuXG4gICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICB0LmRlZXBFcXVhbChhd2FpdCByZW1vdGUuaWRlbnRpdHlEYXRlKGRhdGUpLCBkYXRlKTtcblxuICAgICAgICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShcImNvbnRlbnRzXCIpO1xuICAgICAgICB0LmRlZXBFcXVhbChhd2FpdCByZW1vdGUuaWRlbnRpdHlCdWZmZXIoYnVmZmVyKSwgYnVmZmVyKTtcblxuICAgICAgICB0LmRlZXBFcXVhbChhd2FpdCByZW1vdGUuaWRlbnRpdHlBcnJheU51bShbNDIsIDgsIDEwXSksIFs0MiwgOCwgMTBdKTtcblxuICAgICAgICBjb25zdCBpbmYgPSBbSW5maW5pdHksIC1JbmZpbml0eV07XG4gICAgICAgIHQuZGVlcEVxdWFsKGF3YWl0IHJlbW90ZS5pZGVudGl0eUFycmF5TnVtKGluZiksIGluZik7XG5cbiAgICAgICAgaWYgKG5vZGVNYWpvclZlcnNpb24oKSA+PSAxMCkge1xuICAgICAgICAgICAgdC5kZWVwRXF1YWwoYXdhaXQgcmVtb3RlLmlkZW50aXR5QXJyYXlOdW0oW05hTl0pLCBbTmFOXSk7XG4gICAgICAgIH1cbiAgICAgICAgdC5kZWVwRXF1YWwoYXdhaXQgcmVtb3RlLmlkZW50aXR5QXJyYXlTdHJpbmcoW1wiYVwiLCBcInRoZXJlXCJdKSwgW1wiYVwiLCBcInRoZXJlXCJdKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuaWRlbnRpdHlCb29sKHRydWUpLCB0cnVlKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuaWRlbnRpdHlCb29sKGZhbHNlKSwgZmFsc2UpO1xuICAgICAgICB0LmlzKGF3YWl0IHJlbW90ZS5pZGVudGl0eVVuZGVmaW5lZCh1bmRlZmluZWQpLCB1bmRlZmluZWQpO1xuICAgICAgICB0LmlzKGF3YWl0IHJlbW90ZS5pZGVudGl0eU51bGwobnVsbCksIG51bGwpO1xuICAgICAgICB0LmRlZXBFcXVhbChhd2FpdCByZW1vdGUuaWRlbnRpdHlPYmplY3Qoe30pLCB7fSk7XG4gICAgICAgIHQuZGVlcEVxdWFsKGF3YWl0IHJlbW90ZS5pZGVudGl0eU9iamVjdCh7IGE6IDQyLCBiOiBcImhlbGxvXCIgfSksIHtcbiAgICAgICAgICAgIGE6IDQyLFxuICAgICAgICAgICAgYjogXCJoZWxsb1wiXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBpbnQ4ID0gSW50OEFycmF5Lm9mKDAsIC04LCA0Mik7XG4gICAgICAgIHQuZGVlcEVxdWFsKGF3YWl0IHJlbW90ZS5pZGVudGl0eUludDgoaW50OCksIGludDgpO1xuXG4gICAgICAgIGNvbnN0IHVpbnQ4ID0gVWludDhBcnJheS5vZigwLCA4LCA0Mik7XG4gICAgICAgIHQuZGVlcEVxdWFsKGF3YWl0IHJlbW90ZS5pZGVudGl0eVVpbnQ4KHVpbnQ4KSwgdWludDgpO1xuXG4gICAgICAgIGNvbnN0IHVpbnQ4Q2xhbXBlZCA9IFVpbnQ4Q2xhbXBlZEFycmF5Lm9mKDAsIDgsIDQyKTtcbiAgICAgICAgdC5kZWVwRXF1YWwoYXdhaXQgcmVtb3RlLmlkZW50aXR5VWludDhDbGFtcGVkKHVpbnQ4Q2xhbXBlZCksIHVpbnQ4Q2xhbXBlZCk7XG5cbiAgICAgICAgY29uc3QgaW50MTYgPSBJbnQxNkFycmF5Lm9mKDAsIDgsIDQyLCAtMSk7XG4gICAgICAgIHQuZGVlcEVxdWFsKGF3YWl0IHJlbW90ZS5pZGVudGl0eUludDE2KGludDE2KSwgaW50MTYpO1xuXG4gICAgICAgIGNvbnN0IHVpbnQxNiA9IFVpbnQxNkFycmF5Lm9mKDAsIDgsIDQyLCAtMSk7XG4gICAgICAgIHQuZGVlcEVxdWFsKGF3YWl0IHJlbW90ZS5pZGVudGl0eVVpbnQxNih1aW50MTYpLCB1aW50MTYpO1xuXG4gICAgICAgIGNvbnN0IGludDMyID0gSW50MzJBcnJheS5vZigwLCA4LCA0MiwgLTEpO1xuICAgICAgICB0LmRlZXBFcXVhbChhd2FpdCByZW1vdGUuaWRlbnRpdHlJbnQzMihpbnQzMiksIGludDMyKTtcblxuICAgICAgICBjb25zdCB1aW50MzIgPSBVaW50MzJBcnJheS5vZigwLCA4LCA0MiwgLTEpO1xuICAgICAgICB0LmRlZXBFcXVhbChhd2FpdCByZW1vdGUuaWRlbnRpdHlVaW50MzIodWludDMyKSwgdWludDMyKTtcblxuICAgICAgICBjb25zdCBmbG9hdDMyID0gRmxvYXQzMkFycmF5Lm9mKDAsIDAuMywgMTAwLjA0MiwgLTEpO1xuICAgICAgICB0LmRlZXBFcXVhbChhd2FpdCByZW1vdGUuaWRlbnRpdHlGbG9hdDMyKGZsb2F0MzIpLCBmbG9hdDMyKTtcblxuICAgICAgICBjb25zdCBmbG9hdDY0ID0gRmxvYXQ2NEFycmF5Lm9mKDAsIDAuMywgMTAwLjA0MiwgLTEpO1xuICAgICAgICB0LmRlZXBFcXVhbChhd2FpdCByZW1vdGUuaWRlbnRpdHlGbG9hdDY0KGZsb2F0NjQpLCBmbG9hdDY0KTtcblxuICAgICAgICBjb25zdCBtID0gbmV3IE1hcChbXG4gICAgICAgICAgICBbMSwgMl0sXG4gICAgICAgICAgICBbNDIsIDEwXVxuICAgICAgICBdKTtcbiAgICAgICAgdC5kZWVwRXF1YWwoYXdhaXQgcmVtb3RlLmlkZW50aXR5TWFwKG0pLCBtKTtcblxuICAgICAgICBjb25zdCBzID0gbmV3IFNldChbMSwgNDIsIDEwMF0pO1xuICAgICAgICB0LmRlZXBFcXVhbChhd2FpdCByZW1vdGUuaWRlbnRpdHlTZXQocyksIHMpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCByZW1vdGUuZW1wdHlSZWplY3QoKTtcbiAgICAgICAgICAgIHQuZmFpbChcInJlbW90ZS5lbXB0eVJlamVjdCgpIGRpZCBub3QgcmVqZWN0IGFzIGV4cGVjdGVkXCIpO1xuICAgICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICAgICAgdC5pcyhlcnIsIHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHJlbW90ZS5yZWplY3RlZCgpO1xuICAgICAgICAgICAgdC5mYWlsKFwicmVtb3RlLnJlamVjdGVkKCkgZGlkIG5vdCByZWplY3QgYXMgZXhwZWN0ZWRcIik7XG4gICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgICAgICB0LmlzKGVyciwgXCJpbnRlbnRpb25hbGx5IHJlamVjdGVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCByZW1vdGUuY3VzdG9tRXJyb3IoKTtcbiAgICAgICAgICAgIHQuZmFpbChcInJlbW90ZS5jdXN0b21FcnJvcigpIGRpZCBub3QgcmVqZWN0IGFzIGV4cGVjdGVkXCIpO1xuICAgICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICAgICAgdC50cnVlKGVyciBpbnN0YW5jZW9mIEZhYXN0RXJyb3IpO1xuICAgICAgICAgICAgdC50cnV0aHkoZXJyLm1lc3NhZ2UubWF0Y2goL15jdXN0b20gZXJyb3IgbWVzc2FnZS8pKTtcbiAgICAgICAgICAgIHQuaXMoRmFhc3RFcnJvci5pbmZvKGVycikuY3VzdG9tLCBcImN1c3RvbSB2YWx1ZVwiKTtcbiAgICAgICAgfVxuICAgICAgICB0LmlzKGF3YWl0IHJlbW90ZS5nZXRFbnYoXCJmYWFzdEVudmlyb25tZW50VmFyaWFibGVcIiksIFwidGhlX2Fuc3dlcl9pc180MlwiKTtcbiAgICAgICAgdC5pcyhhd2FpdCByZW1vdGUuZ2V0RW52KFwiZmFhc3ROb25leGlzdGVudFwiKSwgdW5kZWZpbmVkKTtcbiAgICAgICAgdC5kZWVwRXF1YWwoYXdhaXQgcmVtb3RlLnJldHVybnNFcnJvcigpLCBmdW5jcy5yZXR1cm5zRXJyb3IoKSk7XG5cbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSBbXCJiYXJcIiwgXCJiYXpcIl07XG4gICAgICAgIHQuZGVlcEVxdWFsKGF3YWl0IHRvQXJyYXkocmVtb3RlLmdlbmVyYXRvcihlbGVtZW50cykpLCBlbGVtZW50cyk7XG4gICAgICAgIHQuZGVlcEVxdWFsKGF3YWl0IHRvQXJyYXkocmVtb3RlLmFzeW5jR2VuZXJhdG9yKGVsZW1lbnRzKSksIGVsZW1lbnRzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgXyBvZiByZW1vdGUuYXN5bmNHZW5lcmF0b3JFcnJvcihcImFzeW5jIGdlbmVyYXRvciBmYWlsZWRcIikpIHtcbiAgICAgICAgICAgICAgICAvLyBpZ25vcmVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHQuZmFpbChgcmVtb3RlLmFzeW5jR2VuZXJhdG9yRXJyb3IoKSBkaWQgbm90IHJlamVjdCBhcyBleHBlY3RlZCAoMilgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICAgIHQudHJ1ZShlcnIgaW5zdGFuY2VvZiBGYWFzdEVycm9yKTtcbiAgICAgICAgICAgIHQudHJ1dGh5KChlcnIgYXMgRmFhc3RFcnJvcikubWVzc2FnZS5tYXRjaCgvXmFzeW5jIGdlbmVyYXRvciBmYWlsZWQvKSk7XG4gICAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBmYWFzdE1vZHVsZS5jbGVhbnVwKCk7XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB0ZXN0QmFzaWNSZXF1aXJlKHQ6IEV4ZWN1dGlvbkNvbnRleHQsIHByb3ZpZGVyOiBQcm92aWRlcikge1xuICAgIGNvbnN0IHJlcXVpcmVkRnVuY3MgPSByZXF1aXJlKFwiLi9maXh0dXJlcy9mdW5jdGlvbnNcIik7XG4gICAgY29uc3Qgb3B0czogQ29tbW9uT3B0aW9ucyA9IHsgdGltZW91dDogMzAsIGdjOiBcIm9mZlwiLCBkZXNjcmlwdGlvbjogdC50aXRsZSB9O1xuICAgIGNvbnN0IGZhYXN0TW9kdWxlID0gYXdhaXQgZmFhc3QocHJvdmlkZXIsIHJlcXVpcmVkRnVuY3MsIG9wdHMpO1xuICAgIGNvbnN0IHJlbW90ZSA9IGZhYXN0TW9kdWxlLmZ1bmN0aW9ucztcbiAgICB0cnkge1xuICAgICAgICB0LmlzKGF3YWl0IHJlbW90ZS5pZGVudGl0eVN0cmluZyhcImlkXCIpLCBcImlkXCIpO1xuICAgICAgICB0LmlzKGF3YWl0IHJlbW90ZS5hcnJvdyhcImFycm93XCIpLCBcImFycm93XCIpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGZhYXN0TW9kdWxlLmNsZWFudXAoKTtcbiAgICB9XG59XG5cbi8vIGFzeW5jIGZ1bmN0aW9uIHRlc3RDcHVNZXRyaWNzKHQ6IEV4ZWN1dGlvbkNvbnRleHQsIHByb3ZpZGVyOiBQcm92aWRlcikge1xuLy8gICAgIHQucGxhbig0KTtcblxuLy8gICAgIGNvbnN0IGxhbWJkYSA9IGF3YWl0IGZhYXN0KHByb3ZpZGVyLCBmdW5jcywgIHtcbi8vICAgICAgICAgY2hpbGRQcm9jZXNzOiB0cnVlLFxuLy8gICAgICAgICB0aW1lb3V0OiA5MCxcbi8vICAgICAgICAgbWVtb3J5U2l6ZTogNTEyLFxuLy8gICAgICAgICBtYXhSZXRyaWVzOiAwLFxuLy8gICAgICAgICBnYzogXCJvZmZcIixcbi8vICAgICAgICAgZGVzY3JpcHRpb246IHQudGl0bGVcbi8vICAgICB9KTtcblxuLy8gICAgIHRyeSB7XG4vLyAgICAgICAgIGNvbnN0IE5TZWMgPSA0O1xuLy8gICAgICAgICBhd2FpdCBsYW1iZGEuZnVuY3Rpb25zLnNwaW4oTlNlYyAqIDEwMDApO1xuLy8gICAgICAgICBjb25zdCB1c2FnZSA9IGxhbWJkYS5jcHVVc2FnZS5nZXQoXCJzcGluXCIpO1xuLy8gICAgICAgICB0LnRydXRoeSh1c2FnZSk7XG4vLyAgICAgICAgIHQudHJ1ZSh1c2FnZSEuc2l6ZSA+IDApO1xuLy8gICAgICAgICBmb3IgKGNvbnN0IFssIGluc3RhbmNlXSBvZiB1c2FnZSEpIHtcbi8vICAgICAgICAgICAgIHQudHJ1ZShpbnN0YW5jZS5zdGltZSBpbnN0YW5jZW9mIFN0YXRpc3RpY3MpO1xuLy8gICAgICAgICAgICAgdC50cnVlKGluc3RhbmNlLnV0aW1lIGluc3RhbmNlb2YgU3RhdGlzdGljcyk7XG4vLyAgICAgICAgICAgICBicmVhaztcbi8vICAgICAgICAgfVxuLy8gICAgIH0gZmluYWxseSB7XG4vLyAgICAgICAgIGF3YWl0IGxhbWJkYS5jbGVhbnVwKCk7XG4vLyAgICAgfVxuLy8gfVxuXG5mb3IgKGNvbnN0IHByb3ZpZGVyIG9mIHByb3ZpZGVycykge1xuICAgIGZvciAoY29uc3QgY29uZmlnIG9mIFsuLi5jb25maWdzLCAuLi5ub1ZhbGlkYXRlQ29uZmlnc10pIHtcbiAgICAgICAgdGVzdC5zZXJpYWwodGl0bGUocHJvdmlkZXIsIGBiYXNpYyBjYWxsc2AsIGNvbmZpZyksIHRlc3RCYXNpYywgcHJvdmlkZXIsIGNvbmZpZyk7XG4gICAgfVxuICAgIC8vIFhYWCBEaXNhYmxlIENQVSBtZXRyaWNzIGZvciBub3cuXG4gICAgLy8gdGVzdCh0aXRsZShwcm92aWRlciwgYGNwdSBtZXRyaWNzIGFyZSByZWNlaXZlZGApLCB0ZXN0Q3B1TWV0cmljcywgcHJvdmlkZXIpO1xuICAgIHRlc3Quc2VyaWFsKHRpdGxlKHByb3ZpZGVyLCBgYmFzaWMgY2FsbHMgd2l0aCByZXF1aXJlYCksIHRlc3RCYXNpY1JlcXVpcmUsIHByb3ZpZGVyKTtcbn1cbiJdfQ==
;