github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/descriptor/table_test.go (about) 1 package descriptor_test 2 3 import ( 4 "testing" 5 6 "github.com/bananabytelabs/wazero/internal/sys" 7 "github.com/bananabytelabs/wazero/internal/testing/require" 8 ) 9 10 func TestFileTable(t *testing.T) { 11 table := new(sys.FileTable) 12 13 if n := table.Len(); n != 0 { 14 t.Errorf("new table is not empty: length=%d", n) 15 } 16 17 // The id field is used as a sentinel value. 18 v0 := &sys.FileEntry{Name: "1"} 19 v1 := &sys.FileEntry{Name: "2"} 20 v2 := &sys.FileEntry{Name: "3"} 21 22 k0, ok := table.Insert(v0) 23 require.True(t, ok) 24 k1, ok := table.Insert(v1) 25 require.True(t, ok) 26 k2, ok := table.Insert(v2) 27 require.True(t, ok) 28 29 // Try to re-order, but to an invalid value 30 ok = table.InsertAt(v2, -1) 31 require.False(t, ok) 32 33 for _, lookup := range []struct { 34 key int32 35 val *sys.FileEntry 36 }{ 37 {key: k0, val: v0}, 38 {key: k1, val: v1}, 39 {key: k2, val: v2}, 40 } { 41 if v, ok := table.Lookup(lookup.key); !ok { 42 t.Errorf("value not found for key '%v'", lookup.key) 43 } else if v.Name != lookup.val.Name { 44 t.Errorf("wrong value returned for key '%v': want=%v got=%v", lookup.key, lookup.val.Name, v.Name) 45 } 46 } 47 48 if n := table.Len(); n != 3 { 49 t.Errorf("wrong table length: want=3 got=%d", n) 50 } 51 52 k0Found := false 53 k1Found := false 54 k2Found := false 55 table.Range(func(k int32, v *sys.FileEntry) bool { 56 var want *sys.FileEntry 57 switch k { 58 case k0: 59 k0Found, want = true, v0 60 case k1: 61 k1Found, want = true, v1 62 case k2: 63 k2Found, want = true, v2 64 } 65 if v.Name != want.Name { 66 t.Errorf("wrong value found ranging over '%v': want=%v got=%v", k, want.Name, v.Name) 67 } 68 return true 69 }) 70 71 for _, found := range []struct { 72 key int32 73 ok bool 74 }{ 75 {key: k0, ok: k0Found}, 76 {key: k1, ok: k1Found}, 77 {key: k2, ok: k2Found}, 78 } { 79 if !found.ok { 80 t.Errorf("key not found while ranging over table: %v", found.key) 81 } 82 } 83 84 for i, deletion := range []struct { 85 key int32 86 }{ 87 {key: k1}, 88 {key: k0}, 89 {key: k2}, 90 } { 91 table.Delete(deletion.key) 92 if _, ok := table.Lookup(deletion.key); ok { 93 t.Errorf("item found after deletion of '%v'", deletion.key) 94 } 95 if n, want := table.Len(), 3-(i+1); n != want { 96 t.Errorf("wrong table length after deletion: want=%d got=%d", want, n) 97 } 98 } 99 } 100 101 func BenchmarkFileTableInsert(b *testing.B) { 102 table := new(sys.FileTable) 103 entry := new(sys.FileEntry) 104 105 for i := 0; i < b.N; i++ { 106 table.Insert(entry) 107 108 if (i % 65536) == 0 { 109 table.Reset() // to avoid running out of memory 110 } 111 } 112 } 113 114 func BenchmarkFileTableLookup(b *testing.B) { 115 const sentinel = "42" 116 const numFiles = 65536 117 table := new(sys.FileTable) 118 files := make([]int32, numFiles) 119 entry := &sys.FileEntry{Name: sentinel} 120 121 var ok bool 122 for i := range files { 123 files[i], ok = table.Insert(entry) 124 if !ok { 125 b.Fatal("unexpected failure to insert") 126 } 127 } 128 129 var f *sys.FileEntry 130 for i := 0; i < b.N; i++ { 131 f, _ = table.Lookup(files[i%numFiles]) 132 } 133 if f.Name != sentinel { 134 b.Error("wrong file returned by lookup") 135 } 136 }