|
| 1 | +package chdbdriver |
| 2 | + |
| 3 | +import ( |
| 4 | + "database/sql" |
| 5 | + "testing" |
| 6 | + |
| 7 | + "github.com/chdb-io/chdb-go/chdb" |
| 8 | +) |
| 9 | + |
| 10 | +// TestDriverOpenNoKeeperLeak verifies that the legacy Driver.Open path does not |
| 11 | +// leak the connector's keeper session. database/sql owns the connector on the |
| 12 | +// sql.Open path and calls connector.Close(), but a direct Driver.Open(name) |
| 13 | +// discards the connector, so closing the returned conn must release the keeper |
| 14 | +// too. Pre-fix the keeper session (a native connection + a registry refcount) |
| 15 | +// leaks on every Open call. |
| 16 | +func TestDriverOpenNoKeeperLeak(t *testing.T) { |
| 17 | + baseline := chdb.ActiveSessionRefs() |
| 18 | + |
| 19 | + c, err := Driver{}.Open("session=" + session.ConnStr()) |
| 20 | + if err != nil { |
| 21 | + t.Fatalf("Driver.Open failed: %s", err) |
| 22 | + } |
| 23 | + if err := c.Close(); err != nil { |
| 24 | + t.Fatalf("conn.Close failed: %s", err) |
| 25 | + } |
| 26 | + |
| 27 | + if got := chdb.ActiveSessionRefs(); got != baseline { |
| 28 | + t.Fatalf("Driver.Open leaked sessions: refs=%d, baseline=%d (keeper not released on conn.Close)", got, baseline) |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +// TestDbCloseReleasesRefs verifies the database/sql path balances refcounts: |
| 33 | +// opening a *sql.DB, running queries across multiple pooled connections, and |
| 34 | +// closing it returns the registry to its baseline (keeper + per-conn sessions |
| 35 | +// all released). |
| 36 | +func TestDbCloseReleasesRefs(t *testing.T) { |
| 37 | + baseline := chdb.ActiveSessionRefs() |
| 38 | + |
| 39 | + db, err := sql.Open("chdb", "session="+session.ConnStr()) |
| 40 | + if err != nil { |
| 41 | + t.Fatalf("open db failed: %s", err) |
| 42 | + } |
| 43 | + db.SetMaxOpenConns(4) |
| 44 | + |
| 45 | + for i := 0; i < 8; i++ { |
| 46 | + var n int |
| 47 | + if err := db.QueryRow("SELECT count() FROM numbers(10)").Scan(&n); err != nil { |
| 48 | + t.Fatalf("query failed: %s", err) |
| 49 | + } |
| 50 | + if n != 10 { |
| 51 | + t.Fatalf("got %d want 10", n) |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + if err := db.Close(); err != nil { |
| 56 | + t.Fatalf("db.Close failed: %s", err) |
| 57 | + } |
| 58 | + if got := chdb.ActiveSessionRefs(); got != baseline { |
| 59 | + t.Fatalf("db.Close left refs leaked: refs=%d, baseline=%d", got, baseline) |
| 60 | + } |
| 61 | +} |
0 commit comments