Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ggriffiniii/httptest
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.16.2
Choose a base ref
...
head repository: ggriffiniii/httptest
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.16.3
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Feb 8, 2025

  1. Print expectation failures to stdout when the server is dropped due t…

    …o unwinding a panic
    
    Prior to this change the server would not validate expectation if the test
    panic's for reasons unrelated to the server expecations failing to be met.
    However, this could make it difficult to find the issue if the test panic was
    the result of a misconfiguration of the expectations. With this change the
    server will now validate the server expectations and on failure will simply
    print the failure message to stdout.
    ggriffiniii committed Feb 8, 2025
    Copy the full SHA
    4828317 View commit details
  2. chore: Release httptest version 0.16.3

    ggriffiniii committed Feb 8, 2025
    Copy the full SHA
    7143f1b View commit details
Showing with 38 additions and 9 deletions.
  1. +1 −1 Cargo.toml
  2. +13 −8 src/server.rs
  3. +24 −0 tests/tests.rs
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "httptest"
version = "0.16.2"
version = "0.16.3"
authors = ["Glenn Griffin <ggriffiniii@gmail.com>"]
edition = "2018"
description = "HTTP testing facilities including a mock server"
21 changes: 13 additions & 8 deletions src/server.rs
Original file line number Diff line number Diff line change
@@ -68,14 +68,19 @@ impl Server {
/// Verify all registered expectations. Panic if any are not met, then clear
/// all expectations leaving the server running in a clean state.
pub fn verify_and_clear(&mut self) {
// If the test is already panicking don't double panic on drop.
// Instead simply print the message to stdout.
fn safe_panic(args: fmt::Arguments) {
if std::thread::panicking() {
println!("httptest: {}", args);
} else {
panic!("{}", args);
}
}
let state = {
let mut state = self.state.lock().expect("mutex poisoned");
std::mem::take(&mut *state) // reset server to default state.
};
if std::thread::panicking() {
// If the test is already panicking don't double panic on drop.
return;
}
for expectation in state.expected.iter() {
if !hit_count_is_valid(expectation.times, expectation.hit_count) {
let unexpected_requests_message = if state.unexpected_requests.is_empty() {
@@ -88,20 +93,20 @@ impl Server {
)
};

panic!(
safe_panic(format_args!(
"Unexpected number of requests for matcher '{:?}'; received {}; expected {}. {}",
matcher_name(&*expectation.matcher),
expectation.hit_count,
RangeDisplay(expectation.times),
unexpected_requests_message,
);
));
}
}
if !state.unexpected_requests.is_empty() {
panic!(
safe_panic(format_args!(
"received the following unexpected requests:\n{:#?}",
&state.unexpected_requests
);
));
}
}
}
24 changes: 24 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
@@ -272,6 +272,30 @@ fn test_outside_of_tokio_context() {
let _server = httptest::Server::run();
}

// verify the server does not produce a crash if the server is dropped due to a
// panic. This can happen if the test panic's and the panic subsequently Drop's
// the server. On Drop the server typically verifies the expectations and
// panic's if any are unmet, but that would lead to a double panic which causes
// an immediate crash.
#[test]
#[should_panic]
fn test_dont_double_panic() {
let _ = pretty_env_logger::try_init();
// Setup a server to expect a single GET /foo request.
let server = httptest::Server::run();
server.expect(
Expectation::matching(all_of![request::method("GET"), request::path("/foo")])
.respond_with(status_code(200)),
);

// test panics before any server expectation validation happens.
assert_eq!(1, 2);

// panic above will drop the server which would normally panic due to the
// expectation not being met. However since that would cause a double panic
// the server will simply print the error message to stdout instead.
}

#[tokio::test]
async fn test_server_custom() {
let _ = pretty_env_logger::try_init();