1
2
3
4
5 package scan_test
6
7 import (
8 "internal/runtime/gc/scan"
9 "testing"
10 )
11
12 func TestFilterNil(t *testing.T) {
13 runTestFilterNil(t, scan.FilterNil)
14 }
15
16 func runTestFilterNil(t *testing.T, filterNil func(*uintptr, int32) int32) {
17 t.Run("empty", func(t *testing.T) {
18 testFilterNil(t, []uintptr{}, []uintptr{}, filterNil)
19 })
20 t.Run("one", func(t *testing.T) {
21 testFilterNil(t, []uintptr{4}, []uintptr{4}, filterNil)
22 })
23 t.Run("elimOne", func(t *testing.T) {
24 testFilterNil(t, []uintptr{0}, []uintptr{}, filterNil)
25 })
26 t.Run("oneElimBegin", func(t *testing.T) {
27 testFilterNil(t, []uintptr{0, 4}, []uintptr{4}, filterNil)
28 })
29 t.Run("oneElimEnd", func(t *testing.T) {
30 testFilterNil(t, []uintptr{4, 0}, []uintptr{4}, filterNil)
31 })
32 t.Run("oneElimMultiBegin", func(t *testing.T) {
33 testFilterNil(t, []uintptr{0, 0, 0, 4}, []uintptr{4}, filterNil)
34 })
35 t.Run("oneElimMultiEnd", func(t *testing.T) {
36 testFilterNil(t, []uintptr{4, 0, 0, 0}, []uintptr{4}, filterNil)
37 })
38 t.Run("oneElimMulti", func(t *testing.T) {
39 testFilterNil(t, []uintptr{0, 0, 0, 4, 0}, []uintptr{4}, filterNil)
40 })
41 t.Run("two", func(t *testing.T) {
42 testFilterNil(t, []uintptr{5, 12}, []uintptr{5, 12}, filterNil)
43 })
44 t.Run("twoElimBegin", func(t *testing.T) {
45 testFilterNil(t, []uintptr{0, 5, 12}, []uintptr{5, 12}, filterNil)
46 })
47 t.Run("twoElimMid", func(t *testing.T) {
48 testFilterNil(t, []uintptr{5, 0, 12}, []uintptr{5, 12}, filterNil)
49 })
50 t.Run("twoElimEnd", func(t *testing.T) {
51 testFilterNil(t, []uintptr{5, 12, 0}, []uintptr{5, 12}, filterNil)
52 })
53 t.Run("twoElimMulti", func(t *testing.T) {
54 testFilterNil(t, []uintptr{0, 5, 0, 12, 0}, []uintptr{5, 12}, filterNil)
55 })
56 t.Run("Multi", func(t *testing.T) {
57 testFilterNil(t, []uintptr{1, 5, 5, 0, 0, 0, 12, 0, 121, 5, 0}, []uintptr{1, 5, 5, 12, 121, 5}, filterNil)
58 })
59 }
60
61 func testFilterNil(t *testing.T, buf, want []uintptr, filterNil func(*uintptr, int32) int32) {
62 var bufp *uintptr
63 if len(buf) != 0 {
64 bufp = &buf[0]
65 }
66 n := filterNil(bufp, int32(len(buf)))
67 if n > int32(len(buf)) {
68 t.Errorf("bogus new length returned: %d > %d", n, len(buf))
69 return
70 }
71 buf = buf[:n]
72 if len(buf) != len(want) {
73 t.Errorf("lengths differ: got %d, want %d", len(buf), len(want))
74 }
75
76 wantMap := make(map[uintptr]int)
77 gotMap := make(map[uintptr]int)
78 for _, p := range want {
79 wantMap[p]++
80 }
81 for _, p := range buf {
82 gotMap[p]++
83 }
84 for p, nWant := range wantMap {
85 if nGot, ok := gotMap[p]; !ok {
86 t.Errorf("want %d, but missing from output", p)
87 } else if nGot != nWant {
88 t.Errorf("want %d copies of %d, but got %d", nWant, p, nGot)
89 }
90 }
91 for p := range gotMap {
92 if _, ok := wantMap[p]; !ok {
93 t.Errorf("got %d, but didn't want it", p)
94 }
95 }
96 t.Logf("got: %v", buf)
97 t.Logf("want: %v", want)
98 }
99
View as plain text