github.com/cilium/ebpf@v0.10.0/btf/strings_test.go (about) 1 package btf 2 3 import ( 4 "bytes" 5 "strings" 6 "testing" 7 8 qt "github.com/frankban/quicktest" 9 ) 10 11 func TestStringTable(t *testing.T) { 12 const in = "\x00one\x00two\x00" 13 const splitIn = "three\x00four\x00" 14 15 st, err := readStringTable(strings.NewReader(in), nil) 16 if err != nil { 17 t.Fatal(err) 18 } 19 20 var buf bytes.Buffer 21 if err := st.Marshal(&buf); err != nil { 22 t.Fatal("Can't marshal string table:", err) 23 } 24 25 if !bytes.Equal([]byte(in), buf.Bytes()) { 26 t.Error("String table doesn't match input") 27 } 28 29 // Parse string table of split BTF 30 split, err := readStringTable(strings.NewReader(splitIn), st) 31 if err != nil { 32 t.Fatal(err) 33 } 34 35 testcases := []struct { 36 offset uint32 37 want string 38 }{ 39 {0, ""}, 40 {1, "one"}, 41 {5, "two"}, 42 {9, "three"}, 43 {15, "four"}, 44 } 45 46 for _, tc := range testcases { 47 have, err := split.Lookup(tc.offset) 48 if err != nil { 49 t.Errorf("Offset %d: %s", tc.offset, err) 50 continue 51 } 52 53 if have != tc.want { 54 t.Errorf("Offset %d: want %s but have %s", tc.offset, tc.want, have) 55 } 56 } 57 58 if _, err := st.Lookup(2); err == nil { 59 t.Error("No error when using offset pointing into middle of string") 60 } 61 62 // Make sure we reject bogus tables 63 _, err = readStringTable(strings.NewReader("\x00one"), nil) 64 if err == nil { 65 t.Fatal("Accepted non-terminated string") 66 } 67 68 _, err = readStringTable(strings.NewReader("one\x00"), nil) 69 if err == nil { 70 t.Fatal("Accepted non-empty first item") 71 } 72 } 73 74 func TestStringTableBuilder(t *testing.T) { 75 stb := newStringTableBuilder() 76 77 _, err := readStringTable(bytes.NewReader(stb.Marshal()), nil) 78 qt.Assert(t, err, qt.IsNil, qt.Commentf("Can't parse string table")) 79 80 _, err = stb.Add("foo\x00bar") 81 qt.Assert(t, err, qt.IsNotNil) 82 83 empty, err := stb.Add("") 84 qt.Assert(t, err, qt.IsNil) 85 qt.Assert(t, empty, qt.Equals, uint32(0), qt.Commentf("The empty string is not at index 0")) 86 87 foo1, _ := stb.Add("foo") 88 foo2, _ := stb.Add("foo") 89 qt.Assert(t, foo1, qt.Equals, foo2, qt.Commentf("Adding the same string returns different offsets")) 90 91 table := stb.Marshal() 92 if n := bytes.Count(table, []byte("foo")); n != 1 { 93 t.Fatalf("Marshalled string table contains foo %d times instead of once", n) 94 } 95 96 _, err = readStringTable(bytes.NewReader(table), nil) 97 qt.Assert(t, err, qt.IsNil, qt.Commentf("Can't parse string table")) 98 } 99 100 func newStringTable(strings ...string) *stringTable { 101 offsets := make([]uint32, len(strings)) 102 103 var offset uint32 104 for i, str := range strings { 105 offsets[i] = offset 106 offset += uint32(len(str)) + 1 // account for NUL 107 } 108 109 return &stringTable{nil, offsets, strings} 110 }