forked from serverless/serverless
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mocha-patch.js
82 lines (73 loc) · 2.67 KB
/
mocha-patch.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'use strict';
const fs = require('fs');
const Module = require('module');
// Temporary patch to help tackle peekaboo error, by revelaing fuller stack trace for "fs" errors
// https://github.com/serverless/serverless/runs/1740873363
const patchPromised = (name) => {
const original = fs.promises[name];
fs.promises[name] = Object.defineProperties(
function (...args) {
const stack = new Error().stack;
return original.apply(this, args).catch((error) => {
error.message += ` (initiated at: ${stack}\n)`;
throw error;
});
},
{
length: { value: original.length },
name: { value: original.name },
}
);
};
const patchCallback = (name) => {
const original = fs[name];
fs[name] = Object.defineProperties(
function (...args) {
const stack = new Error().stack;
const callback = args[args.length - 1];
original.call(this, ...args.slice(0, -1), (error, ...result) => {
if (error) error.message += ` (initiated at: ${stack}\n)`;
return callback.call(this, error, ...result);
});
},
{
length: { value: original.length },
name: { value: original.name },
}
);
};
patchPromised('mkdir');
patchPromised('open');
patchPromised('readFile');
patchCallback('mkdir');
patchCallback('open');
patchCallback('readFile');
const ensureArtifact = require('../lib/utils/ensure-artifact');
const localServerlessPathModulePath = require.resolve('../lib/cli/local-serverless-path');
const resolveInput = require('../lib/cli/resolve-input');
const BbPromise = require('bluebird');
BbPromise.config({
longStackTraces: true,
});
const { runnerEmitter } = require('@serverless/test/setup/patch');
runnerEmitter.on('runner', (runner) => {
runner.on('suite end', (suite) => {
if (!suite.parent || !suite.parent.root) return;
resolveInput.clear();
// Ensure to reset cache for local serverless installation resolution
// Leaking it across test files may introduce wrong assumptions when result is used for testing
if (require.cache[localServerlessPathModulePath]) {
// As we rely on native require.resolve, we need to ensure that it's cache related to
// tmp homedir is cleared
const homedir = require('os').homedir();
for (const key of Object.keys(Module._pathCache)) {
if (key.includes(homedir)) delete Module._pathCache[key];
}
delete require.cache[localServerlessPathModulePath];
}
// Ensure to reset memoization on artifacts generation after each test file run.
// Reason is that homedir is automatically cleaned for each test,
// therefore eventually built custom resource file is also removed
ensureArtifact.clear();
});
});