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

Treat timeouts as nonexistence (fix #86) #98

Merged
merged 1 commit into from
Jan 23, 2024
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
7 changes: 7 additions & 0 deletions fixtures/timeout/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions fixtures/timeout/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "timeout"
version = "0.1.0"
edition = "2021"

# smoelius: https://stackoverflow.com/a/56459603
repository = "https://httpstat.us/200?sleep=300000" # 5 minutes

[workspace]
1 change: 1 addition & 0 deletions fixtures/timeout/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

17 changes: 11 additions & 6 deletions src/curl.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
use super::RepoStatus;
use anyhow::{anyhow, Result};
use curl::easy::Easy;
use std::time::Duration;

const TIMEOUT: u64 = 10; // seconds

pub(crate) fn existence(url: &str) -> Result<RepoStatus<()>> {
let mut handle = Easy::new();
handle.url(url)?;
handle.follow_location(true)?;
handle.transfer().perform()?;
let response_code = handle.response_code()?;
match response_code {
200 => Ok(RepoStatus::Success(url, ())),
404 => Ok(RepoStatus::Nonexistent(url)),
_ => Err(anyhow!("unexpected response code: {response_code}")),
handle.timeout(Duration::from_secs(TIMEOUT))?;
let result = handle.transfer().perform();
match result.and_then(|()| handle.response_code()) {
Ok(200) => Ok(RepoStatus::Success(url, ())),
Ok(404) => Ok(RepoStatus::Nonexistent(url)),
Err(err) if err.is_operation_timedout() => Ok(RepoStatus::Nonexistent(url)),
Ok(response_code) => Err(anyhow!("unexpected response code: {response_code}")),
Err(err) => Err(err.into()),
}
}
1 change: 1 addition & 0 deletions tests/cases/timeout.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
path = "fixtures/timeout"
1 change: 1 addition & 0 deletions tests/cases/timeout.with_token.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Scanning 1 packages and their dependencies (pass --verbose for more information)
1 change: 1 addition & 0 deletions tests/cases/timeout.with_token.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
timeout (https://httpstat.us/200?sleep=300000 does not exist)
1 change: 1 addition & 0 deletions tests/cases/timeout.without_token.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Scanning 1 packages and their dependencies (pass --verbose for more information)
1 change: 1 addition & 0 deletions tests/cases/timeout.without_token.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
timeout (https://httpstat.us/200?sleep=300000 does not exist)
89 changes: 55 additions & 34 deletions tests/snapbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,24 @@ use snapbox::{
cmd::{cargo_bin, Command as SnapboxCommand},
};
use std::{
env::var,
ffi::OsStr,
fs::{read_dir, read_to_string},
path::{Path, PathBuf},
process::Command,
};
use tempfile::tempdir;

mod util;
use util::{enabled, tee, token_modifier, Tee};

#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct Test {
/// Repo url
url: String,
/// Repo path (cannot be used in conjunction with `url`)
path: Option<String>,

/// Repo url (cannot be used in conjunction with `path`)
url: Option<String>,

/// Repo revision; `None` (the default) means the head of the default branch
#[serde(default)]
Expand All @@ -33,16 +37,22 @@ struct Test {

#[test]
fn snapbox() -> Result<()> {
let mut read_dir = read_dir("tests/cases")?;

let test_paths = read_dir.try_fold(Vec::new(), |mut url_paths, entry| {
let entry = entry?;
let path = entry.path();
if path.extension() == Some(OsStr::new("toml")) {
url_paths.push(path);
}
Result::<_>::Ok(url_paths)
})?;
let test_cases = Path::new("tests/cases");

let test_paths = if let Ok(testcase) = var("TESTCASE") {
vec![test_cases.join(testcase).with_extension("toml")]
} else {
let mut read_dir = read_dir(test_cases)?;

read_dir.try_fold(Vec::new(), |mut url_paths, entry| {
let entry = entry?;
let path = entry.path();
if path.extension() == Some(OsStr::new("toml")) {
url_paths.push(path);
}
Result::<_>::Ok(url_paths)
})?
};

test_paths
.into_par_iter()
Expand All @@ -55,32 +65,43 @@ fn snapbox() -> Result<()> {

let test: Test = toml::from_str(&raw).unwrap();

let tempdir = tempdir()?;

let mut command = SnapboxCommand::new("git").args([
"clone",
&test.url,
&tempdir.path().to_string_lossy(),
]);
if test.rev.is_none() {
command = command.arg("--depth=1");
}
command.assert().success();

if let Some(rev) = &test.rev {
SnapboxCommand::new("git")
.args(["checkout", rev])
.current_dir(&tempdir)
.assert()
.success();
}
let tempdir;
let dir = match (test.path, test.url) {
(Some(path), None) => PathBuf::from(path),
(None, Some(url)) => {
tempdir = tempfile::tempdir()?;

let mut command = SnapboxCommand::new("git").args([
"clone",
&url,
&tempdir.path().to_string_lossy(),
]);
if test.rev.is_none() {
command = command.arg("--depth=1");
}
command.assert().success();

if let Some(rev) = &test.rev {
SnapboxCommand::new("git")
.args(["checkout", rev])
.current_dir(&tempdir)
.assert()
.success();
}
tempdir.path().to_owned()
}
(_, _) => {
panic!("exactly one of `path` and `url` must be set");
}
};

assert!(tempdir.path().join("Cargo.lock").exists());
let path = dir.join("Cargo.lock");
assert!(path.exists(), "{path:?} does not exist");

let mut command = Command::new(cargo_bin("cargo-unmaintained"));
command
.args(["unmaintained", "--color=never", "--imprecise"])
.current_dir(&tempdir);
.current_dir(dir);

if enabled("VERBOSE") {
// smoelius If `VERBOSE` is enabled, don't bother comparing stderr, because it won't
Expand Down