func (s *deployerSuite) TestUnitRemove(c *gc.C) { unit, err := s.st.Unit(s.principal.Tag().(names.UnitTag)) c.Assert(err, gc.IsNil) // It fails because the entity is still alive. // And EnsureDead will fail because there is a subordinate. err = unit.Remove() c.Assert(err, gc.ErrorMatches, `cannot remove entity "unit-mysql-0": still alive`) c.Assert(params.ErrCode(err), gc.Equals, "") // With the subordinate it also fails due to it being alive. unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag)) c.Assert(err, gc.IsNil) err = unit.Remove() c.Assert(err, gc.ErrorMatches, `cannot remove entity "unit-logging-0": still alive`) c.Assert(params.ErrCode(err), gc.Equals, "") // Make it dead first and try again. err = s.subordinate.EnsureDead() c.Assert(err, gc.IsNil) err = unit.Remove() c.Assert(err, gc.IsNil) // Verify it's gone. err = unit.Refresh() s.assertUnauthorized(c, err) unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag)) s.assertUnauthorized(c, err) c.Assert(unit, gc.IsNil) }
func (s *apiclientSuite) TestOpenPassesEnvironTag(c *gc.C) { info := s.APIInfo(c) env, err := s.State.Environment() c.Assert(err, gc.IsNil) // TODO(jam): 2014-06-05 http://pad.lv/1326802 // we want to test this eventually, but for now s.APIInfo uses // conn.StateInfo() which doesn't know about EnvironTag. // c.Check(info.EnvironTag, gc.Equals, env.Tag()) // c.Assert(info.EnvironTag, gc.Not(gc.Equals), "") // We start by ensuring we have an invalid tag, and Open should fail. info.EnvironTag = names.NewEnvironTag("bad-tag") _, err = api.Open(info, api.DialOpts{}) c.Check(err, gc.ErrorMatches, `unknown environment: "bad-tag"`) c.Check(params.ErrCode(err), gc.Equals, params.CodeNotFound) // Now set it to the right tag, and we should succeed. info.EnvironTag = env.Tag() st, err := api.Open(info, api.DialOpts{}) c.Assert(err, gc.IsNil) st.Close() // Backwards compatibility, we should succeed if we do not set an // environ tag info.EnvironTag = nil st, err = api.Open(info, api.DialOpts{}) c.Assert(err, gc.IsNil) st.Close() }
func (s *loginSuite) TestBadLogin(c *gc.C) { // Start our own server so we can control when the first login // happens. Otherwise in JujuConnSuite.SetUpTest api.Open is // called with user-admin permissions automatically. info, cleanup := s.setupServer(c) defer cleanup() for i, t := range badLoginTests { c.Logf("test %d; entity %q; password %q", i, t.tag, t.password) // Note that Open does not log in if the tag and password // are empty. This allows us to test operations on the connection // before calling Login, which we could not do if Open // always logged in. info.Tag = "" info.Password = "" func() { st, err := api.Open(info, fastDialOpts) c.Assert(err, gc.IsNil) defer st.Close() _, err = st.Machiner().Machine(names.NewMachineTag("0")) c.Assert(err, gc.ErrorMatches, `unknown object type "Machiner"`) // Since these are user login tests, the nonce is empty. err = st.Login(t.tag, t.password, "") c.Assert(err, gc.ErrorMatches, t.err) c.Assert(params.ErrCode(err), gc.Equals, t.code) _, err = st.Machiner().Machine(names.NewMachineTag("0")) c.Assert(err, gc.ErrorMatches, `unknown object type "Machiner"`) }() } }
// ServerError returns an error suitable for returning to an API // client, with an error code suitable for various kinds of errors // generated in packages outside the API. func ServerError(err error) *params.Error { if err == nil { return nil } code, ok := singletonCode(err) switch { case ok: case errors.IsUnauthorized(err): code = params.CodeUnauthorized case errors.IsNotFound(err): code = params.CodeNotFound case errors.IsAlreadyExists(err): code = params.CodeAlreadyExists case state.IsNotAssigned(err): code = params.CodeNotAssigned case state.IsHasAssignedUnitsError(err): code = params.CodeHasAssignedUnits case IsNoAddressSetError(err): code = params.CodeNoAddressSet case state.IsNotProvisionedError(err): code = params.CodeNotProvisioned case IsUnknownEnviromentError(err): code = params.CodeNotFound default: code = params.ErrCode(err) } return ¶ms.Error{ Message: err.Error(), Code: code, } }