github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/apicaller/util_test.go (about) 1 // Copyright 2015-2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package apicaller_test 5 6 import ( 7 "github.com/juju/testing" 8 jc "github.com/juju/testing/checkers" 9 "github.com/juju/utils" 10 gc "gopkg.in/check.v1" 11 "gopkg.in/juju/names.v2" 12 13 "github.com/juju/juju/agent" 14 "github.com/juju/juju/api" 15 apiagent "github.com/juju/juju/api/agent" 16 "github.com/juju/juju/api/base" 17 "github.com/juju/juju/apiserver/params" 18 coretesting "github.com/juju/juju/testing" 19 "github.com/juju/juju/worker" 20 "github.com/juju/juju/worker/apicaller" 21 ) 22 23 var errNotProvisioned = ¶ms.Error{Code: params.CodeNotProvisioned} 24 var errNotAuthorized = ¶ms.Error{Code: params.CodeUnauthorized} 25 26 type mockAgent struct { 27 agent.Agent 28 stub *testing.Stub 29 entity names.Tag 30 model names.ModelTag 31 } 32 33 func (mock *mockAgent) CurrentConfig() agent.Config { 34 return dummyConfig{ 35 entity: mock.entity, 36 model: mock.model, 37 } 38 } 39 40 func (mock *mockAgent) ChangeConfig(mutator agent.ConfigMutator) error { 41 mock.stub.AddCall("ChangeConfig") 42 if err := mock.stub.NextErr(); err != nil { 43 return err 44 } 45 return mutator(&mockSetter{stub: mock.stub}) 46 } 47 48 type dummyConfig struct { 49 agent.Config 50 entity names.Tag 51 model names.ModelTag 52 } 53 54 func (dummy dummyConfig) Tag() names.Tag { 55 return dummy.entity 56 } 57 58 func (dummy dummyConfig) Model() names.ModelTag { 59 return dummy.model 60 } 61 62 func (dummy dummyConfig) APIInfo() (*api.Info, bool) { 63 return &api.Info{ 64 ModelTag: dummy.model, 65 Tag: dummy.entity, 66 Password: "new", 67 }, true 68 } 69 70 func (dummy dummyConfig) OldPassword() string { 71 return "old" 72 } 73 74 type mockSetter struct { 75 stub *testing.Stub 76 agent.ConfigSetter 77 } 78 79 func (mock *mockSetter) SetOldPassword(pw string) { 80 mock.stub.AddCall("SetOldPassword", pw) 81 mock.stub.PopNoErr() 82 } 83 84 func (mock *mockSetter) SetPassword(pw string) { 85 mock.stub.AddCall("SetPassword", pw) 86 mock.stub.PopNoErr() 87 } 88 89 type mockConn struct { 90 stub *testing.Stub 91 api.Connection 92 controllerOnly bool 93 broken chan struct{} 94 } 95 96 func (mock *mockConn) ModelTag() (names.ModelTag, bool) { 97 mock.stub.AddCall("ModelTag") 98 if mock.controllerOnly { 99 return names.ModelTag{}, false 100 } 101 return coretesting.ModelTag, true 102 } 103 104 func (mock *mockConn) Broken() <-chan struct{} { 105 return mock.broken 106 } 107 108 func (mock *mockConn) Close() error { 109 mock.stub.AddCall("Close") 110 return mock.stub.NextErr() 111 } 112 113 func newMockConnFacade(stub *testing.Stub, life apiagent.Life) apiagent.ConnFacade { 114 return &mockConnFacade{ 115 stub: stub, 116 life: life, 117 } 118 } 119 120 type mockConnFacade struct { 121 stub *testing.Stub 122 life apiagent.Life 123 } 124 125 func (mock *mockConnFacade) Life(entity names.Tag) (apiagent.Life, error) { 126 mock.stub.AddCall("Life", entity) 127 if err := mock.stub.NextErr(); err != nil { 128 return "", err 129 } 130 return mock.life, nil 131 } 132 133 func (mock *mockConnFacade) SetPassword(entity names.Tag, password string) error { 134 mock.stub.AddCall("SetPassword", entity, password) 135 return mock.stub.NextErr() 136 } 137 138 type dummyWorker struct { 139 worker.Worker 140 } 141 142 func assertStop(c *gc.C, w worker.Worker) { 143 c.Assert(worker.Stop(w), jc.ErrorIsNil) 144 } 145 146 func assertStopError(c *gc.C, w worker.Worker, match string) { 147 c.Assert(worker.Stop(w), gc.ErrorMatches, match) 148 } 149 150 func lifeTest(c *gc.C, stub *testing.Stub, life apiagent.Life, test func() (api.Connection, error)) (api.Connection, error) { 151 newFacade := func(apiCaller base.APICaller) (apiagent.ConnFacade, error) { 152 c.Check(apiCaller, gc.FitsTypeOf, (*mockConn)(nil)) 153 return newMockConnFacade(stub, life), nil 154 } 155 unpatch := testing.PatchValue(apicaller.NewConnFacade, newFacade) 156 defer unpatch() 157 return test() 158 } 159 160 // TODO(katco): 2016-08-09: lp:1611427 161 func strategyTest(stub *testing.Stub, strategy utils.AttemptStrategy, test func(api.OpenFunc) (api.Connection, error)) (api.Connection, error) { 162 unpatch := testing.PatchValue(apicaller.Strategy, strategy) 163 defer unpatch() 164 return test(func(info *api.Info, opts api.DialOpts) (api.Connection, error) { 165 // copy because I don't trust what might happen to info 166 stub.AddCall("apiOpen", *info, opts) 167 err := stub.NextErr() 168 if err != nil { 169 return nil, err 170 } 171 return &mockConn{stub: stub}, nil 172 }) 173 } 174 175 func checkOpenCalls(c *gc.C, stub *testing.Stub, passwords ...string) { 176 calls := openCalls(names.ModelTag{}, nil, passwords...) 177 stub.CheckCalls(c, calls) 178 } 179 180 func openCalls(model names.ModelTag, entity names.Tag, passwords ...string) []testing.StubCall { 181 calls := make([]testing.StubCall, len(passwords)) 182 for i, pw := range passwords { 183 info := api.Info{ 184 ModelTag: model, 185 Tag: entity, 186 Password: pw, 187 } 188 calls[i] = testing.StubCall{ 189 FuncName: "apiOpen", 190 Args: []interface{}{info, api.DialOpts{}}, 191 } 192 } 193 return calls 194 }