github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/test/integration/prepare_int_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "os/exec" 7 "path/filepath" 8 "runtime" 9 "testing" 10 11 "github.com/ActiveState/cli/internal/testhelpers/suite" 12 13 svcApp "github.com/ActiveState/cli/cmd/state-svc/app" 14 svcAutostart "github.com/ActiveState/cli/cmd/state-svc/autostart" 15 "github.com/ActiveState/cli/internal/config" 16 "github.com/ActiveState/cli/internal/constants" 17 "github.com/ActiveState/cli/internal/fileutils" 18 "github.com/ActiveState/cli/internal/osutils" 19 "github.com/ActiveState/cli/internal/osutils/autostart" 20 "github.com/ActiveState/cli/internal/osutils/user" 21 "github.com/ActiveState/cli/internal/rtutils/singlethread" 22 "github.com/ActiveState/cli/internal/subshell" 23 "github.com/ActiveState/cli/internal/testhelpers/e2e" 24 "github.com/ActiveState/cli/internal/testhelpers/tagsuite" 25 "github.com/ActiveState/cli/pkg/platform/runtime/setup" 26 rt "github.com/ActiveState/cli/pkg/platform/runtime/target" 27 ) 28 29 type PrepareIntegrationTestSuite struct { 30 tagsuite.Suite 31 } 32 33 func (suite *PrepareIntegrationTestSuite) TestPrepare() { 34 // Disable test for v0.36: https://activestatef.atlassian.net/browse/DX-1501. 35 // This test should be re-enabled by https://activestatef.atlassian.net/browse/DX-1435. 36 suite.T().SkipNow() 37 38 suite.OnlyRunForTags(tagsuite.Prepare) 39 if !e2e.RunningOnCI() { 40 suite.T().Skipf("Skipping TestPrepare when not running on CI or on MacOS, as it modifies PATH") 41 } 42 43 ts := e2e.New(suite.T(), false) 44 defer ts.Close() 45 46 autostartDir := filepath.Join(ts.Dirs.Work, "autostart") 47 err := fileutils.Mkdir(autostartDir) 48 suite.Require().NoError(err) 49 50 cp := ts.SpawnWithOpts( 51 e2e.OptArgs("_prepare"), 52 e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.AutostartPathOverrideEnvVarName, autostartDir)), 53 // e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.ConfigEnvVarName, ts.Dirs.Work)), 54 ) 55 cp.ExpectExitCode(0) 56 57 isAdmin, err := osutils.IsAdmin() 58 suite.Require().NoError(err, "Could not determine if we are a Windows Administrator") 59 // For Windows Administrator users `state _prepare` is doing nothing now (because it doesn't make sense...) 60 if isAdmin { 61 return 62 } 63 suite.AssertConfig(filepath.Join(ts.Dirs.Cache, "bin")) 64 65 // Verify autostart was enabled. 66 app, err := svcApp.New() 67 suite.Require().NoError(err) 68 enabled, err := autostart.IsEnabled(app.Path(), svcAutostart.Options) 69 suite.Require().NoError(err) 70 suite.Assert().True(enabled, "autostart is not enabled") 71 72 // When installed in a non-desktop environment (i.e. on a server), verify the user's ~/.profile was amended. 73 if runtime.GOOS == "linux" { 74 homeDir, err := user.HomeDir() 75 suite.Require().NoError(err) 76 profile := filepath.Join(homeDir, ".profile") 77 profileContents := string(fileutils.ReadFileUnsafe(profile)) 78 suite.Contains(profileContents, app.Path(), "autostart should be configured for Linux server environment") 79 } 80 81 // Verify autostart can be disabled. 82 err = autostart.Disable(app.Path(), svcAutostart.Options) 83 suite.Require().NoError(err) 84 enabled, err = autostart.IsEnabled(app.Path(), svcAutostart.Options) 85 suite.Require().NoError(err) 86 suite.Assert().False(enabled, "autostart is still enabled") 87 88 // When installed in a non-desktop environment (i.e. on a server), verify the user's ~/.profile was reverted. 89 if runtime.GOOS == "linux" { 90 homeDir, err := user.HomeDir() 91 suite.Require().NoError(err) 92 profile := filepath.Join(homeDir, ".profile") 93 profileContents := fileutils.ReadFileUnsafe(profile) 94 suite.NotContains(profileContents, app.Exec, "autostart should not be configured for Linux server environment anymore") 95 } 96 } 97 98 func (suite *PrepareIntegrationTestSuite) AssertConfig(target string) { 99 if runtime.GOOS != "windows" { 100 // Test config file 101 cfg, err := config.New() 102 suite.Require().NoError(err) 103 104 subshell := subshell.New(cfg) 105 rcFile, err := subshell.RcFile() 106 suite.Require().NoError(err) 107 108 bashContents := fileutils.ReadFileUnsafe(rcFile) 109 suite.Contains(string(bashContents), constants.RCAppendDefaultStartLine, "config file should contain our RC Append Start line") 110 suite.Contains(string(bashContents), constants.RCAppendDefaultStopLine, "config file should contain our RC Append Stop line") 111 suite.Contains(string(bashContents), target, "config file should contain our target dir") 112 } else { 113 // Test registry 114 out, err := exec.Command("reg", "query", `HKCU\Environment`, "/v", "Path").Output() 115 suite.Require().NoError(err) 116 suite.Contains(string(out), target, "Windows system PATH should contain our target dir") 117 } 118 } 119 120 func (suite *PrepareIntegrationTestSuite) TestResetExecutors() { 121 suite.OnlyRunForTags(tagsuite.Prepare) 122 ts := e2e.New(suite.T(), true, constants.DisableRuntime+"=false") 123 err := ts.ClearCache() 124 suite.Require().NoError(err) 125 defer ts.Close() 126 127 cp := ts.SpawnWithOpts( 128 e2e.OptArgs("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work, "--default"), 129 ) 130 cp.Expect("This project will always be available for use") 131 cp.Expect("Downloading") 132 cp.Expect("Installing") 133 cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) 134 135 cp.SendLine("exit") 136 cp.ExpectExitCode(0) 137 138 cfg, err := config.NewCustom(ts.Dirs.Config, singlethread.New(), true) 139 suite.Require().NoError(err) 140 suite.Require().Equal(ts.Dirs.Work, cfg.GetString(constants.GlobalDefaultPrefname)) 141 suite.Require().NoError(cfg.Close()) 142 143 // Remove global executors 144 globalExecDir := filepath.Join(ts.Dirs.Cache, "bin") 145 err = os.RemoveAll(globalExecDir) 146 suite.Assert().NoError(err, "should have removed executor directory, to ensure that it gets re-created") 147 148 // check existens of exec dir 149 targetDir := rt.ProjectDirToTargetDir(ts.Dirs.Work, ts.Dirs.Cache) 150 projectExecDir := setup.ExecDir(targetDir) 151 suite.DirExists(projectExecDir) 152 153 // remove complete marker to force re-creation of executors 154 err = os.Remove(filepath.Join(targetDir, constants.LocalRuntimeEnvironmentDirectory, constants.RuntimeInstallationCompleteMarker)) 155 suite.Assert().NoError(err, "removal of complete marker should have worked") 156 157 cp = ts.Spawn("_prepare") 158 cp.ExpectExitCode(0) 159 160 suite.FileExists(filepath.Join(globalExecDir, "python3"+osutils.ExeExtension)) 161 err = os.RemoveAll(projectExecDir) 162 suite.Assert().NoError(err, "should have removed executor directory, to ensure that it gets re-created") 163 164 cp = ts.Spawn("activate") 165 cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) 166 cp.SendLine("which python3") 167 cp.SendLine("python3 --version") 168 cp.Expect("ActiveState") 169 cp.SendLine("exit") 170 cp.ExpectExitCode(0) 171 172 // executor dir should be re-created 173 suite.DirExists(projectExecDir) 174 } 175 176 func TestPrepareIntegrationTestSuite(t *testing.T) { 177 suite.Run(t, new(PrepareIntegrationTestSuite)) 178 }