robustify 'queue' logic and add tests

This commit is contained in:
Jonathan Lipps
2015-05-21 15:18:30 -07:00
parent 6ee61fe705
commit 30ef86da91
2 changed files with 79 additions and 40 deletions
+7 -11
View File
@@ -12,15 +12,6 @@ class BaseDriver extends MobileJsonWireProtocol {
this.sessionId = null;
this.caps = null;
this.lastCommand = B.delay(0);
// crazy sebv queue
this.createTask = (cmd, args) => {
this.lastCommand = this.lastCommand.then(() => {
return this[cmd](...args);
});
return this.lastCommand;
};
}
sessionExists (sessionId) {
@@ -32,7 +23,7 @@ class BaseDriver extends MobileJsonWireProtocol {
return !!caps;
}
execute (cmd, ...args) {
async execute (cmd, ...args) {
if (!this.sessionId && !_.contains(NO_SESSION_ID_COMMANDS, cmd)) {
throw new errors.NoSuchDriverError();
}
@@ -40,7 +31,12 @@ class BaseDriver extends MobileJsonWireProtocol {
if (!this[cmd]) {
throw new errors.NotYetImplementedError();
}
return this.createTask(cmd, args);
let ret = this.lastCommand.then(() => {
return this[cmd](...args);
});
this.lastCommand = ret.catch(() => {});
return ret;
}
}
+72 -29
View File
@@ -80,6 +80,78 @@ describe('BaseDriver', () => {
url.should.eventually.be.rejectedWith('session');
});
describe('command queue', () => {
let d = new BaseDriver();
let waitMs = 10;
d.getStatus = async () => {
await B.delay(waitMs);
return Date.now();
}.bind(d);
d.getSessions = async () => {
await B.delay(waitMs);
throw new Error("multipass");
}.bind(d);
it('should queue commands and execute/respond in the order received', async () => {
let numCmds = 10;
let cmds = [];
for (let i = 0; i < numCmds; i++) {
cmds.push(d.execute('getStatus'));
}
let results = await B.all(cmds);
for (let i = 1; i < numCmds; i++) {
if (results[i] <= results[i - 1]) {
throw new Error("Got result out of order");
}
}
});
it('should handle errors correctly when queuing', async () => {
let numCmds = 10;
let cmds = [];
for (let i = 0; i < numCmds; i++) {
if (i === 5) {
cmds.push(d.execute('getSessions'));
} else {
cmds.push(d.execute('getStatus'));
}
}
let results = await B.settle(cmds);
for (let i = 1; i < 5; i++) {
if (results[i].value() <= results[i - 1].value()) {
throw new Error("Got result out of order");
}
}
results[5].reason().message.should.contain("multipass");
for (let i = 7; i < numCmds; i++) {
if (results[i].value() <= results[i - 1].value()) {
throw new Error("Got result out of order");
}
}
});
it('should not care if queue empties for a bit', async () => {
let numCmds = 10;
let cmds = [];
for (let i = 0; i < numCmds; i++) {
cmds.push(d.execute('getStatus'));
}
let results = await B.all(cmds);
cmds = [];
for (let i = 0; i < numCmds; i++) {
cmds.push(d.execute('getStatus'));
}
results = await B.all(cmds);
for (let i = 1; i < numCmds; i++) {
if (results[i] <= results[i - 1]) {
throw new Error("Got result out of order");
}
}
});
});
});
describe('BaseDriver via HTTP', () => {
@@ -108,35 +180,6 @@ describe('BaseDriver via HTTP', () => {
});
});
describe('command queue', () => {
function buildStatusRequest () {
return request({
url: 'http://localhost:8181/wd/hub/status',
method: 'GET',
json: true
});
}
it('should queue commands and execute/respond in the order received', async () => {
let numCmds = 10;
let waitMs = 10;
let cmds = [];
for (let i = 0; i < numCmds; i++) {
cmds.push(buildStatusRequest());
}
d.getStatus = async () => {
await B.delay(waitMs);
return Date.now();
}.bind(d);
let results = await B.all(cmds);
for (let i = 1; i < numCmds; i++) {
if (results[i].value <= results[i - 1].value) {
throw new Error("Got result out of order");
}
}
});
});
describe('command timeouts', () => {
it.skip('should throw NYI for commands not implemented', async () => {
});