github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/common/cloudspec/cloudspec_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cloudspec_test 5 6 import ( 7 "errors" 8 9 "github.com/juju/names/v5" 10 "github.com/juju/testing" 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils/v3" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/apiserver/common" 16 "github.com/juju/juju/apiserver/common/cloudspec" 17 apiservertesting "github.com/juju/juju/apiserver/testing" 18 "github.com/juju/juju/cloud" 19 environscloudspec "github.com/juju/juju/environs/cloudspec" 20 "github.com/juju/juju/rpc/params" 21 "github.com/juju/juju/state" 22 coretesting "github.com/juju/juju/testing" 23 ) 24 25 type CloudSpecSuite struct { 26 testing.IsolationSuite 27 testing.Stub 28 result environscloudspec.CloudSpec 29 authFunc common.AuthFunc 30 api cloudspec.CloudSpecAPI 31 } 32 33 var _ = gc.Suite(&CloudSpecSuite{}) 34 35 func (s *CloudSpecSuite) SetUpTest(c *gc.C) { 36 s.IsolationSuite.SetUpTest(c) 37 s.Stub.ResetCalls() 38 39 s.authFunc = func(tag names.Tag) bool { 40 s.AddCall("Auth", tag) 41 return tag == coretesting.ModelTag 42 } 43 s.api = s.getTestCloudSpec(apiservertesting.NewFakeNotifyWatcher()) 44 credential := cloud.NewCredential( 45 "auth-type", 46 map[string]string{"k": "v"}, 47 ) 48 s.result = environscloudspec.CloudSpec{ 49 Type: "type", 50 Name: "name", 51 Region: "region", 52 Endpoint: "endpoint", 53 IdentityEndpoint: "identity-endpoint", 54 StorageEndpoint: "storage-endpoint", 55 Credential: &credential, 56 CACertificates: []string{coretesting.CACert}, 57 SkipTLSVerify: true, 58 } 59 } 60 61 func (s *CloudSpecSuite) getTestCloudSpec(credentialContentWatcher state.NotifyWatcher) cloudspec.CloudSpecAPI { 62 return cloudspec.NewCloudSpec( 63 common.NewResources(), 64 func(tag names.ModelTag) (environscloudspec.CloudSpec, error) { 65 s.AddCall("CloudSpec", tag) 66 return s.result, s.NextErr() 67 }, 68 func(tag names.ModelTag) (state.NotifyWatcher, error) { 69 s.AddCall("WatchCloudSpec", tag) 70 return apiservertesting.NewFakeNotifyWatcher(), s.NextErr() 71 }, 72 func(tag names.ModelTag) (state.NotifyWatcher, error) { 73 s.AddCall("WatchCredentialReference", tag) 74 return apiservertesting.NewFakeNotifyWatcher(), s.NextErr() 75 }, 76 func(tag names.ModelTag) (state.NotifyWatcher, error) { 77 s.AddCall("WatchCredentialContent", tag) 78 return credentialContentWatcher, s.NextErr() 79 }, 80 func() (common.AuthFunc, error) { 81 s.AddCall("GetAuthFunc") 82 return s.authFunc, s.NextErr() 83 }) 84 } 85 86 func (s *CloudSpecSuite) TestCloudSpec(c *gc.C) { 87 otherModelTag := names.NewModelTag(utils.MustNewUUID().String()) 88 machineTag := names.NewMachineTag("42") 89 result, err := s.api.CloudSpec(params.Entities{Entities: []params.Entity{ 90 {coretesting.ModelTag.String()}, 91 {otherModelTag.String()}, 92 {machineTag.String()}, 93 }}) 94 c.Assert(err, jc.ErrorIsNil) 95 c.Assert(result.Results, jc.DeepEquals, []params.CloudSpecResult{{ 96 Result: ¶ms.CloudSpec{ 97 Type: "type", 98 Name: "name", 99 Region: "region", 100 Endpoint: "endpoint", 101 IdentityEndpoint: "identity-endpoint", 102 StorageEndpoint: "storage-endpoint", 103 Credential: ¶ms.CloudCredential{ 104 AuthType: "auth-type", 105 Attributes: map[string]string{"k": "v"}, 106 }, 107 CACertificates: []string{coretesting.CACert}, 108 SkipTLSVerify: true, 109 }, 110 }, { 111 Error: ¶ms.Error{ 112 Code: params.CodeUnauthorized, 113 Message: "permission denied", 114 }, 115 }, { 116 Error: ¶ms.Error{ 117 Message: `"machine-42" is not a valid model tag`, 118 }, 119 }}) 120 s.CheckCalls(c, []testing.StubCall{ 121 {"GetAuthFunc", nil}, 122 {"Auth", []interface{}{coretesting.ModelTag}}, 123 {"CloudSpec", []interface{}{coretesting.ModelTag}}, 124 {"Auth", []interface{}{otherModelTag}}, 125 }) 126 } 127 128 func (s *CloudSpecSuite) TestWatchCloudSpecsChanges(c *gc.C) { 129 otherModelTag := names.NewModelTag(utils.MustNewUUID().String()) 130 machineTag := names.NewMachineTag("42") 131 result, err := s.api.WatchCloudSpecsChanges(params.Entities{Entities: []params.Entity{ 132 {coretesting.ModelTag.String()}, 133 {otherModelTag.String()}, 134 {machineTag.String()}, 135 }}) 136 c.Assert(err, jc.ErrorIsNil) 137 c.Assert(result.Results, jc.DeepEquals, []params.NotifyWatchResult{{ 138 NotifyWatcherId: "1", 139 }, { 140 Error: ¶ms.Error{ 141 Code: params.CodeUnauthorized, 142 Message: "permission denied", 143 }, 144 }, { 145 Error: ¶ms.Error{ 146 Message: `"machine-42" is not a valid model tag`, 147 }, 148 }}) 149 s.CheckCalls(c, []testing.StubCall{ 150 {"GetAuthFunc", nil}, 151 {"Auth", []interface{}{coretesting.ModelTag}}, 152 {"WatchCloudSpec", []interface{}{coretesting.ModelTag}}, 153 {"WatchCredentialReference", []interface{}{coretesting.ModelTag}}, 154 {"WatchCredentialContent", []interface{}{coretesting.ModelTag}}, 155 {"Auth", []interface{}{otherModelTag}}, 156 }) 157 } 158 159 func (s *CloudSpecSuite) TestWatchCloudSpecsNoCredentialContentToWatch(c *gc.C) { 160 s.api = s.getTestCloudSpec(nil) 161 result, err := s.api.WatchCloudSpecsChanges(params.Entities{Entities: []params.Entity{ 162 {coretesting.ModelTag.String()}, 163 }}) 164 c.Assert(err, jc.ErrorIsNil) 165 c.Assert(result.Results, jc.DeepEquals, []params.NotifyWatchResult{{ 166 NotifyWatcherId: "1", 167 }}) 168 s.CheckCalls(c, []testing.StubCall{ 169 {"GetAuthFunc", nil}, 170 {"Auth", []interface{}{coretesting.ModelTag}}, 171 {"WatchCloudSpec", []interface{}{coretesting.ModelTag}}, 172 {"WatchCredentialReference", []interface{}{coretesting.ModelTag}}, 173 {"WatchCredentialContent", []interface{}{coretesting.ModelTag}}, 174 }) 175 } 176 177 func (s *CloudSpecSuite) TestCloudSpecNilCredential(c *gc.C) { 178 s.result.Credential = nil 179 result, err := s.api.CloudSpec(params.Entities{ 180 Entities: []params.Entity{{coretesting.ModelTag.String()}}, 181 }) 182 c.Assert(err, jc.ErrorIsNil) 183 c.Assert(result.Results, jc.DeepEquals, []params.CloudSpecResult{{ 184 Result: ¶ms.CloudSpec{ 185 Type: "type", 186 Name: "name", 187 Region: "region", 188 Endpoint: "endpoint", 189 IdentityEndpoint: "identity-endpoint", 190 StorageEndpoint: "storage-endpoint", 191 Credential: nil, 192 CACertificates: []string{coretesting.CACert}, 193 SkipTLSVerify: true, 194 }, 195 }}) 196 } 197 198 func (s *CloudSpecSuite) TestCloudSpecGetAuthFuncError(c *gc.C) { 199 expect := errors.New("bewm") 200 s.SetErrors(expect) 201 result, err := s.api.CloudSpec(params.Entities{ 202 Entities: []params.Entity{{coretesting.ModelTag.String()}}, 203 }) 204 c.Assert(err, gc.Equals, expect) 205 c.Assert(result, jc.DeepEquals, params.CloudSpecResults{}) 206 } 207 208 func (s *CloudSpecSuite) TestCloudSpecCloudSpecError(c *gc.C) { 209 s.SetErrors(nil, errors.New("bewm")) 210 result, err := s.api.CloudSpec(params.Entities{ 211 Entities: []params.Entity{{coretesting.ModelTag.String()}}, 212 }) 213 c.Assert(err, jc.ErrorIsNil) 214 c.Assert(result, jc.DeepEquals, params.CloudSpecResults{Results: []params.CloudSpecResult{{ 215 Error: ¶ms.Error{Message: "bewm"}, 216 }}}) 217 }