| // Copyright 2018 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 instance |
| |
| import ( |
| "flag" |
| "os" |
| "runtime" |
| "strings" |
| "testing" |
| ) |
| |
| func TestFuzzerCmd(t *testing.T) { |
| // IMPORTANT: if this test fails, do not fix it by changing flags here! |
| // Test how an old version of syz-fuzzer parses flags genereated by the current FuzzerCmd. |
| // This actually happens in syz-ci when we test a patch for an old bug and use an old syz-fuzzer/execprog. |
| flags := flag.NewFlagSet("", flag.ContinueOnError) |
| flagName := flags.String("name", "", "unique name for manager") |
| flagArch := flags.String("arch", "", "target arch") |
| flagManager := flags.String("manager", "", "manager rpc address") |
| flagProcs := flags.Int("procs", 1, "number of parallel test processes") |
| flagLeak := flags.Bool("leak", false, "detect memory leaks") |
| flagOutput := flags.String("output", "stdout", "write programs to none/stdout/dmesg/file") |
| flagPprof := flags.String("pprof", "", "address to serve pprof profiles") |
| flagTest := flags.Bool("test", false, "enable image testing mode") // used by syz-ci |
| flagExecutor := flags.String("executor", "./syz-executor", "path to executor binary") |
| flagSignal := flags.Bool("cover", false, "collect feedback signals (coverage)") |
| flagSandbox := flags.String("sandbox", "none", "sandbox for fuzzing (none/setuid/namespace)") |
| flagDebug := flags.Bool("debug", false, "debug output from executor") |
| flagV := flags.Int("v", 0, "verbosity") |
| cmdLine := OldFuzzerCmd(os.Args[0], "/myexecutor", "myname", "linux", "386", "localhost:1234", |
| "namespace", 3, true, true) |
| args := strings.Split(cmdLine, " ")[1:] |
| if err := flags.Parse(args); err != nil { |
| t.Fatal(err) |
| } |
| if *flagName != "myname" { |
| t.Errorf("bad name: %q, want: %q", *flagName, "myname") |
| } |
| if *flagArch != "386" { |
| t.Errorf("bad arch: %q, want: %q", *flagArch, "386") |
| } |
| if *flagManager != "localhost:1234" { |
| t.Errorf("bad manager: %q, want: %q", *flagManager, "localhost:1234") |
| } |
| if *flagProcs != 3 { |
| t.Errorf("bad procs: %v, want: %v", *flagProcs, 3) |
| } |
| if *flagLeak { |
| t.Errorf("bad leak: %v, want: %v", *flagLeak, false) |
| } |
| if *flagOutput != "stdout" { |
| t.Errorf("bad output: %q, want: %q", *flagOutput, "stdout") |
| } |
| if *flagPprof != "" { |
| t.Errorf("bad pprof: %q, want: %q", *flagPprof, "") |
| } |
| if !*flagTest { |
| t.Errorf("bad test: %v, want: %v", *flagTest, true) |
| } |
| if *flagExecutor != "/myexecutor" { |
| t.Errorf("bad executor: %q, want: %q", *flagExecutor, "/myexecutor") |
| } |
| if *flagSandbox != "namespace" { |
| t.Errorf("bad sandbox: %q, want: %q", *flagSandbox, "namespace") |
| } |
| if !*flagSignal { |
| t.Errorf("bad signal: %v, want: %v", *flagSignal, true) |
| } |
| if *flagDebug { |
| t.Errorf("bad debug: %v, want: %v", *flagDebug, false) |
| } |
| if *flagV != 0 { |
| t.Errorf("bad verbosity: %v, want: %v", *flagV, 0) |
| } |
| } |
| |
| func TestExecprogCmd(t *testing.T) { |
| // IMPORTANT: if this test fails, do not fix it by changing flags here! |
| // See comment in TestFuzzerCmd. |
| flags := flag.NewFlagSet("", flag.ContinueOnError) |
| flagOS := flags.String("os", runtime.GOOS, "target os") |
| flagArch := flags.String("arch", "", "target arch") |
| flagRepeat := flags.Int("repeat", 1, "repeat execution that many times (0 for infinite loop)") |
| flagProcs := flags.Int("procs", 1, "number of parallel processes to execute programs") |
| flagFaultCall := flags.Int("fault_call", -1, "inject fault into this call (0-based)") |
| flagFaultNth := flags.Int("fault_nth", 0, "inject fault on n-th operation (0-based)") |
| flagExecutor := flags.String("executor", "./syz-executor", "path to executor binary") |
| flagThreaded := flags.Bool("threaded", true, "use threaded mode in executor") |
| flagCollide := flags.Bool("collide", true, "collide syscalls to provoke data races") |
| flagSignal := flags.Bool("cover", false, "collect feedback signals (coverage)") |
| flagSandbox := flags.String("sandbox", "none", "sandbox for fuzzing (none/setuid/namespace)") |
| cmdLine := ExecprogCmd(os.Args[0], "/myexecutor", "fuchsia", "386", "namespace", true, false, false, 7, 2, 3, "myprog") |
| args := strings.Split(cmdLine, " ")[1:] |
| if err := flags.Parse(args); err != nil { |
| t.Fatal(err) |
| } |
| if len(flags.Args()) != 1 || flags.Arg(0) != "myprog" { |
| t.Errorf("bad args: %q, want: %q", flags.Args(), "myprog") |
| } |
| if *flagOS != runtime.GOOS { |
| t.Errorf("bad os: %q, want: %q", *flagOS, runtime.GOOS) |
| } |
| if *flagArch != "386" { |
| t.Errorf("bad arch: %q, want: %q", *flagArch, "386") |
| } |
| if *flagRepeat != 0 { |
| t.Errorf("bad repeat: %v, want: %v", *flagRepeat, 0) |
| } |
| if *flagProcs != 7 { |
| t.Errorf("bad procs: %v, want: %v", *flagProcs, 7) |
| } |
| if *flagFaultCall != 2 { |
| t.Errorf("bad procs: %v, want: %v", *flagFaultCall, 2) |
| } |
| if *flagFaultNth != 3 { |
| t.Errorf("bad procs: %v, want: %v", *flagFaultNth, 3) |
| } |
| if *flagExecutor != "/myexecutor" { |
| t.Errorf("bad executor: %q, want: %q", *flagExecutor, "/myexecutor") |
| } |
| if *flagSandbox != "namespace" { |
| t.Errorf("bad sandbox: %q, want: %q", *flagSandbox, "namespace") |
| } |
| if *flagSignal { |
| t.Errorf("bad signal: %v, want: %v", *flagSignal, false) |
| } |
| if *flagThreaded { |
| t.Errorf("bad threaded: %v, want: %v", *flagThreaded, false) |
| } |
| if *flagCollide { |
| t.Errorf("bad collide: %v, want: %v", *flagCollide, false) |
| } |
| } |