Skip to content

Commit

Permalink
Treat timeouts as nonexistence (fix #86)
Browse files Browse the repository at this point in the history
  • Loading branch information
smoelius committed Jan 21, 2024
1 parent 85782b0 commit a084dff
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 40 deletions.
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"
Empty file.
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)
Empty file.
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

0 comments on commit a084dff

Please sign in to comment.