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 }