github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/api/deployer/deployer_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package deployer_test 5 6 import ( 7 stdtesting "testing" 8 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 "gopkg.in/juju/names.v2" 12 13 "github.com/juju/juju/api" 14 "github.com/juju/juju/api/deployer" 15 "github.com/juju/juju/apiserver/params" 16 "github.com/juju/juju/core/status" 17 "github.com/juju/juju/core/watcher/watchertest" 18 "github.com/juju/juju/juju/testing" 19 "github.com/juju/juju/network" 20 "github.com/juju/juju/state" 21 coretesting "github.com/juju/juju/testing" 22 ) 23 24 func TestAll(t *stdtesting.T) { 25 coretesting.MgoTestPackage(t) 26 } 27 28 type deployerSuite struct { 29 testing.JujuConnSuite 30 31 stateAPI api.Connection 32 33 // These are raw State objects. Use them for setup and assertions, but 34 // should never be touched by the API calls themselves 35 machine *state.Machine 36 app0 *state.Application 37 app1 *state.Application 38 principal *state.Unit 39 subordinate *state.Unit 40 41 st *deployer.State 42 } 43 44 var _ = gc.Suite(&deployerSuite{}) 45 46 func (s *deployerSuite) SetUpTest(c *gc.C) { 47 s.JujuConnSuite.SetUpTest(c) 48 s.stateAPI, s.machine = s.OpenAPIAsNewMachine(c, state.JobManageModel, state.JobHostUnits) 49 err := s.machine.SetProviderAddresses(network.NewAddress("0.1.2.3")) 50 c.Assert(err, jc.ErrorIsNil) 51 52 // Create the needed applications and relate them. 53 s.app0 = s.AddTestingApplication(c, "mysql", s.AddTestingCharm(c, "mysql")) 54 s.app1 = s.AddTestingApplication(c, "logging", s.AddTestingCharm(c, "logging")) 55 eps, err := s.State.InferEndpoints("mysql", "logging") 56 c.Assert(err, jc.ErrorIsNil) 57 rel, err := s.State.AddRelation(eps...) 58 c.Assert(err, jc.ErrorIsNil) 59 60 // Create principal and subordinate units and assign them. 61 s.principal, err = s.app0.AddUnit(state.AddUnitParams{}) 62 c.Assert(err, jc.ErrorIsNil) 63 err = s.principal.AssignToMachine(s.machine) 64 c.Assert(err, jc.ErrorIsNil) 65 relUnit, err := rel.Unit(s.principal) 66 c.Assert(err, jc.ErrorIsNil) 67 err = relUnit.EnterScope(nil) 68 c.Assert(err, jc.ErrorIsNil) 69 s.subordinate, err = s.State.Unit("logging/0") 70 c.Assert(err, jc.ErrorIsNil) 71 72 // Create the deployer facade. 73 s.st = deployer.NewState(s.stateAPI) 74 c.Assert(s.st, gc.NotNil) 75 } 76 77 // Note: This is really meant as a unit-test, this isn't a test that 78 // should need all of the setup we have for this test suite 79 func (s *deployerSuite) TestNew(c *gc.C) { 80 deployer := deployer.NewState(s.stateAPI) 81 c.Assert(deployer, gc.NotNil) 82 } 83 84 func (s *deployerSuite) assertUnauthorized(c *gc.C, err error) { 85 c.Assert(err, gc.ErrorMatches, "permission denied") 86 c.Assert(err, jc.Satisfies, params.IsCodeUnauthorized) 87 } 88 89 func (s *deployerSuite) TestWatchUnitsWrongMachine(c *gc.C) { 90 // Try with a non-existent machine tag. 91 machine, err := s.st.Machine(names.NewMachineTag("42")) 92 c.Assert(err, jc.ErrorIsNil) 93 w, err := machine.WatchUnits() 94 s.assertUnauthorized(c, err) 95 c.Assert(w, gc.IsNil) 96 } 97 98 func (s *deployerSuite) TestWatchUnits(c *gc.C) { 99 // TODO(dfc) fix state.Machine to return a MachineTag 100 machine, err := s.st.Machine(s.machine.Tag().(names.MachineTag)) 101 c.Assert(err, jc.ErrorIsNil) 102 w, err := machine.WatchUnits() 103 c.Assert(err, jc.ErrorIsNil) 104 wc := watchertest.NewStringsWatcherC(c, w, s.BackingState.StartSync) 105 defer wc.AssertStops() 106 107 // Initial event. 108 wc.AssertChange("mysql/0", "logging/0") 109 wc.AssertNoChange() 110 111 // Change something other than the lifecycle and make sure it's 112 // not detected. 113 err = s.subordinate.SetPassword("foo") 114 c.Assert(err, gc.ErrorMatches, "password is only 3 bytes long, and is not a valid Agent password") 115 wc.AssertNoChange() 116 117 err = s.subordinate.SetPassword("foo-12345678901234567890") 118 c.Assert(err, jc.ErrorIsNil) 119 wc.AssertNoChange() 120 121 // Make the subordinate dead and check it's detected. 122 err = s.subordinate.EnsureDead() 123 c.Assert(err, jc.ErrorIsNil) 124 wc.AssertChange("logging/0") 125 wc.AssertNoChange() 126 } 127 128 func (s *deployerSuite) TestUnit(c *gc.C) { 129 // Try getting a missing unit and an invalid tag. 130 unit, err := s.st.Unit(names.NewUnitTag("foo/42")) 131 s.assertUnauthorized(c, err) 132 c.Assert(unit, gc.IsNil) 133 134 // Try getting a unit we're not responsible for. 135 // First create a new machine and deploy another unit there. 136 machine, err := s.State.AddMachine("quantal", state.JobHostUnits) 137 c.Assert(err, jc.ErrorIsNil) 138 principal1, err := s.app0.AddUnit(state.AddUnitParams{}) 139 c.Assert(err, jc.ErrorIsNil) 140 err = principal1.AssignToMachine(machine) 141 c.Assert(err, jc.ErrorIsNil) 142 unit, err = s.st.Unit(principal1.Tag().(names.UnitTag)) 143 s.assertUnauthorized(c, err) 144 c.Assert(unit, gc.IsNil) 145 146 // Get the principal and subordinate we're responsible for. 147 unit, err = s.st.Unit(s.principal.Tag().(names.UnitTag)) 148 c.Assert(err, jc.ErrorIsNil) 149 c.Assert(unit.Name(), gc.Equals, "mysql/0") 150 unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag)) 151 c.Assert(err, jc.ErrorIsNil) 152 c.Assert(unit.Name(), gc.Equals, "logging/0") 153 } 154 155 func (s *deployerSuite) TestUnitLifeRefresh(c *gc.C) { 156 unit, err := s.st.Unit(s.subordinate.Tag().(names.UnitTag)) 157 c.Assert(err, jc.ErrorIsNil) 158 159 c.Assert(unit.Life(), gc.Equals, params.Alive) 160 161 // Now make it dead and check again, then refresh and check. 162 err = s.subordinate.EnsureDead() 163 c.Assert(err, jc.ErrorIsNil) 164 err = s.subordinate.Refresh() 165 c.Assert(err, jc.ErrorIsNil) 166 c.Assert(s.subordinate.Life(), gc.Equals, state.Dead) 167 c.Assert(unit.Life(), gc.Equals, params.Alive) 168 err = unit.Refresh() 169 c.Assert(err, jc.ErrorIsNil) 170 c.Assert(unit.Life(), gc.Equals, params.Dead) 171 } 172 173 func (s *deployerSuite) TestUnitRemove(c *gc.C) { 174 unit, err := s.st.Unit(s.principal.Tag().(names.UnitTag)) 175 c.Assert(err, jc.ErrorIsNil) 176 177 // It fails because the entity is still alive. 178 // And EnsureDead will fail because there is a subordinate. 179 err = unit.Remove() 180 c.Assert(err, gc.ErrorMatches, `cannot remove entity "unit-mysql-0": still alive`) 181 c.Assert(params.ErrCode(err), gc.Equals, "") 182 183 // With the subordinate it also fails due to it being alive. 184 unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag)) 185 c.Assert(err, jc.ErrorIsNil) 186 err = unit.Remove() 187 c.Assert(err, gc.ErrorMatches, `cannot remove entity "unit-logging-0": still alive`) 188 c.Assert(params.ErrCode(err), gc.Equals, "") 189 190 // Make it dead first and try again. 191 err = s.subordinate.EnsureDead() 192 c.Assert(err, jc.ErrorIsNil) 193 err = unit.Remove() 194 c.Assert(err, jc.ErrorIsNil) 195 196 // Verify it's gone. 197 err = unit.Refresh() 198 s.assertUnauthorized(c, err) 199 unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag)) 200 s.assertUnauthorized(c, err) 201 c.Assert(unit, gc.IsNil) 202 } 203 204 func (s *deployerSuite) TestUnitSetPassword(c *gc.C) { 205 unit, err := s.st.Unit(s.principal.Tag().(names.UnitTag)) 206 c.Assert(err, jc.ErrorIsNil) 207 208 // Change the principal's password and verify. 209 err = unit.SetPassword("foobar-12345678901234567890") 210 c.Assert(err, jc.ErrorIsNil) 211 err = s.principal.Refresh() 212 c.Assert(err, jc.ErrorIsNil) 213 c.Assert(s.principal.PasswordValid("foobar-12345678901234567890"), jc.IsTrue) 214 215 // Then the subordinate. 216 unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag)) 217 c.Assert(err, jc.ErrorIsNil) 218 err = unit.SetPassword("phony-12345678901234567890") 219 c.Assert(err, jc.ErrorIsNil) 220 err = s.subordinate.Refresh() 221 c.Assert(err, jc.ErrorIsNil) 222 c.Assert(s.subordinate.PasswordValid("phony-12345678901234567890"), jc.IsTrue) 223 } 224 225 func (s *deployerSuite) TestUnitSetStatus(c *gc.C) { 226 unit, err := s.st.Unit(s.principal.Tag().(names.UnitTag)) 227 c.Assert(err, jc.ErrorIsNil) 228 err = unit.SetStatus(status.Blocked, "waiting", map[string]interface{}{"foo": "bar"}) 229 c.Assert(err, jc.ErrorIsNil) 230 231 stateUnit, err := s.BackingState.Unit(unit.Name()) 232 c.Assert(err, jc.ErrorIsNil) 233 sInfo, err := stateUnit.Status() 234 c.Assert(err, jc.ErrorIsNil) 235 sInfo.Since = nil 236 c.Assert(sInfo, jc.DeepEquals, status.StatusInfo{ 237 Status: status.Blocked, 238 Message: "waiting", 239 Data: map[string]interface{}{"foo": "bar"}, 240 }) 241 }