launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/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 "os" 8 "path/filepath" 9 stdtesting "testing" 10 "time" 11 12 errgo "launchpad.net/errgo/errors" 13 gc "launchpad.net/gocheck" 14 15 "launchpad.net/juju-core/agent" 16 agenttools "launchpad.net/juju-core/agent/tools" 17 envtesting "launchpad.net/juju-core/environs/testing" 18 envtools "launchpad.net/juju-core/environs/tools" 19 "launchpad.net/juju-core/errors" 20 jujutesting "launchpad.net/juju-core/juju/testing" 21 "launchpad.net/juju-core/provider/dummy" 22 "launchpad.net/juju-core/state" 23 "launchpad.net/juju-core/state/api" 24 statetesting "launchpad.net/juju-core/state/testing" 25 coretesting "launchpad.net/juju-core/testing" 26 jc "launchpad.net/juju-core/testing/checkers" 27 coretools "launchpad.net/juju-core/tools" 28 "launchpad.net/juju-core/version" 29 "launchpad.net/juju-core/worker/upgrader" 30 ) 31 32 func TestPackage(t *stdtesting.T) { 33 coretesting.MgoTestPackage(t) 34 } 35 36 type UpgraderSuite struct { 37 jujutesting.JujuConnSuite 38 39 machine *state.Machine 40 state *api.State 41 oldRetryAfter func() <-chan time.Time 42 } 43 44 var _ = gc.Suite(&UpgraderSuite{}) 45 46 func (s *UpgraderSuite) SetUpTest(c *gc.C) { 47 s.JujuConnSuite.SetUpTest(c) 48 s.state, s.machine = s.OpenAPIAsNewMachine(c) 49 // Capture the value of RetryAfter, and use that captured 50 // value in the cleanup lambda. 51 oldRetryAfter := *upgrader.RetryAfter 52 s.AddCleanup(func(*gc.C) { 53 *upgrader.RetryAfter = oldRetryAfter 54 }) 55 } 56 57 type mockConfig struct { 58 agent.Config 59 tag string 60 datadir string 61 } 62 63 func (mock *mockConfig) Tag() string { 64 return mock.tag 65 } 66 67 func (mock *mockConfig) DataDir() string { 68 return mock.datadir 69 } 70 71 func agentConfig(tag, datadir string) agent.Config { 72 return &mockConfig{tag: tag, datadir: datadir} 73 } 74 75 func (s *UpgraderSuite) makeUpgrader() *upgrader.Upgrader { 76 config := agentConfig(s.machine.Tag(), s.DataDir()) 77 return upgrader.NewUpgrader(s.state.Upgrader(), config) 78 } 79 80 func (s *UpgraderSuite) TestUpgraderSetsTools(c *gc.C) { 81 vers := version.MustParseBinary("5.4.3-precise-amd64") 82 err := statetesting.SetAgentVersion(s.State, vers.Number) 83 c.Assert(err, gc.IsNil) 84 stor := s.Conn.Environ.Storage() 85 agentTools := envtesting.PrimeTools(c, stor, s.DataDir(), vers) 86 err = envtools.MergeAndWriteMetadata(stor, coretools.List{agentTools}, envtools.DoNotWriteMirrors) 87 _, err = s.machine.AgentTools() 88 c.Assert(err, jc.Satisfies, errors.IsNotFoundError) 89 90 u := s.makeUpgrader() 91 statetesting.AssertStop(c, u) 92 s.machine.Refresh() 93 gotTools, err := s.machine.AgentTools() 94 c.Assert(err, gc.IsNil) 95 envtesting.CheckTools(c, gotTools, agentTools) 96 } 97 98 func (s *UpgraderSuite) TestUpgraderSetVersion(c *gc.C) { 99 vers := version.MustParseBinary("5.4.3-precise-amd64") 100 envtesting.PrimeTools(c, s.Conn.Environ.Storage(), s.DataDir(), vers) 101 err := os.RemoveAll(filepath.Join(s.DataDir(), "tools")) 102 c.Assert(err, gc.IsNil) 103 104 _, err = s.machine.AgentTools() 105 c.Assert(err, jc.Satisfies, errors.IsNotFoundError) 106 err = statetesting.SetAgentVersion(s.State, vers.Number) 107 c.Assert(err, gc.IsNil) 108 109 u := s.makeUpgrader() 110 statetesting.AssertStop(c, u) 111 s.machine.Refresh() 112 gotTools, err := s.machine.AgentTools() 113 c.Assert(err, gc.IsNil) 114 c.Assert(gotTools, gc.DeepEquals, &coretools.Tools{Version: version.Current}) 115 } 116 117 func (s *UpgraderSuite) TestUpgraderUpgradesImmediately(c *gc.C) { 118 stor := s.Conn.Environ.Storage() 119 oldTools := envtesting.PrimeTools(c, stor, s.DataDir(), version.MustParseBinary("5.4.3-precise-amd64")) 120 newTools := envtesting.AssertUploadFakeToolsVersions( 121 c, stor, version.MustParseBinary("5.4.5-precise-amd64"))[0] 122 err := envtools.MergeAndWriteMetadata(stor, coretools.List{oldTools, newTools}, envtools.DoNotWriteMirrors) 123 c.Assert(err, gc.IsNil) 124 err = statetesting.SetAgentVersion(s.State, newTools.Version.Number) 125 c.Assert(err, gc.IsNil) 126 127 // Make the download take a while so that we verify that 128 // the download happens before the upgrader checks if 129 // it's been stopped. 130 dummy.SetStorageDelay(coretesting.ShortWait) 131 132 u := s.makeUpgrader() 133 err = u.Stop() 134 envtesting.CheckUpgraderReadyError(c, err, &upgrader.UpgradeReadyError{ 135 AgentName: s.machine.Tag(), 136 OldTools: oldTools, 137 NewTools: newTools, 138 DataDir: s.DataDir(), 139 }) 140 foundTools, err := agenttools.ReadTools(s.DataDir(), newTools.Version) 141 c.Assert(err, gc.IsNil) 142 envtesting.CheckTools(c, foundTools, newTools) 143 } 144 145 func (s *UpgraderSuite) TestUpgraderRetryAndChanged(c *gc.C) { 146 stor := s.Conn.Environ.Storage() 147 oldTools := envtesting.PrimeTools(c, stor, s.DataDir(), version.MustParseBinary("5.4.3-precise-amd64")) 148 newTools := envtesting.AssertUploadFakeToolsVersions( 149 c, stor, version.MustParseBinary("5.4.5-precise-amd64"))[0] 150 err := envtools.MergeAndWriteMetadata(stor, coretools.List{oldTools, newTools}, envtools.DoNotWriteMirrors) 151 c.Assert(err, gc.IsNil) 152 err = statetesting.SetAgentVersion(s.State, newTools.Version.Number) 153 c.Assert(err, gc.IsNil) 154 155 retryc := make(chan time.Time) 156 *upgrader.RetryAfter = func() <-chan time.Time { 157 c.Logf("replacement retry after") 158 return retryc 159 } 160 dummy.Poison(s.Conn.Environ.Storage(), envtools.StorageName(newTools.Version), errgo.Newf("a non-fatal dose")) 161 u := s.makeUpgrader() 162 defer u.Stop() 163 164 for i := 0; i < 3; i++ { 165 select { 166 case retryc <- time.Now(): 167 case <-time.After(coretesting.LongWait): 168 c.Fatalf("upgrader did not retry (attempt %d)", i) 169 } 170 } 171 172 // Make it upgrade to some newer tools that can be 173 // downloaded ok; it should stop retrying, download 174 // the newer tools and exit. 175 newerTools := envtesting.AssertUploadFakeToolsVersions( 176 c, s.Conn.Environ.Storage(), version.MustParseBinary("5.4.6-precise-amd64"))[0] 177 178 err = statetesting.SetAgentVersion(s.State, newerTools.Version.Number) 179 c.Assert(err, gc.IsNil) 180 181 s.BackingState.StartSync() 182 done := make(chan error) 183 go func() { 184 done <- u.Wait() 185 }() 186 select { 187 case err := <-done: 188 envtesting.CheckUpgraderReadyError(c, err, &upgrader.UpgradeReadyError{ 189 AgentName: s.machine.Tag(), 190 OldTools: oldTools, 191 NewTools: newerTools, 192 DataDir: s.DataDir(), 193 }) 194 case <-time.After(coretesting.LongWait): 195 c.Fatalf("upgrader did not quit after upgrading") 196 } 197 } 198 199 func (s *UpgraderSuite) TestChangeAgentTools(c *gc.C) { 200 oldTools := &coretools.Tools{ 201 Version: version.MustParseBinary("1.2.3-quantal-amd64"), 202 } 203 stor := s.Conn.Environ.Storage() 204 newTools := envtesting.PrimeTools(c, stor, s.DataDir(), version.MustParseBinary("5.4.3-precise-amd64")) 205 err := envtools.MergeAndWriteMetadata(stor, coretools.List{newTools}, envtools.DoNotWriteMirrors) 206 c.Assert(err, gc.IsNil) 207 ugErr := &upgrader.UpgradeReadyError{ 208 AgentName: "anAgent", 209 OldTools: oldTools, 210 NewTools: newTools, 211 DataDir: s.DataDir(), 212 } 213 err = ugErr.ChangeAgentTools() 214 c.Assert(err, gc.IsNil) 215 link, err := os.Readlink(agenttools.ToolsDir(s.DataDir(), "anAgent")) 216 c.Assert(err, gc.IsNil) 217 c.Assert(link, gc.Equals, newTools.Version.String()) 218 } 219 220 func (s *UpgraderSuite) TestEnsureToolsChecksBeforeDownloading(c *gc.C) { 221 stor := s.Conn.Environ.Storage() 222 newTools := envtesting.PrimeTools(c, stor, s.DataDir(), version.MustParseBinary("5.4.3-precise-amd64")) 223 // We've already downloaded the tools, so change the URL to be 224 // something invalid and ensure we don't actually get an error, because 225 // it doesn't actually do an HTTP request 226 u := s.makeUpgrader() 227 newTools.URL = "http://localhost:999999/invalid/path/tools.tgz" 228 err := upgrader.EnsureTools(u, newTools, true) 229 c.Assert(err, gc.IsNil) 230 }