external_cmd_unix_internal_test.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. //go:build !windows && !plan9 && !js
  2. package eval
  3. import (
  4. "os"
  5. "reflect"
  6. "syscall"
  7. "testing"
  8. "src.elv.sh/pkg/env"
  9. "src.elv.sh/pkg/parse"
  10. . "src.elv.sh/pkg/testutil"
  11. )
  12. func TestExec_Argv0Argv(t *testing.T) {
  13. dir := InTempDir(t)
  14. ApplyDir(Dir{
  15. "bin": Dir{
  16. "elvish": File{Perm: 0755},
  17. "cat": File{Perm: 0755},
  18. },
  19. })
  20. Setenv(t, "PATH", dir+"/bin")
  21. Setenv(t, env.SHLVL, "1")
  22. var tests = []struct {
  23. name string
  24. code string
  25. wantArgv0 string
  26. wantArgv []string
  27. wantError bool
  28. }{
  29. {
  30. name: "absolute path command",
  31. code: "exec /bin/sh foo bar",
  32. wantArgv0: "/bin/sh",
  33. wantArgv: []string{"/bin/sh", "foo", "bar"},
  34. },
  35. {
  36. name: "relative path command",
  37. code: "exec cat foo bar",
  38. wantArgv0: dir + "/bin/cat",
  39. wantArgv: []string{dir + "/bin/cat", "foo", "bar"},
  40. },
  41. {
  42. name: "no command",
  43. code: "exec",
  44. wantArgv0: dir + "/bin/elvish",
  45. wantArgv: []string{dir + "/bin/elvish"},
  46. },
  47. {
  48. name: "bad command",
  49. code: "exec bad",
  50. wantError: true,
  51. },
  52. }
  53. for _, test := range tests {
  54. t.Run(test.name, func(t *testing.T) {
  55. t.Helper()
  56. var (
  57. gotArgv0 string
  58. gotArgv []string
  59. )
  60. syscallExec = func(argv0 string, argv []string, envv []string) error {
  61. gotArgv0 = argv0
  62. gotArgv = argv
  63. return nil
  64. }
  65. defer func() { syscallExec = syscall.Exec }()
  66. ev := NewEvaler()
  67. err := ev.Eval(parse.Source{Name: "[test]", Code: test.code}, EvalCfg{})
  68. if gotArgv0 != test.wantArgv0 {
  69. t.Errorf("got argv0 %q, want %q", gotArgv0, test.wantArgv0)
  70. }
  71. if !reflect.DeepEqual(gotArgv, test.wantArgv) {
  72. t.Errorf("got argv %q, want %q", gotArgv, test.wantArgv)
  73. }
  74. hasError := err != nil
  75. if hasError != test.wantError {
  76. t.Errorf("has error %v, want %v", hasError, test.wantError)
  77. }
  78. })
  79. }
  80. }
  81. func TestDecSHLVL(t *testing.T) {
  82. // Valid integers are decremented, regardless of sign
  83. testDecSHLVL(t, "-2", "-3")
  84. testDecSHLVL(t, "-1", "-2")
  85. testDecSHLVL(t, "0", "-1")
  86. testDecSHLVL(t, "1", "0")
  87. testDecSHLVL(t, "2", "1")
  88. testDecSHLVL(t, "3", "2")
  89. // Non-integers are kept unchanged
  90. testDecSHLVL(t, "", "")
  91. testDecSHLVL(t, "x", "x")
  92. }
  93. func testDecSHLVL(t *testing.T, oldValue, newValue string) {
  94. t.Helper()
  95. Setenv(t, env.SHLVL, oldValue)
  96. decSHLVL()
  97. if gotValue := os.Getenv(env.SHLVL); gotValue != newValue {
  98. t.Errorf("got new value %q, want %q", gotValue, newValue)
  99. }
  100. }