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  }