chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

216
vendor/tower/tests/limit/concurrency.rs vendored Normal file
View File

@@ -0,0 +1,216 @@
use crate::support;
use tokio_test::{assert_pending, assert_ready, assert_ready_ok};
use tower::limit::concurrency::ConcurrencyLimitLayer;
use tower_test::{assert_request_eq, mock};
#[tokio::test(flavor = "current_thread")]
async fn basic_service_limit_functionality_with_poll_ready() {
let _t = support::trace_init();
let limit = ConcurrencyLimitLayer::new(2);
let (mut service, mut handle) = mock::spawn_layer(limit);
assert_ready_ok!(service.poll_ready());
let r1 = service.call("hello 1");
assert_ready_ok!(service.poll_ready());
let r2 = service.call("hello 2");
assert_pending!(service.poll_ready());
assert!(!service.is_woken());
// The request gets passed through
assert_request_eq!(handle, "hello 1").send_response("world 1");
// The next request gets passed through
assert_request_eq!(handle, "hello 2").send_response("world 2");
// There are no more requests
assert_pending!(handle.poll_request());
assert_eq!(r1.await.unwrap(), "world 1");
assert!(service.is_woken());
// Another request can be sent
assert_ready_ok!(service.poll_ready());
let r3 = service.call("hello 3");
assert_pending!(service.poll_ready());
assert_eq!(r2.await.unwrap(), "world 2");
// The request gets passed through
assert_request_eq!(handle, "hello 3").send_response("world 3");
assert_eq!(r3.await.unwrap(), "world 3");
}
#[tokio::test(flavor = "current_thread")]
async fn basic_service_limit_functionality_without_poll_ready() {
let _t = support::trace_init();
let limit = ConcurrencyLimitLayer::new(2);
let (mut service, mut handle) = mock::spawn_layer(limit);
assert_ready_ok!(service.poll_ready());
let r1 = service.call("hello 1");
assert_ready_ok!(service.poll_ready());
let r2 = service.call("hello 2");
assert_pending!(service.poll_ready());
// The request gets passed through
assert_request_eq!(handle, "hello 1").send_response("world 1");
assert!(!service.is_woken());
// The next request gets passed through
assert_request_eq!(handle, "hello 2").send_response("world 2");
assert!(!service.is_woken());
// There are no more requests
assert_pending!(handle.poll_request());
assert_eq!(r1.await.unwrap(), "world 1");
assert!(service.is_woken());
// One more request can be sent
assert_ready_ok!(service.poll_ready());
let r4 = service.call("hello 4");
assert_pending!(service.poll_ready());
assert_eq!(r2.await.unwrap(), "world 2");
assert!(service.is_woken());
// The request gets passed through
assert_request_eq!(handle, "hello 4").send_response("world 4");
assert_eq!(r4.await.unwrap(), "world 4");
}
#[tokio::test(flavor = "current_thread")]
async fn request_without_capacity() {
let _t = support::trace_init();
let limit = ConcurrencyLimitLayer::new(0);
let (mut service, _) = mock::spawn_layer::<(), (), _>(limit);
assert_pending!(service.poll_ready());
}
#[tokio::test(flavor = "current_thread")]
async fn reserve_capacity_without_sending_request() {
let _t = support::trace_init();
let limit = ConcurrencyLimitLayer::new(1);
let (mut s1, mut handle) = mock::spawn_layer(limit);
let mut s2 = s1.clone();
// Reserve capacity in s1
assert_ready_ok!(s1.poll_ready());
// Service 2 cannot get capacity
assert_pending!(s2.poll_ready());
// s1 sends the request, then s2 is able to get capacity
let r1 = s1.call("hello");
assert_request_eq!(handle, "hello").send_response("world");
assert_pending!(s2.poll_ready());
r1.await.unwrap();
assert_ready_ok!(s2.poll_ready());
}
#[tokio::test(flavor = "current_thread")]
async fn service_drop_frees_capacity() {
let _t = support::trace_init();
let limit = ConcurrencyLimitLayer::new(1);
let (mut s1, _handle) = mock::spawn_layer::<(), (), _>(limit);
let mut s2 = s1.clone();
// Reserve capacity in s1
assert_ready_ok!(s1.poll_ready());
// Service 2 cannot get capacity
assert_pending!(s2.poll_ready());
drop(s1);
assert!(s2.is_woken());
assert_ready_ok!(s2.poll_ready());
}
#[tokio::test(flavor = "current_thread")]
async fn response_error_releases_capacity() {
let _t = support::trace_init();
let limit = ConcurrencyLimitLayer::new(1);
let (mut s1, mut handle) = mock::spawn_layer::<_, (), _>(limit);
let mut s2 = s1.clone();
// Reserve capacity in s1
assert_ready_ok!(s1.poll_ready());
// s1 sends the request, then s2 is able to get capacity
let r1 = s1.call("hello");
assert_request_eq!(handle, "hello").send_error("boom");
r1.await.unwrap_err();
assert_ready_ok!(s2.poll_ready());
}
#[tokio::test(flavor = "current_thread")]
async fn response_future_drop_releases_capacity() {
let _t = support::trace_init();
let limit = ConcurrencyLimitLayer::new(1);
let (mut s1, _handle) = mock::spawn_layer::<_, (), _>(limit);
let mut s2 = s1.clone();
// Reserve capacity in s1
assert_ready_ok!(s1.poll_ready());
// s1 sends the request, then s2 is able to get capacity
let r1 = s1.call("hello");
assert_pending!(s2.poll_ready());
drop(r1);
assert_ready_ok!(s2.poll_ready());
}
#[tokio::test(flavor = "current_thread")]
async fn multi_waiters() {
let _t = support::trace_init();
let limit = ConcurrencyLimitLayer::new(1);
let (mut s1, _handle) = mock::spawn_layer::<(), (), _>(limit);
let mut s2 = s1.clone();
let mut s3 = s1.clone();
// Reserve capacity in s1
assert_ready_ok!(s1.poll_ready());
// s2 and s3 are not ready
assert_pending!(s2.poll_ready());
assert_pending!(s3.poll_ready());
drop(s1);
assert!(s2.is_woken());
assert!(!s3.is_woken());
drop(s2);
assert!(s3.is_woken());
}

