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  }