@@ -2,6 +2,7 @@ use std::{
2
2
collections:: HashMap ,
3
3
ops:: Deref ,
4
4
option_env,
5
+ path:: { Path , PathBuf } ,
5
6
sync:: { Arc , Mutex as StdMutex } ,
6
7
time:: Duration ,
7
8
} ;
@@ -21,9 +22,14 @@ use tokio::sync::Mutex;
21
22
22
23
static USERS : Lazy < Mutex < HashMap < String , ( Client , TempDir ) > > > = Lazy :: new ( Mutex :: default) ;
23
24
25
+ enum SqlitePath {
26
+ Random ,
27
+ Path ( PathBuf ) ,
28
+ }
29
+
24
30
pub struct TestClientBuilder {
25
31
username : String ,
26
- use_sqlite : bool ,
32
+ use_sqlite_dir : Option < SqlitePath > ,
27
33
encryption_settings : EncryptionSettings ,
28
34
http_proxy : Option < String > ,
29
35
}
@@ -32,7 +38,7 @@ impl TestClientBuilder {
32
38
pub fn new ( username : impl Into < String > ) -> Self {
33
39
Self {
34
40
username : username. into ( ) ,
35
- use_sqlite : false ,
41
+ use_sqlite_dir : None ,
36
42
encryption_settings : Default :: default ( ) ,
37
43
http_proxy : None ,
38
44
}
@@ -45,7 +51,16 @@ impl TestClientBuilder {
45
51
}
46
52
47
53
pub fn use_sqlite ( mut self ) -> Self {
48
- self . use_sqlite = true ;
54
+ self . use_sqlite_dir = Some ( SqlitePath :: Random ) ;
55
+ self
56
+ }
57
+
58
+ /// Create or re-use a Sqlite store (with no passphrase) in the supplied
59
+ /// directory. Note: this path must remain valid throughout the use of
60
+ /// the constructed Client, so if you created a TempDir you must hang on
61
+ /// to a reference to it throughout the test.
62
+ pub fn use_sqlite_dir ( mut self , path : & Path ) -> Self {
63
+ self . use_sqlite_dir = Some ( SqlitePath :: Path ( path. to_owned ( ) ) ) ;
49
64
self
50
65
}
51
66
@@ -59,6 +74,44 @@ impl TestClientBuilder {
59
74
self
60
75
}
61
76
77
+ /// Create a new Client that is a copy of the supplied one, created using
78
+ /// [`Client::restore_session`].
79
+ pub async fn duplicate ( self , other : & Client ) -> Result < Client > {
80
+ let homeserver_url =
81
+ option_env ! ( "HOMESERVER_URL" ) . unwrap_or ( "http://localhost:8228" ) . to_owned ( ) ;
82
+ let sliding_sync_proxy_url =
83
+ option_env ! ( "SLIDING_SYNC_PROXY_URL" ) . unwrap_or ( "http://localhost:8338" ) . to_owned ( ) ;
84
+
85
+ let mut client_builder = Client :: builder ( )
86
+ . user_agent ( "matrix-sdk-integration-tests" )
87
+ . homeserver_url ( homeserver_url)
88
+ . sliding_sync_proxy ( sliding_sync_proxy_url)
89
+ . with_encryption_settings ( self . encryption_settings )
90
+ . request_config ( RequestConfig :: short_retry ( ) ) ;
91
+
92
+ if let Some ( proxy) = self . http_proxy {
93
+ client_builder = client_builder. proxy ( proxy) ;
94
+ }
95
+
96
+ let client = match self . use_sqlite_dir {
97
+ Some ( SqlitePath :: Path ( path_buf) ) => {
98
+ client_builder. sqlite_store ( & path_buf, None ) . build ( ) . await ?
99
+ }
100
+ _ => {
101
+ panic ! ( "You must call use_sqlite_dir for a duplicate client!" ) ;
102
+ }
103
+ } ;
104
+
105
+ client
106
+ . restore_session (
107
+ other. session ( ) . expect ( "Session must be logged in before we can duplicate it" ) ,
108
+ )
109
+ . await
110
+ . expect ( "Failed to restore session" ) ;
111
+
112
+ Ok ( client)
113
+ }
114
+
62
115
pub async fn build ( self ) -> Result < Client > {
63
116
let mut users = USERS . lock ( ) . await ;
64
117
if let Some ( ( client, _) ) = users. get ( & self . username ) {
@@ -83,10 +136,14 @@ impl TestClientBuilder {
83
136
client_builder = client_builder. proxy ( proxy) ;
84
137
}
85
138
86
- let client = if self . use_sqlite {
87
- client_builder. sqlite_store ( tmp_dir. path ( ) , None ) . build ( ) . await ?
88
- } else {
89
- client_builder. build ( ) . await ?
139
+ let client = match self . use_sqlite_dir {
140
+ None => client_builder. build ( ) . await ?,
141
+ Some ( SqlitePath :: Random ) => {
142
+ client_builder. sqlite_store ( tmp_dir. path ( ) , None ) . build ( ) . await ?
143
+ }
144
+ Some ( SqlitePath :: Path ( path_buf) ) => {
145
+ client_builder. sqlite_store ( & path_buf, None ) . build ( ) . await ?
146
+ }
90
147
} ;
91
148
92
149
// safe to assume we have not registered this user yet, but ignore if we did
0 commit comments