Skip to content

Commit

Permalink
Remove --test-threads=1
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Jan 19, 2021
1 parent 4f5eaa1 commit c317eeb
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 148 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ jobs:
- uses: taiki-e/github-actions/install-rust@main
with:
toolchain: stable
# --test-threads=1 is required due to toolchain installation conflicts.
- run: CARGO_HACK_TEST_TOOLCHAIN=${{ matrix.rust }} cargo test --all -- --test-threads=1
- run: CARGO_HACK_TEST_TOOLCHAIN=${{ matrix.rust }} cargo test --all

build:
strategy:
Expand Down
186 changes: 98 additions & 88 deletions tests/auxiliary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use easy_ext::ext;
use once_cell::sync::Lazy;
use path::PathBuf;
use std::{
cmp, env,
env,
ffi::OsStr,
path::{self, Path},
process::{Command, ExitStatus},
Expand All @@ -18,36 +18,28 @@ pub fn cargo_bin_exe() -> Command {
Command::new(env!("CARGO_BIN_EXE_cargo-hack"))
}

fn test_versions(range_start: Option<u32>) -> String {
if let Some(toolchain) = test_toolchain(range_start) {
format!(" +1.{}", toolchain)
} else {
String::new()
}
fn test_toolchain() -> String {
if let Some(toolchain) = test_version() { format!(" +1.{}", toolchain) } else { String::new() }
}

fn test_toolchain(range_start: Option<u32>) -> Option<u32> {
static TEST_TOOLCHAIN: Lazy<Option<u32>> = Lazy::new(|| {
env::var_os("CARGO_HACK_TEST_TOOLCHAIN").map(|s| s.to_string_lossy().parse().unwrap())
fn test_version() -> Option<u32> {
static TEST_VERSION: Lazy<Option<u32>> = Lazy::new(|| {
let toolchain =
env::var_os("CARGO_HACK_TEST_TOOLCHAIN")?.to_string_lossy().parse().unwrap();
// Install toolchain first to avoid toolchain installation conflicts.
let _ = Command::new("rustup")
.args(&["toolchain", "install", &format!("1.{}", toolchain), "--no-self-update"])
.output();
Some(toolchain)
});
TEST_TOOLCHAIN.map(|toolchain| {
if let Some(range_start) = range_start {
cmp::max(range_start, toolchain)
} else {
toolchain
}
})
*TEST_VERSION
}

pub fn cargo_hack<O: AsRef<OsStr>>(args: impl AsRef<[O]>) -> Command {
cargo_hack2(args, None)
}

pub fn cargo_hack2<O: AsRef<OsStr>>(args: impl AsRef<[O]>, range_start: Option<u32>) -> Command {
let args = args.as_ref();
let mut cmd = cargo_bin_exe();
cmd.arg("hack");
if let Some(toolchain) = test_toolchain(range_start) {
if let Some(toolchain) = test_version() {
if !args.iter().any(|a| a.as_ref().to_str().unwrap().starts_with("--version-range")) {
cmd.arg(format!("--version-range=1.{0}..1.{0}", toolchain));
}
Expand All @@ -59,18 +51,23 @@ pub fn cargo_hack2<O: AsRef<OsStr>>(args: impl AsRef<[O]>, range_start: Option<u
#[ext(CommandExt)]
impl Command {
#[track_caller]
pub fn assert_output(&mut self, test_model: &str, range_start: Option<u32>) -> AssertOutput {
pub fn assert_output(&mut self, test_model: &str, require: Option<u32>) -> AssertOutput {
match (test_version(), require) {
(Some(toolchain), Some(require)) if require > toolchain => {
return AssertOutput(None);
}
_ => {}
}
let (_test_project, cur_dir) = test_project(test_model).unwrap();
let output = self
.current_dir(cur_dir)
.output()
.unwrap_or_else(|e| panic!("could not execute process: {}", e));
AssertOutput {
AssertOutput(Some(AssertOutputInner {
stdout: String::from_utf8_lossy(&output.stdout).into_owned(),
stderr: String::from_utf8_lossy(&output.stderr).into_owned(),
status: output.status,
range_start,
}
}))
}

#[track_caller]
Expand All @@ -79,15 +76,17 @@ impl Command {
}

#[track_caller]
pub fn assert_success2(&mut self, test_model: &str, range_start: Option<u32>) -> AssertOutput {
let output = self.assert_output(test_model, range_start);
if !output.status.success() {
panic!(
"assertion failed: `self.status.success()`:\n\nSTDOUT:\n{0}\n{1}\n{0}\n\nSTDERR:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
output.stdout,
output.stderr,
)
pub fn assert_success2(&mut self, test_model: &str, require: Option<u32>) -> AssertOutput {
let output = self.assert_output(test_model, require);
if let Some(output) = &output.0 {
if !output.status.success() {
panic!(
"assertion failed: `self.status.success()`:\n\nSTDOUT:\n{0}\n{1}\n{0}\n\nSTDERR:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
output.stdout,
output.stderr,
)
}
}
output
}
Expand All @@ -98,33 +97,36 @@ impl Command {
}

#[track_caller]
pub fn assert_failure2(&mut self, test_model: &str, range_start: Option<u32>) -> AssertOutput {
let output = self.assert_output(test_model, range_start);
if output.status.success() {
panic!(
"assertion failed: `!self.status.success()`:\n\nSTDOUT:\n{0}\n{1}\n{0}\n\nSTDERR:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
output.stdout,
output.stderr,
)
pub fn assert_failure2(&mut self, test_model: &str, require: Option<u32>) -> AssertOutput {
let output = self.assert_output(test_model, require);
if let Some(output) = &output.0 {
if output.status.success() {
panic!(
"assertion failed: `!self.status.success()`:\n\nSTDOUT:\n{0}\n{1}\n{0}\n\nSTDERR:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
output.stdout,
output.stderr,
)
}
}
output
}
}

pub struct AssertOutput {
pub struct AssertOutput(Option<AssertOutputInner>);

struct AssertOutputInner {
stdout: String,
stderr: String,
status: ExitStatus,
range_start: Option<u32>,
}

#[track_caller]
fn line_separated(lines: &str, test_versions: &str, f: impl FnMut(&str)) {
fn line_separated(lines: &str, f: impl FnMut(&str)) {
let lines = if lines.contains("`cargo +") {
lines.to_string()
} else {
lines.replace("`cargo", &format!("`cargo{}", test_versions))
lines.replace("`cargo", &format!("`cargo{}", test_toolchain()))
};
lines.split('\n').map(str::trim).filter(|line| !line.is_empty()).for_each(f);
}
Expand All @@ -133,64 +135,72 @@ impl AssertOutput {
/// Receives a line(`\n`)-separated list of patterns and asserts whether stderr contains each pattern.
#[track_caller]
pub fn stderr_contains(&self, pats: impl AsRef<str>) -> &Self {
line_separated(pats.as_ref(), &test_versions(self.range_start), |pat| {
if !self.stderr.contains(pat) {
panic!(
"assertion failed: `self.stderr.contains(..)`:\n\nEXPECTED:\n{0}\n{1}\n{0}\n\nACTUAL:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
pat,
self.stderr
)
}
});
if let Some(output) = &self.0 {
line_separated(pats.as_ref(), |pat| {
if !output.stderr.contains(pat) {
panic!(
"assertion failed: `self.stderr.contains(..)`:\n\nEXPECTED:\n{0}\n{1}\n{0}\n\nACTUAL:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
pat,
output.stderr
)
}
});
}
self
}

/// Receives a line(`\n`)-separated list of patterns and asserts whether stdout contains each pattern.
#[track_caller]
pub fn stderr_not_contains(&self, pats: impl AsRef<str>) -> &Self {
line_separated(pats.as_ref(), &test_versions(self.range_start), |pat| {
if self.stderr.contains(pat) {
panic!(
"assertion failed: `!self.stderr.contains(..)`:\n\nEXPECTED:\n{0}\n{1}\n{0}\n\nACTUAL:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
pat,
self.stderr
)
}
});
if let Some(output) = &self.0 {
line_separated(pats.as_ref(), |pat| {
if output.stderr.contains(pat) {
panic!(
"assertion failed: `!self.stderr.contains(..)`:\n\nEXPECTED:\n{0}\n{1}\n{0}\n\nACTUAL:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
pat,
output.stderr
)
}
});
}
self
}

/// Receives a line(`\n`)-separated list of patterns and asserts whether stdout contains each pattern.
#[track_caller]
pub fn stdout_contains(&self, pats: impl AsRef<str>) -> &Self {
line_separated(pats.as_ref(), &test_versions(self.range_start), |pat| {
if !self.stdout.contains(pat) {
panic!(
"assertion failed: `self.stdout.contains(..)`:\n\nEXPECTED:\n{0}\n{1}\n{0}\n\nACTUAL:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
pat,
self.stdout
)
}
});
if let Some(output) = &self.0 {
line_separated(pats.as_ref(), |pat| {
if !output.stdout.contains(pat) {
panic!(
"assertion failed: `self.stdout.contains(..)`:\n\nEXPECTED:\n{0}\n{1}\n{0}\n\nACTUAL:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
pat,
output.stdout
)
}
});
}
self
}

/// Receives a line(`\n`)-separated list of patterns and asserts whether stdout contains each pattern.
#[track_caller]
pub fn stdout_not_contains(&self, pats: impl AsRef<str>) -> &Self {
line_separated(pats.as_ref(), &test_versions(self.range_start), |pat| {
if self.stdout.contains(pat) {
panic!(
"assertion failed: `!self.stdout.contains(..)`:\n\nEXPECTED:\n{0}\n{1}\n{0}\n\nACTUAL:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
pat,
self.stdout
)
}
});
if let Some(output) = &self.0 {
line_separated(pats.as_ref(), |pat| {
if output.stdout.contains(pat) {
panic!(
"assertion failed: `!self.stdout.contains(..)`:\n\nEXPECTED:\n{0}\n{1}\n{0}\n\nACTUAL:\n{0}\n{2}\n{0}\n",
"-".repeat(60),
pat,
output.stdout
)
}
});
}
self
}
}
Expand Down
Loading

0 comments on commit c317eeb

Please sign in to comment.