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 session_id: Some("mysessionid9".to_owned()),
52 };
53
54 let event = EventFactory::new()
55 .text_msg(content)
56 .room(room_id)
57 .sender(*ALICE)
58 .into_raw_timeline()
59 .cast();
60
61 TimelineEvent {
62 kind: TimelineEventKind::Decrypted(DecryptedRoomEvent {
63 event,
64 encryption_info,
65 unsigned_encryption_info: None,
66 }),
67 push_actions: Some(vec![Action::Notify]),
68 }
69}
70
71#[track_caller]
76pub fn check_test_event(event: &TimelineEvent, text: &str) {
77 let actions = event.push_actions.as_ref().unwrap();
79 assert_eq!(actions.len(), 1);
80 assert_matches!(&actions[0], Action::Notify);
81
82 assert_matches!(&event.kind, TimelineEventKind::Decrypted(d) => {
84 assert_eq!(d.encryption_info.sender, *ALICE);
86 assert_matches!(&d.encryption_info.algorithm_info, AlgorithmInfo::MegolmV1AesSha2 { curve25519_key, .. } => {
87 assert_eq!(curve25519_key, "1337");
88 });
89
90 let deserialized = d.event.deserialize().unwrap();
92 assert_matches!(deserialized, ruma::events::AnyMessageLikeEvent::RoomMessage(msg) => {
93 assert_eq!(msg.as_original().unwrap().content.body(), text);
94 });
95 });
96}
97
98#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
103#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
104pub trait EventCacheStoreIntegrationTests {
105 async fn test_media_content(&self);
107
108 async fn test_replace_media_key(&self);
110
111 async fn test_handle_updates_and_rebuild_linked_chunk(&self);
114
115 async fn test_linked_chunk_incremental_loading(&self);
118
119 async fn test_rebuild_empty_linked_chunk(&self);
122
123 async fn test_clear_all_rooms_chunks(&self);
125
126 async fn test_remove_room(&self);
128
129 async fn test_filter_duplicated_events(&self);
131
132 async fn test_find_event(&self);
134}
135
136#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
137#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
138impl EventCacheStoreIntegrationTests for DynEventCacheStore {
139 async fn test_media_content(&self) {
140 let uri = mxc_uri!("mxc://localhost/media");
141 let request_file = MediaRequestParameters {
142 source: MediaSource::Plain(uri.to_owned()),
143 format: MediaFormat::File,
144 };
145 let request_thumbnail = MediaRequestParameters {
146 source: MediaSource::Plain(uri.to_owned()),
147 format: MediaFormat::Thumbnail(MediaThumbnailSettings::with_method(
148 Method::Crop,
149 uint!(100),
150 uint!(100),
151 )),
152 };
153
154 let other_uri = mxc_uri!("mxc://localhost/media-other");
155 let request_other_file = MediaRequestParameters {
156 source: MediaSource::Plain(other_uri.to_owned()),
157 format: MediaFormat::File,
158 };
159
160 let content: Vec<u8> = "hello".into();
161 let thumbnail_content: Vec<u8> = "world".into();
162 let other_content: Vec<u8> = "foo".into();
163
164 assert!(
166 self.get_media_content(&request_file).await.unwrap().is_none(),
167 "unexpected media found"
168 );
169 assert!(
170 self.get_media_content(&request_thumbnail).await.unwrap().is_none(),
171 "media not found"
172 );
173
174 self.add_media_content(&request_file, content.clone(), IgnoreMediaRetentionPolicy::No)
176 .await
177 .expect("adding media failed");
178
179 assert_eq!(
181 self.get_media_content(&request_file).await.unwrap().as_ref(),
182 Some(&content),
183 "media not found though added"
184 );
185 assert_eq!(
186 self.get_media_content_for_uri(uri).await.unwrap().as_ref(),
187 Some(&content),
188 "media not found by URI though added"
189 );
190
191 self.remove_media_content(&request_file).await.expect("removing media failed");
193
194 assert!(
196 self.get_media_content(&request_file).await.unwrap().is_none(),
197 "media still there after removing"
198 );
199 assert!(
200 self.get_media_content_for_uri(uri).await.unwrap().is_none(),
201 "media still found by URI after removing"
202 );
203
204 self.add_media_content(&request_file, content.clone(), IgnoreMediaRetentionPolicy::No)
206 .await
207 .expect("adding media again failed");
208
209 assert_eq!(
210 self.get_media_content(&request_file).await.unwrap().as_ref(),
211 Some(&content),
212 "media not found after adding again"
213 );
214
215 self.add_media_content(
217 &request_thumbnail,
218 thumbnail_content.clone(),
219 IgnoreMediaRetentionPolicy::No,
220 )
221 .await
222 .expect("adding thumbnail failed");
223
224 assert_eq!(
226 self.get_media_content(&request_thumbnail).await.unwrap().as_ref(),
227 Some(&thumbnail_content),
228 "thumbnail not found"
229 );
230
231 assert!(
233 self.get_media_content_for_uri(uri).await.unwrap().is_some(),
234 "media not found by URI though two where added"
235 );
236
237 self.add_media_content(
239 &request_other_file,
240 other_content.clone(),
241 IgnoreMediaRetentionPolicy::No,
242 )
243 .await
244 .expect("adding other media failed");
245
246 assert_eq!(
248 self.get_media_content(&request_other_file).await.unwrap().as_ref(),
249 Some(&other_content),
250 "other file not found"
251 );
252 assert_eq!(
253 self.get_media_content_for_uri(other_uri).await.unwrap().as_ref(),
254 Some(&other_content),
255 "other file not found by URI"
256 );
257
258 self.remove_media_content_for_uri(uri).await.expect("removing all media for uri failed");
260
261 assert!(
262 self.get_media_content(&request_file).await.unwrap().is_none(),
263 "media wasn't removed"
264 );
265 assert!(
266 self.get_media_content(&request_thumbnail).await.unwrap().is_none(),
267 "thumbnail wasn't removed"
268 );
269 assert!(
270 self.get_media_content(&request_other_file).await.unwrap().is_some(),
271 "other media was removed"
272 );
273 assert!(
274 self.get_media_content_for_uri(uri).await.unwrap().is_none(),
275 "media found by URI wasn't removed"
276 );
277 assert!(
278 self.get_media_content_for_uri(other_uri).await.unwrap().is_some(),
279 "other media found by URI was removed"
280 );
281 }
282
283 async fn test_replace_media_key(&self) {
284 let uri = mxc_uri!("mxc://sendqueue.local/tr4n-s4ct-10n1-d");
285 let req = MediaRequestParameters {
286 source: MediaSource::Plain(uri.to_owned()),
287 format: MediaFormat::File,
288 };
289
290 let content = "hello".as_bytes().to_owned();
291
292 assert!(self.get_media_content(&req).await.unwrap().is_none(), "unexpected media found");
294
295 self.add_media_content(&req, content.clone(), IgnoreMediaRetentionPolicy::No)
297 .await
298 .expect("adding media failed");
299
300 assert_eq!(self.get_media_content(&req).await.unwrap().unwrap(), b"hello");
302
303 let new_uri = mxc_uri!("mxc://matrix.org/tr4n-s4ct-10n1-d");
305 let new_req = MediaRequestParameters {
306 source: MediaSource::Plain(new_uri.to_owned()),
307 format: MediaFormat::File,
308 };
309 self.replace_media_key(&req, &new_req)
310 .await
311 .expect("replacing the media request key failed");
312
313 assert!(
315 self.get_media_content(&req).await.unwrap().is_none(),
316 "unexpected media found with the old key"
317 );
318
319 assert_eq!(self.get_media_content(&new_req).await.unwrap().unwrap(), b"hello");
321 }
322
323 async fn test_handle_updates_and_rebuild_linked_chunk(&self) {
324 let room_id = room_id!("!r0:matrix.org");
325
326 self.handle_linked_chunk_updates(
327 room_id,
328 vec![
329 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
331 Update::PushItems {
333 at: Position::new(CId::new(0), 0),
334 items: vec![
335 make_test_event(room_id, "hello"),
336 make_test_event(room_id, "world"),
337 ],
338 },
339 Update::NewGapChunk {
341 previous: Some(CId::new(0)),
342 new: CId::new(1),
343 next: None,
344 gap: Gap { prev_token: "parmesan".to_owned() },
345 },
346 Update::NewItemsChunk { previous: Some(CId::new(1)), new: CId::new(2), next: None },
348 Update::PushItems {
350 at: Position::new(CId::new(2), 0),
351 items: vec![make_test_event(room_id, "sup")],
352 },
353 ],
354 )
355 .await
356 .unwrap();
357
358 let lc =
360 lazy_loader::from_all_chunks::<3, _, _>(self.load_all_chunks(room_id).await.unwrap())
361 .unwrap()
362 .unwrap();
363
364 let mut chunks = lc.chunks();
365
366 {
367 let first = chunks.next().unwrap();
368 assert_eq!(first.identifier(), CId::new(0));
371
372 assert_matches!(first.content(), ChunkContent::Items(events) => {
373 assert_eq!(events.len(), 2);
374 check_test_event(&events[0], "hello");
375 check_test_event(&events[1], "world");
376 });
377 }
378
379 {
380 let second = chunks.next().unwrap();
381 assert_eq!(second.identifier(), CId::new(1));
382
383 assert_matches!(second.content(), ChunkContent::Gap(gap) => {
384 assert_eq!(gap.prev_token, "parmesan");
385 });
386 }
387
388 {
389 let third = chunks.next().unwrap();
390 assert_eq!(third.identifier(), CId::new(2));
391
392 assert_matches!(third.content(), ChunkContent::Items(events) => {
393 assert_eq!(events.len(), 1);
394 check_test_event(&events[0], "sup");
395 });
396 }
397
398 assert!(chunks.next().is_none());
399 }
400
401 async fn test_linked_chunk_incremental_loading(&self) {
402 let room_id = room_id!("!r0:matrix.org");
403 let event = |msg: &str| make_test_event(room_id, msg);
404
405 {
407 let (last_chunk, chunk_identifier_generator) =
408 self.load_last_chunk(room_id).await.unwrap();
409
410 assert!(last_chunk.is_none());
411 assert_eq!(chunk_identifier_generator.current(), 0);
412 }
413
414 self.handle_linked_chunk_updates(
415 room_id,
416 vec![
417 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
419 Update::PushItems {
421 at: Position::new(CId::new(0), 0),
422 items: vec![event("a"), event("b")],
423 },
424 Update::NewGapChunk {
426 previous: Some(CId::new(0)),
427 new: CId::new(1),
428 next: None,
429 gap: Gap { prev_token: "morbier".to_owned() },
430 },
431 Update::NewItemsChunk { previous: Some(CId::new(1)), new: CId::new(2), next: None },
433 Update::PushItems {
435 at: Position::new(CId::new(2), 0),
436 items: vec![event("c"), event("d"), event("e")],
437 },
438 ],
439 )
440 .await
441 .unwrap();
442
443 let mut linked_chunk = {
445 let (last_chunk, chunk_identifier_generator) =
446 self.load_last_chunk(room_id).await.unwrap();
447
448 assert_eq!(chunk_identifier_generator.current(), 2);
449
450 let linked_chunk = lazy_loader::from_last_chunk::<DEFAULT_CHUNK_CAPACITY, _, _>(
451 last_chunk,
452 chunk_identifier_generator,
453 )
454 .unwrap() .unwrap(); let mut rchunks = linked_chunk.rchunks();
458
459 assert_matches!(rchunks.next(), Some(chunk) => {
461 assert_eq!(chunk.identifier(), 2);
462 assert_eq!(chunk.lazy_previous(), Some(CId::new(1)));
463
464 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
465 assert_eq!(events.len(), 3);
466 check_test_event(&events[0], "c");
467 check_test_event(&events[1], "d");
468 check_test_event(&events[2], "e");
469 });
470 });
471
472 assert!(rchunks.next().is_none());
473
474 linked_chunk
475 };
476
477 {
479 let first_chunk = linked_chunk.chunks().next().unwrap().identifier();
480 let previous_chunk =
481 self.load_previous_chunk(room_id, first_chunk).await.unwrap().unwrap();
482
483 let _ = lazy_loader::insert_new_first_chunk(&mut linked_chunk, previous_chunk).unwrap();
484
485 let mut rchunks = linked_chunk.rchunks();
486
487 assert_matches!(rchunks.next(), Some(chunk) => {
489 assert_eq!(chunk.identifier(), 2);
490 assert!(chunk.lazy_previous().is_none());
491
492 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
494 assert_eq!(events.len(), 3);
495 check_test_event(&events[0], "c");
496 check_test_event(&events[1], "d");
497 check_test_event(&events[2], "e");
498 });
499 });
500
501 assert_matches!(rchunks.next(), Some(chunk) => {
503 assert_eq!(chunk.identifier(), 1);
504 assert_eq!(chunk.lazy_previous(), Some(CId::new(0)));
505
506 assert_matches!(chunk.content(), ChunkContent::Gap(gap) => {
507 assert_eq!(gap.prev_token, "morbier");
508 });
509 });
510
511 assert!(rchunks.next().is_none());
512 }
513
514 {
516 let first_chunk = linked_chunk.chunks().next().unwrap().identifier();
517 let previous_chunk =
518 self.load_previous_chunk(room_id, first_chunk).await.unwrap().unwrap();
519
520 let _ = lazy_loader::insert_new_first_chunk(&mut linked_chunk, previous_chunk).unwrap();
521
522 let mut rchunks = linked_chunk.rchunks();
523
524 assert_matches!(rchunks.next(), Some(chunk) => {
526 assert_eq!(chunk.identifier(), 2);
527 assert!(chunk.lazy_previous().is_none());
528
529 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
531 assert_eq!(events.len(), 3);
532 check_test_event(&events[0], "c");
533 check_test_event(&events[1], "d");
534 check_test_event(&events[2], "e");
535 });
536 });
537
538 assert_matches!(rchunks.next(), Some(chunk) => {
540 assert_eq!(chunk.identifier(), 1);
541 assert!(chunk.lazy_previous().is_none());
542
543 assert_matches!(chunk.content(), ChunkContent::Gap(gap) => {
545 assert_eq!(gap.prev_token, "morbier");
546 });
547 });
548
549 assert_matches!(rchunks.next(), Some(chunk) => {
551 assert_eq!(chunk.identifier(), 0);
552 assert!(chunk.lazy_previous().is_none());
553
554 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
555 assert_eq!(events.len(), 2);
556 check_test_event(&events[0], "a");
557 check_test_event(&events[1], "b");
558 });
559 });
560
561 assert!(rchunks.next().is_none());
562 }
563
564 {
566 let first_chunk = linked_chunk.chunks().next().unwrap().identifier();
567 let previous_chunk = self.load_previous_chunk(room_id, first_chunk).await.unwrap();
568
569 assert!(previous_chunk.is_none());
570 }
571
572 {
575 let mut chunks = linked_chunk.chunks();
576
577 assert_matches!(chunks.next(), Some(chunk) => {
579 assert_eq!(chunk.identifier(), 0);
580 assert!(chunk.lazy_previous().is_none());
581
582 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
583 assert_eq!(events.len(), 2);
584 check_test_event(&events[0], "a");
585 check_test_event(&events[1], "b");
586 });
587 });
588
589 assert_matches!(chunks.next(), Some(chunk) => {
591 assert_eq!(chunk.identifier(), 1);
592 assert!(chunk.lazy_previous().is_none());
593
594 assert_matches!(chunk.content(), ChunkContent::Gap(gap) => {
595 assert_eq!(gap.prev_token, "morbier");
596 });
597 });
598
599 assert_matches!(chunks.next(), Some(chunk) => {
601 assert_eq!(chunk.identifier(), 2);
602 assert!(chunk.lazy_previous().is_none());
603
604 assert_matches!(chunk.content(), ChunkContent::Items(events) => {
605 assert_eq!(events.len(), 3);
606 check_test_event(&events[0], "c");
607 check_test_event(&events[1], "d");
608 check_test_event(&events[2], "e");
609 });
610 });
611
612 assert!(chunks.next().is_none());
613 }
614 }
615
616 async fn test_rebuild_empty_linked_chunk(&self) {
617 let linked_chunk = lazy_loader::from_all_chunks::<3, _, _>(
619 self.load_all_chunks(&DEFAULT_TEST_ROOM_ID).await.unwrap(),
620 )
621 .unwrap();
622 assert!(linked_chunk.is_none());
623 }
624
625 async fn test_clear_all_rooms_chunks(&self) {
626 let r0 = room_id!("!r0:matrix.org");
627 let r1 = room_id!("!r1:matrix.org");
628
629 self.handle_linked_chunk_updates(
631 r0,
632 vec![
633 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
635 Update::PushItems {
637 at: Position::new(CId::new(0), 0),
638 items: vec![make_test_event(r0, "hello"), make_test_event(r0, "world")],
639 },
640 ],
641 )
642 .await
643 .unwrap();
644
645 self.handle_linked_chunk_updates(
647 r1,
648 vec![
649 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
651 Update::NewGapChunk {
653 previous: Some(CId::new(0)),
654 new: CId::new(1),
655 next: None,
656 gap: Gap { prev_token: "bleu d'auvergne".to_owned() },
657 },
658 Update::NewItemsChunk { previous: Some(CId::new(1)), new: CId::new(2), next: None },
660 Update::PushItems {
662 at: Position::new(CId::new(2), 0),
663 items: vec![make_test_event(r0, "yummy")],
664 },
665 ],
666 )
667 .await
668 .unwrap();
669
670 assert!(lazy_loader::from_all_chunks::<3, _, _>(self.load_all_chunks(r0).await.unwrap())
672 .unwrap()
673 .is_some());
674 assert!(lazy_loader::from_all_chunks::<3, _, _>(self.load_all_chunks(r1).await.unwrap())
675 .unwrap()
676 .is_some());
677
678 self.clear_all_rooms_chunks().await.unwrap();
680
681 assert!(lazy_loader::from_all_chunks::<3, _, _>(self.load_all_chunks(r0).await.unwrap())
683 .unwrap()
684 .is_none());
685 assert!(lazy_loader::from_all_chunks::<3, _, _>(self.load_all_chunks(r1).await.unwrap())
686 .unwrap()
687 .is_none());
688 }
689
690 async fn test_remove_room(&self) {
691 let r0 = room_id!("!r0:matrix.org");
692 let r1 = room_id!("!r1:matrix.org");
693
694 self.handle_linked_chunk_updates(
696 r0,
697 vec![
698 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
700 Update::PushItems {
702 at: Position::new(CId::new(0), 0),
703 items: vec![make_test_event(r0, "hello"), make_test_event(r0, "world")],
704 },
705 ],
706 )
707 .await
708 .unwrap();
709
710 self.handle_linked_chunk_updates(
712 r1,
713 vec![
714 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
716 Update::PushItems {
718 at: Position::new(CId::new(0), 0),
719 items: vec![make_test_event(r0, "yummy")],
720 },
721 ],
722 )
723 .await
724 .unwrap();
725
726 self.remove_room(r0).await.unwrap();
728
729 let r0_linked_chunk = self.load_all_chunks(r0).await.unwrap();
731 assert!(r0_linked_chunk.is_empty());
732
733 let r1_linked_chunk = self.load_all_chunks(r1).await.unwrap();
735 assert!(!r1_linked_chunk.is_empty());
736 }
737
738 async fn test_filter_duplicated_events(&self) {
739 let room_id = room_id!("!r0:matrix.org");
740 let another_room_id = room_id!("!r1:matrix.org");
741 let event = |msg: &str| make_test_event(room_id, msg);
742
743 let event_comte = event("comté");
744 let event_brigand = event("brigand du jorat");
745 let event_raclette = event("raclette");
746 let event_morbier = event("morbier");
747 let event_gruyere = event("gruyère");
748 let event_tome = event("tome");
749 let event_mont_dor = event("mont d'or");
750
751 self.handle_linked_chunk_updates(
752 room_id,
753 vec![
754 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
755 Update::PushItems {
756 at: Position::new(CId::new(0), 0),
757 items: vec![event_comte.clone(), event_brigand.clone()],
758 },
759 Update::NewGapChunk {
760 previous: Some(CId::new(0)),
761 new: CId::new(1),
762 next: None,
763 gap: Gap { prev_token: "brillat-savarin".to_owned() },
764 },
765 Update::NewItemsChunk { previous: Some(CId::new(1)), new: CId::new(2), next: None },
766 Update::PushItems {
767 at: Position::new(CId::new(2), 0),
768 items: vec![event_morbier.clone(), event_mont_dor.clone()],
769 },
770 ],
771 )
772 .await
773 .unwrap();
774
775 self.handle_linked_chunk_updates(
778 another_room_id,
779 vec![
780 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
781 Update::PushItems {
782 at: Position::new(CId::new(0), 0),
783 items: vec![event_tome.clone()],
784 },
785 ],
786 )
787 .await
788 .unwrap();
789
790 let duplicated_events = self
791 .filter_duplicated_events(
792 room_id,
793 vec![
794 event_comte.event_id().unwrap().to_owned(),
795 event_raclette.event_id().unwrap().to_owned(),
796 event_morbier.event_id().unwrap().to_owned(),
797 event_gruyere.event_id().unwrap().to_owned(),
798 event_tome.event_id().unwrap().to_owned(),
799 event_mont_dor.event_id().unwrap().to_owned(),
800 ],
801 )
802 .await
803 .unwrap();
804
805 assert_eq!(duplicated_events.len(), 3);
806 assert_eq!(
807 duplicated_events[0],
808 (event_comte.event_id().unwrap(), Position::new(CId::new(0), 0))
809 );
810 assert_eq!(
811 duplicated_events[1],
812 (event_morbier.event_id().unwrap(), Position::new(CId::new(2), 0))
813 );
814 assert_eq!(
815 duplicated_events[2],
816 (event_mont_dor.event_id().unwrap(), Position::new(CId::new(2), 1))
817 );
818 }
819
820 async fn test_find_event(&self) {
821 let room_id = room_id!("!r0:matrix.org");
822 let another_room_id = room_id!("!r1:matrix.org");
823 let event = |msg: &str| make_test_event(room_id, msg);
824
825 let event_comte = event("comté");
826 let event_gruyere = event("gruyère");
827
828 self.handle_linked_chunk_updates(
830 room_id,
831 vec![
832 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
833 Update::PushItems {
834 at: Position::new(CId::new(0), 0),
835 items: vec![event_comte.clone()],
836 },
837 ],
838 )
839 .await
840 .unwrap();
841
842 self.handle_linked_chunk_updates(
844 another_room_id,
845 vec![
846 Update::NewItemsChunk { previous: None, new: CId::new(0), next: None },
847 Update::PushItems {
848 at: Position::new(CId::new(0), 0),
849 items: vec![event_gruyere.clone()],
850 },
851 ],
852 )
853 .await
854 .unwrap();
855
856 let (position, event) = self
858 .find_event(room_id, event_comte.event_id().unwrap().as_ref())
859 .await
860 .expect("failed to query for finding an event")
861 .expect("failed to find an event");
862
863 assert_eq!(position.chunk_identifier(), 0);
864 assert_eq!(position.index(), 0);
865 assert_eq!(event.event_id(), event_comte.event_id());
866
867 assert!(self
869 .find_event(room_id, event_gruyere.event_id().unwrap().as_ref())
870 .await
871 .expect("failed to query for finding an event")
872 .is_none());
873 }
874}
875
876#[allow(unused_macros, unused_extern_crates)]
904#[macro_export]
905macro_rules! event_cache_store_integration_tests {
906 () => {
907 mod event_cache_store_integration_tests {
908 use matrix_sdk_test::async_test;
909 use $crate::event_cache::store::{
910 EventCacheStoreIntegrationTests, IntoEventCacheStore,
911 };
912
913 use super::get_event_cache_store;
914
915 #[async_test]
916 async fn test_media_content() {
917 let event_cache_store =
918 get_event_cache_store().await.unwrap().into_event_cache_store();
919 event_cache_store.test_media_content().await;
920 }
921
922 #[async_test]
923 async fn test_replace_media_key() {
924 let event_cache_store =
925 get_event_cache_store().await.unwrap().into_event_cache_store();
926 event_cache_store.test_replace_media_key().await;
927 }
928
929 #[async_test]
930 async fn test_handle_updates_and_rebuild_linked_chunk() {
931 let event_cache_store =
932 get_event_cache_store().await.unwrap().into_event_cache_store();
933 event_cache_store.test_handle_updates_and_rebuild_linked_chunk().await;
934 }
935
936 #[async_test]
937 async fn test_linked_chunk_incremental_loading() {
938 let event_cache_store =
939 get_event_cache_store().await.unwrap().into_event_cache_store();
940 event_cache_store.test_linked_chunk_incremental_loading().await;
941 }
942
943 #[async_test]
944 async fn test_rebuild_empty_linked_chunk() {
945 let event_cache_store =
946 get_event_cache_store().await.unwrap().into_event_cache_store();
947 event_cache_store.test_rebuild_empty_linked_chunk().await;
948 }
949
950 #[async_test]
951 async fn test_clear_all_rooms_chunks() {
952 let event_cache_store =
953 get_event_cache_store().await.unwrap().into_event_cache_store();
954 event_cache_store.test_clear_all_rooms_chunks().await;
955 }
956
957 #[async_test]
958 async fn test_remove_room() {
959 let event_cache_store =
960 get_event_cache_store().await.unwrap().into_event_cache_store();
961 event_cache_store.test_remove_room().await;
962 }
963
964 #[async_test]
965 async fn test_filter_duplicated_events() {
966 let event_cache_store =
967 get_event_cache_store().await.unwrap().into_event_cache_store();
968 event_cache_store.test_filter_duplicated_events().await;
969 }
970
971 #[async_test]
972 async fn test_find_event() {
973 let event_cache_store =
974 get_event_cache_store().await.unwrap().into_event_cache_store();
975 event_cache_store.test_find_event().await;
976 }
977 }
978 };
979}
980
981#[allow(unused_macros)]
984#[macro_export]
985macro_rules! event_cache_store_integration_tests_time {
986 () => {
987 #[cfg(not(target_arch = "wasm32"))]
988 mod event_cache_store_integration_tests_time {
989 use std::time::Duration;
990
991 use matrix_sdk_test::async_test;
992 use $crate::event_cache::store::IntoEventCacheStore;
993
994 use super::get_event_cache_store;
995
996 #[async_test]
997 async fn test_lease_locks() {
998 let store = get_event_cache_store().await.unwrap().into_event_cache_store();
999
1000 let acquired0 = store.try_take_leased_lock(0, "key", "alice").await.unwrap();
1001 assert!(acquired0);
1002
1003 let acquired2 = store.try_take_leased_lock(300, "key", "alice").await.unwrap();
1005 assert!(acquired2);
1006
1007 let acquired3 = store.try_take_leased_lock(300, "key", "alice").await.unwrap();
1009 assert!(acquired3);
1010
1011 let acquired4 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
1013 assert!(!acquired4);
1014
1015 let acquired5 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
1017 assert!(!acquired5);
1018
1019 tokio::time::sleep(Duration::from_millis(50)).await;
1021
1022 let acquired55 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
1024 assert!(!acquired55);
1025
1026 tokio::time::sleep(Duration::from_millis(250)).await;
1028
1029 let acquired6 = store.try_take_leased_lock(0, "key", "bob").await.unwrap();
1031 assert!(acquired6);
1032
1033 tokio::time::sleep(Duration::from_millis(1)).await;
1034
1035 let acquired7 = store.try_take_leased_lock(0, "key", "alice").await.unwrap();
1037 assert!(acquired7);
1038
1039 tokio::time::sleep(Duration::from_millis(1)).await;
1040
1041 let acquired8 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
1043 assert!(acquired8);
1044
1045 let acquired9 = store.try_take_leased_lock(300, "key", "alice").await.unwrap();
1047 assert!(!acquired9);
1048
1049 let acquired10 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
1051 assert!(acquired10);
1052 }
1053 }
1054 };
1055}