зеркало из https://github.com/Azure/ms-rest-js.git
Make unit tests stable
This commit is contained in:
Родитель
9419f81db5
Коммит
1f68aa8b54
|
@ -1,65 +0,0 @@
|
|||
const { major } = require("semver");
|
||||
const { spawn, exec } = require("child_process");
|
||||
const { join } = require("path");
|
||||
const kill = require("tree-kill");
|
||||
|
||||
const webpackDevServer = spawn(join(__dirname, "../node_modules/.bin/ts-node"), ["-T", join(__dirname, "../testserver")], { shell: true })
|
||||
function cleanupDevServer() {
|
||||
webpackDevServer.stderr.destroy();
|
||||
webpackDevServer.stdout.destroy();
|
||||
console.log(`kill ${webpackDevServer.pid}`);
|
||||
kill(webpackDevServer.pid);
|
||||
};
|
||||
|
||||
let mochaRunning = false
|
||||
const webpackDevServerHandler = (data) => {
|
||||
if (!mochaRunning) {
|
||||
mochaRunning = true
|
||||
|
||||
const mochaChromePromise = new Promise((resolve, reject) => {
|
||||
if (major(process.version) < 8) {
|
||||
// Skip browser tests in pre-node 8
|
||||
resolve();
|
||||
} else {
|
||||
const mochaChromeExecutable = join(__dirname, "../node_modules/.bin/mocha-chrome");
|
||||
exec(`${mochaChromeExecutable} http://localhost:3001 --timeout 60000`, (err, stdout, stderr) => {
|
||||
console.log(stdout);
|
||||
console.error(stderr);
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const mochaPromise = new Promise((resolve, reject) => {
|
||||
const mochaExecutable = join(__dirname, "../node_modules/.bin/_mocha");
|
||||
const mocha = exec(mochaExecutable, (err, stdout, stderr) => {
|
||||
console.log(stdout);
|
||||
console.error(stderr);
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Promise.all([mochaPromise, mochaChromePromise]).then(res => {
|
||||
cleanupDevServer();
|
||||
process.exit(0);
|
||||
}).catch((err) => {
|
||||
cleanupDevServer();
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
webpackDevServer.stderr.on('data', data => {
|
||||
console.error("webpack dev server error:", data.toString());
|
||||
});
|
||||
|
||||
webpackDevServer.stdout.on('data', webpackDevServerHandler);
|
||||
webpackDevServer.on('exit', webpackDevServerHandler);
|
148
.scripts/unit.ts
148
.scripts/unit.ts
|
@ -1,8 +1,6 @@
|
|||
import { major } from "semver";
|
||||
import { spawn, exec, ExecException, ChildProcess, spawnSync, execSync } from "child_process";
|
||||
import { spawn, ChildProcess, spawnSync, SpawnSyncReturns } from "child_process";
|
||||
import { join } from "path";
|
||||
import kill from "tree-kill";
|
||||
import { execute } from "./dependencies";
|
||||
|
||||
const repositoryRootFolderPath: string = join(__dirname, "..");
|
||||
const nodeModulesBinFolderPath: string = join(repositoryRootFolderPath, "node_modules/.bin/");
|
||||
|
@ -11,79 +9,99 @@ const testServerFolderPath: string = join(repositoryRootFolderPath, "testserver"
|
|||
const mochaExecutable = join(nodeModulesBinFolderPath, "_mocha");
|
||||
const mochaChromeFilePath: string = join(nodeModulesBinFolderPath, "mocha-chrome");
|
||||
|
||||
interface ServerProcess extends ChildProcess {
|
||||
serverPid?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the provided command on the shell synchronously.
|
||||
* @param {string} command The command to execute.
|
||||
* @param {string} workingDirectory The working directory to execute the command in.
|
||||
* @returns {void}
|
||||
*/
|
||||
function execute(command: string, workingDirectory: string): number {
|
||||
log(workingDirectory, `Running "${command}"...`);
|
||||
return spawnSync(command, { cwd: workingDirectory, stdio: [0, 1, 2] }).status;
|
||||
function executeSync(command: string, workingDirectory: string): SpawnSyncReturns<string> {
|
||||
console.log(`Running "${command}"...`);
|
||||
const result: SpawnSyncReturns<string> = spawnSync(command, { cwd: workingDirectory, stdio: [0, 1, 2], encoding: "utf8", shell: true });
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function startTestServer(): Promise<ServerProcess> {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log(`Starting "${tsNodeFilePath} ${testServerFolderPath}"...`);
|
||||
const testServer: ServerProcess = spawn(tsNodeFilePath, [testServerFolderPath], { cwd: repositoryRootFolderPath, shell: true });
|
||||
|
||||
let testServerRunning = false;
|
||||
testServer.stdout.on("data", (chunk: any) => {
|
||||
const chunkString: string = chunk.toString("utf8");
|
||||
const matchResult: RegExpMatchArray | null = chunkString.match(/ms-rest-js testserver \((.*)\) listening on port (.*).../);
|
||||
if (matchResult) {
|
||||
testServer.serverPid = parseInt(matchResult[1]);
|
||||
}
|
||||
|
||||
if (testServer.serverPid == undefined) {
|
||||
reject(new Error("Test server didn't output its process id in its start message."));
|
||||
} else if (!testServerRunning) {
|
||||
testServerRunning = true;
|
||||
resolve(testServer);
|
||||
}
|
||||
});
|
||||
testServer.stderr.on("data", (data: any) => {
|
||||
console.error(`Test server error: "${data}"`);
|
||||
reject();
|
||||
});
|
||||
testServer.on("exit", (code: number, signal: string) => {
|
||||
console.log(`Test server exit code: ${code}, signal: ${signal}`);
|
||||
if (!testServerRunning) {
|
||||
testServerRunning = true;
|
||||
resolve(testServer);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function stopProcess(processId: number | undefined): void {
|
||||
if (processId != undefined) {
|
||||
console.log(`Stopping process ${processId}...`);
|
||||
process.kill(processId);
|
||||
}
|
||||
}
|
||||
|
||||
function stopTestServer(testServer: ServerProcess): void {
|
||||
stopProcess(testServer.pid);
|
||||
stopProcess(testServer.serverPid);
|
||||
}
|
||||
|
||||
function runNodeJsUnitTests(): number {
|
||||
return spawnSync(mochaExecutable)
|
||||
console.log(`Running Node.js Unit Tests...`);
|
||||
return executeSync(mochaExecutable, repositoryRootFolderPath).status;
|
||||
}
|
||||
|
||||
const webpackDevServer: ChildProcess = spawn(tsNodeFilePath, ["-T", testServerFolderPath], { shell: true });
|
||||
function cleanupDevServer(): void {
|
||||
webpackDevServer.stderr.destroy();
|
||||
webpackDevServer.stdout.destroy();
|
||||
console.log(`kill ${webpackDevServer.pid}`);
|
||||
kill(webpackDevServer.pid);
|
||||
console.log(`Killed dev server.`);
|
||||
function runBrowserUnitTests(): number {
|
||||
console.log(`Running Browser Unit Tests...`);
|
||||
const portNumber: string | number = process.env.PORT || 3001;
|
||||
return executeSync(`${mochaChromeFilePath} http://localhost:${portNumber} --timeout 60000`, repositoryRootFolderPath).status;
|
||||
}
|
||||
|
||||
let mochaRunning = false;
|
||||
const webpackDevServerHandler = () => {
|
||||
if (!mochaRunning) {
|
||||
mochaRunning = true;
|
||||
|
||||
const mochaChromePromise = new Promise((resolve, reject) => {
|
||||
if (major(process.version) < 8) {
|
||||
// Skip browser tests in pre-node 8
|
||||
resolve();
|
||||
} else {
|
||||
exec(`${mochaChromeFilePath} http://localhost:${process.env.PORT || 3001} --timeout 60000`, (err, stdout, stderr) => {
|
||||
console.log(`Browser output: "${stdout}"`);
|
||||
console.error(`Browser error: "${stderr}"`);
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const mochaPromise = new Promise((resolve, reject) => {
|
||||
exec(mochaExecutable, (err: ExecException | null, stdout: string, stderr: string) => {
|
||||
console.log(stdout);
|
||||
console.log(`Node.js error: "${stderr}"`);
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
let exitCode = 0;
|
||||
startTestServer()
|
||||
.then((testServer: ChildProcess) => {
|
||||
try {
|
||||
exitCode = runNodeJsUnitTests();
|
||||
if (exitCode === 0) {
|
||||
if (major(process.version) >= 8) {
|
||||
exitCode = runBrowserUnitTests();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Promise.all([mochaPromise, mochaChromePromise]).then(() => {
|
||||
console.log(`Overall done.`);
|
||||
cleanupDevServer();
|
||||
process.exit(0);
|
||||
}).catch((err) => {
|
||||
console.log(`Error: ${JSON.stringify(err)}`);
|
||||
cleanupDevServer();
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
webpackDevServer.stderr.on("data", data => {
|
||||
console.error("webpack dev server error:", data.toString());
|
||||
});
|
||||
|
||||
webpackDevServer.stdout.on("data", webpackDevServerHandler);
|
||||
webpackDevServer.on("exit", webpackDevServerHandler);
|
||||
}
|
||||
} finally {
|
||||
stopTestServer(testServer);
|
||||
}
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
console.log(`Error: ${error}`);
|
||||
})
|
||||
.finally(() => {
|
||||
process.exit(exitCode);
|
||||
});
|
|
@ -15,6 +15,16 @@
|
|||
"--colors"
|
||||
],
|
||||
"internalConsoleOptions": "openOnSessionStart"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Unit Tests",
|
||||
"args": ["${workspaceFolder}/.scripts/unit.ts"],
|
||||
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
|
||||
"sourceMaps": true,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"protocol": "inspector"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -86,7 +86,6 @@
|
|||
"should": "^5.2.0",
|
||||
"shx": "^0.2.2",
|
||||
"sinon": "^7.1.1",
|
||||
"tree-kill": "^1.2.1",
|
||||
"ts-loader": "^4.2.0",
|
||||
"ts-node": "^7.0.0",
|
||||
"tslint": "^5.10.0",
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
import * as childProcess from "child_process";
|
||||
import * as path from "path";
|
||||
import kill from "tree-kill";
|
||||
|
||||
let serverProcess: childProcess.ChildProcess;
|
||||
|
||||
before(function(done) {
|
||||
serverProcess = childProcess.spawn(path.join(__dirname, "../../node_modules/.bin/ts-node"), ["-T", "testserver", "--no-webpack"], { shell: true });
|
||||
const dataListener = () => {
|
||||
serverProcess.stdout.removeListener("data", dataListener);
|
||||
serverProcess.stderr.removeListener("data", dataListener);
|
||||
done();
|
||||
};
|
||||
serverProcess.stdout.on("data", dataListener);
|
||||
serverProcess.stderr.on("data", dataListener);
|
||||
serverProcess.on("error", err => {
|
||||
console.error(err);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
after(function() {
|
||||
serverProcess.stdout.destroy();
|
||||
serverProcess.stderr.destroy();
|
||||
console.log(`kill ${serverProcess.pid}`);
|
||||
kill(serverProcess.pid);
|
||||
});
|
|
@ -7,8 +7,8 @@ import { RestError } from "../../lib/restError";
|
|||
import { isNode } from "../../lib/util/utils";
|
||||
import { WebResource, HttpRequestBody } from "../../lib/webResource";
|
||||
import { baseURL } from "../testUtils";
|
||||
import { createReadStream } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { createReadStream } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
function getAbortController(): AbortController {
|
||||
let controller: AbortController;
|
||||
|
@ -21,8 +21,8 @@ function getAbortController(): AbortController {
|
|||
return controller;
|
||||
}
|
||||
|
||||
describe("defaultHttpClient", () => {
|
||||
it("should send HTTP requests", async () => {
|
||||
describe("defaultHttpClient", function () {
|
||||
it("should send HTTP requests", async function () {
|
||||
const request = new WebResource(`${baseURL}/example-index.html`, "GET");
|
||||
const httpClient = new DefaultHttpClient();
|
||||
|
||||
|
@ -91,7 +91,7 @@ describe("defaultHttpClient", () => {
|
|||
expectedResponseBody.replace(/\r\n/g, "\n"));
|
||||
});
|
||||
|
||||
it("should return a response instead of throwing for awaited 404", async () => {
|
||||
it("should return a response instead of throwing for awaited 404", async function () {
|
||||
const request = new WebResource(`${baseURL}/nonexistent`, "GET");
|
||||
const httpClient = new DefaultHttpClient();
|
||||
|
||||
|
@ -181,7 +181,7 @@ describe("defaultHttpClient", () => {
|
|||
assert(downloadNotified);
|
||||
});
|
||||
|
||||
it("should report upload and download progress for blob or stream bodies", async function() {
|
||||
it("should report upload and download progress for blob or stream bodies", async function () {
|
||||
let uploadNotified = false;
|
||||
let downloadNotified = false;
|
||||
|
||||
|
@ -213,7 +213,7 @@ describe("defaultHttpClient", () => {
|
|||
if (response.blobBody) {
|
||||
await response.blobBody;
|
||||
} else if (streamBody) {
|
||||
streamBody.on("data", () => {});
|
||||
streamBody.on("data", () => { });
|
||||
await new Promise((resolve, reject) => {
|
||||
streamBody.on("end", resolve);
|
||||
streamBody.on("error", reject);
|
||||
|
@ -234,7 +234,7 @@ describe("defaultHttpClient", () => {
|
|||
}
|
||||
});
|
||||
|
||||
it("should give a graceful error for nonexistent hosts", async function() {
|
||||
it("should give a graceful error for nonexistent hosts", async function () {
|
||||
const request = new WebResource(`http://foo.notawebsite/`);
|
||||
const client = new DefaultHttpClient();
|
||||
try {
|
||||
|
|
|
@ -59,5 +59,5 @@ app.put("/expect-empty", function (req, res) {
|
|||
});
|
||||
|
||||
app.listen(port, function() {
|
||||
console.log(`ms-rest-js testserver listening on port ${port}...`);
|
||||
console.log(`ms-rest-js testserver (${process.pid}) listening on port ${port}...`);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче