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