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 }