Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(271)

Side by Side Diff: webrtc/tools/rtcbot/botmanager.js

Issue 2965593002: Move webrtc/{tools => rtc_tools} (Closed)
Patch Set: Adding back root changes Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/tools/rtcbot/bot/browser/index.html ('k') | webrtc/tools/rtcbot/main.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 //
9 // botmanager.js module allows a test to spawn bots that expose an RPC API
10 // to be controlled by tests.
11 var https = require('https');
12 var fs = require('fs');
13 var child = require('child_process');
14 var Browserify = require('browserify');
15 var Dnode = require('dnode');
16 var Express = require('express');
17 var WebSocketServer = require('ws').Server;
18 var WebSocketStream = require('websocket-stream');
19
20 // BotManager runs a HttpsServer that serves bots assets and and WebSocketServer
21 // that listens to incoming connections. Once a connection is available it
22 // connects it to bots pending endpoints.
23 //
24 // TODO(andresp): There should be a way to control which bot was spawned
25 // and what bot instance it gets connected to.
26 BotManager = function () {
27 this.webSocketServer_ = null;
28 this.bots_ = [];
29 this.pendingConnections_ = [];
30 this.androidDeviceManager_ = new AndroidDeviceManager();
31 }
32
33 BotManager.BotTypes = {
34 CHROME : 'chrome',
35 ANDROID_CHROME : 'android-chrome',
36 };
37
38 BotManager.prototype = {
39 createBot_: function (name, botType, callback) {
40 switch(botType) {
41 case BotManager.BotTypes.CHROME:
42 return new BrowserBot(name, callback);
43 case BotManager.BotTypes.ANDROID_CHROME:
44 return new AndroidChromeBot(name, this.androidDeviceManager_,
45 callback);
46 default:
47 console.log('Error: Type ' + botType + ' not supported by rtc-Bot!');
48 process.exit(1);
49 }
50 },
51
52 spawnNewBot: function (name, botType, callback) {
53 this.startWebSocketServer_();
54 var bot = this.createBot_(name, botType, callback);
55 this.bots_.push(bot);
56 this.pendingConnections_.push(bot.onBotConnected.bind(bot));
57 },
58
59 startWebSocketServer_: function () {
60 if (this.webSocketServer_) return;
61
62 this.app_ = new Express();
63
64 this.app_.use('/bot/api.js',
65 this.serveBrowserifyFile_.bind(this,
66 __dirname + '/bot/api.js'));
67
68 this.app_.use('/bot/', Express.static(__dirname + '/bot'));
69
70 var options = options = {
71 key: fs.readFileSync('configurations/priv.pem', 'utf8'),
72 cert: fs.readFileSync('configurations/cert.crt', 'utf8')
73 };
74 this.server_ = https.createServer(options, this.app_);
75
76 this.webSocketServer_ = new WebSocketServer({ server: this.server_ });
77 this.webSocketServer_.on('connection', this.onConnection_.bind(this));
78
79 this.server_.listen(8080);
80 },
81
82 onConnection_: function (ws) {
83 var callback = this.pendingConnections_.shift();
84 callback(new WebSocketStream(ws));
85 },
86
87 serveBrowserifyFile_: function (file, request, result) {
88 // TODO(andresp): Cache browserify result for future serves.
89 var browserify = new Browserify();
90 browserify.add(file);
91 browserify.bundle().pipe(result);
92 }
93 }
94
95 // A basic bot waits for onBotConnected to be called with a stream to the actual
96 // endpoint with the bot. Once that stream is available it establishes a dnode
97 // connection and calls the callback with the other endpoint interface so the
98 // test can interact with it.
99 Bot = function (name, callback) {
100 this.name_ = name;
101 this.onbotready_ = callback;
102 }
103
104 Bot.prototype = {
105 log: function (msg) {
106 console.log("bot:" + this.name_ + " > " + msg);
107 },
108
109 name: function () { return this.name_; },
110
111 onBotConnected: function (stream) {
112 this.log('Connected');
113 this.stream_ = stream;
114 this.dnode_ = new Dnode();
115 this.dnode_.on('remote', this.onRemoteFromDnode_.bind(this));
116 this.dnode_.pipe(this.stream_).pipe(this.dnode_);
117 },
118
119 onRemoteFromDnode_: function (remote) {
120 this.onbotready_(remote);
121 }
122 }
123
124 // BrowserBot spawns a process to open "https://localhost:8080/bot/browser".
125 //
126 // That page once loaded, connects to the websocket server run by BotManager
127 // and exposes the bot api.
128 BrowserBot = function (name, callback) {
129 Bot.call(this, name, callback);
130 this.spawnBotProcess_();
131 }
132
133 BrowserBot.prototype = {
134 spawnBotProcess_: function () {
135 this.log('Spawning browser');
136 child.exec('google-chrome "https://localhost:8080/bot/browser/"');
137 },
138
139 __proto__: Bot.prototype
140 }
141
142 // AndroidChromeBot spawns a process to open
143 // "https://localhost:8080/bot/browser/" on chrome for Android.
144 AndroidChromeBot = function (name, androidDeviceManager, callback) {
145 Bot.call(this, name, callback);
146 androidDeviceManager.getNewDevice(function (serialNumber) {
147 this.serialNumber_ = serialNumber;
148 this.spawnBotProcess_();
149 }.bind(this));
150 }
151
152 AndroidChromeBot.prototype = {
153 spawnBotProcess_: function () {
154 this.log('Spawning Android device with serial ' + this.serialNumber_);
155 var runChrome = 'adb -s ' + this.serialNumber_ + ' shell am start ' +
156 '-n com.android.chrome/com.google.android.apps.chrome.Main ' +
157 '-d https://localhost:8080/bot/browser/';
158 child.exec(runChrome, function (error, stdout, stderr) {
159 if (error) {
160 this.log(error);
161 process.exit(1);
162 }
163 this.log('Opening Chrome for Android...');
164 this.log(stdout);
165 }.bind(this));
166 },
167
168 __proto__: Bot.prototype
169 }
170
171 AndroidDeviceManager = function () {
172 this.connectedDevices_ = [];
173 }
174
175 AndroidDeviceManager.prototype = {
176 getNewDevice: function (callback) {
177 this.listDevices_(function (devices) {
178 for (var i = 0; i < devices.length; i++) {
179 if (!this.connectedDevices_[devices[i]]) {
180 this.connectedDevices_[devices[i]] = devices[i];
181 callback(this.connectedDevices_[devices[i]]);
182 return;
183 }
184 }
185 if (devices.length == 0) {
186 console.log('Error: No connected devices!');
187 } else {
188 console.log('Error: There is no enough connected devices.');
189 }
190 process.exit(1);
191 }.bind(this));
192 },
193
194 listDevices_: function (callback) {
195 child.exec('adb devices' , function (error, stdout, stderr) {
196 var devices = [];
197 if (error || stderr) {
198 console.log(error || stderr);
199 }
200 if (stdout) {
201 // The first line is "List of devices attached"
202 // and the following lines:
203 // <serial number> <device/emulator>
204 var tempList = stdout.split("\n").slice(1);
205 for (var i = 0; i < tempList.length; i++) {
206 if (tempList[i] == "") {
207 continue;
208 }
209 devices.push(tempList[i].split("\t")[0]);
210 }
211 }
212 callback(devices);
213 });
214 },
215 }
216 module.exports = BotManager;
OLDNEW
« no previous file with comments | « webrtc/tools/rtcbot/bot/browser/index.html ('k') | webrtc/tools/rtcbot/main.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698