Skip to content

Commit f5f8f47

Browse files
committed
integration test: fix racy behavior in the test_toggling_reaction
The room sync could be over, and then the timeline items would not contain the updated item yet, if the timeline didn't get a chance to finish its internal update. Fix this by: 1. limiting the sync time to 10 seconds 2. giving up to one second for the timeline to update internally, by watching its stream of events (we're ignoring stream updates just after this loop)
1 parent c418f0e commit f5f8f47

File tree

1 file changed

+33
-15
lines changed
  • testing/matrix-sdk-integration-testing/src/tests

1 file changed

+33
-15
lines changed

testing/matrix-sdk-integration-testing/src/tests/reactions.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
use std::{sync::Arc, time::Duration};
1616

17-
use anyhow::{Ok, Result};
17+
use anyhow::Result;
1818
use assert_matches::assert_matches;
1919
use assert_matches2::assert_let;
2020
use assign::assign;
@@ -35,16 +35,34 @@ use tokio::time::timeout;
3535

3636
use crate::helpers::TestClientBuilder;
3737

38+
/// Sync until we receive an update for a room.
39+
///
40+
/// Beware: it may sync forever, if it doesn't receive such an update!
41+
async fn sync_until_update_for_room(client: &Client, room_id: &RoomId) -> Result<()> {
42+
client
43+
.sync_with_callback(SyncSettings::default(), |response| async move {
44+
if response.rooms.join.iter().any(|(id, _)| id == room_id) {
45+
LoopCtrl::Break
46+
} else {
47+
LoopCtrl::Continue
48+
}
49+
})
50+
.await?;
51+
Ok(())
52+
}
53+
3854
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
3955
async fn test_toggling_reaction() -> Result<()> {
4056
// Set up sync for user Alice, and create a room.
4157
let alice = TestClientBuilder::new("alice".to_owned()).use_sqlite().build().await?;
58+
4259
let user_id = alice.user_id().unwrap().to_owned();
4360
let room = alice
4461
.create_room(assign!(CreateRoomRequest::new(), {
4562
is_direct: true,
4663
}))
4764
.await?;
65+
4866
let room_id = room.room_id();
4967

5068
// Create a timeline for this room.
@@ -57,12 +75,25 @@ async fn test_toggling_reaction() -> Result<()> {
5775
// Sync until the remote echo arrives.
5876
let mut num_attempts = 0;
5977
let event_id = loop {
60-
sync_room(&alice, room_id).await?;
78+
// We expect a quick update from sync, so timeout after 10 seconds, and ignore
79+
// timeouts; they might just indicate we received the necessary
80+
// information on the previous attempt, but racily tried to read the
81+
// timeline items.
82+
if let Ok(sync_result) =
83+
timeout(Duration::from_secs(10), sync_until_update_for_room(&alice, room_id)).await
84+
{
85+
sync_result?;
86+
}
87+
88+
// Let time to the timeline for processing the update, at most 1 second.
89+
let _ = timeout(Duration::from_secs(1), stream.next()).await;
90+
6191
let items = timeline.items().await;
6292
let last_item = items.last().unwrap().as_event().unwrap();
6393
if !last_item.is_local_echo() {
6494
break last_item.event_id().unwrap().to_owned();
6595
}
96+
6697
if num_attempts == 2 {
6798
panic!("had 3 sync responses and no echo of our own event");
6899
}
@@ -181,19 +212,6 @@ async fn assert_remote_added(
181212
assert!(reaction.unwrap().timestamp <= MilliSecondsSinceUnixEpoch::now());
182213
}
183214

184-
async fn sync_room(client: &Client, room_id: &RoomId) -> Result<()> {
185-
client
186-
.sync_with_callback(SyncSettings::default(), |response| async move {
187-
if response.rooms.join.iter().any(|(id, _)| id == room_id) {
188-
LoopCtrl::Break
189-
} else {
190-
LoopCtrl::Continue
191-
}
192-
})
193-
.await?;
194-
Ok(())
195-
}
196-
197215
async fn assert_event_is_updated(
198216
stream: &mut (impl Stream<Item = VectorDiff<Arc<TimelineItem>>> + Unpin),
199217
event_id: &EventId,

0 commit comments

Comments
 (0)