@datadog/datadog-ci 0.17.9 → 0.17.13
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.
- package/LICENSE-3rdparty.csv +2 -0
- package/README.md +9 -2
- package/dist/{commands/dependencies/index.d.ts → cli.d.ts} +0 -0
- package/dist/cli.js +34 -0
- package/dist/commands/{dsyms/index.d.ts → dependencies/cli.d.ts} +0 -0
- package/dist/commands/dependencies/{index.js → cli.js} +0 -0
- package/dist/commands/dependencies/upload.d.ts +1 -1
- package/dist/commands/{git-metadata/index.d.ts → dsyms/cli.d.ts} +0 -0
- package/dist/commands/dsyms/{index.js → cli.js} +0 -0
- package/dist/commands/dsyms/upload.d.ts +1 -1
- package/dist/commands/{junit/index.d.ts → git-metadata/cli.d.ts} +0 -0
- package/dist/commands/git-metadata/{index.js → cli.js} +0 -0
- package/dist/commands/git-metadata/upload.d.ts +1 -1
- package/dist/commands/git-metadata/upload.js +6 -1
- package/dist/commands/{lambda/index.d.ts → junit/cli.d.ts} +0 -0
- package/dist/commands/junit/{index.js → cli.js} +0 -0
- package/dist/commands/junit/upload.d.ts +1 -1
- package/dist/commands/junit/upload.js +1 -1
- package/dist/commands/lambda/__tests__/fixtures.d.ts +5 -1
- package/dist/commands/lambda/__tests__/fixtures.js +13 -2
- package/dist/commands/lambda/__tests__/functions/commons.test.js +400 -0
- package/dist/commands/lambda/__tests__/functions/instrument.test.js +229 -117
- package/dist/commands/lambda/__tests__/functions/uninstrument.test.js +80 -7
- package/dist/commands/lambda/__tests__/instrument.test.js +542 -111
- package/dist/commands/{sourcemaps/index.d.ts → lambda/__tests__/prompt.test.d.ts} +0 -0
- package/dist/commands/lambda/__tests__/prompt.test.js +216 -0
- package/dist/commands/lambda/__tests__/uninstrument.test.js +381 -17
- package/dist/commands/{trace/index.d.ts → lambda/cli.d.ts} +0 -0
- package/dist/commands/lambda/{index.js → cli.js} +0 -0
- package/dist/commands/lambda/constants.d.ts +27 -6
- package/dist/commands/lambda/constants.js +63 -6
- package/dist/commands/lambda/functions/commons.d.ts +49 -4
- package/dist/commands/lambda/functions/commons.js +198 -7
- package/dist/commands/lambda/functions/instrument.d.ts +5 -14
- package/dist/commands/lambda/functions/instrument.js +63 -80
- package/dist/commands/lambda/functions/uninstrument.d.ts +3 -2
- package/dist/commands/lambda/functions/uninstrument.js +23 -11
- package/dist/commands/lambda/instrument.d.ts +2 -1
- package/dist/commands/lambda/instrument.js +112 -58
- package/dist/commands/lambda/interfaces.d.ts +4 -1
- package/dist/commands/lambda/loggroup.js +3 -1
- package/dist/commands/lambda/prompt.d.ts +9 -0
- package/dist/commands/lambda/prompt.js +187 -0
- package/dist/commands/lambda/uninstrument.d.ts +2 -0
- package/dist/commands/lambda/uninstrument.js +107 -30
- package/dist/commands/sourcemaps/cli.d.ts +1 -0
- package/dist/commands/sourcemaps/{index.js → cli.js} +0 -0
- package/dist/commands/sourcemaps/upload.d.ts +1 -1
- package/dist/commands/synthetics/__tests__/cli.test.js +36 -13
- package/dist/commands/synthetics/__tests__/fixtures.js +1 -0
- package/dist/commands/synthetics/__tests__/run-test.test.js +48 -2
- package/dist/commands/synthetics/__tests__/utils.test.js +11 -4
- package/dist/commands/synthetics/__tests__/websocket.test.js +3 -3
- package/dist/commands/synthetics/cli.d.ts +1 -26
- package/dist/commands/synthetics/cli.js +2 -227
- package/dist/commands/synthetics/command.d.ts +27 -0
- package/dist/commands/synthetics/command.js +236 -0
- package/dist/commands/synthetics/index.d.ts +5 -1
- package/dist/commands/synthetics/index.js +31 -2
- package/dist/commands/synthetics/interfaces.d.ts +8 -3
- package/dist/commands/synthetics/interfaces.js +7 -3
- package/dist/commands/synthetics/reporters/default.js +5 -1
- package/dist/commands/synthetics/run-test.js +3 -1
- package/dist/commands/synthetics/utils.d.ts +3 -3
- package/dist/commands/synthetics/utils.js +17 -8
- package/dist/commands/trace/api.js +1 -1
- package/dist/commands/trace/cli.d.ts +1 -0
- package/dist/commands/trace/{index.js → cli.js} +0 -0
- package/dist/commands/trace/trace.d.ts +1 -1
- package/dist/helpers/__tests__/ci.test.js +97 -136
- package/dist/helpers/__tests__/user-provided-git.test.js +81 -27
- package/dist/helpers/__tests__/utils.test.js +4 -0
- package/dist/helpers/ci.js +54 -95
- package/dist/helpers/interfaces.d.ts +28 -2
- package/dist/helpers/user-provided-git.d.ts +2 -1
- package/dist/helpers/user-provided-git.js +29 -5
- package/dist/helpers/utils.d.ts +4 -0
- package/dist/helpers/utils.js +18 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +23 -31
- package/package.json +10 -8
|
@@ -14,51 +14,130 @@ const aws_sdk_1 = require("aws-sdk");
|
|
|
14
14
|
const chalk_1 = require("chalk");
|
|
15
15
|
const clipanion_1 = require("clipanion");
|
|
16
16
|
const utils_1 = require("../../helpers/utils");
|
|
17
|
+
const constants_1 = require("./constants");
|
|
17
18
|
const commons_1 = require("./functions/commons");
|
|
18
19
|
const uninstrument_1 = require("./functions/uninstrument");
|
|
20
|
+
const prompt_1 = require("./prompt");
|
|
19
21
|
class UninstrumentCommand extends clipanion_1.Command {
|
|
20
22
|
constructor() {
|
|
21
23
|
super(...arguments);
|
|
22
24
|
this.config = {
|
|
23
25
|
functions: [],
|
|
24
|
-
region: process.env.
|
|
26
|
+
region: process.env[constants_1.AWS_DEFAULT_REGION_ENV_VAR],
|
|
25
27
|
};
|
|
26
28
|
this.dryRun = false;
|
|
27
29
|
this.functions = [];
|
|
30
|
+
this.interactive = false;
|
|
28
31
|
}
|
|
29
32
|
execute() {
|
|
33
|
+
var _a, _b, _c;
|
|
30
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
31
35
|
const lambdaConfig = { lambda: this.config };
|
|
32
36
|
this.config = (yield utils_1.parseConfigFile(lambdaConfig, this.configPath)).lambda;
|
|
33
|
-
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
let hasSpecifiedFunctions = this.functions.length !== 0 || this.config.functions.length !== 0;
|
|
38
|
+
if (this.interactive) {
|
|
39
|
+
try {
|
|
40
|
+
if (commons_1.isMissingAWSCredentials()) {
|
|
41
|
+
this.context.stdout.write(`${chalk_1.bold(chalk_1.yellow('[!]'))} No existing AWS credentials found, let's set them up!\n`);
|
|
42
|
+
yield prompt_1.requestAWSCredentials();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
this.context.stdout.write(`${chalk_1.red('[Error]')} ${e}\n`);
|
|
47
|
+
return 1;
|
|
48
|
+
}
|
|
49
|
+
const region = (_b = (_a = this.region) !== null && _a !== void 0 ? _a : this.config.region) !== null && _b !== void 0 ? _b : process.env[constants_1.AWS_DEFAULT_REGION_ENV_VAR];
|
|
50
|
+
this.region = region;
|
|
51
|
+
if (!hasSpecifiedFunctions) {
|
|
52
|
+
try {
|
|
53
|
+
const lambda = new aws_sdk_1.Lambda({ region });
|
|
54
|
+
this.context.stdout.write('Fetching Lambda functions, this might take a while.\n');
|
|
55
|
+
const functionNames = (_c = (yield commons_1.getAllLambdaFunctionConfigs(lambda)).map((config) => config.FunctionName).sort()) !== null && _c !== void 0 ? _c : [];
|
|
56
|
+
if (functionNames.length === 0) {
|
|
57
|
+
this.context.stdout.write(`${chalk_1.red('[Error]')} Couldn't find any Lambda functions in the specified region.\n`);
|
|
58
|
+
return 1;
|
|
59
|
+
}
|
|
60
|
+
const functions = yield prompt_1.requestFunctionSelection(functionNames);
|
|
61
|
+
this.functions = functions;
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
this.context.stdout.write(`${chalk_1.red('[Error]')} Couldn't fetch Lambda functions. ${err}\n`);
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
37
68
|
}
|
|
38
|
-
|
|
39
|
-
|
|
69
|
+
hasSpecifiedFunctions = this.functions.length !== 0 || this.config.functions.length !== 0;
|
|
70
|
+
const hasSpecifiedRegExPattern = this.regExPattern !== undefined && this.regExPattern !== '';
|
|
71
|
+
if (!hasSpecifiedFunctions && !hasSpecifiedRegExPattern) {
|
|
72
|
+
this.context.stdout.write(`${chalk_1.red('[Error]')} No functions specified for un-instrumentation.\n`);
|
|
40
73
|
return 1;
|
|
41
74
|
}
|
|
42
75
|
const configGroups = [];
|
|
43
76
|
// Fetch lambda function configurations that are
|
|
44
77
|
// available to be un-instrumented.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
78
|
+
if (hasSpecifiedRegExPattern) {
|
|
79
|
+
if (hasSpecifiedFunctions) {
|
|
80
|
+
const usedCommand = this.functions.length !== 0 ? '"--functions"' : 'Functions in config file';
|
|
81
|
+
this.context.stdout.write(`${chalk_1.red('[Error]')} ${usedCommand} and "--functions-regex" should not be used at the same time.\n`);
|
|
82
|
+
return 1;
|
|
83
|
+
}
|
|
84
|
+
if (this.regExPattern.match(':')) {
|
|
85
|
+
this.context.stdout.write(`${chalk_1.red('[Error]')} "--functions-regex" isn't meant to be used with ARNs.\n`);
|
|
86
|
+
return 1;
|
|
87
|
+
}
|
|
88
|
+
const region = this.region || this.config.region;
|
|
89
|
+
if (!region) {
|
|
90
|
+
this.context.stdout.write(`${chalk_1.red('[Error]')} No default region specified. Use \`-r\`, \`--region\`.`);
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
48
93
|
try {
|
|
49
|
-
const
|
|
94
|
+
const cloudWatchLogs = new aws_sdk_1.CloudWatchLogs({ region });
|
|
95
|
+
const lambda = new aws_sdk_1.Lambda({ region });
|
|
96
|
+
this.context.stdout.write('Fetching Lambda functions, this might take a while.\n');
|
|
97
|
+
const configs = yield uninstrument_1.getUninstrumentedFunctionConfigsFromRegEx(lambda, cloudWatchLogs, this.regExPattern, this.forwarder);
|
|
50
98
|
configGroups.push({ configs, lambda, cloudWatchLogs });
|
|
51
99
|
}
|
|
52
100
|
catch (err) {
|
|
53
|
-
this.context.stdout.write(`${chalk_1.red('[Error]')} Couldn't fetch
|
|
101
|
+
this.context.stdout.write(`${chalk_1.red('[Error]')} Couldn't fetch Lambda functions. ${err}\n`);
|
|
102
|
+
return 1;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
let functionGroups;
|
|
107
|
+
try {
|
|
108
|
+
functionGroups = commons_1.collectFunctionsByRegion(this.functions.length !== 0 ? this.functions : this.config.functions, this.region || this.config.region);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
this.context.stdout.write(`${chalk_1.red('[Error]')} Couldn't group functions. ${err}`);
|
|
54
112
|
return 1;
|
|
55
113
|
}
|
|
114
|
+
for (const [region, functionARNs] of Object.entries(functionGroups)) {
|
|
115
|
+
const lambda = new aws_sdk_1.Lambda({ region });
|
|
116
|
+
const cloudWatchLogs = new aws_sdk_1.CloudWatchLogs({ region });
|
|
117
|
+
try {
|
|
118
|
+
const configs = yield uninstrument_1.getUninstrumentedFunctionConfigs(lambda, cloudWatchLogs, functionARNs, this.forwarder);
|
|
119
|
+
configGroups.push({ configs, lambda, cloudWatchLogs });
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
this.context.stdout.write(`${chalk_1.red('[Error]')} Couldn't fetch Lambda functions. ${err}\n`);
|
|
123
|
+
return 1;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
56
126
|
}
|
|
57
127
|
const configList = configGroups.map((group) => group.configs).reduce((a, b) => a.concat(b));
|
|
58
128
|
this.printPlannedActions(configList);
|
|
59
129
|
if (this.dryRun || configList.length === 0) {
|
|
60
130
|
return 0;
|
|
61
131
|
}
|
|
132
|
+
const willUpdate = commons_1.willUpdateFunctionConfigs(configList);
|
|
133
|
+
if (this.interactive && willUpdate) {
|
|
134
|
+
this.context.stdout.write(`${chalk_1.yellow('[!]')} Confirmation needed.\n`);
|
|
135
|
+
const isConfirmed = yield prompt_1.requestChangesConfirmation('Do you want to apply the changes?');
|
|
136
|
+
if (!isConfirmed) {
|
|
137
|
+
return 0;
|
|
138
|
+
}
|
|
139
|
+
this.context.stdout.write(`${chalk_1.yellow('[!]')} Uninstrumenting functions.\n`);
|
|
140
|
+
}
|
|
62
141
|
// Un-instrument functions.
|
|
63
142
|
const promises = Object.values(configGroups).map((group) => {
|
|
64
143
|
commons_1.updateLambdaFunctionConfigs(group.lambda, group.cloudWatchLogs, group.configs);
|
|
@@ -74,22 +153,17 @@ class UninstrumentCommand extends clipanion_1.Command {
|
|
|
74
153
|
});
|
|
75
154
|
}
|
|
76
155
|
printPlannedActions(configs) {
|
|
77
|
-
var _a;
|
|
78
156
|
const prefix = this.dryRun ? chalk_1.bold(chalk_1.cyan('[Dry Run] ')) : '';
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (config.updateRequest !== undefined ||
|
|
82
|
-
((_a = config.logGroupConfiguration) === null || _a === void 0 ? void 0 : _a.deleteSubscriptionFilterRequest) !== undefined ||
|
|
83
|
-
(config === null || config === void 0 ? void 0 : config.tagConfiguration) !== undefined) {
|
|
84
|
-
anyUpdates = true;
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
if (!anyUpdates) {
|
|
157
|
+
const willUpdate = commons_1.willUpdateFunctionConfigs(configs);
|
|
158
|
+
if (!willUpdate) {
|
|
89
159
|
this.context.stdout.write(`${prefix}No updates will be applied\n`);
|
|
90
160
|
return;
|
|
91
161
|
}
|
|
92
|
-
this.context.stdout.write(
|
|
162
|
+
this.context.stdout.write(`\n${chalk_1.bold(chalk_1.yellow('[!]'))} Functions to be updated:\n`);
|
|
163
|
+
for (const config of configs) {
|
|
164
|
+
this.context.stdout.write(`\t- ${chalk_1.bold(config.functionARN)}\n`);
|
|
165
|
+
}
|
|
166
|
+
this.context.stdout.write(`\n${prefix}Will apply the following updates:\n`);
|
|
93
167
|
for (const config of configs) {
|
|
94
168
|
if (config.updateRequest) {
|
|
95
169
|
this.context.stdout.write(`UpdateFunctionConfiguration -> ${config.functionARN}\n${JSON.stringify(config.updateRequest, undefined, 2)}\n`);
|
|
@@ -111,17 +185,20 @@ UninstrumentCommand.addOption('region', clipanion_1.Command.String('-r,--region'
|
|
|
111
185
|
UninstrumentCommand.addOption('configPath', clipanion_1.Command.String('--config'));
|
|
112
186
|
UninstrumentCommand.addOption('dryRun', clipanion_1.Command.Boolean('-d,--dry'));
|
|
113
187
|
UninstrumentCommand.addOption('forwarder', clipanion_1.Command.String('--forwarder'));
|
|
188
|
+
UninstrumentCommand.addOption('regExPattern', clipanion_1.Command.String('--functions-regex,--functionsRegex'));
|
|
189
|
+
UninstrumentCommand.addOption('interactive', clipanion_1.Command.Boolean('-i,--interactive'));
|
|
114
190
|
/**
|
|
115
191
|
* Commands that are not really in use, but to
|
|
116
192
|
* make uninstrumentation easier for the user.
|
|
117
193
|
*/
|
|
118
|
-
UninstrumentCommand.addOption('extensionVersion', clipanion_1.Command.String('-e,--extensionVersion', { hidden: true }));
|
|
119
|
-
UninstrumentCommand.addOption('layerVersion', clipanion_1.Command.String('-v,--layerVersion', { hidden: true }));
|
|
194
|
+
UninstrumentCommand.addOption('extensionVersion', clipanion_1.Command.String('-e,--extension-version,--extensionVersion', { hidden: true }));
|
|
195
|
+
UninstrumentCommand.addOption('layerVersion', clipanion_1.Command.String('-v,--layer-version,--layerVersion', { hidden: true }));
|
|
120
196
|
UninstrumentCommand.addOption('tracing', clipanion_1.Command.String('--tracing', { hidden: true }));
|
|
121
|
-
UninstrumentCommand.addOption('mergeXrayTraces', clipanion_1.Command.String('--mergeXrayTraces', { hidden: true }));
|
|
122
|
-
UninstrumentCommand.addOption('flushMetricsToLogs', clipanion_1.Command.String('--flushMetricsToLogs', { hidden: true }));
|
|
123
|
-
UninstrumentCommand.addOption('logLevel', clipanion_1.Command.String('--logLevel', { hidden: true }));
|
|
197
|
+
UninstrumentCommand.addOption('mergeXrayTraces', clipanion_1.Command.String('--merge-xray-traces,--mergeXrayTraces', { hidden: true }));
|
|
198
|
+
UninstrumentCommand.addOption('flushMetricsToLogs', clipanion_1.Command.String('--flush-metrics-to-logs,--flushMetricsToLogs', { hidden: true }));
|
|
199
|
+
UninstrumentCommand.addOption('logLevel', clipanion_1.Command.String('--log-level,--logLevel', { hidden: true }));
|
|
124
200
|
UninstrumentCommand.addOption('service', clipanion_1.Command.String('--service', { hidden: true }));
|
|
125
201
|
UninstrumentCommand.addOption('environment', clipanion_1.Command.String('--env', { hidden: true }));
|
|
126
202
|
UninstrumentCommand.addOption('version', clipanion_1.Command.String('--version', { hidden: true }));
|
|
127
|
-
UninstrumentCommand.addOption('extraTags', clipanion_1.Command.String('--extra-tags', { hidden: true }));
|
|
203
|
+
UninstrumentCommand.addOption('extraTags', clipanion_1.Command.String('--extra-tags,--extraTags', { hidden: true }));
|
|
204
|
+
UninstrumentCommand.addOption('captureLambdaPayload', clipanion_1.Command.String('--capture-lambda-payload,--captureLambdaPayload', { hidden: true }));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
File without changes
|
|
@@ -28,12 +28,34 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
28
28
|
});
|
|
29
29
|
};
|
|
30
30
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
const advanced_1 = require("clipanion/lib/advanced");
|
|
31
32
|
const ciUtils = __importStar(require("../../../helpers/utils"));
|
|
32
|
-
const
|
|
33
|
+
const command_1 = require("../command");
|
|
33
34
|
const interfaces_1 = require("../interfaces");
|
|
34
35
|
const runTests = __importStar(require("../run-test"));
|
|
35
36
|
const utils = __importStar(require("../utils"));
|
|
36
37
|
const fixtures_1 = require("./fixtures");
|
|
38
|
+
test('all option flags are supported', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
const options = [
|
|
40
|
+
'apiKey',
|
|
41
|
+
'appKey',
|
|
42
|
+
'failOnCriticalErrors',
|
|
43
|
+
'config',
|
|
44
|
+
'datadogSite',
|
|
45
|
+
'files',
|
|
46
|
+
'failOnTimeout',
|
|
47
|
+
'public-id',
|
|
48
|
+
'search',
|
|
49
|
+
'subdomain',
|
|
50
|
+
'tunnel',
|
|
51
|
+
'jUnitReport',
|
|
52
|
+
'runName',
|
|
53
|
+
];
|
|
54
|
+
const cli = new advanced_1.Cli();
|
|
55
|
+
cli.register(command_1.RunTestCommand);
|
|
56
|
+
const usage = cli.usage(command_1.RunTestCommand);
|
|
57
|
+
options.forEach((option) => expect(usage).toContain(`--${option}`));
|
|
58
|
+
}));
|
|
37
59
|
describe('run-test', () => {
|
|
38
60
|
beforeEach(() => {
|
|
39
61
|
jest.restoreAllMocks();
|
|
@@ -46,12 +68,12 @@ describe('run-test', () => {
|
|
|
46
68
|
});
|
|
47
69
|
test('should default to datadog us', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
70
|
process.env = {};
|
|
49
|
-
const command = new
|
|
71
|
+
const command = new command_1.RunTestCommand();
|
|
50
72
|
expect(command['getAppBaseURL']()).toBe('https://app.datadoghq.com/');
|
|
51
73
|
}));
|
|
52
74
|
test('subdomain should be overridable', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
75
|
process.env = { DATADOG_SUBDOMAIN: 'custom' };
|
|
54
|
-
const command = new
|
|
76
|
+
const command = new command_1.RunTestCommand();
|
|
55
77
|
yield command['resolveConfig']();
|
|
56
78
|
expect(command['getAppBaseURL']()).toBe('https://custom.datadoghq.com/');
|
|
57
79
|
}));
|
|
@@ -60,7 +82,7 @@ describe('run-test', () => {
|
|
|
60
82
|
DATADOG_SITE: 'datadoghq.eu',
|
|
61
83
|
DATADOG_SUBDOMAIN: 'custom',
|
|
62
84
|
};
|
|
63
|
-
const command = new
|
|
85
|
+
const command = new command_1.RunTestCommand();
|
|
64
86
|
yield command['resolveConfig']();
|
|
65
87
|
expect(command['getAppBaseURL']()).toBe('https://custom.datadoghq.eu/');
|
|
66
88
|
}));
|
|
@@ -83,7 +105,7 @@ describe('run-test', () => {
|
|
|
83
105
|
test5: [{ result: { passed: false } }],
|
|
84
106
|
};
|
|
85
107
|
test('should sort tests with success, non_blocking failures then failures', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
-
const command = new
|
|
108
|
+
const command = new command_1.RunTestCommand();
|
|
87
109
|
tests.sort(command['sortTestsByOutcome'](results));
|
|
88
110
|
expect(tests).toStrictEqual([test3, test1, test2, test5, test4]);
|
|
89
111
|
}));
|
|
@@ -102,9 +124,9 @@ describe('run-test', () => {
|
|
|
102
124
|
DATADOG_SUBDOMAIN: 'custom',
|
|
103
125
|
};
|
|
104
126
|
process.env = overrideEnv;
|
|
105
|
-
const command = new
|
|
127
|
+
const command = new command_1.RunTestCommand();
|
|
106
128
|
yield command['resolveConfig']();
|
|
107
|
-
expect(command['config']).toEqual(Object.assign(Object.assign({},
|
|
129
|
+
expect(command['config']).toEqual(Object.assign(Object.assign({}, command_1.DEFAULT_COMMAND_CONFIG), { apiKey: overrideEnv.DATADOG_API_KEY, appKey: overrideEnv.DATADOG_APP_KEY, datadogSite: overrideEnv.DATADOG_SITE, subdomain: overrideEnv.DATADOG_SUBDOMAIN }));
|
|
108
130
|
}));
|
|
109
131
|
test('override from config file', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
110
132
|
const overrideConfigFile = {
|
|
@@ -122,9 +144,10 @@ describe('run-test', () => {
|
|
|
122
144
|
publicIds: ['ran-dom-id'],
|
|
123
145
|
subdomain: 'ppa',
|
|
124
146
|
tunnel: true,
|
|
147
|
+
variableStrings: [],
|
|
125
148
|
};
|
|
126
149
|
jest.spyOn(ciUtils, 'getConfig').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return overrideConfigFile; }));
|
|
127
|
-
const command = new
|
|
150
|
+
const command = new command_1.RunTestCommand();
|
|
128
151
|
yield command['resolveConfig']();
|
|
129
152
|
expect(command['config']).toEqual(overrideConfigFile);
|
|
130
153
|
}));
|
|
@@ -142,7 +165,7 @@ describe('run-test', () => {
|
|
|
142
165
|
testSearchQuery: 'a-search-query',
|
|
143
166
|
tunnel: true,
|
|
144
167
|
};
|
|
145
|
-
const command = new
|
|
168
|
+
const command = new command_1.RunTestCommand();
|
|
146
169
|
command['apiKey'] = overrideCLI.apiKey;
|
|
147
170
|
command['appKey'] = overrideCLI.appKey;
|
|
148
171
|
command['configPath'] = overrideCLI.configPath;
|
|
@@ -155,7 +178,7 @@ describe('run-test', () => {
|
|
|
155
178
|
command['tunnel'] = overrideCLI.tunnel;
|
|
156
179
|
command['testSearchQuery'] = overrideCLI.testSearchQuery;
|
|
157
180
|
yield command['resolveConfig']();
|
|
158
|
-
expect(command['config']).toEqual(Object.assign(Object.assign({},
|
|
181
|
+
expect(command['config']).toEqual(Object.assign(Object.assign({}, command_1.DEFAULT_COMMAND_CONFIG), { apiKey: 'fake_api_key', appKey: 'fake_app_key', configPath: 'fake-datadog-ci.json', datadogSite: 'datadoghq.eu', failOnCriticalErrors: true, failOnTimeout: false, files: ['new-file'], publicIds: ['ran-dom-id'], subdomain: 'new-sub-domain', testSearchQuery: 'a-search-query', tunnel: true }));
|
|
159
182
|
}));
|
|
160
183
|
test('override from config file < ENV < CLI', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
161
184
|
jest.spyOn(ciUtils, 'getConfig').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -169,10 +192,10 @@ describe('run-test', () => {
|
|
|
169
192
|
DATADOG_API_KEY: 'api_key_env',
|
|
170
193
|
DATADOG_APP_KEY: 'app_key_env',
|
|
171
194
|
};
|
|
172
|
-
const command = new
|
|
195
|
+
const command = new command_1.RunTestCommand();
|
|
173
196
|
command['apiKey'] = 'api_key_cli';
|
|
174
197
|
yield command['resolveConfig']();
|
|
175
|
-
expect(command['config']).toEqual(Object.assign(Object.assign({},
|
|
198
|
+
expect(command['config']).toEqual(Object.assign(Object.assign({}, command_1.DEFAULT_COMMAND_CONFIG), { apiKey: 'api_key_cli', appKey: 'app_key_env', datadogSite: 'datadog.config.file' }));
|
|
176
199
|
}));
|
|
177
200
|
test('override locations with ENV variable', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
178
201
|
const conf = {
|
|
@@ -193,7 +216,7 @@ describe('run-test', () => {
|
|
|
193
216
|
triggerTests,
|
|
194
217
|
};
|
|
195
218
|
const write = jest.fn();
|
|
196
|
-
const command = new
|
|
219
|
+
const command = new command_1.RunTestCommand();
|
|
197
220
|
command.context = { stdout: { write } };
|
|
198
221
|
command['config'].global = { locations: ['aws:us-east-2'] };
|
|
199
222
|
jest.spyOn(runTests, 'getApiHelper').mockImplementation(() => apiHelper);
|
|
@@ -32,6 +32,7 @@ const ciUtils = __importStar(require("../../../helpers/utils"));
|
|
|
32
32
|
const errors_1 = require("../errors");
|
|
33
33
|
const interfaces_1 = require("../interfaces");
|
|
34
34
|
const runTests = __importStar(require("../run-test"));
|
|
35
|
+
const tunnel_1 = require("../tunnel");
|
|
35
36
|
const utils = __importStar(require("../utils"));
|
|
36
37
|
const fixtures_1 = require("./fixtures");
|
|
37
38
|
describe('run-test', () => {
|
|
@@ -95,6 +96,39 @@ describe('run-test', () => {
|
|
|
95
96
|
]), expect.anything());
|
|
96
97
|
expect(apiHelper.getPresignedURL).not.toHaveBeenCalled();
|
|
97
98
|
}));
|
|
99
|
+
test('open and close tunnel for successful runs', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
100
|
+
const location = {
|
|
101
|
+
display_name: 'us1',
|
|
102
|
+
id: 1,
|
|
103
|
+
is_active: true,
|
|
104
|
+
name: 'us1',
|
|
105
|
+
region: 'us1',
|
|
106
|
+
};
|
|
107
|
+
jest.spyOn(utils, 'wait').mockImplementation(() => new Promise((res) => setTimeout(res, 10)));
|
|
108
|
+
const startTunnelSpy = jest
|
|
109
|
+
.spyOn(tunnel_1.Tunnel.prototype, 'start')
|
|
110
|
+
.mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return ({ host: 'host', id: 'id', privateKey: 'key' }); }));
|
|
111
|
+
const stopTunnelSpy = jest.spyOn(tunnel_1.Tunnel.prototype, 'stop');
|
|
112
|
+
jest.spyOn(utils, 'getTestsToTrigger').mockReturnValue(Promise.resolve({
|
|
113
|
+
overriddenTestsToTrigger: [],
|
|
114
|
+
summary: utils.createSummary(),
|
|
115
|
+
tests: [{ options: { ci: { executionRule: interfaces_1.ExecutionRule.BLOCKING } }, public_id: '123-456-789' }],
|
|
116
|
+
}));
|
|
117
|
+
jest.spyOn(utils, 'runTests').mockReturnValue(Promise.resolve({
|
|
118
|
+
locations: [location],
|
|
119
|
+
results: [{ device: 'chrome_laptop.large', location: 1, public_id: '123-456-789', result_id: '1' }],
|
|
120
|
+
triggered_check_ids: [],
|
|
121
|
+
}));
|
|
122
|
+
const apiHelper = {
|
|
123
|
+
getPresignedURL: () => ({ url: 'url' }),
|
|
124
|
+
pollResults: () => fixtures_1.mockPollResultResponse,
|
|
125
|
+
triggerTests: () => fixtures_1.mockTestTriggerResponse,
|
|
126
|
+
};
|
|
127
|
+
jest.spyOn(runTests, 'getApiHelper').mockImplementation(() => apiHelper);
|
|
128
|
+
yield runTests.executeTests(fixtures_1.mockReporter, Object.assign(Object.assign({}, fixtures_1.ciConfig), { failOnCriticalErrors: true, publicIds: ['123-456-789'], tunnel: true }));
|
|
129
|
+
expect(startTunnelSpy).toHaveBeenCalledTimes(1);
|
|
130
|
+
expect(stopTunnelSpy).toHaveBeenCalledTimes(1);
|
|
131
|
+
}));
|
|
98
132
|
test('getTestsList throws', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
99
133
|
const serverError = new Error('Server Error');
|
|
100
134
|
serverError.response = { data: { errors: ['Bad Gateway'] }, status: 502 };
|
|
@@ -137,6 +171,10 @@ describe('run-test', () => {
|
|
|
137
171
|
yield expect(runTests.executeTests(fixtures_1.mockReporter, Object.assign(Object.assign({}, fixtures_1.ciConfig), { publicIds: ['public-id-1', 'public-id-2'], tunnel: true }))).rejects.toMatchError(new errors_1.CriticalError('UNAVAILABLE_TUNNEL_CONFIG'));
|
|
138
172
|
}));
|
|
139
173
|
test('runTests throws', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
174
|
+
jest
|
|
175
|
+
.spyOn(tunnel_1.Tunnel.prototype, 'start')
|
|
176
|
+
.mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return ({ host: 'host', id: 'id', privateKey: 'key' }); }));
|
|
177
|
+
const stopTunnelSpy = jest.spyOn(tunnel_1.Tunnel.prototype, 'stop');
|
|
140
178
|
jest.spyOn(utils, 'getTestsToTrigger').mockReturnValue(Promise.resolve({
|
|
141
179
|
overriddenTestsToTrigger: [],
|
|
142
180
|
summary: utils.createSummary(),
|
|
@@ -146,12 +184,14 @@ describe('run-test', () => {
|
|
|
146
184
|
serverError.response = { data: { errors: ['Bad Gateway'] }, status: 502 };
|
|
147
185
|
serverError.config = { baseURL: 'baseURL', url: 'url' };
|
|
148
186
|
const apiHelper = {
|
|
187
|
+
getPresignedURL: () => ({ url: 'url' }),
|
|
149
188
|
triggerTests: jest.fn(() => {
|
|
150
189
|
throw serverError;
|
|
151
190
|
}),
|
|
152
191
|
};
|
|
153
192
|
jest.spyOn(runTests, 'getApiHelper').mockImplementation(() => apiHelper);
|
|
154
|
-
yield expect(runTests.executeTests(fixtures_1.mockReporter, Object.assign(Object.assign({}, fixtures_1.ciConfig), { publicIds: ['public-id-1', 'public-id-2'] }))).rejects.toMatchError(new errors_1.CriticalError('TRIGGER_TESTS_FAILED'));
|
|
193
|
+
yield expect(runTests.executeTests(fixtures_1.mockReporter, Object.assign(Object.assign({}, fixtures_1.ciConfig), { publicIds: ['public-id-1', 'public-id-2'], tunnel: true }))).rejects.toMatchError(new errors_1.CriticalError('TRIGGER_TESTS_FAILED'));
|
|
194
|
+
expect(stopTunnelSpy).toHaveBeenCalledTimes(1);
|
|
155
195
|
}));
|
|
156
196
|
test('waitForResults throws', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
157
197
|
const location = {
|
|
@@ -161,6 +201,10 @@ describe('run-test', () => {
|
|
|
161
201
|
name: 'us1',
|
|
162
202
|
region: 'us1',
|
|
163
203
|
};
|
|
204
|
+
jest
|
|
205
|
+
.spyOn(tunnel_1.Tunnel.prototype, 'start')
|
|
206
|
+
.mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return ({ host: 'host', id: 'id', privateKey: 'key' }); }));
|
|
207
|
+
const stopTunnelSpy = jest.spyOn(tunnel_1.Tunnel.prototype, 'stop');
|
|
164
208
|
jest.spyOn(utils, 'getTestsToTrigger').mockReturnValue(Promise.resolve({
|
|
165
209
|
overriddenTestsToTrigger: [],
|
|
166
210
|
summary: utils.createSummary(),
|
|
@@ -175,12 +219,14 @@ describe('run-test', () => {
|
|
|
175
219
|
serverError.response = { data: { errors: ['Bad Gateway'] }, status: 502 };
|
|
176
220
|
serverError.config = { baseURL: 'baseURL', url: 'url' };
|
|
177
221
|
const apiHelper = {
|
|
222
|
+
getPresignedURL: () => ({ url: 'url' }),
|
|
178
223
|
pollResults: jest.fn(() => {
|
|
179
224
|
throw serverError;
|
|
180
225
|
}),
|
|
181
226
|
};
|
|
182
227
|
jest.spyOn(runTests, 'getApiHelper').mockImplementation(() => apiHelper);
|
|
183
|
-
yield expect(runTests.executeTests(fixtures_1.mockReporter, Object.assign(Object.assign({}, fixtures_1.ciConfig), { failOnCriticalErrors: true, publicIds: ['public-id-1', 'public-id-2'] }))).rejects.toMatchError(new errors_1.CriticalError('POLL_RESULTS_FAILED'));
|
|
228
|
+
yield expect(runTests.executeTests(fixtures_1.mockReporter, Object.assign(Object.assign({}, fixtures_1.ciConfig), { failOnCriticalErrors: true, publicIds: ['public-id-1', 'public-id-2'], tunnel: true }))).rejects.toMatchError(new errors_1.CriticalError('POLL_RESULTS_FAILED'));
|
|
229
|
+
expect(stopTunnelSpy).toHaveBeenCalledTimes(1);
|
|
184
230
|
}));
|
|
185
231
|
});
|
|
186
232
|
describe('getDatadogHost', () => {
|
|
@@ -367,10 +367,6 @@ describe('utils', () => {
|
|
|
367
367
|
expect(utils.hasResultPassed(result, false, true)).toBeTruthy();
|
|
368
368
|
expect(utils.hasResultPassed(result, true, true)).toBeFalsy();
|
|
369
369
|
});
|
|
370
|
-
test('removeUndefinedValues', () => {
|
|
371
|
-
// tslint:disable-next-line: no-null-keyword
|
|
372
|
-
expect(utils.removeUndefinedValues({ a: 'b', c: 'd', e: undefined, g: null })).toEqual({ a: 'b', c: 'd', g: null });
|
|
373
|
-
});
|
|
374
370
|
test('hasTestSucceeded', () => {
|
|
375
371
|
const testConfiguration = fixtures_1.getApiTest('abc-def-ghi');
|
|
376
372
|
const passingResult = fixtures_1.getBrowserResult();
|
|
@@ -629,4 +625,15 @@ describe('utils', () => {
|
|
|
629
625
|
expect(counter).toBe(3);
|
|
630
626
|
}));
|
|
631
627
|
});
|
|
628
|
+
test('parseVariablesFromCli', () => {
|
|
629
|
+
const mockLogFunction = (message) => undefined;
|
|
630
|
+
expect(utils.parseVariablesFromCli(['TEST=42'], mockLogFunction)).toEqual({ TEST: '42' });
|
|
631
|
+
expect(utils.parseVariablesFromCli(['TEST=42 with some spaces'], mockLogFunction)).toEqual({
|
|
632
|
+
TEST: '42 with some spaces',
|
|
633
|
+
});
|
|
634
|
+
expect(utils.parseVariablesFromCli(['TEST=42=43=44'], mockLogFunction)).toEqual({ TEST: '42=43=44' });
|
|
635
|
+
expect(utils.parseVariablesFromCli(['TEST='], mockLogFunction)).toEqual({ TEST: '' });
|
|
636
|
+
expect(utils.parseVariablesFromCli([''], mockLogFunction)).toBeUndefined();
|
|
637
|
+
expect(utils.parseVariablesFromCli(undefined, mockLogFunction)).toBeUndefined();
|
|
638
|
+
});
|
|
632
639
|
});
|
|
@@ -30,7 +30,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
30
30
|
};
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
32
|
const ciUtils = __importStar(require("../../../helpers/utils"));
|
|
33
|
-
const
|
|
33
|
+
const command_1 = require("../command");
|
|
34
34
|
const interfaces_1 = require("../interfaces");
|
|
35
35
|
const runTests = __importStar(require("../run-test"));
|
|
36
36
|
const fixtures_1 = require("./fixtures");
|
|
@@ -62,7 +62,7 @@ describe('Proxy configuration', () => {
|
|
|
62
62
|
tunnel: true,
|
|
63
63
|
});
|
|
64
64
|
}));
|
|
65
|
-
const command = new
|
|
65
|
+
const command = new command_1.RunTestCommand();
|
|
66
66
|
command.context = { stdout: { write: jest.fn() } };
|
|
67
67
|
jest.spyOn(runTests, 'getDatadogHost').mockImplementation(() => 'http://datadoghq.com/');
|
|
68
68
|
yield command.execute();
|
|
@@ -95,7 +95,7 @@ describe('Proxy configuration', () => {
|
|
|
95
95
|
tunnel: true,
|
|
96
96
|
});
|
|
97
97
|
}));
|
|
98
|
-
const command = new
|
|
98
|
+
const command = new command_1.RunTestCommand();
|
|
99
99
|
command.context = { stdout: { write: jest.fn() } };
|
|
100
100
|
jest.spyOn(runTests, 'getDatadogHost').mockImplementation(() => 'http://datadoghq.com/');
|
|
101
101
|
yield command.execute();
|
|
@@ -1,26 +1 @@
|
|
|
1
|
-
|
|
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
|
-
}
|
|
1
|
+
export {};
|