Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve folder name for persistent doc tests #69458

Merged
merged 1 commit into from
Mar 31, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 63 additions & 40 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rustc_span::source_map::SourceMap;
use rustc_span::symbol::sym;
use rustc_span::{BytePos, FileName, Pos, Span, DUMMY_SP};
use rustc_target::spec::TargetTriple;
use std::collections::HashMap;
use std::env;
use std::io::{self, Write};
use std::panic;
Expand Down Expand Up @@ -190,10 +191,23 @@ enum TestFailure {
UnexpectedRunPass,
}

enum DirState {
Temp(tempfile::TempDir),
Perm(PathBuf),
}

impl DirState {
fn path(&self) -> &std::path::Path {
match self {
DirState::Temp(t) => t.path(),
DirState::Perm(p) => p.as_path(),
}
}
}

fn run_test(
test: &str,
cratename: &str,
filename: &FileName,
line: usize,
options: Options,
should_panic: bool,
Expand All @@ -206,47 +220,11 @@ fn run_test(
mut error_codes: Vec<String>,
opts: &TestOptions,
edition: Edition,
outdir: DirState,
path: PathBuf,
) -> Result<(), TestFailure> {
let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts, edition);

// FIXME(#44940): if doctests ever support path remapping, then this filename
// needs to be the result of `SourceMap::span_to_unmapped_path`.
let path = match filename {
FileName::Real(path) => path.clone(),
_ => PathBuf::from(r"doctest.rs"),
};

enum DirState {
Temp(tempfile::TempDir),
Perm(PathBuf),
}

impl DirState {
fn path(&self) -> &std::path::Path {
match self {
DirState::Temp(t) => t.path(),
DirState::Perm(p) => p.as_path(),
}
}
}

let outdir = if let Some(mut path) = options.persist_doctests {
path.push(format!(
"{}_{}",
filename.to_string().rsplit('/').next().unwrap().replace(".", "_"),
line
));
std::fs::create_dir_all(&path).expect("Couldn't create directory for doctest executables");

DirState::Perm(path)
} else {
DirState::Temp(
TempFileBuilder::new()
.prefix("rustdoctest")
.tempdir()
.expect("rustdoc needs a tempdir"),
)
};
let output_file = outdir.path().join("rust_out");

let rustc_binary = options
Expand Down Expand Up @@ -639,6 +617,7 @@ pub struct Collector {
position: Span,
source_map: Option<Lrc<SourceMap>>,
filename: Option<PathBuf>,
visited_tests: HashMap<(String, usize), usize>,
}

impl Collector {
Expand All @@ -662,6 +641,7 @@ impl Collector {
position: DUMMY_SP,
source_map,
filename,
visited_tests: HashMap::new(),
}
}

Expand Down Expand Up @@ -705,6 +685,48 @@ impl Tester for Collector {
let target = self.options.target.clone();
let target_str = target.to_string();

// FIXME(#44940): if doctests ever support path remapping, then this filename
// needs to be the result of `SourceMap::span_to_unmapped_path`.
let path = match &filename {
FileName::Real(path) => path.clone(),
_ => PathBuf::from(r"doctest.rs"),
};

let outdir = if let Some(mut path) = options.persist_doctests.clone() {
// For example `module/file.rs` would become `module_file_rs`
let folder_name = filename
.to_string()
.chars()
.map(|c| if c == '/' || c == '.' { '_' } else { c })
.collect::<String>();

path.push(format!(
"{name}_{line}_{number}",
name = folder_name,
number = {
// Increases the current test number, if this file already
// exists or it creates a new entry with a test number of 0.
self.visited_tests
.entry((folder_name.clone(), line))
.and_modify(|v| *v += 1)
.or_insert(0)
},
line = line,
));

std::fs::create_dir_all(&path)
.expect("Couldn't create directory for doctest executables");

DirState::Perm(path)
} else {
DirState::Temp(
TempFileBuilder::new()
.prefix("rustdoctest")
.tempdir()
.expect("rustdoc needs a tempdir"),
)
};

debug!("creating test {}: {}", name, test);
self.tests.push(testing::TestDescAndFn {
desc: testing::TestDesc {
Expand All @@ -723,7 +745,6 @@ impl Tester for Collector {
let res = run_test(
&test,
&cratename,
&filename,
line,
options,
config.should_panic,
Expand All @@ -736,6 +757,8 @@ impl Tester for Collector {
config.error_codes,
&opts,
edition,
outdir,
path,
);

if let Err(err) = res {
Expand Down