-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtable_fuzz_test.go
More file actions
88 lines (75 loc) · 2.01 KB
/
table_fuzz_test.go
File metadata and controls
88 lines (75 loc) · 2.01 KB
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
package table
import (
"math/rand"
"testing"
)
func TestTable_FuzzMassive(t *testing.T) {
const (
maxRows = 50_000 // scale to your RAM target
maxCols = 10
maxValLen = 8
seed = 42 // make this configurable for reproducibility
)
rnd := rand.New(rand.NewSource(seed))
tbl := &Table{}
// === Insert Phase ===
for i := 0; i < maxRows; i++ {
row := randomRow(rnd, maxCols, maxValLen)
if rnd.Float64() < 0.05 {
// 5% chance insert as hole row
tbl.InsertHoles([][]string{row})
} else {
tbl.Insert([][]string{row})
}
if i%1_000_000 == 0 && i > 0 {
t.Logf("Inserted %d rows", i)
}
}
// === Fuzz workload ===
for i := 0; i < 1000; i++ {
col := rnd.Intn(maxCols)
val := randString(rnd, maxValLen)
count := tbl.Count(col, val)
// Must match GetAll
all := tbl.GetAll(col, val)
if len(all) != count {
t.Fatalf("Count mismatch: Count()=%d vs GetAll()=%d for col=%d val=%q",
count, len(all), col, val)
}
// Holes must match GetAllHoles >= GetAll
allHoles := tbl.GetAll(col, val)
if len(allHoles) < len(all) {
t.Fatalf("GetAllHoles() should never be smaller than GetAll()")
}
// Do a query
query := tbl.QueryBy(map[int]string{col: val})
for _, row := range query {
if row == nil {
t.Fatalf("QueryBy should skip holes but found nil row")
}
if col >= len(row) || row[col] != val {
t.Fatalf("QueryBy returned invalid row: %+v", row)
}
}
// Delete 10% of values we hit
if rnd.Float64() < 0.1 {
tbl.DeleteBy(map[int]string{col: val})
}
}
// === Holes check ===
all := tbl.All()
allHoles := tbl.AllHoles()
if len(allHoles) < len(all) {
t.Fatalf("AllHoles must never be smaller than All")
}
// === Compact and recheck ===
tbl.Compact()
allAfter := tbl.All()
allHolesAfter := tbl.AllHoles()
if len(allHolesAfter) != len(allAfter) {
t.Logf("After compact: holes should be gone: all=%d allHoles=%d",
len(allAfter), len(allHolesAfter))
}
t.Logf("Fuzz done: final rows=%d holes=%d",
len(allAfter), len(allHolesAfter)-len(allAfter))
}