github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/prog/test_util.go (about)

     1  // Copyright 2020 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 prog
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  	"testing"
    10  )
    11  
    12  func InitTargetTest(t *testing.T, os, arch string) *Target {
    13  	t.Parallel()
    14  	target, err := GetTarget(os, arch)
    15  	if err != nil {
    16  		t.Fatal(err)
    17  	}
    18  	return target
    19  }
    20  
    21  type DeserializeTest struct {
    22  	In        string
    23  	Out       string // if not set, equals to In
    24  	Err       string
    25  	StrictErr string // if not set, equals to Err
    26  }
    27  
    28  func TestDeserializeHelper(t *testing.T, OS, arch string, transform func(*Target, *Prog), tests []DeserializeTest) {
    29  	target := InitTargetTest(t, OS, arch)
    30  	for testidx, test := range tests {
    31  		t.Run(fmt.Sprint(testidx), func(t *testing.T) {
    32  			if test.StrictErr == "" {
    33  				test.StrictErr = test.Err
    34  			}
    35  			if test.Err != "" && test.Out != "" {
    36  				t.Errorf("both Err and Out are set")
    37  			}
    38  			if test.In == test.Out {
    39  				t.Errorf("in and out are equal, remove Out in such case\n%v", test.In)
    40  			}
    41  			if test.Out == "" {
    42  				test.Out = test.In
    43  			}
    44  			for _, mode := range []DeserializeMode{NonStrict, Strict} {
    45  				p, err := target.Deserialize([]byte(test.In), mode)
    46  				wantErr := test.Err
    47  				if mode == Strict {
    48  					wantErr = test.StrictErr
    49  				}
    50  				if err != nil {
    51  					if wantErr == "" {
    52  						t.Fatalf("deserialization failed with\n%s\ndata:\n%s",
    53  							err, test.In)
    54  					}
    55  					if !strings.Contains(err.Error(), wantErr) {
    56  						t.Fatalf("deserialization failed with\n%s\nwhich doesn't match\n%s\ndata:\n%s",
    57  							err, wantErr, test.In)
    58  					}
    59  				} else {
    60  					if wantErr != "" {
    61  						t.Fatalf("deserialization should have failed with:\n%s\ndata:\n%s",
    62  							wantErr, test.In)
    63  					}
    64  					if transform != nil {
    65  						transform(target, p)
    66  					}
    67  					output := strings.TrimSpace(string(p.Serialize()))
    68  					outputVerbose := strings.TrimSpace(string(p.SerializeVerbose()))
    69  					want := strings.TrimSpace(test.Out)
    70  					// We want to compare both verbose & non verbose mode.
    71  					// Otherwise we cannot have just In: field for the calls where
    72  					// the verbose and non-verbose output don't match -- the strict parsing
    73  					// mode does not accept the non-verbose output as input.
    74  					if want != output && want != outputVerbose {
    75  						t.Fatalf("wrong serialized data:\n%s\nexpect:\n%s", outputVerbose, want)
    76  					}
    77  					p.SerializeForExec()
    78  				}
    79  			}
    80  		})
    81  	}
    82  }