github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/syz-verifier/execresult_test.go (about) 1 // Copyright 2021 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 // TODO: switch syz-verifier to use syz-fuzzer. 5 6 //go:build ignore 7 8 package main 9 10 import ( 11 "testing" 12 13 "github.com/google/go-cmp/cmp" 14 "github.com/google/syzkaller/prog" 15 ) 16 17 func TestIsEqual(t *testing.T) { 18 tests := []struct { 19 name string 20 res []*ExecResult 21 want bool 22 }{ 23 { 24 name: "only crashes", 25 res: []*ExecResult{ 26 makeExecResultCrashed(1), 27 makeExecResultCrashed(4), 28 }, 29 want: false, 30 }, 31 { 32 name: "mismatch because result and crash", 33 res: []*ExecResult{ 34 makeExecResultCrashed(1), 35 makeExecResult(2, []int{11, 33, 22}, []int{1, 3, 3}...), 36 }, 37 want: false, 38 }, 39 { 40 name: "mismatches because of diffent length", 41 res: []*ExecResult{ 42 makeExecResult(2, []int{11, 33}, []int{1, 3}...), 43 makeExecResult(4, []int{11, 33, 22}, []int{1, 3, 3}...)}, 44 want: false, 45 }, 46 { 47 name: "mismatches not found", 48 res: []*ExecResult{ 49 makeExecResult(2, []int{11, 33, 22}, []int{1, 3, 3}...), 50 makeExecResult(4, []int{11, 33, 22}, []int{1, 3, 3}...)}, 51 want: true, 52 }, 53 { 54 name: "mismatches found in results", 55 res: []*ExecResult{ 56 makeExecResult(1, []int{1, 3, 2}, []int{4, 7, 7}...), 57 makeExecResult(4, []int{1, 3, 5}, []int{4, 7, 3}...), 58 }, 59 want: false, 60 }} 61 62 for _, test := range tests { 63 t.Run(test.name, func(t *testing.T) { 64 got := test.res[0].IsEqual(test.res[1]) 65 if diff := cmp.Diff(test.want, got); diff != "" { 66 t.Errorf("ExecResult.IsEqual failure (-want +got):\n%s", diff) 67 } 68 }) 69 } 70 } 71 72 func TestCompareResults(t *testing.T) { 73 p := "breaks_returns()\n" + 74 "minimize$0(0x1, 0x1)\n" + 75 "test$res0()\n" 76 tests := []struct { 77 name string 78 res []*ExecResult 79 wantReport *ResultReport 80 wantStats []*CallStats 81 }{ 82 { 83 name: "only crashes", 84 res: []*ExecResult{ 85 makeExecResultCrashed(1), 86 makeExecResultCrashed(4), 87 }, 88 wantReport: &ResultReport{ 89 Prog: p, 90 Reports: []*CallReport{ 91 {Call: "breaks_returns", States: map[int]ReturnState{ 92 1: crashedReturnState(), 93 4: crashedReturnState()}, 94 }, 95 {Call: "minimize$0", States: map[int]ReturnState{ 96 1: crashedReturnState(), 97 4: crashedReturnState()}, 98 }, 99 {Call: "test$res0", States: map[int]ReturnState{ 100 1: crashedReturnState(), 101 4: crashedReturnState()}, 102 }, 103 }, 104 Mismatch: false, 105 }, 106 }, 107 { 108 name: "mismatches because results and crashes", 109 res: []*ExecResult{ 110 makeExecResultCrashed(1), 111 makeExecResult(2, []int{11, 33, 22}, []int{1, 3, 3}...), 112 makeExecResult(4, []int{11, 33, 22}, []int{1, 3, 3}...), 113 }, 114 wantReport: &ResultReport{ 115 Prog: p, 116 Reports: []*CallReport{ 117 {Call: "breaks_returns", States: map[int]ReturnState{ 118 1: crashedReturnState(), 119 2: returnState(11, 1), 120 4: returnState(11, 1)}, 121 Mismatch: true}, 122 {Call: "minimize$0", States: map[int]ReturnState{ 123 1: crashedReturnState(), 124 2: returnState(33, 3), 125 4: returnState(33, 3)}, 126 Mismatch: true}, 127 {Call: "test$res0", States: map[int]ReturnState{ 128 1: crashedReturnState(), 129 2: returnState(22, 3), 130 4: returnState(22, 3)}, 131 Mismatch: true}, 132 }, 133 Mismatch: true, 134 }, 135 }, 136 { 137 name: "mismatches not found in results", 138 res: []*ExecResult{ 139 makeExecResult(2, []int{11, 33, 22}, []int{1, 3, 3}...), 140 makeExecResult(4, []int{11, 33, 22}, []int{1, 3, 3}...)}, 141 wantReport: &ResultReport{ 142 Prog: p, 143 Reports: []*CallReport{ 144 {Call: "breaks_returns", States: map[int]ReturnState{2: {Errno: 11, Flags: 1}, 4: {Errno: 11, Flags: 1}}}, 145 {Call: "minimize$0", States: map[int]ReturnState{2: {Errno: 33, Flags: 3}, 4: {Errno: 33, Flags: 3}}}, 146 {Call: "test$res0", States: map[int]ReturnState{2: {Errno: 22, Flags: 3}, 4: {Errno: 22, Flags: 3}}}, 147 }, 148 Mismatch: false, 149 }, 150 }, 151 { 152 name: "mismatches found in results", 153 res: []*ExecResult{ 154 makeExecResult(1, []int{1, 3, 2}, []int{4, 7, 7}...), 155 makeExecResult(4, []int{1, 3, 5}, []int{4, 7, 3}...), 156 }, 157 wantReport: &ResultReport{ 158 Prog: p, 159 Reports: []*CallReport{ 160 {Call: "breaks_returns", States: map[int]ReturnState{1: {Errno: 1, Flags: 4}, 4: {Errno: 1, Flags: 4}}}, 161 {Call: "minimize$0", States: map[int]ReturnState{1: {Errno: 3, Flags: 7}, 4: {Errno: 3, Flags: 7}}}, 162 {Call: "test$res0", States: map[int]ReturnState{1: {Errno: 2, Flags: 7}, 4: {Errno: 5, Flags: 3}}, Mismatch: true}, 163 }, 164 Mismatch: true, 165 }, 166 }} 167 168 for _, test := range tests { 169 t.Run(test.name, func(t *testing.T) { 170 target := prog.InitTargetTest(t, "test", "64") 171 prog, err := target.Deserialize([]byte(p), prog.Strict) 172 if err != nil { 173 t.Fatalf("failed to deserialise test program: %v", err) 174 } 175 got := CompareResults(test.res, prog) 176 if diff := cmp.Diff(test.wantReport, got); diff != "" { 177 t.Errorf("verify report mismatch (-want +got):\n%s", diff) 178 } 179 }) 180 } 181 }