github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/agent/credentialvalidator/backend_test.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package credentialvalidator_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/testing"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  	"gopkg.in/juju/names.v2"
    12  
    13  	"github.com/juju/juju/apiserver/facades/agent/credentialvalidator"
    14  	apiservertesting "github.com/juju/juju/apiserver/testing"
    15  	"github.com/juju/juju/cloud"
    16  	"github.com/juju/juju/state"
    17  	statetesting "github.com/juju/juju/state/testing"
    18  	coretesting "github.com/juju/juju/testing"
    19  )
    20  
    21  type BackendSuite struct {
    22  	coretesting.BaseSuite
    23  
    24  	state   *mockState
    25  	backend credentialvalidator.Backend
    26  }
    27  
    28  var _ = gc.Suite(&BackendSuite{})
    29  
    30  func (s *BackendSuite) SetUpTest(c *gc.C) {
    31  	s.BaseSuite.SetUpTest(c)
    32  	s.state = newMockState()
    33  
    34  	s.backend = credentialvalidator.NewBackend(s.state)
    35  }
    36  
    37  func (s *BackendSuite) TestModelUsesCredential(c *gc.C) {
    38  	uses, err := s.backend.ModelUsesCredential(s.state.aModel.credentialTag)
    39  	c.Assert(err, jc.ErrorIsNil)
    40  	c.Assert(uses, jc.IsTrue)
    41  	s.state.CheckCallNames(c, "Model", "mockModel.CloudCredential")
    42  }
    43  
    44  func (s *BackendSuite) TestModelUsesCredentialUnset(c *gc.C) {
    45  	s.state.aModel.credentialSet = false
    46  	uses, err := s.backend.ModelUsesCredential(s.state.aModel.credentialTag)
    47  	c.Assert(err, jc.ErrorIsNil)
    48  	c.Assert(uses, jc.IsFalse)
    49  	s.state.CheckCallNames(c, "Model", "mockModel.CloudCredential")
    50  }
    51  
    52  func (s *BackendSuite) TestModelUsesCredentialWrongCredential(c *gc.C) {
    53  	uses, err := s.backend.ModelUsesCredential(names.NewCloudCredentialTag("foo/bob/two"))
    54  	c.Assert(err, jc.ErrorIsNil)
    55  	c.Assert(uses, jc.IsFalse)
    56  	s.state.CheckCallNames(c, "Model", "mockModel.CloudCredential")
    57  }
    58  
    59  func (s *BackendSuite) TestModelCredentialUnsetNotSupported(c *gc.C) {
    60  	s.state.aModel.credentialSet = false
    61  	mc, err := s.backend.ModelCredential()
    62  	c.Assert(err, jc.ErrorIsNil)
    63  	c.Assert(mc, gc.DeepEquals, &credentialvalidator.ModelCredential{
    64  		Exists:     false,
    65  		Credential: names.CloudCredentialTag{},
    66  		Valid:      false,
    67  	})
    68  	s.state.CheckCallNames(c, "Model", "mockModel.CloudCredential", "ModelTag", "Cloud", "Cloud")
    69  }
    70  
    71  func (s *BackendSuite) TestModelCredentialUnsetSupported(c *gc.C) {
    72  	s.state.aModel.credentialSet = false
    73  	s.state.aCloud.AuthTypes = cloud.AuthTypes{cloud.EmptyAuthType}
    74  	mc, err := s.backend.ModelCredential()
    75  	c.Assert(err, jc.ErrorIsNil)
    76  	c.Assert(mc, gc.DeepEquals, &credentialvalidator.ModelCredential{
    77  		Exists:     false,
    78  		Credential: names.CloudCredentialTag{},
    79  		Valid:      true,
    80  	})
    81  	s.state.CheckCallNames(c, "Model", "mockModel.CloudCredential", "ModelTag", "Cloud", "Cloud")
    82  }
    83  
    84  func (s *BackendSuite) TestModelCredentialSetButCloudCredentialNotFound(c *gc.C) {
    85  	assertValidity := func(expected bool) {
    86  		mc, err := s.backend.ModelCredential()
    87  		c.Assert(err, gc.IsNil)
    88  		c.Assert(mc, gc.DeepEquals, &credentialvalidator.ModelCredential{
    89  			Exists:     true,
    90  			Credential: s.state.aModel.credentialTag,
    91  			Valid:      expected,
    92  		})
    93  		s.state.CheckCallNames(c, "Model", "mockModel.CloudCredential", "ModelTag", "mockState.CloudCredential")
    94  		s.state.ResetCalls()
    95  	}
    96  
    97  	assertValidity(true)
    98  	s.state.SetErrors(
    99  		nil,                      // Model
   100  		errors.NotFoundf("lost"), // CloudCredential
   101  	)
   102  	assertValidity(false)
   103  }
   104  
   105  func (s *BackendSuite) TestWatchModelCredentialErr(c *gc.C) {
   106  	s.state.SetErrors(errors.New("no nope niet"))
   107  	w, err := s.backend.WatchModelCredential()
   108  	c.Assert(err, gc.ErrorMatches, "no nope niet")
   109  	c.Assert(w, gc.DeepEquals, nil)
   110  	s.state.CheckCallNames(c, "Model")
   111  }
   112  
   113  func newMockState() *mockState {
   114  	b := &mockState{
   115  		Stub:        &testing.Stub{},
   116  		aCredential: statetesting.NewEmptyCredential(),
   117  		aCloud: cloud.Cloud{
   118  			Name:      "stratus",
   119  			Type:      "low",
   120  			AuthTypes: cloud.AuthTypes{cloud.AccessKeyAuthType, cloud.UserPassAuthType},
   121  		},
   122  	}
   123  	b.aModel = &mockModel{
   124  		Stub:          b.Stub,
   125  		credentialTag: names.NewCloudCredentialTag("foo/bob/one"),
   126  		credentialSet: true,
   127  	}
   128  	return b
   129  }
   130  
   131  type mockState struct {
   132  	*testing.Stub
   133  
   134  	aCloud      cloud.Cloud
   135  	aModel      *mockModel
   136  	aCredential state.Credential
   137  }
   138  
   139  func (b *mockState) Model() (credentialvalidator.ModelAccessor, error) {
   140  	b.AddCall("Model")
   141  	if err := b.NextErr(); err != nil {
   142  		return nil, err
   143  	}
   144  	return b.aModel, nil
   145  }
   146  
   147  func (b *mockState) CloudCredential(tag names.CloudCredentialTag) (state.Credential, error) {
   148  	b.AddCall("mockState.CloudCredential", tag)
   149  	if err := b.NextErr(); err != nil {
   150  		return state.Credential{}, err
   151  	}
   152  	return b.aCredential, nil
   153  }
   154  
   155  func (b *mockState) WatchCredential(tag names.CloudCredentialTag) state.NotifyWatcher {
   156  	b.AddCall("WatchCredential", tag)
   157  	return apiservertesting.NewFakeNotifyWatcher()
   158  }
   159  
   160  func (b *mockState) InvalidateModelCredential(reason string) error {
   161  	b.AddCall("InvalidateModelCredential", reason)
   162  	return b.NextErr()
   163  }
   164  
   165  func (b *mockState) Cloud(name string) (cloud.Cloud, error) {
   166  	b.AddCall("Cloud", name)
   167  	if err := b.NextErr(); err != nil {
   168  		return cloud.Cloud{}, err
   169  	}
   170  	return b.aCloud, nil
   171  }
   172  
   173  type mockModel struct {
   174  	*testing.Stub
   175  
   176  	modelTag names.ModelTag
   177  
   178  	credentialTag names.CloudCredentialTag
   179  	credentialSet bool
   180  
   181  	cloud string
   182  }
   183  
   184  func (m *mockModel) CloudCredential() (names.CloudCredentialTag, bool) {
   185  	m.MethodCall(m, "mockModel.CloudCredential")
   186  	return m.credentialTag, m.credentialSet
   187  }
   188  
   189  func (m *mockModel) ModelTag() names.ModelTag {
   190  	m.MethodCall(m, "ModelTag")
   191  	return m.modelTag
   192  }
   193  
   194  func (m *mockModel) Cloud() string {
   195  	m.MethodCall(m, "Cloud")
   196  	return m.cloud
   197  }
   198  
   199  func (m *mockModel) WatchModelCredential() state.NotifyWatcher {
   200  	m.MethodCall(m, "WatchModelCredential")
   201  	return apiservertesting.NewFakeNotifyWatcher()
   202  }