github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/common/errors_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common_test 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/testing" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/environs" 15 "github.com/juju/juju/environs/context" 16 "github.com/juju/juju/provider/common" 17 ) 18 19 type ErrorsSuite struct { 20 testing.IsolationSuite 21 } 22 23 var _ = gc.Suite(&ErrorsSuite{}) 24 25 func (*ErrorsSuite) TestWrapZoneIndependentError(c *gc.C) { 26 err1 := errors.New("foo") 27 err2 := errors.Annotate(err1, "bar") 28 wrapped := environs.ZoneIndependentError(err2) 29 c.Assert(errors.Is(wrapped, environs.ErrAvailabilityZoneIndependent), jc.IsTrue) 30 c.Assert(wrapped, gc.ErrorMatches, "bar: foo") 31 } 32 33 func (s *ErrorsSuite) TestInvalidCredentialWrapped(c *gc.C) { 34 err1 := errors.New("foo") 35 err2 := errors.Annotate(err1, "bar") 36 err := common.CredentialNotValidError(err2) 37 38 // This is to confirm that Is(err, ErrorCredentialNotValid) is correct. 39 c.Assert(errors.Is(err, common.ErrorCredentialNotValid), jc.IsTrue) 40 c.Assert(err, gc.ErrorMatches, "bar: foo") 41 } 42 43 func (s *ErrorsSuite) TestCredentialNotValidErrorLocationer(c *gc.C) { 44 err := errors.New("some error") 45 err = common.CredentialNotValidError(err) 46 _, ok := err.(errors.Locationer) 47 c.Assert(ok, jc.IsTrue) 48 } 49 50 func (s *ErrorsSuite) TestInvalidCredentialNew(c *gc.C) { 51 err := fmt.Errorf("%w: Your account is blocked.", common.ErrorCredentialNotValid) 52 c.Assert(errors.Is(err, common.ErrorCredentialNotValid), jc.IsTrue) 53 c.Assert(err, gc.ErrorMatches, "credential not valid: Your account is blocked.") 54 } 55 56 func (s *ErrorsSuite) TestInvalidCredentialf(c *gc.C) { 57 err1 := errors.New("foo") 58 err := fmt.Errorf("bar: %w", common.CredentialNotValidError(err1)) 59 c.Assert(errors.Is(err, common.ErrorCredentialNotValid), jc.IsTrue) 60 c.Assert(err, gc.ErrorMatches, "bar: foo") 61 } 62 63 var authFailureError = errors.New("auth failure") 64 65 func (s *ErrorsSuite) TestNilContext(c *gc.C) { 66 isAuthF := func(e error) bool { 67 return true 68 } 69 denied := common.MaybeHandleCredentialError(isAuthF, authFailureError, nil) 70 c.Assert(c.GetTestLog(), jc.DeepEquals, "") 71 c.Assert(denied, jc.IsTrue) 72 } 73 74 func (s *ErrorsSuite) TestInvalidationCallbackErrorOnlyLogs(c *gc.C) { 75 isAuthF := func(e error) bool { 76 return true 77 } 78 ctx := context.NewEmptyCloudCallContext() 79 ctx.InvalidateCredentialFunc = func(msg string) error { 80 return errors.New("kaboom") 81 } 82 denied := common.MaybeHandleCredentialError(isAuthF, authFailureError, ctx) 83 c.Assert(c.GetTestLog(), jc.Contains, "could not invalidate stored cloud credential on the controller") 84 c.Assert(denied, jc.IsTrue) 85 } 86 87 func (s *ErrorsSuite) TestHandleCredentialErrorPermissionError(c *gc.C) { 88 s.checkPermissionHandling(c, authFailureError, true) 89 90 e := errors.Trace(authFailureError) 91 s.checkPermissionHandling(c, e, true) 92 93 e = errors.Annotatef(authFailureError, "more and more") 94 s.checkPermissionHandling(c, e, true) 95 } 96 97 func (s *ErrorsSuite) TestHandleCredentialErrorAnotherError(c *gc.C) { 98 s.checkPermissionHandling(c, errors.New("fluffy"), false) 99 } 100 101 func (s *ErrorsSuite) TestNilError(c *gc.C) { 102 s.checkPermissionHandling(c, nil, false) 103 } 104 105 func (s *ErrorsSuite) checkPermissionHandling(c *gc.C, e error, handled bool) { 106 isAuthF := func(e error) bool { 107 return handled 108 } 109 ctx := context.NewEmptyCloudCallContext() 110 called := false 111 ctx.InvalidateCredentialFunc = func(msg string) error { 112 c.Assert(msg, gc.Matches, "cloud denied access:.*auth failure") 113 called = true 114 return nil 115 } 116 117 denied := common.MaybeHandleCredentialError(isAuthF, e, ctx) 118 c.Assert(called, gc.Equals, handled) 119 c.Assert(denied, gc.Equals, handled) 120 }