1// Copyright 2015 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 4package csource 5 6import ( 7 "fmt" 8 "math/rand" 9 "os" 10 "strings" 11 "testing" 12 "time" 13 14 "github.com/google/syzkaller/prog" 15 _ "github.com/google/syzkaller/sys" 16) 17 18func TestGenerate(t *testing.T) { 19 t.Parallel() 20 for _, target := range prog.AllTargets() { 21 switch target.OS { 22 case "netbsd", "windows": 23 continue 24 } 25 target := target 26 t.Run(target.OS+"/"+target.Arch, func(t *testing.T) { 27 if target.OS == "linux" && target.Arch == "arm" { 28 // This currently fails (at least with my arm-linux-gnueabihf-gcc-4.8) with: 29 // Assembler messages: 30 // Error: alignment too large: 15 assumed 31 t.Skip("broken") 32 } 33 if target.OS == "linux" && target.Arch == "386" { 34 // Currently fails on travis with: 35 // fatal error: asm/unistd.h: No such file or directory 36 t.Skip("broken") 37 } 38 if target.OS == "test" && target.PtrSize == 4 { 39 // The same reason as linux/32. 40 t.Skip("broken") 41 } 42 t.Parallel() 43 testTarget(t, target) 44 }) 45 } 46} 47 48func testTarget(t *testing.T, target *prog.Target) { 49 seed := int64(time.Now().UnixNano()) 50 rs := rand.NewSource(seed) 51 t.Logf("seed=%v", seed) 52 r := rand.New(rs) 53 progs := []*prog.Prog{target.GenerateSimpleProg()} 54 if p := target.GenerateAllSyzProg(rs); len(p.Calls) != 0 { 55 progs = append(progs, p) 56 } 57 if !testing.Short() { 58 progs = append(progs, target.Generate(rs, 10, nil)) 59 } 60 opts := allOptionsSingle(target.OS) 61 opts = append(opts, Options{ 62 Threaded: true, 63 Collide: true, 64 Repeat: true, 65 Procs: 2, 66 Sandbox: "none", 67 Repro: true, 68 UseTmpDir: true, 69 }) 70 allPermutations := allOptionsPermutations(target.OS) 71 if testing.Short() { 72 for i := 0; i < 16; i++ { 73 opts = append(opts, allPermutations[r.Intn(len(allPermutations))]) 74 } 75 } else { 76 opts = allPermutations 77 } 78 for pi, p := range progs { 79 for opti, opts := range opts { 80 p, opts := p, opts 81 t.Run(fmt.Sprintf("%v/%v", pi, opti), func(t *testing.T) { 82 t.Parallel() 83 testOne(t, p, opts) 84 }) 85 } 86 } 87} 88 89func testOne(t *testing.T, p *prog.Prog, opts Options) { 90 src, err := Write(p, opts) 91 if err != nil { 92 t.Logf("opts: %+v\nprogram:\n%s\n", opts, p.Serialize()) 93 t.Fatalf("%v", err) 94 } 95 bin, err := Build(p.Target, src) 96 if err != nil { 97 if strings.Contains(err.Error(), "no target compiler") { 98 t.Skip(err) 99 } 100 t.Logf("opts: %+v\nprogram:\n%s\n", opts, p.Serialize()) 101 t.Fatalf("%v", err) 102 } 103 defer os.Remove(bin) 104} 105