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  }