UNPKG

15.8 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const ava_1 = require("ava");
4const sys = require("child_process");
5const fs_extra_1 = require("fs-extra");
6const path = require("path");
7const path_1 = require("path");
8const index_1 = require("../index");
9const aws_faast_1 = require("../src/aws/aws-faast");
10const google_faast_1 = require("../src/google/google-faast");
11const local_faast_1 = require("../src/local/local-faast");
12const packer_1 = require("../src/packer");
13const kb = 1024;
14function exec(cmd) {
15 const result = sys.execSync(cmd).toString();
16 index_1.log.info(result);
17 return result;
18}
19const testPacker = async (t, provider, pack, config, size) => {
20 const identifier = `${provider}-${config.name}`;
21 const tmpDir = path.join("tmp", identifier);
22 exec(`mkdir -p ${tmpDir}`);
23 process.env["FAAST_PACKAGE_DIR"] = "tmp";
24 const { archive } = await pack(require.resolve("./fixtures/functions"), config, {}, identifier);
25 await (0, fs_extra_1.remove)(tmpDir);
26 const writePromise = new Promise(resolve => archive.on("end", resolve));
27 const unzipPromise = (0, packer_1.unzipInDir)(tmpDir, archive);
28 await Promise.all([writePromise, unzipPromise]);
29 const zipFile = path.join("tmp", identifier + ".zip");
30 const bytes = (await (0, fs_extra_1.stat)(zipFile)).size;
31 t.true(bytes < size, `package size ${bytes} exceeded maximum ${size}`);
32 t.is(exec(`cd ${tmpDir} && node index.js`), "faast: successful cold start.\n");
33 config.check && (await config.check(t, tmpDir));
34};
35testPacker.title = (_title = "", provider, _packer, options) => `packer ${provider}-${options.name}`;
36function added(dir) {
37 return async (t, root) => {
38 const filePath = (0, path_1.join)(root, dir, "file.txt");
39 t.true(await (0, fs_extra_1.pathExists)(filePath), `file ${filePath} does not exist in package`);
40 const { mode } = await (0, fs_extra_1.stat)((0, path_1.join)(root, dir, "script"));
41 const { mode: origMode } = await (0, fs_extra_1.stat)("test/fixtures/dir/script");
42 t.is(mode, origMode, "file modes are preserved");
43 t.is(mode & 0o700, 0o700, "executable mode is preserved in added files");
44 };
45}
46function excluded(file) {
47 return async (t, root) => {
48 const filePath = (0, path_1.join)(root, file);
49 t.false(await (0, fs_extra_1.pathExists)(filePath), `file ${file} exists but it should be excluded`);
50 };
51}
52const configs = [
53 { name: "https", mode: "https" },
54 { name: "queue", mode: "queue" },
55 { name: "https-package", mode: "https", packageJson: "test/fixtures/package.json" },
56 { name: "queue-package", mode: "queue", packageJson: "test/fixtures/package.json" },
57 {
58 name: "include",
59 include: ["test/fixtures/dir/**/*"],
60 check: added("test/fixtures/dir")
61 },
62 {
63 name: "include-cwd",
64 include: [{ path: "dir/**/*", cwd: "test/fixtures" }],
65 check: added("dir")
66 },
67 {
68 name: "include-dir",
69 include: ["test/fixtures/dir"],
70 check: added("test/fixtures/dir")
71 },
72 {
73 name: "include-dir-cwd",
74 include: [{ path: "dir", cwd: "test/fixtures" }],
75 check: added("dir")
76 },
77 {
78 name: "exclude",
79 include: ["test/fixtures/dir/**/*"],
80 exclude: ["**/*.exc"],
81 check: excluded("test/fixtures/dir/excluded.exc")
82 },
83 {
84 name: "exclude-file",
85 include: ["test/fixtures/dir/**/*"],
86 exclude: ["test/fixtures/dir/excluded.exc"],
87 check: excluded("test/fixtures/dir/excluded.exc")
88 }
89];
90const packers = {
91 aws: aws_faast_1.awsPacker,
92 google: google_faast_1.googlePacker,
93 local: local_faast_1.localPacker
94};
95for (const name of index_1.providers) {
96 for (const config of configs) {
97 let size = 130 * kb;
98 if (name === "google" && !config.packageJson) {
99 size = 1400 * kb;
100 }
101 (0, ava_1.default)(testPacker, name, packers[name], config, size);
102 }
103}
104//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pdC1wYWNrZXIudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvdW5pdC1wYWNrZXIudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUFvRDtBQUNwRCxxQ0FBcUM7QUFDckMsdUNBQW9EO0FBQ3BELDZCQUE2QjtBQUM3QiwrQkFBNEI7QUFDNUIsb0NBQW1FO0FBQ25FLG9EQUFpRDtBQUNqRCw2REFBMEQ7QUFDMUQsMERBQXVEO0FBQ3ZELDBDQUF5RDtBQUd6RCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFPaEIsU0FBUyxJQUFJLENBQUMsR0FBVztJQUNyQixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzVDLFdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakIsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQztBQVNELE1BQU0sVUFBVSxHQUE0RCxLQUFLLEVBQzdFLENBQW1CLEVBQ25CLFFBQWtCLEVBQ2xCLElBQVksRUFDWixNQUE0QixFQUM1QixJQUFZLEVBQ2QsRUFBRTtJQUNBLE1BQU0sVUFBVSxHQUFHLEdBQUcsUUFBUSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNoRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztJQUM1QyxJQUFJLENBQUMsWUFBWSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBRTNCLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsR0FBRyxLQUFLLENBQUM7SUFFekMsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUMxQixPQUFPLENBQUMsT0FBTyxDQUFDLHNCQUFzQixDQUFDLEVBQ3ZDLE1BQU0sRUFDTixFQUFFLEVBQ0YsVUFBVSxDQUNiLENBQUM7SUFFRixNQUFN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QUFHLEVBQUUscUJBQVM7SUFDZCxNQUFNLEVBQUUsMkJBQVk7SUFDcEIsS0FBSyxFQUFFLHlCQUFXO0NBQ3JCLENBQUM7QUFFRixLQUFLLE1BQU0sSUFBSSxJQUFJLGlCQUFTLEVBQUU7SUFDMUIsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUU7UUFDMUIsSUFBSSxJQUFJLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUNwQixJQUFJLElBQUksS0FBSyxRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFO1lBQzFDLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1NBQ3BCO1FBQ0QsSUFBQSxhQUFJLEVBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0tBQ3ZEO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdGVzdCwgeyBFeGVjdXRpb25Db250ZXh0LCBNYWNybyB9IGZyb20gXCJhdmFcIjtcbmltcG9ydCAqIGFzIHN5cyBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgcGF0aEV4aXN0cywgcmVtb3ZlLCBzdGF0IH0gZnJvbSBcImZzLWV4dHJhXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IENvbW1vbk9wdGlvbnMsIGxvZywgUHJvdmlkZXIsIHByb3ZpZGVycyB9IGZyb20gXCIuLi9pbmRleFwiO1xuaW1wb3J0IHsgYXdzUGFja2VyIH0gZnJvbSBcIi4uL3NyYy9hd3MvYXdzLWZhYXN0XCI7XG5pbXBvcnQgeyBnb29nbGVQYWNrZXIgfSBmcm9tIFwiLi4vc3JjL2dvb2dsZS9nb29nbGUtZmFhc3RcIjtcbmltcG9ydCB7IGxvY2FsUGFja2VyIH0gZnJvbSBcIi4uL3NyYy9sb2NhbC9sb2NhbC1mYWFzdFwiO1xuaW1wb3J0IHsgUGFja2VyUmVzdWx0LCB1bnppcEluRGlyIH0gZnJvbSBcIi4uL3NyYy9wYWNrZXJcIjtcbmltcG9ydCB7IFdyYXBwZXJPcHRpb25zIH0gZnJvbSBcIi4uL3NyYy93cmFwcGVyXCI7XG5cbmNvbnN0IGtiID0gMTAyNDtcblxuaW50ZXJmYWNlIFBhY2thZ2VDb25maWd1cmF0aW9uIGV4dGVuZHMgQ29tbW9uT3B0aW9ucyB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIGNoZWNrPzogKHQ6IEV4ZWN1dGlvbkNvbnRleHQsIHJvb3Q6IHN0cmluZykgPT4gUHJvbWlzZTx2b2lkPjtcbn1cblxuZnVuY3Rpb24gZXhlYyhjbWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHJlc3VsdCA9IHN5cy5leGVjU3luYyhjbWQpLnRvU3RyaW5nKCk7XG4gICAgbG9nLmluZm8ocmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG50eXBlIFBhY2tlciA9IChcbiAgICBmdW5jdGlvbk1vZHVsZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IENvbW1vbk9wdGlvbnMsXG4gICAgd3JhcHBlck9wdGlvbnM6IFdyYXBwZXJPcHRpb25zLFxuICAgIEZ1bmN0aW9uTmFtZTogc3RyaW5nXG4pID0+IFByb21pc2U8UGFja2VyUmVzdWx0PjtcblxuY29uc3QgdGVzdFBhY2tlcjogTWFjcm88W1Byb3ZpZGVyLCBQYWNrZXIsIFBhY2thZ2VDb25maWd1cmF0aW9uLCBudW1iZXJdPiA9IGFzeW5jIChcbiAgICB0OiBFeGVjdXRpb25Db250ZXh0LFxuICAgIHByb3ZpZGVyOiBQcm92aWRlcixcbiAgICBwYWNrOiBQYWNrZXIsXG4gICAgY29uZmlnOiBQYWNrYWdlQ29uZmlndXJhdGlvbixcbiAgICBzaXplOiBudW1iZXJcbikgPT4ge1xuICAgIGNvbnN0IGlkZW50aWZpZXIgPSBgJHtwcm92aWRlcn0tJHtjb25maWcubmFtZX1gO1xuICAgIGNvbnN0IHRtcERpciA9IHBhdGguam9pbihcInRtcFwiLCBpZGVudGlmaWVyKTtcbiAgICBleGVjKGBta2RpciAtcCAke3RtcERpcn1gKTtcblxuICAgIHByb2Nlc3MuZW52W1wiRkFBU1RfUEFDS0FHRV9ESVJcIl0gPSBcInRtcFwiO1xuXG4gICAgY29uc3QgeyBhcmNoaXZlIH0gPSBhd2FpdCBwYWNrKFxuICAgICAgICByZXF1aXJlLnJlc29sdmUoXCIuL2ZpeHR1cmVzL2Z1bmN0aW9uc1wiKSxcbiAgICAgICAgY29uZmlnLFxuICAgICAgICB7fSxcbiAgICAgICAgaWRlbnRpZmllclxuICAgICk7XG5cbiAgICBhd2FpdCByZW1vdmUodG1wRGlyKTtcbiAgICBjb25zdCB3cml0ZVByb21pc2UgPSBuZXcgUHJvbWlzZShyZXNvbHZlID0+IGFyY2hpdmUub24oXCJlbmRcIiwgcmVzb2x2ZSkpO1xuICAgIGNvbnN0IHVuemlwUHJvbWlzZSA9IHVuemlwSW5EaXIodG1wRGlyLCBhcmNoaXZlKTtcblxuICAgIGF3YWl0IFByb21pc2UuYWxsKFt3cml0ZVByb21pc2UsIHVuemlwUHJvbWlzZV0pO1xuICAgIGNvbnN0IHppcEZpbGUgPSBwYXRoLmpvaW4oXCJ0bXBcIiwgaWRlbnRpZmllciArIFwiLnppcFwiKTtcbiAgICBjb25zdCBieXRlcyA9IChhd2FpdCBzdGF0KHppcEZpbGUpKS5zaXplO1xuICAgIHQudHJ1ZShieXRlcyA8IHNpemUsIGBwYWNrYWdlIHNpemUgJHtieXRlc30gZXhjZWVkZWQgbWF4aW11bSAke3NpemV9YCk7XG4gICAgdC5pcyhleGVjKGBjZCAke3RtcERpcn0gJiYgbm9kZSBpbmRleC5qc2ApLCBcImZhYXN0OiBzdWNjZXNzZnVsIGNvbGQgc3RhcnQuXFxuXCIpO1xuICAgIGNvbmZpZy5jaGVjayAmJiAoYXdhaXQgY29uZmlnLmNoZWNrKHQsIHRtcERpcikpO1xufTtcblxudGVzdFBhY2tlci50aXRsZSA9IChfdGl0bGUgPSBcIlwiLCBwcm92aWRlciwgX3BhY2tlciwgb3B0aW9ucykgPT5cbiAgICBgcGFja2VyICR7cHJvdmlkZXJ9LSR7b3B0aW9ucy5uYW1lfWA7XG5cbmZ1bmN0aW9uIGFkZGVkKGRpcjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGFzeW5jICh0OiBFeGVjdXRpb25Db250ZXh0LCByb290OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgZmlsZVBhdGggPSBqb2luKHJvb3QsIGRpciwgXCJmaWxlLnR4dFwiKTtcbiAgICAgICAgdC50cnVlKGF3YWl0IHBhdGhFeGlzdHMoZmlsZVBhdGgpLCBgZmlsZSAke2ZpbGVQYXRofSBkb2VzIG5vdCBleGlzdCBpbiBwYWNrYWdlYCk7XG4gICAgICAgIGNvbnN0IHsgbW9kZSB9ID0gYXdhaXQgc3RhdChqb2luKHJvb3QsIGRpciwgXCJzY3JpcHRcIikpO1xuICAgICAgICBjb25zdCB7IG1vZGU6IG9yaWdNb2RlIH0gPSBhd2FpdCBzdGF0KFwidGVzdC9maXh0dXJlcy9kaXIvc2NyaXB0XCIpO1xuICAgICAgICB0LmlzKG1vZGUsIG9yaWdNb2RlLCBcImZpbGUgbW9kZXMgYXJlIHByZXNlcnZlZFwiKTtcbiAgICAgICAgdC5pcyhtb2RlICYgMG83MDAsIDBvNzAwLCBcImV4ZWN1dGFibGUgbW9kZSBpcyBwcmVzZXJ2ZWQgaW4gYWRkZWQgZmlsZXNcIik7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gZXhjbHVkZWQoZmlsZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGFzeW5jICh0OiBFeGVjdXRpb25Db250ZXh0LCByb290OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgZmlsZVBhdGggPSBqb2luKHJvb3QsIGZpbGUpO1xuICAgICAgICB0LmZhbHNlKFxuICAgICAgICAgICAgYXdhaXQgcGF0aEV4aXN0cyhmaWxlUGF0aCksXG4gICAgICAgICAgICBgZmlsZSAke2ZpbGV9IGV4aXN0cyBidXQgaXQgc2hvdWxkIGJlIGV4Y2x1ZGVkYFxuICAgICAgICApO1xuICAgIH07XG59XG5cbmNvbnN0IGNvbmZpZ3M6IFBhY2thZ2VDb25maWd1cmF0aW9uW10gPSBbXG4gICAgeyBuYW1lOiBcImh0dHBzXCIsIG1vZGU6IFwiaHR0cHNcIiB9LFxuICAgIHsgbmFtZTogXCJxdWV1ZVwiLCBtb2RlOiBcInF1ZXVlXCIgfSxcbiAgICB7IG5hbWU6IFwiaHR0cHMtcGFja2FnZVwiLCBtb2RlOiBcImh0dHBzXCIsIHBhY2thZ2VKc29uOiBcInRlc3QvZml4dHVyZXMvcGFja2FnZS5qc29uXCIgfSxcbiAgICB7IG5hbWU6IFwicXVldWUtcGFja2FnZVwiLCBtb2RlOiBcInF1ZXVlXCIsIHBhY2thZ2VKc29uOiBcInRlc3QvZml4dHVyZXMvcGFja2FnZS5qc29uXCIgfSxcbiAgICB7XG4gICAgICAgIG5hbWU6IFwiaW5jbHVkZVwiLFxuICAgICAgICBpbmNsdWRlOiBbXCJ0ZXN0L2ZpeHR1cmVzL2Rpci8qKi8qXCJdLFxuICAgICAgICBjaGVjazogYWRkZWQoXCJ0ZXN0L2ZpeHR1cmVzL2RpclwiKVxuICAgIH0sXG4gICAge1xuICAgICAgICBuYW1lOiBcImluY2x1ZGUtY3dkXCIsXG4gICAgICAgIGluY2x1ZGU6IFt7IHBhdGg6IFwiZGlyLyoqLypcIiwgY3dkOiBcInRlc3QvZml4dHVyZXNcIiB9XSxcbiAgICAgICAgY2hlY2s6IGFkZGVkKFwiZGlyXCIpXG4gICAgfSxcbiAgICB7XG4gICAgICAgIG5hbWU6IFwiaW5jbHVkZS1kaXJcIixcbiAgICAgICAgaW5jbHVkZTogW1widGVzdC9maXh0dXJlcy9kaXJcIl0sXG4gICAgICAgIGNoZWNrOiBhZGRlZChcInRlc3QvZml4dHVyZXMvZGlyXCIpXG4gICAgfSxcbiAgICB7XG4gICAgICAgIG5hbWU6IFwiaW5jbHVkZS1kaXItY3dkXCIsXG4gICAgICAgIGluY2x1ZGU6IFt7IHBhdGg6IFwiZGlyXCIsIGN3ZDogXCJ0ZXN0L2ZpeHR1cmVzXCIgfV0sXG4gICAgICAgIGNoZWNrOiBhZGRlZChcImRpclwiKVxuICAgIH0sXG4gICAge1xuICAgICAgICBuYW1lOiBcImV4Y2x1ZGVcIixcbiAgICAgICAgaW5jbHVkZTogW1widGVzdC9maXh0dXJlcy9kaXIvKiovKlwiXSxcbiAgICAgICAgZXhjbHVkZTogW1wiKiovKi5leGNcIl0sXG4gICAgICAgIGNoZWNrOiBleGNsdWRlZChcInRlc3QvZml4dHVyZXMvZGlyL2V4Y2x1ZGVkLmV4Y1wiKVxuICAgIH0sXG4gICAge1xuICAgICAgICBuYW1lOiBcImV4Y2x1ZGUtZmlsZVwiLFxuICAgICAgICBpbmNsdWRlOiBbXCJ0ZXN0L2ZpeHR1cmVzL2Rpci8qKi8qXCJdLFxuICAgICAgICBleGNsdWRlOiBbXCJ0ZXN0L2ZpeHR1cmVzL2Rpci9leGNsdWRlZC5leGNcIl0sXG4gICAgICAgIGNoZWNrOiBleGNsdWRlZChcInRlc3QvZml4dHVyZXMvZGlyL2V4Y2x1ZGVkLmV4Y1wiKVxuICAgIH1cbl07XG5cbmNvbnN0IHBhY2tlcnM6IHsgW3Byb3ZpZGVyIGluIFByb3ZpZGVyXTogUGFja2VyIH0gPSB7XG4gICAgYXdzOiBhd3NQYWNrZXIsXG4gICAgZ29vZ2xlOiBnb29nbGVQYWNrZXIsXG4gICAgbG9jYWw6IGxvY2FsUGFja2VyXG59O1xuXG5mb3IgKGNvbnN0IG5hbWUgb2YgcHJvdmlkZXJzKSB7XG4gICAgZm9yIChjb25zdCBjb25maWcgb2YgY29uZmlncykge1xuICAgICAgICBsZXQgc2l6ZSA9IDEzMCAqIGtiO1xuICAgICAgICBpZiAobmFtZSA9PT0gXCJnb29nbGVcIiAmJiAhY29uZmlnLnBhY2thZ2VKc29uKSB7XG4gICAgICAgICAgICBzaXplID0gMTQwMCAqIGtiO1xuICAgICAgICB9XG4gICAgICAgIHRlc3QodGVzdFBhY2tlciwgbmFtZSwgcGFja2Vyc1tuYW1lXSwgY29uZmlnLCBzaXplKTtcbiAgICB9XG59XG4iXX0=
\No newline at end of file