зеркало из https://github.com/mozilla/gecko-dev.git
geckodriver: Connect between geckodriver and marionette on a random port. (#112)
This allows running multiple sessions without needing to reuse the same port. Source-Repo: https://github.com/mozilla/geckodriver Source-Revision: 4d9e5b321e2665cb94f59fab16798a210020dc4b committer: GitHub <noreply@github.com> --HG-- extra : rebase_source : 2b43771675aa3b476ecad2068e94fdbe82fc9a6b
This commit is contained in:
Родитель
d9161df980
Коммит
6e1cfa655d
|
@ -19,7 +19,7 @@ use std::net::{SocketAddr, IpAddr};
|
|||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
|
||||
use argparse::{ArgumentParser, IncrBy, StoreTrue, Store};
|
||||
use argparse::{ArgumentParser, IncrBy, StoreTrue, Store, StoreOption};
|
||||
use webdriver::server::start;
|
||||
|
||||
use marionette::{MarionetteHandler, BrowserLauncher, LogLevel, MarionetteSettings, extension_routes};
|
||||
|
@ -46,7 +46,7 @@ struct Options {
|
|||
binary: String,
|
||||
webdriver_host: String,
|
||||
webdriver_port: u16,
|
||||
marionette_port: u16,
|
||||
marionette_port: Option<u16>,
|
||||
connect_existing: bool,
|
||||
e10s: bool,
|
||||
log_level: String,
|
||||
|
@ -59,7 +59,7 @@ fn parse_args() -> Options {
|
|||
binary: "".to_owned(),
|
||||
webdriver_host: "127.0.0.1".to_owned(),
|
||||
webdriver_port: 4444u16,
|
||||
marionette_port: 2828u16,
|
||||
marionette_port: None,
|
||||
connect_existing: false,
|
||||
e10s: false,
|
||||
log_level: "".to_owned(),
|
||||
|
@ -81,7 +81,7 @@ fn parse_args() -> Options {
|
|||
.add_option(&["--webdriver-port"], Store,
|
||||
"Port to run webdriver on");
|
||||
parser.refer(&mut opts.marionette_port)
|
||||
.add_option(&["--marionette-port"], Store,
|
||||
.add_option(&["--marionette-port"], StoreOption,
|
||||
"Port to run marionette on");
|
||||
parser.refer(&mut opts.connect_existing)
|
||||
.add_option(&["--connect-existing"], StoreTrue,
|
||||
|
@ -205,6 +205,8 @@ mod tests {
|
|||
use mozprofile::preferences::Pref;
|
||||
use std::io::Read;
|
||||
|
||||
const MARIONETTE_DEFAULT_PORT: u16 = 2828;
|
||||
|
||||
#[test]
|
||||
fn test_profile() {
|
||||
let mut profile_data = Vec::with_capacity(1024);
|
||||
|
@ -227,7 +229,7 @@ mod tests {
|
|||
};
|
||||
|
||||
let settings = MarionetteSettings {
|
||||
port: 2828,
|
||||
port: None,
|
||||
launcher: BrowserLauncher::None,
|
||||
e10s: false,
|
||||
log_level: None,
|
||||
|
@ -235,7 +237,7 @@ mod tests {
|
|||
let handler = MarionetteHandler::new(settings);
|
||||
|
||||
let mut gecko_profile = handler.load_profile(&capabilities).unwrap().unwrap();
|
||||
handler.set_prefs(&mut gecko_profile, true).unwrap();
|
||||
handler.set_prefs(MARIONETTE_DEFAULT_PORT, &mut gecko_profile, true).unwrap();
|
||||
|
||||
let prefs = gecko_profile.user_prefs().unwrap();
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::io::ErrorKind;
|
|||
use std::io::Result as IoResult;
|
||||
use std::io::prelude::*;
|
||||
use std::io;
|
||||
use std::net::TcpStream;
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
use std::thread::sleep;
|
||||
|
@ -277,7 +277,7 @@ impl FromStr for LogLevel {
|
|||
}
|
||||
|
||||
pub struct MarionetteSettings {
|
||||
pub port: u16,
|
||||
pub port: Option<u16>,
|
||||
pub launcher: BrowserLauncher,
|
||||
|
||||
/// Enable or disable Electrolysis, or multi-processing, in Gecko.
|
||||
|
@ -293,7 +293,7 @@ pub struct MarionetteHandler {
|
|||
connection: Mutex<Option<MarionetteConnection>>,
|
||||
launcher: BrowserLauncher,
|
||||
browser: Option<FirefoxRunner>,
|
||||
port: u16,
|
||||
port: Option<u16>,
|
||||
e10s: bool,
|
||||
log_level: Option<LogLevel>,
|
||||
}
|
||||
|
@ -315,7 +315,11 @@ impl MarionetteHandler {
|
|||
debug!("create_connection");
|
||||
let profile = try!(self.load_profile(capabilities));
|
||||
let args = try!(self.load_browser_args(capabilities));
|
||||
match self.start_browser(profile, args) {
|
||||
let port = match self.port {
|
||||
Some(x) => x,
|
||||
None => try!(get_free_port())
|
||||
};
|
||||
match self.start_browser(port, profile, args) {
|
||||
Err(e) => {
|
||||
return Err(WebDriverError::new(ErrorStatus::UnknownError,
|
||||
e.description().to_owned()));
|
||||
|
@ -323,7 +327,7 @@ impl MarionetteHandler {
|
|||
Ok(_) => {}
|
||||
}
|
||||
debug!("Creating connection");
|
||||
let mut connection = MarionetteConnection::new(self.port, session_id.clone());
|
||||
let mut connection = MarionetteConnection::new(port, session_id.clone());
|
||||
debug!("Starting marionette connection");
|
||||
try!(connection.connect());
|
||||
debug!("Marionette connection started");
|
||||
|
@ -331,7 +335,7 @@ impl MarionetteHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn start_browser(&mut self, profile: Option<Profile>, args: Option<Vec<String>>) -> Result<(), RunnerError> {
|
||||
fn start_browser(&mut self, port: u16, profile: Option<Profile>, args: Option<Vec<String>>) -> Result<(), RunnerError> {
|
||||
let custom_profile = profile.is_some();
|
||||
|
||||
match self.launcher {
|
||||
|
@ -340,7 +344,7 @@ impl MarionetteHandler {
|
|||
if let Some(cmd_args) = args {
|
||||
runner.args().extend(cmd_args);
|
||||
};
|
||||
try!(self.set_prefs(&mut runner.profile, custom_profile));
|
||||
try!(self.set_prefs(port, &mut runner.profile, custom_profile));
|
||||
try!(runner.start());
|
||||
|
||||
self.browser = Some(runner);
|
||||
|
@ -353,10 +357,10 @@ impl MarionetteHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_prefs(&self, profile: &mut Profile, custom_profile: bool)
|
||||
pub fn set_prefs(&self, port: u16, profile: &mut Profile, custom_profile: bool)
|
||||
-> Result<(), RunnerError> {
|
||||
let prefs = try!(profile.user_prefs());
|
||||
prefs.insert("marionette.defaultPrefs.port", Pref::new(self.port as i64));
|
||||
prefs.insert("marionette.defaultPrefs.port", Pref::new(port as i64));
|
||||
|
||||
prefs.insert_slice(&FIREFOX_REQUIRED_PREFERENCES[..]);
|
||||
if !custom_profile {
|
||||
|
@ -1085,6 +1089,12 @@ impl ToJson for MarionetteError {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_free_port() -> IoResult<u16> {
|
||||
TcpListener::bind(&("localhost", 0))
|
||||
.and_then(|stream| stream.local_addr())
|
||||
.map(|x| x.port())
|
||||
}
|
||||
|
||||
pub struct MarionetteConnection {
|
||||
port: u16,
|
||||
stream: Option<TcpStream>,
|
||||
|
@ -1105,6 +1115,7 @@ impl MarionetteConnection {
|
|||
let poll_interval = 100; // ms
|
||||
let poll_attempts = timeout / poll_interval;
|
||||
let mut poll_attempt = 0;
|
||||
info!("Connecting to Marionette on localhost:{}", self.port);
|
||||
loop {
|
||||
match TcpStream::connect(&("localhost", self.port)) {
|
||||
Ok(stream) => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче