From 14be1f888a3eaead23d3c2135f38269e5d73ca4e Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 27 Jan 2023 22:17:18 +0100 Subject: [PATCH] test(sliding-sync): integration test for UnknownPos --- Cargo.toml | 2 +- crates/matrix-sdk/Cargo.toml | 1 + crates/matrix-sdk/src/lib.rs | 4 +- crates/matrix-sdk/src/sliding_sync.rs | 6 +- crates/matrix-sdk/src/test_utils.rs | 11 + .../sliding-sync-integration-test/Cargo.toml | 2 +- .../sliding-sync-integration-test/src/lib.rs | 485 ++++++------------ 7 files changed, 172 insertions(+), 339 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dd1f5edcf..91f4581e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ byteorder = "1.4.3" ctor = "0.1.26" dashmap = "5.2.0" http = "0.2.6" -ruma = { git = "https://github.com/ruma/ruma", rev = "00045e559f864eabff08295d603f7b3238288b6f", features = ["client-api-c"] } +ruma = { git = "https://github.com/ruma/ruma", rev = "00045e559f864eabff08295d603f7b3238288b6f", features = ["client-api-c"] } ruma-common = { git = "https://github.com/ruma/ruma", rev = "00045e559f864eabff08295d603f7b3238288b6f" } once_cell = "1.16.0" serde = "1.0.151" diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index 87e5a4b30..0f4856968 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -21,6 +21,7 @@ default = [ "sled", "native-tls", ] +testing = [] e2e-encryption = [ "matrix-sdk-base/e2e-encryption", diff --git a/crates/matrix-sdk/src/lib.rs b/crates/matrix-sdk/src/lib.rs index 39f75d0c7..c03466e1a 100644 --- a/crates/matrix-sdk/src/lib.rs +++ b/crates/matrix-sdk/src/lib.rs @@ -61,8 +61,8 @@ pub use sliding_sync::{ SlidingSyncState, SlidingSyncView, SlidingSyncViewBuilder, UpdateSummary, }; -#[cfg(test)] -mod test_utils; +#[cfg(any(test, feature = "testing"))] +pub mod test_utils; #[cfg(all(test, not(target_arch = "wasm32")))] #[ctor::ctor] diff --git a/crates/matrix-sdk/src/sliding_sync.rs b/crates/matrix-sdk/src/sliding_sync.rs index aa7c0b145..740d9254f 100644 --- a/crates/matrix-sdk/src/sliding_sync.rs +++ b/crates/matrix-sdk/src/sliding_sync.rs @@ -677,7 +677,7 @@ pub struct SlidingSync { storage_key: Option, // ------ Internal state - pos: StringState, + pub(crate) pos: StringState, delta_token: StringState, /// The views of this sliding sync instance @@ -1436,7 +1436,7 @@ impl SlidingSyncViewRequestGenerator { limit, }; self.view.state.set_if(SlidingSyncState::CatchingUp, |before, _now| { - matches!(before, SlidingSyncState::Preload | SlidingSyncState::Cold) + !matches!(before, SlidingSyncState::CatchingUp) }); } InnerSlidingSyncViewRequestGenerator::GrowingFullSync { @@ -1450,7 +1450,7 @@ impl SlidingSyncViewRequestGenerator { limit, }; self.view.state.set_if(SlidingSyncState::CatchingUp, |before, _now| { - matches!(before, SlidingSyncState::Preload | SlidingSyncState::Cold) + !matches!(before, SlidingSyncState::CatchingUp) }); } InnerSlidingSyncViewRequestGenerator::Live => { diff --git a/crates/matrix-sdk/src/test_utils.rs b/crates/matrix-sdk/src/test_utils.rs index 2a770920c..30ebe50fe 100644 --- a/crates/matrix-sdk/src/test_utils.rs +++ b/crates/matrix-sdk/src/test_utils.rs @@ -1,6 +1,11 @@ +//! Testing utilities - DO NOT USE IN PRODUCTION. + +#![allow(dead_code)] use matrix_sdk_base::Session; use ruma::{api::MatrixVersion, device_id, user_id}; +#[cfg(feature = "experimental-sliding-sync")] +use crate::sliding_sync::SlidingSync; use crate::{config::RequestConfig, Client, ClientBuilder}; pub(crate) fn test_client_builder(homeserver_url: Option) -> ClientBuilder { @@ -28,3 +33,9 @@ pub(crate) async fn logged_in_client(homeserver_url: Option) -> Client { client } + +/// Force a specific pos-value to be used for the given sliding-sync instance. +#[cfg(feature = "experimental-sliding-sync")] +pub fn force_sliding_sync_pos(sliding_sync: &SlidingSync, new_pos: String) { + sliding_sync.pos.set(Some(new_pos)); +} diff --git a/testing/sliding-sync-integration-test/Cargo.toml b/testing/sliding-sync-integration-test/Cargo.toml index 1922c730c..bab74a456 100644 --- a/testing/sliding-sync-integration-test/Cargo.toml +++ b/testing/sliding-sync-integration-test/Cargo.toml @@ -8,7 +8,7 @@ publish = false anyhow = { workspace = true } ctor = { workspace = true } matrix-sdk-integration-testing = { path = "../matrix-sdk-integration-testing", features = ["helpers"] } -matrix-sdk = { path = "../../crates/matrix-sdk", features = ["experimental-sliding-sync"] } +matrix-sdk = { path = "../../crates/matrix-sdk", features = ["experimental-sliding-sync", "testing"] } tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] } futures = { version = "0.3.25" } uuid = { version = "1.2.2" } diff --git a/testing/sliding-sync-integration-test/src/lib.rs b/testing/sliding-sync-integration-test/src/lib.rs index 0577ec5a8..b21b0739b 100644 --- a/testing/sliding-sync-integration-test/src/lib.rs +++ b/testing/sliding-sync-integration-test/src/lib.rs @@ -47,7 +47,7 @@ async fn make_room(client: &Client, room_name: String) -> anyhow::Result<()> { Ok(()) } -#[derive(PartialEq, Eq, Debug)] +#[derive(PartialEq, Eq, Clone, Debug)] enum RoomListEntryEasy { Empty, Invalid, @@ -66,13 +66,20 @@ impl From<&RoomListEntry> for RoomListEntryEasy { #[cfg(test)] mod tests { - use std::time::{Duration, Instant}; + use std::{ + iter::repeat, + time::{Duration, Instant}, + }; use anyhow::{bail, Context}; use futures::{pin_mut, stream::StreamExt}; use matrix_sdk::{ - ruma::events::room::message::RoomMessageEventContent, SlidingSyncMode, SlidingSyncState, - SlidingSyncViewBuilder, + ruma::{ + api::client::error::ErrorKind as RumaError, + events::room::message::RoomMessageEventContent, + }, + test_utils::force_sliding_sync_pos, + SlidingSyncMode, SlidingSyncState, SlidingSyncViewBuilder, }; use super::*; @@ -362,32 +369,7 @@ mod tests { .map(Into::::into) .collect::>(); - assert_eq!( - rooms_list, - [ - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, // -- 10 - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, // -- 20 - RoomListEntryEasy::Filled, - ] - ); + assert_eq!(rooms_list, repeat(RoomListEntryEasy::Filled).take(21).collect::>()); assert_eq!(full_view.state.get_cloned(), SlidingSyncState::Live, "full isn't live yet"); Ok(()) @@ -419,28 +401,10 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - ] + repeat(RoomListEntryEasy::Filled) + .take(11) + .chain(repeat(RoomListEntryEasy::Empty).take(9)) + .collect::>() ); let _signal = view.rooms_list.signal_vec_cloned(); @@ -467,28 +431,11 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - ] + repeat(RoomListEntryEasy::Invalid) + .take(1) + .chain(repeat(RoomListEntryEasy::Filled).take(10)) + .chain(repeat(RoomListEntryEasy::Empty).take(9)) + .collect::>() ); view.set_range(5, 10); @@ -510,28 +457,11 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - ] + repeat(RoomListEntryEasy::Invalid) + .take(5) + .chain(repeat(RoomListEntryEasy::Filled).take(6)) + .chain(repeat(RoomListEntryEasy::Empty).take(9)) + .collect::>() ); // let's move the window @@ -555,28 +485,11 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - ] + repeat(RoomListEntryEasy::Invalid) + .take(5) + .chain(repeat(RoomListEntryEasy::Filled).take(11)) + .chain(repeat(RoomListEntryEasy::Empty).take(4)) + .collect::>() ); Ok(()) } @@ -607,28 +520,11 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Empty, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - ] + repeat(RoomListEntryEasy::Empty) + .take(1) + .chain(repeat(RoomListEntryEasy::Filled).take(10)) + .chain(repeat(RoomListEntryEasy::Empty).take(9)) + .collect::>() ); let _signal = view.rooms_list.signal_vec_cloned(); @@ -654,28 +550,10 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - ] + repeat(RoomListEntryEasy::Filled) + .take(11) + .chain(repeat(RoomListEntryEasy::Empty).take(9)) + .collect::>() ); // let's move the window again @@ -699,28 +577,11 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - ] + repeat(RoomListEntryEasy::Invalid) + .take(2) + .chain(repeat(RoomListEntryEasy::Filled).take(11)) + .chain(repeat(RoomListEntryEasy::Empty).take(7)) + .collect::>() ); // now we "move" the room of pos 3 to pos 0; @@ -759,28 +620,11 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - ] + repeat(RoomListEntryEasy::Invalid) + .take(2) + .chain(repeat(RoomListEntryEasy::Filled).take(11)) + .chain(repeat(RoomListEntryEasy::Empty).take(7)) + .collect::>() ); // items has moved, thus we shouldn't find it where it was @@ -807,28 +651,11 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Invalid, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - ] + repeat(RoomListEntryEasy::Filled) + .take(11) + .chain(repeat(RoomListEntryEasy::Invalid).take(2)) + .chain(repeat(RoomListEntryEasy::Empty).take(7)) + .collect::>() ); // and check that our room move has been accepted properly, too. @@ -938,58 +765,10 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, // 10 - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, // 20 - RoomListEntryEasy::Filled, // 20 - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, // 30 - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, // 40 - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, // 50 - ] + repeat(RoomListEntryEasy::Filled) + .take(21) + .chain(repeat(RoomListEntryEasy::Empty).take(29)) + .collect::>() ); // we have 50 and catch up in batches of 10. let's go two more, see it grow. @@ -1006,58 +785,10 @@ mod tests { .collect::>(); assert_eq!( collection_simple, - [ - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, // 10 - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, // 20 - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, // 30 - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, - RoomListEntryEasy::Filled, // 40 - RoomListEntryEasy::Filled, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, - RoomListEntryEasy::Empty, // 50 - ] + repeat(RoomListEntryEasy::Filled) + .take(41) + .chain(repeat(RoomListEntryEasy::Empty).take(9)) + .collect::>() ); Ok(()) @@ -1130,6 +861,96 @@ mod tests { Ok(()) } + #[tokio::test(flavor = "multi_thread", worker_threads = 4)] + async fn continue_on_reset() -> anyhow::Result<()> { + let (_client, sync_proxy_builder) = random_setup_with_rooms(30).await?; + print!("setup took its time"); + let growing_sync = SlidingSyncViewBuilder::default() + .sync_mode(SlidingSyncMode::GrowingFullSync) + .limit(100) + .sort(vec!["by_recency".to_string(), "by_name".to_string()]) + .name("growing") + .build()?; + + println!("starting the sliding sync setup"); + let sync_proxy = sync_proxy_builder + .clone() + .cold_cache("sliding_sync") + .add_view(growing_sync) + .build() + .await?; + let view = sync_proxy.view("growing").context("but we just added that view!")?; // let's catch it up fully. + let stream = sync_proxy.stream(); + pin_mut!(stream); + + for _n in 0..2 { + let room_summary = stream.next().await.context("sync has closed unexpectedly")?; + let summary = room_summary?; + if summary.views.iter().any(|s| s == "growing") { + break; + } + } + + let collection_simple = view + .rooms_list + .lock_ref() + .iter() + .map(Into::::into) + .collect::>(); + assert_eq!( + collection_simple.iter().fold(0, |acc, i| if *i == RoomListEntryEasy::Filled { + acc + 1 + } else { + acc + }), + 21 + ); + + // force the pos to be invalid and thus this being reset internally + force_sliding_sync_pos(&sync_proxy, "100".to_owned()); + let mut error_seen = false; + + for _n in 0..2 { + let summary = match stream.next().await { + Some(Ok(e)) => e, + Some(Err(e)) => { + match e.client_api_error_kind() { + Some(RumaError::UnknownPos) => { + // we expect this to come through. + error_seen = true; + continue; + } + _ => Err(e)?, + } + } + None => anyhow::bail!("Stream ended unexpectedly."), + }; + // we only heard about the ones we had asked for + if summary.views.iter().any(|s| s == "growing") { + break; + } + } + + assert!(error_seen, "We have not seen the UnknownPos error"); + + let collection_simple = view + .rooms_list + .lock_ref() + .iter() + .map(Into::::into) + .collect::>(); + assert_eq!( + collection_simple.iter().fold(0, |acc, i| if *i == RoomListEntryEasy::Filled { + acc + 1 + } else { + acc + }), + 30 + ); + + Ok(()) + } + #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn noticing_new_rooms_in_growing() -> anyhow::Result<()> { let (client, sync_proxy_builder) = random_setup_with_rooms(30).await?;