github.com/neonyo/sys@v0.0.0-20230720094341-b1ee14be3ce8/execabs/execabs_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package execabs 6 7 import ( 8 "context" 9 "fmt" 10 "io/ioutil" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "runtime" 15 "strings" 16 "testing" 17 ) 18 19 // hasExec reports whether the current system can start new processes 20 // using os.StartProcess or (more commonly) exec.Command. 21 // Copied from internal/testenv.HasExec 22 func hasExec() bool { 23 switch runtime.GOOS { 24 case "wasip1", "js", "ios": 25 return false 26 } 27 return true 28 } 29 30 // mustHaveExec checks that the current system can start new processes 31 // using os.StartProcess or (more commonly) exec.Command. 32 // If not, mustHaveExec calls t.Skip with an explanation. 33 // Copied from internal/testenv.MustHaveExec 34 func mustHaveExec(t testing.TB) { 35 if !hasExec() { 36 t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH) 37 } 38 } 39 40 func TestFixCmd(t *testing.T) { 41 cmd := &exec.Cmd{Path: "hello"} 42 fixCmd("hello", cmd) 43 if cmd.Path != "" { 44 t.Errorf("fixCmd didn't clear cmd.Path") 45 } 46 expectedErr := fmt.Sprintf("hello resolves to executable in current directory (.%chello)", filepath.Separator) 47 if err := cmd.Run(); err == nil { 48 t.Fatal("Command.Run didn't fail") 49 } else if err.Error() != expectedErr { 50 t.Fatalf("Command.Run returned unexpected error: want %q, got %q", expectedErr, err.Error()) 51 } 52 } 53 54 func TestCommand(t *testing.T) { 55 mustHaveExec(t) 56 57 for _, cmd := range []func(string) *Cmd{ 58 func(s string) *Cmd { return Command(s) }, 59 func(s string) *Cmd { return CommandContext(context.Background(), s) }, 60 } { 61 tmpDir, err := ioutil.TempDir("", "execabs-test") 62 if err != nil { 63 t.Fatalf("ioutil.TempDir failed: %s", err) 64 } 65 defer os.RemoveAll(tmpDir) 66 executable := "execabs-test" 67 if runtime.GOOS == "windows" { 68 executable += ".exe" 69 } 70 if err = ioutil.WriteFile(filepath.Join(tmpDir, executable), []byte{1, 2, 3}, 0111); err != nil { 71 t.Fatalf("ioutil.WriteFile failed: %s", err) 72 } 73 cwd, err := os.Getwd() 74 if err != nil { 75 t.Fatalf("os.Getwd failed: %s", err) 76 } 77 defer os.Chdir(cwd) 78 if err = os.Chdir(tmpDir); err != nil { 79 t.Fatalf("os.Chdir failed: %s", err) 80 } 81 if runtime.GOOS != "windows" { 82 // add "." to PATH so that exec.LookPath looks in the current directory on 83 // non-windows platforms as well 84 origPath := os.Getenv("PATH") 85 defer os.Setenv("PATH", origPath) 86 os.Setenv("PATH", fmt.Sprintf(".:%s", origPath)) 87 } 88 expectedErr := fmt.Sprintf("execabs-test resolves to executable in current directory (.%c%s)", filepath.Separator, executable) 89 if err = cmd("execabs-test").Run(); err == nil { 90 t.Fatalf("Command.Run didn't fail when exec.LookPath returned a relative path") 91 } else if err.Error() != expectedErr && !isGo119ErrDot(err) { 92 t.Errorf("Command.Run returned unexpected error: want %q, got %q", expectedErr, err.Error()) 93 } 94 } 95 } 96 97 func TestLookPath(t *testing.T) { 98 mustHaveExec(t) 99 100 tmpDir, err := ioutil.TempDir("", "execabs-test") 101 if err != nil { 102 t.Fatalf("ioutil.TempDir failed: %s", err) 103 } 104 defer os.RemoveAll(tmpDir) 105 executable := "execabs-test" 106 if runtime.GOOS == "windows" { 107 executable += ".exe" 108 } 109 if err = ioutil.WriteFile(filepath.Join(tmpDir, executable), []byte{1, 2, 3}, 0111); err != nil { 110 t.Fatalf("ioutil.WriteFile failed: %s", err) 111 } 112 cwd, err := os.Getwd() 113 if err != nil { 114 t.Fatalf("os.Getwd failed: %s", err) 115 } 116 defer os.Chdir(cwd) 117 if err = os.Chdir(tmpDir); err != nil { 118 t.Fatalf("os.Chdir failed: %s", err) 119 } 120 if runtime.GOOS != "windows" { 121 // add "." to PATH so that exec.LookPath looks in the current directory on 122 // non-windows platforms as well 123 origPath := os.Getenv("PATH") 124 defer os.Setenv("PATH", origPath) 125 os.Setenv("PATH", fmt.Sprintf(".:%s", origPath)) 126 } 127 expectedErr := fmt.Sprintf("execabs-test resolves to executable in current directory (.%c%s)", filepath.Separator, executable) 128 if _, err := LookPath("execabs-test"); err == nil { 129 t.Fatalf("LookPath didn't fail when finding a non-relative path") 130 } else if err.Error() != expectedErr { 131 t.Errorf("LookPath returned unexpected error: want %q, got %q", expectedErr, err.Error()) 132 } 133 } 134 135 // Issue #58606 136 func TestDoesNotExist(t *testing.T) { 137 err := Command("this-executable-should-not-exist").Start() 138 if err == nil { 139 t.Fatal("command should have failed") 140 } 141 if strings.Contains(err.Error(), "resolves to executable in current directory") { 142 t.Errorf("error (%v) should not refer to current directory", err) 143 } 144 }