gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/kernel/table_test.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package kernel 16 17 import ( 18 "testing" 19 20 "gvisor.dev/gvisor/pkg/abi" 21 "gvisor.dev/gvisor/pkg/sentry/arch" 22 ) 23 24 const ( 25 maxTestSyscall = 1000 26 ) 27 28 func createSyscallTable() *SyscallTable { 29 m := make(map[uintptr]Syscall) 30 for i := uintptr(0); i <= maxTestSyscall; i++ { 31 j := i 32 m[i] = Syscall{ 33 Fn: func(t *Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *SyscallControl, error) { 34 return j, nil, nil 35 }, 36 } 37 } 38 39 s := &SyscallTable{ 40 OS: abi.Linux, 41 Arch: arch.AMD64, 42 Table: m, 43 } 44 45 RegisterSyscallTable(s) 46 return s 47 } 48 49 func TestTable(t *testing.T) { 50 table := createSyscallTable() 51 defer func() { 52 // Cleanup registered tables to keep tests separate. 53 allSyscallTables = []*SyscallTable{} 54 }() 55 56 // Go through all functions and check that they return the right value. 57 for i := uintptr(0); i < maxTestSyscall; i++ { 58 fn := table.Lookup(i) 59 if fn == nil { 60 t.Errorf("Syscall %v is set to nil", i) 61 continue 62 } 63 64 v, _, _ := fn(nil, i, arch.SyscallArguments{}) 65 if v != i { 66 t.Errorf("Wrong return value for syscall %v: expected %v, got %v", i, i, v) 67 } 68 } 69 70 // Check that values outside the range return nil. 71 for i := uintptr(maxTestSyscall + 1); i < maxTestSyscall+100; i++ { 72 fn := table.Lookup(i) 73 if fn != nil { 74 t.Errorf("Syscall %v is not nil: %v", i, fn) 75 continue 76 } 77 } 78 } 79 80 func BenchmarkTableLookup(b *testing.B) { 81 table := createSyscallTable() 82 83 b.ResetTimer() 84 85 j := uintptr(0) 86 for i := 0; i < b.N; i++ { 87 table.Lookup(j) 88 j = (j + 1) % 310 89 } 90 91 b.StopTimer() 92 // Cleanup registered tables to keep tests separate. 93 allSyscallTables = []*SyscallTable{} 94 } 95 96 func BenchmarkTableMapLookup(b *testing.B) { 97 table := createSyscallTable() 98 99 b.ResetTimer() 100 101 j := uintptr(0) 102 for i := 0; i < b.N; i++ { 103 table.mapLookup(j) 104 j = (j + 1) % 310 105 } 106 107 b.StopTimer() 108 // Cleanup registered tables to keep tests separate. 109 allSyscallTables = []*SyscallTable{} 110 }