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