diff --git a/webrtc/tools/rtcbot/README b/webrtc/tools/rtcbot/README index 72f9f63f87..bfa981c5a0 100644 --- a/webrtc/tools/rtcbot/README +++ b/webrtc/tools/rtcbot/README @@ -17,7 +17,10 @@ access its exposed API. Details are in botmanager.js. == How to run the test == $ cd trunk/webrtc/tool/rtcbot $ npm install express browserify ws websocket-stream dnode - $ node test.js + $ node main.js "" + +== How can I see the list of available tests? == + $ node main.js == Example on how to install nodejs == $ cd /work/tools/ @@ -30,7 +33,7 @@ access its exposed API. Details are in botmanager.js. - "chrome": chrome on host machine. - "android-chrome": chrome on android device. Details in "Android" Section. - * Bot type is specified for each spawned bot in the test file. + * Bot type is specified directly by the test. == Android == Before running test with Android one MUST forward the device port 8080 to the diff --git a/webrtc/tools/rtcbot/main.js b/webrtc/tools/rtcbot/main.js new file mode 100644 index 0000000000..665f6e88e8 --- /dev/null +++ b/webrtc/tools/rtcbot/main.js @@ -0,0 +1,102 @@ +// Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// +// This script loads all the test/* files into a very small context that +// only exposes a minimal set of functions that allows to register tests. +// +// Once all files are loaded it runs the specific test on the command line. +// If no arguments are given it lists all the registered tests. +// +// Note: the small context where the scripts are loaded is intended to keep +// nodejs-isms away from the test code and isolate implementation details away +// from them. +var fs = require('fs'); +var vm = require('vm'); +var Test = require('./test.js'); + +var testSuites = {}; + +function registerTest(name, func) { + testSuites[name] = func; +} + +function registerBotTest(name, func, bots) { + registerTest(name, bootstrap); + + function bootstrap(test) { + var callbacks = []; + for (var i = 0; i != bots.length; ++i) + callbacks.push(test.spawnBot.bind(test, "", bots[i])); + + test.wait(callbacks, func.bind(test, test)); + } +} + +function loadTestFile(filename, doneCallback) { + var loadTestContext = { + setTimeout: setTimeout, + registerTest: registerTest, + registerBotTest: registerBotTest + }; + var script = vm.createScript(fs.readFileSync(filename), filename); + script.runInNewContext(loadTestContext); + doneCallback(); +} + +function iterateOverTestFiles(foreachCallback, doneCallback) { + fs.readdir('test', function (error, list) { + function iterateNextFile() { + if (list.length === 0) { + doneCallback(); + } else { + var filename = list.pop(); + if (filename[0] === '.' || filename.slice(-3) !== '.js') { + // Skip hidden and non .js files on that directory. + iterateNextFile(); + } else { + foreachCallback('test/' + filename, iterateNextFile); + } + } + } + + if (error !== null) { + throw error; + } + iterateNextFile(); + }); +} + +function runTest(testname) { + if (testname in testSuites) { + console.log("Running test: " + testname); + var test = new Test(); + testSuites[testname](test); + } else { + console.log("Unknown test: " + testname); + } +} + +function printUsage() { + console.log('Run as:\n $ ' + + process.argv[0] + ' ' + process.argv[1] + + ' '); + console.log('These are the existent ones:'); + for (var testname in testSuites) + console.log(' ' + testname); +} + +function main() { + // TODO(andresp): support multiple tests. + var testList = process.argv.slice(2); + if (testList.length === 1) + runTest(testList[0]); + else + printUsage(); +} + +iterateOverTestFiles(loadTestFile, main); diff --git a/webrtc/tools/rtcbot/test.js b/webrtc/tools/rtcbot/test.js index e1173985d3..abf0e173d4 100644 --- a/webrtc/tools/rtcbot/test.js +++ b/webrtc/tools/rtcbot/test.js @@ -6,14 +6,9 @@ // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // -// This script loads the test file in the virtual machine and runs it in a -// context that only exposes a test variable with methods for testing and to -// spawn bots. -// -// Note: an important part of this script is to keep nodejs-isms away from test -// code and isolate it from implementation details. +// Provides a Test class that exposes api to the tests. +// Read test.prototype to see what methods are exposed. var fs = require('fs'); -var vm = require('vm'); var BotManager = require('./botmanager.js'); function Test() { @@ -134,13 +129,6 @@ StatisticsReport.prototype = { doneCallback); } }, -} +}; -function runTest(testfile) { - console.log("Running test: " + testfile); - var script = vm.createScript(fs.readFileSync(testfile), testfile); - script.runInNewContext({ test: new Test(), setInterval: setInterval, - setTimeout: setTimeout }); -} - -runTest(process.argv[2]); +module.exports = Test; diff --git a/webrtc/tools/rtcbot/test/ping_pong.js b/webrtc/tools/rtcbot/test/ping_pong.js index feee3bcb9b..1d9886e962 100644 --- a/webrtc/tools/rtcbot/test/ping_pong.js +++ b/webrtc/tools/rtcbot/test/ping_pong.js @@ -6,8 +6,9 @@ // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // -function testPingPong(bot) { - test.log('bot:alice > Sending Ping to bot'); +function testPingPong(test, bot) { + test.assert(typeof bot.ping === 'function', 'Bot does not exposes ping.'); + bot.ping(gotAnswer); function gotAnswer(answer) { @@ -16,4 +17,4 @@ function testPingPong(bot) { } } -test.spawnBot("alice", "chrome", testPingPong); +registerBotTest('testPingPong/chrome', testPingPong, ['chrome']); diff --git a/webrtc/tools/rtcbot/test/simple_offer_answer.js b/webrtc/tools/rtcbot/test/simple_offer_answer.js index e052598922..43553f0bc0 100644 --- a/webrtc/tools/rtcbot/test/simple_offer_answer.js +++ b/webrtc/tools/rtcbot/test/simple_offer_answer.js @@ -10,17 +10,12 @@ // // Note: This test does not performs ice candidate exchange and // does not verifies that media can flow between the peers. -function testOfferAnswer(peer1, peer2) { - test.wait([ - createPeerConnection.bind(peer1), - createPeerConnection.bind(peer2) ], - establishCall); +function testOfferAnswer(test, bot1, bot2) { + test.wait( [ bot1.createPeerConnection.bind(bot1, null), + bot2.createPeerConnection.bind(bot2, null) ], + run); - function createPeerConnection(done) { - this.createPeerConnection(null, done, test.fail); - } - - function establishCall(pc1, pc2) { + function run(pc1, pc2) { test.log("Establishing call."); pc1.createOffer(gotOffer); @@ -38,17 +33,16 @@ function testOfferAnswer(peer1, peer2) { pc2.setLocalDescription(answer, expectedCall, test.fail); pc1.setRemoteDescription(answer, expectedCall, test.fail); } + + // TODO(andresp): Implement utilities in test to write expectations + // that certain methods must be called. + var expectedCalls = 0; + function expectedCall() { + if (++expectedCalls == 6) + test.done(); + } } } -// TODO(andresp): Implement utilities in test to write expectations that certain -// methods must be called. -var expectedCalls = 0; -function expectedCall() { - if (++expectedCalls == 6) - test.done(); -} - -test.wait( [ test.spawnBot.bind(test, "alice", "chrome"), - test.spawnBot.bind(test, "bob", "chrome") ], - testOfferAnswer); +registerBotTest('testOfferAnswer/chrome=>chrome', + testOfferAnswer, ['chrome', 'chrome']); diff --git a/webrtc/tools/rtcbot/test/webrtc_video_streaming.js b/webrtc/tools/rtcbot/test/webrtc_video_streaming.js index 62b7056b20..9142c530c3 100644 --- a/webrtc/tools/rtcbot/test/webrtc_video_streaming.js +++ b/webrtc/tools/rtcbot/test/webrtc_video_streaming.js @@ -11,11 +11,7 @@ // and then write these stats to a file. // // Note: the source of the video and audio stream is getUserMedia(). -// -function testVideoStreaming(bot1, bot2) { - var pc1 = null; - var pc2 = null; - +function testOneWayVideo(test, bot1, bot2) { var report = test.createStatisticsReport("webrtc_video_streaming"); test.wait([ @@ -29,10 +25,8 @@ function testVideoStreaming(bot1, bot2) { }.bind(this), test.fail); } - function onPeerConnectionCreated(peer1, peer2) { + function onPeerConnectionCreated(pc1, pc2) { test.log("RTC Peers created."); - pc1 = peer1; - pc2 = peer2; pc1.addEventListener('addstream', test.fail); pc2.addEventListener('addstream', onAddStream); pc1.addEventListener('icecandidate', onIceCandidate.bind(pc2)); @@ -45,7 +39,7 @@ function testVideoStreaming(bot1, bot2) { pc1.addStream(stream); bot1.showStream(stream.id, true, true); - createOfferAndAnswer(); + createOfferAndAnswer(pc1, pc2); } } @@ -55,18 +49,18 @@ function testVideoStreaming(bot1, bot2) { } function onIceCandidate(event) { - if(event.candidate){ + if(event.candidate) { test.log(event.candidate.candidate); this.addIceCandidate(event.candidate, onAddIceCandidateSuccess, test.fail); - }; + } function onAddIceCandidateSuccess() { test.log("Candidate added successfully"); - }; + } } - function createOfferAndAnswer() { + function createOfferAndAnswer(pc1, pc2) { test.log("Creating offer."); pc1.createOffer(gotOffer, test.fail); @@ -103,6 +97,5 @@ function testVideoStreaming(bot1, bot2) { } } -test.wait( [ test.spawnBot.bind(test, "alice", "chrome"), - test.spawnBot.bind(test, "bob", "android-chrome") ], - testVideoStreaming); +registerBotTest('testOneWayVideo/chrome=>chrome', + testOneWayVideo, ['chrome', 'chrome']);