github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/upgrader/upgrader_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package upgrader_test 5 6 import ( 7 "fmt" 8 "os" 9 "path/filepath" 10 stdtesting "testing" 11 "time" 12 13 "github.com/juju/clock/testclock" 14 "github.com/juju/errors" 15 "github.com/juju/loggo" 16 "github.com/juju/names/v5" 17 "github.com/juju/testing" 18 jc "github.com/juju/testing/checkers" 19 "github.com/juju/utils/v3" 20 "github.com/juju/utils/v3/symlink" 21 "github.com/juju/version/v2" 22 "github.com/juju/worker/v3" 23 "github.com/juju/worker/v3/workertest" 24 gc "gopkg.in/check.v1" 25 26 "github.com/juju/juju/agent" 27 agenttools "github.com/juju/juju/agent/tools" 28 "github.com/juju/juju/api" 29 upgraderapi "github.com/juju/juju/api/agent/upgrader" 30 agenterrors "github.com/juju/juju/cmd/jujud/agent/errors" 31 "github.com/juju/juju/core/arch" 32 coreos "github.com/juju/juju/core/os" 33 "github.com/juju/juju/core/os/ostype" 34 "github.com/juju/juju/environs/simplestreams" 35 sstesting "github.com/juju/juju/environs/simplestreams/testing" 36 envtesting "github.com/juju/juju/environs/testing" 37 envtools "github.com/juju/juju/environs/tools" 38 jujutesting "github.com/juju/juju/juju/testing" 39 "github.com/juju/juju/state" 40 statetesting "github.com/juju/juju/state/testing" 41 coretesting "github.com/juju/juju/testing" 42 coretools "github.com/juju/juju/tools" 43 "github.com/juju/juju/upgrades" 44 jujuversion "github.com/juju/juju/version" 45 "github.com/juju/juju/worker/gate" 46 "github.com/juju/juju/worker/upgrader" 47 ) 48 49 func TestPackage(t *stdtesting.T) { 50 coretesting.MgoTestPackage(t) 51 } 52 53 type UpgraderSuite struct { 54 jujutesting.JujuConnSuite 55 56 machine *state.Machine 57 state api.Connection 58 confVersion version.Number 59 upgradeStepsComplete gate.Lock 60 initialCheckComplete gate.Lock 61 clock *testclock.Clock 62 } 63 64 type AllowedTargetVersionSuite struct{} 65 66 var _ = gc.Suite(&UpgraderSuite{}) 67 var _ = gc.Suite(&AllowedTargetVersionSuite{}) 68 69 func (s *UpgraderSuite) SetUpTest(c *gc.C) { 70 s.JujuConnSuite.SetUpTest(c) 71 // s.machine needs to have IsManager() so that it can get the actual 72 // current revision to upgrade to. 73 s.state, s.machine = s.OpenAPIAsNewMachine(c, state.JobManageModel) 74 75 // For expediency we assume that upgrade-steps have run as the default. 76 // Create a new locked gate for alternative test composition. 77 s.upgradeStepsComplete = gate.NewLock() 78 s.upgradeStepsComplete.Unlock() 79 80 s.initialCheckComplete = gate.NewLock() 81 s.clock = testclock.NewClock(time.Now()) 82 } 83 84 func (s *UpgraderSuite) patchVersion(v version.Binary) { 85 s.PatchValue(&arch.HostArch, func() string { return v.Arch }) 86 s.PatchValue(&coreos.HostOS, func() ostype.OSType { return ostype.Ubuntu }) 87 vers := v.Number 88 vers.Build = 666 89 s.PatchValue(&jujuversion.Current, vers) 90 } 91 92 type mockConfig struct { 93 agent.Config 94 tag names.Tag 95 datadir string 96 } 97 98 func (mock *mockConfig) Tag() names.Tag { 99 return mock.tag 100 } 101 102 func (mock *mockConfig) DataDir() string { 103 return mock.datadir 104 } 105 106 func agentConfig(tag names.Tag, datadir string) agent.Config { 107 return &mockConfig{ 108 tag: tag, 109 datadir: datadir, 110 } 111 } 112 113 func (s *UpgraderSuite) makeUpgrader(c *gc.C) *upgrader.Upgrader { 114 w, err := upgrader.NewAgentUpgrader(upgrader.Config{ 115 Clock: s.clock, 116 Logger: loggo.GetLogger("test"), 117 State: upgraderapi.NewState(s.state), 118 AgentConfig: agentConfig(s.machine.Tag(), s.DataDir()), 119 OrigAgentVersion: s.confVersion, 120 UpgradeStepsWaiter: s.upgradeStepsComplete, 121 InitialUpgradeCheckComplete: s.initialCheckComplete, 122 CheckDiskSpace: func(string, uint64) error { return nil }, 123 }) 124 c.Assert(err, jc.ErrorIsNil) 125 return w 126 } 127 128 func (s *UpgraderSuite) TestUpgraderSetsTools(c *gc.C) { 129 vers := version.MustParseBinary("5.4.3-ubuntu-amd64") 130 err := statetesting.SetAgentVersion(s.State, vers.Number) 131 c.Assert(err, jc.ErrorIsNil) 132 133 store := s.DefaultToolsStorage 134 agentTools := envtesting.PrimeTools(c, store, s.DataDir(), s.Environ.Config().AgentStream(), vers) 135 s.patchVersion(agentTools.Version) 136 137 ss := simplestreams.NewSimpleStreams(sstesting.TestDataSourceFactory()) 138 err = envtools.MergeAndWriteMetadata( 139 ss, store, "released", "released", coretools.List{agentTools}, envtools.DoNotWriteMirrors) 140 c.Assert(err, jc.ErrorIsNil) 141 142 _, err = s.machine.AgentTools() 143 c.Assert(err, jc.Satisfies, errors.IsNotFound) 144 145 u := s.makeUpgrader(c) 146 s.waitForUpgradeCheck(c) 147 workertest.CleanKill(c, u) 148 149 err = s.machine.Refresh() 150 c.Assert(err, jc.ErrorIsNil) 151 152 gotTools, err := s.machine.AgentTools() 153 154 c.Assert(err, jc.ErrorIsNil) 155 agentTools.Version.Build = 666 156 envtesting.CheckTools(c, gotTools, agentTools) 157 } 158 159 func (s *UpgraderSuite) TestUpgraderSetVersion(c *gc.C) { 160 vers := version.MustParseBinary("5.4.3-ubuntu-amd64") 161 agentTools := envtesting.PrimeTools(c, s.DefaultToolsStorage, s.DataDir(), s.Environ.Config().AgentStream(), vers) 162 s.patchVersion(agentTools.Version) 163 err := os.RemoveAll(filepath.Join(s.DataDir(), "tools")) 164 c.Assert(err, jc.ErrorIsNil) 165 166 _, err = s.machine.AgentTools() 167 c.Assert(err, jc.Satisfies, errors.IsNotFound) 168 err = statetesting.SetAgentVersion(s.State, vers.Number) 169 c.Assert(err, jc.ErrorIsNil) 170 171 u := s.makeUpgrader(c) 172 s.waitForUpgradeCheck(c) 173 workertest.CleanKill(c, u) 174 175 err = s.machine.Refresh() 176 c.Assert(err, jc.ErrorIsNil) 177 gotTools, err := s.machine.AgentTools() 178 c.Assert(err, jc.ErrorIsNil) 179 vers.Build = 666 180 c.Assert(gotTools, gc.DeepEquals, &coretools.Tools{Version: vers}) 181 } 182 183 func (s *UpgraderSuite) TestUpgraderWaitsForUpgradeStepsGate(c *gc.C) { 184 // Replace with a locked gate. 185 s.upgradeStepsComplete = gate.NewLock() 186 187 stor := s.DefaultToolsStorage 188 189 oldTools := envtesting.PrimeTools( 190 c, stor, s.DataDir(), s.Environ.Config().AgentStream(), version.MustParseBinary("5.4.3-ubuntu-amd64")) 191 s.patchVersion(oldTools.Version) 192 193 newTools := envtesting.AssertUploadFakeToolsVersions( 194 c, stor, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), 195 version.MustParseBinary("5.4.5-ubuntu-amd64"))[0] 196 err := statetesting.SetAgentVersion(s.State, newTools.Version.Number) 197 c.Assert(err, jc.ErrorIsNil) 198 199 u := s.makeUpgrader(c) 200 workertest.CheckAlive(c, u) 201 202 s.expectInitialUpgradeCheckNotDone(c) 203 204 // No upgrade-ready error. 205 workertest.CleanKill(c, u) 206 } 207 208 func (s *UpgraderSuite) TestUpgraderUpgradesImmediately(c *gc.C) { 209 stor := s.DefaultToolsStorage 210 211 oldTools := envtesting.PrimeTools( 212 c, stor, s.DataDir(), s.Environ.Config().AgentStream(), version.MustParseBinary("5.4.3-ubuntu-amd64")) 213 s.patchVersion(oldTools.Version) 214 215 newTools := envtesting.AssertUploadFakeToolsVersions( 216 c, stor, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), 217 version.MustParseBinary("5.4.5-ubuntu-amd64"))[0] 218 err := statetesting.SetAgentVersion(s.State, newTools.Version.Number) 219 c.Assert(err, jc.ErrorIsNil) 220 221 u := s.makeUpgrader(c) 222 err = workertest.CheckKilled(c, u) 223 s.expectInitialUpgradeCheckNotDone(c) 224 225 envtesting.CheckUpgraderReadyError(c, err, &agenterrors.UpgradeReadyError{ 226 AgentName: s.machine.Tag().String(), 227 OldTools: oldTools.Version, 228 NewTools: newTools.Version, 229 DataDir: s.DataDir(), 230 }) 231 foundTools, err := agenttools.ReadTools(s.DataDir(), newTools.Version) 232 c.Assert(err, jc.ErrorIsNil) 233 newTools.URL = fmt.Sprintf("https://%s/model/%s/tools/5.4.5-ubuntu-amd64", 234 s.APIState.Addr(), coretesting.ModelTag.Id()) 235 envtesting.CheckTools(c, foundTools, newTools) 236 } 237 238 func (s *UpgraderSuite) TestUpgraderRetryAndChanged(c *gc.C) { 239 stor := s.DefaultToolsStorage 240 241 oldTools := envtesting.PrimeTools( 242 c, stor, s.DataDir(), s.Environ.Config().AgentStream(), version.MustParseBinary("5.4.3-ubuntu-amd64")) 243 s.patchVersion(oldTools.Version) 244 245 newTools := envtesting.AssertUploadFakeToolsVersions( 246 c, stor, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), 247 version.MustParseBinary("5.4.5-ubuntu-amd64"))[0] 248 err := statetesting.SetAgentVersion(s.State, newTools.Version.Number) 249 c.Assert(err, jc.ErrorIsNil) 250 251 err = stor.Remove(envtools.StorageName(newTools.Version, "released")) 252 c.Assert(err, jc.ErrorIsNil) 253 254 u := s.makeUpgrader(c) 255 defer func() { _ = workertest.CheckKilled(c, u) }() 256 s.expectInitialUpgradeCheckNotDone(c) 257 258 for i := 0; i < 3; i++ { 259 err := s.clock.WaitAdvance(5*time.Second, coretesting.LongWait, 1) 260 c.Assert(err, jc.ErrorIsNil) 261 } 262 263 // Make it upgrade to some newer tools that can be 264 // downloaded ok; it should stop retrying, download 265 // the newer tools and exit. 266 newerTools := envtesting.AssertUploadFakeToolsVersions( 267 c, stor, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), 268 version.MustParseBinary("5.4.6-ubuntu-amd64"))[0] 269 270 err = statetesting.SetAgentVersion(s.State, newerTools.Version.Number) 271 c.Assert(err, jc.ErrorIsNil) 272 273 done := make(chan error) 274 go func() { 275 done <- u.Wait() 276 }() 277 select { 278 case err := <-done: 279 envtesting.CheckUpgraderReadyError(c, err, &agenterrors.UpgradeReadyError{ 280 AgentName: s.machine.Tag().String(), 281 OldTools: oldTools.Version, 282 NewTools: newerTools.Version, 283 DataDir: s.DataDir(), 284 }) 285 case <-time.After(coretesting.LongWait): 286 c.Fatalf("upgrader did not quit after upgrading") 287 } 288 } 289 290 func (s *UpgraderSuite) TestChangeAgentTools(c *gc.C) { 291 oldTools := &coretools.Tools{Version: version.MustParseBinary("1.2.3-ubuntu-amd64")} 292 293 store := s.DefaultToolsStorage 294 newToolsBinary := "5.4.3-ubuntu-amd64" 295 newTools := envtesting.PrimeTools( 296 c, store, s.DataDir(), s.Environ.Config().AgentStream(), version.MustParseBinary(newToolsBinary)) 297 s.patchVersion(newTools.Version) 298 299 ss := simplestreams.NewSimpleStreams(sstesting.TestDataSourceFactory()) 300 err := envtools.MergeAndWriteMetadata( 301 ss, store, "released", "released", coretools.List{newTools}, envtools.DoNotWriteMirrors) 302 c.Assert(err, jc.ErrorIsNil) 303 304 ugErr := &agenterrors.UpgradeReadyError{ 305 AgentName: "anAgent", 306 OldTools: oldTools.Version, 307 NewTools: newTools.Version, 308 DataDir: s.DataDir(), 309 } 310 err = ugErr.ChangeAgentTools(loggo.GetLogger("test")) 311 c.Assert(err, jc.ErrorIsNil) 312 313 target := agenttools.ToolsDir(s.DataDir(), newToolsBinary) 314 link, err := symlink.Read(agenttools.ToolsDir(s.DataDir(), "anAgent")) 315 c.Assert(err, jc.ErrorIsNil) 316 c.Assert(link, jc.SamePath, target) 317 } 318 319 func (s *UpgraderSuite) TestUsesAlreadyDownloadedToolsIfAvailable(c *gc.C) { 320 oldVersion := version.MustParseBinary("1.2.3-ubuntu-amd64") 321 s.patchVersion(oldVersion) 322 323 newVersion := version.MustParseBinary("5.4.3-ubuntu-amd64") 324 err := statetesting.SetAgentVersion(s.State, newVersion.Number) 325 c.Assert(err, jc.ErrorIsNil) 326 327 // Install tools matching the new version in the data directory 328 // but *not* in environment storage. The upgrader should find the 329 // downloaded tools without looking in environment storage. 330 envtesting.InstallFakeDownloadedTools(c, s.DataDir(), newVersion) 331 332 u := s.makeUpgrader(c) 333 err = workertest.CheckKilled(c, u) 334 s.expectInitialUpgradeCheckNotDone(c) 335 336 envtesting.CheckUpgraderReadyError(c, err, &agenterrors.UpgradeReadyError{ 337 AgentName: s.machine.Tag().String(), 338 OldTools: oldVersion, 339 NewTools: newVersion, 340 DataDir: s.DataDir(), 341 }) 342 } 343 344 func (s *UpgraderSuite) TestUpgraderAllowsDowngradingMinorVersions(c *gc.C) { 345 // We allow this scenario to allow reverting upgrades by restoring 346 // a backup from the previous version. 347 stor := s.DefaultToolsStorage 348 origTools := envtesting.PrimeTools( 349 c, stor, s.DataDir(), s.Environ.Config().AgentStream(), version.MustParseBinary("5.4.3-ubuntu-amd64")) 350 s.patchVersion(origTools.Version) 351 352 downgradeTools := envtesting.AssertUploadFakeToolsVersions( 353 c, stor, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), 354 version.MustParseBinary("5.3.3-ubuntu-amd64"))[0] 355 err := statetesting.SetAgentVersion(s.State, downgradeTools.Version.Number) 356 c.Assert(err, jc.ErrorIsNil) 357 358 u := s.makeUpgrader(c) 359 err = workertest.CheckKilled(c, u) 360 s.expectInitialUpgradeCheckNotDone(c) 361 362 envtesting.CheckUpgraderReadyError(c, err, &agenterrors.UpgradeReadyError{ 363 AgentName: s.machine.Tag().String(), 364 OldTools: origTools.Version, 365 NewTools: downgradeTools.Version, 366 DataDir: s.DataDir(), 367 }) 368 foundTools, err := agenttools.ReadTools(s.DataDir(), downgradeTools.Version) 369 c.Assert(err, jc.ErrorIsNil) 370 downgradeTools.URL = fmt.Sprintf("https://%s/model/%s/tools/5.3.3-ubuntu-amd64", 371 s.APIState.Addr(), coretesting.ModelTag.Id()) 372 envtesting.CheckTools(c, foundTools, downgradeTools) 373 } 374 375 func (s *UpgraderSuite) TestUpgraderForbidsDowngradingToMajorVersion(c *gc.C) { 376 stor := s.DefaultToolsStorage 377 origTools := envtesting.PrimeTools(c, stor, s.DataDir(), s.Environ.Config().AgentStream(), 378 version.MustParseBinary("2.4.3-ubuntu-amd64")) 379 s.patchVersion(origTools.Version) 380 381 downgradeTools := envtesting.AssertUploadFakeToolsVersions( 382 c, stor, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), 383 version.MustParseBinary("1.25.3-ubuntu-amd64"))[0] 384 err := statetesting.SetAgentVersion(s.State, downgradeTools.Version.Number) 385 c.Assert(err, jc.ErrorIsNil) 386 387 u := s.makeUpgrader(c) 388 s.waitForUpgradeCheck(c) 389 err = worker.Stop(u) 390 391 // If the upgrade had been allowed we would get an UpgradeReadyError. 392 c.Assert(err, jc.ErrorIsNil) 393 _, err = agenttools.ReadTools(s.DataDir(), downgradeTools.Version) 394 // TODO: ReadTools *should* be returning some form of 395 // errors.NotFound, however, it just passes back a fmt.Errorf so 396 // we live with it c.Assert(err, jc.Satisfies, errors.IsNotFound) 397 c.Check(err, gc.ErrorMatches, "cannot read agent metadata in directory.*"+utils.NoSuchFileErrRegexp) 398 } 399 400 func (s *UpgraderSuite) TestUpgraderAllowsDowngradingPatchVersions(c *gc.C) { 401 stor := s.DefaultToolsStorage 402 origTools := envtesting.PrimeTools(c, stor, s.DataDir(), s.Environ.Config().AgentStream(), 403 version.MustParseBinary("5.4.3-ubuntu-amd64")) 404 s.patchVersion(origTools.Version) 405 406 downgradeTools := envtesting.AssertUploadFakeToolsVersions( 407 c, stor, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), 408 version.MustParseBinary("5.4.2-ubuntu-amd64"))[0] 409 err := statetesting.SetAgentVersion(s.State, downgradeTools.Version.Number) 410 c.Assert(err, jc.ErrorIsNil) 411 412 u := s.makeUpgrader(c) 413 err = workertest.CheckKilled(c, u) 414 s.expectInitialUpgradeCheckNotDone(c) 415 416 envtesting.CheckUpgraderReadyError(c, err, &agenterrors.UpgradeReadyError{ 417 AgentName: s.machine.Tag().String(), 418 OldTools: origTools.Version, 419 NewTools: downgradeTools.Version, 420 DataDir: s.DataDir(), 421 }) 422 foundTools, err := agenttools.ReadTools(s.DataDir(), downgradeTools.Version) 423 c.Assert(err, jc.ErrorIsNil) 424 downgradeTools.URL = fmt.Sprintf("https://%s/model/%s/tools/5.4.2-ubuntu-amd64", 425 s.APIState.Addr(), coretesting.ModelTag.Id()) 426 envtesting.CheckTools(c, foundTools, downgradeTools) 427 } 428 429 func (s *UpgraderSuite) TestUpgraderAllowsDowngradeToPriorMinorVersion(c *gc.C) { 430 // We now allow this to support restoring 431 // a backup from a previous version. 432 downgradeVersion := version.MustParseBinary("5.3.0-ubuntu-amd64") 433 s.confVersion = downgradeVersion.Number 434 435 stor := s.DefaultToolsStorage 436 origTools := envtesting.PrimeTools(c, stor, s.DataDir(), s.Environ.Config().AgentStream(), 437 version.MustParseBinary("5.4.3-ubuntu-amd64")) 438 s.patchVersion(origTools.Version) 439 440 envtesting.AssertUploadFakeToolsVersions( 441 c, stor, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), downgradeVersion) 442 443 prevTools := envtesting.AssertUploadFakeToolsVersions( 444 c, stor, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), downgradeVersion)[0] 445 446 err := statetesting.SetAgentVersion(s.State, downgradeVersion.Number) 447 c.Assert(err, jc.ErrorIsNil) 448 449 u := s.makeUpgrader(c) 450 err = workertest.CheckKilled(c, u) 451 s.expectInitialUpgradeCheckNotDone(c) 452 453 envtesting.CheckUpgraderReadyError(c, err, &agenterrors.UpgradeReadyError{ 454 AgentName: s.machine.Tag().String(), 455 OldTools: origTools.Version, 456 NewTools: prevTools.Version, 457 DataDir: s.DataDir(), 458 }) 459 foundTools, err := agenttools.ReadTools(s.DataDir(), prevTools.Version) 460 c.Assert(err, jc.ErrorIsNil) 461 prevTools.URL = fmt.Sprintf("https://%s/model/%s/tools/5.3.0-ubuntu-amd64", 462 s.APIState.Addr(), coretesting.ModelTag.Id()) 463 envtesting.CheckTools(c, foundTools, prevTools) 464 } 465 466 func (s *UpgraderSuite) TestChecksSpaceBeforeDownloading(c *gc.C) { 467 stor := s.DefaultToolsStorage 468 oldTools := envtesting.PrimeTools(c, stor, s.DataDir(), s.Environ.Config().AgentStream(), 469 version.MustParseBinary("5.4.3-ubuntu-amd64")) 470 s.patchVersion(oldTools.Version) 471 472 newTools := envtesting.AssertUploadFakeToolsVersions( 473 c, stor, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), 474 version.MustParseBinary("5.4.5-ubuntu-amd64"))[0] 475 err := statetesting.SetAgentVersion(s.State, newTools.Version.Number) 476 c.Assert(err, jc.ErrorIsNil) 477 478 // We want to wait for the model to settle so that we get a single event 479 // from the version watcher. 480 // If we start the worker too quickly after setting the new tools, 481 // it is possible to get 2 watcher changes - the guaranteed initial event 482 // and *then* the one for the change. 483 s.WaitForModelWatchersIdle(c, s.State.ModelUUID()) 484 485 var diskSpaceStub testing.Stub 486 diskSpaceStub.SetErrors(nil, errors.Errorf("full-up")) 487 diskSpaceChecked := make(chan struct{}, 1) 488 489 u, err := upgrader.NewAgentUpgrader(upgrader.Config{ 490 Clock: s.clock, 491 Logger: loggo.GetLogger("test"), 492 State: upgraderapi.NewState(s.state), 493 AgentConfig: agentConfig(s.machine.Tag(), s.DataDir()), 494 OrigAgentVersion: s.confVersion, 495 UpgradeStepsWaiter: s.upgradeStepsComplete, 496 InitialUpgradeCheckComplete: s.initialCheckComplete, 497 CheckDiskSpace: func(dir string, size uint64) error { 498 diskSpaceStub.AddCall("CheckDiskSpace", dir, size) 499 500 // CheckDiskSpace is called twice in checkForSpace. 501 // We only care that we arrived there, so if we've already buffered 502 // a write, just proceed. 503 select { 504 case diskSpaceChecked <- struct{}{}: 505 default: 506 } 507 508 return diskSpaceStub.NextErr() 509 }, 510 }) 511 c.Assert(err, jc.ErrorIsNil) 512 513 select { 514 case <-diskSpaceChecked: 515 workertest.CleanKill(c, u) 516 case <-time.After(coretesting.LongWait): 517 c.Fatalf("timed out waiting for disk space check.") 518 } 519 520 s.expectInitialUpgradeCheckNotDone(c) 521 522 c.Assert(diskSpaceStub.Calls(), gc.HasLen, 2) 523 diskSpaceStub.CheckCall(c, 0, "CheckDiskSpace", s.DataDir(), upgrades.MinDiskSpaceMib) 524 diskSpaceStub.CheckCall(c, 1, "CheckDiskSpace", os.TempDir(), upgrades.MinDiskSpaceMib) 525 526 _, err = agenttools.ReadTools(s.DataDir(), newTools.Version) 527 c.Assert(err, gc.ErrorMatches, `cannot read agent metadata in directory.*: no such file or directory`) 528 } 529 530 func (s *UpgraderSuite) waitForUpgradeCheck(c *gc.C) { 531 select { 532 case <-s.initialCheckComplete.Unlocked(): 533 case <-time.After(coretesting.LongWait): 534 c.Fatalf("timed out waiting for initial upgrade check") 535 } 536 } 537 538 func (s *UpgraderSuite) expectInitialUpgradeCheckNotDone(c *gc.C) { 539 c.Assert(s.initialCheckComplete.IsUnlocked(), jc.IsFalse) 540 } 541 542 type allowedTest struct { 543 current string 544 target string 545 allowed bool 546 } 547 548 func (s *AllowedTargetVersionSuite) TestAllowedTargetVersionSuite(c *gc.C) { 549 cases := []allowedTest{ 550 {current: "2.7.4", target: "2.8.0", allowed: true}, // normal upgrade 551 {current: "2.8.0", target: "2.7.4", allowed: true}, // downgrade caused by restore after upgrade 552 {current: "3.8.0", target: "1.2.3", allowed: false}, // can't downgrade to major version 1.x 553 {current: "2.7.4", target: "2.7.5", allowed: true}, // point release 554 {current: "2.8.0", target: "2.7.4", allowed: true}, // downgrade after upgrade but before config file updated 555 } 556 for i, test := range cases { 557 c.Logf("test case %d, %#v", i, test) 558 current := version.MustParse(test.current) 559 target := version.MustParse(test.target) 560 result := upgrader.AllowedTargetVersion(current, target) 561 c.Check(result, gc.Equals, test.allowed) 562 } 563 }