github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/tools/syz-trace2syz/parser/parser_test.go (about) 1 // Copyright 2018 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 4 //go:build !codeanalysis 5 6 package parser 7 8 import ( 9 "testing" 10 11 _ "github.com/google/syzkaller/sys" 12 ) 13 14 func TestParseLoopBasic(t *testing.T) { 15 tests := []string{ 16 `open() = 3 17 fstat() = 0`, 18 `open() = 0x73ffddabc 19 fstat() = 0`, 20 `open() = -1 ENOSPEC (something) 21 fstat() = 0`, 22 `open( , <unfinished ...> 23 <... open resumed>) = 3 24 fstat() = 0`, 25 `open( , <unfinished ...> 26 <... open resumed> , 2) = 3 27 fstat() = 0`, 28 `open( <unfinished ...> 29 <... open resumed>) = 3 30 fstat() = 0`, 31 `open( <unfinished ...> 32 <... open resumed>) = 0x44277ffff 33 fstat() = 0`, 34 `open( <unfinished ...> 35 <... open resumed>) = ? 36 fstat() = 0`, 37 `open( <unfinished ...> 38 <... open resumed>) = -1 FLAG (sdfjfjfjf) 39 fstat() = 0`, 40 `open(1, <unfinished ...> 41 <... open resumed> , 0x1|0x2) = -1 FLAG (sdfjfjfjf) 42 fstat() = 0`, 43 `open([0x1, 0x2], NULL, {tv_sec=5, tv_nsec=0}, 8 <unfinished ...> 44 <... rt_sigtimedwait resumed> ) = 10 (SIGUSR1) 45 fstat() = 0`, 46 `open(0, 536892418, {c_cc[VMIN]=1, c_cc[VTIME]=0} <unfinished ...> 47 <... open resumed> , 0x1|0x2) = -1 FLAG (sdfjfjfjf) 48 fstat() = 0`, 49 `open(-19) = 0 50 fstat() = 0`, 51 `open(1 + 2) = 0 52 fstat() = 0`, 53 `open(3 - 1) = 0 54 fstat() = 0`, 55 `open(1075599392, 0x20000000) = -1 EBADF (Bad file descriptor) 56 fstat() = 0`, 57 `open() = -1 EIO (Input/output error) 58 fstat() = 0`, 59 `open(113->114) = -1 EIO (Input/output error) 60 fstat() = 0`, 61 } 62 63 for _, test := range tests { 64 tree, err := ParseData([]byte(test)) 65 if err != nil { 66 t.Fatal(err) 67 } 68 if tree.RootPid != -1 { 69 t.Fatalf("Incorrect Root Pid: %d", tree.RootPid) 70 } 71 72 calls := tree.TraceMap[tree.RootPid].Calls 73 if len(calls) != 2 { 74 t.Fatalf("expected 2 calls. Got %d instead", len(calls)) 75 } 76 if calls[0].CallName != "open" || calls[1].CallName != "fstat" { 77 t.Fatalf("call list should be open->fstat. Got %s->%s", calls[0].CallName, calls[1].CallName) 78 } 79 } 80 } 81 82 func TestEvaluateExpressions(t *testing.T) { 83 type ExprTest struct { 84 line string 85 expectedEval uint64 86 } 87 tests := []ExprTest{ 88 {"open(0x1) = 0", 1}, 89 {"open(1) = 0", 1}, 90 {"open(0x1|0x2) = 0", 3}, 91 {"open(0x1|2) = 0", 3}, 92 {"open(1 << 5) = 0", 32}, 93 {"open(1 << 5|1) = 0", 33}, 94 {"open(1 & 0) = 0", 0}, 95 {"open(1 + 2) = 0", 3}, 96 {"open(1-2) = 0", ^uint64(0)}, 97 {"open(4 >> 1) = 0", 2}, 98 {"open(0700) = 0", 448}, 99 {"open(0) = 0", 0}, 100 } 101 for i, test := range tests { 102 tree, err := ParseData([]byte(test.line)) 103 if err != nil { 104 t.Fatal(err) 105 } 106 if tree.RootPid != -1 { 107 t.Fatalf("failed test: %d. Incorrect Root Pid: %d", i, tree.RootPid) 108 } 109 calls := tree.TraceMap[tree.RootPid].Calls 110 if len(calls) != 1 { 111 t.Fatalf("failed test: %d. Expected 1 call. Got %d instead", i, len(calls)) 112 } 113 arg, ok := calls[0].Args[0].(Constant) 114 if !ok { 115 t.Fatalf("first argument expected to be constant. Got: %s", arg.String()) 116 } 117 if arg.Val() != test.expectedEval { 118 t.Fatalf("expected %v != %v", test.expectedEval, arg.Val()) 119 } 120 } 121 } 122 123 func TestParseLoopPid(t *testing.T) { 124 data := `1 open() = 3 125 1 fstat() = 0` 126 127 tree, err := ParseData([]byte(data)) 128 if err != nil { 129 t.Fatal(err) 130 } 131 if tree.RootPid != 1 { 132 t.Fatalf("Incorrect Root Pid: %d", tree.RootPid) 133 } 134 135 calls := tree.TraceMap[tree.RootPid].Calls 136 if len(calls) != 2 { 137 t.Fatalf("Expect 2 calls. Got %d instead", len(calls)) 138 } 139 if calls[0].CallName != "open" || calls[1].CallName != "fstat" { 140 t.Fatalf("call list should be open->fstat. Got %s->%s", calls[0].CallName, calls[1].CallName) 141 } 142 } 143 144 func TestParseLoop1Child(t *testing.T) { 145 data1Child := `1 open() = 3 146 1 clone() = 2 147 2 read() = 16` 148 149 tree, err := ParseData([]byte(data1Child)) 150 if err != nil { 151 t.Fatal(err) 152 } 153 if len(tree.TraceMap) != 2 { 154 t.Fatalf("Incorrect Root Pid. Expected: 2, Got %d", tree.RootPid) 155 } 156 if tree.RootPid != 1 { 157 t.Fatalf("Incorrect Root Pid. Expected: 1, Got %d", tree.RootPid) 158 } 159 if tree.Ptree[tree.RootPid][0] != 2 { 160 t.Fatalf("Expected child to have pid: 2. Got %d", tree.Ptree[tree.RootPid][0]) 161 } else { 162 if len(tree.TraceMap[2].Calls) != 1 { 163 t.Fatalf("Child trace should have only 1 call. Got %d", len(tree.TraceMap[2].Calls)) 164 } 165 } 166 } 167 168 func TestParseLoop2Childs(t *testing.T) { 169 data2Childs := `1 open() = 3 170 1 clone() = 2 171 2 read() = 16 172 1 clone() = 3 173 3 open() = 3` 174 tree, err := ParseData([]byte(data2Childs)) 175 if err != nil { 176 t.Fatal(err) 177 } 178 if len(tree.TraceMap) != 3 { 179 t.Fatalf("Incorrect Root Pid. Expected: 3, Got %d", tree.RootPid) 180 } 181 if len(tree.Ptree[tree.RootPid]) != 2 { 182 t.Fatalf("Expected Pid 1 to have 2 children: Got %d", len(tree.Ptree[tree.RootPid])) 183 } 184 } 185 186 func TestParseLoop1Grandchild(t *testing.T) { 187 data1Grandchild := `1 open() = 3 188 1 clone() = 2 189 2 clone() = 3 190 3 open() = 4` 191 tree, err := ParseData([]byte(data1Grandchild)) 192 if err != nil { 193 t.Fatal(err) 194 } 195 if len(tree.Ptree[tree.RootPid]) != 1 { 196 t.Fatalf("Expect RootPid to have 1 child. Got %d", tree.RootPid) 197 } 198 if len(tree.Ptree[2]) != 1 { 199 t.Fatalf("Incorrect Root Pid. Expected: 3, Got %d", tree.RootPid) 200 201 } 202 } 203 204 func TestParseGroupType(t *testing.T) { 205 type irTest struct { 206 test string 207 } 208 tests := []irTest{ 209 {`open({1, 2, 3}) = 0`}, 210 {`open([1, 2, 3]) = 0`}, 211 {`open([1 2 3]) = 0`}, 212 } 213 for _, test := range tests { 214 tree, err := ParseData([]byte(test.test)) 215 if err != nil { 216 t.Fatal(err) 217 } 218 call := tree.TraceMap[tree.RootPid].Calls[0] 219 _, ok := call.Args[0].(*GroupType) 220 if !ok { 221 t.Fatalf("Expected Group type. Got: %#v", call.Args[0]) 222 } 223 } 224 }