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