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