Skip to content

Commit f85f56e

Browse files
committed
test: add test for the generational counter invalidation
1 parent dd9584c commit f85f56e

File tree

4 files changed

+103
-3
lines changed

4 files changed

+103
-3
lines changed

crates/matrix-sdk-crypto/src/machine.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,14 @@ impl OlmMachine {
18431843

18441844
Ok(true)
18451845
}
1846+
1847+
#[cfg(any(feature = "testing", test))]
1848+
/// Returns whether this `OlmMachine` is the same another one.
1849+
///
1850+
/// Useful for testing purposes only.
1851+
pub fn same_as(&self, other: &OlmMachine) -> bool {
1852+
Arc::ptr_eq(&self.inner, &other.inner)
1853+
}
18461854
}
18471855

18481856
#[cfg(any(feature = "testing", test))]

crates/matrix-sdk-sqlite/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ rust-version = { workspace = true }
99

1010
[features]
1111
default = ["state-store"]
12+
testing = ["matrix-sdk-crypto?/testing"]
1213

1314
bundled = ["rusqlite/bundled"]
1415
crypto-store = [

crates/matrix-sdk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"]
1717

1818
[features]
1919
default = ["e2e-encryption", "automatic-room-key-forwarding", "sqlite", "native-tls"]
20-
testing = []
20+
testing = ["matrix-sdk-sqlite?/testing"]
2121

2222
e2e-encryption = [
2323
"matrix-sdk-base/e2e-encryption",

crates/matrix-sdk/src/encryption/mod.rs

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -941,12 +941,15 @@ impl Encryption {
941941

942942
#[cfg(all(test, not(target_arch = "wasm32")))]
943943
mod tests {
944+
use std::time::Duration;
945+
946+
use matrix_sdk_base::SessionMeta;
944947
use matrix_sdk_test::{
945948
async_test, test_json, EventBuilder, GlobalAccountDataTestEvent, JoinedRoomBuilder,
946949
StateTestEvent,
947950
};
948951
use ruma::{
949-
event_id,
952+
device_id, event_id,
950953
events::{reaction::ReactionEventContent, relation::Annotation},
951954
user_id,
952955
};
@@ -956,7 +959,12 @@ mod tests {
956959
Mock, MockServer, ResponseTemplate,
957960
};
958961

959-
use crate::test_utils::logged_in_client;
962+
use crate::{
963+
config::RequestConfig,
964+
matrix_auth::{Session, SessionTokens},
965+
test_utils::logged_in_client,
966+
Client,
967+
};
960968

961969
#[async_test]
962970
async fn test_reaction_sending() {
@@ -1076,4 +1084,87 @@ mod tests {
10761084
let found_room = client.get_dm_room(user_id).expect("DM not found!");
10771085
assert!(found_room.get_member_no_sync(user_id).await.unwrap().is_some());
10781086
}
1087+
1088+
#[cfg(feature = "sqlite")]
1089+
#[async_test]
1090+
async fn test_generation_counter_invalidates_olm_machine() {
1091+
// Create two clients using the same sqlite database.
1092+
let sqlite_path = std::env::temp_dir().join("generation_counter_sqlite.db");
1093+
let session = Session {
1094+
meta: SessionMeta {
1095+
user_id: user_id!("@example:localhost").to_owned(),
1096+
device_id: device_id!("DEVICEID").to_owned(),
1097+
},
1098+
tokens: SessionTokens { access_token: "1234".to_owned(), refresh_token: None },
1099+
};
1100+
1101+
let client1 = Client::builder()
1102+
.homeserver_url("http://localhost:1234")
1103+
.request_config(RequestConfig::new().disable_retry())
1104+
.sqlite_store(&sqlite_path, None)
1105+
.build()
1106+
.await
1107+
.unwrap();
1108+
client1.matrix_auth().restore_session(session.clone()).await.unwrap();
1109+
1110+
let client2 = Client::builder()
1111+
.homeserver_url("http://localhost:1234")
1112+
.request_config(RequestConfig::new().disable_retry())
1113+
.sqlite_store(sqlite_path, None)
1114+
.build()
1115+
.await
1116+
.unwrap();
1117+
client2.matrix_auth().restore_session(session).await.unwrap();
1118+
1119+
// When the lock isn't enabled, any attempt at locking won't return a guard.
1120+
let guard = client1.encryption().try_lock_store_once().await.unwrap();
1121+
assert!(guard.is_none());
1122+
1123+
client1.encryption().enable_cross_process_store_lock("client1".to_owned()).await.unwrap();
1124+
client2.encryption().enable_cross_process_store_lock("client2".to_owned()).await.unwrap();
1125+
1126+
// One client can take the lock.
1127+
let acquired1 = client1.encryption().try_lock_store_once().await.unwrap();
1128+
assert!(acquired1.is_some());
1129+
1130+
// Keep the olm machine, so we can see if it's changed later, by comparing Arcs.
1131+
let initial_olm_machine =
1132+
client1.olm_machine().await.clone().expect("must have an olm machine");
1133+
1134+
// The other client can't take the lock too.
1135+
let acquired2 = client2.encryption().try_lock_store_once().await.unwrap();
1136+
assert!(acquired2.is_none());
1137+
1138+
// Now have the first client release the lock,
1139+
drop(acquired1);
1140+
tokio::time::sleep(Duration::from_millis(100)).await;
1141+
1142+
// And re-take it.
1143+
let acquired1 = client1.encryption().try_lock_store_once().await.unwrap();
1144+
assert!(acquired1.is_some());
1145+
1146+
// In that case, the Olm Machine shouldn't change.
1147+
let olm_machine = client1.olm_machine().await.clone().expect("must have an olm machine");
1148+
assert!(initial_olm_machine.same_as(&olm_machine));
1149+
1150+
// Ok, release again.
1151+
drop(acquired1);
1152+
tokio::time::sleep(Duration::from_millis(100)).await;
1153+
1154+
// Client2 can acquire the lock.
1155+
let acquired2 = client2.encryption().try_lock_store_once().await.unwrap();
1156+
assert!(acquired2.is_some());
1157+
1158+
// And then release it.
1159+
drop(acquired2);
1160+
tokio::time::sleep(Duration::from_millis(100)).await;
1161+
1162+
// Client1 can acquire it again,
1163+
let acquired1 = client1.encryption().try_lock_store_once().await.unwrap();
1164+
assert!(acquired1.is_some());
1165+
1166+
// But now its olm machine has been invalidated and thus regenerated!
1167+
let olm_machine = client1.olm_machine().await.clone().expect("must have an olm machine");
1168+
assert!(!initial_olm_machine.same_as(&olm_machine));
1169+
}
10791170
}

0 commit comments

Comments
 (0)