...

Text file src/github.com/linkerd/linkerd2/policy-test/tests/e2e_failure_accrual.rs

Documentation: github.com/linkerd/linkerd2/policy-test/tests

     1use linkerd_policy_test::{
     2    annotate_service, bb, create, create_ready_pod, curl, with_temp_ns, LinkerdInject,
     3};
     4
     5#[tokio::test(flavor = "current_thread")]
     6async fn consecutive_failures() {
     7    const MAX_FAILS: usize = 5;
     8    with_temp_ns(|client, ns| async move {
     9        // Create a bb service with one pod that always returns 500s.
    10        let bad_pod = bb::Terminus::new(&ns)
    11            .named("bb-bad")
    12            .percent_failure(100)
    13            .to_pod();
    14        let svc = {
    15            let svc = bb::Terminus::service(&ns);
    16            annotate_service(svc, maplit::btreemap!{
    17                "balancer.linkerd.io/failure-accrual" => "consecutive".to_string(),
    18                "balancer.linkerd.io/failure-accrual-consecutive-max-failures" => MAX_FAILS.to_string(),
    19                // don't allow the failing pod to enter probation during the test.
    20                "balancer.linkerd.io/failure-accrual-consecutive-min-penalty" => "5m".to_string(),
    21                "balancer.linkerd.io/failure-accrual-consecutive-max-penalty" => "10m".to_string(),
    22            })
    23        };
    24        tokio::join!(
    25            create(&client, svc),
    26            create_ready_pod(&client, bad_pod),
    27        );
    28
    29        let curl = curl::Runner::init(&client, &ns)
    30            .await
    31            .run_execable("curl", LinkerdInject::Enabled)
    32            .await;
    33
    34        let url = format!("http://{}", bb::Terminus::SERVICE_NAME);
    35        for request in 0..MAX_FAILS * 2 {
    36            tracing::info!("Sending request {request}...");
    37            let status = curl
    38                .get(&url)
    39                .await
    40                .expect("curl command should succeed");
    41            tracing::info!(request, ?status);
    42            if request < MAX_FAILS {
    43                assert_eq!(status, hyper::StatusCode::INTERNAL_SERVER_ERROR);
    44            } else {
    45                // Once the circuit breaker has tripped, any in flight request
    46                // will fail with a 504 due to failfast, and subsequent requests
    47                // will fail with a 503 because the balancer has no available
    48                // endpoints.
    49                assert!(
    50                    matches!(status, hyper::StatusCode::GATEWAY_TIMEOUT | hyper::StatusCode::SERVICE_UNAVAILABLE),
    51                    "expected 503 or 504, got {status:?}"
    52                );
    53            }
    54        }
    55    })
    56    .await;
    57}

View as plain text