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 }