5
vendor/tower/tests/limit/main.rs vendored Normal file
View File

@@ -0,0 +1,5 @@
#![cfg(feature = "limit")]
mod concurrency;
mod rate;
#[path = "../support.rs"]
pub(crate) mod support;

71
vendor/tower/tests/limit/rate.rs vendored Normal file
View File

@@ -0,0 +1,71 @@
use super::support;
use std::time::Duration;
use tokio::time;
use tokio_test::{assert_pending, assert_ready, assert_ready_ok};
use tower::limit::rate::RateLimitLayer;
use tower_test::{assert_request_eq, mock};
#[tokio::test(flavor = "current_thread")]
async fn reaching_capacity() {
let _t = support::trace_init();
time::pause();
let rate_limit = RateLimitLayer::new(1, Duration::from_millis(100));
let (mut service, mut handle) = mock::spawn_layer(rate_limit);
assert_ready_ok!(service.poll_ready());
let response = service.call("hello");
assert_request_eq!(handle, "hello").send_response("world");
assert_eq!(response.await.unwrap(), "world");
assert_pending!(service.poll_ready());
assert_pending!(handle.poll_request());
time::advance(Duration::from_millis(101)).await;
assert_ready_ok!(service.poll_ready());
let response = service.call("two");
assert_request_eq!(handle, "two").send_response("done");
assert_eq!(response.await.unwrap(), "done");
}
#[tokio::test(flavor = "current_thread")]
async fn remaining_gets_reset() {
// This test checks for the case where the `until` state gets reset
// but the `rem` does not. This was a bug found `cd7dd12315706fc0860a35646b1eb7b60c50a5c1`.
//
// The main premise here is that we can make one request which should initialize the state
// as ready. Then we can advance the clock to put us beyond the current period. When we make
// subsequent requests the `rem` for the next window is continued from the previous when
// it should be totally reset.
let _t = support::trace_init();
time::pause();
let rate_limit = RateLimitLayer::new(3, Duration::from_millis(100));
let (mut service, mut handle) = mock::spawn_layer(rate_limit);
assert_ready_ok!(service.poll_ready());
let response = service.call("hello");
assert_request_eq!(handle, "hello").send_response("world");
assert_eq!(response.await.unwrap(), "world");
time::advance(Duration::from_millis(100)).await;
assert_ready_ok!(service.poll_ready());
let response = service.call("hello");
assert_request_eq!(handle, "hello").send_response("world");
assert_eq!(response.await.unwrap(), "world");
assert_ready_ok!(service.poll_ready());
let response = service.call("hello");
assert_request_eq!(handle, "hello").send_response("world");
assert_eq!(response.await.unwrap(), "world");
assert_ready_ok!(service.poll_ready());
}