Skip to content

Commit 388d1d5

Browse files
authored
Merge pull request #645 from TimNN/telemetry-huge
Support Telemetry with lots of output
2 parents 5a9553a + 9e1f219 commit 388d1d5

File tree

9 files changed

+106
-18
lines changed

9 files changed

+106
-18
lines changed

Cargo.lock

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ term = "0.4.4"
4040
itertools = "0.4.1"
4141
time = "0.1.34"
4242
tempdir = "0.3.4"
43+
tempfile = "2.1.4"
4344
libc = "0.2.0"
4445
rand = "0.3.11"
4546
scopeguard = "0.1.2"

src/rustup-mock/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ tar = "0.4.0"
2121
toml = "0.1.27"
2222
rustup-utils = { path = "../rustup-utils", version = "0.5.0" }
2323
sha2 = "0.1.2"
24+
wait-timeout = "0.1.3"
2425

2526
[target."cfg(windows)".dependencies]
2627
winapi = "0.2.8"

src/rustup-mock/src/clitools.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@
33
44
use std::path::{PathBuf, Path};
55
use std::env;
6-
use std::process::Command;
6+
use std::process::{Command, Stdio};
77
use std::env::consts::EXE_SUFFIX;
88
use std::fs::{self, File};
99
use std::io::{self, Read, Write};
1010
use std::sync::Mutex;
11+
use std::time::Duration;
1112
use tempdir::TempDir;
1213
use {MockInstallerBuilder, MockCommand};
1314
use dist::{MockDistServer, MockChannel, MockPackage,
1415
MockTargettedPackage, MockComponent, change_channel_date,
1516
ManifestVersion};
1617
use url::Url;
1718
use scopeguard;
19+
use wait_timeout::ChildExt;
1820

