From 4d60a1c59c4c9a4186f154fc6b04a166b09ee9ac Mon Sep 17 00:00:00 2001 From: erhant Date: Tue, 7 Jul 2026 21:56:00 +0300 Subject: [PATCH] test(indexer): rename test, move to more suitable file --- integration_tests/tests/bridge.rs | 31 -------------- integration_tests/tests/indexer_stall.rs | 54 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 integration_tests/tests/indexer_stall.rs diff --git a/integration_tests/tests/bridge.rs b/integration_tests/tests/bridge.rs index 67c75abc..9c241ebb 100644 --- a/integration_tests/tests/bridge.rs +++ b/integration_tests/tests/bridge.rs @@ -557,37 +557,6 @@ fn create_zone_indexer_observer( )) } -/// Test that the indexer status RPC reports caught-up with no stall after a clean run. -/// -/// TODO: Integration-level park testing (publishing a bad block to force a stall) is a follow-up -/// needing fault injection support in the test harness. -#[test] -async fn indexer_status_rpc_reports_caught_up_with_no_stall() -> anyhow::Result<()> { - use indexer_service_rpc::RpcClient as _; - - let ctx = TestContext::new().await?; - - let indexer_tip = wait_for_indexer_to_catch_up(&ctx).await?; - - let status = ctx.indexer_client().get_status().await?; - assert_eq!( - status.state, - indexer_service_protocol::IndexerSyncState::CaughtUp, - "indexer should be caught up, got {status:?}" - ); - assert!( - status.stall_reason.is_none(), - "indexer should have no stall reason after a clean run, got {status:?}" - ); - assert_eq!( - status.indexed_block_id, - Some(indexer_tip), - "status indexed_block_id should equal the caught-up tip" - ); - - Ok(()) -} - async fn wait_for_finalized_withdraw_op( observer: &ZoneIndexer, expected_amount: u64, diff --git a/integration_tests/tests/indexer_stall.rs b/integration_tests/tests/indexer_stall.rs new file mode 100644 index 00000000..ae1b8b6a --- /dev/null +++ b/integration_tests/tests/indexer_stall.rs @@ -0,0 +1,54 @@ +#![expect( + clippy::tests_outside_test_module, + reason = "We don't care about these in tests" +)] + +use std::time::Duration; + +use anyhow::{Context as _, Result}; +use indexer_service_protocol::IndexerSyncState; +use indexer_service_rpc::RpcClient as _; +use integration_tests::{TestContext, wait_for_indexer_to_catch_up}; +use log::info; + +const CAUGHT_UP_STATUS_TIMEOUT: Duration = Duration::from_secs(60); + +/// Test that the indexer status RPC reports caught-up with no stall after a clean run. +/// +/// The sequencer keeps producing blocks while we assert, so the status is polled until a +/// `CaughtUp` snapshot is observed and the indexed tip is checked as a lower bound. +/// +/// TODO: Integration-level park testing (publishing a bad block to force a stall) is a follow-up +/// needing fault injection support in the test harness. +#[tokio::test] +async fn indexer_status_rpc_reports_caught_up_with_no_stall() -> Result<()> { + let ctx = TestContext::new().await?; + + let indexer_tip = wait_for_indexer_to_catch_up(&ctx).await?; + + let status = tokio::time::timeout(CAUGHT_UP_STATUS_TIMEOUT, async { + loop { + let status = ctx.indexer_client().get_status().await?; + if status.state == IndexerSyncState::CaughtUp { + return anyhow::Ok(status); + } + info!("Waiting for caught-up indexer status, got {status:?}"); + tokio::time::sleep(Duration::from_millis(500)).await; + } + }) + .await + .context("Timed out waiting for indexer status to report caught-up")??; + + assert!( + status.stall_reason.is_none(), + "indexer should have no stall reason after a clean run, got {status:?}" + ); + // test for >= here because the sequencer keeps producing blocks while we assert, + // so the indexed tip may be ahead of the tip we observed when we waited for caught-up. + assert!( + status.indexed_block_id >= Some(indexer_tip), + "status indexed_block_id should be at least the caught-up tip {indexer_tip}, got {status:?}" + ); + + Ok(()) +}