1use assert_matches::assert_matches;
18use async_trait::async_trait;
19use matrix_sdk_common::{
20 deserialized_responses::{
21 AlgorithmInfo, DecryptedRoomEvent, EncryptionInfo, TimelineEvent, TimelineEventKind,
22 VerificationState,
23 },
24 linked_chunk::{lazy_loader, ChunkContent, ChunkIdentifier as CId, Position, Update},
25};
26use matrix_sdk_test::{event_factory::EventFactory, ALICE, DEFAULT_TEST_ROOM_ID};
27use ruma::{
28 api::client::media::get_content_thumbnail::v3::Method, events::room::MediaSource, mxc_uri,
29 push::Action, room_id, uint, RoomId,
30};
31
32use super::{media::IgnoreMediaRetentionPolicy, DynEventCacheStore};
33use crate::{
34 event_cache::{store::DEFAULT_CHUNK_CAPACITY, Gap},
35 media::{MediaFormat, MediaRequestParameters, MediaThumbnailSettings},
36};
37
38pub fn make_test_event(room_id: &RoomId, content: &str) -> TimelineEvent {
43 let encryption_info = EncryptionInfo {
44 sender: (*ALICE).into(),
45 sender_device: None,
46 algorithm_info: AlgorithmInfo::MegolmV1AesSha2 {
47 curve25519_key: "1337".to_owned(),
48 sender_claimed_keys: Default::default(),
49 },
50 verification_state: VerificationState::Verified,
51 };
52
53 let event = EventFactory::new()
54 .text_msg(content)
55 .room(room_id)
56 .sender(*ALICE)
57 .into_raw_timeline()
58 .cast();
59
60 TimelineEvent {
61 kind: TimelineEventKind::Decrypted(DecryptedRoomEvent {
62 event,
63 encryption_info,
64 unsigned_encryption_info: None,
65 }),
66 push_actions: Some(vec![Action::Notify]),
67 }
68}
69
70#[track_caller]
75pub fn check_test_event(event: &TimelineEvent, text: &str) {
76 let actions = event.push_actions.as_ref().unwrap();
78 assert_eq!(actions.len(), 1);
79 assert_matches!(&actions[0], Action::Notify);
80
81 assert_matches!(&event.kind, TimelineEventKind::Decrypted(d) => {
83 assert_eq!(d.encryption_info.sender, *ALICE);
85 assert_matches!(&d.encryption_info.algorithm_info, AlgorithmInfo::MegolmV1AesSha2 { curve25519_key, .. } => {
86 assert_eq!(curve25519_key, "1337");
87 });
88
89 let deserialized = d.event.deserialize().unwrap();
91 assert_matches!(deserialized, ruma::events::AnyMessageLikeEvent::RoomMessage(msg) => {
92 assert_eq!(msg.as_original().unwrap().content.body(), text);
93 });
94 });
95}
96
97#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
102#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
103pub trait EventCacheStoreIntegrationTests {
104 async fn test_media_content(&self);
106
107 async fn test_replace_media_key(&self);
109
110 async fn test_handle_updates_and_rebuild_linked_chunk(&self);
113
114 async fn test_linked_chunk_incremental_loading(&self);
117
118 async fn test_rebuild_empty_linked_chunk(&self);
121
122 async fn test_clear_all_rooms_chunks(&self);
124
125 async fn test_remove_room(&self);
127
128 async fn test_filter_duplicated_events(&self);
130}
131
132#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
133#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
134impl EventCacheStoreIntegrationTests for DynEventCacheStore {
135 async fn test_media_content(&self) {
136 let uri = mxc_uri!("mxc://localhost/media");
137 let request_file = MediaRequestParameters {
138 source: MediaSource::Plain(uri.to_owned()),
139 format: MediaFormat::File,
140 };
141 let request_thumbnail = MediaRequestParameters {
142 source: MediaSource::Plain(uri.to_owned()),
143 format: MediaFormat::Thumbnail(MediaThumbnailSettings::with_method(
144 Method::Crop,
145 uint!(100),
146 uint!(100),
147 )),
148 };
149
150 let other_uri = mxc_uri!("mxc://localhost/media-other");
151 let request_other_file = MediaRequestParameters {
152 source: MediaSource::Plain(other_uri.to_owned()),
153 format: MediaFormat::File,
154 };
155
156 let content: Vec<u8> = "hello".into();
157 let thumbnail_content: Vec<u8> = "world".into();
158 let other_content: Vec<u8> = "foo".into();
159
160 assert!(
162 self.get_media_content(&request_file).await.unwrap().is_none(),
163 "unexpected media found"
164 );
165 assert!(
166 self.get_media_content(&request_thumbnail).await.unwrap().is_none(),
167 "media not found"
168 );
169
170 self.add_media_content(&request_file, content.clone(), IgnoreMediaRetentionPolicy::No)
172 .await
173 .expect("adding media failed");
174
175 assert_eq!(
177 self.get_media_content(&request_file).await.unwrap().as_ref(),
178 Some(&content),
179 "media not found though added"
180 );
181 assert_eq!(
182 self.get_media_content_for_uri(uri).await.unwrap().as_ref(),
183 Some(&content),
184 "media not found by URI though added"
185 );
186
187 self.remove_media_content(&request_file).await.expect("removing media failed");
189
190 assert!(
192 self.get_media_content(&request_file).await.unwrap().is_none(),
193 "media still there after removing"
194 );
195 assert!(
196 self.get_media_content_for_uri(uri).await.unwrap().is_none(),
197 "media still found by URI after removing"
198 );
199
200 self.add_media_content(&request_file, content.clone(), IgnoreMediaRetentionPolicy::No)
202 .await
203 .expect("adding media again failed");
204
205 assert_eq!(
206 self.get_media_content(&request_file).await.unwrap().as_ref(),
207 Some(&content),
208 "media not found after adding again"
209 );
210
211 self.add_media_content(
213 &request_thumbnail,
214 thumbnail_content.clone(),
215 IgnoreMediaRetentionPolicy::No,
216 )
217 .await
218 .expect("adding thumbnail failed");
219
220 assert_eq!(
222 self.get_media_content(&request_thumbnail).await.unwrap().as_ref(),
223 Some(&thumbnail_content),
224 "thumbnail not found"
225 );
226
227 assert!(
229 self.get_media_content_for_uri(uri).await.unwrap().is_some(),
230 "media not found by URI though two where added"
231 );
232
233 self.add_media_content(
235 &request_other_file,
236 other_content.clone(),
237 IgnoreMediaRetentionPolicy::No,
238 )
239 .await
240 .expect("adding other media failed");
241
242 assert_eq!(
244 self.get_media_content(&request_other_file).await.unwrap().as_ref(),
245 Some(&other_content),
246 "other file not found"
247 );
248 assert_eq!(
249 self.get_media_content_for_uri(other_uri).await.unwrap().as_ref(),
250 Some(&other_content),
251 "other file not found by URI"
252 );
253
254 self.remove_media_content_for_uri(uri).await.expect("removing all media for uri failed");
256
257 assert!(
258 self.get_media_content(&request_file).await.unwrap().is_none(),
259 "media wasn't removed"
260 );
261 assert!(
262 self.get_media_content(&request_thumbnail).await.unwrap().is_none(),
263 "thumbnail wasn't removed"
264 );
265 assert!(
266 self.get_media_content(&request_other_file).await.unwrap().is_some(),
267 "other media was removed"
268 );
269 assert!(
270 self.get_media_content_for_uri(uri).await.unwrap().is_none(),
271 "media found by URI wasn't removed"
272 );
273 assert!(
274 self.get_media_content_for_uri(other_uri).await.unwrap().is_some(),
275 "other media found by URI was removed"
276 );
277 }
278
279 async fn test_replace_media_key(&self) {
280 let uri = mxc_uri!("mxc://sendqueue.local/tr4n-s4ct-10n1-d");
281 let req = MediaRequestParameters {
282 source: MediaSource::Plain(uri.to_owned()),
283 format: MediaFormat::File,
284 };
285
286 let content = "hello".as_bytes().to_owned();
287
288 assert!(self.get_media_content(&req).await.unwrap().is_none(), "unexpected media found");
290
291 self.add_media_content(&req, content.clone(), IgnoreMediaRetentionPolicy::No)
293 .await
294 .expect("adding media failed");
295
296 assert_eq!(self.get_media_content(&req).await.unwrap().unwrap(), b"hello");
298
299 let new_uri = mxc_uri!("mxc://matrix.org/tr4n-s4ct-10n1-d");
301 let new_req = MediaRequestParameters {
302 source: MediaSource::Plain(new_uri.to_owned()),
303 format: MediaFormat::File,
304 };
305 self.replace_media_key(&req, &new_req)
306 .await
307 .expect("replacing the media request key failed");
308
309 assert!(
311 self.get_media_content(&req).await.unwrap().is_none(),
312 "unexpected media found with the old key"
313 );
314
315 assert_eq!(self.get_media_content(&new_req).await.unwrap().unwrap(), b"hello");
317 }
318
319 async fn test_handle_updates_and_rebuild_linked_chunk(&self) {
320 let room_id = room_id!("!r0:matrix.org");
321
322 self.handle_linked_chunk_updates(
323 room_id,
324 vec![
325 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
327 Update::PushItems {
329 at: Position::new(CId::new(0), 0),
330 items: vec![
331 make_test_event(room_id, "hello"),
332 make_test_event(room_id, "world"),
333 ],
334 },
335 Update::NewGapChunk {
337 previous: Some(CId::new(0)),
338 new: CId::new(1),
339 next: None,
340 gap: Gap { prev_token: "parmesan".to_owned() },
341 },
342 Update::NewItemsChunk { previous: Some(CId::new(1)), new: CId::new(2), next: None },
344 Update::PushItems {
346 at: Position::new(CId::new(2), 0),
347 items: vec![make_test_event(room_id, "sup")],
348 },
349 ],
350 )
351 .await
352 .unwrap();
353
354 let lc =
356 lazy_loader::from_all_chunks::<3, _, _>(self.load_all_chunks(room_id).await.unwrap())
357 .unwrap()
358 .unwrap();
359
360 let mut chunks = lc.chunks();
361
362 {
363 let first = chunks.next().unwrap();
364 assert_eq!(first.identifier(), CId::new(0));
367
368 assert_matches!(first.content(), ChunkContent::Items(events) => {
369 assert_eq!(events.len(), 2);
370 check_test_event(&events[0], "hello");
371 check_test_event(&events[1], "world");
372 });
373 }
374
375 {
376 let second = chunks.next().unwrap();
377 assert_eq!(second.identifier(), CId::new(1));
378
379 assert_matches!(second.content(), ChunkContent::Gap(gap) => {
380 assert_eq!(gap.prev_token, "parmesan");
381 });
382 }
383
384 {
385 let third = chunks.next().unwrap();
386 assert_eq!(third.identifier(), CId::new(2));
387
388 assert_matches!(third.content(), ChunkContent::Items(events) => {
389 assert_eq!(events.len(), 1);
390 check_test_event(&events[0], "sup");
391 });
392 }
393
394 assert!(chunks.next().is_none());
395 }
396
397 async fn test_linked_chunk_incremental_loading(&self) {
398 let room_id = room_id!("!r0:matrix.org");
399 let event = |msg: &str| make_test_event(room_id, msg);
400
401 {
403 let (last_chunk, chunk_identifier_generator) =
404 self.load_last_chunk(room_id).await.unwrap();
405
406 assert!(last_chunk.is_none());
407 assert_eq!(chunk_identifier_generator.current(), 0);
408 }
409
410 self.handle_linked_chunk_updates(
411 room_id,
412 vec![
413 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
415 Update::PushItems {
417 at: Position::new(CId::new(0), 0),
418 items: vec![event("a"), event("b")],
419 },
420 Update::NewGapChunk {
422 previous: Some(CId::new(0)),
423 new: CId::new(1),
424 next: None,
425 gap: Gap { prev_token: "morbier".to_owned() },
426 },
427 Update::NewItemsChunk { previous: Some(CId::new(1)), new: CId::new(2), next: None },
429 Update::PushItems {
431 at: Position::new(CId::new(2), 0),
432 items: vec![event("c"), event("d"), event("e")],
433 },
434 ],
435 )
436 .await
437 .unwrap();
438
439 let mut linked_chunk = {
441 let (last_chunk, chunk_identifier_generator) =
442 self.load_last_chunk(room_id).await.unwrap();
443
444 assert_eq!(chunk_identifier_generator.current(), 2);
445
446 let linked_chunk = lazy_loader::from_last_chunk::<DEFAULT_CHUNK_CAPACITY, _, _>(
447 last_chunk,
448 chunk_identifier_generator,
449 )
450 .unwrap() .unwrap(); let mut rchunks = linked_chunk.rchunks();
454
455 assert_matches!(rchunks.next(), Some(chunk) => {
457 assert_eq!(chunk.identifier(), 2);
458
459 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
460 assert_eq!(events.len(), 3);
461 check_test_event(&events[0], "c");
462 check_test_event(&events[1], "d");
463 check_test_event(&events[2], "e");
464 });
465 });
466
467 assert!(rchunks.next().is_none());
468
469 linked_chunk
470 };
471
472 {
474 let first_chunk = linked_chunk.chunks().next().unwrap().identifier();
475 let mut previous_chunk =
476 self.load_previous_chunk(room_id, first_chunk).await.unwrap().unwrap();
477
478 previous_chunk.previous = None;
480
481 let _ = lazy_loader::insert_new_first_chunk(&mut linked_chunk, previous_chunk).unwrap();
482
483 let mut rchunks = linked_chunk.rchunks();
484
485 assert_matches!(rchunks.next(), Some(chunk) => {
487 assert_eq!(chunk.identifier(), 2);
488
489 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
491 assert_eq!(events.len(), 3);
492 check_test_event(&events[0], "c");
493 check_test_event(&events[1], "d");
494 check_test_event(&events[2], "e");
495 });
496 });
497
498 assert_matches!(rchunks.next(), Some(chunk) => {
500 assert_eq!(chunk.identifier(), 1);
501
502 assert_matches!(chunk.content(), ChunkContent::Gap(gap) => {
503 assert_eq!(gap.prev_token, "morbier");
504 });
505 });
506
507 assert!(rchunks.next().is_none());
508 }
509
510 {
512 let first_chunk = linked_chunk.chunks().next().unwrap().identifier();
513 let previous_chunk =
514 self.load_previous_chunk(room_id, first_chunk).await.unwrap().unwrap();
515
516 let _ = lazy_loader::insert_new_first_chunk(&mut linked_chunk, previous_chunk).unwrap();
517
518 let mut rchunks = linked_chunk.rchunks();
519
520 assert_matches!(rchunks.next(), Some(chunk) => {
522 assert_eq!(chunk.identifier(), 2);
523
524 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
526 assert_eq!(events.len(), 3);
527 check_test_event(&events[0], "c");
528 check_test_event(&events[1], "d");
529 check_test_event(&events[2], "e");
530 });
531 });
532
533 assert_matches!(rchunks.next(), Some(chunk) => {
535 assert_eq!(chunk.identifier(), 1);
536
537 assert_matches!(chunk.content(), ChunkContent::Gap(gap) => {
539 assert_eq!(gap.prev_token, "morbier");
540 });
541 });
542
543 assert_matches!(rchunks.next(), Some(chunk) => {
545 assert_eq!(chunk.identifier(), 0);
546
547 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
548 assert_eq!(events.len(), 2);
549 check_test_event(&events[0], "a");
550 check_test_event(&events[1], "b");
551 });
552 });
553
554 assert!(rchunks.next().is_none());
555 }
556
557 {
559 let first_chunk = linked_chunk.chunks().next().unwrap().identifier();
560 let previous_chunk = self.load_previous_chunk(room_id, first_chunk).await.unwrap();
561
562 assert!(previous_chunk.is_none());
563 }
564
565 {
568 let mut chunks = linked_chunk.chunks();
569
570 assert_matches!(chunks.next(), Some(chunk) => {
572 assert_eq!(chunk.identifier(), 0);
573
574 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
575 assert_eq!(events.len(), 2);
576 check_test_event(&events[0], "a");
577 check_test_event(&events[1], "b");
578 });
579 });
580
581 assert_matches!(chunks.next(), Some(chunk) => {
583 assert_eq!(chunk.identifier(), 1);
584
585 assert_matches!(chunk.content(), ChunkContent::Gap(gap) => {
586 assert_eq!(gap.prev_token, "morbier");
587 });
588 });
589
590 assert_matches!(chunks.next(), Some(chunk) => {
592 assert_eq!(chunk.identifier(), 2);
593
594 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
595 assert_eq!(events.len(), 3);
596 check_test_event(&events[0], "c");
597 check_test_event(&events[1], "d");
598 check_test_event(&events[2], "e");
599 });
600 });
601
602 assert!(chunks.next().is_none());
603 }
604 }
605
606 async fn test_rebuild_empty_linked_chunk(&self) {
607 let linked_chunk = lazy_loader::from_all_chunks::<3, _, _>(
609 self.load_all_chunks(&DEFAULT_TEST_ROOM_ID).await.unwrap(),
610 )
611 .unwrap();
612 assert!(linked_chunk.is_none());
613 }
614
615 async fn test_clear_all_rooms_chunks(&self) {
616 let r0 = room_id!("!r0:matrix.org");
617 let r1 = room_id!("!r1:matrix.org");
618
619 self.handle_linked_chunk_updates(
621 r0,
622 vec![
623 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
625 Update::PushItems {
627 at: Position::new(CId::new(0), 0),
628 items: vec![make_test_event(r0, "hello"), make_test_event(r0, "world")],
629 },
630 ],
631 )
632 .await
633 .unwrap();
634
635 self.handle_linked_chunk_updates(
637 r1,
638 vec![
639 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
641 Update::NewGapChunk {
643 previous: Some(CId::new(0)),
644 new: CId::new(1),
645 next: None,
646 gap: Gap { prev_token: "bleu d'auvergne".to_owned() },
647 },
648 Update::NewItemsChunk { previous: Some(CId::new(1)), new: CId::new(2), next: None },
650 Update::PushItems {
652 at: Position::new(CId::new(2), 0),
653 items: vec![make_test_event(r0, "yummy")],
654 },
655 ],
656 )
657 .await
658 .unwrap();
659
660 assert!(lazy_loader::from_all_chunks::<3, _, _>(self.load_all_chunks(r0).await.unwrap())
662 .unwrap()
663 .is_some());
664 assert!(lazy_loader::from_all_chunks::<3, _, _>(self.load_all_chunks(r1).await.unwrap())
665 .unwrap()
666 .is_some());
667
668 self.clear_all_rooms_chunks().await.unwrap();
670
671 assert!(lazy_loader::from_all_chunks::<3, _, _>(self.load_all_chunks(r0).await.unwrap())
673 .unwrap()
674 .is_none());
675 assert!(lazy_loader::from_all_chunks::<3, _, _>(self.load_all_chunks(r1).await.unwrap())
676 .unwrap()
677 .is_none());
678 }
679
680 async fn test_remove_room(&self) {
681 let r0 = room_id!("!r0:matrix.org");
682 let r1 = room_id!("!r1:matrix.org");
683
684 self.handle_linked_chunk_updates(
686 r0,
687 vec![
688 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
690 Update::PushItems {
692 at: Position::new(CId::new(0), 0),
693 items: vec![make_test_event(r0, "hello"), make_test_event(r0, "world")],
694 },
695 ],
696 )
697 .await
698 .unwrap();
699
700 self.handle_linked_chunk_updates(
702 r1,
703 vec![
704 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
706 Update::PushItems {
708 at: Position::new(CId::new(0), 0),
709 items: vec![make_test_event(r0, "yummy")],
710 },
711 ],
712 )
713 .await
714 .unwrap();
715
716 self.remove_room(r0).await.unwrap();
718
719 let r0_linked_chunk = self.load_all_chunks(r0).await.unwrap();
721 assert!(r0_linked_chunk.is_empty());
722
723 let r1_linked_chunk = self.load_all_chunks(r1).await.unwrap();
725 assert!(!r1_linked_chunk.is_empty());
726 }
727
728 async fn test_filter_duplicated_events(&self) {
729 let room_id = room_id!("!r0:matrix.org");
730 let another_room_id = room_id!("!r1:matrix.org");
731 let event = |msg: &str| make_test_event(room_id, msg);
732
733 let event_comte = event("comté");
734 let event_brigand = event("brigand du jorat");
735 let event_raclette = event("raclette");
736 let event_morbier = event("morbier");
737 let event_gruyere = event("gruyère");
738 let event_tome = event("tome");
739 let event_mont_dor = event("mont d'or");
740
741 self.handle_linked_chunk_updates(
742 room_id,
743 vec![
744 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
745 Update::PushItems {
746 at: Position::new(CId::new(0), 0),
747 items: vec![event_comte.clone(), event_brigand.clone()],
748 },
749 Update::NewGapChunk {
750 previous: Some(CId::new(0)),
751 new: CId::new(1),
752 next: None,
753 gap: Gap { prev_token: "brillat-savarin".to_owned() },
754 },
755 Update::NewItemsChunk { previous: Some(CId::new(1)), new: CId::new(2), next: None },
756 Update::PushItems {
757 at: Position::new(CId::new(2), 0),
758 items: vec![event_morbier.clone(), event_mont_dor.clone()],
759 },
760 ],
761 )
762 .await
763 .unwrap();
764
765 self.handle_linked_chunk_updates(
768 another_room_id,
769 vec![
770 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
771 Update::PushItems {
772 at: Position::new(CId::new(0), 0),
773 items: vec![event_tome.clone()],
774 },
775 ],
776 )
777 .await
778 .unwrap();
779
780 let duplicated_events = self
781 .filter_duplicated_events(
782 room_id,
783 vec![
784 event_comte.event_id().unwrap().to_owned(),
785 event_raclette.event_id().unwrap().to_owned(),
786 event_morbier.event_id().unwrap().to_owned(),
787 event_gruyere.event_id().unwrap().to_owned(),
788 event_tome.event_id().unwrap().to_owned(),
789 event_mont_dor.event_id().unwrap().to_owned(),
790 ],
791 )
792 .await
793 .unwrap();
794
795 assert_eq!(duplicated_events.len(), 3);
796 assert_eq!(duplicated_events[0], event_comte.event_id().unwrap());
797 assert_eq!(duplicated_events[1], event_morbier.event_id().unwrap());
798 assert_eq!(duplicated_events[2], event_mont_dor.event_id().unwrap());
799 }
800}
801
802#[allow(unused_macros, unused_extern_crates)]
830#[macro_export]
831macro_rules! event_cache_store_integration_tests {
832 () => {
833 mod event_cache_store_integration_tests {
834 use matrix_sdk_test::async_test;
835 use $crate::event_cache::store::{
836 EventCacheStoreIntegrationTests, IntoEventCacheStore,
837 };
838
839 use super::get_event_cache_store;
840
841 #[async_test]
842 async fn test_media_content() {
843 let event_cache_store =
844 get_event_cache_store().await.unwrap().into_event_cache_store();
845 event_cache_store.test_media_content().await;
846 }
847
848 #[async_test]
849 async fn test_replace_media_key() {
850 let event_cache_store =
851 get_event_cache_store().await.unwrap().into_event_cache_store();
852 event_cache_store.test_replace_media_key().await;
853 }
854
855 #[async_test]
856 async fn test_handle_updates_and_rebuild_linked_chunk() {
857 let event_cache_store =
858 get_event_cache_store().await.unwrap().into_event_cache_store();
859 event_cache_store.test_handle_updates_and_rebuild_linked_chunk().await;
860 }
861
862 #[async_test]
863 async fn test_linked_chunk_incremental_loading() {
864 let event_cache_store =
865 get_event_cache_store().await.unwrap().into_event_cache_store();
866 event_cache_store.test_linked_chunk_incremental_loading().await;
867 }
868
869 #[async_test]
870 async fn test_rebuild_empty_linked_chunk() {
871 let event_cache_store =
872 get_event_cache_store().await.unwrap().into_event_cache_store();
873 event_cache_store.test_rebuild_empty_linked_chunk().await;
874 }
875
876 #[async_test]
877 async fn test_clear_all_rooms_chunks() {
878 let event_cache_store =
879 get_event_cache_store().await.unwrap().into_event_cache_store();
880 event_cache_store.test_clear_all_rooms_chunks().await;
881 }
882
883 #[async_test]
884 async fn test_remove_room() {
885 let event_cache_store =
886 get_event_cache_store().await.unwrap().into_event_cache_store();
887 event_cache_store.test_remove_room().await;
888 }
889
890 #[async_test]
891 async fn test_filter_duplicated_events() {
892 let event_cache_store =
893 get_event_cache_store().await.unwrap().into_event_cache_store();
894 event_cache_store.test_filter_duplicated_events().await;
895 }
896 }
897 };
898}
899
900#[allow(unused_macros)]
903#[macro_export]
904macro_rules! event_cache_store_integration_tests_time {
905 () => {
906 #[cfg(not(target_arch = "wasm32"))]
907 mod event_cache_store_integration_tests_time {
908 use std::time::Duration;
909
910 use matrix_sdk_test::async_test;
911 use $crate::event_cache::store::IntoEventCacheStore;
912
913 use super::get_event_cache_store;
914
915 #[async_test]
916 async fn test_lease_locks() {
917 let store = get_event_cache_store().await.unwrap().into_event_cache_store();
918
919 let acquired0 = store.try_take_leased_lock(0, "key", "alice").await.unwrap();
920 assert!(acquired0);
921
922 let acquired2 = store.try_take_leased_lock(300, "key", "alice").await.unwrap();
924 assert!(acquired2);
925
926 let acquired3 = store.try_take_leased_lock(300, "key", "alice").await.unwrap();
928 assert!(acquired3);
929
930 let acquired4 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
932 assert!(!acquired4);
933
934 let acquired5 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
936 assert!(!acquired5);
937
938 tokio::time::sleep(Duration::from_millis(50)).await;
940
941 let acquired55 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
943 assert!(!acquired55);
944
945 tokio::time::sleep(Duration::from_millis(250)).await;
947
948 let acquired6 = store.try_take_leased_lock(0, "key", "bob").await.unwrap();
950 assert!(acquired6);
951
952 tokio::time::sleep(Duration::from_millis(1)).await;
953
954 let acquired7 = store.try_take_leased_lock(0, "key", "alice").await.unwrap();
956 assert!(acquired7);
957
958 tokio::time::sleep(Duration::from_millis(1)).await;
959
960 let acquired8 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
962 assert!(acquired8);
963
964 let acquired9 = store.try_take_leased_lock(300, "key", "alice").await.unwrap();
966 assert!(!acquired9);
967
968 let acquired10 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
970 assert!(acquired10);
971 }
972 }
973 };
974}