azure-pipelines-task-lib 3.2.0 → 4.0.0-preview
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 +22 -22
- package/README.md +74 -74
- package/Strings/resources.resjson/{de-de → de-DE}/resources.resjson +34 -34
- package/Strings/resources.resjson/{es-es → es-ES}/resources.resjson +34 -34
- package/Strings/resources.resjson/{fr-fr → fr-FR}/resources.resjson +34 -34
- package/Strings/resources.resjson/{ja-jp → ja-JP}/resources.resjson +34 -34
- package/ThirdPartyNotice.txt +1114 -1114
- package/internal.d.ts +130 -130
- package/internal.js +885 -885
- package/lib.json +37 -37
- package/mock-answer.d.ts +55 -55
- package/mock-answer.js +41 -41
- package/mock-run.d.ts +44 -44
- package/mock-run.js +92 -92
- package/mock-task.d.ts +111 -111
- package/mock-task.js +447 -438
- package/mock-test.d.ts +28 -28
- package/mock-test.js +298 -298
- package/mock-toolrunner.d.ts +41 -41
- package/mock-toolrunner.js +268 -268
- package/package.json +49 -49
- package/task.d.ts +718 -667
- package/task.js +2003 -1915
- package/taskcommand.d.ts +10 -10
- package/taskcommand.js +103 -103
- package/toolrunner.d.ts +159 -159
- package/toolrunner.js +967 -967
- package/vault.d.ts +10 -10
- package/vault.js +71 -71
package/mock-test.d.ts
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
export declare class MockTestRunner {
|
|
2
|
-
constructor(testPath: string, taskJsonPath?: string);
|
|
3
|
-
private _testPath;
|
|
4
|
-
private _taskJsonPath;
|
|
5
|
-
nodePath: string;
|
|
6
|
-
stdout: string;
|
|
7
|
-
stderr: string;
|
|
8
|
-
cmdlines: {};
|
|
9
|
-
invokedToolCount: number;
|
|
10
|
-
succeeded: boolean;
|
|
11
|
-
errorIssues: string[];
|
|
12
|
-
warningIssues: string[];
|
|
13
|
-
get failed(): boolean;
|
|
14
|
-
ran(cmdline: string): boolean;
|
|
15
|
-
createdErrorIssue(message: string): boolean;
|
|
16
|
-
createdWarningIssue(message: string): boolean;
|
|
17
|
-
stdOutContained(message: string): boolean;
|
|
18
|
-
stdErrContained(message: string): boolean;
|
|
19
|
-
run(nodeVersion?: number): void;
|
|
20
|
-
private getNodePath;
|
|
21
|
-
private getNodeVersion;
|
|
22
|
-
private getTaskJsonPath;
|
|
23
|
-
private downloadNode;
|
|
24
|
-
private downloadFile;
|
|
25
|
-
private downloadTarGz;
|
|
26
|
-
private getPathToNodeExe;
|
|
27
|
-
private getPlatform;
|
|
28
|
-
}
|
|
1
|
+
export declare class MockTestRunner {
|
|
2
|
+
constructor(testPath: string, taskJsonPath?: string);
|
|
3
|
+
private _testPath;
|
|
4
|
+
private _taskJsonPath;
|
|
5
|
+
nodePath: string;
|
|
6
|
+
stdout: string;
|
|
7
|
+
stderr: string;
|
|
8
|
+
cmdlines: {};
|
|
9
|
+
invokedToolCount: number;
|
|
10
|
+
succeeded: boolean;
|
|
11
|
+
errorIssues: string[];
|
|
12
|
+
warningIssues: string[];
|
|
13
|
+
get failed(): boolean;
|
|
14
|
+
ran(cmdline: string): boolean;
|
|
15
|
+
createdErrorIssue(message: string): boolean;
|
|
16
|
+
createdWarningIssue(message: string): boolean;
|
|
17
|
+
stdOutContained(message: string): boolean;
|
|
18
|
+
stdErrContained(message: string): boolean;
|
|
19
|
+
run(nodeVersion?: number): void;
|
|
20
|
+
private getNodePath;
|
|
21
|
+
private getNodeVersion;
|
|
22
|
+
private getTaskJsonPath;
|
|
23
|
+
private downloadNode;
|
|
24
|
+
private downloadFile;
|
|
25
|
+
private downloadTarGz;
|
|
26
|
+
private getPathToNodeExe;
|
|
27
|
+
private getPlatform;
|
|
28
|
+
}
|
package/mock-test.js
CHANGED
|
@@ -1,298 +1,298 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MockTestRunner = void 0;
|
|
4
|
-
var cp = require("child_process");
|
|
5
|
-
var fs = require("fs");
|
|
6
|
-
var ncp = require("child_process");
|
|
7
|
-
var os = require("os");
|
|
8
|
-
var path = require("path");
|
|
9
|
-
var cmdm = require("./taskcommand");
|
|
10
|
-
var shelljs = require("shelljs");
|
|
11
|
-
var sync_request_1 = require("sync-request");
|
|
12
|
-
var COMMAND_TAG = '[command]';
|
|
13
|
-
var COMMAND_LENGTH = COMMAND_TAG.length;
|
|
14
|
-
var downloadDirectory = path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, 'azure-pipelines-task-lib', '_download');
|
|
15
|
-
var MockTestRunner = /** @class */ (function () {
|
|
16
|
-
function MockTestRunner(testPath, taskJsonPath) {
|
|
17
|
-
this._testPath = '';
|
|
18
|
-
this._taskJsonPath = '';
|
|
19
|
-
this.nodePath = '';
|
|
20
|
-
this.stdout = '';
|
|
21
|
-
this.stderr = '';
|
|
22
|
-
this.cmdlines = {};
|
|
23
|
-
this.invokedToolCount = 0;
|
|
24
|
-
this.succeeded = false;
|
|
25
|
-
this.errorIssues = [];
|
|
26
|
-
this.warningIssues = [];
|
|
27
|
-
this._taskJsonPath = taskJsonPath || '';
|
|
28
|
-
this._testPath = testPath;
|
|
29
|
-
this.nodePath = this.getNodePath();
|
|
30
|
-
}
|
|
31
|
-
Object.defineProperty(MockTestRunner.prototype, "failed", {
|
|
32
|
-
get: function () {
|
|
33
|
-
return !this.succeeded;
|
|
34
|
-
},
|
|
35
|
-
enumerable: false,
|
|
36
|
-
configurable: true
|
|
37
|
-
});
|
|
38
|
-
MockTestRunner.prototype.ran = function (cmdline) {
|
|
39
|
-
return this.cmdlines.hasOwnProperty(cmdline.trim());
|
|
40
|
-
};
|
|
41
|
-
MockTestRunner.prototype.createdErrorIssue = function (message) {
|
|
42
|
-
return this.errorIssues.indexOf(message.trim()) >= 0;
|
|
43
|
-
};
|
|
44
|
-
MockTestRunner.prototype.createdWarningIssue = function (message) {
|
|
45
|
-
return this.warningIssues.indexOf(message.trim()) >= 0;
|
|
46
|
-
};
|
|
47
|
-
MockTestRunner.prototype.stdOutContained = function (message) {
|
|
48
|
-
return this.stdout.indexOf(message) > 0;
|
|
49
|
-
};
|
|
50
|
-
MockTestRunner.prototype.stdErrContained = function (message) {
|
|
51
|
-
return this.stderr.indexOf(message) > 0;
|
|
52
|
-
};
|
|
53
|
-
MockTestRunner.prototype.run = function (nodeVersion) {
|
|
54
|
-
var _this = this;
|
|
55
|
-
this.cmdlines = {};
|
|
56
|
-
this.invokedToolCount = 0;
|
|
57
|
-
this.succeeded = true;
|
|
58
|
-
this.errorIssues = [];
|
|
59
|
-
this.warningIssues = [];
|
|
60
|
-
var nodePath = this.nodePath;
|
|
61
|
-
if (nodeVersion) {
|
|
62
|
-
nodePath = this.getNodePath(nodeVersion);
|
|
63
|
-
}
|
|
64
|
-
var spawn = cp.spawnSync(nodePath, [this._testPath]);
|
|
65
|
-
// Clean environment
|
|
66
|
-
Object.keys(process.env)
|
|
67
|
-
.filter(function (key) { return (key.substr(0, 'INPUT_'.length) === 'INPUT_' ||
|
|
68
|
-
key.substr(0, 'SECRET_'.length) === 'SECRET_' ||
|
|
69
|
-
key.substr(0, 'VSTS_TASKVARIABLE_'.length) === 'VSTS_TASKVARIABLE_'); })
|
|
70
|
-
.forEach(function (key) { return delete process.env[key]; });
|
|
71
|
-
if (spawn.error) {
|
|
72
|
-
console.error('Running test failed');
|
|
73
|
-
console.error(spawn.error.message);
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
this.stdout = spawn.stdout.toString();
|
|
77
|
-
this.stderr = spawn.stderr.toString();
|
|
78
|
-
if (process.env['TASK_TEST_TRACE']) {
|
|
79
|
-
console.log('');
|
|
80
|
-
}
|
|
81
|
-
var lines = this.stdout.replace(/\r\n/g, '\n').split('\n');
|
|
82
|
-
var traceFile = this._testPath + '.log';
|
|
83
|
-
lines.forEach(function (line) {
|
|
84
|
-
var ci = line.indexOf('##vso[');
|
|
85
|
-
var cmd;
|
|
86
|
-
var cmi = line.indexOf(COMMAND_TAG);
|
|
87
|
-
if (ci >= 0) {
|
|
88
|
-
cmd = cmdm.commandFromString(line.substring(ci));
|
|
89
|
-
if (cmd.command === 'task.complete' && cmd.properties['result'] === 'Failed') {
|
|
90
|
-
_this.succeeded = false;
|
|
91
|
-
}
|
|
92
|
-
if (cmd.command === 'task.issue' && cmd.properties['type'] === 'error') {
|
|
93
|
-
_this.errorIssues.push(cmd.message.trim());
|
|
94
|
-
}
|
|
95
|
-
if (cmd.command === 'task.issue' && cmd.properties['type'] === 'warning') {
|
|
96
|
-
_this.warningIssues.push(cmd.message.trim());
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
else if (cmi == 0 && line.length > COMMAND_LENGTH) {
|
|
100
|
-
var cmdline = line.substr(COMMAND_LENGTH).trim();
|
|
101
|
-
_this.cmdlines[cmdline] = true;
|
|
102
|
-
_this.invokedToolCount++;
|
|
103
|
-
}
|
|
104
|
-
if (process.env['TASK_TEST_TRACE']) {
|
|
105
|
-
fs.appendFileSync(traceFile, line + os.EOL);
|
|
106
|
-
if (line && !cmd) {
|
|
107
|
-
console.log(line);
|
|
108
|
-
}
|
|
109
|
-
// don't print task.debug commands to console - too noisy.
|
|
110
|
-
// otherwise omit command details - can interfere during CI.
|
|
111
|
-
else if (cmd && cmd.command != 'task.debug') {
|
|
112
|
-
console.log(cmd.command + " details omitted");
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
if (this.stderr && process.env['TASK_TEST_TRACE']) {
|
|
117
|
-
console.log('STDERR: ' + this.stderr);
|
|
118
|
-
fs.appendFileSync(traceFile, 'STDERR: ' + this.stderr + os.EOL);
|
|
119
|
-
}
|
|
120
|
-
if (process.env['TASK_TEST_TRACE']) {
|
|
121
|
-
console.log('TRACE FILE: ' + traceFile);
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
// Returns a path to node.exe with the correct version for this task (based on if its node10 or node)
|
|
125
|
-
MockTestRunner.prototype.getNodePath = function (nodeVersion) {
|
|
126
|
-
var version = nodeVersion || this.getNodeVersion();
|
|
127
|
-
var downloadVersion;
|
|
128
|
-
switch (version) {
|
|
129
|
-
case 5:
|
|
130
|
-
downloadVersion = 'v5.10.1';
|
|
131
|
-
break;
|
|
132
|
-
case 6:
|
|
133
|
-
downloadVersion = 'v6.17.1';
|
|
134
|
-
break;
|
|
135
|
-
case 10:
|
|
136
|
-
downloadVersion = 'v10.21.0';
|
|
137
|
-
break;
|
|
138
|
-
case 14:
|
|
139
|
-
downloadVersion = 'v14.11.0';
|
|
140
|
-
break;
|
|
141
|
-
default:
|
|
142
|
-
throw new Error('Invalid node version, must be 5, 6, 10, or 14 (received ' + version + ')');
|
|
143
|
-
}
|
|
144
|
-
// Install node in home directory if it isn't already there.
|
|
145
|
-
var downloadDestination = path.join(downloadDirectory, 'node' + version);
|
|
146
|
-
var pathToExe = this.getPathToNodeExe(downloadVersion, downloadDestination);
|
|
147
|
-
if (pathToExe) {
|
|
148
|
-
return pathToExe;
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
return this.downloadNode(downloadVersion, downloadDestination);
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
// Determines the correct version of node to use based on the contents of the task's task.json. Defaults to Node 14.
|
|
155
|
-
MockTestRunner.prototype.getNodeVersion = function () {
|
|
156
|
-
var taskJsonPath = this.getTaskJsonPath();
|
|
157
|
-
if (!taskJsonPath) {
|
|
158
|
-
console.warn('Unable to find task.json, defaulting to use Node 14');
|
|
159
|
-
return 10;
|
|
160
|
-
}
|
|
161
|
-
var taskJsonContents = fs.readFileSync(taskJsonPath, { encoding: 'utf-8' });
|
|
162
|
-
var taskJson = JSON.parse(taskJsonContents);
|
|
163
|
-
var nodeVersionFound = false;
|
|
164
|
-
var execution = (taskJson['execution']
|
|
165
|
-
|| taskJson['prejobexecution']
|
|
166
|
-
|| taskJson['postjobexecution']);
|
|
167
|
-
var keys = Object.keys(execution);
|
|
168
|
-
for (var i = 0; i < keys.length; i++) {
|
|
169
|
-
if (keys[i].toLowerCase() == 'node14') {
|
|
170
|
-
// Prefer node 14 and return immediately.
|
|
171
|
-
return 14;
|
|
172
|
-
}
|
|
173
|
-
else if (keys[i].toLowerCase() == 'node10') {
|
|
174
|
-
// Prefer node 10 and return immediately.
|
|
175
|
-
return 10;
|
|
176
|
-
}
|
|
177
|
-
else if (keys[i].toLowerCase() == 'node') {
|
|
178
|
-
nodeVersionFound = true;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
if (!nodeVersionFound) {
|
|
182
|
-
console.warn('Unable to determine execution type from task.json, defaulting to use Node 10');
|
|
183
|
-
return 10;
|
|
184
|
-
}
|
|
185
|
-
return 6;
|
|
186
|
-
};
|
|
187
|
-
// Returns the path to the task.json for the task being tested. Returns null if unable to find it.
|
|
188
|
-
// Searches by moving up the directory structure from the initial starting point and checking at each level.
|
|
189
|
-
MockTestRunner.prototype.getTaskJsonPath = function () {
|
|
190
|
-
if (this._taskJsonPath) {
|
|
191
|
-
return this._taskJsonPath;
|
|
192
|
-
}
|
|
193
|
-
var curPath = this._testPath;
|
|
194
|
-
var newPath = path.join(this._testPath, '..');
|
|
195
|
-
while (curPath != newPath) {
|
|
196
|
-
curPath = newPath;
|
|
197
|
-
var taskJsonPath = path.join(curPath, 'task.json');
|
|
198
|
-
if (fs.existsSync(taskJsonPath)) {
|
|
199
|
-
return taskJsonPath;
|
|
200
|
-
}
|
|
201
|
-
newPath = path.join(curPath, '..');
|
|
202
|
-
}
|
|
203
|
-
return '';
|
|
204
|
-
};
|
|
205
|
-
// Downloads the specified node version to the download destination. Returns a path to node.exe
|
|
206
|
-
MockTestRunner.prototype.downloadNode = function (nodeVersion, downloadDestination) {
|
|
207
|
-
shelljs.rm('-rf', downloadDestination);
|
|
208
|
-
var nodeUrl = process.env['TASK_NODE_URL'] || 'https://nodejs.org/dist';
|
|
209
|
-
nodeUrl = nodeUrl.replace(/\/$/, ''); // ensure there is no trailing slash on the base URL
|
|
210
|
-
var downloadPath = '';
|
|
211
|
-
switch (this.getPlatform()) {
|
|
212
|
-
case 'darwin':
|
|
213
|
-
this.downloadTarGz(nodeUrl + '/' + nodeVersion + '/node-' + nodeVersion + '-darwin-x64.tar.gz', downloadDestination);
|
|
214
|
-
downloadPath = path.join(downloadDestination, 'node-' + nodeVersion + '-darwin-x64', 'bin', 'node');
|
|
215
|
-
break;
|
|
216
|
-
case 'linux':
|
|
217
|
-
this.downloadTarGz(nodeUrl + '/' + nodeVersion + '/node-' + nodeVersion + '-linux-x64.tar.gz', downloadDestination);
|
|
218
|
-
downloadPath = path.join(downloadDestination, 'node-' + nodeVersion + '-linux-x64', 'bin', 'node');
|
|
219
|
-
break;
|
|
220
|
-
case 'win32':
|
|
221
|
-
this.downloadFile(nodeUrl + '/' + nodeVersion + '/win-x64/node.exe', downloadDestination, 'node.exe');
|
|
222
|
-
this.downloadFile(nodeUrl + '/' + nodeVersion + '/win-x64/node.lib', downloadDestination, 'node.lib');
|
|
223
|
-
downloadPath = path.join(downloadDestination, 'node.exe');
|
|
224
|
-
}
|
|
225
|
-
// Write marker to indicate download completed.
|
|
226
|
-
var marker = downloadDestination + '.completed';
|
|
227
|
-
fs.writeFileSync(marker, '');
|
|
228
|
-
return downloadPath;
|
|
229
|
-
};
|
|
230
|
-
// Downloads file to the downloadDestination, making any necessary folders along the way.
|
|
231
|
-
MockTestRunner.prototype.downloadFile = function (url, downloadDestination, fileName) {
|
|
232
|
-
var filePath = path.join(downloadDestination, fileName);
|
|
233
|
-
if (!url) {
|
|
234
|
-
throw new Error('Parameter "url" must be set.');
|
|
235
|
-
}
|
|
236
|
-
if (!downloadDestination) {
|
|
237
|
-
throw new Error('Parameter "downloadDestination" must be set.');
|
|
238
|
-
}
|
|
239
|
-
console.log('Downloading file:', url);
|
|
240
|
-
shelljs.mkdir('-p', downloadDestination);
|
|
241
|
-
var result = sync_request_1.default('GET', url);
|
|
242
|
-
fs.writeFileSync(filePath, result.getBody());
|
|
243
|
-
};
|
|
244
|
-
// Downloads tarGz to the download destination, making any necessary folders along the way.
|
|
245
|
-
MockTestRunner.prototype.downloadTarGz = function (url, downloadDestination) {
|
|
246
|
-
if (!url) {
|
|
247
|
-
throw new Error('Parameter "url" must be set.');
|
|
248
|
-
}
|
|
249
|
-
if (!downloadDestination) {
|
|
250
|
-
throw new Error('Parameter "downloadDestination" must be set.');
|
|
251
|
-
}
|
|
252
|
-
var tarGzName = 'node.tar.gz';
|
|
253
|
-
this.downloadFile(url, downloadDestination, tarGzName);
|
|
254
|
-
// Extract file
|
|
255
|
-
var originalCwd = process.cwd();
|
|
256
|
-
process.chdir(downloadDestination);
|
|
257
|
-
try {
|
|
258
|
-
ncp.execSync("tar -xzf \"" + path.join(downloadDestination, tarGzName) + "\"");
|
|
259
|
-
}
|
|
260
|
-
catch (_a) {
|
|
261
|
-
throw new Error('Failed to unzip node tar.gz from ' + url);
|
|
262
|
-
}
|
|
263
|
-
finally {
|
|
264
|
-
process.chdir(originalCwd);
|
|
265
|
-
}
|
|
266
|
-
};
|
|
267
|
-
// Checks if node is installed at downloadDestination. If it is, returns a path to node.exe, otherwise returns null.
|
|
268
|
-
MockTestRunner.prototype.getPathToNodeExe = function (nodeVersion, downloadDestination) {
|
|
269
|
-
var exePath = '';
|
|
270
|
-
switch (this.getPlatform()) {
|
|
271
|
-
case 'darwin':
|
|
272
|
-
exePath = path.join(downloadDestination, 'node-' + nodeVersion + '-darwin-x64', 'bin', 'node');
|
|
273
|
-
break;
|
|
274
|
-
case 'linux':
|
|
275
|
-
exePath = path.join(downloadDestination, 'node-' + nodeVersion + '-linux-x64', 'bin', 'node');
|
|
276
|
-
break;
|
|
277
|
-
case 'win32':
|
|
278
|
-
exePath = path.join(downloadDestination, 'node.exe');
|
|
279
|
-
}
|
|
280
|
-
// Only use path if marker is found indicating download completed successfully (and not partially)
|
|
281
|
-
var marker = downloadDestination + '.completed';
|
|
282
|
-
if (fs.existsSync(exePath) && fs.existsSync(marker)) {
|
|
283
|
-
return exePath;
|
|
284
|
-
}
|
|
285
|
-
else {
|
|
286
|
-
return '';
|
|
287
|
-
}
|
|
288
|
-
};
|
|
289
|
-
MockTestRunner.prototype.getPlatform = function () {
|
|
290
|
-
var platform = os.platform();
|
|
291
|
-
if (platform != 'darwin' && platform != 'linux' && platform != 'win32') {
|
|
292
|
-
throw new Error('Unexpected platform: ' + platform);
|
|
293
|
-
}
|
|
294
|
-
return platform;
|
|
295
|
-
};
|
|
296
|
-
return MockTestRunner;
|
|
297
|
-
}());
|
|
298
|
-
exports.MockTestRunner = MockTestRunner;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MockTestRunner = void 0;
|
|
4
|
+
var cp = require("child_process");
|
|
5
|
+
var fs = require("fs");
|
|
6
|
+
var ncp = require("child_process");
|
|
7
|
+
var os = require("os");
|
|
8
|
+
var path = require("path");
|
|
9
|
+
var cmdm = require("./taskcommand");
|
|
10
|
+
var shelljs = require("shelljs");
|
|
11
|
+
var sync_request_1 = require("sync-request");
|
|
12
|
+
var COMMAND_TAG = '[command]';
|
|
13
|
+
var COMMAND_LENGTH = COMMAND_TAG.length;
|
|
14
|
+
var downloadDirectory = path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, 'azure-pipelines-task-lib', '_download');
|
|
15
|
+
var MockTestRunner = /** @class */ (function () {
|
|
16
|
+
function MockTestRunner(testPath, taskJsonPath) {
|
|
17
|
+
this._testPath = '';
|
|
18
|
+
this._taskJsonPath = '';
|
|
19
|
+
this.nodePath = '';
|
|
20
|
+
this.stdout = '';
|
|
21
|
+
this.stderr = '';
|
|
22
|
+
this.cmdlines = {};
|
|
23
|
+
this.invokedToolCount = 0;
|
|
24
|
+
this.succeeded = false;
|
|
25
|
+
this.errorIssues = [];
|
|
26
|
+
this.warningIssues = [];
|
|
27
|
+
this._taskJsonPath = taskJsonPath || '';
|
|
28
|
+
this._testPath = testPath;
|
|
29
|
+
this.nodePath = this.getNodePath();
|
|
30
|
+
}
|
|
31
|
+
Object.defineProperty(MockTestRunner.prototype, "failed", {
|
|
32
|
+
get: function () {
|
|
33
|
+
return !this.succeeded;
|
|
34
|
+
},
|
|
35
|
+
enumerable: false,
|
|
36
|
+
configurable: true
|
|
37
|
+
});
|
|
38
|
+
MockTestRunner.prototype.ran = function (cmdline) {
|
|
39
|
+
return this.cmdlines.hasOwnProperty(cmdline.trim());
|
|
40
|
+
};
|
|
41
|
+
MockTestRunner.prototype.createdErrorIssue = function (message) {
|
|
42
|
+
return this.errorIssues.indexOf(message.trim()) >= 0;
|
|
43
|
+
};
|
|
44
|
+
MockTestRunner.prototype.createdWarningIssue = function (message) {
|
|
45
|
+
return this.warningIssues.indexOf(message.trim()) >= 0;
|
|
46
|
+
};
|
|
47
|
+
MockTestRunner.prototype.stdOutContained = function (message) {
|
|
48
|
+
return this.stdout.indexOf(message) > 0;
|
|
49
|
+
};
|
|
50
|
+
MockTestRunner.prototype.stdErrContained = function (message) {
|
|
51
|
+
return this.stderr.indexOf(message) > 0;
|
|
52
|
+
};
|
|
53
|
+
MockTestRunner.prototype.run = function (nodeVersion) {
|
|
54
|
+
var _this = this;
|
|
55
|
+
this.cmdlines = {};
|
|
56
|
+
this.invokedToolCount = 0;
|
|
57
|
+
this.succeeded = true;
|
|
58
|
+
this.errorIssues = [];
|
|
59
|
+
this.warningIssues = [];
|
|
60
|
+
var nodePath = this.nodePath;
|
|
61
|
+
if (nodeVersion) {
|
|
62
|
+
nodePath = this.getNodePath(nodeVersion);
|
|
63
|
+
}
|
|
64
|
+
var spawn = cp.spawnSync(nodePath, [this._testPath]);
|
|
65
|
+
// Clean environment
|
|
66
|
+
Object.keys(process.env)
|
|
67
|
+
.filter(function (key) { return (key.substr(0, 'INPUT_'.length) === 'INPUT_' ||
|
|
68
|
+
key.substr(0, 'SECRET_'.length) === 'SECRET_' ||
|
|
69
|
+
key.substr(0, 'VSTS_TASKVARIABLE_'.length) === 'VSTS_TASKVARIABLE_'); })
|
|
70
|
+
.forEach(function (key) { return delete process.env[key]; });
|
|
71
|
+
if (spawn.error) {
|
|
72
|
+
console.error('Running test failed');
|
|
73
|
+
console.error(spawn.error.message);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this.stdout = spawn.stdout.toString();
|
|
77
|
+
this.stderr = spawn.stderr.toString();
|
|
78
|
+
if (process.env['TASK_TEST_TRACE']) {
|
|
79
|
+
console.log('');
|
|
80
|
+
}
|
|
81
|
+
var lines = this.stdout.replace(/\r\n/g, '\n').split('\n');
|
|
82
|
+
var traceFile = this._testPath + '.log';
|
|
83
|
+
lines.forEach(function (line) {
|
|
84
|
+
var ci = line.indexOf('##vso[');
|
|
85
|
+
var cmd;
|
|
86
|
+
var cmi = line.indexOf(COMMAND_TAG);
|
|
87
|
+
if (ci >= 0) {
|
|
88
|
+
cmd = cmdm.commandFromString(line.substring(ci));
|
|
89
|
+
if (cmd.command === 'task.complete' && cmd.properties['result'] === 'Failed') {
|
|
90
|
+
_this.succeeded = false;
|
|
91
|
+
}
|
|
92
|
+
if (cmd.command === 'task.issue' && cmd.properties['type'] === 'error') {
|
|
93
|
+
_this.errorIssues.push(cmd.message.trim());
|
|
94
|
+
}
|
|
95
|
+
if (cmd.command === 'task.issue' && cmd.properties['type'] === 'warning') {
|
|
96
|
+
_this.warningIssues.push(cmd.message.trim());
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (cmi == 0 && line.length > COMMAND_LENGTH) {
|
|
100
|
+
var cmdline = line.substr(COMMAND_LENGTH).trim();
|
|
101
|
+
_this.cmdlines[cmdline] = true;
|
|
102
|
+
_this.invokedToolCount++;
|
|
103
|
+
}
|
|
104
|
+
if (process.env['TASK_TEST_TRACE']) {
|
|
105
|
+
fs.appendFileSync(traceFile, line + os.EOL);
|
|
106
|
+
if (line && !cmd) {
|
|
107
|
+
console.log(line);
|
|
108
|
+
}
|
|
109
|
+
// don't print task.debug commands to console - too noisy.
|
|
110
|
+
// otherwise omit command details - can interfere during CI.
|
|
111
|
+
else if (cmd && cmd.command != 'task.debug') {
|
|
112
|
+
console.log(cmd.command + " details omitted");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
if (this.stderr && process.env['TASK_TEST_TRACE']) {
|
|
117
|
+
console.log('STDERR: ' + this.stderr);
|
|
118
|
+
fs.appendFileSync(traceFile, 'STDERR: ' + this.stderr + os.EOL);
|
|
119
|
+
}
|
|
120
|
+
if (process.env['TASK_TEST_TRACE']) {
|
|
121
|
+
console.log('TRACE FILE: ' + traceFile);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
// Returns a path to node.exe with the correct version for this task (based on if its node10 or node)
|
|
125
|
+
MockTestRunner.prototype.getNodePath = function (nodeVersion) {
|
|
126
|
+
var version = nodeVersion || this.getNodeVersion();
|
|
127
|
+
var downloadVersion;
|
|
128
|
+
switch (version) {
|
|
129
|
+
case 5:
|
|
130
|
+
downloadVersion = 'v5.10.1';
|
|
131
|
+
break;
|
|
132
|
+
case 6:
|
|
133
|
+
downloadVersion = 'v6.17.1';
|
|
134
|
+
break;
|
|
135
|
+
case 10:
|
|
136
|
+
downloadVersion = 'v10.21.0';
|
|
137
|
+
break;
|
|
138
|
+
case 14:
|
|
139
|
+
downloadVersion = 'v14.11.0';
|
|
140
|
+
break;
|
|
141
|
+
default:
|
|
142
|
+
throw new Error('Invalid node version, must be 5, 6, 10, or 14 (received ' + version + ')');
|
|
143
|
+
}
|
|
144
|
+
// Install node in home directory if it isn't already there.
|
|
145
|
+
var downloadDestination = path.join(downloadDirectory, 'node' + version);
|
|
146
|
+
var pathToExe = this.getPathToNodeExe(downloadVersion, downloadDestination);
|
|
147
|
+
if (pathToExe) {
|
|
148
|
+
return pathToExe;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
return this.downloadNode(downloadVersion, downloadDestination);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
// Determines the correct version of node to use based on the contents of the task's task.json. Defaults to Node 14.
|
|
155
|
+
MockTestRunner.prototype.getNodeVersion = function () {
|
|
156
|
+
var taskJsonPath = this.getTaskJsonPath();
|
|
157
|
+
if (!taskJsonPath) {
|
|
158
|
+
console.warn('Unable to find task.json, defaulting to use Node 14');
|
|
159
|
+
return 10;
|
|
160
|
+
}
|
|
161
|
+
var taskJsonContents = fs.readFileSync(taskJsonPath, { encoding: 'utf-8' });
|
|
162
|
+
var taskJson = JSON.parse(taskJsonContents);
|
|
163
|
+
var nodeVersionFound = false;
|
|
164
|
+
var execution = (taskJson['execution']
|
|
165
|
+
|| taskJson['prejobexecution']
|
|
166
|
+
|| taskJson['postjobexecution']);
|
|
167
|
+
var keys = Object.keys(execution);
|
|
168
|
+
for (var i = 0; i < keys.length; i++) {
|
|
169
|
+
if (keys[i].toLowerCase() == 'node14') {
|
|
170
|
+
// Prefer node 14 and return immediately.
|
|
171
|
+
return 14;
|
|
172
|
+
}
|
|
173
|
+
else if (keys[i].toLowerCase() == 'node10') {
|
|
174
|
+
// Prefer node 10 and return immediately.
|
|
175
|
+
return 10;
|
|
176
|
+
}
|
|
177
|
+
else if (keys[i].toLowerCase() == 'node') {
|
|
178
|
+
nodeVersionFound = true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (!nodeVersionFound) {
|
|
182
|
+
console.warn('Unable to determine execution type from task.json, defaulting to use Node 10');
|
|
183
|
+
return 10;
|
|
184
|
+
}
|
|
185
|
+
return 6;
|
|
186
|
+
};
|
|
187
|
+
// Returns the path to the task.json for the task being tested. Returns null if unable to find it.
|
|
188
|
+
// Searches by moving up the directory structure from the initial starting point and checking at each level.
|
|
189
|
+
MockTestRunner.prototype.getTaskJsonPath = function () {
|
|
190
|
+
if (this._taskJsonPath) {
|
|
191
|
+
return this._taskJsonPath;
|
|
192
|
+
}
|
|
193
|
+
var curPath = this._testPath;
|
|
194
|
+
var newPath = path.join(this._testPath, '..');
|
|
195
|
+
while (curPath != newPath) {
|
|
196
|
+
curPath = newPath;
|
|
197
|
+
var taskJsonPath = path.join(curPath, 'task.json');
|
|
198
|
+
if (fs.existsSync(taskJsonPath)) {
|
|
199
|
+
return taskJsonPath;
|
|
200
|
+
}
|
|
201
|
+
newPath = path.join(curPath, '..');
|
|
202
|
+
}
|
|
203
|
+
return '';
|
|
204
|
+
};
|
|
205
|
+
// Downloads the specified node version to the download destination. Returns a path to node.exe
|
|
206
|
+
MockTestRunner.prototype.downloadNode = function (nodeVersion, downloadDestination) {
|
|
207
|
+
shelljs.rm('-rf', downloadDestination);
|
|
208
|
+
var nodeUrl = process.env['TASK_NODE_URL'] || 'https://nodejs.org/dist';
|
|
209
|
+
nodeUrl = nodeUrl.replace(/\/$/, ''); // ensure there is no trailing slash on the base URL
|
|
210
|
+
var downloadPath = '';
|
|
211
|
+
switch (this.getPlatform()) {
|
|
212
|
+
case 'darwin':
|
|
213
|
+
this.downloadTarGz(nodeUrl + '/' + nodeVersion + '/node-' + nodeVersion + '-darwin-x64.tar.gz', downloadDestination);
|
|
214
|
+
downloadPath = path.join(downloadDestination, 'node-' + nodeVersion + '-darwin-x64', 'bin', 'node');
|
|
215
|
+
break;
|
|
216
|
+
case 'linux':
|
|
217
|
+
this.downloadTarGz(nodeUrl + '/' + nodeVersion + '/node-' + nodeVersion + '-linux-x64.tar.gz', downloadDestination);
|
|
218
|
+
downloadPath = path.join(downloadDestination, 'node-' + nodeVersion + '-linux-x64', 'bin', 'node');
|
|
219
|
+
break;
|
|
220
|
+
case 'win32':
|
|
221
|
+
this.downloadFile(nodeUrl + '/' + nodeVersion + '/win-x64/node.exe', downloadDestination, 'node.exe');
|
|
222
|
+
this.downloadFile(nodeUrl + '/' + nodeVersion + '/win-x64/node.lib', downloadDestination, 'node.lib');
|
|
223
|
+
downloadPath = path.join(downloadDestination, 'node.exe');
|
|
224
|
+
}
|
|
225
|
+
// Write marker to indicate download completed.
|
|
226
|
+
var marker = downloadDestination + '.completed';
|
|
227
|
+
fs.writeFileSync(marker, '');
|
|
228
|
+
return downloadPath;
|
|
229
|
+
};
|
|
230
|
+
// Downloads file to the downloadDestination, making any necessary folders along the way.
|
|
231
|
+
MockTestRunner.prototype.downloadFile = function (url, downloadDestination, fileName) {
|
|
232
|
+
var filePath = path.join(downloadDestination, fileName);
|
|
233
|
+
if (!url) {
|
|
234
|
+
throw new Error('Parameter "url" must be set.');
|
|
235
|
+
}
|
|
236
|
+
if (!downloadDestination) {
|
|
237
|
+
throw new Error('Parameter "downloadDestination" must be set.');
|
|
238
|
+
}
|
|
239
|
+
console.log('Downloading file:', url);
|
|
240
|
+
shelljs.mkdir('-p', downloadDestination);
|
|
241
|
+
var result = sync_request_1.default('GET', url);
|
|
242
|
+
fs.writeFileSync(filePath, result.getBody());
|
|
243
|
+
};
|
|
244
|
+
// Downloads tarGz to the download destination, making any necessary folders along the way.
|
|
245
|
+
MockTestRunner.prototype.downloadTarGz = function (url, downloadDestination) {
|
|
246
|
+
if (!url) {
|
|
247
|
+
throw new Error('Parameter "url" must be set.');
|
|
248
|
+
}
|
|
249
|
+
if (!downloadDestination) {
|
|
250
|
+
throw new Error('Parameter "downloadDestination" must be set.');
|
|
251
|
+
}
|
|
252
|
+
var tarGzName = 'node.tar.gz';
|
|
253
|
+
this.downloadFile(url, downloadDestination, tarGzName);
|
|
254
|
+
// Extract file
|
|
255
|
+
var originalCwd = process.cwd();
|
|
256
|
+
process.chdir(downloadDestination);
|
|
257
|
+
try {
|
|
258
|
+
ncp.execSync("tar -xzf \"" + path.join(downloadDestination, tarGzName) + "\"");
|
|
259
|
+
}
|
|
260
|
+
catch (_a) {
|
|
261
|
+
throw new Error('Failed to unzip node tar.gz from ' + url);
|
|
262
|
+
}
|
|
263
|
+
finally {
|
|
264
|
+
process.chdir(originalCwd);
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
// Checks if node is installed at downloadDestination. If it is, returns a path to node.exe, otherwise returns null.
|
|
268
|
+
MockTestRunner.prototype.getPathToNodeExe = function (nodeVersion, downloadDestination) {
|
|
269
|
+
var exePath = '';
|
|
270
|
+
switch (this.getPlatform()) {
|
|
271
|
+
case 'darwin':
|
|
272
|
+
exePath = path.join(downloadDestination, 'node-' + nodeVersion + '-darwin-x64', 'bin', 'node');
|
|
273
|
+
break;
|
|
274
|
+
case 'linux':
|
|
275
|
+
exePath = path.join(downloadDestination, 'node-' + nodeVersion + '-linux-x64', 'bin', 'node');
|
|
276
|
+
break;
|
|
277
|
+
case 'win32':
|
|
278
|
+
exePath = path.join(downloadDestination, 'node.exe');
|
|
279
|
+
}
|
|
280
|
+
// Only use path if marker is found indicating download completed successfully (and not partially)
|
|
281
|
+
var marker = downloadDestination + '.completed';
|
|
282
|
+
if (fs.existsSync(exePath) && fs.existsSync(marker)) {
|
|
283
|
+
return exePath;
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
return '';
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
MockTestRunner.prototype.getPlatform = function () {
|
|
290
|
+
var platform = os.platform();
|
|
291
|
+
if (platform != 'darwin' && platform != 'linux' && platform != 'win32') {
|
|
292
|
+
throw new Error('Unexpected platform: ' + platform);
|
|
293
|
+
}
|
|
294
|
+
return platform;
|
|
295
|
+
};
|
|
296
|
+
return MockTestRunner;
|
|
297
|
+
}());
|
|
298
|
+
exports.MockTestRunner = MockTestRunner;
|