1// Copyright 2015 syzkaller project authors. All rights reserved. 2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4package prog 5 6import ( 7 "strings" 8 "testing" 9) 10 11func TestResourceCtors(t *testing.T) { 12 if testing.Short() && raceEnabled { 13 t.Skip("too slow") 14 } 15 testEachTarget(t, func(t *testing.T, target *Target) { 16 for _, c := range target.Syscalls { 17 for _, res := range target.inputResources(c) { 18 if len(target.calcResourceCtors(res.Kind, true)) == 0 { 19 t.Errorf("call %v requires input resource %v,"+ 20 " but there are no calls that can create this resource", 21 c.Name, res.Name) 22 } 23 } 24 } 25 }) 26} 27 28func TestTransitivelyEnabledCalls(t *testing.T) { 29 testEachTarget(t, func(t *testing.T, target *Target) { 30 calls := make(map[*Syscall]bool) 31 for _, c := range target.Syscalls { 32 calls[c] = true 33 } 34 enabled, disabled := target.TransitivelyEnabledCalls(calls) 35 for c, ok := range enabled { 36 if !ok { 37 t.Fatalf("syscalls %v is false in enabled map", c.Name) 38 } 39 } 40 if target.OS == "test" { 41 for c := range enabled { 42 if c.CallName == "unsupported" { 43 t.Errorf("call %v is not disabled", c.Name) 44 } 45 } 46 for c, reason := range disabled { 47 if c.CallName != "unsupported" { 48 t.Errorf("call %v is disabled: %v", c.Name, reason) 49 } 50 } 51 } else { 52 if len(enabled) != len(target.Syscalls) { 53 t.Errorf("some calls are disabled: %v/%v", len(enabled), len(target.Syscalls)) 54 } 55 for c, reason := range disabled { 56 t.Errorf("disabled %v: %v", c.Name, reason) 57 } 58 } 59 }) 60} 61 62func TestTransitivelyEnabledCallsLinux(t *testing.T) { 63 t.Parallel() 64 target, err := GetTarget("linux", "amd64") 65 if err != nil { 66 t.Fatal(err) 67 } 68 calls := make(map[*Syscall]bool) 69 for _, c := range target.Syscalls { 70 calls[c] = true 71 } 72 delete(calls, target.SyscallMap["epoll_create"]) 73 if trans, disabled := target.TransitivelyEnabledCalls(calls); len(disabled) != 0 || len(trans) != len(calls) { 74 t.Fatalf("still must be able to create epoll fd with epoll_create1") 75 } 76 delete(calls, target.SyscallMap["epoll_create1"]) 77 trans, disabled := target.TransitivelyEnabledCalls(calls) 78 if len(calls)-6 != len(trans) || 79 trans[target.SyscallMap["epoll_ctl$EPOLL_CTL_ADD"]] || 80 trans[target.SyscallMap["epoll_ctl$EPOLL_CTL_MOD"]] || 81 trans[target.SyscallMap["epoll_ctl$EPOLL_CTL_DEL"]] || 82 trans[target.SyscallMap["epoll_wait"]] || 83 trans[target.SyscallMap["epoll_pwait"]] || 84 trans[target.SyscallMap["kcmp$KCMP_EPOLL_TFD"]] { 85 t.Fatalf("epoll fd is not disabled") 86 } 87 if len(disabled) != 6 { 88 t.Fatalf("disabled %v syscalls, want 6", len(disabled)) 89 } 90 for c, reason := range disabled { 91 if !strings.Contains(reason, "no syscalls can create resource fd_epoll,"+ 92 " enable some syscalls that can create it [epoll_create epoll_create1]") { 93 t.Fatalf("%v: wrong disable reason: %v", c.Name, reason) 94 } 95 } 96} 97 98func TestClockGettime(t *testing.T) { 99 t.Parallel() 100 target, err := GetTarget("linux", "amd64") 101 if err != nil { 102 t.Fatal(err) 103 } 104 calls := make(map[*Syscall]bool) 105 for _, c := range target.Syscalls { 106 calls[c] = true 107 } 108 // Removal of clock_gettime should disable all calls that accept timespec/timeval. 109 delete(calls, target.SyscallMap["clock_gettime"]) 110 trans, disabled := target.TransitivelyEnabledCalls(calls) 111 if len(trans)+10 > len(calls) || len(trans)+len(disabled) != len(calls) || len(trans) == 0 { 112 t.Fatalf("clock_gettime did not disable enough calls: before %v, after %v, disabled %v", 113 len(calls), len(trans), len(disabled)) 114 } 115} 116