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