github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/caasoperatorprovisioner/mock_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package caasoperatorprovisioner_test 5 6 import ( 7 "sync" 8 9 "github.com/juju/charm/v12" 10 "github.com/juju/errors" 11 "github.com/juju/names/v5" 12 "github.com/juju/testing" 13 "github.com/juju/version/v2" 14 "gopkg.in/tomb.v2" 15 16 "github.com/juju/juju/agent" 17 "github.com/juju/juju/api/common/charms" 18 apicaasprovisioner "github.com/juju/juju/api/controller/caasoperatorprovisioner" 19 "github.com/juju/juju/caas" 20 "github.com/juju/juju/core/life" 21 "github.com/juju/juju/core/resources" 22 "github.com/juju/juju/core/watcher" 23 "github.com/juju/juju/rpc/params" 24 "github.com/juju/juju/storage" 25 coretesting "github.com/juju/juju/testing" 26 ) 27 28 type mockProvisionerFacade struct { 29 mu sync.Mutex 30 stub *testing.Stub 31 applicationsWatcher *mockStringsWatcher 32 apiWatcher *mockNotifyWatcher 33 life life.Value 34 withStorage bool 35 charmInfo *charms.CharmInfo 36 } 37 38 func newMockProvisionerFacade(stub *testing.Stub) *mockProvisionerFacade { 39 return &mockProvisionerFacade{ 40 stub: stub, 41 applicationsWatcher: newMockStringsWatcher(), 42 apiWatcher: newMockNotifyWatcher(), 43 withStorage: true, 44 charmInfo: &charms.CharmInfo{ 45 Meta: &charm.Meta{}, 46 Manifest: &charm.Manifest{}, 47 }, 48 } 49 } 50 51 func (m *mockProvisionerFacade) WatchApplications() (watcher.StringsWatcher, error) { 52 m.mu.Lock() 53 defer m.mu.Unlock() 54 m.stub.MethodCall(m, "WatchApplications") 55 if err := m.stub.NextErr(); err != nil { 56 return nil, err 57 } 58 return m.applicationsWatcher, nil 59 } 60 61 func (m *mockProvisionerFacade) OperatorProvisioningInfo(appName string) (apicaasprovisioner.OperatorProvisioningInfo, error) { 62 m.mu.Lock() 63 defer m.mu.Unlock() 64 m.stub.MethodCall(m, "OperatorProvisioningInfo", appName) 65 if err := m.stub.NextErr(); err != nil { 66 return apicaasprovisioner.OperatorProvisioningInfo{}, err 67 } 68 result := apicaasprovisioner.OperatorProvisioningInfo{ 69 ImageDetails: resources.DockerImageDetails{RegistryPath: "juju-operator-image"}, 70 Version: version.MustParse("2.99.0"), 71 APIAddresses: []string{"10.0.0.1:17070", "192.18.1.1:17070"}, 72 Tags: map[string]string{"fred": "mary"}, 73 } 74 if m.withStorage { 75 result.CharmStorage = &storage.KubernetesFilesystemParams{ 76 Provider: "kubernetes", 77 Size: uint64(1024), 78 ResourceTags: map[string]string{"foo": "bar"}, 79 Attributes: map[string]interface{}{"key": "value"}, 80 } 81 } 82 return result, nil 83 } 84 85 func (m *mockProvisionerFacade) IssueOperatorCertificate(string) (apicaasprovisioner.OperatorCertificate, error) { 86 m.mu.Lock() 87 defer m.mu.Unlock() 88 m.stub.MethodCall(m, "IssueOperatorCertificate") 89 if err := m.stub.NextErr(); err != nil { 90 return apicaasprovisioner.OperatorCertificate{}, err 91 } 92 return apicaasprovisioner.OperatorCertificate{ 93 CACert: coretesting.CACert, 94 Cert: coretesting.ServerCert, 95 PrivateKey: coretesting.ServerKey, 96 }, nil 97 } 98 99 func (m *mockProvisionerFacade) Life(entityName string) (life.Value, error) { 100 m.mu.Lock() 101 defer m.mu.Unlock() 102 m.stub.MethodCall(m, "Life", entityName) 103 if err := m.stub.NextErr(); err != nil { 104 return "", err 105 } 106 return m.life, nil 107 } 108 109 func (m *mockProvisionerFacade) ApplicationCharmInfo(appName string) (*charms.CharmInfo, error) { 110 m.mu.Lock() 111 defer m.mu.Unlock() 112 m.stub.MethodCall(m, "ApplicationCharmInfo", appName) 113 if err := m.stub.NextErr(); err != nil { 114 return nil, err 115 } 116 if m.charmInfo == nil { 117 return nil, errors.NotFoundf("charm %q", appName) 118 } 119 return m.charmInfo, nil 120 } 121 122 func (m *mockProvisionerFacade) SetPasswords(passwords []apicaasprovisioner.ApplicationPassword) (params.ErrorResults, error) { 123 m.mu.Lock() 124 defer m.mu.Unlock() 125 m.stub.MethodCall(m, "SetPasswords", passwords) 126 if err := m.stub.NextErr(); err != nil { 127 return params.ErrorResults{}, err 128 } 129 return params.ErrorResults{ 130 Results: make([]params.ErrorResult, len(passwords)), 131 }, nil 132 } 133 134 type mockAgentConfig struct { 135 agent.Config 136 } 137 138 func (m *mockAgentConfig) Controller() names.ControllerTag { 139 return coretesting.ControllerTag 140 } 141 142 func (m *mockAgentConfig) DataDir() string { 143 return "/var/lib/juju" 144 } 145 146 func (m *mockAgentConfig) LogDir() string { 147 return "/var/log/juju" 148 } 149 150 func (m *mockAgentConfig) OldPassword() string { 151 return "old password" 152 } 153 154 func (m *mockAgentConfig) CACert() string { 155 return coretesting.CACert 156 } 157 158 type mockBroker struct { 159 testing.Stub 160 caas.Broker 161 162 mu sync.Mutex 163 terminating bool 164 operatorExists bool 165 config *caas.OperatorConfig 166 } 167 168 func (m *mockBroker) setTerminating(terminating bool) { 169 m.mu.Lock() 170 defer m.mu.Unlock() 171 172 m.terminating = terminating 173 } 174 175 func (m *mockBroker) setOperatorExists(operatorExists bool) { 176 m.mu.Lock() 177 defer m.mu.Unlock() 178 179 m.operatorExists = operatorExists 180 } 181 182 func (m *mockBroker) EnsureOperator(appName, agentPath string, config *caas.OperatorConfig) error { 183 m.MethodCall(m, "EnsureOperator", appName, agentPath, config) 184 return m.NextErr() 185 } 186 187 func (m *mockBroker) OperatorExists(appName string) (caas.DeploymentState, error) { 188 m.mu.Lock() 189 defer m.mu.Unlock() 190 m.MethodCall(m, "OperatorExists", appName) 191 return caas.DeploymentState{Exists: m.operatorExists, Terminating: m.terminating}, m.NextErr() 192 } 193 194 func (m *mockBroker) DeleteOperator(appName string) error { 195 m.MethodCall(m, "DeleteOperator", appName) 196 return m.NextErr() 197 } 198 199 func (m *mockBroker) Operator(appName string) (*caas.Operator, error) { 200 m.mu.Lock() 201 defer m.mu.Unlock() 202 m.MethodCall(m, "Operator", appName) 203 err := m.NextErr() 204 if err != nil { 205 return nil, err 206 } 207 if m.operatorExists == false { 208 return nil, errors.NotFoundf("operator %s", appName) 209 } 210 return &caas.Operator{ 211 Dying: m.terminating, 212 Config: m.config, 213 }, nil 214 } 215 216 type mockWatcher struct { 217 testing.Stub 218 tomb.Tomb 219 mu sync.Mutex 220 terminated bool 221 } 222 223 func (w *mockWatcher) Kill() { 224 w.MethodCall(w, "Kill") 225 w.Tomb.Kill(nil) 226 w.mu.Lock() 227 defer w.mu.Unlock() 228 w.terminated = true 229 } 230 231 func (w *mockWatcher) Stop() error { 232 w.MethodCall(w, "Stop") 233 if err := w.NextErr(); err != nil { 234 return err 235 } 236 w.Tomb.Kill(nil) 237 return w.Tomb.Wait() 238 } 239 240 type mockStringsWatcher struct { 241 mockWatcher 242 changes chan []string 243 } 244 245 func newMockStringsWatcher() *mockStringsWatcher { 246 w := &mockStringsWatcher{changes: make(chan []string, 5)} 247 w.Tomb.Go(func() error { 248 <-w.Tomb.Dying() 249 return nil 250 }) 251 return w 252 } 253 254 func (w *mockStringsWatcher) Changes() watcher.StringsChannel { 255 return w.changes 256 } 257 258 type mockNotifyWatcher struct { 259 mockWatcher 260 changes chan struct{} 261 } 262 263 func newMockNotifyWatcher() *mockNotifyWatcher { 264 w := &mockNotifyWatcher{changes: make(chan struct{}, 5)} 265 w.Tomb.Go(func() error { 266 <-w.Tomb.Dying() 267 return nil 268 }) 269 return w 270 } 271 272 func (m *mockNotifyWatcher) Changes() watcher.NotifyChannel { 273 return m.changes 274 }