github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/uniter/operation/failaction_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package operation_test
     5  
     6  import (
     7  	"github.com/juju/charm/v12/hooks"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/worker/uniter/hook"
    14  	"github.com/juju/juju/worker/uniter/operation"
    15  )
    16  
    17  type FailActionSuite struct {
    18  	testing.IsolationSuite
    19  }
    20  
    21  var _ = gc.Suite(&FailActionSuite{})
    22  
    23  func (s *FailActionSuite) TestPrepare(c *gc.C) {
    24  	factory := newOpFactory(nil, nil)
    25  	op, err := factory.NewFailAction(someActionId)
    26  	c.Assert(err, jc.ErrorIsNil)
    27  
    28  	newState, err := op.Prepare(operation.State{})
    29  	c.Assert(err, jc.ErrorIsNil)
    30  	c.Assert(newState, jc.DeepEquals, &operation.State{
    31  		Kind:     operation.RunAction,
    32  		Step:     operation.Pending,
    33  		ActionId: &someActionId,
    34  	})
    35  }
    36  
    37  func (s *FailActionSuite) TestExecuteSuccess(c *gc.C) {
    38  	var stateChangeTests = []struct {
    39  		description string
    40  		before      operation.State
    41  		after       operation.State
    42  	}{{
    43  		description: "empty state",
    44  		after: operation.State{
    45  			Kind:     operation.RunAction,
    46  			Step:     operation.Done,
    47  			ActionId: &someActionId,
    48  		},
    49  	}, {
    50  		description: "preserves appropriate fields",
    51  		before:      overwriteState,
    52  		after: operation.State{
    53  			Kind:     operation.RunAction,
    54  			Step:     operation.Done,
    55  			ActionId: &someActionId,
    56  			Hook:     &hook.Info{Kind: hooks.Install},
    57  			Started:  true,
    58  		},
    59  	}}
    60  
    61  	for i, test := range stateChangeTests {
    62  		c.Logf("test %d: %s", i, test.description)
    63  		callbacks := &RunActionCallbacks{MockFailAction: &MockFailAction{}}
    64  		factory := newOpFactory(nil, callbacks)
    65  		op, err := factory.NewFailAction(someActionId)
    66  		c.Assert(err, jc.ErrorIsNil)
    67  		midState, err := op.Prepare(test.before)
    68  		c.Assert(midState, gc.NotNil)
    69  		c.Assert(err, jc.ErrorIsNil)
    70  
    71  		newState, err := op.Execute(*midState)
    72  		c.Assert(err, jc.ErrorIsNil)
    73  		c.Assert(newState, jc.DeepEquals, &test.after)
    74  		c.Assert(*callbacks.MockFailAction.gotMessage, gc.Equals, "action terminated")
    75  		c.Assert(*callbacks.MockFailAction.gotActionId, gc.Equals, someActionId)
    76  	}
    77  }
    78  
    79  func (s *FailActionSuite) TestExecuteFail(c *gc.C) {
    80  	st := operation.State{
    81  		Kind:     operation.RunAction,
    82  		Step:     operation.Done,
    83  		ActionId: &someActionId,
    84  	}
    85  	callbacks := &RunActionCallbacks{MockFailAction: &MockFailAction{err: errors.New("squelch")}}
    86  	factory := newOpFactory(nil, callbacks)
    87  	op, err := factory.NewFailAction(someActionId)
    88  	c.Assert(err, jc.ErrorIsNil)
    89  	midState, err := op.Prepare(st)
    90  	c.Assert(midState, gc.NotNil)
    91  	c.Assert(err, jc.ErrorIsNil)
    92  
    93  	_, err = op.Execute(*midState)
    94  	c.Assert(err, gc.ErrorMatches, "squelch")
    95  }
    96  
    97  func (s *FailActionSuite) TestCommit(c *gc.C) {
    98  	var stateChangeTests = []struct {
    99  		description string
   100  		before      operation.State
   101  		after       operation.State
   102  	}{{
   103  		description: "empty state",
   104  		after: operation.State{
   105  			Kind: operation.Continue,
   106  			Step: operation.Pending,
   107  		},
   108  	}, {
   109  		description: "preserves only appropriate fields, no hook",
   110  		before: operation.State{
   111  			Kind:     operation.Continue,
   112  			Step:     operation.Pending,
   113  			Started:  true,
   114  			CharmURL: "ch:quantal/wordpress-2",
   115  			ActionId: &randomActionId,
   116  		},
   117  		after: operation.State{
   118  			Kind:    operation.Continue,
   119  			Step:    operation.Pending,
   120  			Started: true,
   121  		},
   122  	}, {
   123  		description: "preserves only appropriate fields, with hook",
   124  		before: operation.State{
   125  			Kind:     operation.Continue,
   126  			Step:     operation.Pending,
   127  			Started:  true,
   128  			CharmURL: "ch:quantal/wordpress-2",
   129  			ActionId: &randomActionId,
   130  			Hook:     &hook.Info{Kind: hooks.Install},
   131  		},
   132  		after: operation.State{
   133  			Kind:    operation.RunHook,
   134  			Step:    operation.Pending,
   135  			Hook:    &hook.Info{Kind: hooks.Install},
   136  			Started: true,
   137  		},
   138  	}}
   139  
   140  	for i, test := range stateChangeTests {
   141  		c.Logf("test %d: %s", i, test.description)
   142  		factory := newOpFactory(nil, nil)
   143  		op, err := factory.NewFailAction(someActionId)
   144  		c.Assert(err, jc.ErrorIsNil)
   145  
   146  		newState, err := op.Commit(test.before)
   147  		c.Assert(err, jc.ErrorIsNil)
   148  		c.Assert(newState, jc.DeepEquals, &test.after)
   149  	}
   150  }
   151  
   152  func (s *FailActionSuite) TestNeedsGlobalMachineLock(c *gc.C) {
   153  	factory := newOpFactory(nil, nil)
   154  	op, err := factory.NewFailAction(someActionId)
   155  	c.Assert(err, jc.ErrorIsNil)
   156  	c.Assert(op.NeedsGlobalMachineLock(), jc.IsTrue)
   157  }