v1.1.0-beta.1: add proxy integration tests (62 tests, all green)
Nine end-to-end tests for the proxy feature: 6 network tests exercising every proxy code path through a real hyper forward proxy (TestProxy) and a mockito origin, plus 3 CLI tests verifying flag parsing and error handling. TestProxy binds to 127.0.0.1:0, forwards in absolute-form, counts requests via an atomic so we can assert traffic actually traversed the proxy. Key issues resolved during implementation: - ENV_MUTEX serializes all tests that mutate HTTPS_PROXY/HTTP_PROXY in both the unit test module and the integration suite. Without it, parallel test execution within a single binary produces nondeterministic failures. - reqwest's blocking::Client owns an internal tokio Runtime. Dropping it inside a #[tokio::test] async fn panics on tokio >= 1.49. All reqwest work runs inside spawn_blocking so the Client drops on a thread-pool thread where that's permitted. - service_fn's closure can't carry a return-type annotation, and async blocks don't support one either. The handler is extracted to a named async fn (proxy_handler) so the compiler can see the concrete Result<Response, Infallible> and satisfy serve_connection's Error bound.
This commit is contained in:
@@ -209,9 +209,16 @@ pub fn print_offline_instructions() {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::sync::Mutex;
|
||||
|
||||
// Env vars are process-global. cargo test runs tests in parallel within
|
||||
// a single binary, so any test that sets/removes HTTPS_PROXY or HTTP_PROXY
|
||||
// must hold this lock for its entire duration.
|
||||
static ENV_MUTEX: Mutex<()> = Mutex::new(());
|
||||
|
||||
#[test]
|
||||
fn no_proxy_flag_forces_direct() {
|
||||
let _env_lock = ENV_MUTEX.lock().unwrap();
|
||||
std::env::set_var("HTTPS_PROXY", "http://proxy.example.com:3128");
|
||||
let config = ProxyConfig::resolve(None, true).unwrap();
|
||||
assert!(config.url.is_none());
|
||||
@@ -220,6 +227,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn explicit_flag_overrides_env() {
|
||||
let _env_lock = ENV_MUTEX.lock().unwrap();
|
||||
std::env::set_var("HTTPS_PROXY", "http://env-proxy.example.com:3128");
|
||||
let config = ProxyConfig::resolve(Some("http://flag-proxy.example.com:8080"), false).unwrap();
|
||||
assert_eq!(config.url.as_ref().unwrap().host_str(), Some("flag-proxy.example.com"));
|
||||
@@ -229,6 +237,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn picks_up_env_var() {
|
||||
let _env_lock = ENV_MUTEX.lock().unwrap();
|
||||
std::env::remove_var("HTTPS_PROXY");
|
||||
std::env::remove_var("https_proxy");
|
||||
std::env::set_var("HTTP_PROXY", "http://env-proxy.example.com:3128");
|
||||
@@ -240,6 +249,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn direct_when_nothing_set() {
|
||||
let _env_lock = ENV_MUTEX.lock().unwrap();
|
||||
std::env::remove_var("HTTPS_PROXY");
|
||||
std::env::remove_var("https_proxy");
|
||||
std::env::remove_var("HTTP_PROXY");
|
||||
@@ -262,6 +272,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn client_builds_direct() {
|
||||
let _env_lock = ENV_MUTEX.lock().unwrap();
|
||||
std::env::remove_var("HTTPS_PROXY");
|
||||
std::env::remove_var("https_proxy");
|
||||
std::env::remove_var("HTTP_PROXY");
|
||||
@@ -272,6 +283,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn git_proxy_guard_sets_and_restores() {
|
||||
let _env_lock = ENV_MUTEX.lock().unwrap();
|
||||
std::env::set_var("HTTPS_PROXY", "http://original:1111");
|
||||
std::env::set_var("HTTP_PROXY", "http://original:2222");
|
||||
|
||||
@@ -291,6 +303,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn git_proxy_guard_clears_for_direct() {
|
||||
let _env_lock = ENV_MUTEX.lock().unwrap();
|
||||
std::env::set_var("HTTPS_PROXY", "http://should-be-cleared:1111");
|
||||
std::env::set_var("HTTP_PROXY", "http://should-be-cleared:2222");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user