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

Fix a bug in the linkchecker #86156

Merged
merged 4 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
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
5 changes: 5 additions & 0 deletions src/bootstrap/builder/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,9 +613,14 @@ mod dist {
// Note that the stages here are +1 than what they actually are because
// Rustdoc::run swaps out the compiler with stage minus 1 if --stage is
// not 0.
//
// The stage 0 copy is the one downloaded for bootstrapping. It is
// (currently) needed to run "cargo test" on the linkchecker, and
// should be relatively "free".
assert_eq!(
first(builder.cache.all::<tool::Rustdoc>()),
&[
tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },
tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },
]
Expand Down
17 changes: 17 additions & 0 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,25 @@ You can skip linkcheck with --exclude src/tools/linkchecker"

builder.info(&format!("Linkcheck ({})", host));

// Test the linkchecker itself.
let bootstrap_host = builder.config.build;
let compiler = builder.compiler(0, bootstrap_host);
let cargo = tool::prepare_tool_cargo(
builder,
compiler,
Mode::ToolBootstrap,
bootstrap_host,
"test",
"src/tools/linkchecker",
SourceType::InTree,
&[],
);
try_run(builder, &mut cargo.into());

// Build all the default documentation.
builder.default_doc(&[]);

// Run the linkchecker.
let _time = util::timeit(&builder);
try_run(
builder,
Expand Down
2 changes: 1 addition & 1 deletion src/tools/linkchecker/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ impl Checker {
} else {
report.errors += 1;
print!("{}:{}: broken link fragment ", pretty_path, i + 1);
println!("`#{}` pointing to `{}`", fragment, pretty_path);
println!("`#{}` pointing to `{}`", fragment, target_pretty_path);
};
}
});
Expand Down
1 change: 1 addition & 0 deletions src/tools/linkchecker/tests/broken_redir/redir-bad.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=sometarget">
<title>Redirection</title>
</head>
<body>
<p>Redirecting to <a href="sometarget">sometarget</a>...</p>
Expand Down
50 changes: 43 additions & 7 deletions src/tools/linkchecker/tests/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn run(dirname: &str) -> (ExitStatus, String, String) {
fn broken_test(dirname: &str, expected: &str) {
let (status, stdout, stderr) = run(dirname);
assert!(!status.success());
if !stdout.contains(expected) {
if !contains(expected, &stdout) {
panic!(
"stdout did not contain expected text: {}\n\
--- stdout:\n\
Expand All @@ -27,6 +27,25 @@ fn broken_test(dirname: &str, expected: &str) {
}
}

fn contains(expected: &str, actual: &str) -> bool {
// Normalize for Windows paths.
let actual = actual.replace('\\', "/");
actual.lines().any(|mut line| {
for (i, part) in expected.split("[..]").enumerate() {
match line.find(part) {
Some(j) => {
if i == 0 && j != 0 {
return false;
}
line = &line[j + part.len()..];
}
None => return false,
}
}
line.is_empty() || expected.ends_with("[..]")
})
}

fn valid_test(dirname: &str) {
let (status, stdout, stderr) = run(dirname);
if !status.success() {
Expand All @@ -48,30 +67,47 @@ fn valid() {

#[test]
fn basic_broken() {
broken_test("basic_broken", "bar.html");
broken_test("basic_broken", "foo.html:3: broken link - `bar.html`");
}

#[test]
fn broken_fragment_local() {
broken_test("broken_fragment_local", "#somefrag");
broken_test(
"broken_fragment_local",
"foo.html:3: broken link fragment `#somefrag` pointing to `foo.html`",
);
}

#[test]
fn broken_fragment_remote() {
broken_test("broken_fragment_remote/inner", "#somefrag");
broken_test(
"broken_fragment_remote/inner",
"foo.html:3: broken link fragment `#somefrag` pointing to \
`[..]/broken_fragment_remote/bar.html`",
);
}

#[test]
fn broken_redir() {
broken_test("broken_redir", "sometarget");
broken_test(
"broken_redir",
"foo.html:3: broken redirect from `redir-bad.html` to `sometarget`",
);
}

#[test]
fn directory_link() {
broken_test("directory_link", "somedir");
broken_test(
"directory_link",
"foo.html:3: directory link to `somedir` (directory links should use index.html instead)",
);
}

#[test]
fn redirect_loop() {
broken_test("redirect_loop", "redir-bad.html");
broken_test(
"redirect_loop",
"foo.html:3: redirect from `redir-bad.html` to `[..]redirect_loop/redir-bad.html` \
which is also a redirect (not supported)",
);
}
1 change: 1 addition & 0 deletions src/tools/linkchecker/tests/redirect_loop/redir-bad.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=redir-bad.html">
<title>Redirection</title>
</head>
<body>
<p>Redirecting to <a href="redir-bad.html">redir-bad.html</a>...</p>
Expand Down
1 change: 1 addition & 0 deletions src/tools/linkchecker/tests/valid/inner/redir-bad.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=xxx">
<title>Redirection</title>
</head>
<body>
<p>Redirecting to <a href="xxx">xxx</a>...</p>
Expand Down
1 change: 1 addition & 0 deletions src/tools/linkchecker/tests/valid/inner/redir.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=redir-target.html">
<title>Redirection</title>
</head>
<body>
<p>Redirecting to <a href="redir-target.html">redir-target.html</a>...</p>
Expand Down