Skip to content

Commit ece5ff0

Browse files
cuviperrami3l
authored andcommitted
test(download): serialize tests with proxy-sensitive URLs
There was already a guard for tests that *set* a proxy variable in the environment, but this is also relevant for tests that would implicitly read those variables while downloading a local `serve_file` URL.
1 parent 72f5415 commit ece5ff0

File tree

1 file changed

+38
-25
lines changed

1 file changed

+38
-25
lines changed

src/download/tests.rs

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use std::convert::Infallible;
2+
use std::env::remove_var;
23
use std::fs;
34
use std::io;
45
use std::net::SocketAddr;
56
use std::path::Path;
7+
use std::sync::LazyLock;
68
use std::sync::mpsc::{Sender, channel};
79
use std::thread;
810

@@ -20,7 +22,7 @@ mod curl {
2022

2123
use url::Url;
2224

23-
use super::{serve_file, tmp_dir, write_file};
25+
use super::{scrub_env, serve_file, tmp_dir, write_file};
2426
use crate::download::{Backend, Event};
2527

2628
#[tokio::test]
@@ -43,6 +45,7 @@ mod curl {
4345

4446
#[tokio::test]
4547
async fn callback_gets_all_data_as_if_the_download_happened_all_at_once() {
48+
let _guard = scrub_env().await;
4649
let tmpdir = tmp_dir();
4750
let target_path = tmpdir.path().join("downloaded");
4851
write_file(&target_path, "123");
@@ -94,46 +97,28 @@ mod curl {
9497

9598
#[cfg(any(feature = "reqwest-rustls-tls", feature = "reqwest-native-tls"))]
9699
mod reqwest {
97-
use std::env::{remove_var, set_var};
100+
use std::env::set_var;
98101
use std::error::Error;
99102
use std::net::TcpListener;
103+
use std::sync::Mutex;
100104
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
101-
use std::sync::{LazyLock, Mutex};
102105
use std::thread;
103106
use std::time::Duration;
104107

105108
use env_proxy::for_url;
106109
use reqwest::{Client, Proxy};
107110
use url::Url;
108111

109-
use super::{serve_file, tmp_dir, write_file};
112+
use super::{scrub_env, serve_file, tmp_dir, write_file};
110113
use crate::download::{Backend, Event, TlsBackend};
111114

112-
static SERIALISE_TESTS: LazyLock<tokio::sync::Mutex<()>> =
113-
LazyLock::new(|| tokio::sync::Mutex::new(()));
114-
115-
unsafe fn scrub_env() {
116-
unsafe {
117-
remove_var("http_proxy");
118-
remove_var("https_proxy");
119-
remove_var("HTTPS_PROXY");
120-
remove_var("ftp_proxy");
121-
remove_var("FTP_PROXY");
122-
remove_var("all_proxy");
123-
remove_var("ALL_PROXY");
124-
remove_var("no_proxy");
125-
remove_var("NO_PROXY");
126-
}
127-
}
128-
129115
// Tests for correctly retrieving the proxy (host, port) tuple from $https_proxy
130116
#[tokio::test]
131117
async fn read_basic_proxy_params() {
132-
let _guard = SERIALISE_TESTS.lock().await;
118+
let _guard = scrub_env().await;
133119
// SAFETY: We are setting environment variables when `SERIALISE_TESTS` is locked,
134120
// and those environment variables in question are not relevant elsewhere in the test suite.
135121
unsafe {
136-
scrub_env();
137122
set_var("https_proxy", "http://proxy.example.com:8080");
138123
}
139124
let u = Url::parse("https://www.example.org").ok().unwrap();
@@ -147,12 +132,11 @@ mod reqwest {
147132
#[tokio::test]
148133
async fn socks_proxy_request() {
149134
static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
150-
let _guard = SERIALISE_TESTS.lock().await;
135+
let _guard = scrub_env().await;
151136

152137
// SAFETY: We are setting environment variables when `SERIALISE_TESTS` is locked,
153138
// and those environment variables in question are not relevant elsewhere in the test suite.
154139
unsafe {
155-
scrub_env();
156140
set_var("all_proxy", "socks5://127.0.0.1:1080");
157141
}
158142

@@ -210,6 +194,7 @@ mod reqwest {
210194

211195
#[tokio::test]
212196
async fn callback_gets_all_data_as_if_the_download_happened_all_at_once() {
197+
let _guard = scrub_env().await;
213198
let tmpdir = tmp_dir();
214199
let target_path = tmpdir.path().join("downloaded");
215200
write_file(&target_path, "123");
@@ -363,3 +348,31 @@ fn serve_contents(
363348
}
364349
res
365350
}
351+
352+
/// Clear proxy-related environment variables
353+
///
354+
/// Every test using a proxy-sensitive URL should call this and hold the returned guard,
355+
/// regardless of whether the test is going to set its own proxy environment variables.
356+
async fn scrub_env() -> tokio::sync::MutexGuard<'static, ()> {
357+
static SERIALISE_TESTS: LazyLock<tokio::sync::Mutex<()>> =
358+
LazyLock::new(|| tokio::sync::Mutex::new(()));
359+
360+
let guard = SERIALISE_TESTS.lock().await;
361+
362+
// SAFETY: We are clearing environment variables when `SERIALISE_TESTS` is locked, and those
363+
// environment variables in question are only relevant in tests that continue to hold this
364+
// mutex guard.
365+
unsafe {
366+
remove_var("http_proxy");
367+
remove_var("https_proxy");
368+
remove_var("HTTPS_PROXY");
369+
remove_var("ftp_proxy");
370+
remove_var("FTP_PROXY");
371+
remove_var("all_proxy");
372+
remove_var("ALL_PROXY");
373+
remove_var("no_proxy");
374+
remove_var("NO_PROXY");
375+
}
376+
377+
guard
378+
}

0 commit comments

Comments
 (0)