toasty_driver_integration_suite/tests/
connection_per_clone.rs

1use crate::prelude::*;
2
3#[driver_test(id(ID))]
4pub async fn clone_acquires_separate_connection(t: &mut Test) -> Result<()> {
5    if !t.capability().test_connection_pool {
6        return Ok(());
7    }
8
9    #[derive(Debug, toasty::Model)]
10    struct Item {
11        #[key]
12        #[auto]
13        id: ID,
14    }
15
16    let mut db = t.setup_db(models!(Item)).await;
17
18    // Before any operation, no connection has been acquired yet (the one from
19    // push_schema during setup_db already holds one).
20    let status = db.pool().status();
21    assert_eq!(
22        status.size, 1,
23        "setup_db should have acquired one connection"
24    );
25    assert_eq!(
26        status.available, 0,
27        "that connection should be in use by db"
28    );
29
30    // Clone the handle — the clone starts with no connection.
31    let mut db2 = db.clone();
32
33    // The clone hasn't done anything yet, pool state unchanged.
34    let status = db.pool().status();
35    assert_eq!(status.size, 1, "clone should not acquire a connection yet");
36
37    // Use the clone — this should lazily acquire a second connection.
38    Item::create().exec(&mut db2).await?;
39
40    let status = db.pool().status();
41    assert_eq!(
42        status.size, 2,
43        "using the clone should have acquired a second connection"
44    );
45    assert_eq!(status.available, 0, "both connections should be in use");
46
47    // Drop the clone — its connection should return to the pool.
48    drop(db2);
49
50    // The background task needs a moment to notice the channel closed and exit,
51    // which drops the PoolConnection and returns it to the pool.
52    tokio::task::yield_now().await;
53
54    let status = db.pool().status();
55    assert_eq!(status.size, 2, "pool should still have 2 connections total");
56    assert_eq!(
57        status.available, 1,
58        "dropped clone's connection should be back in the pool"
59    );
60
61    // The original handle still works fine.
62    let item = Item::create().exec(&mut db).await?;
63    let found = Item::filter_by_id(item.id).exec(&mut db).await?;
64    assert_eq!(found.len(), 1);
65
66    Ok(())
67}
68
69#[driver_test(id(ID))]
70pub async fn write_visible_on_same_handle(t: &mut Test) -> Result<()> {
71    #[derive(Debug, toasty::Model)]
72    struct Note {
73        #[key]
74        #[auto]
75        id: ID,
76
77        body: String,
78    }
79
80    let mut db = t.setup_db(models!(Note)).await;
81
82    // Write and immediately read on the same handle — must see the write.
83    let created = Note::create().body("hello").exec(&mut db).await?;
84    let found = Note::filter_by_id(created.id).get(&mut db).await?;
85    assert_eq!(found.body, "hello");
86
87    Ok(())
88}