-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresolver_integration_test.go
116 lines (93 loc) · 2.82 KB
/
resolver_integration_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package dbresolver_test
import (
"database/sql"
"sync"
"testing"
"time"
"github.com/go-batteries/dbresolver"
_ "github.com/mattn/go-sqlite3"
)
func Test_DatabaseWithQueryKoalescer(t *testing.T) {
db, err := sql.Open("sqlite3", "./tmp/test.db")
if err != nil {
t.Fatalf("failed to open SQLite database: %v", err)
}
defer db.Close()
// Create a sample table
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)`)
if err != nil {
t.Fatalf("failed to create table: %v", err)
}
db.Exec(`DELETE FROM users`)
_, err = db.Exec(`INSERT INTO users (name) VALUES ('Alice'), ('Bob')`)
if err != nil {
t.Fatalf("failed to insert sample data: %v", err)
}
koalescer := dbresolver.NewKoalescer(&dbresolver.NoopEvictor{})
database := dbresolver.Register(dbresolver.DBConfig{
Master: dbresolver.AsMaster(db, "users"),
DefaultMode: &dbresolver.DbWriteMode,
Replicas: []*dbresolver.ResolverDB{dbresolver.AsSyncReplica(db, "users_read")},
}, dbresolver.WithQueryQualescer(koalescer))
// Simulate concurrent queries using the koalescer
var wg sync.WaitGroup
concurrentQueries := 5
results := make(chan dbresolver.Rows, concurrentQueries)
queryFunc := func() {
defer wg.Done()
rows, err := database.Query(`SELECT * FROM users`)
if err != nil {
t.Errorf("query failed: %v", err)
return
}
results <- rows
}
// Run concurrent queries
wg.Add(concurrentQueries)
for i := 0; i < concurrentQueries; i++ {
go queryFunc()
}
// Simulate adding a new record.
// This should not affect the total count
// Since result has not been evicted yet
time.Sleep(100 * time.Millisecond)
_, err = db.Exec(`INSERT INTO users(name) VALUES ('Paul')`)
if err != nil {
t.Fatal("failed to insert another value in users")
}
// Wait for all queries to complete
wg.Wait()
close(results)
// Check that results are as expected
var totalRows int
for rows := range results {
totalRows += len(rows)
}
expectedRows := 2
if totalRows != concurrentQueries*expectedRows {
t.Errorf("unexpected number of rows: got %d, want %d", totalRows, concurrentQueries*expectedRows)
}
_, err = db.Exec(`DELETE FROM users WHERE name = 'Paul'`)
if err != nil {
t.Fatal("failed to delete exisisting user from db")
}
rows, err := database.Query(`SELECT name FROM users`)
if err != nil {
t.Fatal("should not have failed to get user names")
}
if len(rows) != 2 {
t.Fatal("there are more than two records for this test.")
}
// This should evict the old record and get data
_, err = database.Exec(`INSERT INTO users (name) VALUES ('Jane')`)
if err != nil {
t.Fatal("should not have failed to insert data")
}
rows, err = database.Query(`SELECT * FROM users`)
if err != nil {
t.Fatal("should not have failed to get users")
}
if len(rows) != 3 {
t.Fatal("should have a total of 3 records")
}
}