github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/test/integration/update_lock_int_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "regexp" 8 9 "github.com/ActiveState/cli/internal/config" 10 "github.com/ActiveState/cli/internal/constants" 11 "github.com/ActiveState/cli/internal/fileutils" 12 "github.com/ActiveState/cli/internal/rtutils/singlethread" 13 "github.com/ActiveState/cli/internal/testhelpers/e2e" 14 "github.com/ActiveState/cli/internal/testhelpers/tagsuite" 15 "github.com/ActiveState/cli/pkg/projectfile" 16 ) 17 18 func (suite *UpdateIntegrationTestSuite) TestLocked() { 19 suite.OnlyRunForTags(tagsuite.Update) 20 suite.T().Skip("Requires https://www.pivotaltracker.com/story/show/177827538 and needs to be adapted.") 21 pjfile := projectfile.Project{ 22 Project: lockedProjectURL(), 23 } 24 ts := e2e.New(suite.T(), false) 25 defer ts.Close() 26 27 cfg, err := config.NewCustom(ts.Dirs.Config, singlethread.New(), true) 28 suite.Require().NoError(err) 29 defer cfg.Close() 30 31 pjfile.SetPath(filepath.Join(ts.Dirs.Work, constants.ConfigFileName)) 32 err = pjfile.Save(cfg) 33 suite.Require().NoError(err) 34 35 cp := ts.SpawnWithOpts( 36 e2e.OptArgs("update", "lock"), 37 e2e.OptAppendEnv(suite.env(false, false)...), 38 ) 39 40 cp.Expect("Version locked at") 41 cp.ExpectExitCode(0) 42 43 suite.versionCompare(ts, constants.Version, suite.NotEqual) 44 } 45 46 func (suite *UpdateIntegrationTestSuite) TestLockedChannel() { 47 suite.OnlyRunForTags(tagsuite.Update) 48 targetBranch := "release" 49 if constants.ChannelName == "release" { 50 targetBranch = "master" 51 } 52 tests := []struct { 53 name string 54 lock string 55 expectLockError bool 56 expectedChannel string 57 }{ 58 { 59 "oldVersion", 60 oldUpdateVersion, 61 true, 62 "beta", 63 }, 64 { 65 "channel", 66 targetBranch, 67 true, 68 targetBranch, 69 }, 70 { 71 "locked-multi-file-version", 72 fmt.Sprintf("%s@0.29.0-SHA000000", targetBranch), 73 true, 74 targetBranch, 75 }, 76 } 77 78 for _, tt := range tests { 79 suite.Run(tt.name, func() { 80 pjfile := projectfile.Project{ 81 Project: lockedProjectURL(), 82 } 83 ts := e2e.New(suite.T(), false) 84 defer ts.Close() 85 86 cfg, err := config.NewCustom(ts.Dirs.Config, singlethread.New(), true) 87 suite.Require().NoError(err) 88 defer cfg.Close() 89 90 yamlPath := filepath.Join(ts.Dirs.Work, constants.ConfigFileName) 91 pjfile.SetPath(yamlPath) 92 err = pjfile.Save(cfg) 93 suite.Require().NoError(err) 94 95 cp := ts.SpawnWithOpts( 96 e2e.OptArgs("update", "lock", "--set-channel", tt.lock), 97 e2e.OptAppendEnv(suite.env(false, false)...), 98 ) 99 cp.Expect("Version locked at") 100 cp.Expect(tt.expectedChannel + "@") 101 cp.ExpectExitCode(0) 102 103 yamlContents, err := fileutils.ReadFile(yamlPath) 104 suite.Require().NoError(err) 105 suite.Contains(string(yamlContents), tt.lock) 106 107 if tt.expectLockError { 108 cp = ts.SpawnWithOpts(e2e.OptArgs("--version"), e2e.OptAppendEnv(suite.env(true, false)...)) 109 cp.Expect("This project is locked at State Tool version") 110 cp.ExpectExitCode(1) 111 ts.IgnoreLogErrors() 112 return 113 } 114 }) 115 } 116 } 117 118 func (suite *UpdateIntegrationTestSuite) TestUpdateLockedConfirmation() { 119 tests := []struct { 120 Name string 121 Confirm bool 122 Forced bool 123 }{ 124 {"Negative", false, false}, 125 {"Positive", true, false}, 126 {"Forced", true, true}, 127 } 128 129 for _, tt := range tests { 130 if tt.Forced || tt.Confirm { 131 suite.T().Skip("Requires https://www.pivotaltracker.com/story/show/177827538 and needs to be adapted.") 132 } 133 suite.Run(tt.Name, func() { 134 suite.OnlyRunForTags(tagsuite.Update) 135 pjfile := projectfile.Project{ 136 Project: lockedProjectURL(), 137 Lock: fmt.Sprintf("%s@%s", constants.ChannelName, constants.Version), 138 } 139 140 ts := e2e.New(suite.T(), false) 141 defer ts.Close() 142 143 cfg, err := config.NewCustom(ts.Dirs.Config, singlethread.New(), true) 144 suite.Require().NoError(err) 145 defer cfg.Close() 146 147 pjfile.SetPath(filepath.Join(ts.Dirs.Work, constants.ConfigFileName)) 148 err = pjfile.Save(cfg) 149 suite.Require().NoError(err) 150 151 args := []string{"update", "lock"} 152 if tt.Forced { 153 args = append(args, "--non-interactive") 154 } 155 cp := ts.SpawnWithOpts( 156 e2e.OptArgs(args...), 157 e2e.OptAppendEnv(suite.env(true, true)...), 158 ) 159 cp.Expect("sure you want") 160 if tt.Confirm || tt.Forced { 161 cp.SendLine("y") 162 cp.Expect("Version locked at") 163 } else { 164 cp.SendLine("n") 165 cp.Expect("Cancelling") 166 } 167 cp.ExpectNotExitCode(0) 168 ts.IgnoreLogErrors() 169 }) 170 } 171 } 172 173 func (suite *UpdateIntegrationTestSuite) TestLockUnlock() { 174 suite.OnlyRunForTags(tagsuite.Update) 175 176 pjfile := projectfile.Project{ 177 Project: lockedProjectURL(), 178 } 179 ts := e2e.New(suite.T(), false) 180 defer ts.Close() 181 182 cfg, err := config.New() 183 suite.Require().NoError(err) 184 defer cfg.Close() 185 186 pjfile.SetPath(filepath.Join(ts.Dirs.Work, constants.ConfigFileName)) 187 err = pjfile.Save(cfg) 188 suite.Require().NoError(err) 189 190 cp := ts.SpawnWithOpts( 191 e2e.OptArgs("update", "lock", "--non-interactive"), 192 e2e.OptAppendEnv(suite.env(false, false)...), 193 ) 194 cp.Expect("locked at") 195 196 data, err := os.ReadFile(pjfile.Path()) 197 suite.Require().NoError(err) 198 199 lockRegex := regexp.MustCompile(`(?m)^lock:.*`) 200 suite.Assert().True(lockRegex.Match(data), "lock info was not written to "+pjfile.Path()) 201 202 cp = ts.SpawnWithOpts( 203 e2e.OptArgs("update", "unlock", "-n"), 204 e2e.OptAppendEnv(suite.env(false, false)...), 205 ) 206 cp.Expect("unlocked") 207 208 data, err = os.ReadFile(pjfile.Path()) 209 suite.Require().NoError(err) 210 suite.Assert().False(lockRegex.Match(data), "lock info was not removed from "+pjfile.Path()) 211 // Ignore log errors here as the project we are using in this test does not 212 // actually exist. So there will be some errors related to fetching the 213 // project into. 214 ts.IgnoreLogErrors() 215 } 216 217 func (suite *UpdateIntegrationTestSuite) TestJSON() { 218 suite.OnlyRunForTags(tagsuite.Update, tagsuite.JSON) 219 ts := e2e.New(suite.T(), false) 220 defer ts.Close() 221 222 cp := ts.Spawn("checkout", "ActiveState-CLI/Python3", ".") 223 cp.Expect("Skipping runtime setup") 224 cp.Expect("Checked out") 225 cp.ExpectExitCode(0) 226 227 cp = ts.Spawn("update", "lock", "-o", "json") 228 cp.Expect(`"channel":`) 229 cp.Expect(`"version":`) 230 cp.ExpectExitCode(0) 231 AssertValidJSON(suite.T(), cp) 232 }