1 | ;
|
2 | /**
|
3 | * The purpose of this test is to check that the trampoline function on google
|
4 | * can route calls, invoke the wrapper, and return values correctly, without
|
5 | * actually creating a cloud function. However, it does use real cloud queues.
|
6 | */
|
7 | Object.defineProperty(exports, "__esModule", { value: true });
|
8 | const ava_1 = require("ava");
|
9 | const uuid_1 = require("uuid");
|
10 | const google_faast_1 = require("../src/google/google-faast");
|
11 | const google_queue_1 = require("../src/google/google-queue");
|
12 | const google_trampoline_https_1 = require("../src/google/google-trampoline-https");
|
13 | const google_trampoline_queue_1 = require("../src/google/google-trampoline-queue");
|
14 | const provider_1 = require("../src/provider");
|
15 | const serialize_1 = require("../src/serialize");
|
16 | const wrapper_1 = require("../src/wrapper");
|
17 | const funcs = require("./fixtures/functions");
|
18 | const util_1 = require("./fixtures/util");
|
19 | const shared_1 = require("../src/shared");
|
20 | process.env.FAAST_SILENT = "true";
|
21 | async function initGoogleResources() {
|
22 | const services = await (0, google_faast_1.initializeGoogleServices)();
|
23 | const { google } = services;
|
24 | const pubsub = google.pubsub("v1");
|
25 | const project = await google.auth.getProjectId();
|
26 | const FunctionName = `faast-${(0, uuid_1.v4)()}`;
|
27 | const topic = await pubsub.projects.topics.create({
|
28 | name: (0, google_faast_1.getResponseQueueTopic)(project, FunctionName)
|
29 | });
|
30 | const topicName = topic.data.name;
|
31 | const subscriptionName = (0, google_faast_1.getResponseSubscription)(project, FunctionName);
|
32 | await pubsub.projects.subscriptions.create({
|
33 | name: subscriptionName,
|
34 | requestBody: {
|
35 | topic: topicName
|
36 | }
|
37 | });
|
38 | const resources = {
|
39 | topicName,
|
40 | subscriptionName,
|
41 | google
|
42 | };
|
43 | return resources;
|
44 | }
|
45 | async function cleanupGoogleResources(resources) {
|
46 | const { google, subscriptionName, topicName } = resources;
|
47 | const pubsub = google.pubsub("v1");
|
48 | // Give google a little time to propagate the existence of the queue.
|
49 | await (0, shared_1.sleep)(5000);
|
50 | await pubsub.projects.subscriptions.delete({
|
51 | subscription: subscriptionName
|
52 | });
|
53 | await pubsub.projects.topics.delete({
|
54 | topic: topicName
|
55 | });
|
56 | }
|
57 | async function getMessages(resources, kind, nExpected) {
|
58 | const { google, subscriptionName } = resources;
|
59 | const pubsub = google.pubsub("v1");
|
60 | const metrics = new google_faast_1.GoogleMetrics();
|
61 | const cancel = new Promise(_ => { });
|
62 | const result = [];
|
63 | while (result.length < nExpected) {
|
64 | const messages = await (0, google_queue_1.receiveMessages)(pubsub, subscriptionName, metrics, cancel);
|
65 | result.push(...(0, provider_1.filterMessages)(messages.Messages, kind));
|
66 | }
|
67 | return result;
|
68 | }
|
69 | (0, ava_1.default)((0, util_1.title)("google", "trampoline https mode with promise response"), async (t) => {
|
70 | const resources = await initGoogleResources();
|
71 | try {
|
72 | const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
|
73 | const { trampoline } = (0, google_trampoline_https_1.makeTrampoline)(wrapper);
|
74 | const arg = "promise with https on google";
|
75 | const name = funcs.identityNum.name;
|
76 | const call = {
|
77 | callId: "42",
|
78 | name,
|
79 | args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
|
80 | modulePath: "./fixtures/functions",
|
81 | ResponseQueueId: resources.topicName
|
82 | };
|
83 | const headers = {
|
84 | "function-execution-id": "google-trampoline-test-function-execution-id"
|
85 | };
|
86 | const request = { body: call, headers };
|
87 | const response = { send: (_) => { } };
|
88 | await trampoline(request, response);
|
89 | const [msg] = await getMessages(resources, "promise", 1);
|
90 | (0, util_1.expectMessage)(t, msg, "promise", arg);
|
91 | }
|
92 | finally {
|
93 | await cleanupGoogleResources(resources);
|
94 | }
|
95 | });
|
96 | (0, ava_1.default)((0, util_1.title)("google", "trampoline https mode with async iterator response"), async (t) => {
|
97 | const resources = await initGoogleResources();
|
98 | try {
|
99 | const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
|
100 | const { trampoline } = (0, google_trampoline_https_1.makeTrampoline)(wrapper);
|
101 | const arg = ["async iterator with https on google", "second arg"];
|
102 | const name = funcs.asyncGenerator.name;
|
103 | const call = {
|
104 | callId: "42",
|
105 | name,
|
106 | args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
|
107 | modulePath: "./fixtures/functions",
|
108 | ResponseQueueId: resources.topicName
|
109 | };
|
110 | const headers = {
|
111 | "function-execution-id": "google-trampoline-test-function-execution-id"
|
112 | };
|
113 | const request = { body: call, headers };
|
114 | const response = { send: (_) => { } };
|
115 | await trampoline(request, response);
|
116 | const messages = await getMessages(resources, "iterator", arg.length + 1);
|
117 | (0, util_1.checkIteratorMessages)(t, messages, arg);
|
118 | }
|
119 | finally {
|
120 | await cleanupGoogleResources(resources);
|
121 | }
|
122 | });
|
123 | (0, ava_1.default)((0, util_1.title)("google", "trampoline queue mode with promise response"), async (t) => {
|
124 | const resources = await initGoogleResources();
|
125 | try {
|
126 | const arg = "promise with queue on google";
|
127 | const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
|
128 | const { trampoline } = (0, google_trampoline_queue_1.makeTrampoline)(wrapper);
|
129 | const name = funcs.identityNum.name;
|
130 | const call = {
|
131 | callId: "42",
|
132 | name,
|
133 | args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
|
134 | modulePath: "./fixtures/functions",
|
135 | ResponseQueueId: resources.topicName
|
136 | };
|
137 | const event = {
|
138 | data: Buffer.from((0, serialize_1.serialize)(call)).toString("base64")
|
139 | };
|
140 | const context = {
|
141 | eventId: "",
|
142 | timestamp: "",
|
143 | eventType: "",
|
144 | resource: {}
|
145 | };
|
146 | await trampoline(event, context);
|
147 | const [msg] = await getMessages(resources, "promise", 1);
|
148 | (0, util_1.expectMessage)(t, msg, "promise", arg);
|
149 | }
|
150 | finally {
|
151 | await cleanupGoogleResources(resources);
|
152 | }
|
153 | });
|
154 | (0, ava_1.default)((0, util_1.title)("google", "trampoline queue mode with async iterator response"), async (t) => {
|
155 | const resources = await initGoogleResources();
|
156 | try {
|
157 | const wrapper = new wrapper_1.Wrapper(funcs, { childProcess: false, wrapperLog: () => { } });
|
158 | const arg = ["async iterator with queue on google"];
|
159 | const { trampoline } = (0, google_trampoline_queue_1.makeTrampoline)(wrapper);
|
160 | const name = funcs.asyncGenerator.name;
|
161 | const call = {
|
162 | callId: "42",
|
163 | name,
|
164 | args: (0, serialize_1.serializeFunctionArgs)(name, [arg], true),
|
165 | modulePath: "./fixtures/functions",
|
166 | ResponseQueueId: resources.topicName
|
167 | };
|
168 | const event = {
|
169 | data: Buffer.from((0, serialize_1.serialize)(call)).toString("base64")
|
170 | };
|
171 | const context = {
|
172 | eventId: "",
|
173 | timestamp: "",
|
174 | eventType: "",
|
175 | resource: {}
|
176 | };
|
177 | await trampoline(event, context);
|
178 | const messages = await getMessages(resources, "iterator", arg.length + 1);
|
179 | (0, util_1.checkIteratorMessages)(t, messages, arg);
|
180 | }
|
181 | finally {
|
182 | await cleanupGoogleResources(resources);
|
183 | }
|
184 | });
|
185 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29vZ2xlLXRyYW1wb2xpbmUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvZ29vZ2xlLXRyYW1wb2xpbmUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7R0FJRzs7QUFFSCw2QkFBdUI7QUFHdkIsK0JBQW9DO0FBQ3BDLDZEQUtvQztBQUNwQyw2REFBNkQ7QUFDN0QsbUZBQThGO0FBQzlGLG1GQUcrQztBQUMvQyw4Q0FBdUQ7QUFDdkQsZ0RBQW9FO0FBQ3BFLDRDQUF5QztBQUN6Qyw4Q0FBOEM7QUFDOUMsMENBQThFO0FBQzlFLDBDQUFzQztBQUV0QyxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUM7QUFRbEMsS0FBSyxVQUFVLG1CQUFtQjtJQUM5QixNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUEsdUNBQXdCLEdBQUUsQ0FBQztJQUNsRCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDO0lBQzVCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsTUFBTSxPQUFPLEdBQUcsTUFBTSxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ2pELE1BQU0sWUFBWSxHQUFHLFNBQVMsSUFBQSxTQUFNLEdBQUUsRUFBRSxDQUFDO0lBQ3pDLE1BQU0sS0FBSyxHQUFHLE1BQU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBQzlDLElBQUksRUFBRSxJQUFBLG9DQUFxQixFQUFDLE9BQU8sRUFBRSxZQUFZLENBQUM7S0FDckQsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFLLENBQUM7SUFFbkMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFBLHNDQUF1QixFQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztJQUN4RSxNQUFNLE1BQU0s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R0FBRyxDQUFDLENBQUM7S0FDM0M7WUFBUztRQUNOLE1BQU0sc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7S0FDM0M7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhlIHB1cnBvc2Ugb2YgdGhpcyB0ZXN0IGlzIHRvIGNoZWNrIHRoYXQgdGhlIHRyYW1wb2xpbmUgZnVuY3Rpb24gb24gZ29vZ2xlXG4gKiBjYW4gcm91dGUgY2FsbHMsIGludm9rZSB0aGUgd3JhcHBlciwgYW5kIHJldHVybiB2YWx1ZXMgY29ycmVjdGx5LCB3aXRob3V0XG4gKiBhY3R1YWxseSBjcmVhdGluZyBhIGNsb3VkIGZ1bmN0aW9uLiBIb3dldmVyLCBpdCBkb2VzIHVzZSByZWFsIGNsb3VkIHF1ZXVlcy5cbiAqL1xuXG5pbXBvcnQgdGVzdCBmcm9tIFwiYXZhXCI7XG5pbXBvcnQgeyBSZXF1ZXN0LCBSZXNwb25zZSB9IGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQgeyBHb29nbGVBcGlzIH0gZnJvbSBcImdvb2dsZWFwaXNcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWR2NCB9IGZyb20gXCJ1dWlkXCI7XG5pbXBvcnQge1xuICAgIGdldFJlc3BvbnNlUXVldWVUb3BpYyxcbiAgICBnZXRSZXNwb25zZVN1YnNjcmlwdGlvbixcbiAgICBHb29nbGVNZXRyaWNzLFxuICAgIGluaXRpYWxpemVHb29nbGVTZXJ2aWNlc1xufSBmcm9tIFwiLi4vc3JjL2dvb2dsZS9nb29nbGUtZmFhc3RcIjtcbmltcG9ydCB7IHJlY2VpdmVNZXNzYWdlcyB9IGZyb20gXCIuLi9zcmMvZ29vZ2xlL2dvb2dsZS1xdWV1ZVwiO1xuaW1wb3J0IHsgbWFrZVRyYW1wb2xpbmUgYXMgbWFrZVRyYW1wb2xpbmVIdHRwcyB9IGZyb20gXCIuLi9zcmMvZ29vZ2xlL2dvb2dsZS10cmFtcG9saW5lLWh0dHBzXCI7XG5pbXBvcnQge1xuICAgIENsb3VkRnVuY3Rpb25Db250ZXh0LFxuICAgIG1ha2VUcmFtcG9saW5lIGFzIG1ha2VUcmFtcG9saW5lUXVldWVcbn0gZnJvbSBcIi4uL3NyYy9nb29nbGUvZ29vZ2xlLXRyYW1wb2xpbmUtcXVldWVcIjtcbmltcG9ydCB7IGZpbHRlck1lc3NhZ2VzLCBLaW5kIH0gZnJvbSBcIi4uL3NyYy9wcm92aWRlclwiO1xuaW1wb3J0IHsgc2VyaWFsaXplLCBzZXJpYWxpemVGdW5jdGlvbkFyZ3MgfSBmcm9tIFwiLi4vc3JjL3NlcmlhbGl6ZVwiO1xuaW1wb3J0IHsgV3JhcHBlciB9IGZyb20gXCIuLi9zcmMvd3JhcHBlclwiO1xuaW1wb3J0ICogYXMgZnVuY3MgZnJvbSBcIi4vZml4dHVyZXMvZnVuY3Rpb25zXCI7XG5pbXBvcnQgeyBjaGVja0l0ZXJhdG9yTWVzc2FnZXMsIGV4cGVjdE1lc3NhZ2UsIHRpdGxlIH0gZnJvbSBcIi4vZml4dHVyZXMvdXRpbFwiO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tIFwiLi4vc3JjL3NoYXJlZFwiO1xuXG5wcm9jZXNzLmVudi5GQUFTVF9TSUxFTlQgPSBcInRydWVcIjtcblxuaW50ZXJmYWNlIEdvb2dsZVRyYW1wb2xpbmVUZXN0UmVzb3VyY2VzIHtcbiAgICB0b3BpY05hbWU6IHN0cmluZztcbiAgICBzdWJzY3JpcHRpb25OYW1lOiBzdHJpbmc7XG4gICAgZ29vZ2xlOiBHb29nbGVBcGlzO1xufVxuXG5hc3luYyBmdW5jdGlvbiBpbml0R29vZ2xlUmVzb3VyY2VzKCkge1xuICAgIGNvbnN0IHNlcnZpY2VzID0gYXdhaXQgaW5pdGlhbGl6ZUdvb2dsZVNlcnZpY2VzKCk7XG4gICAgY29uc3QgeyBnb29nbGUgfSA9IHNlcnZpY2VzO1xuICAgIGNvbnN0IHB1YnN1YiA9IGdvb2dsZS5wdWJzdWIoXCJ2MVwiKTtcbiAgICBjb25zdCBwcm9qZWN0ID0gYXdhaXQgZ29vZ2xlLmF1dGguZ2V0UHJvamVjdElkKCk7XG4gICAgY29uc3QgRnVuY3Rpb25OYW1lID0gYGZhYXN0LSR7dXVpZHY0KCl9YDtcbiAgICBjb25zdCB0b3BpYyA9IGF3YWl0IHB1YnN1Yi5wcm9qZWN0cy50b3BpY3MuY3JlYXRlKHtcbiAgICAgICAgbmFtZTogZ2V0UmVzcG9uc2VRdWV1ZVRvcGljKHByb2plY3QsIEZ1bmN0aW9uTmFtZSlcbiAgICB9KTtcbiAgICBjb25zdCB0b3BpY05hbWUgPSB0b3BpYy5kYXRhLm5hbWUhO1xuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uTmFtZSA9IGdldFJlc3BvbnNlU3Vic2NyaXB0aW9uKHByb2plY3QsIEZ1bmN0aW9uTmFtZSk7XG4gICAgYXdhaXQgcHVic3ViLnByb2plY3RzLnN1YnNjcmlwdGlvbnMuY3JlYXRlKHtcbiAgICAgICAgbmFtZTogc3Vic2NyaXB0aW9uTmFtZSxcbiAgICAgICAgcmVxdWVzdEJvZHk6IHtcbiAgICAgICAgICAgIHRvcGljOiB0b3BpY05hbWVcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzb3VyY2VzOiBHb29nbGVUcmFtcG9saW5lVGVzdFJlc291cmNlcyA9IHtcbiAgICAgICAgdG9waWNOYW1lLFxuICAgICAgICBzdWJzY3JpcHRpb25OYW1lLFxuICAgICAgICBnb29nbGVcbiAgICB9O1xuICAgIHJldHVybiByZXNvdXJjZXM7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNsZWFudXBHb29nbGVSZXNvdXJjZXMocmVzb3VyY2VzOiBHb29nbGVUcmFtcG9saW5lVGVzdFJlc291cmNlcykge1xuICAgIGNvbnN0IHsgZ29vZ2xlLCBzdWJzY3JpcHRpb25OYW1lLCB0b3BpY05hbWUgfSA9IHJlc291cmNlcztcbiAgICBjb25zdCBwdWJzdWIgPSBnb29nbGUucHVic3ViKFwidjFcIik7XG4gICAgLy8gR2l2ZSBnb29nbGUgYSBsaXR0bGUgdGltZSB0byBwcm9wYWdhdGUgdGhlIGV4aXN0ZW5jZSBvZiB0aGUgcXVldWUuXG4gICAgYXdhaXQgc2xlZXAoNTAwMCk7XG4gICAgYXdhaXQgcHVic3ViLnByb2plY3RzLnN1YnNjcmlwdGlvbnMuZGVsZXRlKHtcbiAgICAgICAgc3Vic2NyaXB0aW9uOiBzdWJzY3JpcHRpb25OYW1lXG4gICAgfSk7XG4gICAgYXdhaXQgcHVic3ViLnByb2plY3RzLnRvcGljcy5kZWxldGUoe1xuICAgICAgICB0b3BpYzogdG9waWNOYW1lXG4gICAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldE1lc3NhZ2VzPEsgZXh0ZW5kcyBLaW5kPihcbiAgICByZXNvdXJjZXM6IEdvb2dsZVRyYW1wb2xpbmVUZXN0UmVzb3VyY2VzLFxuICAgIGtpbmQ6IEssXG4gICAgbkV4cGVjdGVkOiBudW1iZXJcbikge1xuICAgIGNvbnN0IHsgZ29vZ2xlLCBzdWJzY3JpcHRpb25OYW1lIH0gPSByZXNvdXJjZXM7XG4gICAgY29uc3QgcHVic3ViID0gZ29vZ2xlLnB1YnN1YihcInYxXCIpO1xuICAgIGNvbnN0IG1ldHJpY3MgPSBuZXcgR29vZ2xlTWV0cmljcygpO1xuICAgIGNvbnN0IGNhbmNlbCA9IG5ldyBQcm9taXNlPHZvaWQ+KF8gPT4ge30pO1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIHdoaWxlIChyZXN1bHQubGVuZ3RoIDwgbkV4cGVjdGVkKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gYXdhaXQgcmVjZWl2ZU1lc3NhZ2VzKHB1YnN1Yiwgc3Vic2NyaXB0aW9uTmFtZSwgbWV0cmljcywgY2FuY2VsKTtcbiAgICAgICAgcmVzdWx0LnB1c2goLi4uZmlsdGVyTWVzc2FnZXMobWVzc2FnZXMuTWVzc2FnZXMsIGtpbmQpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxudGVzdCh0aXRsZShcImdvb2dsZVwiLCBcInRyYW1wb2xpbmUgaHR0cHMgbW9kZSB3aXRoIHByb21pc2UgcmVzcG9uc2VcIiksIGFzeW5jIHQgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlcyA9IGF3YWl0IGluaXRHb29nbGVSZXNvdXJjZXMoKTtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCB3cmFwcGVyID0gbmV3IFdyYXBwZXIoZnVuY3MsIHsgY2hpbGRQcm9jZXNzOiBmYWxzZSwgd3JhcHBlckxvZzogKCkgPT4ge30gfSk7XG4gICAgICAgIGNvbnN0IHsgdHJhbXBvbGluZSB9ID0gbWFrZVRyYW1wb2xpbmVIdHRwcyh3cmFwcGVyKTtcbiAgICAgICAgY29uc3QgYXJnID0gXCJwcm9taXNlIHdpdGggaHR0cHMgb24gZ29vZ2xlXCI7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBmdW5jcy5pZGVudGl0eU51bS5uYW1lO1xuICAgICAgICBjb25zdCBjYWxsID0ge1xuICAgICAgICAgICAgY2FsbElkOiBcIjQyXCIsXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgYXJnczogc2VyaWFsaXplRnVuY3Rpb25BcmdzKG5hbWUsIFthcmddLCB0cnVlKSxcbiAgICAgICAgICAgIG1vZHVsZVBhdGg6IFwiLi9maXh0dXJlcy9mdW5jdGlvbnNcIixcbiAgICAgICAgICAgIFJlc3BvbnNlUXVldWVJZDogcmVzb3VyY2VzLnRvcGljTmFtZVxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGhlYWRlcnM6IFJlcXVlc3RbXCJoZWFkZXJzXCJdID0ge1xuICAgICAgICAgICAgXCJmdW5jdGlvbi1leGVjdXRpb24taWRcIjogXCJnb29nbGUtdHJhbXBvbGluZS10ZXN0LWZ1bmN0aW9uLWV4ZWN1dGlvbi1pZFwiXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IHsgYm9keTogY2FsbCwgaGVhZGVycyB9IGFzIFJlcXVlc3Q7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0geyBzZW5kOiAoXzogYW55KSA9PiB7fSB9IGFzIFJlc3BvbnNlO1xuXG4gICAgICAgIGF3YWl0IHRyYW1wb2xpbmUocmVxdWVzdCwgcmVzcG9uc2UpO1xuXG4gICAgICAgIGNvbnN0IFttc2ddID0gYXdhaXQgZ2V0TWVzc2FnZXMocmVzb3VyY2VzLCBcInByb21pc2VcIiwgMSk7XG4gICAgICAgIGV4cGVjdE1lc3NhZ2UodCwgbXNnLCBcInByb21pc2VcIiwgYXJnKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBjbGVhbnVwR29vZ2xlUmVzb3VyY2VzKHJlc291cmNlcyk7XG4gICAgfVxufSk7XG5cbnRlc3QodGl0bGUoXCJnb29nbGVcIiwgXCJ0cmFtcG9saW5lIGh0dHBzIG1vZGUgd2l0aCBhc3luYyBpdGVyYXRvciByZXNwb25zZVwiKSwgYXN5bmMgdCA9PiB7XG4gICAgY29uc3QgcmVzb3VyY2VzID0gYXdhaXQgaW5pdEdvb2dsZVJlc291cmNlcygpO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHdyYXBwZXIgPSBuZXcgV3JhcHBlcihmdW5jcywgeyBjaGlsZFByb2Nlc3M6IGZhbHNlLCB3cmFwcGVyTG9nOiAoKSA9PiB7fSB9KTtcbiAgICAgICAgY29uc3QgeyB0cmFtcG9saW5lIH0gPSBtYWtlVHJhbXBvbGluZUh0dHBzKHdyYXBwZXIpO1xuICAgICAgICBjb25zdCBhcmcgPSBbXCJhc3luYyBpdGVyYXRvciB3aXRoIGh0dHBzIG9uIGdvb2dsZVwiLCBcInNlY29uZCBhcmdcIl07XG4gICAgICAgIGNvbnN0IG5hbWUgPSBmdW5jcy5hc3luY0dlbmVyYXRvci5uYW1lO1xuICAgICAgICBjb25zdCBjYWxsID0ge1xuICAgICAgICAgICAgY2FsbElkOiBcIjQyXCIsXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgYXJnczogc2VyaWFsaXplRnVuY3Rpb25BcmdzKG5hbWUsIFthcmddLCB0cnVlKSxcbiAgICAgICAgICAgIG1vZHVsZVBhdGg6IFwiLi9maXh0dXJlcy9mdW5jdGlvbnNcIixcbiAgICAgICAgICAgIFJlc3BvbnNlUXVldWVJZDogcmVzb3VyY2VzLnRvcGljTmFtZVxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGhlYWRlcnM6IFJlcXVlc3RbXCJoZWFkZXJzXCJdID0ge1xuICAgICAgICAgICAgXCJmdW5jdGlvbi1leGVjdXRpb24taWRcIjogXCJnb29nbGUtdHJhbXBvbGluZS10ZXN0LWZ1bmN0aW9uLWV4ZWN1dGlvbi1pZFwiXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IHsgYm9keTogY2FsbCwgaGVhZGVycyB9IGFzIFJlcXVlc3Q7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0geyBzZW5kOiAoXzogYW55KSA9PiB7fSB9IGFzIFJlc3BvbnNlO1xuXG4gICAgICAgIGF3YWl0IHRyYW1wb2xpbmUocmVxdWVzdCwgcmVzcG9uc2UpO1xuXG4gICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gYXdhaXQgZ2V0TWVzc2FnZXMocmVzb3VyY2VzLCBcIml0ZXJhdG9yXCIsIGFyZy5sZW5ndGggKyAxKTtcbiAgICAgICAgY2hlY2tJdGVyYXRvck1lc3NhZ2VzKHQsIG1lc3NhZ2VzLCBhcmcpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGNsZWFudXBHb29nbGVSZXNvdXJjZXMocmVzb3VyY2VzKTtcbiAgICB9XG59KTtcblxudGVzdCh0aXRsZShcImdvb2dsZVwiLCBcInRyYW1wb2xpbmUgcXVldWUgbW9kZSB3aXRoIHByb21pc2UgcmVzcG9uc2VcIiksIGFzeW5jIHQgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlcyA9IGF3YWl0IGluaXRHb29nbGVSZXNvdXJjZXMoKTtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBhcmcgPSBcInByb21pc2Ugd2l0aCBxdWV1ZSBvbiBnb29nbGVcIjtcbiAgICAgICAgY29uc3Qgd3JhcHBlciA9IG5ldyBXcmFwcGVyKGZ1bmNzLCB7IGNoaWxkUHJvY2VzczogZmFsc2UsIHdyYXBwZXJMb2c6ICgpID0+IHt9IH0pO1xuICAgICAgICBjb25zdCB7IHRyYW1wb2xpbmUgfSA9IG1ha2VUcmFtcG9saW5lUXVldWUod3JhcHBlcik7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBmdW5jcy5pZGVudGl0eU51bS5uYW1lO1xuICAgICAgICBjb25zdCBjYWxsID0ge1xuICAgICAgICAgICAgY2FsbElkOiBcIjQyXCIsXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgYXJnczogc2VyaWFsaXplRnVuY3Rpb25BcmdzKG5hbWUsIFthcmddLCB0cnVlKSxcbiAgICAgICAgICAgIG1vZHVsZVBhdGg6IFwiLi9maXh0dXJlcy9mdW5jdGlvbnNcIixcbiAgICAgICAgICAgIFJlc3BvbnNlUXVldWVJZDogcmVzb3VyY2VzLnRvcGljTmFtZVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBldmVudCA9IHtcbiAgICAgICAgICAgIGRhdGE6IEJ1ZmZlci5mcm9tKHNlcmlhbGl6ZShjYWxsKSkudG9TdHJpbmcoXCJiYXNlNjRcIilcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBjb250ZXh0OiBDbG91ZEZ1bmN0aW9uQ29udGV4dCA9IHtcbiAgICAgICAgICAgIGV2ZW50SWQ6IFwiXCIsXG4gICAgICAgICAgICB0aW1lc3RhbXA6IFwiXCIsXG4gICAgICAgICAgICBldmVudFR5cGU6IFwiXCIsXG4gICAgICAgICAgICByZXNvdXJjZToge31cbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCB0cmFtcG9saW5lKGV2ZW50LCBjb250ZXh0KTtcblxuICAgICAgICBjb25zdCBbbXNnXSA9IGF3YWl0IGdldE1lc3NhZ2VzKHJlc291cmNlcywgXCJwcm9taXNlXCIsIDEpO1xuICAgICAgICBleHBlY3RNZXNzYWdlKHQsIG1zZywgXCJwcm9taXNlXCIsIGFyZyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgY2xlYW51cEdvb2dsZVJlc291cmNlcyhyZXNvdXJjZXMpO1xuICAgIH1cbn0pO1xuXG50ZXN0KHRpdGxlKFwiZ29vZ2xlXCIsIFwidHJhbXBvbGluZSBxdWV1ZSBtb2RlIHdpdGggYXN5bmMgaXRlcmF0b3IgcmVzcG9uc2VcIiksIGFzeW5jIHQgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlcyA9IGF3YWl0IGluaXRHb29nbGVSZXNvdXJjZXMoKTtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCB3cmFwcGVyID0gbmV3IFdyYXBwZXIoZnVuY3MsIHsgY2hpbGRQcm9jZXNzOiBmYWxzZSwgd3JhcHBlckxvZzogKCkgPT4ge30gfSk7XG4gICAgICAgIGNvbnN0IGFyZyA9IFtcImFzeW5jIGl0ZXJhdG9yIHdpdGggcXVldWUgb24gZ29vZ2xlXCJdO1xuXG4gICAgICAgIGNvbnN0IHsgdHJhbXBvbGluZSB9ID0gbWFrZVRyYW1wb2xpbmVRdWV1ZSh3cmFwcGVyKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IGZ1bmNzLmFzeW5jR2VuZXJhdG9yLm5hbWU7XG4gICAgICAgIGNvbnN0IGNhbGwgPSB7XG4gICAgICAgICAgICBjYWxsSWQ6IFwiNDJcIixcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBhcmdzOiBzZXJpYWxpemVGdW5jdGlvbkFyZ3MobmFtZSwgW2FyZ10sIHRydWUpLFxuICAgICAgICAgICAgbW9kdWxlUGF0aDogXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiLFxuICAgICAgICAgICAgUmVzcG9uc2VRdWV1ZUlkOiByZXNvdXJjZXMudG9waWNOYW1lXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV2ZW50ID0ge1xuICAgICAgICAgICAgZGF0YTogQnVmZmVyLmZyb20oc2VyaWFsaXplKGNhbGwpKS50b1N0cmluZyhcImJhc2U2NFwiKVxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGNvbnRleHQ6IENsb3VkRnVuY3Rpb25Db250ZXh0ID0ge1xuICAgICAgICAgICAgZXZlbnRJZDogXCJcIixcbiAgICAgICAgICAgIHRpbWVzdGFtcDogXCJcIixcbiAgICAgICAgICAgIGV2ZW50VHlwZTogXCJcIixcbiAgICAgICAgICAgIHJlc291cmNlOiB7fVxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IHRyYW1wb2xpbmUoZXZlbnQsIGNvbnRleHQpO1xuXG4gICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gYXdhaXQgZ2V0TWVzc2FnZXMocmVzb3VyY2VzLCBcIml0ZXJhdG9yXCIsIGFyZy5sZW5ndGggKyAxKTtcbiAgICAgICAgY2hlY2tJdGVyYXRvck1lc3NhZ2VzKHQsIG1lc3NhZ2VzLCBhcmcpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IGNsZWFudXBHb29nbGVSZXNvdXJjZXMocmVzb3VyY2VzKTtcbiAgICB9XG59KTtcbiJdfQ== |
\ | No newline at end of file |