@datadog/datadog-ci 0.17.7 → 0.17.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/LICENSE-3rdparty.csv +2 -0
  2. package/README.md +3 -1
  3. package/dist/{commands/dependencies/index.d.ts → cli.d.ts} +0 -0
  4. package/dist/cli.js +34 -0
  5. package/dist/commands/{dsyms/index.d.ts → dependencies/cli.d.ts} +0 -0
  6. package/dist/commands/dependencies/{index.js → cli.js} +0 -0
  7. package/dist/commands/dependencies/upload.d.ts +1 -1
  8. package/dist/commands/{git-metadata/index.d.ts → dsyms/cli.d.ts} +0 -0
  9. package/dist/commands/dsyms/{index.js → cli.js} +0 -0
  10. package/dist/commands/dsyms/upload.d.ts +1 -1
  11. package/dist/commands/{junit/index.d.ts → git-metadata/cli.d.ts} +0 -0
  12. package/dist/commands/git-metadata/{index.js → cli.js} +0 -0
  13. package/dist/commands/git-metadata/upload.d.ts +1 -1
  14. package/dist/commands/git-metadata/upload.js +6 -1
  15. package/dist/commands/{lambda/__tests__/function.test.d.ts → junit/cli.d.ts} +0 -0
  16. package/dist/commands/junit/{index.js → cli.js} +0 -0
  17. package/dist/commands/junit/upload.d.ts +1 -1
  18. package/dist/commands/lambda/__tests__/fixtures.d.ts +42 -0
  19. package/dist/commands/lambda/__tests__/fixtures.js +73 -0
  20. package/dist/commands/lambda/{index.d.ts → __tests__/functions/commons.test.d.ts} +0 -0
  21. package/dist/commands/lambda/__tests__/functions/commons.test.js +350 -0
  22. package/dist/commands/{sourcemaps/index.d.ts → lambda/__tests__/functions/instrument.test.d.ts} +0 -0
  23. package/dist/commands/lambda/__tests__/{function.test.js → functions/instrument.test.js} +504 -476
  24. package/dist/commands/{trace/index.d.ts → lambda/__tests__/functions/uninstrument.test.d.ts} +0 -0
  25. package/dist/commands/lambda/__tests__/functions/uninstrument.test.js +371 -0
  26. package/dist/commands/lambda/__tests__/instrument.test.js +351 -234
  27. package/dist/commands/lambda/__tests__/loggroup.test.js +98 -34
  28. package/dist/commands/lambda/__tests__/tags.test.js +107 -31
  29. package/dist/commands/lambda/__tests__/uninstrument.test.d.ts +1 -0
  30. package/dist/commands/lambda/__tests__/uninstrument.test.js +281 -0
  31. package/dist/commands/lambda/cli.d.ts +1 -0
  32. package/dist/commands/lambda/cli.js +5 -0
  33. package/dist/commands/lambda/constants.d.ts +18 -6
  34. package/dist/commands/lambda/constants.js +30 -6
  35. package/dist/commands/lambda/functions/commons.d.ts +101 -0
  36. package/dist/commands/lambda/functions/commons.js +258 -0
  37. package/dist/commands/lambda/functions/instrument.d.ts +7 -0
  38. package/dist/commands/lambda/functions/instrument.js +186 -0
  39. package/dist/commands/lambda/functions/uninstrument.d.ts +7 -0
  40. package/dist/commands/lambda/functions/uninstrument.js +121 -0
  41. package/dist/commands/lambda/instrument.d.ts +4 -4
  42. package/dist/commands/lambda/instrument.js +103 -57
  43. package/dist/commands/lambda/interfaces.d.ts +53 -0
  44. package/dist/commands/lambda/loggroup.d.ts +4 -7
  45. package/dist/commands/lambda/loggroup.js +30 -5
  46. package/dist/commands/lambda/tags.d.ts +3 -4
  47. package/dist/commands/lambda/tags.js +19 -3
  48. package/dist/commands/lambda/uninstrument.d.ts +12 -0
  49. package/dist/commands/lambda/uninstrument.js +166 -0
  50. package/dist/commands/sourcemaps/cli.d.ts +1 -0
  51. package/dist/commands/sourcemaps/{index.js → cli.js} +0 -0
  52. package/dist/commands/sourcemaps/upload.d.ts +1 -1
  53. package/dist/commands/synthetics/__tests__/cli.test.js +13 -13
  54. package/dist/commands/synthetics/__tests__/fixtures.js +0 -1
  55. package/dist/commands/synthetics/__tests__/reporters/default.test.js +3 -2
  56. package/dist/commands/synthetics/__tests__/run-test.test.js +6 -6
  57. package/dist/commands/synthetics/__tests__/utils.test.js +9 -5
  58. package/dist/commands/synthetics/__tests__/websocket.test.js +3 -3
  59. package/dist/commands/synthetics/cli.d.ts +1 -26
  60. package/dist/commands/synthetics/cli.js +2 -227
  61. package/dist/commands/synthetics/command.d.ts +26 -0
  62. package/dist/commands/synthetics/command.js +229 -0
  63. package/dist/commands/synthetics/index.d.ts +5 -1
  64. package/dist/commands/synthetics/index.js +31 -2
  65. package/dist/commands/synthetics/interfaces.d.ts +1 -1
  66. package/dist/commands/synthetics/reporters/default.d.ts +3 -3
  67. package/dist/commands/synthetics/reporters/default.js +4 -3
  68. package/dist/commands/synthetics/utils.d.ts +1 -3
  69. package/dist/commands/synthetics/utils.js +14 -15
  70. package/dist/commands/trace/cli.d.ts +1 -0
  71. package/dist/commands/trace/{index.js → cli.js} +0 -0
  72. package/dist/commands/trace/trace.d.ts +1 -1
  73. package/dist/helpers/__tests__/ci.test.js +51 -114
  74. package/dist/helpers/__tests__/user-provided-git.test.js +14 -2
  75. package/dist/helpers/__tests__/utils.test.js +4 -0
  76. package/dist/helpers/ci.js +62 -96
  77. package/dist/helpers/interfaces.d.ts +28 -2
  78. package/dist/helpers/user-provided-git.js +11 -2
  79. package/dist/helpers/utils.d.ts +4 -0
  80. package/dist/helpers/utils.js +18 -1
  81. package/dist/index.d.ts +3 -1
  82. package/dist/index.js +23 -31
  83. package/package.json +8 -6
  84. package/dist/commands/lambda/function.d.ts +0 -43
  85. package/dist/commands/lambda/function.js +0 -273
  86. package/dist/commands/lambda/index.js +0 -4
