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