-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfuzz_test.go
More file actions
114 lines (96 loc) · 2.85 KB
/
Copy pathfuzz_test.go
File metadata and controls
114 lines (96 loc) · 2.85 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
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
// Copyright (c) 2025 Andrey Kolkov and GoGPU Contributors
// SPDX-License-Identifier: MIT
package galloc
import "testing"
func FuzzAllocFree(f *testing.F) {
// Seed corpus.
f.Add(uint32(1024), uint8(10), uint16(64))
f.Add(uint32(65536), uint8(50), uint16(256))
f.Add(uint32(1), uint8(1), uint16(1))
f.Add(uint32(1024*1024), uint8(100), uint16(1024))
f.Fuzz(func(t *testing.T, totalSize uint32, numOps uint8, allocSize uint16) {
if totalSize == 0 || totalSize > 1024*1024*16 {
return // skip degenerate or excessively large inputs
}
maxAllocs := uint32(numOps)*2 + 16
if maxAllocs > 65536 {
maxAllocs = 65536
}
a := New(totalSize, maxAllocs)
// Perform a sequence of alloc/free operations. No panics or corruption.
var live []Allocation
for i := uint8(0); i < numOps; i++ {
size := uint32(allocSize)
if size == 0 {
size = 1
}
alloc := a.Allocate(size)
if !alloc.Failed() {
live = append(live, alloc)
}
// Free half of live allocations periodically.
if len(live) > 4 && i%3 == 0 {
half := len(live) / 2
for _, alloc := range live[:half] {
a.Free(alloc)
}
live = live[half:]
}
}
// Free all remaining.
for _, alloc := range live {
a.Free(alloc)
}
// After freeing everything, the report should show totalSize as free.
report := a.StorageReport()
if report.TotalFreeSpace != totalSize {
t.Errorf("after freeing all: TotalFreeSpace = %d, want %d", report.TotalFreeSpace, totalSize)
}
})
}
func FuzzAllocAligned(f *testing.F) {
f.Add(uint32(65536), uint8(20), uint16(256), uint8(8)) // align=256
f.Add(uint32(1024), uint8(5), uint16(64), uint8(2)) // align=4
f.Add(uint32(1024*1024), uint8(50), uint16(4096), uint8(9)) // align=512
f.Fuzz(func(t *testing.T, totalSize uint32, numOps uint8, allocSize uint16, alignShift uint8) {
if totalSize == 0 || totalSize > 1024*1024*16 {
return
}
// Clamp alignment to [1, 65536] as power of 2.
alignShift %= 17 // 0..16 → 1..65536
alignment := uint32(1) << alignShift
maxAllocs := uint32(numOps)*2 + 16
if maxAllocs > 65536 {
maxAllocs = 65536
}
a := New(totalSize, maxAllocs)
var live []Allocation
for i := uint8(0); i < numOps; i++ {
size := uint32(allocSize)
if size == 0 {
size = 1
}
alloc := a.AllocateAligned(size, alignment)
if !alloc.Failed() {
if alloc.Offset%alignment != 0 {
t.Fatalf("offset %d not aligned to %d", alloc.Offset, alignment)
}
live = append(live, alloc)
}
if len(live) > 4 && i%3 == 0 {
half := len(live) / 2
for _, alloc := range live[:half] {
a.Free(alloc)
}
live = live[half:]
}
}
for _, alloc := range live {
a.Free(alloc)
}
report := a.StorageReport()
if report.TotalFreeSpace != totalSize {
t.Errorf("after freeing all: TotalFreeSpace = %d, want %d", report.TotalFreeSpace, totalSize)
}
})
}