github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/test/integration/exec_int_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "regexp" 8 "runtime" 9 "testing" 10 11 "github.com/ActiveState/cli/internal/testhelpers/suite" 12 13 "github.com/ActiveState/cli/internal/constants" 14 "github.com/ActiveState/cli/internal/fileutils" 15 "github.com/ActiveState/cli/internal/testhelpers/e2e" 16 "github.com/ActiveState/cli/internal/testhelpers/tagsuite" 17 ) 18 19 type ExecIntegrationTestSuite struct { 20 tagsuite.Suite 21 } 22 23 func (suite *ExecIntegrationTestSuite) createProjectFile(ts *e2e.Session) { 24 ts.PrepareProject("ActiveState-CLI/Python3", "fbc613d6-b0b1-4f84-b26e-4aa5869c4e54") 25 } 26 27 func (suite *ExecIntegrationTestSuite) TestExec_Environment() { 28 suite.OnlyRunForTags(tagsuite.Exec) 29 ts := e2e.New(suite.T(), false) 30 defer ts.Close() 31 32 suite.createProjectFile(ts) 33 34 scriptBlock := `echo ${PATH:0:500}` 35 filename := fmt.Sprintf("%s/%s.sh", ts.Dirs.Work, suite.T().Name()) 36 if runtime.GOOS == "windows" { 37 scriptBlock = `echo %PATH:~0,500%` 38 filename = fmt.Sprintf("%s/%s.bat", ts.Dirs.Work, suite.T().Name()) 39 } 40 41 testScript := filepath.Join(filename) 42 err := fileutils.WriteFile(testScript, []byte(scriptBlock)) 43 suite.Require().NoError(err) 44 45 err = os.Chmod(testScript, 0777) 46 suite.Require().NoError(err) 47 48 cp := ts.SpawnWithOpts( 49 e2e.OptArgs("exec", testScript), 50 ) 51 cp.ExpectExitCode(0) 52 output := cp.Output() 53 suite.Contains(output, ts.Dirs.Bin, "PATH was not updated to contain cache directory, original PATH:", os.Getenv("PATH")) 54 } 55 56 func (suite *ExecIntegrationTestSuite) TestExec_ExitCode() { 57 suite.OnlyRunForTags(tagsuite.Exec) 58 ts := e2e.New(suite.T(), false) 59 defer ts.Close() 60 61 suite.createProjectFile(ts) 62 63 scriptBlock := `exit 42` 64 filename := fmt.Sprintf("%s/%s.sh", ts.Dirs.Work, suite.T().Name()) 65 if runtime.GOOS == "windows" { 66 scriptBlock = `EXIT 42` 67 filename = fmt.Sprintf("%s/%s.bat", ts.Dirs.Work, suite.T().Name()) 68 } 69 70 testScript := filepath.Join(filename) 71 err := fileutils.WriteFile(testScript, []byte(scriptBlock)) 72 suite.Require().NoError(err) 73 74 err = os.Chmod(testScript, 0777) 75 suite.Require().NoError(err) 76 77 cp := ts.SpawnWithOpts( 78 e2e.OptArgs("exec", "--", testScript), 79 ) 80 cp.ExpectExitCode(42) 81 } 82 83 func (suite *ExecIntegrationTestSuite) TestExec_Args() { 84 suite.OnlyRunForTags(tagsuite.Exec) 85 ts := e2e.New(suite.T(), false) 86 defer ts.Close() 87 88 suite.createProjectFile(ts) 89 90 scriptBlock := ` 91 for i; do 92 echo $i 93 done 94 echo "Number of arguments: $#" 95 ` 96 97 filename := fmt.Sprintf("%s/%s.sh", ts.Dirs.Work, suite.T().Name()) 98 if runtime.GOOS == "windows" { 99 scriptBlock = ` 100 set argCount=0 101 for %%a in (%*) do ( 102 echo %%a 103 set /A argCount+=1 104 ) 105 echo Number of arguments: %argCount%` 106 filename = fmt.Sprintf("%s/%s.bat", ts.Dirs.Work, suite.T().Name()) 107 } 108 109 testScript := filepath.Join(filename) 110 err := fileutils.WriteFile(testScript, []byte(scriptBlock)) 111 suite.Require().NoError(err) 112 113 err = os.Chmod(testScript, 0777) 114 suite.Require().NoError(err) 115 116 args := []string{ 117 "firstArgument", 118 "secondArgument", 119 "thirdArgument", 120 } 121 122 cp := ts.SpawnWithOpts( 123 e2e.OptArgs("exec", "--", testScript, args[0], args[1], args[2]), 124 ) 125 cp.Expect(args[0]) 126 cp.Expect(args[1]) 127 cp.Expect(args[2]) 128 cp.Expect(fmt.Sprintf("Number of arguments: %d", len(args))) 129 cp.ExpectExitCode(0) 130 } 131 132 func (suite *ExecIntegrationTestSuite) TestExec_Input() { 133 suite.OnlyRunForTags(tagsuite.Exec) 134 ts := e2e.New(suite.T(), false) 135 defer ts.Close() 136 137 suite.createProjectFile(ts) 138 139 scriptBlock := ` 140 echo "Enter your name: " 141 read name 142 echo "Hello $name!" 143 ` 144 145 filename := fmt.Sprintf("%s/%s.sh", ts.Dirs.Work, suite.T().Name()) 146 if runtime.GOOS == "windows" { 147 scriptBlock = `set /P name="Enter your name: " 148 echo Hello %name%!` 149 filename = fmt.Sprintf("%s/%s.bat", ts.Dirs.Work, suite.T().Name()) 150 } 151 152 testScript := filepath.Join(filename) 153 err := fileutils.WriteFile(testScript, []byte(scriptBlock)) 154 suite.Require().NoError(err) 155 156 err = os.Chmod(testScript, 0777) 157 suite.Require().NoError(err) 158 159 cp := ts.SpawnWithOpts( 160 e2e.OptArgs("exec", "--", testScript), 161 ) 162 cp.SendLine("ActiveState") 163 cp.Expect("Hello ActiveState!") 164 cp.ExpectExitCode(0) 165 } 166 167 func (suite *ExecIntegrationTestSuite) TestExecWithPath() { 168 if runtime.GOOS == "windows" { 169 suite.T().Skip("Windows does not have `which` command") 170 } 171 suite.OnlyRunForTags(tagsuite.Exec) 172 173 ts := e2e.New(suite.T(), false) 174 defer ts.Close() 175 176 pythonDir := filepath.Join(ts.Dirs.Work, "MyPython3") 177 178 cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9", pythonDir)) 179 cp.Expect("Skipping runtime setup") 180 cp.Expect("Checked out project") 181 cp.ExpectExitCode(0) 182 183 cp = ts.SpawnWithOpts( 184 e2e.OptArgs("exec", "--path", pythonDir, "which", "python3"), 185 e2e.OptAppendEnv(constants.DisableRuntime+"=false"), 186 ) 187 cp.Expect("Operating on project ActiveState-CLI/Python-3.9", e2e.RuntimeSourcingTimeoutOpt) 188 cp.ExpectRe(regexp.MustCompile("cache/[0-9A-Fa-f]+/usr/bin/python3").String()) 189 cp.ExpectExitCode(0) 190 191 cp = ts.SpawnWithOpts( 192 e2e.OptArgs("exec", "echo", "python3", "--path", pythonDir, "--", "--path", "doesNotExist", "--", "extra"), 193 e2e.OptAppendEnv(constants.DisableRuntime+"=false"), 194 ) 195 cp.Expect("python3 --path doesNotExist -- extra") 196 cp.ExpectExitCode(0) 197 198 } 199 200 func (suite *ExecIntegrationTestSuite) TestExecPerlArgs() { 201 suite.OnlyRunForTags(tagsuite.Exec) 202 ts := e2e.New(suite.T(), false) 203 defer ts.Close() 204 205 cp := ts.Spawn("checkout", "ActiveState-CLI/Perl-5.32", ".") 206 cp.Expect("Skipping runtime setup") 207 cp.Expect("Checked out") 208 cp.ExpectExitCode(0) 209 210 suite.NoError(fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "testargs.pl"), []byte(` 211 printf "Argument: '%s'.\n", $ARGV[0]; 212 `))) 213 214 cp = ts.SpawnWithOpts( 215 e2e.OptArgs("exec", "perl", "testargs.pl", "<3"), 216 e2e.OptAppendEnv(constants.DisableRuntime+"=false"), 217 ) 218 cp.Expect("Argument: '<3'", e2e.RuntimeSourcingTimeoutOpt) 219 cp.ExpectExitCode(0) 220 } 221 222 func TestExecIntegrationTestSuite(t *testing.T) { 223 suite.Run(t, new(ExecIntegrationTestSuite)) 224 }