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