github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/undertaker/undertaker_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package undertaker_test 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/testing" 9 gc "gopkg.in/check.v1" 10 "gopkg.in/juju/worker.v1" 11 "gopkg.in/juju/worker.v1/workertest" 12 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/core/status" 15 ) 16 17 // UndertakerSuite is *not* complete. But it's a lot more so 18 // than it was before, and should be much easier to extend. 19 type UndertakerSuite struct { 20 testing.IsolationSuite 21 fix fixture 22 } 23 24 var _ = gc.Suite(&UndertakerSuite{}) 25 26 func (s *UndertakerSuite) SetUpTest(c *gc.C) { 27 s.IsolationSuite.SetUpTest(c) 28 s.fix = fixture{ 29 info: params.UndertakerModelInfoResult{ 30 Result: params.UndertakerModelInfo{ 31 Life: "dying", 32 }, 33 }, 34 } 35 } 36 37 func (s *UndertakerSuite) TestAliveError(c *gc.C) { 38 s.fix.info.Result.Life = "alive" 39 s.fix.dirty = true 40 stub := s.fix.run(c, func(w worker.Worker) { 41 err := workertest.CheckKilled(c, w) 42 c.Check(err, gc.ErrorMatches, "model still alive") 43 }) 44 stub.CheckCallNames(c, "ModelInfo") 45 } 46 47 func (s *UndertakerSuite) TestAlreadyDeadRemoves(c *gc.C) { 48 s.fix.info.Result.Life = "dead" 49 stub := s.fix.run(c, func(w worker.Worker) { 50 workertest.CheckKilled(c, w) 51 }) 52 stub.CheckCallNames(c, "ModelInfo", "SetStatus", "Destroy", "RemoveModel") 53 } 54 55 func (s *UndertakerSuite) TestDyingDeadRemoved(c *gc.C) { 56 stub := s.fix.run(c, func(w worker.Worker) { 57 workertest.CheckKilled(c, w) 58 }) 59 stub.CheckCallNames(c, 60 "ModelInfo", 61 "SetStatus", 62 "WatchModelResources", 63 "ProcessDyingModel", 64 "SetStatus", 65 "Destroy", 66 "RemoveModel", 67 ) 68 } 69 70 func (s *UndertakerSuite) TestSetStatusDestroying(c *gc.C) { 71 stub := s.fix.run(c, func(w worker.Worker) { 72 workertest.CheckKilled(c, w) 73 }) 74 stub.CheckCall( 75 c, 1, "SetStatus", status.Destroying, 76 "cleaning up cloud resources", map[string]interface{}(nil), 77 ) 78 stub.CheckCall( 79 c, 4, "SetStatus", status.Destroying, 80 "tearing down cloud environment", map[string]interface{}(nil), 81 ) 82 } 83 84 func (s *UndertakerSuite) TestControllerStopsWhenModelDead(c *gc.C) { 85 s.fix.info.Result.IsSystem = true 86 stub := s.fix.run(c, func(w worker.Worker) { 87 workertest.CheckKilled(c, w) 88 }) 89 stub.CheckCallNames(c, 90 "ModelInfo", 91 "SetStatus", 92 "WatchModelResources", 93 "ProcessDyingModel", 94 ) 95 } 96 97 func (s *UndertakerSuite) TestModelInfoErrorFatal(c *gc.C) { 98 s.fix.errors = []error{errors.New("pow")} 99 s.fix.dirty = true 100 stub := s.fix.run(c, func(w worker.Worker) { 101 err := workertest.CheckKilled(c, w) 102 c.Check(err, gc.ErrorMatches, "pow") 103 }) 104 stub.CheckCallNames(c, "ModelInfo") 105 } 106 107 func (s *UndertakerSuite) TestWatchModelResourcesErrorFatal(c *gc.C) { 108 s.fix.errors = []error{nil, nil, errors.New("pow")} 109 s.fix.dirty = true 110 stub := s.fix.run(c, func(w worker.Worker) { 111 err := workertest.CheckKilled(c, w) 112 c.Check(err, gc.ErrorMatches, "pow") 113 }) 114 stub.CheckCallNames(c, "ModelInfo", "SetStatus", "WatchModelResources") 115 } 116 117 func (s *UndertakerSuite) TestProcessDyingModelErrorRetried(c *gc.C) { 118 s.fix.errors = []error{ 119 nil, // ModelInfo 120 nil, // SetStatus 121 nil, // WatchModelResources, 122 ¶ms.Error{Code: params.CodeHasHostedModels}, 123 nil, // SetStatus 124 ¶ms.Error{Code: params.CodeModelNotEmpty}, 125 nil, // SetStatus 126 nil, // ProcessDyingModel, 127 nil, // SetStatus 128 nil, // Destroy, 129 nil, // RemoveModel 130 } 131 stub := s.fix.run(c, func(w worker.Worker) { 132 workertest.CheckKilled(c, w) 133 }) 134 stub.CheckCallNames(c, 135 "ModelInfo", 136 "SetStatus", 137 "WatchModelResources", 138 "ProcessDyingModel", 139 "SetStatus", 140 "ProcessDyingModel", 141 "SetStatus", 142 "ProcessDyingModel", 143 "SetStatus", 144 "Destroy", 145 "RemoveModel", 146 ) 147 } 148 149 func (s *UndertakerSuite) TestProcessDyingModelErrorFatal(c *gc.C) { 150 s.fix.errors = []error{ 151 nil, // ModelInfo 152 nil, // SetStatus 153 nil, // WatchModelResources, 154 errors.New("nope"), 155 } 156 s.fix.dirty = true 157 stub := s.fix.run(c, func(w worker.Worker) { 158 err := workertest.CheckKilled(c, w) 159 c.Check(err, gc.ErrorMatches, "nope") 160 }) 161 stub.CheckCallNames(c, 162 "ModelInfo", 163 "SetStatus", 164 "WatchModelResources", 165 "ProcessDyingModel", 166 ) 167 } 168 169 func (s *UndertakerSuite) TestDestroyErrorFatal(c *gc.C) { 170 s.fix.errors = []error{nil, nil, errors.New("pow")} 171 s.fix.info.Result.Life = "dead" 172 s.fix.dirty = true 173 stub := s.fix.run(c, func(w worker.Worker) { 174 err := workertest.CheckKilled(c, w) 175 c.Check(err, gc.ErrorMatches, "pow") 176 }) 177 stub.CheckCallNames(c, "ModelInfo", "SetStatus", "Destroy") 178 } 179 180 func (s *UndertakerSuite) TestRemoveModelErrorFatal(c *gc.C) { 181 s.fix.errors = []error{nil, nil, nil, errors.New("pow")} 182 s.fix.info.Result.Life = "dead" 183 s.fix.dirty = true 184 stub := s.fix.run(c, func(w worker.Worker) { 185 err := workertest.CheckKilled(c, w) 186 c.Check(err, gc.ErrorMatches, "cannot remove model: pow") 187 }) 188 stub.CheckCallNames(c, "ModelInfo", "SetStatus", "Destroy", "RemoveModel") 189 }