github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/machineremovals_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	jc "github.com/juju/testing/checkers"
     9  	"github.com/juju/worker/v3/workertest"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/state"
    13  	"github.com/juju/juju/state/testing"
    14  )
    15  
    16  type MachineRemovalSuite struct {
    17  	ConnSuite
    18  }
    19  
    20  var _ = gc.Suite(&MachineRemovalSuite{})
    21  
    22  func (s *MachineRemovalSuite) TestMarkingAndCompletingMachineRemoval(c *gc.C) {
    23  	m1 := s.makeMachine(c, true)
    24  	m2 := s.makeMachine(c, true)
    25  
    26  	err := m1.MarkForRemoval()
    27  	c.Assert(err, jc.ErrorIsNil)
    28  	err = m2.MarkForRemoval()
    29  	c.Assert(err, jc.ErrorIsNil)
    30  
    31  	// Check marking a machine multiple times is ok.
    32  	err = m1.MarkForRemoval()
    33  	c.Assert(err, jc.ErrorIsNil)
    34  
    35  	// Check machines haven't been removed.
    36  	_, err = s.State.Machine(m1.Id())
    37  	c.Assert(err, jc.ErrorIsNil)
    38  	_, err = s.State.Machine(m2.Id())
    39  	c.Assert(err, jc.ErrorIsNil)
    40  
    41  	removals, err := s.State.AllMachineRemovals()
    42  	c.Assert(err, jc.ErrorIsNil)
    43  	c.Check(removals, jc.SameContents, []string{m1.Id(), m2.Id()})
    44  
    45  	err = s.State.CompleteMachineRemovals(m1.Id(), "100")
    46  	c.Assert(err, jc.ErrorIsNil)
    47  	removals2, err := s.State.AllMachineRemovals()
    48  	c.Assert(err, jc.ErrorIsNil)
    49  	c.Check(removals2, jc.SameContents, []string{m2.Id()})
    50  
    51  	_, err = s.State.Machine(m1.Id())
    52  	c.Assert(err, gc.ErrorMatches, "machine 0 not found")
    53  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
    54  	// But m2 is still there.
    55  	_, err = s.State.Machine(m2.Id())
    56  	c.Assert(err, jc.ErrorIsNil)
    57  }
    58  
    59  func (s *MachineRemovalSuite) TestMarkForRemovalRequiresDeadness(c *gc.C) {
    60  	m := s.makeMachine(c, false)
    61  	err := m.MarkForRemoval()
    62  	c.Assert(err, gc.ErrorMatches, "cannot remove machine 0: machine is not dead")
    63  }
    64  
    65  func (s *MachineRemovalSuite) TestMarkForRemovalAssertsMachineStillExists(c *gc.C) {
    66  	m := s.makeMachine(c, true)
    67  	defer state.SetBeforeHooks(c, s.State, func() {
    68  		c.Assert(m.Remove(), gc.IsNil)
    69  	}).Check()
    70  	err := m.MarkForRemoval()
    71  	c.Assert(err, gc.ErrorMatches, "cannot remove machine 0: machine 0 not found")
    72  }
    73  
    74  func (s *MachineRemovalSuite) TestCompleteMachineRemovalsRequiresMark(c *gc.C) {
    75  	m1 := s.makeMachine(c, true)
    76  	m2 := s.makeMachine(c, true)
    77  	err := s.State.CompleteMachineRemovals(m1.Id(), m2.Id())
    78  	c.Assert(err, gc.ErrorMatches, "cannot remove machines 0, 1: not marked for removal")
    79  }
    80  
    81  func (s *MachineRemovalSuite) TestCompleteMachineRemovalsRequiresMarkSingular(c *gc.C) {
    82  	m1 := s.makeMachine(c, true)
    83  	err := s.State.CompleteMachineRemovals(m1.Id())
    84  	c.Assert(err, gc.ErrorMatches, "cannot remove machine 0: not marked for removal")
    85  }
    86  
    87  func (s *MachineRemovalSuite) TestCompleteMachineRemovalsIgnoresNonexistent(c *gc.C) {
    88  	err := s.State.CompleteMachineRemovals("0", "1")
    89  	c.Assert(err, jc.ErrorIsNil)
    90  }
    91  
    92  func (s *MachineRemovalSuite) TestCompleteMachineRemovalsInvalid(c *gc.C) {
    93  	err := s.State.CompleteMachineRemovals("A", "0/lxd/1", "B")
    94  	c.Assert(err, gc.ErrorMatches, "Invalid machine ids: A, B")
    95  }
    96  
    97  func (s *MachineRemovalSuite) TestWatchMachineRemovals(c *gc.C) {
    98  	w, wc := s.createRemovalWatcher(c, s.State)
    99  	wc.AssertOneChange() // Initial event.
   100  
   101  	m1 := s.makeMachine(c, true)
   102  	m2 := s.makeMachine(c, true)
   103  
   104  	err := m1.MarkForRemoval()
   105  	c.Assert(err, jc.ErrorIsNil)
   106  	wc.AssertOneChange()
   107  
   108  	err = m2.MarkForRemoval()
   109  	c.Assert(err, jc.ErrorIsNil)
   110  	wc.AssertOneChange()
   111  
   112  	s.State.CompleteMachineRemovals(m1.Id(), m2.Id())
   113  	wc.AssertOneChange()
   114  
   115  	testing.AssertStop(c, w)
   116  	wc.AssertClosed()
   117  }
   118  
   119  func (s *MachineRemovalSuite) createRemovalWatcher(c *gc.C, st *state.State) (
   120  	state.NotifyWatcher, testing.NotifyWatcherC,
   121  ) {
   122  	w := st.WatchMachineRemovals()
   123  	s.AddCleanup(func(c *gc.C) { workertest.CleanKill(c, w) })
   124  	return w, testing.NewNotifyWatcherC(c, w)
   125  }
   126  
   127  func (s *MachineRemovalSuite) makeMachine(c *gc.C, deadAlready bool) *state.Machine {
   128  	m, err := s.State.AddMachine(state.UbuntuBase("16.04"), state.JobHostUnits)
   129  	c.Assert(err, jc.ErrorIsNil)
   130  	if deadAlready {
   131  		deadenMachine(c, m)
   132  	}
   133  	return m
   134  }
   135  
   136  func deadenMachine(c *gc.C, m *state.Machine) {
   137  	c.Assert(m.EnsureDead(), jc.ErrorIsNil)
   138  }