1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | /**
|
4 | * The purpose of this test is to check that the trampoline function on AWS can
|
5 | * route calls, invoke the wrapper, and return values correctly, without
|
6 | * actually creating a cloud function. However, it does use real cloud queues.
|
7 | */
|
8 | const ava_1 = require("ava");
|
9 | const aws_sdk_1 = require("aws-sdk");
|
10 | const uuid_1 = require("uuid");
|
11 | const aws_faast_1 = require("../src/aws/aws-faast");
|
12 | const aws_queue_1 = require("../src/aws/aws-queue");
|
13 | const aws_trampoline_1 = require("../src/aws/aws-trampoline");
|
14 | const provider_1 = require("../src/provider");
|
15 | const serialize_1 = require("../src/serialize");
|
16 | const shared_1 = require("../src/shared");
|
17 | const wrapper_1 = require("../src/wrapper");
|
18 | const funcs = require("./fixtures/functions");
|
19 | const util_1 = require("./fixtures/util");
|
20 | const sqs = new aws_sdk_1.SQS({ apiVersion: "2012-11-05", region: "us-west-2" });
|
21 | process.env.AWS_REGION = "us-west-2";
|
22 | process.env.FAAST_SILENT = "true";
|
23 | const lambdaContext = {
|
24 | callbackWaitsForEmptyEventLoop: true,
|
25 | awsRequestId: "aws-trampoline-test-awsRequestId",
|
26 | logGroupName: "aws-trampoline-test-logGroupName",
|
27 | logStreamName: "aws-trampoline-test-logStreamName",
|
28 | getRemainingTimeInMillis: () => 1000,
|
29 | functionName: "aws-trampoline-test-functionName",
|
30 | functionVersion: "aws-trampoline-test-functionVersion",
|
31 | invokedFunctionArn: "aws-trampoline-test-invokedFunctionArn",
|
32 | memoryLimitInMB: "1728",
|
33 | done: () => { },
|
34 | fail: _ => { },
|
35 | succeed: (_) => { }
|
36 | };
|
37 | async function makeResponseQueue() {
|
38 | const QueueName = `faast-${(0, uuid_1.v4)()}-test`;
|
39 | const { QueueUrl } = await sqs.createQueue({ QueueName }).promise();
|
40 | return QueueUrl;
|
41 | }
|
42 | async function deleteResponseQueue(QueueUrl) {
|
43 | try {
|
44 | // Sometimes AWS needs time to propagate the existence of a queue before
|
45 | // deleting it. This manifests as a NonExistentQueue error. Waiting
|
46 | // a short while seems to make this less common.
|
47 | await (0, shared_1.sleep)(5000);
|
48 | return await sqs.deleteQueue({ QueueUrl }).promise();
|
49 | }
|
50 | catch (err) {
|
51 | console.error(`Could not delete response queue: ${err}`);
|
52 | throw err;
|
53 | }
|
54 | }
|
55 | async function getMessages(QueueUrl, kind, nExpected) {
|
56 | const metrics = new aws_faast_1.AwsMetrics();
|
57 | const cancel = new Promise(_ => { });
|
58 | const result = [];
|
59 | while (result.length < nExpected) {
|
60 | const messages = await (0, aws_queue_1.receiveMessages)(sqs, QueueUrl, metrics, cancel);
|
61 | result.push(...(0, provider_1.filterMessages)(messages.Messages, kind));
|
62 | }
|
63 | return result;
|
64 | }
|
65 | (0, ava_1.default)((0, util_1.title)("aws", "trampoline https mode with promise response"), async (t) => {
|
66 | const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
|
67 | const { trampoline } = (0, aws_trampoline_1.makeTrampoline)(wrapper);
|
68 | const arg = "promise with https on aws";
|
69 | const name = funcs.identityString.name;
|
70 | const QueueUrl = await makeResponseQueue();
|
71 | try {
|
72 | await trampoline({
|
73 | callId: "42",
|
74 | name,
|
75 | args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
|
76 | modulePath: "./fixtures/functions",
|
77 | ResponseQueueId: QueueUrl
|
78 | }, lambdaContext);
|
79 | const [msg] = await getMessages(QueueUrl, "promise", 1);
|
80 | (0, util_1.expectMessage)(t, msg, "promise", arg);
|
81 | }
|
82 | finally {
|
83 | deleteResponseQueue(QueueUrl);
|
84 | }
|
85 | });
|
86 | (0, ava_1.default)((0, util_1.title)("aws", "trampoline queue mode with promise response"), async (t) => {
|
87 | const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
|
88 | const arg = "promise with queue on aws";
|
89 | const QueueUrl = await makeResponseQueue();
|
90 | try {
|
91 | const { trampoline } = (0, aws_trampoline_1.makeTrampoline)(wrapper);
|
92 | const name = funcs.identityString.name;
|
93 | const call = {
|
94 | callId: "43",
|
95 | name,
|
96 | args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
|
97 | modulePath: "./fixtures/functions",
|
98 | ResponseQueueId: QueueUrl
|
99 | };
|
100 | const event = {
|
101 | Records: [
|
102 | {
|
103 | Sns: {
|
104 | Message: (0, serialize_1.serialize)(call)
|
105 | }
|
106 | }
|
107 | ]
|
108 | };
|
109 | await trampoline(event, lambdaContext);
|
110 | const [msg] = await getMessages(QueueUrl, "promise", 1);
|
111 | (0, util_1.expectMessage)(t, msg, "promise", arg);
|
112 | }
|
113 | finally {
|
114 | await deleteResponseQueue(QueueUrl);
|
115 | }
|
116 | });
|
117 | (0, ava_1.default)((0, util_1.title)("aws", "trampoline https mode with async iterator response"), async (t) => {
|
118 | const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
|
119 | const { trampoline } = (0, aws_trampoline_1.makeTrampoline)(wrapper);
|
120 | const name = funcs.asyncGenerator.name;
|
121 | const arg = ["async generator with https on aws", "second arg"];
|
122 | const QueueUrl = await makeResponseQueue();
|
123 | try {
|
124 | await trampoline({
|
125 | callId: "44",
|
126 | name,
|
127 | args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
|
128 | modulePath: "./fixtures/functions",
|
129 | ResponseQueueId: QueueUrl
|
130 | }, lambdaContext);
|
131 | const messages = await getMessages(QueueUrl, "iterator", arg.length + 1);
|
132 | (0, util_1.checkIteratorMessages)(t, messages, arg);
|
133 | }
|
134 | finally {
|
135 | await deleteResponseQueue(QueueUrl);
|
136 | }
|
137 | });
|
138 | (0, ava_1.default)((0, util_1.title)("aws", "trampoline queue mode with async iterator response"), async (t) => {
|
139 | const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
|
140 | const QueueUrl = await makeResponseQueue();
|
141 | const arg = ["async generator with queue on aws", "second arg"];
|
142 | try {
|
143 | const { trampoline } = (0, aws_trampoline_1.makeTrampoline)(wrapper);
|
144 | const name = funcs.asyncGenerator.name;
|
145 | const call = {
|
146 | callId: "45",
|
147 | name,
|
148 | args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
|
149 | modulePath: "./fixtures/functions",
|
150 | ResponseQueueId: QueueUrl
|
151 | };
|
152 | const event = {
|
153 | Records: [
|
154 | {
|
155 | Sns: {
|
156 | Message: (0, serialize_1.serialize)(call)
|
157 | }
|
158 | }
|
159 | ]
|
160 | };
|
161 | await trampoline(event, lambdaContext);
|
162 | const messages = await getMessages(QueueUrl, "iterator", arg.length + 1);
|
163 | (0, util_1.checkIteratorMessages)(t, messages, arg);
|
164 | }
|
165 | finally {
|
166 | await deleteResponseQueue(QueueUrl);
|
167 | }
|
168 | });
|
169 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLXRyYW1wb2xpbmUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvYXdzLXRyYW1wb2xpbmUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBOzs7O0dBSUc7QUFDSCw2QkFBdUI7QUFFdkIscUNBQThCO0FBQzlCLCtCQUFvQztBQUNwQyxvREFBa0Q7QUFDbEQsb0RBQXVEO0FBQ3ZELDhEQUEyRDtBQUMzRCw4Q0FBdUQ7QUFDdkQsZ0RBQW9FO0FBQ3BFLDBDQUFzQztBQUN0Qyw0Q0FBeUM7QUFDekMsOENBQThDO0FBQzlDLDBDQUE4RTtBQUU5RSxNQUFNLEdBQUcsR0FBRyxJQUFJLGFBQUcsQ0FBQyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7QUFDdkUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEdBQUcsV0FBVyxDQUFDO0FBQ3JDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxHQUFHLE1BQU0sQ0FBQztBQUVsQyxNQUFNLGFBQWEsR0FBWTtJQUMzQiw4QkFBOEIsRUFBRSxJQUFJO0lBQ3BDLFlBQVksRUFBRSxrQ0FBa0M7SUFDaEQsWUFBWSxFQUFFLGtDQUFrQztJQUNoRCxhQUFhLEVBQUUsbUNBQW1DO0lBQ2xELHdCQUF3QixFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUk7SUFDcEMsWUFBWSxFQUFFLGtDQUFrQztJQUNoRCxlQUFlLEVBQUUscUNBQXFDO0lBQ3RELGtCQUFrQixFQUFFLHdDQUF3QztJQUM1RCxlQUFlLEVBQUUsTUFBTTtJQUN2QixJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQztJQUNkLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFFLENBQUM7SUFDYixPQUFPLEVBQUUsQ0FBQyxDQUFTLEVBQUUsRUFBRSxHQUFFLENBQUM7Q0FDN0IsQ0FBQztBQUVGLEtBQUssVUFBVSxpQkFBaUI7SUFDNUIsTUFBTSxTQUFTLEdB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QixDQUFDLFFBQVEsQ0FBQyxDQUFDO0tBQ3ZDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoZSBwdXJwb3NlIG9mIHRoaXMgdGVzdCBpcyB0byBjaGVjayB0aGF0IHRoZSB0cmFtcG9saW5lIGZ1bmN0aW9uIG9uIEFXUyBjYW5cbiAqIHJvdXRlIGNhbGxzLCBpbnZva2UgdGhlIHdyYXBwZXIsIGFuZCByZXR1cm4gdmFsdWVzIGNvcnJlY3RseSwgd2l0aG91dFxuICogYWN0dWFsbHkgY3JlYXRpbmcgYSBjbG91ZCBmdW5jdGlvbi4gSG93ZXZlciwgaXQgZG9lcyB1c2UgcmVhbCBjbG91ZCBxdWV1ZXMuXG4gKi9cbmltcG9ydCB0ZXN0IGZyb20gXCJhdmFcIjtcbmltcG9ydCB7IENvbnRleHQsIFNOU0V2ZW50IH0gZnJvbSBcImF3cy1sYW1iZGFcIjtcbmltcG9ydCB7IFNRUyB9IGZyb20gXCJhd3Mtc2RrXCI7XG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tIFwidXVpZFwiO1xuaW1wb3J0IHsgQXdzTWV0cmljcyB9IGZyb20gXCIuLi9zcmMvYXdzL2F3cy1mYWFzdFwiO1xuaW1wb3J0IHsgcmVjZWl2ZU1lc3NhZ2VzIH0gZnJvbSBcIi4uL3NyYy9hd3MvYXdzLXF1ZXVlXCI7XG5pbXBvcnQgeyBtYWtlVHJhbXBvbGluZSB9IGZyb20gXCIuLi9zcmMvYXdzL2F3cy10cmFtcG9saW5lXCI7XG5pbXBvcnQgeyBmaWx0ZXJNZXNzYWdlcywgS2luZCB9IGZyb20gXCIuLi9zcmMvcHJvdmlkZXJcIjtcbmltcG9ydCB7IHNlcmlhbGl6ZSwgc2VyaWFsaXplRnVuY3Rpb25BcmdzIH0gZnJvbSBcIi4uL3NyYy9zZXJpYWxpemVcIjtcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSBcIi4uL3NyYy9zaGFyZWRcIjtcbmltcG9ydCB7IFdyYXBwZXIgfSBmcm9tIFwiLi4vc3JjL3dyYXBwZXJcIjtcbmltcG9ydCAqIGFzIGZ1bmNzIGZyb20gXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiO1xuaW1wb3J0IHsgY2hlY2tJdGVyYXRvck1lc3NhZ2VzLCBleHBlY3RNZXNzYWdlLCB0aXRsZSB9IGZyb20gXCIuL2ZpeHR1cmVzL3V0aWxcIjtcblxuY29uc3Qgc3FzID0gbmV3IFNRUyh7IGFwaVZlcnNpb246IFwiMjAxMi0xMS0wNVwiLCByZWdpb246IFwidXMtd2VzdC0yXCIgfSk7XG5wcm9jZXNzLmVudi5BV1NfUkVHSU9OID0gXCJ1cy13ZXN0LTJcIjtcbnByb2Nlc3MuZW52LkZBQVNUX1NJTEVOVCA9IFwidHJ1ZVwiO1xuXG5jb25zdCBsYW1iZGFDb250ZXh0OiBDb250ZXh0ID0ge1xuICAgIGNhbGxiYWNrV2FpdHNGb3JFbXB0eUV2ZW50TG9vcDogdHJ1ZSxcbiAgICBhd3NSZXF1ZXN0SWQ6IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1hd3NSZXF1ZXN0SWRcIixcbiAgICBsb2dHcm91cE5hbWU6IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1sb2dHcm91cE5hbWVcIixcbiAgICBsb2dTdHJlYW1OYW1lOiBcImF3cy10cmFtcG9saW5lLXRlc3QtbG9nU3RyZWFtTmFtZVwiLFxuICAgIGdldFJlbWFpbmluZ1RpbWVJbk1pbGxpczogKCkgPT4gMTAwMCxcbiAgICBmdW5jdGlvbk5hbWU6IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1mdW5jdGlvbk5hbWVcIixcbiAgICBmdW5jdGlvblZlcnNpb246IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1mdW5jdGlvblZlcnNpb25cIixcbiAgICBpbnZva2VkRnVuY3Rpb25Bcm46IFwiYXdzLXRyYW1wb2xpbmUtdGVzdC1pbnZva2VkRnVuY3Rpb25Bcm5cIixcbiAgICBtZW1vcnlMaW1pdEluTUI6IFwiMTcyOFwiLFxuICAgIGRvbmU6ICgpID0+IHt9LFxuICAgIGZhaWw6IF8gPT4ge30sXG4gICAgc3VjY2VlZDogKF86IHN0cmluZykgPT4ge31cbn07XG5cbmFzeW5jIGZ1bmN0aW9uIG1ha2VSZXNwb25zZVF1ZXVlKCkge1xuICAgIGNvbnN0IFF1ZXVlTmFtZSA9IGBmYWFzdC0ke3V1aWR2NCgpfS10ZXN0YDtcbiAgICBjb25zdCB7IFF1ZXVlVXJsIH0gPSBhd2FpdCBzcXMuY3JlYXRlUXVldWUoeyBRdWV1ZU5hbWUgfSkucHJvbWlzZSgpO1xuICAgIHJldHVybiBRdWV1ZVVybCE7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGRlbGV0ZVJlc3BvbnNlUXVldWUoUXVldWVVcmw6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICAgIC8vIFNvbWV0aW1lcyBBV1MgbmVlZHMgdGltZSB0byBwcm9wYWdhdGUgdGhlIGV4aXN0ZW5jZSBvZiBhIHF1ZXVlIGJlZm9yZVxuICAgICAgICAvLyBkZWxldGluZyBpdC4gVGhpcyBtYW5pZmVzdHMgYXMgYSBOb25FeGlzdGVudFF1ZXVlIGVycm9yLiBXYWl0aW5nXG4gICAgICAgIC8vIGEgc2hvcnQgd2hpbGUgc2VlbXMgdG8gbWFrZSB0aGlzIGxlc3MgY29tbW9uLlxuICAgICAgICBhd2FpdCBzbGVlcCg1MDAwKTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHNxcy5kZWxldGVRdWV1ZSh7IFF1ZXVlVXJsIH0pLnByb21pc2UoKTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBDb3VsZCBub3QgZGVsZXRlIHJlc3BvbnNlIHF1ZXVlOiAke2Vycn1gKTtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0TWVzc2FnZXM8SyBleHRlbmRzIEtpbmQ+KFF1ZXVlVXJsOiBzdHJpbmcsIGtpbmQ6IEssIG5FeHBlY3RlZDogbnVtYmVyKSB7XG4gICAgY29uc3QgbWV0cmljcyA9IG5ldyBBd3NNZXRyaWNzKCk7XG4gICAgY29uc3QgY2FuY2VsID0gbmV3IFByb21pc2U8dm9pZD4oXyA9PiB7fSk7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgd2hpbGUgKHJlc3VsdC5sZW5ndGggPCBuRXhwZWN0ZWQpIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZXMgPSBhd2FpdCByZWNlaXZlTWVzc2FnZXMoc3FzLCBRdWV1ZVVybCwgbWV0cmljcywgY2FuY2VsKTtcbiAgICAgICAgcmVzdWx0LnB1c2goLi4uZmlsdGVyTWVzc2FnZXMobWVzc2FnZXMuTWVzc2FnZXMsIGtpbmQpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxudGVzdCh0aXRsZShcImF3c1wiLCBcInRyYW1wb2xpbmUgaHR0cHMgbW9kZSB3aXRoIHByb21pc2UgcmVzcG9uc2VcIiksIGFzeW5jIHQgPT4ge1xuICAgIGNvbnN0IHdyYXBwZXIgPSBuZXcgV3JhcHBlcihmdW5jcywgeyBjaGlsZFByb2Nlc3M6IGZhbHNlLCB3cmFwcGVyTG9nOiAoKSA9PiB7fSB9KTtcbiAgICBjb25zdCB7IHRyYW1wb2xpbmUgfSA9IG1ha2VUcmFtcG9saW5lKHdyYXBwZXIpO1xuICAgIGNvbnN0IGFyZyA9IFwicHJvbWlzZSB3aXRoIGh0dHBzIG9uIGF3c1wiO1xuICAgIGNvbnN0IG5hbWUgPSBmdW5jcy5pZGVudGl0eVN0cmluZy5uYW1lO1xuICAgIGNvbnN0IFF1ZXVlVXJsID0gYXdhaXQgbWFrZVJlc3BvbnNlUXVldWUoKTtcbiAgICB0cnkge1xuICAgICAgICBhd2FpdCB0cmFtcG9saW5lKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNhbGxJZDogXCI0MlwiLFxuICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgYXJnczogc2VyaWFsaXplRnVuY3Rpb25BcmdzKG5hbWUsIFthcmddLCB0cnVlKSxcbiAgICAgICAgICAgICAgICBtb2R1bGVQYXRoOiBcIi4vZml4dHVyZXMvZnVuY3Rpb25zXCIsXG4gICAgICAgICAgICAgICAgUmVzcG9uc2VRdWV1ZUlkOiBRdWV1ZVVybFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhbWJkYUNvbnRleHRcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBbbXNnXSA9IGF3YWl0IGdldE1lc3NhZ2VzKFF1ZXVlVXJsLCBcInByb21pc2VcIiwgMSk7XG4gICAgICAgIGV4cGVjdE1lc3NhZ2UodCwgbXNnLCBcInByb21pc2VcIiwgYXJnKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBkZWxldGVSZXNwb25zZVF1ZXVlKFF1ZXVlVXJsKTtcbiAgICB9XG59KTtcblxudGVzdCh0aXRsZShcImF3c1wiLCBcInRyYW1wb2xpbmUgcXVldWUgbW9kZSB3aXRoIHByb21pc2UgcmVzcG9uc2VcIiksIGFzeW5jIHQgPT4ge1xuICAgIGNvbnN0IHdyYXBwZXIgPSBuZXcgV3JhcHBlcihmdW5jcywgeyBjaGlsZFByb2Nlc3M6IGZhbHNlLCB3cmFwcGVyTG9nOiAoKSA9PiB7fSB9KTtcbiAgICBjb25zdCBhcmcgPSBcInByb21pc2Ugd2l0aCBxdWV1ZSBvbiBhd3NcIjtcbiAgICBjb25zdCBRdWV1ZVVybCA9IGF3YWl0IG1ha2VSZXNwb25zZVF1ZXVlKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyB0cmFtcG9saW5lIH0gPSBtYWtlVHJhbXBvbGluZSh3cmFwcGVyKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IGZ1bmNzLmlkZW50aXR5U3RyaW5nLm5hbWU7XG4gICAgICAgIGNvbnN0IGNhbGwgPSB7XG4gICAgICAgICAgICBjYWxsSWQ6IFwiNDNcIixcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBhcmdzOiBzZXJpYWxpemVGdW5jdGlvbkFyZ3MobmFtZSwgW2FyZ10sIHRydWUpLFxuICAgICAgICAgICAgbW9kdWxlUGF0aDogXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiLFxuICAgICAgICAgICAgUmVzcG9uc2VRdWV1ZUlkOiBRdWV1ZVVybFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBldmVudCA9IHtcbiAgICAgICAgICAgIFJlY29yZHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFNuczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZTogc2VyaWFsaXplKGNhbGwpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgdHJhbXBvbGluZShldmVudCBhcyBTTlNFdmVudCwgbGFtYmRhQ29udGV4dCk7XG5cbiAgICAgICAgY29uc3QgW21zZ10gPSBhd2FpdCBnZXRNZXNzYWdlcyhRdWV1ZVVybCwgXCJwcm9taXNlXCIsIDEpO1xuICAgICAgICBleHBlY3RNZXNzYWdlKHQsIG1zZywgXCJwcm9taXNlXCIsIGFyZyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgZGVsZXRlUmVzcG9uc2VRdWV1ZShRdWV1ZVVybCk7XG4gICAgfVxufSk7XG5cbnRlc3QodGl0bGUoXCJhd3NcIiwgXCJ0cmFtcG9saW5lIGh0dHBzIG1vZGUgd2l0aCBhc3luYyBpdGVyYXRvciByZXNwb25zZVwiKSwgYXN5bmMgdCA9PiB7XG4gICAgY29uc3Qgd3JhcHBlciA9IG5ldyBXcmFwcGVyKGZ1bmNzLCB7IGNoaWxkUHJvY2VzczogZmFsc2UsIHdyYXBwZXJMb2c6ICgpID0+IHt9IH0pO1xuICAgIGNvbnN0IHsgdHJhbXBvbGluZSB9ID0gbWFrZVRyYW1wb2xpbmUod3JhcHBlcik7XG4gICAgY29uc3QgbmFtZSA9IGZ1bmNzLmFzeW5jR2VuZXJhdG9yLm5hbWU7XG4gICAgY29uc3QgYXJnID0gW1wiYXN5bmMgZ2VuZXJhdG9yIHdpdGggaHR0cHMgb24gYXdzXCIsIFwic2Vjb25kIGFyZ1wiXTtcbiAgICBjb25zdCBRdWV1ZVVybCA9IGF3YWl0IG1ha2VSZXNwb25zZVF1ZXVlKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdHJhbXBvbGluZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjYWxsSWQ6IFwiNDRcIixcbiAgICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgICAgIGFyZ3M6IHNlcmlhbGl6ZUZ1bmN0aW9uQXJncyhuYW1lLCBbYXJnXSwgdHJ1ZSksXG4gICAgICAgICAgICAgICAgbW9kdWxlUGF0aDogXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiLFxuICAgICAgICAgICAgICAgIFJlc3BvbnNlUXVldWVJZDogUXVldWVVcmxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYW1iZGFDb250ZXh0XG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gYXdhaXQgZ2V0TWVzc2FnZXMoUXVldWVVcmwsIFwiaXRlcmF0b3JcIiwgYXJnLmxlbmd0aCArIDEpO1xuICAgICAgICBjaGVja0l0ZXJhdG9yTWVzc2FnZXModCwgbWVzc2FnZXMsIGFyZyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgZGVsZXRlUmVzcG9uc2VRdWV1ZShRdWV1ZVVybCk7XG4gICAgfVxufSk7XG5cbnRlc3QodGl0bGUoXCJhd3NcIiwgXCJ0cmFtcG9saW5lIHF1ZXVlIG1vZGUgd2l0aCBhc3luYyBpdGVyYXRvciByZXNwb25zZVwiKSwgYXN5bmMgdCA9PiB7XG4gICAgY29uc3Qgd3JhcHBlciA9IG5ldyBXcmFwcGVyKGZ1bmNzLCB7IGNoaWxkUHJvY2VzczogZmFsc2UsIHdyYXBwZXJMb2c6ICgpID0+IHt9IH0pO1xuICAgIGNvbnN0IFF1ZXVlVXJsID0gYXdhaXQgbWFrZVJlc3BvbnNlUXVldWUoKTtcbiAgICBjb25zdCBhcmcgPSBbXCJhc3luYyBnZW5lcmF0b3Igd2l0aCBxdWV1ZSBvbiBhd3NcIiwgXCJzZWNvbmQgYXJnXCJdO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyB0cmFtcG9saW5lIH0gPSBtYWtlVHJhbXBvbGluZSh3cmFwcGVyKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IGZ1bmNzLmFzeW5jR2VuZXJhdG9yLm5hbWU7XG4gICAgICAgIGNvbnN0IGNhbGwgPSB7XG4gICAgICAgICAgICBjYWxsSWQ6IFwiNDVcIixcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBhcmdzOiBzZXJpYWxpemVGdW5jdGlvbkFyZ3MobmFtZSwgW2FyZ10sIHRydWUpLFxuICAgICAgICAgICAgbW9kdWxlUGF0aDogXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiLFxuICAgICAgICAgICAgUmVzcG9uc2VRdWV1ZUlkOiBRdWV1ZVVybFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBldmVudCA9IHtcbiAgICAgICAgICAgIFJlY29yZHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFNuczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZTogc2VyaWFsaXplKGNhbGwpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgdHJhbXBvbGluZShldmVudCBhcyBTTlNFdmVudCwgbGFtYmRhQ29udGV4dCk7XG5cbiAgICAgICAgY29uc3QgbWVzc2FnZXMgPSBhd2FpdCBnZXRNZXNzYWdlcyhRdWV1ZVVybCwgXCJpdGVyYXRvclwiLCBhcmcubGVuZ3RoICsgMSk7XG4gICAgICAgIGNoZWNrSXRlcmF0b3JNZXNzYWdlcyh0LCBtZXNzYWdlcywgYXJnKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBkZWxldGVSZXNwb25zZVF1ZXVlKFF1ZXVlVXJsKTtcbiAgICB9XG59KTtcbiJdfQ== |
\ | No newline at end of file |