github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/test/integration/uninstall_int_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "runtime" 7 "testing" 8 "time" 9 10 "github.com/ActiveState/cli/internal/constants" 11 "github.com/ActiveState/cli/internal/fileutils" 12 "github.com/ActiveState/cli/internal/httputil" 13 "github.com/ActiveState/cli/internal/osutils/user" 14 "github.com/ActiveState/cli/internal/testhelpers/e2e" 15 "github.com/ActiveState/cli/internal/testhelpers/suite" 16 "github.com/ActiveState/cli/internal/testhelpers/tagsuite" 17 ) 18 19 type UninstallIntegrationTestSuite struct { 20 tagsuite.Suite 21 } 22 23 func (suite *UninstallIntegrationTestSuite) TestUninstall() { 24 suite.OnlyRunForTags(tagsuite.Uninstall, tagsuite.Critical) 25 suite.T().Run("Partial uninstall", func(t *testing.T) { suite.testUninstall(false) }) 26 suite.T().Run("Full uninstall", func(t *testing.T) { suite.testUninstall(true) }) 27 } 28 29 func (suite *UninstallIntegrationTestSuite) install(ts *e2e.Session) string { 30 // Determine URL of install script. 31 baseUrl := "https://state-tool.s3.amazonaws.com/update/state/" 32 scriptBaseName := "install." 33 if runtime.GOOS != "windows" { 34 scriptBaseName += "sh" 35 } else { 36 scriptBaseName += "ps1" 37 } 38 scriptUrl := baseUrl + constants.ChannelName + "/" + scriptBaseName 39 40 // Fetch it. 41 b, err := httputil.GetDirect(scriptUrl) 42 suite.Require().NoError(err) 43 script := filepath.Join(ts.Dirs.Work, scriptBaseName) 44 suite.Require().NoError(fileutils.WriteFile(script, b)) 45 46 // Make the directory to install to. 47 appInstallDir := filepath.Join(ts.Dirs.Work, "app") 48 suite.NoError(fileutils.Mkdir(appInstallDir)) 49 50 // Perform the installation. 51 cmd := "bash" 52 opts := []e2e.SpawnOptSetter{ 53 e2e.OptArgs(script, appInstallDir, "-n"), 54 e2e.OptAppendEnv(constants.DisableRuntime + "=false"), 55 e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), 56 e2e.OptAppendEnv(fmt.Sprintf("%s=FOO", constants.OverrideSessionTokenEnvVarName)), 57 } 58 if runtime.GOOS == "windows" { 59 cmd = "powershell.exe" 60 opts = append(opts, e2e.OptAppendEnv("SHELL=")) 61 } 62 cp := ts.SpawnCmdWithOpts(cmd, opts...) 63 cp.Expect("Installation Complete", e2e.RuntimeSourcingTimeoutOpt) 64 cp.SendLine("exit") 65 cp.ExpectExit() // exit code differs depending on shell; just assert the process exited 66 67 return appInstallDir 68 } 69 70 func (suite *UninstallIntegrationTestSuite) testUninstall(all bool) { 71 ts := e2e.New(suite.T(), true) 72 defer ts.Close() 73 74 appInstallDir := suite.install(ts) 75 binDir := filepath.Join(appInstallDir, "bin") 76 stateExe := filepath.Join(binDir, filepath.Base(ts.Exe)) 77 svcExe := filepath.Join(binDir, filepath.Base(ts.SvcExe)) 78 79 if runtime.GOOS == "linux" { 80 // When installed in a non-desktop environment (i.e. on a server), verify the user's ~/.profile was changed. 81 profile := filepath.Join(ts.Dirs.HomeDir, ".profile") 82 suite.Contains(string(fileutils.ReadFileUnsafe(profile)), svcExe, "autostart should be configured for Linux server environment") 83 } 84 85 cp := ts.SpawnCmdWithOpts(svcExe, e2e.OptArgs("start")) 86 cp.ExpectExitCode(0) 87 88 args := []string{"clean", "uninstall"} 89 if all { 90 args = append(args, "--all") 91 } 92 cp = ts.SpawnCmdWithOpts( 93 stateExe, 94 e2e.OptArgs(args...), 95 ) 96 cp.Expect("You are about to remove") 97 if !all { 98 cp.Expect("--all") // verify mention of "--all" to remove everything 99 } 100 cp.SendLine("y") 101 if runtime.GOOS == "windows" { 102 cp.Expect("Deletion of State Tool has been scheduled.") 103 } else { 104 cp.Expect("Successfully removed State Tool and related files") 105 } 106 cp.ExpectExitCode(0) 107 108 if runtime.GOOS == "windows" { 109 // Allow time for spawned script to remove directories 110 time.Sleep(2 * time.Second) 111 } 112 113 if all { 114 suite.NoDirExists(ts.Dirs.Cache, "Cache dir should not exist after full uninstall") 115 suite.NoDirExists(ts.Dirs.Config, "Config dir should not exist after full uninstall") 116 } else { 117 suite.DirExists(ts.Dirs.Cache, "Cache dir should still exist after partial uninstall") 118 suite.DirExists(ts.Dirs.Config, "Config dir should still exist after partial uninstall") 119 } 120 121 if fileutils.FileExists(stateExe) { 122 suite.Fail("State tool executable should not exist after uninstall") 123 } 124 125 if fileutils.FileExists(svcExe) { 126 suite.Fail("State service executable should not exist after uninstall") 127 } 128 129 if runtime.GOOS == "linux" { 130 // When installed in a non-desktop environment (i.e. on a server), verify the user's ~/.profile was reverted. 131 homeDir, err := user.HomeDir() 132 suite.Require().NoError(err) 133 profile := filepath.Join(homeDir, ".profile") 134 suite.NotContains(string(fileutils.ReadFileUnsafe(profile)), svcExe, "autostart should not be configured for Linux server environment anymore") 135 } 136 137 if runtime.GOOS == "darwin" { 138 if fileutils.DirExists(filepath.Join(binDir, "system")) { 139 suite.Fail("system directory should not exist after uninstall") 140 } 141 } 142 143 if fileutils.DirExists(binDir) { 144 suite.Fail("bin directory should not exist after uninstall") 145 } 146 } 147 148 func TestUninstallIntegrationTestSuite(t *testing.T) { 149 suite.Run(t, new(UninstallIntegrationTestSuite)) 150 }