@@ -1,229 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
2
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.RunTestCommand = exports.DEFAULT_COMMAND_CONFIG = void 0;
16
- const chalk_1 = __importDefault(require("chalk"));
17
- const clipanion_1 = require("clipanion");
18
- const deep_extend_1 = __importDefault(require("deep-extend"));
19
- const utils_1 = require("../../helpers/utils");
20
- const errors_1 = require("./errors");
21
- const interfaces_1 = require("./interfaces");
22
- const default_1 = require("./reporters/default");
23
- const junit_1 = require("./reporters/junit");
24
- const run_test_1 = require("./run-test");
25
- const utils_2 = require("./utils");
26
- exports.DEFAULT_COMMAND_CONFIG = {
27
- apiKey: '',
28
- appKey: '',
29
- configPath: 'datadog-ci.json',
30
- datadogSite: 'datadoghq.com',
31
- failOnCriticalErrors: false,
32
- failOnTimeout: true,
33
- files: ['{,!(node_modules)/**/}*.synthetics.json'],
34
- global: {},
35
- locations: [],
36
- pollingTimeout: 2 * 60 * 1000,
37
- proxy: { protocol: 'http' },
38
- publicIds: [],
39
- subdomain: 'app',
40
- tunnel: false,
41
- };
42
- class RunTestCommand extends clipanion_1.Command {
43
- constructor() {
44
- super(...arguments);
45
- this.config = JSON.parse(JSON.stringify(exports.DEFAULT_COMMAND_CONFIG)); // Deep copy to avoid mutation during unit tests
46
- }
47
- execute() {
48
- return __awaiter(this, void 0, void 0, function* () {
49
- const reporters = [new default_1.DefaultReporter(this)];
50
- this.reporter = utils_2.getReporter(reporters);
51
- if (this.jUnitReport) {
52
- reporters.push(new junit_1.JUnitReporter(this));
53
- }
54
- yield this.resolveConfig();
55
- const startTime = Date.now();
56
- if (this.config.tunnel) {
57
- this.reporter.log('You are using tunnel option, the chosen location(s) will be overridden by a location in your account region.\n');
58
- }
59
- let results;
60
- let summary;
61
- let tests;
62
- let triggers;
63
- try {
64
- ;
65
- ({ results, summary, tests, triggers } = yield run_test_1.executeTests(this.reporter, this.config));
66
- }
67
- catch (error) {
68
- if (error instanceof errors_1.CiError) {
69
- this.reportCiError(error, this.reporter);
70
- if (error instanceof errors_1.CriticalError && this.config.failOnCriticalErrors) {
71
- return 1;
72
- }
73
- }
74
- return 0;
75
- }
76
- return this.renderResults(results, summary, tests, triggers, startTime);
77
- });
78
- }
79
- getAppBaseURL() {
80
- return `https://${this.config.subdomain}.${this.config.datadogSite}/`;
81
- }
82
- renderResults(results, summary, tests, triggers, startTime) {
83
- var _a, _b, _c, _d;
84
- // Sort tests to show success first then non blocking failures and finally blocking failures.
85
- tests.sort(this.sortTestsByOutcome(results));
86
- // Rendering the results.
87
- (_a = this.reporter) === null || _a === void 0 ? void 0 : _a.reportStart({ startTime });
88
- const locationNames = triggers.locations.reduce((mapping, location) => {
89
- mapping[location.id] = location.display_name;
90
- return mapping;
91
- }, {});
92
- let hasSucceeded = true; // Determine if all the tests have succeeded
93
- for (const test of tests) {
94
- const testResults = results[test.public_id];
95
- if (!this.config.failOnTimeout) {
96
- if (!summary.timedOut) {
97
- summary.timedOut = 0;
98
- }
99
- const hasTimeout = testResults.some((pollResult) => pollResult.result.error === interfaces_1.ERRORS.TIMEOUT);
100
- if (hasTimeout) {
101
- summary.timedOut++;
102
- }
103
- }
104
- if (!this.config.failOnCriticalErrors) {
105
- if (!summary.criticalErrors) {
106
- summary.criticalErrors = 0;
107
- }
108
- const hasCriticalErrors = testResults.some((pollResult) => utils_2.isCriticalError(pollResult.result));
109
- if (hasCriticalErrors) {
110
- summary.criticalErrors++;
111
- }
112
- }
113
- const passed = utils_2.hasTestSucceeded(testResults, this.config.failOnCriticalErrors, this.config.failOnTimeout);
114
- if (passed) {
115
- summary.passed++;
116
- }
117
- else {
118
- summary.failed++;
119
- if (((_b = test.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) !== interfaces_1.ExecutionRule.NON_BLOCKING) {
120
- hasSucceeded = false;
121
- }
122
- }
123
- (_c = this.reporter) === null || _c === void 0 ? void 0 : _c.testEnd(test, testResults, this.getAppBaseURL(), locationNames, this.config.failOnCriticalErrors, this.config.failOnTimeout);
124
- }
125
- (_d = this.reporter) === null || _d === void 0 ? void 0 : _d.runEnd(summary);
126
- return hasSucceeded ? 0 : 1;
127
- }
128
- reportCiError(error, reporter) {
129
- switch (error.code) {
130
- case 'NO_RESULTS_TO_POLL':
131
- reporter.log('No results to poll.\n');
132
- break;
133
- case 'NO_TESTS_TO_RUN':
134
- reporter.log('No test to run.\n');
135
- break;
136
- case 'MISSING_APP_KEY':
137
- reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_APP_KEY')} in your environment.\n`);
138
- break;
139
- case 'MISSING_API_KEY':
140
- reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_API_KEY')} in your environment.\n`);
141
- break;
142
- case 'POLL_RESULTS_FAILED':
143
- reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to poll test results ')}\n${error.message}\n\n`);
144
- break;
145
- case 'TUNNEL_START_FAILED':
146
- reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to start tunnel')}\n${error.message}\n\n`);
147
- break;
148
- case 'TRIGGER_TESTS_FAILED':
149
- reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to trigger tests')}\n${error.message}\n\n`);
150
- break;
151
- case 'UNAVAILABLE_TEST_CONFIG':
152
- reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to obtain test configurations with search query ')}\n${error.message}\n\n`);
153
- break;
154
- case 'UNAVAILABLE_TUNNEL_CONFIG':
155
- reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to get tunnel configuration')}\n${error.message}\n\n`);
156
- }
157
- }
158
- resolveConfig() {
159
- var _a, _b;
160
- return __awaiter(this, void 0, void 0, function* () {
161
- // Default < file < ENV < CLI
162
- // Override with file config variables
163
- try {
164
- this.config = yield utils_1.parseConfigFile(this.config, (_a = this.configPath) !== null && _a !== void 0 ? _a : this.config.configPath);
165
- }
166
- catch (error) {
167
- if (this.configPath) {
168
- throw error;
169
- }
170
- }
171
- // Override with ENV variables
172
- this.config = deep_extend_1.default(this.config, utils_2.removeUndefinedValues({
173
- apiKey: process.env.DATADOG_API_KEY,
174
- appKey: process.env.DATADOG_APP_KEY,
175
- datadogSite: process.env.DATADOG_SITE,
176
- locations: (_b = process.env.DATADOG_SYNTHETICS_LOCATIONS) === null || _b === void 0 ? void 0 : _b.split(';'),
177
- subdomain: process.env.DATADOG_SUBDOMAIN,
178
- }));
179
- // Override with CLI parameters
180
- this.config = deep_extend_1.default(this.config, utils_2.removeUndefinedValues({
181
- apiKey: this.apiKey,
182
- appKey: this.appKey,
183
- configPath: this.configPath,
184
- datadogSite: this.datadogSite,
185
- failOnCriticalErrors: this.failOnCriticalErrors,
186
- failOnTimeout: this.failOnTimeout,
187
- files: this.files,
188
- publicIds: this.publicIds,
189
- subdomain: this.subdomain,
190
- testSearchQuery: this.testSearchQuery,
191
- tunnel: this.tunnel,
192
- }));
193
- if (typeof this.config.files === 'string') {
194
- this.reporter.log('[DEPRECATED] "files" should be an array of string instead of a string.\n');
195
- this.config.files = [this.config.files];
196
- }
197
- });
198
- }
199
- sortTestsByOutcome(results) {
200
- return (t1, t2) => {
201
- var _a, _b;
202
- const success1 = utils_2.hasTestSucceeded(results[t1.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
203
- const success2 = utils_2.hasTestSucceeded(results[t2.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
204
- const isNonBlockingTest1 = ((_a = t1.options.ci) === null || _a === void 0 ? void 0 : _a.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
205
- const isNonBlockingTest2 = ((_b = t2.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
206
- if (success1 === success2) {
207
- if (isNonBlockingTest1 === isNonBlockingTest2) {
208
- return 0;
209
- }
210
- return isNonBlockingTest1 ? -1 : 1;
211
- }
212
- return success1 ? -1 : 1;
213
- };
214
- }
215
- }
216
- exports.RunTestCommand = RunTestCommand;
217
- RunTestCommand.addPath('synthetics', 'run-tests');
218
- RunTestCommand.addOption('apiKey', clipanion_1.Command.String('--apiKey'));
219
- RunTestCommand.addOption('appKey', clipanion_1.Command.String('--appKey'));
220
- RunTestCommand.addOption('failOnCriticalErrors', clipanion_1.Command.Boolean('--failOnCriticalErrors'));
221
- RunTestCommand.addOption('configPath', clipanion_1.Command.String('--config'));
222
- RunTestCommand.addOption('datadogSite', clipanion_1.Command.String('--datadogSite'));
223
- RunTestCommand.addOption('files', clipanion_1.Command.Array('-f,--files'));
224
- RunTestCommand.addOption('failOnTimeout', clipanion_1.Command.Boolean('--failOnTimeout'));
225
- RunTestCommand.addOption('publicIds', clipanion_1.Command.Array('-p,--public-id'));
226
- RunTestCommand.addOption('testSearchQuery', clipanion_1.Command.String('-s,--search'));
227
- RunTestCommand.addOption('subdomain', clipanion_1.Command.Boolean('--subdomain'));
228
- RunTestCommand.addOption('tunnel', clipanion_1.Command.Boolean('-t,--tunnel'));
229
- RunTestCommand.addOption('runName', clipanion_1.Command.String('-n,--runName'));
3
+ const command_1 = require("./command");
4
+ module.exports = [command_1.RunTestCommand];
@@ -0,0 +1,26 @@
1
+ import { Command } from 'clipanion';
2
+ import { CommandConfig } from './interfaces';
3
+ export declare const DEFAULT_COMMAND_CONFIG: CommandConfig;
4
+ export declare class RunTestCommand extends Command {
5
+ jUnitReport?: string;
6
+ runName?: string;
7
+ private apiKey?;
8
+ private appKey?;
9
+ private config;
10
+ private configPath?;
11
+ private datadogSite?;
12
+ private failOnCriticalErrors?;
13
+ private failOnTimeout?;
14
+ private files?;
15
+ private publicIds?;
16
+ private reporter?;
17
+ private subdomain?;
18
+ private testSearchQuery?;
19
+ private tunnel?;
20
+ execute(): Promise<1 | 0>;
21
+ private getAppBaseURL;
22
+ private renderResults;
23
+ private reportCiError;
24
+ private resolveConfig;
25
+ private sortTestsByOutcome;
26
+ }
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.RunTestCommand = exports.DEFAULT_COMMAND_CONFIG = void 0;
16
+ const chalk_1 = __importDefault(require("chalk"));
17
+ const clipanion_1 = require("clipanion");
18
+ const deep_extend_1 = __importDefault(require("deep-extend"));
19
+ const utils_1 = require("../../helpers/utils");
20
+ const errors_1 = require("./errors");
21
+ const interfaces_1 = require("./interfaces");
22
+ const default_1 = require("./reporters/default");
23
+ const junit_1 = require("./reporters/junit");
24
+ const run_test_1 = require("./run-test");
25
+ const utils_2 = require("./utils");
26
+ exports.DEFAULT_COMMAND_CONFIG = {
27
+ apiKey: '',
28
+ appKey: '',
29
+ configPath: 'datadog-ci.json',
30
+ datadogSite: 'datadoghq.com',
31
+ failOnCriticalErrors: false,
32
+ failOnTimeout: true,
33
+ files: ['{,!(node_modules)/**/}*.synthetics.json'],
34
+ global: {},
35
+ locations: [],
36
+ pollingTimeout: 2 * 60 * 1000,
37
+ proxy: { protocol: 'http' },
38
+ publicIds: [],
39
+ subdomain: 'app',
40
+ tunnel: false,
41
+ };
42
+ class RunTestCommand extends clipanion_1.Command {
43
+ constructor() {
44
+ super(...arguments);
45
+ this.config = JSON.parse(JSON.stringify(exports.DEFAULT_COMMAND_CONFIG)); // Deep copy to avoid mutation during unit tests
46
+ }
47
+ execute() {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ const reporters = [new default_1.DefaultReporter(this)];
50
+ this.reporter = utils_2.getReporter(reporters);
51
+ if (this.jUnitReport) {
52
+ reporters.push(new junit_1.JUnitReporter(this));
53
+ }
54
+ yield this.resolveConfig();
55
+ const startTime = Date.now();
56
+ if (this.config.tunnel) {
57
+ this.reporter.log('You are using tunnel option, the chosen location(s) will be overridden by a location in your account region.\n');
58
+ }
59
+ let results;
60
+ let summary;
61
+ let tests;
62
+ let triggers;
63
+ try {
64
+ ;
65
+ ({ results, summary, tests, triggers } = yield run_test_1.executeTests(this.reporter, this.config));
66
+ }
67
+ catch (error) {
68
+ if (error instanceof errors_1.CiError) {
69
+ this.reportCiError(error, this.reporter);
70
+ if (error instanceof errors_1.CriticalError && this.config.failOnCriticalErrors) {
71
+ return 1;
72
+ }
73
+ }
74
+ return 0;
75
+ }
76
+ return this.renderResults(results, summary, tests, triggers, startTime);
77
+ });
78
+ }
79
+ getAppBaseURL() {
80
+ return `https://${this.config.subdomain}.${this.config.datadogSite}/`;
81
+ }
82
+ renderResults(results, summary, tests, triggers, startTime) {
83
+ var _a, _b, _c, _d;
84
+ // Sort tests to show success first then non blocking failures and finally blocking failures.
85
+ tests.sort(this.sortTestsByOutcome(results));
86
+ // Rendering the results.
87
+ (_a = this.reporter) === null || _a === void 0 ? void 0 : _a.reportStart({ startTime });
88
+ const locationNames = triggers.locations.reduce((mapping, location) => {
89
+ mapping[location.id] = location.display_name;
90
+ return mapping;
91
+ }, {});
92
+ let hasSucceeded = true; // Determine if all the tests have succeeded
93
+ for (const test of tests) {
94
+ const testResults = results[test.public_id];
95
+ if (!this.config.failOnTimeout) {
96
+ if (!summary.timedOut) {
97
+ summary.timedOut = 0;
98
+ }
99
+ const hasTimeout = testResults.some((pollResult) => pollResult.result.error === interfaces_1.ERRORS.TIMEOUT);
100
+ if (hasTimeout) {
101
+ summary.timedOut++;
102
+ }
103
+ }
104
+ if (!this.config.failOnCriticalErrors) {
105
+ if (!summary.criticalErrors) {
106
+ summary.criticalErrors = 0;
107
+ }
108
+ const hasCriticalErrors = testResults.some((pollResult) => utils_2.isCriticalError(pollResult.result));
109
+ if (hasCriticalErrors) {
110
+ summary.criticalErrors++;
111
+ }
112
+ }
113
+ const passed = utils_2.hasTestSucceeded(testResults, this.config.failOnCriticalErrors, this.config.failOnTimeout);
114
+ if (passed) {
115
+ summary.passed++;
116
+ }
117
+ else {
118
+ summary.failed++;
119
+ if (((_b = test.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) !== interfaces_1.ExecutionRule.NON_BLOCKING) {
120
+ hasSucceeded = false;
121
+ }
122
+ }
123
+ (_c = this.reporter) === null || _c === void 0 ? void 0 : _c.testEnd(test, testResults, this.getAppBaseURL(), locationNames, this.config.failOnCriticalErrors, this.config.failOnTimeout);
124
+ }
125
+ (_d = this.reporter) === null || _d === void 0 ? void 0 : _d.runEnd(summary);
126
+ return hasSucceeded ? 0 : 1;
127
+ }
128
+ reportCiError(error, reporter) {
129
+ switch (error.code) {
130
+ case 'NO_RESULTS_TO_POLL':
131
+ reporter.log('No results to poll.\n');
132
+ break;
133
+ case 'NO_TESTS_TO_RUN':
134
+ reporter.log('No test to run.\n');
135
+ break;
136
+ case 'MISSING_APP_KEY':
137
+ reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_APP_KEY')} in your environment.\n`);
138
+ break;
139
+ case 'MISSING_API_KEY':
140
+ reporter.error(`Missing ${chalk_1.default.red.bold('DATADOG_API_KEY')} in your environment.\n`);
141
+ break;
142
+ case 'POLL_RESULTS_FAILED':
143
+ reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to poll test results ')}\n${error.message}\n\n`);
144
+ break;
145
+ case 'TUNNEL_START_FAILED':
146
+ reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to start tunnel')}\n${error.message}\n\n`);
147
+ break;
148
+ case 'TRIGGER_TESTS_FAILED':
149
+ reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to trigger tests')}\n${error.message}\n\n`);
150
+ break;
151
+ case 'UNAVAILABLE_TEST_CONFIG':
152
+ reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to obtain test configurations with search query ')}\n${error.message}\n\n`);
153
+ break;
154
+ case 'UNAVAILABLE_TUNNEL_CONFIG':
155
+ reporter.error(`\n${chalk_1.default.bgRed.bold(' ERROR: unable to get tunnel configuration')}\n${error.message}\n\n`);
156
+ }
157
+ }
158
+ resolveConfig() {
159
+ var _a, _b;
160
+ return __awaiter(this, void 0, void 0, function* () {
161
+ // Default < file < ENV < CLI
162
+ // Override with file config variables
163
+ try {
164
+ this.config = yield utils_1.parseConfigFile(this.config, (_a = this.configPath) !== null && _a !== void 0 ? _a : this.config.configPath);
165
+ }
166
+ catch (error) {
167
+ if (this.configPath) {
168
+ throw error;
169
+ }
170
+ }
171
+ // Override with ENV variables
172
+ this.config = deep_extend_1.default(this.config, utils_1.removeUndefinedValues({
173
+ apiKey: process.env.DATADOG_API_KEY,
174
+ appKey: process.env.DATADOG_APP_KEY,
175
+ datadogSite: process.env.DATADOG_SITE,
176
+ locations: (_b = process.env.DATADOG_SYNTHETICS_LOCATIONS) === null || _b === void 0 ? void 0 : _b.split(';'),
177
+ subdomain: process.env.DATADOG_SUBDOMAIN,
178
+ }));
179
+ // Override with CLI parameters
180
+ this.config = deep_extend_1.default(this.config, utils_1.removeUndefinedValues({
181
+ apiKey: this.apiKey,
182
+ appKey: this.appKey,
183
+ configPath: this.configPath,
184
+ datadogSite: this.datadogSite,
185
+ failOnCriticalErrors: this.failOnCriticalErrors,
186
+ failOnTimeout: this.failOnTimeout,
187
+ files: this.files,
188
+ publicIds: this.publicIds,
189
+ subdomain: this.subdomain,
190
+ testSearchQuery: this.testSearchQuery,
191
+ tunnel: this.tunnel,
192
+ }));
193
+ if (typeof this.config.files === 'string') {
194
+ this.reporter.log('[DEPRECATED] "files" should be an array of string instead of a string.\n');
195
+ this.config.files = [this.config.files];
196
+ }
197
+ });
198
+ }
199
+ sortTestsByOutcome(results) {
200
+ return (t1, t2) => {
201
+ var _a, _b;
202
+ const success1 = utils_2.hasTestSucceeded(results[t1.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
203
+ const success2 = utils_2.hasTestSucceeded(results[t2.public_id], this.config.failOnCriticalErrors, this.config.failOnTimeout);
204
+ const isNonBlockingTest1 = ((_a = t1.options.ci) === null || _a === void 0 ? void 0 : _a.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
205
+ const isNonBlockingTest2 = ((_b = t2.options.ci) === null || _b === void 0 ? void 0 : _b.executionRule) === interfaces_1.ExecutionRule.NON_BLOCKING;
206
+ if (success1 === success2) {
207
+ if (isNonBlockingTest1 === isNonBlockingTest2) {
208
+ return 0;
209
+ }
210
+ return isNonBlockingTest1 ? -1 : 1;
211
+ }
212
+ return success1 ? -1 : 1;
213
+ };
214
+ }
215
+ }
216
+ exports.RunTestCommand = RunTestCommand;
217
+ RunTestCommand.addPath('synthetics', 'run-tests');
218
+ RunTestCommand.addOption('apiKey', clipanion_1.Command.String('--apiKey'));
219
+ RunTestCommand.addOption('appKey', clipanion_1.Command.String('--appKey'));
220
+ RunTestCommand.addOption('failOnCriticalErrors', clipanion_1.Command.Boolean('--failOnCriticalErrors'));
221
+ RunTestCommand.addOption('configPath', clipanion_1.Command.String('--config'));
222
+ RunTestCommand.addOption('datadogSite', clipanion_1.Command.String('--datadogSite'));
223
+ RunTestCommand.addOption('files', clipanion_1.Command.Array('-f,--files'));
224
+ RunTestCommand.addOption('failOnTimeout', clipanion_1.Command.Boolean('--failOnTimeout'));
225
+ RunTestCommand.addOption('publicIds', clipanion_1.Command.Array('-p,--public-id'));
226
+ RunTestCommand.addOption('testSearchQuery', clipanion_1.Command.String('-s,--search'));
227
+ RunTestCommand.addOption('subdomain', clipanion_1.Command.Boolean('--subdomain'));
228
+ RunTestCommand.addOption('tunnel', clipanion_1.Command.Boolean('-t,--tunnel'));
229
+ RunTestCommand.addOption('runName', clipanion_1.Command.String('-n,--runName'));
@@ -1 +1,5 @@
1
- export {};
1
+ export { CiError } from './errors';
2
+ export * from './interfaces';
3
+ export { DefaultReporter } from './reporters/default';
4
+ export { executeTests } from './run-test';
5
+ export * as utils from './utils';
@@ -1,4 +1,33 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
+ };
17
+ var __importStar = (this && this.__importStar) || function (mod) {
18
+ if (mod && mod.__esModule) return mod;
19
+ var result = {};
20
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
21
+ __setModuleDefault(result, mod);
22
+ return result;
23
+ };
2
24
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const cli_1 = require("./cli");
4
- module.exports = [cli_1.RunTestCommand];
25
+ exports.utils = exports.executeTests = exports.DefaultReporter = exports.CiError = void 0;
26
+ var errors_1 = require("./errors");
27
+ Object.defineProperty(exports, "CiError", { enumerable: true, get: function () { return errors_1.CiError; } });
28
+ __exportStar(require("./interfaces"), exports);
29
+ var default_1 = require("./reporters/default");
30
+ Object.defineProperty(exports, "DefaultReporter", { enumerable: true, get: function () { return default_1.DefaultReporter; } });
31
+ var run_test_1 = require("./run-test");
32
+ Object.defineProperty(exports, "executeTests", { enumerable: true, get: function () { return run_test_1.executeTests; } });
33
+ exports.utils = __importStar(require("./utils"));
@@ -292,9 +292,9 @@ export interface Suite {
292
292
  export interface Summary {
293
293
  criticalErrors: number;
294
294
  failed: number;
295
- notFound: number;
296
295
  passed: number;
297
296
  skipped: number;
297
+ testsNotFound: Set<string>;
298
298
  timedOut: number;
299
299
  }
300
300
  export interface TestSearchResult {
@@ -1,12 +1,12 @@
1
1
  import { BaseContext } from 'clipanion';
2
- import { ConfigOverride, ExecutionRule, LocationsMapping, PollResult, Reporter, Summary, Test } from '../interfaces';
3
- export declare class DefaultReporter implements Reporter {
2
+ import { ConfigOverride, ExecutionRule, LocationsMapping, MainReporter, PollResult, Summary, Test } from '../interfaces';
3
+ export declare class DefaultReporter implements MainReporter {
4
4
  private write;
5
5
  constructor({ context }: {
6
6
  context: BaseContext;
7
7
  });
8
8
  error(error: string): void;
9
- initError(errors: string[]): void;
9
+ initErrors(errors: string[]): void;
10
10
  log(log: string): void;
11
11
  reportStart(timings: {
12
12
  startTime: number;
@@ -190,7 +190,7 @@ class DefaultReporter {
190
190
  error(error) {
191
191
  this.write(error);
192
192
  }
193
- initError(errors) {
193
+ initErrors(errors) {
194
194
  this.write(errors.join('\n'));
195
195
  }
196
196
  log(log) {
@@ -208,8 +208,9 @@ class DefaultReporter {
208
208
  if (summary.skipped) {
209
209
  summaries.push(`${chalk_1.default.bold(summary.skipped)} skipped`);
210
210
  }
211
- if (summary.notFound) {
212
- summaries.push(chalk_1.default.yellow(`${chalk_1.default.bold(summary.notFound)} not found`));
211
+ if (summary.testsNotFound.size > 0) {
212
+ const testsNotFoundStr = chalk_1.default.gray(`(${[...summary.testsNotFound].join(', ')})`);
213
+ summaries.push(`${chalk_1.default.yellow(`${chalk_1.default.bold(summary.testsNotFound.size)} not found`)} ${testsNotFoundStr}`);
213
214
  }
214
215
  const extraInfo = [];
215
216
  if (summary.timedOut) {
@@ -12,6 +12,7 @@ export declare const waitForResults: (api: APIHelper, triggerResponses: TriggerR
12
12
  [key: string]: PollResult[];
13
13
  }>;
14
14
  export declare const createTriggerResultMap: (triggerResponses: TriggerResponse[], defaultTimeout: number, triggerConfigs: TriggerConfig[]) => Map<string, TriggerResult>;
15
+ export declare const createSummary: () => Summary;
15
16
  export declare const getResultDuration: (result: Result) => number;
16
17
  export declare const getReporter: (reporters: Reporter[]) => MainReporter;
17
18
  export declare const getTestsToTrigger: (api: APIHelper, triggerConfigs: TriggerConfig[], reporter: MainReporter) => Promise<{
@@ -21,6 +22,3 @@ export declare const getTestsToTrigger: (api: APIHelper, triggerConfigs: Trigger
21
22
  }>;
22
23
  export declare const runTests: (api: APIHelper, testsToTrigger: TestPayload[]) => Promise<Trigger>;
23
24
  export declare const retry: <T, E extends Error>(func: () => Promise<T>, shouldRetryAfterWait: (retries: number, error: E) => number | undefined) => Promise<T>;
24
- export declare const removeUndefinedValues: <T extends {
25
- [key: string]: any;
26
- }>(object: T) => T;
@@ -31,7 +31,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
31
31
  return (mod && mod.__esModule) ? mod : { "default": mod };
32
32
  };
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
- exports.removeUndefinedValues = exports.retry = exports.runTests = exports.getTestsToTrigger = exports.getReporter = exports.getResultDuration = exports.createTriggerResultMap = exports.waitForResults = exports.wait = exports.getSuites = exports.hasTestSucceeded = exports.hasResultPassed = exports.isCriticalError = exports.getStrictestExecutionRule = exports.getExecutionRule = exports.handleConfig = void 0;
34
+ exports.retry = exports.runTests = exports.getTestsToTrigger = exports.getReporter = exports.getResultDuration = exports.createSummary = exports.createTriggerResultMap = exports.waitForResults = exports.wait = exports.getSuites = exports.hasTestSucceeded = exports.hasResultPassed = exports.isCriticalError = exports.getStrictestExecutionRule = exports.getExecutionRule = exports.handleConfig = void 0;
35
35
  const fs = __importStar(require("fs"));
36
36
  const path = __importStar(require("path"));
37
37
  const url_1 = require("url");
@@ -284,12 +284,21 @@ const createFailingResult = (errorMessage, resultId, deviceId, dcId, tunnel) =>
284
284
  resultID: resultId,
285
285
  timestamp: 0,
286
286
  });
287
+ const createSummary = () => ({
288
+ criticalErrors: 0,
289
+ failed: 0,
290
+ passed: 0,
291
+ skipped: 0,
292
+ testsNotFound: new Set(),
293
+ timedOut: 0,
294
+ });
295
+ exports.createSummary = createSummary;
287
296
  const getResultDuration = (result) => {
288
297
  if ('duration' in result) {
289
- return result.duration;
298
+ return Math.round(result.duration);
290
299
  }
291
300
  if ('timings' in result) {
292
- return result.timings.total;
301
+ return Math.round(result.timings.total);
293
302
  }
294
303
  return 0;
295
304
  };
@@ -356,7 +365,7 @@ exports.getReporter = getReporter;
356
365
  const getTestsToTrigger = (api, triggerConfigs, reporter) => __awaiter(void 0, void 0, void 0, function* () {
357
366
  const overriddenTestsToTrigger = [];
358
367
  const errorMessages = [];
359
- const summary = { criticalErrors: 0, failed: 0, notFound: 0, passed: 0, skipped: 0, timedOut: 0 };
368
+ const summary = exports.createSummary();
360
369
  const tests = yield Promise.all(triggerConfigs.map(({ config, id, suite }) => __awaiter(void 0, void 0, void 0, function* () {
361
370
  let test;
362
371
  id = PUBLIC_ID_REGEX.test(id) ? id : id.substr(id.lastIndexOf('/') + 1);
@@ -367,7 +376,7 @@ const getTestsToTrigger = (api, triggerConfigs, reporter) => __awaiter(void 0, v
367
376
  if (api_1.is5xxError(e)) {
368
377
  throw e;
369
378
  }
370
- summary.notFound++;
379
+ summary.testsNotFound.add(id);
371
380
  const errorMessage = api_1.formatBackendErrors(e);
372
381
  errorMessages.push(`[${chalk_1.default.bold.dim(id)}] ${chalk_1.default.yellow.bold('Test not found')}: ${errorMessage}\n`);
373
382
  return;
@@ -426,13 +435,3 @@ const retry = (func, shouldRetryAfterWait) => __awaiter(void 0, void 0, void 0,
426
435
  return trier();
427
436
  });
428
437
  exports.retry = retry;
429
- const removeUndefinedValues = (object) => {
430
- const newObject = Object.assign({}, object);
431
- for (const [key, value] of Object.entries(newObject)) {
432
- if (value === undefined) {
433
- delete newObject[key];
434
- }
435
- }
436
- return newObject;
437
- };
438
- exports.removeUndefinedValues = removeUndefinedValues;
@@ -0,0 +1 @@
1
+ export {};
File without changes