github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/uniter/operation/runcommands_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 utilexec "github.com/juju/utils/v3/exec" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/worker/uniter/operation" 14 "github.com/juju/juju/worker/uniter/runner" 15 "github.com/juju/juju/worker/uniter/runner/context" 16 ) 17 18 type RunCommandsSuite struct { 19 testing.IsolationSuite 20 } 21 22 var _ = gc.Suite(&RunCommandsSuite{}) 23 24 func (s *RunCommandsSuite) TestPrepareError(c *gc.C) { 25 runnerFactory := &MockRunnerFactory{ 26 MockNewCommandRunner: &MockNewCommandRunner{err: errors.New("blooey")}, 27 } 28 factory := newOpFactory(runnerFactory, nil) 29 sendResponse := func(*utilexec.ExecResponse, error) bool { panic("not expected") } 30 op, err := factory.NewCommands(someCommandArgs, sendResponse) 31 c.Assert(err, jc.ErrorIsNil) 32 33 newState, err := op.Prepare(operation.State{}) 34 c.Assert(err, gc.ErrorMatches, "blooey") 35 c.Assert(newState, gc.IsNil) 36 c.Assert(*runnerFactory.MockNewCommandRunner.gotInfo, gc.Equals, context.CommandInfo{ 37 RelationId: 123, 38 RemoteUnitName: "foo/456", 39 ForceRemoteUnit: true, 40 }) 41 } 42 43 func (s *RunCommandsSuite) TestPrepareSuccess(c *gc.C) { 44 ctx := &MockContext{} 45 runnerFactory := &MockRunnerFactory{ 46 MockNewCommandRunner: &MockNewCommandRunner{ 47 runner: &MockRunner{ 48 context: ctx, 49 }, 50 }, 51 } 52 factory := newOpFactory(runnerFactory, nil) 53 sendResponse := func(*utilexec.ExecResponse, error) bool { panic("not expected") } 54 op, err := factory.NewCommands(someCommandArgs, sendResponse) 55 c.Assert(err, jc.ErrorIsNil) 56 57 newState, err := op.Prepare(operation.State{}) 58 c.Assert(err, jc.ErrorIsNil) 59 c.Assert(newState, gc.IsNil) 60 c.Assert(*runnerFactory.MockNewCommandRunner.gotInfo, gc.Equals, context.CommandInfo{ 61 RelationId: 123, 62 RemoteUnitName: "foo/456", 63 ForceRemoteUnit: true, 64 }) 65 ctx.CheckCall(c, 0, "Prepare") 66 } 67 68 func (s *RunCommandsSuite) TestPrepareCtxError(c *gc.C) { 69 ctx := &MockContext{} 70 ctx.SetErrors(errors.New("ctx prepare error")) 71 runnerFactory := &MockRunnerFactory{ 72 MockNewCommandRunner: &MockNewCommandRunner{ 73 runner: &MockRunner{ 74 context: ctx, 75 }, 76 }, 77 } 78 factory := newOpFactory(runnerFactory, nil) 79 sendResponse := func(*utilexec.ExecResponse, error) bool { panic("not expected") } 80 op, err := factory.NewCommands(someCommandArgs, sendResponse) 81 c.Assert(err, jc.ErrorIsNil) 82 83 newState, err := op.Prepare(operation.State{}) 84 c.Assert(err, gc.ErrorMatches, "ctx prepare error") 85 c.Assert(newState, gc.IsNil) 86 ctx.CheckCall(c, 0, "Prepare") 87 } 88 89 func (s *RunCommandsSuite) TestExecuteRebootErrors(c *gc.C) { 90 for _, sendErr := range []error{context.ErrRequeueAndReboot, context.ErrReboot} { 91 runnerFactory := NewRunCommandsRunnerFactory( 92 &utilexec.ExecResponse{Code: 101}, sendErr, 93 ) 94 callbacks := &RunCommandsCallbacks{} 95 factory := newOpFactory(runnerFactory, callbacks) 96 sendResponse := &MockSendResponse{} 97 op, err := factory.NewCommands(someCommandArgs, sendResponse.Call) 98 c.Assert(err, jc.ErrorIsNil) 99 _, err = op.Prepare(operation.State{}) 100 c.Assert(err, jc.ErrorIsNil) 101 102 newState, err := op.Execute(operation.State{}) 103 c.Assert(newState, gc.IsNil) 104 c.Assert(err, gc.Equals, operation.ErrNeedsReboot) 105 c.Assert(*runnerFactory.MockNewCommandRunner.runner.MockRunCommands.gotCommands, gc.Equals, "do something") 106 c.Assert(*runnerFactory.MockNewCommandRunner.runner.MockRunCommands.gotRunLocation, gc.Equals, runner.Workload) 107 c.Assert(*sendResponse.gotResponse, gc.DeepEquals, &utilexec.ExecResponse{Code: 101}) 108 c.Assert(*sendResponse.gotErr, jc.ErrorIsNil) 109 } 110 } 111 112 func (s *RunCommandsSuite) TestExecuteOtherError(c *gc.C) { 113 runnerFactory := NewRunCommandsRunnerFactory( 114 nil, errors.New("sneh"), 115 ) 116 callbacks := &RunCommandsCallbacks{} 117 factory := newOpFactory(runnerFactory, callbacks) 118 sendResponse := &MockSendResponse{} 119 op, err := factory.NewCommands(someCommandArgs, sendResponse.Call) 120 c.Assert(err, jc.ErrorIsNil) 121 _, err = op.Prepare(operation.State{}) 122 c.Assert(err, jc.ErrorIsNil) 123 124 newState, err := op.Execute(operation.State{}) 125 c.Assert(newState, gc.IsNil) 126 c.Assert(err, gc.ErrorMatches, "sneh") 127 c.Assert(*runnerFactory.MockNewCommandRunner.runner.MockRunCommands.gotCommands, gc.Equals, "do something") 128 c.Assert(*runnerFactory.MockNewCommandRunner.runner.MockRunCommands.gotRunLocation, gc.Equals, runner.Workload) 129 c.Assert(*sendResponse.gotResponse, gc.IsNil) 130 c.Assert(*sendResponse.gotErr, gc.ErrorMatches, "sneh") 131 } 132 133 func (s *RunCommandsSuite) TestExecuteConsumeOtherError(c *gc.C) { 134 runnerFactory := NewRunCommandsRunnerFactory( 135 nil, errors.New("sneh"), 136 ) 137 callbacks := &RunCommandsCallbacks{} 138 factory := newOpFactory(runnerFactory, callbacks) 139 sendResponse := &MockSendResponse{ 140 eatError: true, 141 } 142 op, err := factory.NewCommands(someCommandArgs, sendResponse.Call) 143 c.Assert(err, jc.ErrorIsNil) 144 _, err = op.Prepare(operation.State{}) 145 c.Assert(err, jc.ErrorIsNil) 146 147 newState, err := op.Execute(operation.State{}) 148 c.Assert(newState, gc.IsNil) 149 c.Assert(err, jc.ErrorIsNil) 150 c.Assert(*runnerFactory.MockNewCommandRunner.runner.MockRunCommands.gotCommands, gc.Equals, "do something") 151 c.Assert(*runnerFactory.MockNewCommandRunner.runner.MockRunCommands.gotRunLocation, gc.Equals, runner.Workload) 152 c.Assert(*sendResponse.gotResponse, gc.IsNil) 153 c.Assert(*sendResponse.gotErr, gc.ErrorMatches, "sneh") 154 } 155 156 func (s *RunCommandsSuite) TestExecuteSuccess(c *gc.C) { 157 runnerFactory := NewRunCommandsRunnerFactory( 158 &utilexec.ExecResponse{Code: 222}, nil, 159 ) 160 callbacks := &RunCommandsCallbacks{} 161 factory := newOpFactory(runnerFactory, callbacks) 162 sendResponse := &MockSendResponse{} 163 op, err := factory.NewCommands(someCommandArgs, sendResponse.Call) 164 c.Assert(err, jc.ErrorIsNil) 165 _, err = op.Prepare(operation.State{}) 166 c.Assert(err, jc.ErrorIsNil) 167 168 newState, err := op.Execute(operation.State{}) 169 c.Assert(newState, gc.IsNil) 170 c.Assert(err, jc.ErrorIsNil) 171 c.Assert(*runnerFactory.MockNewCommandRunner.runner.MockRunCommands.gotCommands, gc.Equals, "do something") 172 c.Assert(*runnerFactory.MockNewCommandRunner.runner.MockRunCommands.gotRunLocation, gc.Equals, runner.Workload) 173 c.Assert(*sendResponse.gotResponse, gc.DeepEquals, &utilexec.ExecResponse{Code: 222}) 174 c.Assert(*sendResponse.gotErr, jc.ErrorIsNil) 175 } 176 177 func (s *RunCommandsSuite) TestExecuteSuccessOperator(c *gc.C) { 178 runnerFactory := NewRunCommandsRunnerFactory( 179 &utilexec.ExecResponse{Code: 222}, nil, 180 ) 181 callbacks := &RunCommandsCallbacks{} 182 factory := newOpFactory(runnerFactory, callbacks) 183 sendResponse := &MockSendResponse{} 184 commandArgs := someCommandArgs 185 commandArgs.RunLocation = runner.Operator 186 op, err := factory.NewCommands(commandArgs, sendResponse.Call) 187 c.Assert(err, jc.ErrorIsNil) 188 _, err = op.Prepare(operation.State{}) 189 c.Assert(err, jc.ErrorIsNil) 190 191 newState, err := op.Execute(operation.State{}) 192 c.Assert(newState, gc.IsNil) 193 c.Assert(err, jc.ErrorIsNil) 194 c.Assert(*runnerFactory.MockNewCommandRunner.runner.MockRunCommands.gotCommands, gc.Equals, "do something") 195 c.Assert(*runnerFactory.MockNewCommandRunner.runner.MockRunCommands.gotRunLocation, gc.Equals, runner.Operator) 196 c.Assert(*sendResponse.gotResponse, gc.DeepEquals, &utilexec.ExecResponse{Code: 222}) 197 c.Assert(*sendResponse.gotErr, jc.ErrorIsNil) 198 } 199 200 func (s *RunCommandsSuite) TestCommit(c *gc.C) { 201 factory := newOpFactory(nil, nil) 202 sendResponse := func(*utilexec.ExecResponse, error) bool { panic("not expected") } 203 op, err := factory.NewCommands(someCommandArgs, sendResponse) 204 c.Assert(err, jc.ErrorIsNil) 205 newState, err := op.Commit(operation.State{}) 206 c.Assert(newState, gc.IsNil) 207 c.Assert(err, jc.ErrorIsNil) 208 } 209 210 func (s *RunCommandsSuite) TestNeedsGlobalMachineLock(c *gc.C) { 211 factory := newOpFactory(nil, nil) 212 sendResponse := &MockSendResponse{} 213 op, err := factory.NewCommands(someCommandArgs, sendResponse.Call) 214 c.Assert(err, jc.ErrorIsNil) 215 c.Assert(op.NeedsGlobalMachineLock(), jc.IsTrue) 216 }