UNPKG

faastjs

Version:

Serverless batch computing made simple.

169 lines 23.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * 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 ava_1 = require("ava"); const aws_sdk_1 = require("aws-sdk"); 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 = require("./fixtures/functions"); const util_1 = require("./fixtures/util"); const sqs = new aws_sdk_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 }).promise(); 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 }).promise(); } 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLXRyYW1wb2xpbmUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvYXdzLXRyYW1wb2xpbmUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBOzs7O0dBSUc7QUFDSCw2QkFBdUI7QUFFdkIscUNBQThCO0FBQzlCLCtCQUFvQztBQUNwQyxvREFBa0Q7QUFDbEQsb0RBQXVEO0FBQ3ZELDhEQUEyRDtBQUMzRCw4Q0FBdUQ7QUFDdkQsZ0RBQW9FO0FBQ3BFLDBDQUFzQztBQUN0Qyw0Q0FBeUM7QUFDekMsOENBQThDO0FBQzlDLDBDQUE4RTtBQUU5RSxNQUFNLEdBQUcsR0FBRyxJQUFJLGFBQUcsQ0FBQyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7QUFDdkUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEdBQUcsV0FBVyxDQUFDO0FBQ3JDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxHQUFHLE1BQU0sQ0FBQztBQUVsQyxNQUFNLGFBQWEsR0FBWTtJQUMzQiw4QkFBOEIsRUFBRSxJQUFJO0lBQ3BDLFlBQVksRUFBRSxrQ0FBa0M7SUFDaEQsWUFBWSxFQUFFLGtDQUFrQztJQUNoRCxhQUFhLEVBQUUsbUNBQW1DO0lBQ2xELHdCQUF3QixFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUk7SUFDcEMsWUFBWSxFQUFFLGtDQUFrQztJQUNoRCxlQUFlLEVBQUUscUNBQXFDO0lBQ3RELGtCQUFrQixFQUFFLHdDQUF3QztJQUM1RCxlQUFlLEVBQUUsTUFBTTtJQUN2QixJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQztJQUNkLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFFLENBQUM7SUFDYixPQUFPLEVBQUUsQ0FBQyxDQUFTLEVBQUUsRUFBRSxHQUFFLENBQUM7Q0FDN0IsQ0FBQztBQUVGLEtBQUssVUFBVSxpQkFBaUI7SUFDNUIsTUFBTSxTQUFTLEdB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QixDQUFDLFFBQVEsQ0FBQyxDQUFDO0tBQ3ZDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoZSBwdXJwb3NlIG9mIHRoaXMgdGVzdCBpcyB0byBjaGVjayB0aGF0IHRoZSB0cmFtcG9saW5lIGZ1bmN0aW9uIG9uIEFXUyBjYW5cbiAqIHJvdXRlIGNhbGxzLCBpbnZva2UgdGhlIHdyYXBwZXIsIGFuZCByZXR1cm4gdmFsdWVzIGNvcnJlY3RseSwgd2l0aG91dFxuICogYWN0dWFsbHkgY3JlYXRpbmcgYSBjbG91ZCBmdW5jdGlvbi4gSG93ZXZlciwgaXQgZG9lcyB1c2UgcmVhbCBjbG91ZCBxdWV1ZXMuXG4gKi9cbmltcG9ydCB0ZXN0IGZyb20gXCJhdmFcIjtcbmltcG9ydCB7IENvbnRleHQsIFNOU0V2ZW50IH0gZnJvbSBcImF3cy1sYW1iZGFcIjtcbmltcG9ydCB7IFNRUyB9IGZyb20gXCJhd3Mtc2RrXCI7XG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tIFwidXVpZFwiO1xuaW1wb3J0IHsgQXdzTWV0cmljcyB9IGZyb20gXCIuLi9zcmMvYXdzL2F3cy1mYWFzdFwiO1xuaW1wb3J0IHsgcmVjZWl2ZU1lc3NhZ2VzIH0gZnJvbSBcIi4uL3NyYy9hd3MvYXdzLXF1ZXVlXCI7XG5pbXBvcnQgeyBtYWtlVHJhbXBvbGluZSB9IGZyb20gXCIuLi9zcmMvYXdzL2F3cy10cmFtcG9saW5lXCI7XG5pbXBvcnQgeyBmaWx0ZXJNZXNzYWdlcywgS2luZCB9IGZyb20gXCIuLi9zcmMvcHJvdmlkZXJcIjtcbmltcG9ydCB7IHNlcmlhbGl6ZSwgc2VyaWFsaXplRnVuY3Rpb25BcmdzIH0gZnJvbSBcIi4uL3NyYy9zZXJpYWxpemVcIjtcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSBcIi4uL3NyYy9zaGFyZWRcIjtcbmltcG9ydCB7IFdyYXBwZXIgfSBmcm9tIFwiLi4vc3JjL3dyYXBwZXJcIjtcbmltcG9ydCAqIGFzIGZ1bmNzIGZyb20gXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiO1xuaW1wb3J0IHsgY2hlY2tJdGVyYXRvck1lc3NhZ2VzLCBleHBlY3RNZXNzYWdlLCB0aXRsZSB9IGZyb20gXCIuL2ZpeHR1cmVzL3V0aWxcIjtcblxuY29uc3Qgc3FzID0gbmV3IFNRUyh7IGFwaVZlcnNpb246IFwiMjAxMi0xMS0wNVwiLCByZWdpb246IFwidXMtd2VzdC0yXCIgfSk7XG5wcm9jZXNzLmVudi5BV1NfUkVHSU9OID0gXCJ1cy13ZXN0LTJcIjtcbnByb2Nlc3MuZW52LkZBQVNUX1NJTEVOVCA9IFwidHJ1ZVwiO1xuXG5jb25zdCBsYW1iZGFDb250ZXh0OiBDb250ZXh0ID0ge1xuICAgIGNhbGxiYWNrV2FpdHNGb3JFbXB0eUV2ZW50TG9vcDogdHJ1ZSxcbiAgICBhd3NSZXF1ZXN0SWQ6IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1hd3NSZXF1ZXN0SWRcIixcbiAgICBsb2dHcm91cE5hbWU6IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1sb2dHcm91cE5hbWVcIixcbiAgICBsb2dTdHJlYW1OYW1lOiBcImF3cy10cmFtcG9saW5lLXRlc3QtbG9nU3RyZWFtTmFtZVwiLFxuICAgIGdldFJlbWFpbmluZ1RpbWVJbk1pbGxpczogKCkgPT4gMTAwMCxcbiAgICBmdW5jdGlvbk5hbWU6IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1mdW5jdGlvbk5hbWVcIixcbiAgICBmdW5jdGlvblZlcnNpb246IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1mdW5jdGlvblZlcnNpb25cIixcbiAgICBpbnZva2VkRnVuY3Rpb25Bcm46IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1pbnZva2VkRnVuY3Rpb25Bcm5cIixcbiAgICBtZW1vcnlMaW1pdEluTUI6IFwiMTcyOFwiLFxuICAgIGRvbmU6ICgpID0+IHt9LFxuICAgIGZhaWw6IF8gPT4ge30sXG4gICAgc3VjY2VlZDogKF86IHN0cmluZykgPT4ge31cbn07XG5cbmFzeW5jIGZ1bmN0aW9uIG1ha2VSZXNwb25zZVF1ZXVlKCkge1xuICAgIGNvbnN0IFF1ZXVlTmFtZSA9IGBmYWFzdC0ke3V1aWR2NCgpfS10ZXN0YDtcbiAgICBjb25zdCB7IFF1ZXVlVXJsIH0gPSBhd2FpdCBzcXMuY3JlYXRlUXVldWUoeyBRdWV1ZU5hbWUgfSkucHJvbWlzZSgpO1xuICAgIHJldHVybiBRdWV1ZVVybCE7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGRlbGV0ZVJlc3BvbnNlUXVldWUoUXVldWVVcmw6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICAgIC8vIFNvbWV0aW1lcyBBV1MgbmVlZHMgdGltZSB0byBwcm9wYWdhdGUgdGhlIGV4aXN0ZW5jZSBvZiBhIHF1ZXVlIGJlZm9yZVxuICAgICAgICAvLyBkZWxldGluZyBpdC4gVGhpcyBtYW5pZmVzdHMgYXMgYSBOb25FeGlzdGVudFF1ZXVlIGVycm9yLiBXYWl0aW5nXG4gICAgICAgIC8vIGEgc2hvcnQgd2hpbGUgc2VlbXMgdG8gbWFrZSB0aGlzIGxlc3MgY29tbW9uLlxuICAgICAgICBhd2FpdCBzbGVlcCg1MDAwKTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHNxcy5kZWxldGVRdWV1ZSh7IFF1ZXVlVXJsIH0pLnByb21pc2UoKTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBDb3VsZCBub3QgZGVsZXRlIHJlc3BvbnNlIHF1ZXVlOiAke2Vycn1gKTtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0TWVzc2FnZXM8SyBleHRlbmRzIEtpbmQ+KFF1ZXVlVXJsOiBzdHJpbmcsIGtpbmQ6IEssIG5FeHBlY3RlZDogbnVtYmVyKSB7XG4gICAgY29uc3QgbWV0cmljcyA9IG5ldyBBd3NNZXRyaWNzKCk7XG4gICAgY29uc3QgY2FuY2VsID0gbmV3IFByb21pc2U8dm9pZD4oXyA9PiB7fSk7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgd2hpbGUgKHJlc3VsdC5sZW5ndGggPCBuRXhwZWN0ZWQpIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZXMgPSBhd2FpdCByZWNlaXZlTWVzc2FnZXMoc3FzLCBRdWV1ZVVybCwgbWV0cmljcywgY2FuY2VsKTtcbiAgICAgICAgcmVzdWx0LnB1c2goLi4uZmlsdGVyTWVzc2FnZXMobWVzc2FnZXMuTWVzc2FnZXMsIGtpbmQpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxudGVzdCh0aXRsZShcImF3c1wiLCBcInRyYW1wb2xpbmUgaHR0cHMgbW9kZSB3aXRoIHByb21pc2UgcmVzcG9uc2VcIiksIGFzeW5jIHQgPT4ge1xuICAgIGNvbnN0IHdyYXBwZXIgPSBuZXcgV3JhcHBlcihmdW5jcywgeyBjaGlsZFByb2Nlc3M6IGZhbHNlLCB3cmFwcGVyTG9nOiAoKSA9PiB7fSB9KTtcbiAgICBjb25zdCB7IHRyYW1wb2xpbmUgfSA9IG1ha2VUcmFtcG9saW5lKHdyYXBwZXIpO1xuICAgIGNvbnN0IGFyZyA9IFwicHJvbWlzZSB3aXRoIGh0dHBzIG9uIGF3c1wiO1xuICAgIGNvbnN0IG5hbWUgPSBmdW5jcy5pZGVudGl0eVN0cmluZy5uYW1lO1xuICAgIGNvbnN0IFF1ZXVlVXJsID0gYXdhaXQgbWFrZVJlc3BvbnNlUXVldWUoKTtcbiAgICB0cnkge1xuICAgICAgICBhd2FpdCB0cmFtcG9saW5lKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNhbGxJZDogXCI0MlwiLFxuICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgYXJnczogc2VyaWFsaXplRnVuY3Rpb25BcmdzKG5hbWUsIFthcmddLCB0cnVlKSxcbiAgICAgICAgICAgICAgICBtb2R1bGVQYXRoOiBcIi4vZml4dHVyZXMvZnVuY3Rpb25zXCIsXG4gICAgICAgICAgICAgICAgUmVzcG9uc2VRdWV1ZUlkOiBRdWV1ZVVybFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhbWJkYUNvbnRleHRcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBbbXNnXSA9IGF3YWl0IGdldE1lc3NhZ2VzKFF1ZXVlVXJsLCBcInByb21pc2VcIiwgMSk7XG4gICAgICAgIGV4cGVjdE1lc3NhZ2UodCwgbXNnLCBcInByb21pc2VcIiwgYXJnKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBkZWxldGVSZXNwb25zZVF1ZXVlKFF1ZXVlVXJsKTtcbiAgICB9XG59KTtcblxudGVzdCh0aXRsZShcImF3c1wiLCBcInRyYW1wb2xpbmUgcXVldWUgbW9kZSB3aXRoIHByb21pc2UgcmVzcG9uc2VcIiksIGFzeW5jIHQgPT4ge1xuICAgIGNvbnN0IHdyYXBwZXIgPSBuZXcgV3JhcHBlcihmdW5jcywgeyBjaGlsZFByb2Nlc3M6IGZhbHNlLCB3cmFwcGVyTG9nOiAoKSA9PiB7fSB9KTtcbiAgICBjb25zdCBhcmcgPSBcInByb21pc2Ugd2l0aCBxdWV1ZSBvbiBhd3NcIjtcbiAgICBjb25zdCBRdWV1ZVVybCA9IGF3YWl0IG1ha2VSZXNwb25zZVF1ZXVlKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyB0cmFtcG9saW5lIH0gPSBtYWtlVHJhbXBvbGluZSh3cmFwcGVyKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IGZ1bmNzLmlkZW50aXR5U3RyaW5nLm5hbWU7XG4gICAgICAgIGNvbnN0IGNhbGwgPSB7XG4gICAgICAgICAgICBjYWxsSWQ6IFwiNDNcIixcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBhcmdzOiBzZXJpYWxpemVGdW5jdGlvbkFyZ3MobmFtZSwgW2FyZ10sIHRydWUpLFxuICAgICAgICAgICAgbW9kdWxlUGF0aDogXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiLFxuICAgICAgICAgICAgUmVzcG9uc2VRdWV1ZUlkOiBRdWV1ZVVybFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBldmVudCA9IHtcbiAgICAgICAgICAgIFJlY29yZHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFNuczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZTogc2VyaWFsaXplKGNhbGwpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgdHJhbXBvbGluZShldmVudCBhcyBTTlNFdmVudCwgbGFtYmRhQ29udGV4dCk7XG5cbiAgICAgICAgY29uc3QgW21zZ10gPSBhd2FpdCBnZXRNZXNzYWdlcyhRdWV1ZVVybCwgXCJwcm9taXNlXCIsIDEpO1xuICAgICAgICBleHBlY3RNZXNzYWdlKHQsIG1zZywgXCJwcm9taXNlXCIsIGFyZyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgZGVsZXRlUmVzcG9uc2VRdWV1ZShRdWV1ZVVybCk7XG4gICAgfVxufSk7XG5cbnRlc3QodGl0bGUoXCJhd3NcIiwgXCJ0cmFtcG9saW5lIGh0dHBzIG1vZGUgd2l0aCBhc3luYyBpdGVyYXRvciByZXNwb25zZVwiKSwgYXN5bmMgdCA9PiB7XG4gICAgY29uc3Qgd3JhcHBlciA9IG5ldyBXcmFwcGVyKGZ1bmNzLCB7IGNoaWxkUHJvY2VzczogZmFsc2UsIHdyYXBwZXJMb2c6ICgpID0+IHt9IH0pO1xuICAgIGNvbnN0IHsgdHJhbXBvbGluZSB9ID0gbWFrZVRyYW1wb2xpbmUod3JhcHBlcik7XG4gICAgY29uc3QgbmFtZSA9IGZ1bmNzLmFzeW5jR2VuZXJhdG9yLm5hbWU7XG4gICAgY29uc3QgYXJnID0gW1wiYXN5bmMgZ2VuZXJhdG9yIHdpdGggaHR0cHMgb24gYXdzXCIsIFwic2Vjb25kIGFyZ1wiXTtcbiAgICBjb25zdCBRdWV1ZVVybCA9IGF3YWl0IG1ha2VSZXNwb25zZVF1ZXVlKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdHJhbXBvbGluZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjYWxsSWQ6IFwiNDRcIixcbiAgICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgICAgIGFyZ3M6IHNlcmlhbGl6ZUZ1bmN0aW9uQXJncyhuYW1lLCBbYXJnXSwgdHJ1ZSksXG4gICAgICAgICAgICAgICAgbW9kdWxlUGF0aDogXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiLFxuICAgICAgICAgICAgICAgIFJlc3BvbnNlUXVldWVJZDogUXVldWVVcmxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYW1iZGFDb250ZXh0XG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gYXdhaXQgZ2V0TWVzc2FnZXMoUXVldWVVcmwsIFwiaXRlcmF0b3JcIiwgYXJnLmxlbmd0aCArIDEpO1xuICAgICAgICBjaGVja0l0ZXJhdG9yTWVzc2FnZXModCwgbWVzc2FnZXMsIGFyZyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgZGVsZXRlUmVzcG9uc2VRdWV1ZShRdWV1ZVVybCk7XG4gICAgfVxufSk7XG5cbnRlc3QodGl0bGUoXCJhd3NcIiwgXCJ0cmFtcG9saW5lIHF1ZXVlIG1vZGUgd2l0aCBhc3luYyBpdGVyYXRvciByZXNwb25zZVwiKSwgYXN5bmMgdCA9PiB7XG4gICAgY29uc3Qgd3JhcHBlciA9IG5ldyBXcmFwcGVyKGZ1bmNzLCB7IGNoaWxkUHJvY2VzczogZmFsc2UsIHdyYXBwZXJMb2c6ICgpID0+IHt9IH0pO1xuICAgIGNvbnN0IFF1ZXVlVXJsID0gYXdhaXQgbWFrZVJlc3BvbnNlUXVldWUoKTtcbiAgICBjb25zdCBhcmcgPSBbXCJhc3luYyBnZW5lcmF0b3Igd2l0aCBxdWV1ZSBvbiBhd3NcIiwgXCJzZWNvbmQgYXJnXCJdO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyB0cmFtcG9saW5lIH0gPSBtYWtlVHJhbXBvbGluZSh3cmFwcGVyKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IGZ1bmNzLmFzeW5jR2VuZXJhdG9yLm5hbWU7XG4gICAgICAgIGNvbnN0IGNhbGwgPSB7XG4gICAgICAgICAgICBjYWxsSWQ6IFwiNDVcIixcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBhcmdzOiBzZXJpYWxpemVGdW5jdGlvbkFyZ3MobmFtZSwgW2FyZ10sIHRydWUpLFxuICAgICAgICAgICAgbW9kdWxlUGF0aDogXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiLFxuICAgICAgICAgICAgUmVzcG9uc2VRdWV1ZUlkOiBRdWV1ZVVybFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBldmVudCA9IHtcbiAgICAgICAgICAgIFJlY29yZHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFNuczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZTogc2VyaWFsaXplKGNhbGwpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgdHJhbXBvbGluZShldmVudCBhcyBTTlNFdmVudCwgbGFtYmRhQ29udGV4dCk7XG5cbiAgICAgICAgY29uc3QgbWVzc2FnZXMgPSBhd2FpdCBnZXRNZXNzYWdlcyhRdWV1ZVVybCwgXCJpdGVyYXRvclwiLCBhcmcubGVuZ3RoICsgMSk7XG4gICAgICAgIGNoZWNrSXRlcmF0b3JNZXNzYWdlcyh0LCBtZXNzYWdlcywgYXJnKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBkZWxldGVSZXNwb25zZVF1ZXVlKFF1ZXVlVXJsKTtcbiAgICB9XG59KTtcbiJdfQ==