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  }