Skip to content

Commit 3f2f4eb

Browse files
authored
Merge pull request #1522 from viccuad/test/fix-flaky-proxy
test(policy-evaluator,policy-server): Fix flaky tests
2 parents 1302c59 + cb47b43 commit 3f2f4eb

5 files changed

Lines changed: 24 additions & 20 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/kwctl/tests/proxy.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use std::time::Duration;
2-
3-
use backon::{BlockingRetryable, ExponentialBuilder};
1+
use backon::{BlockingRetryable, ConstantBuilder};
42
use predicates::str::contains;
53
use rstest::rstest;
64
use tempfile::tempdir;
@@ -31,7 +29,8 @@ fn start_proxy() -> (Container<GenericImage>, u16) {
3129

3230
/// Used to verify that traffic was (or was not) routed through the proxy.
3331
/// Returns true if the proxy container's logs (stdout or stderr) contain `needle`.
34-
/// Retries with exponential backoff because tinyproxy may not flush its log immediately.
32+
/// Retries with a constant backoff to handle testcontainers' log collection latency.
33+
/// The container should be stopped before calling this to ensure tinyproxy has flushed its logs.
3534
fn proxy_log_contains(container: &Container<GenericImage>, needle: &str) -> bool {
3635
let check = || {
3736
let stdout =
@@ -46,9 +45,9 @@ fn proxy_log_contains(container: &Container<GenericImage>, needle: &str) -> bool
4645
};
4746
check
4847
.retry(
49-
ExponentialBuilder::default()
50-
.with_min_delay(Duration::from_millis(100))
51-
.with_max_times(5),
48+
ConstantBuilder::default()
49+
.with_delay(std::time::Duration::from_millis(100))
50+
.with_max_times(10),
5251
)
5352
.call()
5453
.is_ok()

crates/policy-evaluator/tests/proxy.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod common;
66
mod proxy_tests {
77
use std::time::Duration;
88

9-
use backon::{ExponentialBuilder, Retryable};
9+
use backon::{ConstantBuilder, Retryable};
1010
use policy_evaluator::callback_requests::{CallbackRequest, CallbackRequestType};
1111
use policy_fetcher::{proxy::ProxyConfig, sources::Sources};
1212
use testcontainers::{
@@ -34,7 +34,7 @@ mod proxy_tests {
3434

3535
/// Used to verify that traffic was (or was not) routed through the proxy.
3636
/// Returns true if the proxy container's logs (stdout or stderr) contain `needle`.
37-
/// Retries with exponential backoff because tinyproxy may not flush its log immediately.
37+
/// Retries with a constant backoff to give tinyproxy time to flush its log.
3838
async fn proxy_log_contains(container: &ContainerAsync<GenericImage>, needle: &str) -> bool {
3939
let check = || async {
4040
let stdout = String::from_utf8(container.stdout_to_vec().await.unwrap_or_default())
@@ -49,9 +49,9 @@ mod proxy_tests {
4949
};
5050
check
5151
.retry(
52-
ExponentialBuilder::default()
53-
.with_min_delay(Duration::from_millis(100))
54-
.with_max_times(5),
52+
ConstantBuilder::default()
53+
.with_delay(std::time::Duration::from_millis(100))
54+
.with_max_times(10),
5555
)
5656
.await
5757
.is_ok()
@@ -119,7 +119,9 @@ mod proxy_tests {
119119
cb_channel
120120
.try_send(CallbackRequest {
121121
request: CallbackRequestType::OciManifest {
122-
image: "ghcr.io/kubewarden/tests/pod-privileged:v0.2.5".to_owned(),
122+
// Use a different image than the https_proxy test to avoid a process-wide
123+
// cache hit (the `#[cached]` key is the image URL only, not the proxy config).
124+
image: "ghcr.io/kubewarden/tests/pod-privileged:v0.2.1".to_owned(),
123125
},
124126
response_channel: resp_tx,
125127
})

crates/policy-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ tokio-stream = "0.1.18"
6767

6868
[dev-dependencies]
6969
backon = { version = "1.6", features = ["tokio-sleep"] }
70+
serial_test = "3"
7071
http-body-util = "0.1.3"
7172
mockall = "0.14"
7273
rcgen = { version = "0.14", features = ["crypto"] }

crates/policy-server/tests/integration_test.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,9 +1305,7 @@ fn build_request_client(
13051305

13061306
// helper functions for testing proxy functionality
13071307
mod proxy_helpers {
1308-
use std::time::Duration;
1309-
1310-
use backon::{ExponentialBuilder, Retryable};
1308+
use backon::{ConstantBuilder, Retryable};
13111309
use testcontainers::{
13121310
ContainerAsync, GenericImage,
13131311
core::{IntoContainerPort, WaitFor},
@@ -1329,7 +1327,7 @@ mod proxy_helpers {
13291327

13301328
/// Used to verify that traffic was (or was not) routed through the proxy.
13311329
/// Returns true if the proxy container's logs (stdout or stderr) contain `needle`.
1332-
/// Retries with exponential backoff because tinyproxy may not flush its log immediately.
1330+
/// Retries with a constant backoff to give tinyproxy time to flush its log.
13331331
pub async fn proxy_log_contains(
13341332
container: &ContainerAsync<GenericImage>,
13351333
needle: &str,
@@ -1347,9 +1345,9 @@ mod proxy_helpers {
13471345
};
13481346
check
13491347
.retry(
1350-
ExponentialBuilder::default()
1351-
.with_min_delay(Duration::from_millis(100))
1352-
.with_max_times(5),
1348+
ConstantBuilder::default()
1349+
.with_delay(std::time::Duration::from_millis(500))
1350+
.with_max_times(20),
13531351
)
13541352
.await
13551353
.is_ok()
@@ -1359,6 +1357,7 @@ mod proxy_helpers {
13591357
#[rstest]
13601358
#[case::both_http_and_https_proxy(true)]
13611359
#[case::https_proxy_only(false)]
1360+
#[serial_test::serial]
13621361
#[tokio::test]
13631362
async fn test_policy_server_with_https_proxy(#[case] set_http_proxy: bool) {
13641363
use proxy_helpers::*;
@@ -1415,6 +1414,7 @@ async fn test_policy_server_with_https_proxy(#[case] set_http_proxy: bool) {
14151414
/// source. The policy is first fetched from ghcr.io, pushed to the local registry, then the policy
14161415
/// server is started with HTTP_PROXY pointing at tinyproxy. Both containers share the default
14171416
/// docker bridge network so the proxy can forward requests to the registry by its bridge IP.
1417+
#[serial_test::serial]
14181418
#[tokio::test]
14191419
async fn test_policy_server_with_http_proxy() {
14201420
use proxy_helpers::*;
@@ -1518,6 +1518,7 @@ async fn test_policy_server_with_http_proxy() {
15181518
/// A real tinyproxy is started and set as HTTPS_PROXY. With NO_PROXY=ghcr.io the policy server
15191519
/// must connect directly to ghcr.io, so startup and validation succeed and the proxy logs must not
15201520
/// contain any reference to ghcr.io.
1521+
#[serial_test::serial]
15211522
#[tokio::test]
15221523
async fn test_policy_server_with_no_proxy() {
15231524
use proxy_helpers::*;

0 commit comments

Comments
 (0)