github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/migrationminion/worker_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package migrationminion_test 5 6 import ( 7 "sync" 8 "time" 9 10 "github.com/juju/errors" 11 jujutesting "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/agent" 16 "github.com/juju/juju/core/migration" 17 "github.com/juju/juju/network" 18 coretesting "github.com/juju/juju/testing" 19 "github.com/juju/juju/watcher" 20 "github.com/juju/juju/worker" 21 "github.com/juju/juju/worker/fortress" 22 "github.com/juju/juju/worker/migrationminion" 23 "github.com/juju/juju/worker/workertest" 24 ) 25 26 type Suite struct { 27 coretesting.BaseSuite 28 stub *jujutesting.Stub 29 client *stubMinionClient 30 guard *stubGuard 31 agent *stubAgent 32 } 33 34 var _ = gc.Suite(&Suite{}) 35 36 func (s *Suite) SetUpTest(c *gc.C) { 37 s.BaseSuite.SetUpTest(c) 38 s.stub = new(jujutesting.Stub) 39 s.client = newStubMinionClient(s.stub) 40 s.guard = newStubGuard(s.stub) 41 s.agent = newStubAgent() 42 } 43 44 func (s *Suite) TestStartAndStop(c *gc.C) { 45 w, err := migrationminion.New(migrationminion.Config{ 46 Facade: s.client, 47 Guard: s.guard, 48 Agent: s.agent, 49 }) 50 c.Assert(err, jc.ErrorIsNil) 51 workertest.CleanKill(c, w) 52 s.stub.CheckCallNames(c, "Watch") 53 } 54 55 func (s *Suite) TestWatchFailure(c *gc.C) { 56 s.client.watchErr = errors.New("boom") 57 w, err := migrationminion.New(migrationminion.Config{ 58 Facade: s.client, 59 Guard: s.guard, 60 Agent: s.agent, 61 }) 62 c.Assert(err, jc.ErrorIsNil) 63 err = workertest.CheckKilled(c, w) 64 c.Check(err, gc.ErrorMatches, "setting up watcher: boom") 65 } 66 67 func (s *Suite) TestClosedWatcherChannel(c *gc.C) { 68 close(s.client.watcher.changes) 69 w, err := migrationminion.New(migrationminion.Config{ 70 Facade: s.client, 71 Guard: s.guard, 72 Agent: s.agent, 73 }) 74 c.Assert(err, jc.ErrorIsNil) 75 err = workertest.CheckKilled(c, w) 76 c.Check(err, gc.ErrorMatches, "watcher channel closed") 77 } 78 79 func (s *Suite) TestUnlockError(c *gc.C) { 80 s.client.watcher.changes <- watcher.MigrationStatus{ 81 Phase: migration.NONE, 82 } 83 s.guard.unlockErr = errors.New("squish") 84 w, err := migrationminion.New(migrationminion.Config{ 85 Facade: s.client, 86 Guard: s.guard, 87 Agent: s.agent, 88 }) 89 c.Assert(err, jc.ErrorIsNil) 90 91 err = workertest.CheckKilled(c, w) 92 c.Check(err, gc.ErrorMatches, "squish") 93 s.stub.CheckCallNames(c, "Watch", "Unlock") 94 } 95 96 func (s *Suite) TestLockdownError(c *gc.C) { 97 s.client.watcher.changes <- watcher.MigrationStatus{ 98 Phase: migration.QUIESCE, 99 } 100 s.guard.lockdownErr = errors.New("squash") 101 w, err := migrationminion.New(migrationminion.Config{ 102 Facade: s.client, 103 Guard: s.guard, 104 Agent: s.agent, 105 }) 106 c.Assert(err, jc.ErrorIsNil) 107 108 err = workertest.CheckKilled(c, w) 109 c.Check(err, gc.ErrorMatches, "squash") 110 s.stub.CheckCallNames(c, "Watch", "Lockdown") 111 } 112 113 func (s *Suite) TestNONE(c *gc.C) { 114 s.client.watcher.changes <- watcher.MigrationStatus{ 115 Phase: migration.NONE, 116 } 117 w, err := migrationminion.New(migrationminion.Config{ 118 Facade: s.client, 119 Guard: s.guard, 120 Agent: s.agent, 121 }) 122 c.Assert(err, jc.ErrorIsNil) 123 124 workertest.CheckAlive(c, w) 125 workertest.CleanKill(c, w) 126 s.stub.CheckCallNames(c, "Watch", "Unlock") 127 } 128 129 func (s *Suite) TestSUCCESS(c *gc.C) { 130 addrs := []string{"1.1.1.1:1", "9.9.9.9:9"} 131 s.client.watcher.changes <- watcher.MigrationStatus{ 132 Phase: migration.SUCCESS, 133 TargetAPIAddrs: addrs, 134 TargetCACert: "top secret", 135 } 136 w, err := migrationminion.New(migrationminion.Config{ 137 Facade: s.client, 138 Guard: s.guard, 139 Agent: s.agent, 140 }) 141 c.Assert(err, jc.ErrorIsNil) 142 143 select { 144 case <-s.agent.configChanged: 145 case <-time.After(coretesting.LongWait): 146 c.Fatal("timed out waiting for config to be changed") 147 } 148 workertest.CleanKill(c, w) 149 c.Assert(s.agent.conf.addrs, gc.DeepEquals, addrs) 150 c.Assert(s.agent.conf.caCert, gc.DeepEquals, "top secret") 151 s.stub.CheckCallNames(c, "Watch", "Lockdown") 152 } 153 154 func newStubGuard(stub *jujutesting.Stub) *stubGuard { 155 return &stubGuard{stub: stub} 156 } 157 158 type stubGuard struct { 159 stub *jujutesting.Stub 160 unlockErr error 161 lockdownErr error 162 } 163 164 func (g *stubGuard) Lockdown(fortress.Abort) error { 165 g.stub.AddCall("Lockdown") 166 return g.lockdownErr 167 } 168 169 func (g *stubGuard) Unlock() error { 170 g.stub.AddCall("Unlock") 171 return g.unlockErr 172 } 173 174 func newStubMinionClient(stub *jujutesting.Stub) *stubMinionClient { 175 return &stubMinionClient{ 176 stub: stub, 177 watcher: newStubWatcher(), 178 } 179 } 180 181 type stubMinionClient struct { 182 stub *jujutesting.Stub 183 watcher *stubWatcher 184 watchErr error 185 } 186 187 func (c *stubMinionClient) Watch() (watcher.MigrationStatusWatcher, error) { 188 c.stub.MethodCall(c, "Watch") 189 if c.watchErr != nil { 190 return nil, c.watchErr 191 } 192 return c.watcher, nil 193 } 194 195 func newStubWatcher() *stubWatcher { 196 return &stubWatcher{ 197 Worker: workertest.NewErrorWorker(nil), 198 changes: make(chan watcher.MigrationStatus, 1), 199 } 200 } 201 202 type stubWatcher struct { 203 worker.Worker 204 changes chan watcher.MigrationStatus 205 } 206 207 func (w *stubWatcher) Changes() <-chan watcher.MigrationStatus { 208 return w.changes 209 } 210 211 func newStubAgent() *stubAgent { 212 return &stubAgent{ 213 configChanged: make(chan bool), 214 } 215 } 216 217 type stubAgent struct { 218 agent.Agent 219 configChanged chan bool 220 conf stubConfig 221 } 222 223 func (ma *stubAgent) CurrentConfig() agent.Config { 224 return &ma.conf 225 } 226 227 func (ma *stubAgent) ChangeConfig(f agent.ConfigMutator) error { 228 defer close(ma.configChanged) 229 return f(&ma.conf) 230 } 231 232 type stubConfig struct { 233 agent.ConfigSetter 234 235 mu sync.Mutex 236 addrs []string 237 caCert string 238 } 239 240 func (mc *stubConfig) setAddresses(addrs ...string) { 241 mc.mu.Lock() 242 defer mc.mu.Unlock() 243 mc.addrs = append([]string(nil), addrs...) 244 } 245 246 func (mc *stubConfig) SetAPIHostPorts(servers [][]network.HostPort) { 247 mc.mu.Lock() 248 defer mc.mu.Unlock() 249 mc.addrs = nil 250 for _, hps := range servers { 251 for _, hp := range hps { 252 mc.addrs = append(mc.addrs, hp.NetAddr()) 253 } 254 } 255 } 256 257 func (mc *stubConfig) SetCACert(cert string) { 258 mc.mu.Lock() 259 defer mc.mu.Unlock() 260 mc.caCert = cert 261 }