UNPKG

4.32 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.TestTracker = void 0;
7const ms_1 = __importDefault(require("ms"));
8const utils_1 = require("@terascope/utils");
9const signale_1 = __importDefault(require("../signale"));
10const misc_1 = require("../misc");
11class TestTracker {
12 constructor(options) {
13 this.options = options;
14 this.started = 0;
15 this.ended = 0;
16 this.expected = 0;
17 this.cleanups = new Map();
18 this.errors = new Set();
19 this.shuttingDown = false;
20 this.onSIGTERM = () => {
21 process.stderr.write('\n');
22 signale_1.default.info('received SIGTERM');
23 this.finish();
24 };
25 this.onSIGINT = () => {
26 process.stderr.write('\n');
27 signale_1.default.info('received SIGINT');
28 this.finish();
29 };
30 process.on('SIGINT', this.onSIGINT);
31 process.on('SIGTERM', this.onSIGTERM);
32 }
33 hasErrors() {
34 return this.errors.size > 0;
35 }
36 addError(error) {
37 this.errors.add(utils_1.isString(error) ? error : utils_1.getFullErrorStack(error));
38 }
39 addCleanup(key, fn, ...args) {
40 this.cleanups.set(key, () => fn(...args));
41 }
42 async runCleanupByKey(key) {
43 if (!this.cleanups.has(key))
44 return;
45 const fn = this.cleanups.get(key);
46 if (!utils_1.isFunction(fn)) {
47 signale_1.default.warn(new Error(`Expected cleanup function for key ${key} got nothing`));
48 this.cleanups.delete(key);
49 return;
50 }
51 try {
52 await fn();
53 this.cleanups.delete(key);
54 }
55 catch (err) {
56 signale_1.default.warn(err, `cleanup ${key} error`);
57 }
58 }
59 async finish() {
60 if (this.shuttingDown) {
61 await this.end(true);
62 process.removeListener('SIGINT', this.onSIGINT);
63 process.removeListener('SIGTERM', this.onSIGTERM);
64 return;
65 }
66 this.shuttingDown = true;
67 if (this.options.keepOpen) {
68 signale_1.default.info('keeping the tests open so the services don\'t shutdown, use ctrl-c to exit.');
69 const id = setTimeout(() => {
70 this.end();
71 }, ms_1.default('1 hour'));
72 this.addCleanup('keepOpen', (timeoutId) => clearTimeout(timeoutId), id);
73 return;
74 }
75 await this.end();
76 }
77 async end(force = false) {
78 if (!force) {
79 const keys = [...this.cleanups.keys()];
80 if (keys.length && this.options.debug) {
81 signale_1.default.info('Cleaning up after tests tests');
82 }
83 for (const key of keys) {
84 await this.runCleanupByKey(key);
85 }
86 }
87 else {
88 signale_1.default.warn('Skipping cleanup because the SIGTERM and SIGINT was called more than once');
89 }
90 let errorMsg = '';
91 const errors = [...this.errors];
92 if (errors.length > 1) {
93 errorMsg = `Multiple Test Failures:${misc_1.formatList(errors)}`;
94 }
95 else if (errors.length === 1) {
96 ([errorMsg] = errors);
97 }
98 if (errors.length) {
99 process.stderr.write('\n');
100 signale_1.default.fatal(`${errorMsg}`);
101 process.stderr.write('\n');
102 const exitCode = (process.exitCode || 0) > 0 ? process.exitCode : 1;
103 process.exit(exitCode);
104 }
105 if (this.started === 0 || this.expected === 0) {
106 signale_1.default.warn('No tests ran');
107 // if not tests are expected to run, it is safe to exit
108 process.exit(this.expected === 0 ? 0 : 1);
109 }
110 if (this.ended !== this.expected) {
111 const msg = `started: ${this.started}, completed: ${this.ended}, total: ${this.expected}`;
112 signale_1.default.error(`Incomplete tests - ${msg}`);
113 process.exit(1);
114 }
115 signale_1.default.success('All tests completed');
116 process.exit(0);
117 }
118}
119exports.TestTracker = TestTracker;
120//# sourceMappingURL=tracker.js.map
\No newline at end of file