test(license): show the ungated search-job reads stay open through the real route table

This commit is contained in:
Ashish Kolhe
2026-11-04 20:18:56 +05:30
parent 19dccd0d81
commit 308d2679db
3 changed files with 50 additions and 14 deletions
+22 -13
View File
@@ -1282,18 +1282,11 @@ fn alert_calibration_routes(router: Router) -> Router {
#[rustfmt::skip]
pub fn service_routes() -> Router {
let cfg = get_config();
// Set server header
#[cfg(feature = "enterprise")]
let server = format!(
"{}-{}",
get_o2_config().super_cluster.region,
cfg.common.instance_name_short
);
#[cfg(not(feature = "enterprise"))]
let server = cfg.common.instance_name_short.to_string();
with_service_layers(service_route_table())
}
/// The `/api` route table before the auth, audit and org layers wrap it.
fn service_route_table() -> Router {
// Downtimes, Slack, search and service streams live in their own tables to keep this function under the line limit.
let mut router = public_dashboard_admin_routes(
Router::new()
@@ -2253,6 +2246,22 @@ pub fn service_routes() -> Router {
);
}
router
}
fn with_service_layers(router: Router) -> Router {
let cfg = get_config();
// Set server header
#[cfg(feature = "enterprise")]
let server = format!(
"{}-{}",
get_o2_config().super_cluster.region,
cfg.common.instance_name_short
);
#[cfg(not(feature = "enterprise"))]
let server = cfg.common.instance_name_short.to_string();
// Snappy preprocessing sits outside RequestDecompressionLayer, which rejects snappy with 415.
router
.layer(middleware::from_fn(blocked_orgs_middleware))
@@ -5088,8 +5097,8 @@ mod tests {
/// `service_routes()` minus comments, whitespace and wrap commas.
fn service_routes_registrations() -> String {
let source = include_str!("mod.rs");
let start = source.find("pub fn service_routes() -> Router {").unwrap();
let end = start + source[start..].find("\npub fn ").unwrap();
let start = source.find("fn service_route_table() -> Router {").unwrap();
let end = start + source[start..].find("\n}\n").unwrap();
let mut body = String::new();
let mut rest = &source[start..end];
while let Some(at) = rest.find("/*") {
@@ -1681,7 +1681,7 @@ mod tests {
const ROUTER_SOURCE: &str = include_str!("mod.rs");
#[cfg(feature = "enterprise")]
const SERVICE_ROUTES_SIGNATURE: &str = "pub fn service_routes(";
const SERVICE_ROUTES_SIGNATURE: &str = "fn service_route_table(";
#[cfg(feature = "enterprise")]
const SEARCH_ROUTES_SIGNATURE: &str = "fn search_routes_with(";
@@ -693,6 +693,33 @@ async fn an_operational_stream_in_the_path_does_not_open_the_gate() {
assert_eq!(response.status(), StatusCode::TOO_MANY_REQUESTS);
}
#[cfg(feature = "enterprise")]
#[tokio::test]
async fn closed_gate_leaves_the_ungated_search_job_reads_open() {
use o2_enterprise::enterprise::license::close_search_gate_for_tests;
let _gate = close_search_gate_for_tests().await;
// the table without its auth layers, which would answer 401 before any route
let app = service_route_table();
for (method, uri, gated) in [
(Method::GET, "/acme/search_jobs", false),
(Method::GET, "/acme/search_jobs/j1", false),
(Method::POST, "/acme/search_jobs", true),
] {
let request = axum::http::Request::builder()
.method(method.clone())
.uri(uri)
.body(Body::empty())
.unwrap();
let status = app.clone().oneshot(request).await.unwrap().status();
assert_eq!(
status == StatusCode::TOO_MANY_REQUESTS,
gated,
"{method} {uri}: {status}"
);
}
}
#[cfg(feature = "enterprise")]
#[tokio::test]
async fn meta_org_passes_the_closed_gate() {