@@ -141,11 +141,8 @@ pub async fn setup_migrations(environment: &str) {
141
141
#[ cfg( test) ]
142
142
pub mod tests_postgres {
143
143
use std:: {
144
- ops:: Deref ,
145
- sync:: {
146
- atomic:: { AtomicUsize , Ordering } ,
147
- Arc ,
148
- } ,
144
+ ops:: { Deref , DerefMut } ,
145
+ sync:: atomic:: { AtomicUsize , Ordering } ,
149
146
} ;
150
147
151
148
use deadpool:: managed:: { Manager as ManagerTrait , RecycleResult } ;
@@ -159,45 +156,64 @@ pub mod tests_postgres {
159
156
160
157
pub type Pool = deadpool:: managed:: Pool < Manager > ;
161
158
162
- pub static DATABASE_POOL : Lazy < Pool > = Lazy :: new ( || {
159
+ pub static DATABASE_POOL : Lazy < Pool > = Lazy :: new ( || create_pool ( "test" ) ) ;
160
+
161
+ /// we must have a duplication of the migration because of how migrant is handling migrations
162
+ /// we need to separately setup test migrations
163
+ pub static MIGRATIONS : & [ & str ] = & [ "20190806011140_initial-tables" ] ;
164
+
165
+ fn create_pool ( db_prefix : & str ) -> Pool {
163
166
let manager_config = ManagerConfig {
164
167
recycling_method : deadpool_postgres:: RecyclingMethod :: Fast ,
165
168
} ;
166
- let manager = Manager :: new ( POSTGRES_CONFIG . clone ( ) , manager_config) ;
169
+ let manager = Manager :: new ( POSTGRES_CONFIG . clone ( ) , manager_config, db_prefix ) ;
167
170
168
171
Pool :: new ( manager, 15 )
169
- } ) ;
170
-
171
- /// we must have a duplication of the migration because of how migrant is handling migrations
172
- /// we need to separately setup test migrations
173
- pub static MIGRATIONS : & [ & str ] = & [ "20190806011140_initial-tables" ] ;
172
+ }
174
173
175
174
/// A Database is used to isolate test runs from each other
176
175
/// we need to know the name of the database we've created.
177
176
/// This will allow us the drop the database when we are recycling the connection
178
177
pub struct Database {
179
- inner : Arc < DatabaseInner > ,
178
+ /// The database name that will be created by the pool `CREATE DATABASE`
179
+ /// This database will be set on configuration level of the underlying connection Pool for tests
180
+ pub name : String ,
181
+ pub pool : deadpool_postgres:: Pool < NoTls > ,
180
182
}
183
+
181
184
impl Database {
182
185
pub fn new ( name : String , pool : DbPool ) -> Self {
183
- Self {
184
- inner : Arc :: new ( DatabaseInner { name, pool } ) ,
185
- }
186
+ Self { name, pool }
186
187
}
187
- }
188
188
189
- struct DatabaseInner {
190
- /// The database name that will be created by the pool `CREATE DATABASE`
191
- /// This database will be set on configuration level of the underlying connection Pool for tests
192
- pub name : String ,
193
- pub pool : deadpool_postgres:: Pool < NoTls > ,
189
+ pub fn get_pool ( & self ) -> deadpool_postgres:: Pool < NoTls > {
190
+ self . pool . clone ( )
191
+ }
194
192
}
195
193
196
194
impl Deref for Database {
197
195
type Target = deadpool_postgres:: Pool < NoTls > ;
198
196
199
197
fn deref ( & self ) -> & deadpool_postgres:: Pool < NoTls > {
200
- & self . inner . pool
198
+ & self . pool
199
+ }
200
+ }
201
+
202
+ impl DerefMut for Database {
203
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
204
+ & mut self . pool
205
+ }
206
+ }
207
+
208
+ impl AsRef < deadpool_postgres:: Pool < NoTls > > for Database {
209
+ fn as_ref ( & self ) -> & deadpool_postgres:: Pool < NoTls > {
210
+ & self . pool
211
+ }
212
+ }
213
+
214
+ impl AsMut < deadpool_postgres:: Pool < NoTls > > for Database {
215
+ fn as_mut ( & mut self ) -> & mut deadpool_postgres:: Pool < NoTls > {
216
+ & mut self . pool
201
217
}
202
218
}
203
219
@@ -208,10 +224,15 @@ pub mod tests_postgres {
208
224
base_pool : deadpool_postgres:: Pool < NoTls > ,
209
225
manager_config : ManagerConfig ,
210
226
index : AtomicUsize ,
227
+ db_prefix : String ,
211
228
}
212
229
213
230
impl Manager {
214
- pub fn new ( base_config : tokio_postgres:: Config , manager_config : ManagerConfig ) -> Self {
231
+ pub fn new (
232
+ base_config : tokio_postgres:: Config ,
233
+ manager_config : ManagerConfig ,
234
+ db_prefix : & str ,
235
+ ) -> Self {
215
236
// We need to create the schema with a temporary connection, in order to use it for the real Test Pool
216
237
let base_manager = deadpool_postgres:: Manager :: from_config (
217
238
base_config. clone ( ) ,
@@ -220,19 +241,21 @@ pub mod tests_postgres {
220
241
) ;
221
242
let base_pool = deadpool_postgres:: Pool :: new ( base_manager, 15 ) ;
222
243
223
- Self :: new_with_pool ( base_pool, base_config, manager_config)
244
+ Self :: new_with_pool ( base_pool, base_config, manager_config, db_prefix )
224
245
}
225
246
226
247
pub fn new_with_pool (
227
248
base_pool : deadpool_postgres:: Pool < NoTls > ,
228
249
base_config : tokio_postgres:: Config ,
229
250
manager_config : ManagerConfig ,
251
+ db_prefix : & str ,
230
252
) -> Self {
231
253
Self {
232
254
base_config,
233
255
base_pool,
234
256
manager_config,
235
257
index : AtomicUsize :: new ( 0 ) ,
258
+ db_prefix : db_prefix. into ( ) ,
236
259
}
237
260
}
238
261
}
@@ -245,7 +268,9 @@ pub mod tests_postgres {
245
268
246
269
async fn create ( & self ) -> Result < Self :: Type , Self :: Error > {
247
270
let pool_index = self . index . fetch_add ( 1 , Ordering :: SeqCst ) ;
248
- let db_name = format ! ( "test_{}" , pool_index) ;
271
+
272
+ // e.g. test_0, test_1, test_2
273
+ let db_name = format ! ( "{}_{}" , self . db_prefix, pool_index) ;
249
274
250
275
// 1. Drop the database if it exists - if a test failed before, the database wouldn't have been removed
251
276
// 2. Create database
@@ -279,16 +304,18 @@ pub mod tests_postgres {
279
304
}
280
305
281
306
async fn recycle ( & self , database : & mut Database ) -> RecycleResult < Self :: Error > {
282
- let queries = format ! ( "DROP DATABASE {0} WITH (FORCE);" , database. inner. name) ;
283
- let result = self
284
- . base_pool
307
+ // DROP the public schema and create it again for usage after recycling
308
+ let queries = format ! ( "DROP SCHEMA public CASCADE; CREATE SCHEMA public;" ) ;
309
+ let result = database
310
+ . pool
285
311
. get ( )
286
312
. await ?
287
313
. simple_query ( & queries)
288
314
. await
289
315
. map_err ( |err| PoolError :: Backend ( err) ) ?;
290
- assert_eq ! ( 1 , result. len( ) ) ;
316
+ assert_eq ! ( 2 , result. len( ) ) ;
291
317
assert ! ( matches!( result[ 0 ] , SimpleQueryMessage :: CommandComplete ( ..) ) ) ;
318
+ assert ! ( matches!( result[ 1 ] , SimpleQueryMessage :: CommandComplete ( ..) ) ) ;
292
319
293
320
Ok ( ( ) )
294
321
}
@@ -318,6 +345,59 @@ pub mod tests_postgres {
318
345
319
346
Ok ( client. batch_execute ( & full_query) . await ?)
320
347
}
348
+
349
+ #[ cfg( test) ]
350
+ mod test {
351
+ use super :: * ;
352
+
353
+ #[ tokio:: test]
354
+ /// Does not use the `DATABASE_POOL` as other tests can interfere with the pool objects!
355
+ async fn test_postgres_pool ( ) {
356
+ let pool = create_pool ( "testing_pool" ) ;
357
+
358
+ let database_1 = pool. get ( ) . await . expect ( "Should get" ) ;
359
+ let status = pool. status ( ) ;
360
+ assert_eq ! ( status. size, 1 ) ;
361
+ assert_eq ! ( status. available, 0 ) ;
362
+
363
+ let database_2 = pool. get ( ) . await . expect ( "Should get" ) ;
364
+ let status = pool. status ( ) ;
365
+ assert_eq ! ( status. size, 2 ) ;
366
+ assert_eq ! ( status. available, 0 ) ;
367
+
368
+ drop ( database_1) ;
369
+ let status = pool. status ( ) ;
370
+ assert_eq ! ( status. size, 2 ) ;
371
+ assert_eq ! ( status. available, 1 ) ;
372
+
373
+ drop ( database_2) ;
374
+ let status = pool. status ( ) ;
375
+ assert_eq ! ( status. size, 2 ) ;
376
+ assert_eq ! ( status. available, 2 ) ;
377
+
378
+ let database_3 = pool. get ( ) . await . expect ( "Should get" ) ;
379
+ let status = pool. status ( ) ;
380
+ assert_eq ! ( status. size, 2 ) ;
381
+ assert_eq ! ( status. available, 1 ) ;
382
+
383
+ let database_4 = pool. get ( ) . await . expect ( "Should get" ) ;
384
+ let status = pool. status ( ) ;
385
+ assert_eq ! ( status. size, 2 ) ;
386
+ assert_eq ! ( status. available, 0 ) ;
387
+
388
+ let database_5 = pool. get ( ) . await . expect ( "Should get" ) ;
389
+ let status = pool. status ( ) ;
390
+ assert_eq ! ( status. size, 3 ) ;
391
+ assert_eq ! ( status. available, 0 ) ;
392
+
393
+ drop ( database_3) ;
394
+ drop ( database_4) ;
395
+ drop ( database_5) ;
396
+ let status = pool. status ( ) ;
397
+ assert_eq ! ( status. size, 3 ) ;
398
+ assert_eq ! ( status. available, 3 ) ;
399
+ }
400
+ }
321
401
}
322
402
323
403
#[ cfg( test) ]
0 commit comments