-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbatch_check_debug_test.go
More file actions
72 lines (65 loc) · 2.03 KB
/
Copy pathbatch_check_debug_test.go
File metadata and controls
72 lines (65 loc) · 2.03 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
//go:build qdfdebug || race
package qdf
import "testing"
// TestBatchStaleHandlePanics: resolving a handle after Release must panic in
// debug/race builds instead of returning silent garbage (Release nils the
// Batch's slab pointer and bumps batchSlab.epoch — checkEpoch catches both).
func TestBatchStaleHandlePanics(t *testing.T) {
src := mkBatSrc(4)
data, _ := Marshal(src, OptBalanced)
b, _ := UnmarshalBatch[batDoc](data)
h := b.Rows[0].Name
b.Release()
defer func() {
if recover() == nil {
t.Fatal("stale handle resolve must panic in debug builds")
}
}()
_ = b.Str(h)
}
// TestBatchStaleHandlePanicsBytesOf mirrors the Str case for BytesOf, using
// the qdf.Bytes column so the checkEpoch guard on that resolve path is
// exercised too.
func TestBatchStaleHandlePanicsBytesOf(t *testing.T) {
src := []batBytesSrc{{ID: 1, Blob: []byte("payload"), Name: "n"}}
data, err := Marshal(src, OptBalanced)
if err != nil {
t.Fatal(err)
}
b, err := UnmarshalBatch[batBytesDoc](data)
if err != nil {
t.Fatal(err)
}
h := b.Rows[0].Blob
b.Release()
defer func() {
if recover() == nil {
t.Fatal("stale handle resolve must panic in debug builds")
}
}()
_ = b.BytesOf(h)
}
// TestBatchStaleHandlePanicsAfterSlabReuse: after Release, the slab is
// returned to the pool and its epoch bumped. A fresh decode may reuse the
// same *batchSlab (same pointer) at a new epoch — the stale Batch's captured
// epoch must no longer match, so resolving its handles still panics rather
// than silently reading whatever the new decode wrote into the same buffer.
func TestBatchStaleHandlePanicsAfterSlabReuse(t *testing.T) {
src := mkBatSrc(4)
data, _ := Marshal(src, OptBalanced)
b, _ := UnmarshalBatch[batDoc](data)
h := b.Rows[0].Name
b.Release()
// Force a second decode through the same pooled slab.
b2, err := UnmarshalBatch[batDoc](data)
if err != nil {
t.Fatal(err)
}
defer b2.Release()
defer func() {
if recover() == nil {
t.Fatal("stale handle resolve after slab reuse must panic in debug builds")
}
}()
_ = b.Str(h)
}