github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/worker/uniter/operation/runaction_test.go (about)

     1  // Copyright 2014 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  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  	"gopkg.in/juju/charm.v5/hooks"
    12  
    13  	"github.com/juju/juju/worker/uniter/hook"
    14  	"github.com/juju/juju/worker/uniter/operation"
    15  	"github.com/juju/juju/worker/uniter/runner"
    16  )
    17  
    18  type RunActionSuite struct {
    19  	testing.IsolationSuite
    20  }
    21  
    22  var _ = gc.Suite(&RunActionSuite{})
    23  
    24  func (s *RunActionSuite) TestPrepareErrorBadActionAndFailSucceeds(c *gc.C) {
    25  	errBadAction := runner.NewBadActionError("some-action-id", "splat")
    26  	runnerFactory := &MockRunnerFactory{
    27  		MockNewActionRunner: &MockNewActionRunner{err: errBadAction},
    28  	}
    29  	callbacks := &RunActionCallbacks{
    30  		MockFailAction: &MockFailAction{err: errors.New("squelch")},
    31  	}
    32  	factory := operation.NewFactory(nil, runnerFactory, callbacks, nil, nil)
    33  	op, err := factory.NewAction(someActionId)
    34  	c.Assert(err, jc.ErrorIsNil)
    35  
    36  	newState, err := op.Prepare(operation.State{})
    37  	c.Assert(newState, gc.IsNil)
    38  	c.Assert(err, gc.ErrorMatches, "squelch")
    39  	c.Assert(*runnerFactory.MockNewActionRunner.gotActionId, gc.Equals, someActionId)
    40  	c.Assert(*callbacks.MockFailAction.gotActionId, gc.Equals, someActionId)
    41  	c.Assert(*callbacks.MockFailAction.gotMessage, gc.Equals, errBadAction.Error())
    42  }
    43  
    44  func (s *RunActionSuite) TestPrepareErrorBadActionAndFailErrors(c *gc.C) {
    45  	errBadAction := runner.NewBadActionError("some-action-id", "foof")
    46  	runnerFactory := &MockRunnerFactory{
    47  		MockNewActionRunner: &MockNewActionRunner{err: errBadAction},
    48  	}
    49  	callbacks := &RunActionCallbacks{
    50  		MockFailAction: &MockFailAction{},
    51  	}
    52  	factory := operation.NewFactory(nil, runnerFactory, callbacks, nil, nil)
    53  	op, err := factory.NewAction(someActionId)
    54  	c.Assert(err, jc.ErrorIsNil)
    55  
    56  	newState, err := op.Prepare(operation.State{})
    57  	c.Assert(newState, gc.IsNil)
    58  	c.Assert(err, gc.Equals, operation.ErrSkipExecute)
    59  	c.Assert(*runnerFactory.MockNewActionRunner.gotActionId, gc.Equals, someActionId)
    60  	c.Assert(*callbacks.MockFailAction.gotActionId, gc.Equals, someActionId)
    61  	c.Assert(*callbacks.MockFailAction.gotMessage, gc.Equals, errBadAction.Error())
    62  }
    63  
    64  func (s *RunActionSuite) TestPrepareErrorActionNotAvailable(c *gc.C) {
    65  	runnerFactory := &MockRunnerFactory{
    66  		MockNewActionRunner: &MockNewActionRunner{err: runner.ErrActionNotAvailable},
    67  	}
    68  	factory := operation.NewFactory(nil, runnerFactory, nil, nil, nil)
    69  	op, err := factory.NewAction(someActionId)
    70  	c.Assert(err, jc.ErrorIsNil)
    71  
    72  	newState, err := op.Prepare(operation.State{})
    73  	c.Assert(newState, gc.IsNil)
    74  	c.Assert(err, gc.Equals, operation.ErrSkipExecute)
    75  	c.Assert(*runnerFactory.MockNewActionRunner.gotActionId, gc.Equals, someActionId)
    76  }
    77  
    78  func (s *RunActionSuite) TestPrepareErrorOther(c *gc.C) {
    79  	runnerFactory := &MockRunnerFactory{
    80  		MockNewActionRunner: &MockNewActionRunner{err: errors.New("foop")},
    81  	}
    82  	factory := operation.NewFactory(nil, runnerFactory, nil, nil, nil)
    83  	op, err := factory.NewAction(someActionId)
    84  	c.Assert(err, jc.ErrorIsNil)
    85  
    86  	newState, err := op.Prepare(operation.State{})
    87  	c.Assert(newState, gc.IsNil)
    88  	c.Assert(err, gc.ErrorMatches, `cannot create runner for action ".*": foop`)
    89  	c.Assert(*runnerFactory.MockNewActionRunner.gotActionId, gc.Equals, someActionId)
    90  }
    91  
    92  func (s *RunActionSuite) TestPrepareSuccessCleanState(c *gc.C) {
    93  	runnerFactory := NewRunActionRunnerFactory(errors.New("should not call"))
    94  	factory := operation.NewFactory(nil, runnerFactory, nil, nil, nil)
    95  	op, err := factory.NewAction(someActionId)
    96  	c.Assert(err, jc.ErrorIsNil)
    97  
    98  	newState, err := op.Prepare(operation.State{})
    99  	c.Assert(err, jc.ErrorIsNil)
   100  	c.Assert(newState, jc.DeepEquals, &operation.State{
   101  		Kind:     operation.RunAction,
   102  		Step:     operation.Pending,
   103  		ActionId: &someActionId,
   104  	})
   105  	c.Assert(*runnerFactory.MockNewActionRunner.gotActionId, gc.Equals, someActionId)
   106  }
   107  
   108  func (s *RunActionSuite) TestPrepareSuccessDirtyState(c *gc.C) {
   109  	runnerFactory := NewRunActionRunnerFactory(errors.New("should not call"))
   110  	factory := operation.NewFactory(nil, runnerFactory, nil, nil, nil)
   111  	op, err := factory.NewAction(someActionId)
   112  	c.Assert(err, jc.ErrorIsNil)
   113  
   114  	newState, err := op.Prepare(overwriteState)
   115  	c.Assert(err, jc.ErrorIsNil)
   116  	c.Assert(newState, jc.DeepEquals, &operation.State{
   117  		Kind:               operation.RunAction,
   118  		Step:               operation.Pending,
   119  		ActionId:           &someActionId,
   120  		Started:            true,
   121  		CollectMetricsTime: 1234567,
   122  		UpdateStatusTime:   1234567,
   123  		Hook:               &hook.Info{Kind: hooks.Install},
   124  	})
   125  	c.Assert(*runnerFactory.MockNewActionRunner.gotActionId, gc.Equals, someActionId)
   126  }
   127  
   128  func (s *RunActionSuite) TestExecuteSuccess(c *gc.C) {
   129  	var stateChangeTests = []struct {
   130  		description string
   131  		before      operation.State
   132  		after       operation.State
   133  	}{{
   134  		description: "empty state",
   135  		after: operation.State{
   136  			Kind:     operation.RunAction,
   137  			Step:     operation.Done,
   138  			ActionId: &someActionId,
   139  		},
   140  	}, {
   141  		description: "preserves appropriate fields",
   142  		before:      overwriteState,
   143  		after: operation.State{
   144  			Kind:               operation.RunAction,
   145  			Step:               operation.Done,
   146  			ActionId:           &someActionId,
   147  			Hook:               &hook.Info{Kind: hooks.Install},
   148  			Started:            true,
   149  			CollectMetricsTime: 1234567,
   150  			UpdateStatusTime:   1234567,
   151  		},
   152  	}}
   153  
   154  	for i, test := range stateChangeTests {
   155  		c.Logf("test %d: %s", i, test.description)
   156  		runnerFactory := NewRunActionRunnerFactory(nil)
   157  		callbacks := &RunActionCallbacks{}
   158  		factory := operation.NewFactory(nil, runnerFactory, callbacks, nil, nil)
   159  		op, err := factory.NewAction(someActionId)
   160  		c.Assert(err, jc.ErrorIsNil)
   161  		midState, err := op.Prepare(test.before)
   162  		c.Assert(midState, gc.NotNil)
   163  		c.Assert(err, jc.ErrorIsNil)
   164  
   165  		newState, err := op.Execute(*midState)
   166  		c.Assert(err, jc.ErrorIsNil)
   167  		c.Assert(newState, jc.DeepEquals, &test.after)
   168  		c.Assert(callbacks.executingMessage, gc.Equals, "running action some-action-name")
   169  		c.Assert(*runnerFactory.MockNewActionRunner.runner.MockRunAction.gotName, gc.Equals, "some-action-name")
   170  	}
   171  }
   172  
   173  func (s *RunActionSuite) TestCommit(c *gc.C) {
   174  	var stateChangeTests = []struct {
   175  		description string
   176  		before      operation.State
   177  		after       operation.State
   178  	}{{
   179  		description: "empty state",
   180  		after: operation.State{
   181  			Kind: operation.Continue,
   182  			Step: operation.Pending,
   183  		},
   184  	}, {
   185  		description: "preserves only appropriate fields, no hook",
   186  		before: operation.State{
   187  			Kind:               operation.Continue,
   188  			Step:               operation.Pending,
   189  			Started:            true,
   190  			CollectMetricsTime: 1234567,
   191  			UpdateStatusTime:   1234567,
   192  			CharmURL:           curl("cs:quantal/wordpress-2"),
   193  			ActionId:           &randomActionId,
   194  		},
   195  		after: operation.State{
   196  			Kind:               operation.Continue,
   197  			Step:               operation.Pending,
   198  			Started:            true,
   199  			CollectMetricsTime: 1234567,
   200  			UpdateStatusTime:   1234567,
   201  		},
   202  	}, {
   203  		description: "preserves only appropriate fields, with hook",
   204  		before: operation.State{
   205  			Kind:               operation.Continue,
   206  			Step:               operation.Pending,
   207  			Started:            true,
   208  			CollectMetricsTime: 1234567,
   209  			UpdateStatusTime:   1234567,
   210  			CharmURL:           curl("cs:quantal/wordpress-2"),
   211  			ActionId:           &randomActionId,
   212  			Hook:               &hook.Info{Kind: hooks.Install},
   213  		},
   214  		after: operation.State{
   215  			Kind:               operation.RunHook,
   216  			Step:               operation.Pending,
   217  			Hook:               &hook.Info{Kind: hooks.Install},
   218  			Started:            true,
   219  			CollectMetricsTime: 1234567,
   220  			UpdateStatusTime:   1234567,
   221  		},
   222  	}}
   223  
   224  	for i, test := range stateChangeTests {
   225  		c.Logf("test %d: %s", i, test.description)
   226  		factory := operation.NewFactory(nil, nil, nil, nil, nil)
   227  		op, err := factory.NewAction(someActionId)
   228  		c.Assert(err, jc.ErrorIsNil)
   229  
   230  		newState, err := op.Commit(test.before)
   231  		c.Assert(newState, jc.DeepEquals, &test.after)
   232  	}
   233  }
   234  
   235  func (s *RunActionSuite) TestNeedsGlobalMachineLock(c *gc.C) {
   236  	factory := operation.NewFactory(nil, nil, nil, nil, nil)
   237  	op, err := factory.NewAction(someActionId)
   238  	c.Assert(err, jc.ErrorIsNil)
   239  	c.Assert(op.NeedsGlobalMachineLock(), jc.IsTrue)
   240  }