mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-23 19:39:40 +00:00
52a33fd516
Now each prog function accepts the desired target explicitly. No global, implicit state involved. This is much cleaner and allows cross-OS/arch testing, etc.
127 lines
2.7 KiB
Go
127 lines
2.7 KiB
Go
// Copyright 2016 syzkaller project authors. All rights reserved.
|
|
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
|
|
|
package prog
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"regexp"
|
|
"sort"
|
|
"testing"
|
|
)
|
|
|
|
func setToArray(s map[string]struct{}) []string {
|
|
a := make([]string, 0, len(s))
|
|
for c := range s {
|
|
a = append(a, c)
|
|
}
|
|
sort.Strings(a)
|
|
return a
|
|
}
|
|
|
|
func TestCallSet(t *testing.T) {
|
|
tests := []struct {
|
|
prog string
|
|
ok bool
|
|
calls []string
|
|
}{
|
|
{
|
|
"",
|
|
false,
|
|
[]string{},
|
|
},
|
|
{
|
|
"r0 = (foo)",
|
|
false,
|
|
[]string{},
|
|
},
|
|
{
|
|
"getpid()",
|
|
true,
|
|
[]string{"getpid"},
|
|
},
|
|
{
|
|
"r11 = getpid()",
|
|
true,
|
|
[]string{"getpid"},
|
|
},
|
|
{
|
|
"getpid()\n" +
|
|
"open(0x1, something that this package may not understand)\n" +
|
|
"getpid()\n" +
|
|
"#read()\n" +
|
|
"\n" +
|
|
"close$foo(&(0x0000) = {})\n",
|
|
true,
|
|
[]string{"getpid", "open", "close$foo"},
|
|
},
|
|
}
|
|
for i, test := range tests {
|
|
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
|
calls, err := CallSet([]byte(test.prog))
|
|
if err != nil && test.ok {
|
|
t.Fatalf("parsing failed: %v", err)
|
|
}
|
|
if err == nil && !test.ok {
|
|
t.Fatalf("parsing did not fail")
|
|
}
|
|
callArray := setToArray(calls)
|
|
sort.Strings(test.calls)
|
|
if !reflect.DeepEqual(callArray, test.calls) {
|
|
t.Fatalf("got call set %+v, expect %+v", callArray, test.calls)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCallSetRandom(t *testing.T) {
|
|
target, rs, iters := initTest(t)
|
|
for i := 0; i < iters; i++ {
|
|
p := target.Generate(rs, 10, nil)
|
|
calls0 := make(map[string]struct{})
|
|
for _, c := range p.Calls {
|
|
calls0[c.Meta.Name] = struct{}{}
|
|
}
|
|
calls1, err := CallSet(p.Serialize())
|
|
if err != nil {
|
|
t.Fatalf("CallSet failed: %v", err)
|
|
}
|
|
callArray0 := setToArray(calls0)
|
|
callArray1 := setToArray(calls1)
|
|
if !reflect.DeepEqual(callArray0, callArray1) {
|
|
t.Fatalf("got call set:\n%+v\nexpect:\n%+v", callArray1, callArray0)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDeserialize(t *testing.T) {
|
|
target, _, _ := initTest(t)
|
|
tests := []struct {
|
|
data string
|
|
err *regexp.Regexp
|
|
}{
|
|
{
|
|
"syz_test$struct(&(0x7f0000000000)={0x0, {0x0}})",
|
|
nil,
|
|
},
|
|
{
|
|
"syz_test$struct(&(0x7f0000000000)=0x0)",
|
|
regexp.MustCompile(`bad const type.*`),
|
|
},
|
|
}
|
|
for _, test := range tests {
|
|
_, err := target.Deserialize([]byte(test.data))
|
|
if err != nil {
|
|
if test.err == nil {
|
|
t.Fatalf("deserialization failed with\n%s\ndata:\n%s\n", err, test.data)
|
|
}
|
|
if !test.err.MatchString(err.Error()) {
|
|
t.Fatalf("deserialization failed with\n%s\nwhich doesn't match\n%s\ndata:\n%s\n", err, test.err, test.data)
|
|
}
|
|
} else if test.err != nil {
|
|
t.Fatalf("deserialization should have failed with:\n%s\ndata:\n%s\n", test.err, test.data)
|
|
}
|
|
}
|
|
}
|