commit aff09a20eb5b2e6eee195c865954c2a57623f599
parent 0fcc40ffb626736f8eb20d1498caee53d1a8ce4f
Author: triesap <tyson@radroots.org>
Date: Mon, 10 Aug 2026 18:36:54 +0000
test: stabilize observer qualification timing
- wait for callback panic cleanup instead of assuming a fixed scheduler delay
- give the local relay adapter a realistic bounded test deadline
- preserve production observer behavior and public FFI metadata unchanged
- exercise the observer suite repeatedly and keep the full capsule check green
Diffstat:
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/core/crates/harvestcircle_ffi/src/observer.rs b/core/crates/harvestcircle_ffi/src/observer.rs
@@ -239,6 +239,7 @@ mod tests {
};
const SECRET_HEX: &str = "7e7e9c42a91bfef19fa7ea99d52d8afdb67d893a8fefba1f5cb9793f2107f6d7";
+ const TEST_RELAY_TIMEOUT: Duration = Duration::from_secs(2);
#[derive(Default)]
struct RecordingObserver {
@@ -274,7 +275,7 @@ mod tests {
RuntimeDependencies::new(
Arc::new(InMemorySecretStore::default()),
Arc::new(SystemClock),
- Arc::new(SdkNostrClient::new(std::time::Duration::from_millis(10))),
+ Arc::new(SdkNostrClient::new(TEST_RELAY_TIMEOUT)),
Arc::new(UuidInstallationIdentitySource),
),
NonZeroUsize::new(ACTOR_MAILBOX_CAPACITY).expect("capacity"),
@@ -382,8 +383,7 @@ mod tests {
.subscribe_changes_v2(Box::new(PanickingObserver))
.await
.expect("panic observer registration");
- tokio::time::sleep(Duration::from_millis(10)).await;
- assert!(core.inner.observers.lock().expect("observers").is_empty());
+ wait_for_observer_count(&core, 0).await;
panic_subscription.unsubscribe().await;
let observer = Arc::new(RecordingObserver::default());
@@ -503,6 +503,16 @@ mod tests {
.expect("snapshot delivery");
}
+ async fn wait_for_observer_count(core: &HarvestCircleAppCore, expected: usize) {
+ tokio::time::timeout(OBSERVER_DELIVERY_TIMEOUT, async {
+ while core.inner.observers.lock().expect("observers").len() != expected {
+ tokio::task::yield_now().await;
+ }
+ })
+ .await
+ .expect("observer deregistration");
+ }
+
async fn wait_for_fresh_profile(observer: &RecordingObserver) {
tokio::time::timeout(OBSERVER_DELIVERY_TIMEOUT, async {
loop {