servo: Merge #3365 - Try to parse command line argument as file names (from SimonSapin:command-line-argument-filenames)
authorSimon Sapin <simon.sapin@exyr.org>
Tue, 16 Sep 2014 20:32:40 +0100
changeset 381573 8f231a41eacaa626fb72b42b56d5896215e590bf
parent 381572 8c042dda59c243fe849722f483cebd8973370ba4
child 381574 a9ae7a73622bec92653a2e38ef0f9288269bb035
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
servo: Merge #3365 - Try to parse command line argument as file names (from SimonSapin:command-line-argument-filenames) Source-Repo: https://github.com/servo/servo Source-Revision: 14f7d2dabdbe63f7728cb4ed6fa6a012d7de2cec
servo/Cargo.lock
servo/Cargo.toml
servo/src/lib.rs
servo/tests/reftest.rs
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -3,16 +3,17 @@ name = "servo"
 version = "0.0.1"
 dependencies = [
  "compositing 0.0.1",
  "gfx 0.0.1",
  "layout 0.0.1",
  "msg 0.0.1",
  "net 0.0.1",
  "script 0.0.1",
+ "url 0.1.0 (git+https://github.com/servo/rust-url#678bb4d52638b1cfdab78ef8e521566c9240fb1a)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "alert"
 version = "0.1.0"
 source = "git+https://github.com/servo/rust-alert#fdc24f13be8d8a2d15214ec228d166b3221b809e"
 dependencies = [
--- a/servo/Cargo.toml
+++ b/servo/Cargo.toml
@@ -40,8 +40,11 @@ path = "components/util"
 [dependencies.script]
 path = "components/script"
 
 [dependencies.layout]
 path = "components/layout"
 
 [dependencies.gfx]
 path = "components/gfx"
+
+[dependencies.url]
+git = "https://github.com/servo/rust-url"
--- a/servo/src/lib.rs
+++ b/servo/src/lib.rs
@@ -52,18 +52,16 @@ use servo_util::opts;
 #[cfg(not(test))]
 use green::GreenTaskBuilder;
 #[cfg(not(test))]
 use std::os;
 #[cfg(not(test))]
 use std::task::TaskBuilder;
 #[cfg(not(test), target_os="android")]
 use std::string;
-#[cfg(not(test))]
-use url::{Url, UrlParser};
 
 #[cfg(not(test), target_os="android")]
 #[no_mangle]
 #[allow(dead_code)]
 pub extern "C" fn android_start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, proc() {
         let mut args: Vec<String> = vec!();
         for i in range(0u, argc as uint) {
@@ -120,22 +118,25 @@ pub fn run(opts: opts::Opts) {
                                                  script::script_task::ScriptTask>::start(
                                                       compositor_chan,
                                                       opts,
                                                       resource_task,
                                                       image_cache_task,
                                                       font_cache_task,
                                                       time_profiler_chan_clone);
 
-        let base_url = Url::from_directory_path(&os::getcwd()).unwrap();
-        let mut url_parser = UrlParser::new();
-        let url_parser = url_parser.base_url(&base_url);
         // Send the URL command to the constellation.
-        for url in opts.urls.iter() {
-            let url = url_parser.parse(url.as_slice()).ok().expect("URL parsing failed");
+        let cwd = os::getcwd();
+        for &url in opts.urls.iter() {
+            let url = match url::Url::parse(url.as_slice()) {
+                Ok(url) => url,
+                Err(url::RelativeUrlWithoutBase)
+                => url::Url::from_file_path(&cwd.join(url)).unwrap(),
+                Err(_) => fail!("URL parsing failed"),
+            };
 
             let ConstellationChan(ref chan) = constellation_chan;
             chan.send(InitLoadUrlMsg(url));
         }
 
         // Send the constallation Chan as the result
         result_chan.send(constellation_chan);
     });
--- a/servo/tests/reftest.rs
+++ b/servo/tests/reftest.rs
@@ -8,25 +8,28 @@
 // except according to those terms.
 
 #![deny(unused_imports, unused_variable)]
 
 extern crate png;
 extern crate std;
 extern crate test;
 extern crate regex;
+extern crate url;
 
 use std::ascii::StrAsciiExt;
 use std::io;
 use std::io::{File, Reader, Command};
 use std::io::process::ExitStatus;
 use std::os;
+use std::path::Path;
 use test::{AutoColor, DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn};
 use test::run_tests_console;
 use regex::Regex;
+use url::Url;
 
 
 bitflags!(
     flags RenderMode: u32 {
         static CpuRendering  = 0x00000001,
         static GpuRendering  = 0x00000010,
         static LinuxTarget   = 0x00000100,
         static MacOsTarget   = 0x00001000,
@@ -66,19 +69,18 @@ fn main() {
     let mut all_tests = vec!();
     println!("Scanning {} for manifests\n", base_path);
 
     for file in io::fs::walk_dir(&Path::new(base_path.as_slice())).unwrap() {
         let maybe_extension = file.extension_str();
         match maybe_extension {
             Some(extension) => {
                 if extension.to_ascii_lower().as_slice() == "list" && file.is_file() {
-                    let manifest = file.as_str().unwrap();
-                    let tests = parse_lists(manifest, servo_args, render_mode, all_tests.len());
-                    println!("\t{} [{} tests]", manifest, tests.len());
+                    let tests = parse_lists(&file, servo_args, render_mode, all_tests.len());
+                    println!("\t{} [{} tests]", file.display(), tests.len());
                     all_tests.push_all_move(tests);
                 }
             }
             _ => {}
         }
     }
 
     let test_opts = TestOpts {
@@ -106,35 +108,35 @@ fn main() {
 enum ReftestKind {
     Same,
     Different,
 }
 
 struct Reftest {
     name: String,
     kind: ReftestKind,
-    files: [String, ..2],
+    files: [Path, ..2],
     id: uint,
     servo_args: Vec<String>,
     render_mode: RenderMode,
     is_flaky: bool,
     experimental: bool,
+    fragment_identifier: Option<String>,
 }
 
 struct TestLine<'a> {
     conditions: &'a str,
     kind: &'a str,
     file_left: &'a str,
     file_right: &'a str,
 }
 
-fn parse_lists(file: &str, servo_args: &[String], render_mode: RenderMode, id_offset: uint) -> Vec<TestDescAndFn> {
+fn parse_lists(file: &Path, servo_args: &[String], render_mode: RenderMode, id_offset: uint) -> Vec<TestDescAndFn> {
     let mut tests = Vec::new();
-    let file_path = Path::new(file);
-    let contents = File::open_mode(&file_path, io::Open, io::Read)
+    let contents = File::open_mode(file, io::Open, io::Read)
                        .and_then(|mut f| f.read_to_string())
                        .ok().expect("Could not read file");
 
     for line in contents.as_slice().lines() {
         // ignore comments or empty lines
         if line.starts_with("#") || line.is_empty() {
             continue;
         }
@@ -157,44 +159,48 @@ fn parse_lists(file: &str, servo_args: &
             _ => fail!("reftest line: '{:s}' doesn't match '[CONDITIONS] KIND LEFT RIGHT'", line),
         };
 
         let kind = match test_line.kind {
             "==" => Same,
             "!=" => Different,
             part => fail!("reftest line: '{:s}' has invalid kind '{:s}'", line, part)
         };
-        let src_path = file_path.dir_path();
-        let src_dir = src_path.display().to_string();
-        let file_left =  src_dir.clone().append("/").append(test_line.file_left);
-        let file_right = src_dir.append("/").append(test_line.file_right);
+        let base = file.dir_path();
+        let file_left =  base.join(test_line.file_left);
+        let file_right = base.join(test_line.file_right);
 
         let mut conditions_list = test_line.conditions.split(',');
         let mut flakiness = RenderMode::empty();
         let mut experimental = false;
+        let mut fragment_identifier = None;
         for condition in conditions_list {
             match condition {
                 "flaky_cpu" => flakiness.insert(CpuRendering),
                 "flaky_gpu" => flakiness.insert(GpuRendering),
                 "flaky_linux" => flakiness.insert(LinuxTarget),
                 "flaky_macos" => flakiness.insert(MacOsTarget),
                 "experimental" => experimental = true,
                 _ => (),
             }
+            if condition.starts_with("fragment=") {
+                fragment_identifier = Some(condition.slice_from("fragment=".len()).to_string());
+            }
         }
 
         let reftest = Reftest {
             name: format!("{} {} {}", test_line.file_left, test_line.kind, test_line.file_right),
             kind: kind,
             files: [file_left, file_right],
             id: id_offset + tests.len(),
             render_mode: render_mode,
             servo_args: servo_args.iter().map(|x| x.clone()).collect(),
             is_flaky: render_mode.intersects(flakiness),
             experimental: experimental,
+            fragment_identifier: fragment_identifier,
         };
 
         tests.push(make_test(reftest));
     }
     tests
 }
 
 fn make_test(reftest: Reftest) -> TestDescAndFn {
@@ -207,37 +213,43 @@ fn make_test(reftest: Reftest) -> TestDe
         },
         testfn: DynTestFn(proc() {
             check_reftest(reftest);
         }),
     }
 }
 
 fn capture(reftest: &Reftest, side: uint) -> (u32, u32, Vec<u8>) {
-    let filename = format!("/tmp/servo-reftest-{:06u}-{:u}.png", reftest.id, side);
-    let mut args = reftest.servo_args.clone();
+    let png_filename = format!("/tmp/servo-reftest-{:06u}-{:u}.png", reftest.id, side);
+    let mut command = Command::new("target/servo");
+    command
+        .args(reftest.servo_args.as_slice())
+        // Allows pixel perfect rendering of Ahem font for reftests.
+        .arg("--disable-text-aa")
+        .args(["-f", "-o"])
+        .arg(png_filename.as_slice())
+        .arg({
+            let mut url = Url::from_file_path(&reftest.files[side]).unwrap();
+            url.fragment = reftest.fragment_identifier.clone();
+            url.to_string()
+        });
     // GPU rendering is the default
     if reftest.render_mode.contains(CpuRendering) {
-        args.push("-c".to_string());
+        command.arg("-c");
     }
     if reftest.experimental {
-        args.push("--experimental".to_string());
+        command.arg("--experimental");
     }
-    // Allows pixel perfect rendering of Ahem font for reftests.
-    args.push("--disable-text-aa".to_string());
-    args.push_all(["-f".to_string(), "-o".to_string(), filename.clone(),
-                   reftest.files[side].clone()]);
-
-    let retval = match Command::new("target/servo").args(args.as_slice()).status() {
+    let retval = match command.status() {
         Ok(status) => status,
         Err(e) => fail!("failed to execute process: {}", e),
     };
     assert!(retval == ExitStatus(0));
 
-    let image = png::load_png(&from_str::<Path>(filename.as_slice()).unwrap()).unwrap();
+    let image = png::load_png(&from_str::<Path>(png_filename.as_slice()).unwrap()).unwrap();
     let rgba8_bytes = match image.pixels {
         png::RGBA8(pixels) => pixels,
         _ => fail!(),
     };
     (image.width, image.height, rgba8_bytes)
 }
 
 fn check_reftest(reftest: Reftest) {