From 0ab030f90752abf4f4fec324843d8b4833b450ba Mon Sep 17 00:00:00 2001 From: M3gA-Mind Date: Fri, 23 Oct 2026 05:15:27 +0530 Subject: [PATCH] test(cortex): pin forget batching and a retry that finds the events gone forget_events sends at most FORGET_BATCH (100) ids per request, and a hosted retry that answers 404 means an earlier send already removed them, which is success. Neither was tested. The new test forgets 250 ids against a backend that fails each batch's first send with 503 and answers its retry 404. --- .../src/cortex/engine/mod_hosted_tests.rs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/crates/tinymemory-integrations/src/cortex/engine/mod_hosted_tests.rs b/crates/tinymemory-integrations/src/cortex/engine/mod_hosted_tests.rs index 6b6f9b41..0028641b 100644 --- a/crates/tinymemory-integrations/src/cortex/engine/mod_hosted_tests.rs +++ b/crates/tinymemory-integrations/src/cortex/engine/mod_hosted_tests.rs @@ -521,3 +521,44 @@ async fn a_visibility_timeout_says_whether_the_listing_was_rate_limited() { "{missing}" ); } + +#[tokio::test] +async fn a_forget_is_sent_in_batches_and_a_retry_that_finds_them_gone_succeeds() { + use axum::http::StatusCode; + use axum::routing::post; + use axum::{Json, Router}; + use std::sync::Mutex; + let bodies: Arc>> = Arc::default(); + let seen = bodies.clone(); + // Each batch's first send fails transiently; its retry finds the + // events already gone (404), which is success for an idempotent removal. + let app = Router::new().route( + "/memory/forget", + post(move |Json(body): Json| { + let seen = seen.clone(); + async move { + let mut seen = seen.lock().unwrap(); + seen.push(body); + if seen.len() % 2 == 1 { + (StatusCode::SERVICE_UNAVAILABLE, Json(serde_json::json!({}))) + } else { + (StatusCode::NOT_FOUND, Json(serde_json::json!({}))) + } + } + }), + ); + let engine = hosted_engine(&serve(app).await); + let ids: Vec = (0..250).map(|i| format!("e{i}")).collect(); + engine + .log + .forget_events("user:alice/app:learnings", &ids) + .await + .unwrap(); + let sizes: Vec = bodies + .lock() + .unwrap() + .iter() + .map(|body| body["selector"]["memory_ids"].as_array().unwrap().len()) + .collect(); + assert_eq!(sizes, vec![100, 100, 100, 100, 50, 50]); +}