Improve node.js test runner: send response after each test, update timeout after each test.

This commit is contained in:
Alexey Andreev 2017-10-26 14:11:56 +03:00
parent 6848984a10
commit 5c436c3391
2 changed files with 54 additions and 24 deletions

View File

@ -34,30 +34,27 @@ function tryConnect() {
function listen(ws) { function listen(ws) {
ws.onmessage = (event) => { ws.onmessage = (event) => {
let resultConsumer = [];
let request = JSON.parse(event.data); let request = JSON.parse(event.data);
console.log("Request #" + request.id + " received"); console.log("Request #" + request.id + " received");
runTests(request.tests, resultConsumer, 0, () => { runTests(ws, request.id, request.tests, 0);
console.log("Sending response #" + request.id);
ws.send(JSON.stringify({
id: request.id,
result: resultConsumer
}));
});
} }
} }
function runTests(tests, consumer, index, callback) { function runTests(ws, suiteId, tests, index) {
if (index === tests.length) { if (index === tests.length) {
callback(); return;
} else { }
let test = tests[index]; let test = tests[index];
runSingleTest(test, result => { runSingleTest(test, result => {
consumer.push(result); console.log("Sending response #" + suiteId);
runTests(tests, consumer, index + 1, callback); ws.send(JSON.stringify({
id: suiteId,
index: index,
result: result
}));
runTests(ws, suiteId, tests, index + 1);
}); });
} }
}
function runSingleTest(test, callback) { function runSingleTest(test, callback) {
console.log("Running test " + test.name + " consisting of " + test.files); console.log("Running test " + test.name + " consisting of " + test.files);

View File

@ -127,10 +127,15 @@ class TestRunner {
this.pendingRequests = Object.create(null); this.pendingRequests = Object.create(null);
this.requestIdGen = 0; this.requestIdGen = 0;
this.timeout = null;
this.ws.on("message", (message) => { this.ws.on("message", (message) => {
const response = JSON.parse(message.utf8Data); const response = JSON.parse(message.utf8Data);
const pendingRequest = this.pendingRequests[response.id]; const pendingRequest = this.pendingRequests[response.id + "-" + response.index];
delete this.pendingRequests[response.id]; delete this.pendingRequests[response.id];
if (this.timeout) {
this.timeout.refresh();
}
pendingRequest(response.result); pendingRequest(response.result);
}) })
} }
@ -149,14 +154,17 @@ class TestRunner {
}); });
this.testsRun += suite.testCases.length; this.testsRun += suite.testCases.length;
const resultPromise = new Promise(resolve => { const resultPromises = [];
this.pendingRequests[request.id] = resolve;
}); this.timeout = createRefreshableTimeoutPromise(10000);
const timeoutPromise = new Promise((_, reject) => { for (let i = 0; i < suite.testCases.length; ++i) {
setTimeout(() => reject(new Error("connection timeout")), 120000); resultPromises.push(new Promise(resolve => {
}); this.pendingRequests[request.id + "-" + i] = resolve;
}));
}
this.ws.send(JSON.stringify(request)); this.ws.send(JSON.stringify(request));
const result = await Promise.race([resultPromise, timeoutPromise]); const result = await Promise.race([Promise.all(resultPromises), this.timeout.promise]);
for (let i = 0; i < suite.testCases.length; i++) { for (let i = 0; i < suite.testCases.length; i++) {
const testCase = suite.testCases[i]; const testCase = suite.testCases[i];
@ -264,6 +272,31 @@ function runTeaVM() {
}) })
} }
function createRefreshableTimeoutPromise(timeout) {
const obj = {
currentId: 0,
resolveFun: () => {},
refresh: () => {
const expectedId = ++obj.currentId;
setTimeout(() => {
if (expectedId === obj.currentId) {
obj.resolveFun(new Error("Connection timeout"))
}
}, timeout);
}
};
const result = {
promise: new Promise((_, reject) => {
obj.resolveFun = reject;
}),
refresh: () => obj.refresh()
};
obj.refresh();
return result;
}
runAll().catch(e => { runAll().catch(e => {
console.log(e.stack); console.log(e.stack);
process.exit(1); process.exit(1);