Build a fake firefox.exe for integration-tests

This commit is contained in:
Barret Rennie 2020-09-21 18:11:28 -04:00
Родитель c9dfca73d5
Коммит 3cf57dccc8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4D71D86C09132D72
11 изменённых файлов: 164 добавлений и 40 удалений

16
Cargo.lock сгенерированный
Просмотреть файл

@ -326,6 +326,13 @@ dependencies = [
"syn",
]
[[package]]
name = "fakefox"
version = "0.1.0"
dependencies = [
"structopt",
]
[[package]]
name = "flate2"
version = "1.0.14"
@ -684,6 +691,7 @@ dependencies = [
"tempfile",
"tokio",
"url",
"zip",
]
[[package]]
@ -1402,9 +1410,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "structopt"
version = "0.3.14"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "863246aaf5ddd0d6928dfeb1a9ca65f505599e4e1b399935ef7e75107516b4ef"
checksum = "6cc388d94ffabf39b5ed5fadddc40147cb21e605f53db6f8f36a625d27489ac5"
dependencies = [
"clap",
"lazy_static",
@ -1413,9 +1421,9 @@ dependencies = [
[[package]]
name = "structopt-derive"
version = "0.4.7"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d239ca4b13aee7a2142e6795cbd69e457665ff8037aed33b3effdc430d2f927a"
checksum = "5e2513111825077552a6751dfad9e11ce0fba07d7276a3943a037d7e93e64c5f"
dependencies = [
"heck",
"proc-macro-error",

Просмотреть файл

@ -1,5 +1,6 @@
[workspace]
members = [
"fakefox",
"fxrecorder",
"fxrunner",
"libfxrecord",

13
fakefox/Cargo.toml Normal file
Просмотреть файл

@ -0,0 +1,13 @@
[package]
name = "fakefox"
version = "0.1.0"
authors = ["barret Rennie <barret@mozilla.com>"]
edition = "2018"
license = "MPL-2.0"
[[bin]]
name = "fakefox"
path = "src/main.rs"
[dependencies]
structopt = "0.3.17"

76
fakefox/src/main.rs Normal file
Просмотреть файл

@ -0,0 +1,76 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::env;
use std::process::{exit, Command};
use std::thread::sleep;
use std::time::Duration;
use structopt::StructOpt;
/// Mimic the behaviour of `firefox.exe` on Windows.
///
/// By default, the first run of firefox.exe starts the "Launcher Process", which
/// does a bunch of work before re-executing `firefox.exe` as the main (parent)
/// process.
/// Matches the options passed to `firefox.exe` by `fxrunner.
#[derive(StructOpt)]
struct LauncherOptions {
#[structopt(long = "profile")]
_profile: String,
#[structopt(long)]
new_instance: bool,
#[structopt(long)]
wait_for_browser: bool,
}
/// Options to distinguish main process mode from launcher mode.
#[derive(StructOpt)]
struct MainOptions {
#[structopt(long)]
main: bool,
}
fn main() {
let args: Vec<String> = env::args().collect();
if let Ok(opts) = LauncherOptions::from_iter_safe(&args) {
eprintln!("[launcher] args: {:?}", args);
// Launcher process.
// Launch this executable with different command
assert!(opts.wait_for_browser);
assert!(opts.new_instance);
let mut child = Command::new(&args[0])
.arg("--main")
.spawn()
.expect("Could not spawn child");
eprintln!("[launcher] spawned child process {}", child.id());
let exit_status = child.wait().expect("wait()");
let code = exit_status.code().unwrap();
eprintln!("[launcher] child exited: {}", code);
exit(code);
} else if let Ok(opts) = MainOptions::from_iter_safe(&args) {
if opts.main {
eprintln!("[main] args: {:?}", args);
assert!(opts.main);
// Main process.
// Just spin the even loop waiting to be terminated.
loop {
sleep(Duration::from_secs(30));
}
}
}
eprintln!("[fakefox] args: {:?}", args);
panic!("[fakefox] not executed as child or parent");
}

Просмотреть файл

@ -166,19 +166,6 @@ mod test {
assert_eq!(stats.top_level_dir, None);
}
{
let zip = test_dir.join("firefox.zip");
let tempdir = TempDir::new().unwrap();
let stats = unzip(&zip, tempdir.path()).unwrap();
let firefox_dir = tempdir.path().join("firefox");
assert!(firefox_dir.join("firefox.exe").is_file());
assert_eq!(stats.extracted, 1);
assert_eq!(stats.top_level_dir, Some(PathBuf::from("firefox")));
}
{
let zip = test_dir.join("profile.zip");
let tempdir = TempDir::new().unwrap();

Просмотреть файл

@ -9,6 +9,9 @@ license = "MPL-2.0"
name = "integration-tests"
path = "src/test.rs"
[build-dependencies]
zip = "0.5.6"
[dev-dependencies]
assert_matches = "1.3.0"
async-trait = "0.1.36"

Просмотреть файл

@ -0,0 +1,49 @@
use std::env;
use std::fs::File;
use std::io;
use std::path::Path;
use std::process::Command;
use zip::write::FileOptions;
use zip::ZipWriter;
fn main() {
// We need to build fakefox in a separate target directory, or else nested
// cargo build will hang forever waiting for a lock on the target directory.
let fakefox_target_path = env::current_dir()
.expect("no cwd")
.parent()
.expect("no parent diorectory")
.join("target")
.join("nested");
let cargo = env::var("CARGO").expect("no CARGO during cargo build");
let cargo_status = Command::new(&cargo)
.args(&["build", "-p", "fakefox", "--target-dir"])
.arg(&fakefox_target_path)
.status()
.expect("could not execute `cargo build -p fakefox`.");
assert!(
cargo_status.success(),
"Failed to run `cargo build -p fakefox`."
);
let out_dir = env::var("OUT_DIR").expect("no OUT_DIR during cargo build");
let out_dir = Path::new(&out_dir);
let fakefox_path = fakefox_target_path.join("debug").join("fakefox.exe");
let zip_path = out_dir.join("firefox.zip");
let mut zip_file = File::create(&zip_path).expect("could not create firefox.zip");
let mut fakefox_file = File::open(&fakefox_path).expect("could not open fakefox.exe");
let mut zip = ZipWriter::new(&mut zip_file);
zip.add_directory("firefox", FileOptions::default())
.unwrap();
zip.start_file("firefox/firefox.exe", FileOptions::default())
.unwrap();
io::copy(&mut fakefox_file, &mut zip).unwrap();
zip.finish().unwrap();
println!("wrote firefox.zip to {}", zip_path.display());
}

Просмотреть файл

@ -18,7 +18,7 @@ use libfxrunner::taskcluster::Taskcluster;
use tempfile::TempDir;
use tokio::fs;
use crate::util::{test_dir, touch, AssertInvoked};
use crate::util::{firefox_zip_path, test_dir, AssertInvoked};
/// The only valid session ID for TestSessionManager.
pub const VALID_SESSION_ID: &str = "REQUESTID";
@ -80,7 +80,7 @@ impl Taskcluster for TestTaskcluster {
}
Some(TaskclusterFailureMode::BadZip) => test_dir().join("test.zip"),
Some(TaskclusterFailureMode::NotZip) => test_dir().join("README.md"),
None => test_dir().join("firefox.zip"),
None => firefox_zip_path(),
};
let dest = download_dir.join("firefox.zip");
@ -289,12 +289,8 @@ impl SessionManager for TestSessionManager {
fs::create_dir(&session_info.path.join("profile"))
.await
.unwrap();
fs::create_dir(&session_info.path.join("firefox"))
.await
.unwrap();
touch(&session_info.path.join("firefox").join("firefox.exe"))
.await
.unwrap();
libfxrunner::zip::unzip(&firefox_zip_path(), &session_info.path).unwrap();
*self.handle.last_session_info.lock().unwrap() = Some(session_info.clone());
Ok(session_info)

Просмотреть файл

@ -3,7 +3,7 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::fs::File;
use std::io::{self, Read};
use std::io::Read;
use std::path::{Path, PathBuf};
/// A test helper that is used to assert an operation either occurred or did not
@ -50,6 +50,11 @@ pub fn test_dir() -> PathBuf {
.join("test")
}
/// Return the path of the build-generated `firefox.zip`.
pub fn firefox_zip_path() -> PathBuf {
PathBuf::from(env!("OUT_DIR")).join("firefox.zip")
}
pub fn directory_is_empty(path: &Path) -> bool {
path.read_dir()
.unwrap()
@ -80,12 +85,3 @@ pub fn assert_file_contents_eq(path: &Path, expected: &'static str) {
};
assert_eq!(contents, expected);
}
pub async fn touch(path: &Path) -> Result<(), io::Error> {
tokio::fs::OpenOptions::new()
.create(true)
.write(true)
.open(path)
.await
.map(drop)
}

Просмотреть файл

@ -2,11 +2,6 @@
This directory contains artifacts used for testing.
## firefox.zip
This is a sample build artifact containing a "Firefox executable" (an empty
file) used for mocking Taskcluster responses.
## profile.zip
This file is a sample profile containing some files present in Firefox

Двоичные данные
test/firefox.zip

Двоичный файл не отображается.