github.com/cilium/ebpf@v0.10.0/btf/traversal_test.go (about) 1 package btf 2 3 import ( 4 "fmt" 5 "math/rand" 6 "testing" 7 "time" 8 9 qt "github.com/frankban/quicktest" 10 ) 11 12 func init() { 13 seed := time.Now().UnixMicro() 14 fmt.Println("seed:", seed) 15 rand.Seed(seed) 16 } 17 18 func TestPostorderTraversal(t *testing.T) { 19 ptr := newCyclicalType(2).(*Pointer) 20 cst := ptr.Target.(*Const) 21 str := cst.Type.(*Struct) 22 23 t.Logf("%3v", ptr) 24 pending := []Type{str, cst, ptr} 25 iter := postorderTraversal(ptr, nil) 26 for iter.Next() { 27 qt.Assert(t, iter.Type, qt.Equals, pending[0]) 28 pending = pending[1:] 29 } 30 qt.Assert(t, pending, qt.HasLen, 0) 31 32 i := &Int{Name: "foo"} 33 // i appears twice at the same nesting depth. 34 arr := &Array{Index: i, Type: i} 35 seen := make(map[Type]bool) 36 iter = postorderTraversal(arr, nil) 37 for iter.Next() { 38 qt.Assert(t, seen[iter.Type], qt.IsFalse) 39 seen[iter.Type] = true 40 } 41 qt.Assert(t, seen[arr], qt.IsTrue) 42 qt.Assert(t, seen[i], qt.IsTrue) 43 } 44 45 func TestPostorderTraversalVmlinux(t *testing.T) { 46 spec := vmlinuxTestdataSpec(t) 47 48 typ, err := spec.AnyTypeByName("gov_update_cpu_data") 49 if err != nil { 50 t.Fatal(err) 51 } 52 53 for _, typ := range []Type{typ} { 54 t.Run(fmt.Sprintf("%s", typ), func(t *testing.T) { 55 seen := make(map[Type]bool) 56 var last Type 57 iter := postorderTraversal(typ, nil) 58 for iter.Next() { 59 if seen[iter.Type] { 60 t.Fatalf("%s visited twice", iter.Type) 61 } 62 seen[iter.Type] = true 63 last = iter.Type 64 } 65 if last != typ { 66 t.Fatalf("Expected %s got %s as last type", typ, last) 67 } 68 69 walkType(typ, func(child *Type) { 70 qt.Check(t, seen[*child], qt.IsTrue, qt.Commentf("missing child %s", *child)) 71 }) 72 }) 73 } 74 } 75 76 func BenchmarkPostorderTraversal(b *testing.B) { 77 spec := vmlinuxTestdataSpec(b) 78 79 var fn *Func 80 err := spec.TypeByName("gov_update_cpu_data", &fn) 81 if err != nil { 82 b.Fatal(err) 83 } 84 85 for _, test := range []struct { 86 name string 87 typ Type 88 }{ 89 {"single type", &Int{}}, 90 {"cycle(1)", newCyclicalType(1)}, 91 {"cycle(10)", newCyclicalType(10)}, 92 {"gov_update_cpu_data", fn}, 93 } { 94 b.Logf("%10v", test.typ) 95 96 b.Run(test.name, func(b *testing.B) { 97 b.ReportAllocs() 98 for i := 0; i < b.N; i++ { 99 iter := postorderTraversal(test.typ, nil) 100 for iter.Next() { 101 } 102 } 103 }) 104 } 105 }