faastjs
Version:
Serverless batch computing made simple.
170 lines • 23.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
/**
* The purpose of this test is to check that the trampoline function on AWS can
* route calls, invoke the wrapper, and return values correctly, without
* actually creating a cloud function. However, it does use real cloud queues.
*/
const client_sqs_1 = require("@aws-sdk/client-sqs");
const ava_1 = tslib_1.__importDefault(require("ava"));
const uuid_1 = require("uuid");
const aws_faast_1 = require("../src/aws/aws-faast");
const aws_queue_1 = require("../src/aws/aws-queue");
const aws_trampoline_1 = require("../src/aws/aws-trampoline");
const provider_1 = require("../src/provider");
const serialize_1 = require("../src/serialize");
const shared_1 = require("../src/shared");
const wrapper_1 = require("../src/wrapper");
const funcs = tslib_1.__importStar(require("./fixtures/functions"));
const util_1 = require("./fixtures/util");
const sqs = new client_sqs_1.SQS({ apiVersion: "2012-11-05", region: "us-west-2" });
process.env.AWS_REGION = "us-west-2";
process.env.FAAST_SILENT = "true";
const lambdaContext = {
callbackWaitsForEmptyEventLoop: true,
awsRequestId: "aws-trampoline-test-awsRequestId",
logGroupName: "aws-trampoline-test-logGroupName",
logStreamName: "aws-trampoline-test-logStreamName",
getRemainingTimeInMillis: () => 1000,
functionName: "aws-trampoline-test-functionName",
functionVersion: "aws-trampoline-test-functionVersion",
invokedFunctionArn: "aws-trampoline-test-invokedFunctionArn",
memoryLimitInMB: "1728",
done: () => { },
fail: _ => { },
succeed: (_) => { }
};
async function makeResponseQueue() {
const QueueName = `faast-${(0, uuid_1.v4)()}-test`;
const { QueueUrl } = await sqs.createQueue({ QueueName });
return QueueUrl;
}
async function deleteResponseQueue(QueueUrl) {
try {
// Sometimes AWS needs time to propagate the existence of a queue before
// deleting it. This manifests as a NonExistentQueue error. Waiting
// a short while seems to make this less common.
await (0, shared_1.sleep)(5000);
return await sqs.deleteQueue({ QueueUrl });
}
catch (err) {
console.error(`Could not delete response queue: ${err}`);
throw err;
}
}
async function getMessages(QueueUrl, kind, nExpected) {
const metrics = new aws_faast_1.AwsMetrics();
const cancel = new Promise(_ => { });
const result = [];
while (result.length < nExpected) {
const messages = await (0, aws_queue_1.receiveMessages)(sqs, QueueUrl, metrics, cancel);
result.push(...(0, provider_1.filterMessages)(messages.Messages, kind));
}
return result;
}
(0, ava_1.default)((0, util_1.title)("aws", "trampoline https mode with promise response"), async (t) => {
const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
const { trampoline } = (0, aws_trampoline_1.makeTrampoline)(wrapper);
const arg = "promise with https on aws";
const name = funcs.identityString.name;
const QueueUrl = await makeResponseQueue();
try {
await trampoline({
callId: "42",
name,
args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
modulePath: "./fixtures/functions",
ResponseQueueId: QueueUrl
}, lambdaContext);
const [msg] = await getMessages(QueueUrl, "promise", 1);
(0, util_1.expectMessage)(t, msg, "promise", arg);
}
finally {
deleteResponseQueue(QueueUrl);
}
});
(0, ava_1.default)((0, util_1.title)("aws", "trampoline queue mode with promise response"), async (t) => {
const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
const arg = "promise with queue on aws";
const QueueUrl = await makeResponseQueue();
try {
const { trampoline } = (0, aws_trampoline_1.makeTrampoline)(wrapper);
const name = funcs.identityString.name;
const call = {
callId: "43",
name,
args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
modulePath: "./fixtures/functions",
ResponseQueueId: QueueUrl
};
const event = {
Records: [
{
Sns: {
Message: (0, serialize_1.serialize)(call)
}
}
]
};
await trampoline(event, lambdaContext);
const [msg] = await getMessages(QueueUrl, "promise", 1);
(0, util_1.expectMessage)(t, msg, "promise", arg);
}
finally {
await deleteResponseQueue(QueueUrl);
}
});
(0, ava_1.default)((0, util_1.title)("aws", "trampoline https mode with async iterator response"), async (t) => {
const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
const { trampoline } = (0, aws_trampoline_1.makeTrampoline)(wrapper);
const name = funcs.asyncGenerator.name;
const arg = ["async generator with https on aws", "second arg"];
const QueueUrl = await makeResponseQueue();
try {
await trampoline({
callId: "44",
name,
args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
modulePath: "./fixtures/functions",
ResponseQueueId: QueueUrl
}, lambdaContext);
const messages = await getMessages(QueueUrl, "iterator", arg.length + 1);
(0, util_1.checkIteratorMessages)(t, messages, arg);
}
finally {
await deleteResponseQueue(QueueUrl);
}
});
(0, ava_1.default)((0, util_1.title)("aws", "trampoline queue mode with async iterator response"), async (t) => {
const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
const QueueUrl = await makeResponseQueue();
const arg = ["async generator with queue on aws", "second arg"];
try {
const { trampoline } = (0, aws_trampoline_1.makeTrampoline)(wrapper);
const name = funcs.asyncGenerator.name;
const call = {
callId: "45",
name,
args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
modulePath: "./fixtures/functions",
ResponseQueueId: QueueUrl
};
const event = {
Records: [
{
Sns: {
Message: (0, serialize_1.serialize)(call)
}
}
]
};
await trampoline(event, lambdaContext);
const messages = await getMessages(QueueUrl, "iterator", arg.length + 1);
(0, util_1.checkIteratorMessages)(t, messages, arg);
}
finally {
await deleteResponseQueue(QueueUrl);
}
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLXRyYW1wb2xpbmUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvYXdzLXRyYW1wb2xpbmUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7OztHQUlHO0FBQ0gsb0RBQTBDO0FBQzFDLHNEQUF1QjtBQUV2QiwrQkFBb0M7QUFDcEMsb0RBQWtEO0FBQ2xELG9EQUF1RDtBQUN2RCw4REFBMkQ7QUFDM0QsOENBQXVEO0FBQ3ZELGdEQUFvRTtBQUNwRSwwQ0FBc0M7QUFDdEMsNENBQXlDO0FBQ3pDLG9FQUE4QztBQUM5QywwQ0FBOEU7QUFFOUUsTUFBTSxHQUFHLEdBQUcsSUFBSSxnQkFBRyxDQUFDLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUN2RSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsR0FBRyxXQUFXLENBQUM7QUFDckMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLEdBQUcsTUFBTSxDQUFDO0FBRWxDLE1BQU0sYUFBYSxHQUFZO0lBQzNCLDhCQUE4QixFQUFFLElBQUk7SUFDcEMsWUFBWSxFQUFFLGtDQUFrQztJQUNoRCxZQUFZLEVBQUUsa0NBQWtDO0lBQ2hELGFBQWEsRUFBRSxtQ0FBbUM7SUFDbEQsd0JBQXdCLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSTtJQUNwQyxZQUFZLEVBQUUsa0NBQWtDO0lBQ2hELGVBQWUsRUFBRSxxQ0FBcUM7SUFDdEQsa0JBQWtCLEVBQUUsd0NBQXdDO0lBQzVELGVBQWUsRUFBRSxNQUFNO0lBQ3ZCLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRSxDQUFDO0lBQ2QsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUUsQ0FBQztJQUNiLE9BQU8sRUFBRSxDQUFDLENBQVMsRUFBRSxFQUFFLEdBQUUsQ0FBQztDQUM3QixDQUFDO0FBRUYsS0FBSyxVQUFVLGlCQUFpQjtJQUM1QixNQUFNLFNBQVMs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QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhlIHB1cnBvc2Ugb2YgdGhpcyB0ZXN0IGlzIHRvIGNoZWNrIHRoYXQgdGhlIHRyYW1wb2xpbmUgZnVuY3Rpb24gb24gQVdTIGNhblxuICogcm91dGUgY2FsbHMsIGludm9rZSB0aGUgd3JhcHBlciwgYW5kIHJldHVybiB2YWx1ZXMgY29ycmVjdGx5LCB3aXRob3V0XG4gKiBhY3R1YWxseSBjcmVhdGluZyBhIGNsb3VkIGZ1bmN0aW9uLiBIb3dldmVyLCBpdCBkb2VzIHVzZSByZWFsIGNsb3VkIHF1ZXVlcy5cbiAqL1xuaW1wb3J0IHsgU1FTIH0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1zcXNcIjtcbmltcG9ydCB0ZXN0IGZyb20gXCJhdmFcIjtcbmltcG9ydCB7IENvbnRleHQsIFNOU0V2ZW50IH0gZnJvbSBcImF3cy1sYW1iZGFcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWR2NCB9IGZyb20gXCJ1dWlkXCI7XG5pbXBvcnQgeyBBd3NNZXRyaWNzIH0gZnJvbSBcIi4uL3NyYy9hd3MvYXdzLWZhYXN0XCI7XG5pbXBvcnQgeyByZWNlaXZlTWVzc2FnZXMgfSBmcm9tIFwiLi4vc3JjL2F3cy9hd3MtcXVldWVcIjtcbmltcG9ydCB7IG1ha2VUcmFtcG9saW5lIH0gZnJvbSBcIi4uL3NyYy9hd3MvYXdzLXRyYW1wb2xpbmVcIjtcbmltcG9ydCB7IGZpbHRlck1lc3NhZ2VzLCBLaW5kIH0gZnJvbSBcIi4uL3NyYy9wcm92aWRlclwiO1xuaW1wb3J0IHsgc2VyaWFsaXplLCBzZXJpYWxpemVGdW5jdGlvbkFyZ3MgfSBmcm9tIFwiLi4vc3JjL3NlcmlhbGl6ZVwiO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tIFwiLi4vc3JjL3NoYXJlZFwiO1xuaW1wb3J0IHsgV3JhcHBlciB9IGZyb20gXCIuLi9zcmMvd3JhcHBlclwiO1xuaW1wb3J0ICogYXMgZnVuY3MgZnJvbSBcIi4vZml4dHVyZXMvZnVuY3Rpb25zXCI7XG5pbXBvcnQgeyBjaGVja0l0ZXJhdG9yTWVzc2FnZXMsIGV4cGVjdE1lc3NhZ2UsIHRpdGxlIH0gZnJvbSBcIi4vZml4dHVyZXMvdXRpbFwiO1xuXG5jb25zdCBzcXMgPSBuZXcgU1FTKHsgYXBpVmVyc2lvbjogXCIyMDEyLTExLTA1XCIsIHJlZ2lvbjogXCJ1cy13ZXN0LTJcIiB9KTtcbnByb2Nlc3MuZW52LkFXU19SRUdJT04gPSBcInVzLXdlc3QtMlwiO1xucHJvY2Vzcy5lbnYuRkFBU1RfU0lMRU5UID0gXCJ0cnVlXCI7XG5cbmNvbnN0IGxhbWJkYUNvbnRleHQ6IENvbnRleHQgPSB7XG4gICAgY2FsbGJhY2tXYWl0c0ZvckVtcHR5RXZlbnRMb29wOiB0cnVlLFxuICAgIGF3c1JlcXVlc3RJZDogXCJhd3MtdHJhbXBvbGluZS10ZXN0LWF3c1JlcXVlc3RJZFwiLFxuICAgIGxvZ0dyb3VwTmFtZTogXCJhd3MtdHJhbXBvbGluZS10ZXN0LWxvZ0dyb3VwTmFtZVwiLFxuICAgIGxvZ1N0cmVhbU5hbWU6IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1sb2dTdHJlYW1OYW1lXCIsXG4gICAgZ2V0UmVtYWluaW5nVGltZUluTWlsbGlzOiAoKSA9PiAxMDAwLFxuICAgIGZ1bmN0aW9uTmFtZTogXCJhd3MtdHJhbXBvbGluZS10ZXN0LWZ1bmN0aW9uTmFtZVwiLFxuICAgIGZ1bmN0aW9uVmVyc2lvbjogXCJhd3MtdHJhbXBvbGluZS10ZXN0LWZ1bmN0aW9uVmVyc2lvblwiLFxuICAgIGludm9rZWRGdW5jdGlvbkFybjogXCJhd3MtdHJhbXBvbGluZS10ZXN0LWludm9rZWRGdW5jdGlvbkFyblwiLFxuICAgIG1lbW9yeUxpbWl0SW5NQjogXCIxNzI4XCIsXG4gICAgZG9uZTogKCkgPT4ge30sXG4gICAgZmFpbDogXyA9PiB7fSxcbiAgICBzdWNjZWVkOiAoXzogc3RyaW5nKSA9PiB7fVxufTtcblxuYXN5bmMgZnVuY3Rpb24gbWFrZVJlc3BvbnNlUXVldWUoKSB7XG4gICAgY29uc3QgUXVldWVOYW1lID0gYGZhYXN0LSR7dXVpZHY0KCl9LXRlc3RgO1xuICAgIGNvbnN0IHsgUXVldWVVcmwgfSA9IGF3YWl0IHNxcy5jcmVhdGVRdWV1ZSh7IFF1ZXVlTmFtZSB9KTtcbiAgICByZXR1cm4gUXVldWVVcmwhO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZWxldGVSZXNwb25zZVF1ZXVlKFF1ZXVlVXJsOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgICAvLyBTb21ldGltZXMgQVdTIG5lZWRzIHRpbWUgdG8gcHJvcGFnYXRlIHRoZSBleGlzdGVuY2Ugb2YgYSBxdWV1ZSBiZWZvcmVcbiAgICAgICAgLy8gZGVsZXRpbmcgaXQuIFRoaXMgbWFuaWZlc3RzIGFzIGEgTm9uRXhpc3RlbnRRdWV1ZSBlcnJvci4gV2FpdGluZ1xuICAgICAgICAvLyBhIHNob3J0IHdoaWxlIHNlZW1zIHRvIG1ha2UgdGhpcyBsZXNzIGNvbW1vbi5cbiAgICAgICAgYXdhaXQgc2xlZXAoNTAwMCk7XG4gICAgICAgIHJldHVybiBhd2FpdCBzcXMuZGVsZXRlUXVldWUoeyBRdWV1ZVVybCB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgQ291bGQgbm90IGRlbGV0ZSByZXNwb25zZSBxdWV1ZTogJHtlcnJ9YCk7XG4gICAgICAgIHRocm93IGVycjtcbiAgICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldE1lc3NhZ2VzPEsgZXh0ZW5kcyBLaW5kPihRdWV1ZVVybDogc3RyaW5nLCBraW5kOiBLLCBuRXhwZWN0ZWQ6IG51bWJlcikge1xuICAgIGNvbnN0IG1ldHJpY3MgPSBuZXcgQXdzTWV0cmljcygpO1xuICAgIGNvbnN0IGNhbmNlbCA9IG5ldyBQcm9taXNlPHZvaWQ+KF8gPT4ge30pO1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIHdoaWxlIChyZXN1bHQubGVuZ3RoIDwgbkV4cGVjdGVkKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gYXdhaXQgcmVjZWl2ZU1lc3NhZ2VzKHNxcywgUXVldWVVcmwsIG1ldHJpY3MsIGNhbmNlbCk7XG4gICAgICAgIHJlc3VsdC5wdXNoKC4uLmZpbHRlck1lc3NhZ2VzKG1lc3NhZ2VzLk1lc3NhZ2VzLCBraW5kKSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbnRlc3QodGl0bGUoXCJhd3NcIiwgXCJ0cmFtcG9saW5lIGh0dHBzIG1vZGUgd2l0aCBwcm9taXNlIHJlc3BvbnNlXCIpLCBhc3luYyB0ID0+IHtcbiAgICBjb25zdCB3cmFwcGVyID0gbmV3IFdyYXBwZXIoZnVuY3MsIHsgY2hpbGRQcm9jZXNzOiBmYWxzZSwgd3JhcHBlckxvZzogKCkgPT4ge30gfSk7XG4gICAgY29uc3QgeyB0cmFtcG9saW5lIH0gPSBtYWtlVHJhbXBvbGluZSh3cmFwcGVyKTtcbiAgICBjb25zdCBhcmcgPSBcInByb21pc2Ugd2l0aCBodHRwcyBvbiBhd3NcIjtcbiAgICBjb25zdCBuYW1lID0gZnVuY3MuaWRlbnRpdHlTdHJpbmcubmFtZTtcbiAgICBjb25zdCBRdWV1ZVVybCA9IGF3YWl0IG1ha2VSZXNwb25zZVF1ZXVlKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdHJhbXBvbGluZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjYWxsSWQ6IFwiNDJcIixcbiAgICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgICAgIGFyZ3M6IHNlcmlhbGl6ZUZ1bmN0aW9uQXJncyhuYW1lLCBbYXJnXSwgdHJ1ZSksXG4gICAgICAgICAgICAgICAgbW9kdWxlUGF0aDogXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiLFxuICAgICAgICAgICAgICAgIFJlc3BvbnNlUXVldWVJZDogUXVldWVVcmxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYW1iZGFDb250ZXh0XG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgW21zZ10gPSBhd2FpdCBnZXRNZXNzYWdlcyhRdWV1ZVVybCwgXCJwcm9taXNlXCIsIDEpO1xuICAgICAgICBleHBlY3RNZXNzYWdlKHQsIG1zZywgXCJwcm9taXNlXCIsIGFyZyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgZGVsZXRlUmVzcG9uc2VRdWV1ZShRdWV1ZVVybCk7XG4gICAgfVxufSk7XG5cbnRlc3QodGl0bGUoXCJhd3NcIiwgXCJ0cmFtcG9saW5lIHF1ZXVlIG1vZGUgd2l0aCBwcm9taXNlIHJlc3BvbnNlXCIpLCBhc3luYyB0ID0+IHtcbiAgICBjb25zdCB3cmFwcGVyID0gbmV3IFdyYXBwZXIoZnVuY3MsIHsgY2hpbGRQcm9jZXNzOiBmYWxzZSwgd3JhcHBlckxvZzogKCkgPT4ge30gfSk7XG4gICAgY29uc3QgYXJnID0gXCJwcm9taXNlIHdpdGggcXVldWUgb24gYXdzXCI7XG4gICAgY29uc3QgUXVldWVVcmwgPSBhd2FpdCBtYWtlUmVzcG9uc2VRdWV1ZSgpO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgdHJhbXBvbGluZSB9ID0gbWFrZVRyYW1wb2xpbmUod3JhcHBlcik7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBmdW5jcy5pZGVudGl0eVN0cmluZy5uYW1lO1xuICAgICAgICBjb25zdCBjYWxsID0ge1xuICAgICAgICAgICAgY2FsbElkOiBcIjQzXCIsXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgYXJnczogc2VyaWFsaXplRnVuY3Rpb25BcmdzKG5hbWUsIFthcmddLCB0cnVlKSxcbiAgICAgICAgICAgIG1vZHVsZVBhdGg6IFwiLi9maXh0dXJlcy9mdW5jdGlvbnNcIixcbiAgICAgICAgICAgIFJlc3BvbnNlUXVldWVJZDogUXVldWVVcmxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB7XG4gICAgICAgICAgICBSZWNvcmRzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBTbnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2U6IHNlcmlhbGl6ZShjYWxsKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IHRyYW1wb2xpbmUoZXZlbnQgYXMgU05TRXZlbnQsIGxhbWJkYUNvbnRleHQpO1xuXG4gICAgICAgIGNvbnN0IFttc2ddID0gYXdhaXQgZ2V0TWVzc2FnZXMoUXVldWVVcmwsIFwicHJvbWlzZVwiLCAxKTtcbiAgICAgICAgZXhwZWN0TWVzc2FnZSh0LCBtc2csIFwicHJvbWlzZVwiLCBhcmcpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGRlbGV0ZVJlc3BvbnNlUXVldWUoUXVldWVVcmwpO1xuICAgIH1cbn0pO1xuXG50ZXN0KHRpdGxlKFwiYXdzXCIsIFwidHJhbXBvbGluZSBodHRwcyBtb2RlIHdpdGggYXN5bmMgaXRlcmF0b3IgcmVzcG9uc2VcIiksIGFzeW5jIHQgPT4ge1xuICAgIGNvbnN0IHdyYXBwZXIgPSBuZXcgV3JhcHBlcihmdW5jcywgeyBjaGlsZFByb2Nlc3M6IGZhbHNlLCB3cmFwcGVyTG9nOiAoKSA9PiB7fSB9KTtcbiAgICBjb25zdCB7IHRyYW1wb2xpbmUgfSA9IG1ha2VUcmFtcG9saW5lKHdyYXBwZXIpO1xuICAgIGNvbnN0IG5hbWUgPSBmdW5jcy5hc3luY0dlbmVyYXRvci5uYW1lO1xuICAgIGNvbnN0IGFyZyA9IFtcImFzeW5jIGdlbmVyYXRvciB3aXRoIGh0dHBzIG9uIGF3c1wiLCBcInNlY29uZCBhcmdcIl07XG4gICAgY29uc3QgUXVldWVVcmwgPSBhd2FpdCBtYWtlUmVzcG9uc2VRdWV1ZSgpO1xuICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRyYW1wb2xpbmUoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY2FsbElkOiBcIjQ0XCIsXG4gICAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgICAgICBhcmdzOiBzZXJpYWxpemVGdW5jdGlvbkFyZ3MobmFtZSwgW2FyZ10sIHRydWUpLFxuICAgICAgICAgICAgICAgIG1vZHVsZVBhdGg6IFwiLi9maXh0dXJlcy9mdW5jdGlvbnNcIixcbiAgICAgICAgICAgICAgICBSZXNwb25zZVF1ZXVlSWQ6IFF1ZXVlVXJsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFtYmRhQ29udGV4dFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBtZXNzYWdlcyA9IGF3YWl0IGdldE1lc3NhZ2VzKFF1ZXVlVXJsLCBcIml0ZXJhdG9yXCIsIGFyZy5sZW5ndGggKyAxKTtcbiAgICAgICAgY2hlY2tJdGVyYXRvck1lc3NhZ2VzKHQsIG1lc3NhZ2VzLCBhcmcpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGRlbGV0ZVJlc3BvbnNlUXVldWUoUXVldWVVcmwpO1xuICAgIH1cbn0pO1xuXG50ZXN0KHRpdGxlKFwiYXdzXCIsIFwidHJhbXBvbGluZSBxdWV1ZSBtb2RlIHdpdGggYXN5bmMgaXRlcmF0b3IgcmVzcG9uc2VcIiksIGFzeW5jIHQgPT4ge1xuICAgIGNvbnN0IHdyYXBwZXIgPSBuZXcgV3JhcHBlcihmdW5jcywgeyBjaGlsZFByb2Nlc3M6IGZhbHNlLCB3cmFwcGVyTG9nOiAoKSA9PiB7fSB9KTtcbiAgICBjb25zdCBRdWV1ZVVybCA9IGF3YWl0IG1ha2VSZXNwb25zZVF1ZXVlKCk7XG4gICAgY29uc3QgYXJnID0gW1wiYXN5bmMgZ2VuZXJhdG9yIHdpdGggcXVldWUgb24gYXdzXCIsIFwic2Vjb25kIGFyZ1wiXTtcblxuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgdHJhbXBvbGluZSB9ID0gbWFrZVRyYW1wb2xpbmUod3JhcHBlcik7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBmdW5jcy5hc3luY0dlbmVyYXRvci5uYW1lO1xuICAgICAgICBjb25zdCBjYWxsID0ge1xuICAgICAgICAgICAgY2FsbElkOiBcIjQ1XCIsXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgYXJnczogc2VyaWFsaXplRnVuY3Rpb25BcmdzKG5hbWUsIFthcmddLCB0cnVlKSxcbiAgICAgICAgICAgIG1vZHVsZVBhdGg6IFwiLi9maXh0dXJlcy9mdW5jdGlvbnNcIixcbiAgICAgICAgICAgIFJlc3BvbnNlUXVldWVJZDogUXVldWVVcmxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB7XG4gICAgICAgICAgICBSZWNvcmRzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBTbnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2U6IHNlcmlhbGl6ZShjYWxsKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IHRyYW1wb2xpbmUoZXZlbnQgYXMgU05TRXZlbnQsIGxhbWJkYUNvbnRleHQpO1xuXG4gICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gYXdhaXQgZ2V0TWVzc2FnZXMoUXVldWVVcmwsIFwiaXRlcmF0b3JcIiwgYXJnLmxlbmd0aCArIDEpO1xuICAgICAgICBjaGVja0l0ZXJhdG9yTWVzc2FnZXModCwgbWVzc2FnZXMsIGFyZyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgZGVsZXRlUmVzcG9uc2VRdWV1ZShRdWV1ZVVybCk7XG4gICAgfVxufSk7XG4iXX0=