github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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/names" 8 "github.com/juju/testing" 9 jc "github.com/juju/testing/checkers" 10 "github.com/juju/utils" 11 gc "gopkg.in/check.v1" 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) Migrate(params agent.MigrateParams) error { 80 mock.stub.AddCall("Migrate", params) 81 return mock.stub.NextErr() 82 } 83 84 func (mock *mockSetter) SetOldPassword(pw string) { 85 mock.stub.AddCall("SetOldPassword", pw) 86 mock.stub.PopNoErr() 87 } 88 89 func (mock *mockSetter) SetPassword(pw string) { 90 mock.stub.AddCall("SetPassword", pw) 91 mock.stub.PopNoErr() 92 } 93 94 type mockConn struct { 95 stub *testing.Stub 96 api.Connection 97 broken chan struct{} 98 } 99 100 func (mock *mockConn) ModelTag() (names.ModelTag, error) { 101 mock.stub.AddCall("ModelTag") 102 if err := mock.stub.NextErr(); err != nil { 103 return names.ModelTag{}, err 104 } 105 return coretesting.ModelTag, nil 106 } 107 108 func (mock *mockConn) Broken() <-chan struct{} { 109 return mock.broken 110 } 111 112 func (mock *mockConn) Close() error { 113 mock.stub.AddCall("Close") 114 return mock.stub.NextErr() 115 } 116 117 func newMockConnFacade(stub *testing.Stub, life apiagent.Life) apiagent.ConnFacade { 118 return &mockConnFacade{ 119 stub: stub, 120 life: life, 121 } 122 } 123 124 type mockConnFacade struct { 125 stub *testing.Stub 126 life apiagent.Life 127 } 128 129 func (mock *mockConnFacade) Life(entity names.Tag) (apiagent.Life, error) { 130 mock.stub.AddCall("Life", entity) 131 if err := mock.stub.NextErr(); err != nil { 132 return "", err 133 } 134 return mock.life, nil 135 } 136 137 func (mock *mockConnFacade) SetPassword(entity names.Tag, password string) error { 138 mock.stub.AddCall("SetPassword", entity, password) 139 return mock.stub.NextErr() 140 } 141 142 type dummyWorker struct { 143 worker.Worker 144 } 145 146 func assertStop(c *gc.C, w worker.Worker) { 147 c.Assert(worker.Stop(w), jc.ErrorIsNil) 148 } 149 150 func assertStopError(c *gc.C, w worker.Worker, match string) { 151 c.Assert(worker.Stop(w), gc.ErrorMatches, match) 152 } 153 154 func lifeTest(c *gc.C, stub *testing.Stub, life apiagent.Life, test func() (api.Connection, error)) (api.Connection, error) { 155 expectConn := &mockConn{stub: stub} 156 newFacade := func(apiCaller base.APICaller) (apiagent.ConnFacade, error) { 157 c.Check(apiCaller, jc.DeepEquals, expectConn) 158 return newMockConnFacade(stub, life), nil 159 } 160 unpatch := testing.PatchValue(apicaller.NewConnFacade, newFacade) 161 defer unpatch() 162 return test() 163 } 164 165 func strategyTest(stub *testing.Stub, strategy utils.AttemptStrategy, test func(api.OpenFunc) (api.Connection, error)) (api.Connection, error) { 166 unpatch := testing.PatchValue(apicaller.Strategy, strategy) 167 defer unpatch() 168 return test(func(info *api.Info, opts api.DialOpts) (api.Connection, error) { 169 // copy because I don't trust what might happen to info 170 stub.AddCall("apiOpen", *info, opts) 171 err := stub.NextErr() 172 if err != nil { 173 return nil, err 174 } 175 return &mockConn{stub: stub}, nil 176 }) 177 } 178 179 func checkOpenCalls(c *gc.C, stub *testing.Stub, passwords ...string) { 180 calls := openCalls(names.ModelTag{}, nil, passwords...) 181 stub.CheckCalls(c, calls) 182 } 183 184 func openCalls(model names.ModelTag, entity names.Tag, passwords ...string) []testing.StubCall { 185 calls := make([]testing.StubCall, len(passwords)) 186 for i, pw := range passwords { 187 info := api.Info{ 188 ModelTag: model, 189 Tag: entity, 190 Password: pw, 191 } 192 calls[i] = testing.StubCall{ 193 FuncName: "apiOpen", 194 Args: []interface{}{info, api.DialOpts{}}, 195 } 196 } 197 return calls 198 }