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  }