github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/worker/uniter/operation/util_test.go (about) 1 // Copyright 2014-2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package operation_test 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/testing" 9 utilexec "github.com/juju/utils/exec" 10 corecharm "gopkg.in/juju/charm.v5" 11 "gopkg.in/juju/charm.v5/hooks" 12 13 "github.com/juju/juju/worker/uniter/charm" 14 "github.com/juju/juju/worker/uniter/hook" 15 "github.com/juju/juju/worker/uniter/operation" 16 "github.com/juju/juju/worker/uniter/runner" 17 "github.com/juju/juju/worker/uniter/runner/jujuc" 18 ) 19 20 type MockGetArchiveInfo struct { 21 gotCharmURL *corecharm.URL 22 info charm.BundleInfo 23 err error 24 } 25 26 func (mock *MockGetArchiveInfo) Call(charmURL *corecharm.URL) (charm.BundleInfo, error) { 27 mock.gotCharmURL = charmURL 28 return mock.info, mock.err 29 } 30 31 type MockSetCurrentCharm struct { 32 gotCharmURL *corecharm.URL 33 err error 34 } 35 36 func (mock *MockSetCurrentCharm) Call(charmURL *corecharm.URL) error { 37 mock.gotCharmURL = charmURL 38 return mock.err 39 } 40 41 type DeployCallbacks struct { 42 operation.Callbacks 43 *MockGetArchiveInfo 44 *MockSetCurrentCharm 45 MockClearResolvedFlag *MockNoArgs 46 MockInitializeMetricsTimers *MockNoArgs 47 } 48 49 func (cb *DeployCallbacks) GetArchiveInfo(charmURL *corecharm.URL) (charm.BundleInfo, error) { 50 return cb.MockGetArchiveInfo.Call(charmURL) 51 } 52 53 func (cb *DeployCallbacks) SetCurrentCharm(charmURL *corecharm.URL) error { 54 return cb.MockSetCurrentCharm.Call(charmURL) 55 } 56 57 func (cb *DeployCallbacks) ClearResolvedFlag() error { 58 return cb.MockClearResolvedFlag.Call() 59 } 60 61 func (cb *DeployCallbacks) InitializeMetricsTimers() error { 62 return cb.MockInitializeMetricsTimers.Call() 63 } 64 65 type MockBundleInfo struct { 66 charm.BundleInfo 67 } 68 69 type MockStage struct { 70 gotInfo *charm.BundleInfo 71 gotAbort *<-chan struct{} 72 err error 73 } 74 75 func (mock *MockStage) Call(info charm.BundleInfo, abort <-chan struct{}) error { 76 mock.gotInfo = &info 77 mock.gotAbort = &abort 78 return mock.err 79 } 80 81 type MockNoArgs struct { 82 called bool 83 err error 84 } 85 86 func (mock *MockNoArgs) Call() error { 87 mock.called = true 88 return mock.err 89 } 90 91 type MockDeployer struct { 92 charm.Deployer 93 *MockStage 94 MockDeploy *MockNoArgs 95 MockNotifyRevert *MockNoArgs 96 MockNotifyResolved *MockNoArgs 97 } 98 99 func (d *MockDeployer) Stage(info charm.BundleInfo, abort <-chan struct{}) error { 100 return d.MockStage.Call(info, abort) 101 } 102 103 func (d *MockDeployer) Deploy() error { 104 return d.MockDeploy.Call() 105 } 106 107 func (d *MockDeployer) NotifyRevert() error { 108 return d.MockNotifyRevert.Call() 109 } 110 111 func (d *MockDeployer) NotifyResolved() error { 112 return d.MockNotifyResolved.Call() 113 } 114 115 type MockFailAction struct { 116 gotActionId *string 117 gotMessage *string 118 err error 119 } 120 121 func (mock *MockFailAction) Call(actionId, message string) error { 122 mock.gotActionId = &actionId 123 mock.gotMessage = &message 124 return mock.err 125 } 126 127 type RunActionCallbacks struct { 128 operation.Callbacks 129 *MockFailAction 130 executingMessage string 131 } 132 133 func (cb *RunActionCallbacks) FailAction(actionId, message string) error { 134 return cb.MockFailAction.Call(actionId, message) 135 } 136 137 func (cb *RunActionCallbacks) SetExecutingStatus(message string) error { 138 cb.executingMessage = message 139 return nil 140 } 141 142 type RunCommandsCallbacks struct { 143 operation.Callbacks 144 executingMessage string 145 } 146 147 func (cb *RunCommandsCallbacks) SetExecutingStatus(message string) error { 148 cb.executingMessage = message 149 return nil 150 } 151 152 type MockPrepareHook struct { 153 gotHook *hook.Info 154 name string 155 err error 156 } 157 158 func (mock *MockPrepareHook) Call(hookInfo hook.Info) (string, error) { 159 mock.gotHook = &hookInfo 160 return mock.name, mock.err 161 } 162 163 type PrepareHookCallbacks struct { 164 operation.Callbacks 165 *MockPrepareHook 166 MockClearResolvedFlag *MockNoArgs 167 executingMessage string 168 } 169 170 func (cb *PrepareHookCallbacks) PrepareHook(hookInfo hook.Info) (string, error) { 171 return cb.MockPrepareHook.Call(hookInfo) 172 } 173 174 func (cb *PrepareHookCallbacks) ClearResolvedFlag() error { 175 return cb.MockClearResolvedFlag.Call() 176 } 177 178 func (cb *PrepareHookCallbacks) SetExecutingStatus(message string) error { 179 cb.executingMessage = message 180 return nil 181 } 182 183 type MockNotify struct { 184 gotName *string 185 gotContext *runner.Context 186 } 187 188 func (mock *MockNotify) Call(hookName string, ctx runner.Context) { 189 mock.gotName = &hookName 190 mock.gotContext = &ctx 191 } 192 193 type ExecuteHookCallbacks struct { 194 *PrepareHookCallbacks 195 MockNotifyHookCompleted *MockNotify 196 MockNotifyHookFailed *MockNotify 197 } 198 199 func (cb *ExecuteHookCallbacks) NotifyHookCompleted(hookName string, ctx runner.Context) { 200 cb.MockNotifyHookCompleted.Call(hookName, ctx) 201 } 202 203 func (cb *ExecuteHookCallbacks) NotifyHookFailed(hookName string, ctx runner.Context) { 204 cb.MockNotifyHookFailed.Call(hookName, ctx) 205 } 206 207 type MockCommitHook struct { 208 gotHook *hook.Info 209 err error 210 } 211 212 func (mock *MockCommitHook) Call(hookInfo hook.Info) error { 213 mock.gotHook = &hookInfo 214 return mock.err 215 } 216 217 type CommitHookCallbacks struct { 218 operation.Callbacks 219 *MockCommitHook 220 } 221 222 func (cb *CommitHookCallbacks) CommitHook(hookInfo hook.Info) error { 223 return cb.MockCommitHook.Call(hookInfo) 224 } 225 226 type MockUpdateRelations struct { 227 gotIds *[]int 228 err error 229 } 230 231 func (mock *MockUpdateRelations) Call(ids []int) error { 232 mock.gotIds = &ids 233 return mock.err 234 } 235 236 type UpdateRelationsCallbacks struct { 237 operation.Callbacks 238 *MockUpdateRelations 239 } 240 241 func (cb *UpdateRelationsCallbacks) UpdateRelations(ids []int) error { 242 return cb.MockUpdateRelations.Call(ids) 243 } 244 245 type MockNewActionRunner struct { 246 gotActionId *string 247 runner *MockRunner 248 err error 249 } 250 251 func (mock *MockNewActionRunner) Call(actionId string) (runner.Runner, error) { 252 mock.gotActionId = &actionId 253 return mock.runner, mock.err 254 } 255 256 type MockNewHookRunner struct { 257 gotHook *hook.Info 258 runner *MockRunner 259 err error 260 } 261 262 func (mock *MockNewHookRunner) Call(hookInfo hook.Info) (runner.Runner, error) { 263 mock.gotHook = &hookInfo 264 return mock.runner, mock.err 265 } 266 267 type MockNewCommandRunner struct { 268 gotInfo *runner.CommandInfo 269 runner *MockRunner 270 err error 271 } 272 273 func (mock *MockNewCommandRunner) Call(info runner.CommandInfo) (runner.Runner, error) { 274 mock.gotInfo = &info 275 return mock.runner, mock.err 276 } 277 278 type MockRunnerFactory struct { 279 *MockNewActionRunner 280 *MockNewHookRunner 281 *MockNewCommandRunner 282 } 283 284 func (f *MockRunnerFactory) NewActionRunner(actionId string) (runner.Runner, error) { 285 return f.MockNewActionRunner.Call(actionId) 286 } 287 288 func (f *MockRunnerFactory) NewHookRunner(hookInfo hook.Info) (runner.Runner, error) { 289 return f.MockNewHookRunner.Call(hookInfo) 290 } 291 292 func (f *MockRunnerFactory) NewCommandRunner(commandInfo runner.CommandInfo) (runner.Runner, error) { 293 return f.MockNewCommandRunner.Call(commandInfo) 294 } 295 296 type MockContext struct { 297 runner.Context 298 testing.Stub 299 actionData *runner.ActionData 300 setStatusCalled bool 301 status jujuc.StatusInfo 302 } 303 304 func (mock *MockContext) ActionData() (*runner.ActionData, error) { 305 if mock.actionData == nil { 306 return nil, errors.New("not an action context") 307 } 308 return mock.actionData, nil 309 } 310 311 func (mock *MockContext) HasExecutionSetUnitStatus() bool { 312 return mock.setStatusCalled 313 } 314 315 func (mock *MockContext) ResetExecutionSetUnitStatus() { 316 mock.setStatusCalled = false 317 } 318 319 func (mock *MockContext) SetUnitStatus(status jujuc.StatusInfo) error { 320 mock.setStatusCalled = true 321 mock.status = status 322 return nil 323 } 324 325 func (mock *MockContext) UnitStatus() (*jujuc.StatusInfo, error) { 326 return &mock.status, nil 327 } 328 329 func (mock *MockContext) Prepare() error { 330 mock.MethodCall(mock, "Prepare") 331 return mock.NextErr() 332 } 333 334 type MockRunAction struct { 335 gotName *string 336 err error 337 } 338 339 func (mock *MockRunAction) Call(actionName string) error { 340 mock.gotName = &actionName 341 return mock.err 342 } 343 344 type MockRunCommands struct { 345 gotCommands *string 346 response *utilexec.ExecResponse 347 err error 348 } 349 350 func (mock *MockRunCommands) Call(commands string) (*utilexec.ExecResponse, error) { 351 mock.gotCommands = &commands 352 return mock.response, mock.err 353 } 354 355 type MockRunHook struct { 356 gotName *string 357 err error 358 setStatusCalled bool 359 } 360 361 func (mock *MockRunHook) Call(hookName string) error { 362 mock.gotName = &hookName 363 return mock.err 364 } 365 366 type MockRunner struct { 367 *MockRunAction 368 *MockRunCommands 369 *MockRunHook 370 context runner.Context 371 } 372 373 func (r *MockRunner) Context() runner.Context { 374 return r.context 375 } 376 377 func (r *MockRunner) RunAction(actionName string) error { 378 return r.MockRunAction.Call(actionName) 379 } 380 381 func (r *MockRunner) RunCommands(commands string) (*utilexec.ExecResponse, error) { 382 return r.MockRunCommands.Call(commands) 383 } 384 385 func (r *MockRunner) RunHook(hookName string) error { 386 r.Context().(*MockContext).setStatusCalled = r.MockRunHook.setStatusCalled 387 return r.MockRunHook.Call(hookName) 388 } 389 390 func NewDeployCallbacks() *DeployCallbacks { 391 return &DeployCallbacks{ 392 MockGetArchiveInfo: &MockGetArchiveInfo{info: &MockBundleInfo{}}, 393 MockSetCurrentCharm: &MockSetCurrentCharm{}, 394 MockClearResolvedFlag: &MockNoArgs{}, 395 } 396 } 397 398 func NewDeployCommitCallbacks(err error) *DeployCallbacks { 399 return &DeployCallbacks{ 400 MockInitializeMetricsTimers: &MockNoArgs{err: err}, 401 } 402 } 403 func NewMockDeployer() *MockDeployer { 404 return &MockDeployer{ 405 MockStage: &MockStage{}, 406 MockDeploy: &MockNoArgs{}, 407 MockNotifyRevert: &MockNoArgs{}, 408 MockNotifyResolved: &MockNoArgs{}, 409 } 410 } 411 412 func NewPrepareHookCallbacks() *PrepareHookCallbacks { 413 return &PrepareHookCallbacks{ 414 MockPrepareHook: &MockPrepareHook{nil, "some-hook-name", nil}, 415 MockClearResolvedFlag: &MockNoArgs{}, 416 } 417 } 418 419 func NewRunActionRunnerFactory(runErr error) *MockRunnerFactory { 420 return &MockRunnerFactory{ 421 MockNewActionRunner: &MockNewActionRunner{ 422 runner: &MockRunner{ 423 MockRunAction: &MockRunAction{err: runErr}, 424 context: &MockContext{ 425 actionData: &runner.ActionData{Name: "some-action-name"}, 426 }, 427 }, 428 }, 429 } 430 } 431 432 func NewRunCommandsRunnerFactory(runResponse *utilexec.ExecResponse, runErr error) *MockRunnerFactory { 433 return &MockRunnerFactory{ 434 MockNewCommandRunner: &MockNewCommandRunner{ 435 runner: &MockRunner{ 436 MockRunCommands: &MockRunCommands{response: runResponse, err: runErr}, 437 context: &MockContext{}, 438 }, 439 }, 440 } 441 } 442 443 func NewRunHookRunnerFactory(runErr error) *MockRunnerFactory { 444 return &MockRunnerFactory{ 445 MockNewHookRunner: &MockNewHookRunner{ 446 runner: &MockRunner{ 447 MockRunHook: &MockRunHook{err: runErr}, 448 context: &MockContext{}, 449 }, 450 }, 451 } 452 } 453 454 type MockSendResponse struct { 455 gotResponse **utilexec.ExecResponse 456 gotErr *error 457 } 458 459 func (mock *MockSendResponse) Call(response *utilexec.ExecResponse, err error) { 460 mock.gotResponse = &response 461 mock.gotErr = &err 462 } 463 464 var curl = corecharm.MustParseURL 465 var someActionId = "f47ac10b-58cc-4372-a567-0e02b2c3d479" 466 var randomActionId = "9f484882-2f18-4fd2-967d-db9663db7bea" 467 var overwriteState = operation.State{ 468 Kind: operation.Continue, 469 Step: operation.Pending, 470 Started: true, 471 CollectMetricsTime: 1234567, 472 UpdateStatusTime: 1234567, 473 CharmURL: curl("cs:quantal/wordpress-2"), 474 ActionId: &randomActionId, 475 Hook: &hook.Info{Kind: hooks.Install}, 476 } 477 var someCommandArgs = operation.CommandArgs{ 478 Commands: "do something", 479 RelationId: 123, 480 RemoteUnitName: "foo/456", 481 ForceRemoteUnit: true, 482 }