1921
/// The configuration used by the tests in this module
2022
pub struct Config {
@@ -218,6 +220,24 @@ pub fn expect_err_ex(config: &Config, args: &[&str],
218220
assert!(out.stderr == stderr, format!("err {:?}", args));
219221
}
220222

223+
pub fn expect_timeout_ok(config: &Config, timeout: Duration, args: &[&str]) {
224+
let mut child = cmd(config, args[0], &args[1..])
225+
.stdout(Stdio::null())
226+
.stderr(Stdio::null())
227+
.spawn().unwrap();
228+
229+
match child.wait_timeout(timeout).unwrap() {
230+
Some(status) => {
231+
assert!(status.success(), "not ok {:?}", args);
232+
}
233+
None => {
234+
// child hasn't exited yet
235+
child.kill().unwrap();
236+
panic!("command timed out: {:?}", args);
237+
}
238+
}
239+
}
240+
221241
#[derive(Debug)]
222242
pub struct SanitizedOutput {
223243
pub ok: bool,
@@ -545,18 +565,10 @@ fn mock_bin(_name: &str, version: &str, version_hash: &str) -> Vec<u8> {
545565
let ref dest_path = tempdir.path().join(&format!("out{}", EXE_SUFFIX));
546566

547567
// Write the source
548-
let ref source = format!(r#"
549-
fn main() {{
550-
let args: Vec<_> = ::std::env::args().collect();
551-
if args.get(1) == Some(&"--version".to_string()) {{
552-
println!("{} ({})");
553-
}} else if args.get(1) == Some(&"--empty-arg-test".to_string()) {{
554-
assert!(args.get(2) == Some(&"".to_string()));
555-
}} else {{
556-
panic!("bad mock proxy commandline");
557-
}}
558-
}}
559-
"#, EXAMPLE_VERSION, EXAMPLE_VERSION_HASH);
568+
let source = include_str!("mock_bin_src.rs")
569+
.replace("%EXAMPLE_VERSION%", EXAMPLE_VERSION)
570+
.replace("%EXAMPLE_VERSION_HASH%", EXAMPLE_VERSION_HASH);
571+
560572
File::create(source_path).and_then(|mut f| f.write_all(source.as_bytes())).unwrap();
561573

562574
// Create the executable

src/rustup-mock/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ extern crate tar;
1212
extern crate toml;
1313
extern crate rustup_utils;
1414
extern crate sha2;
15+
extern crate wait_timeout;
1516

1617
#[cfg(windows)]
1718
extern crate winapi;

src/rustup-mock/src/mock_bin_src.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use std::io::{self, BufWriter, Write};
2+
3+
fn main() {
4+
let args: Vec<_> = ::std::env::args().collect();
5+
if args.get(1) == Some(&"--version".to_string()) {
6+
println!("%EXAMPLE_VERSION% (%EXAMPLE_VERSION_HASH%)");
7+
} else if args.get(1) == Some(&"--empty-arg-test".to_string()) {
8+
assert!(args.get(2) == Some(&"".to_string()));
9+
} else if args.get(1) == Some(&"--huge-output".to_string()) {
10+
let out = io::stderr();
11+
let lock = out.lock();
12+
let mut buf = BufWriter::new(lock);
13+
for _ in 0 .. 10000 {
14+
buf.write_all(b"error: a value named `fail` has already been defined in this module [E0428]\n").unwrap();
15+
}
16+
} else {
17+
panic!("bad mock proxy commandline");
18+
}
19+
}

src/rustup/command.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use std::env;
22
use std::ffi::OsStr;
3-
use std::io::{self, Write, BufRead, BufReader};
3+
use std::fs::File;
4+
use std::io::{self, Write, BufRead, BufReader, Seek, SeekFrom};
45
use std::path::PathBuf;
56
use std::process::{self, Command, Stdio};
67
use std::time::Instant;
78
use regex::Regex;
9+
use tempfile::tempfile;
810

911
use Cfg;
1012
use errors::*;
@@ -29,6 +31,18 @@ pub fn run_command_for_dir<S: AsRef<OsStr>>(cmd: Command,
2931
}
3032

3133
fn telemetry_rustc<S: AsRef<OsStr>>(mut cmd: Command, args: &[S], cfg: &Cfg) -> Result<()> {
34+
#[cfg(unix)]
35+
fn file_as_stdio(file: &File) -> Stdio {
36+
use std::os::unix::io::{AsRawFd, FromRawFd};
37+
unsafe { Stdio::from_raw_fd(file.as_raw_fd()) }
38+
}
39+
40+
#[cfg(windows)]
41+
fn file_as_stdio(file: &File) -> Stdio {
42+
use std::os::windows::io::{AsRawHandle, FromRawHandle};
43+
unsafe { Stdio::from_raw_handle(file.as_raw_handle()) }
44+
}
45+
3246
let now = Instant::now();
3347

3448
cmd.args(&args[1..]);
@@ -44,15 +58,17 @@ fn telemetry_rustc<S: AsRef<OsStr>>(mut cmd: Command, args: &[S], cfg: &Cfg) ->
4458
cmd.arg("always");
4559
}
4660

61+
let mut cmd_err_file = tempfile().unwrap();
62+
let cmd_err_stdio = file_as_stdio(&cmd_err_file);
63+
4764
// FIXME rust-lang/rust#32254. It's not clear to me
4865
// when and why this is needed.
4966
let mut cmd = cmd.stdin(Stdio::inherit())
5067
.stdout(Stdio::inherit())
51-
.stderr(Stdio::piped())
68+
.stderr(cmd_err_stdio)
5269
.spawn()
5370
.unwrap();
5471

55-
let mut buffered_stderr = BufReader::new(cmd.stderr.take().unwrap());
5672
let status = cmd.wait();
5773

5874
let duration = now.elapsed();
@@ -75,6 +91,10 @@ fn telemetry_rustc<S: AsRef<OsStr>>(mut cmd: Command, args: &[S], cfg: &Cfg) ->
7591
let stderr = io::stderr();
7692
let mut handle = stderr.lock();
7793

94+
cmd_err_file.seek(SeekFrom::Start(0)).unwrap();
95+
96+
let mut buffered_stderr = BufReader::new(cmd_err_file);
97+
7898
while buffered_stderr.read_line(&mut buffer).unwrap() > 0 {
7999
let b = buffer.to_owned();
80100
buffer.clear();

src/rustup/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern crate url;
99
extern crate regex;
1010
extern crate itertools;
1111
extern crate rustc_serialize;
12+
extern crate tempfile;
1213
extern crate time;
1314
extern crate toml;
1415
#[cfg(unix)]

tests/cli-misc.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ extern crate rustup_mock;
77
extern crate time;
88
use rustup_mock::clitools::{self, Config, Scenario,
99
expect_stdout_ok, expect_stderr_ok,
10-
expect_ok, expect_err, run,
11-
this_host_triple};
10+
expect_ok, expect_err, expect_timeout_ok,
11+
run, this_host_triple};
1212
use rustup_utils::{raw, utils};
1313

1414
use time::Duration;
1515
use std::ops::Sub;
1616
use std::ops::Add;
17+
use std::time::Duration as StdDuration;
1718

1819
macro_rules! for_host { ($s: expr) => (&format!($s, this_host_triple())) }
1920

@@ -334,6 +335,16 @@ fn enabling_telemetry_and_compiling_creates_log() {
334335
});
335336
}
336337

338+
#[test]
339+
fn telemetry_supports_huge_output() {
340+
setup(&|config| {
341+
expect_ok(config, &["rustup", "default", "stable"]);
342+
expect_ok(config, &["rustup", "telemetry", "enable"]);
343+
expect_timeout_ok(&config, StdDuration::from_secs(5), &["rustc", "--huge-output"]);
344+
expect_stdout_ok(config, &["rustup", "telemetry", "analyze"], "'E0428': 10000")
345+
})
346+
}
347+
337348
#[test]
338349
fn telemetry_cleanup_removes_old_files() {
339350
setup(&|config| {

0 commit comments

Comments
 (0)