Skip to content

Commit d4092c0

Browse files
committed
test(subtree): add fuzz tests for power-of-two functions
1 parent 2cad906 commit d4092c0

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

subtree_fuzz_test.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,136 @@
11
package subtree
2+
3+
import (
4+
"testing"
5+
)
6+
7+
// FuzzCeilPowerOfTwo tests the CeilPowerOfTwo function with fuzzing
8+
func FuzzCeilPowerOfTwo(f *testing.F) {
9+
// Add seed corpus
10+
f.Add(0)
11+
f.Add(1)
12+
f.Add(2)
13+
f.Add(7)
14+
f.Add(8)
15+
f.Add(15)
16+
f.Add(16)
17+
f.Add(31)
18+
f.Add(32)
19+
f.Add(1024)
20+
f.Add(-1)
21+
f.Add(-10)
22+
23+
f.Fuzz(func(t *testing.T, num int) {
24+
result := CeilPowerOfTwo(num)
25+
26+
// Property 1: Result should always be >= 1
27+
if result < 1 {
28+
t.Errorf("CeilPowerOfTwo(%d) = %d, want >= 1", num, result)
29+
}
30+
31+
// Property 2: Result should always be a power of 2
32+
if !IsPowerOfTwo(result) {
33+
t.Errorf("CeilPowerOfTwo(%d) = %d, which is not a power of 2", num, result)
34+
}
35+
36+
// Property 3: For positive numbers, result should be >= input
37+
if num > 0 && result < num {
38+
t.Errorf("CeilPowerOfTwo(%d) = %d, want >= %d", num, result, num)
39+
}
40+
41+
// Property 4: For positive numbers, result/2 should be < input (unless input is a power of 2)
42+
if num > 1 && !IsPowerOfTwo(num) && result/2 >= num {
43+
t.Errorf("CeilPowerOfTwo(%d) = %d, but %d/2 = %d >= %d", num, result, result, result/2, num)
44+
}
45+
})
46+
}
47+
48+
// FuzzNextPowerOfTwo tests the NextPowerOfTwo function with fuzzing
49+
func FuzzNextPowerOfTwo(f *testing.F) {
50+
// Add seed corpus
51+
f.Add(0)
52+
f.Add(1)
53+
f.Add(2)
54+
f.Add(7)
55+
f.Add(8)
56+
f.Add(15)
57+
f.Add(16)
58+
f.Add(31)
59+
f.Add(32)
60+
f.Add(1024)
61+
f.Add(1073741823) // 2^30 - 1
62+
63+
f.Fuzz(func(t *testing.T, n int) {
64+
// Skip negative numbers as the function behavior is undefined for them
65+
if n <= 0 {
66+
t.Skip()
67+
}
68+
69+
result := NextPowerOfTwo(n)
70+
71+
// Property 1: Result should be a power of 2
72+
if !IsPowerOfTwo(result) {
73+
t.Errorf("NextPowerOfTwo(%d) = %d, which is not a power of 2", n, result)
74+
}
75+
76+
// Property 2: Result should be >= n
77+
if result < n {
78+
t.Errorf("NextPowerOfTwo(%d) = %d, want >= %d", n, result, n)
79+
}
80+
81+
// Property 3: If n is already a power of 2, result should equal n
82+
if IsPowerOfTwo(n) && result != n {
83+
t.Errorf("NextPowerOfTwo(%d) = %d, want %d (input is already power of 2)", n, result, n)
84+
}
85+
86+
// Property 4: If n is not a power of 2, result should be the smallest power of 2 > n
87+
if !IsPowerOfTwo(n) && result/2 >= n {
88+
t.Errorf("NextPowerOfTwo(%d) = %d, but %d/2 = %d >= %d", n, result, result, result/2, n)
89+
}
90+
})
91+
}
92+
93+
// FuzzNextLowerPowerOfTwo tests the NextLowerPowerOfTwo function with fuzzing
94+
func FuzzNextLowerPowerOfTwo(f *testing.F) {
95+
// Add seed corpus
96+
f.Add(uint(0))
97+
f.Add(uint(1))
98+
f.Add(uint(2))
99+
f.Add(uint(7))
100+
f.Add(uint(8))
101+
f.Add(uint(15))
102+
f.Add(uint(16))
103+
f.Add(uint(31))
104+
f.Add(uint(32))
105+
f.Add(uint(1024))
106+
f.Add(uint(4294967295)) // Max uint32
107+
108+
f.Fuzz(func(t *testing.T, x uint) {
109+
result := NextLowerPowerOfTwo(x)
110+
111+
// Property 1: For x = 0, result should be 0
112+
if x == 0 && result != 0 {
113+
t.Errorf("NextLowerPowerOfTwo(0) = %d, want 0", result)
114+
}
115+
116+
// Property 2: For x > 0, result should be a power of 2
117+
if x > 0 && !IsPowerOfTwo(int(result)) {
118+
t.Errorf("NextLowerPowerOfTwo(%d) = %d, which is not a power of 2", x, result)
119+
}
120+
121+
// Property 3: Result should be <= x
122+
if result > x {
123+
t.Errorf("NextLowerPowerOfTwo(%d) = %d, want <= %d", x, result, x)
124+
}
125+
126+
// Property 4: For x > 1, result*2 should be > x (unless x is a power of 2)
127+
if x > 1 && !IsPowerOfTwo(int(x)) && result*2 <= x {
128+
t.Errorf("NextLowerPowerOfTwo(%d) = %d, but %d*2 = %d <= %d", x, result, result, result*2, x)
129+
}
130+
131+
// Property 5: If x is a power of 2, result should equal x
132+
if x > 0 && IsPowerOfTwo(int(x)) && result != x {
133+
t.Errorf("NextLowerPowerOfTwo(%d) = %d, want %d (input is power of 2)", x, result, x)
134+
}
135+
})
136+
}

0 commit comments

Comments
 (0)