launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/state/apiserver/server_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package apiserver_test 5 6 import ( 7 "launchpad.net/errgo/errors" 8 gc "launchpad.net/gocheck" 9 stdtesting "testing" 10 "time" 11 12 jujutesting "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/params" 16 "launchpad.net/juju-core/state/apiserver" 17 coretesting "launchpad.net/juju-core/testing" 18 jc "launchpad.net/juju-core/testing/checkers" 19 "launchpad.net/juju-core/utils" 20 ) 21 22 func TestAll(t *stdtesting.T) { 23 coretesting.MgoTestPackage(t) 24 } 25 26 var fastDialOpts = api.DialOpts{} 27 28 type serverSuite struct { 29 jujutesting.JujuConnSuite 30 } 31 32 var _ = gc.Suite(&serverSuite{}) 33 34 func (s *serverSuite) TestStop(c *gc.C) { 35 // Start our own instance of the server so we have 36 // a handle on it to stop it. 37 srv, err := apiserver.NewServer(s.State, "localhost:0", []byte(coretesting.ServerCert), []byte(coretesting.ServerKey), "") 38 c.Assert(err, gc.IsNil) 39 defer srv.Stop() 40 41 stm, err := s.State.AddMachine("quantal", state.JobHostUnits) 42 c.Assert(err, gc.IsNil) 43 err = stm.SetProvisioned("foo", "fake_nonce", nil) 44 c.Assert(err, gc.IsNil) 45 password, err := utils.RandomPassword() 46 c.Assert(err, gc.IsNil) 47 err = stm.SetPassword(password) 48 c.Assert(err, gc.IsNil) 49 50 // Note we can't use openAs because we're not connecting to 51 // s.APIConn. 52 apiInfo := &api.Info{ 53 Tag: stm.Tag(), 54 Password: password, 55 Nonce: "fake_nonce", 56 Addrs: []string{srv.Addr()}, 57 CACert: []byte(coretesting.CACert), 58 } 59 st, err := api.Open(apiInfo, fastDialOpts) 60 c.Assert(err, gc.IsNil) 61 defer st.Close() 62 63 _, err = st.Machiner().Machine(stm.Tag()) 64 c.Assert(err, gc.IsNil) 65 66 err = srv.Stop() 67 c.Assert(err, gc.IsNil) 68 69 _, err = st.Machiner().Machine(stm.Tag()) 70 if errors.Cause(err) != params.CodeServerShutdown { 71 c.Fatalf("unexpected error from request: %#v", err) 72 } 73 74 // Check it can be stopped twice. 75 err = srv.Stop() 76 c.Assert(err, gc.IsNil) 77 } 78 79 func (s *serverSuite) TestOpenAsMachineErrors(c *gc.C) { 80 assertNotProvisioned := func(err error) { 81 c.Assert(err, gc.NotNil) 82 c.Assert(err, jc.Satisfies, params.IsCodeNotProvisioned) 83 c.Assert(err, gc.ErrorMatches, `machine \d+ is not provisioned`) 84 } 85 stm, err := s.State.AddMachine("quantal", state.JobHostUnits) 86 c.Assert(err, gc.IsNil) 87 err = stm.SetProvisioned("foo", "fake_nonce", nil) 88 c.Assert(err, gc.IsNil) 89 password, err := utils.RandomPassword() 90 c.Assert(err, gc.IsNil) 91 err = stm.SetPassword(password) 92 c.Assert(err, gc.IsNil) 93 94 // This does almost exactly the same as OpenAPIAsMachine but checks 95 // for failures instead. 96 _, info, err := s.APIConn.Environ.StateInfo() 97 info.Tag = stm.Tag() 98 info.Password = password 99 info.Nonce = "invalid-nonce" 100 st, err := api.Open(info, fastDialOpts) 101 assertNotProvisioned(err) 102 c.Assert(st, gc.IsNil) 103 104 // Try with empty nonce as well. 105 info.Nonce = "" 106 st, err = api.Open(info, fastDialOpts) 107 assertNotProvisioned(err) 108 c.Assert(st, gc.IsNil) 109 110 // Finally, with the correct one succeeds. 111 info.Nonce = "fake_nonce" 112 st, err = api.Open(info, fastDialOpts) 113 c.Assert(err, gc.IsNil) 114 c.Assert(st, gc.NotNil) 115 st.Close() 116 117 // Now add another machine, intentionally unprovisioned. 118 stm1, err := s.State.AddMachine("quantal", state.JobHostUnits) 119 c.Assert(err, gc.IsNil) 120 err = stm1.SetPassword(password) 121 c.Assert(err, gc.IsNil) 122 123 // Try connecting, it will fail. 124 info.Tag = stm1.Tag() 125 info.Nonce = "" 126 st, err = api.Open(info, fastDialOpts) 127 assertNotProvisioned(err) 128 c.Assert(st, gc.IsNil) 129 } 130 131 func (s *serverSuite) TestMachineLoginStartsPinger(c *gc.C) { 132 // This is the same steps as OpenAPIAsNewMachine but we need to assert 133 // the agent is not alive before we actually open the API. 134 // Create a new machine to verify "agent alive" behavior. 135 machine, err := s.State.AddMachine("quantal", state.JobHostUnits) 136 c.Assert(err, gc.IsNil) 137 err = machine.SetProvisioned("foo", "fake_nonce", nil) 138 c.Assert(err, gc.IsNil) 139 password, err := utils.RandomPassword() 140 c.Assert(err, gc.IsNil) 141 err = machine.SetPassword(password) 142 c.Assert(err, gc.IsNil) 143 144 // Not alive yet. 145 s.assertAlive(c, machine, false) 146 147 // Login as the machine agent of the created machine. 148 st := s.OpenAPIAsMachine(c, machine.Tag(), password, "fake_nonce") 149 150 // Make sure the pinger has started. 151 s.assertAlive(c, machine, true) 152 153 // Now make sure it stops when connection is closed. 154 c.Assert(st.Close(), gc.IsNil) 155 156 // Sync, then wait for a bit to make sure the state is updated. 157 s.State.StartSync() 158 <-time.After(coretesting.ShortWait) 159 s.State.StartSync() 160 161 s.assertAlive(c, machine, false) 162 } 163 164 func (s *serverSuite) TestUnitLoginStartsPinger(c *gc.C) { 165 // Create a new service and unit to verify "agent alive" behavior. 166 service := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress")) 167 unit, err := service.AddUnit() 168 c.Assert(err, gc.IsNil) 169 password, err := utils.RandomPassword() 170 c.Assert(err, gc.IsNil) 171 err = unit.SetPassword(password) 172 c.Assert(err, gc.IsNil) 173 174 // Not alive yet. 175 s.assertAlive(c, unit, false) 176 177 // Login as the unit agent of the created unit. 178 st := s.OpenAPIAs(c, unit.Tag(), password) 179 180 // Make sure the pinger has started. 181 s.assertAlive(c, unit, true) 182 183 // Now make sure it stops when connection is closed. 184 c.Assert(st.Close(), gc.IsNil) 185 186 // Sync, then wait for a bit to make sure the state is updated. 187 s.State.StartSync() 188 <-time.After(coretesting.ShortWait) 189 s.State.StartSync() 190 191 s.assertAlive(c, unit, false) 192 } 193 194 type agentAliver interface { 195 AgentAlive() (bool, error) 196 } 197 198 func (s *serverSuite) assertAlive(c *gc.C, entity agentAliver, isAlive bool) { 199 s.State.StartSync() 200 alive, err := entity.AgentAlive() 201 c.Assert(err, gc.IsNil) 202 c.Assert(alive, gc.Equals, isAlive) 203 }