github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/block_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state_test 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/names" 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/state" 16 "github.com/juju/juju/testing" 17 ) 18 19 type blockSuite struct { 20 ConnSuite 21 } 22 23 var _ = gc.Suite(&blockSuite{}) 24 25 func (s *blockSuite) SetUpTest(c *gc.C) { 26 s.ConnSuite.SetUpTest(c) 27 } 28 29 func assertNoEnvBlock(c *gc.C, st *state.State) { 30 all, err := st.AllBlocks() 31 c.Assert(err, jc.ErrorIsNil) 32 c.Assert(all, gc.HasLen, 0) 33 } 34 35 func (s *blockSuite) assertNoTypedBlock(c *gc.C, t state.BlockType) { 36 one, found, err := s.State.GetBlockForType(t) 37 c.Assert(err, jc.ErrorIsNil) 38 c.Assert(found, jc.IsFalse) 39 c.Assert(one, gc.IsNil) 40 } 41 42 func assertEnvHasBlock(c *gc.C, st *state.State, t state.BlockType, msg string) { 43 dBlock, found, err := st.GetBlockForType(t) 44 c.Assert(err, jc.ErrorIsNil) 45 c.Assert(found, jc.IsTrue) 46 c.Assert(dBlock, gc.NotNil) 47 c.Assert(dBlock.Type(), gc.DeepEquals, t) 48 tag, err := dBlock.Tag() 49 c.Assert(err, jc.ErrorIsNil) 50 c.Assert(tag, gc.DeepEquals, st.ModelTag()) 51 c.Assert(dBlock.Message(), gc.DeepEquals, msg) 52 } 53 54 func (s *blockSuite) switchOnBlock(c *gc.C, t state.BlockType) string { 55 msg := "" 56 err := s.State.SwitchBlockOn(t, msg) 57 c.Assert(err, jc.ErrorIsNil) 58 59 assertEnvHasBlock(c, s.State, t, msg) 60 return msg 61 } 62 63 func (s *blockSuite) switchOffBlock(c *gc.C, t state.BlockType) { 64 err := s.State.SwitchBlockOff(t) 65 c.Assert(err, jc.ErrorIsNil) 66 assertNoEnvBlock(c, s.State) 67 s.assertNoTypedBlock(c, t) 68 } 69 70 func (s *blockSuite) assertBlocked(c *gc.C, t state.BlockType) { 71 msg := s.switchOnBlock(c, t) 72 73 expectedErr := fmt.Sprintf(".*block %v is already ON.*", t.String()) 74 // cannot duplicate 75 err := s.State.SwitchBlockOn(t, msg) 76 c.Assert(errors.Cause(err), gc.ErrorMatches, expectedErr) 77 78 // cannot update 79 err = s.State.SwitchBlockOn(t, "Test block update") 80 c.Assert(errors.Cause(err), gc.ErrorMatches, expectedErr) 81 82 s.switchOffBlock(c, t) 83 84 err = s.State.SwitchBlockOff(t) 85 expectedErr = fmt.Sprintf(".*block %v is already OFF.*", t.String()) 86 c.Assert(errors.Cause(err), gc.ErrorMatches, expectedErr) 87 } 88 89 func (s *blockSuite) TestNewModelNotBlocked(c *gc.C) { 90 assertNoEnvBlock(c, s.State) 91 s.assertNoTypedBlock(c, state.DestroyBlock) 92 s.assertNoTypedBlock(c, state.RemoveBlock) 93 s.assertNoTypedBlock(c, state.ChangeBlock) 94 } 95 96 func (s *blockSuite) TestDestroyBlocked(c *gc.C) { 97 s.assertBlocked(c, state.DestroyBlock) 98 } 99 100 func (s *blockSuite) TestRemoveBlocked(c *gc.C) { 101 s.assertBlocked(c, state.RemoveBlock) 102 } 103 104 func (s *blockSuite) TestChangeBlocked(c *gc.C) { 105 s.assertBlocked(c, state.ChangeBlock) 106 } 107 108 func (s *blockSuite) TestNonsenseBlocked(c *gc.C) { 109 bType := state.BlockType(42) 110 // This could be useful for entity blocks... 111 s.switchOnBlock(c, bType) 112 s.switchOffBlock(c, bType) 113 // but for multiwatcher, it should panic. 114 c.Assert(func() { bType.ToParams() }, gc.PanicMatches, ".*unknown block type.*") 115 } 116 117 func (s *blockSuite) TestMultiEnvBlocked(c *gc.C) { 118 // create another env 119 _, st2 := s.createTestEnv(c) 120 defer st2.Close() 121 122 // switch one block type on 123 t := state.ChangeBlock 124 msg := "another env tst" 125 err := st2.SwitchBlockOn(t, msg) 126 c.Assert(err, jc.ErrorIsNil) 127 assertEnvHasBlock(c, st2, t, msg) 128 129 //check correct env has it 130 assertNoEnvBlock(c, s.State) 131 s.assertNoTypedBlock(c, t) 132 } 133 134 func (s *blockSuite) TestAllBlocksForController(c *gc.C) { 135 _, st2 := s.createTestEnv(c) 136 defer st2.Close() 137 138 err := st2.SwitchBlockOn(state.ChangeBlock, "block test") 139 c.Assert(err, jc.ErrorIsNil) 140 err = s.State.SwitchBlockOn(state.ChangeBlock, "block test") 141 c.Assert(err, jc.ErrorIsNil) 142 143 blocks, err := s.State.AllBlocksForController() 144 c.Assert(err, jc.ErrorIsNil) 145 c.Assert(len(blocks), gc.Equals, 2) 146 } 147 148 func (s *blockSuite) TestRemoveAllBlocksForController(c *gc.C) { 149 _, st2 := s.createTestEnv(c) 150 defer st2.Close() 151 152 err := st2.SwitchBlockOn(state.ChangeBlock, "block test") 153 c.Assert(err, jc.ErrorIsNil) 154 err = s.State.SwitchBlockOn(state.ChangeBlock, "block test") 155 c.Assert(err, jc.ErrorIsNil) 156 157 err = s.State.RemoveAllBlocksForController() 158 c.Assert(err, jc.ErrorIsNil) 159 160 blocks, err := s.State.AllBlocksForController() 161 c.Assert(err, jc.ErrorIsNil) 162 c.Assert(len(blocks), gc.Equals, 0) 163 } 164 165 func (s *blockSuite) TestRemoveAllBlocksForControllerNoBlocks(c *gc.C) { 166 _, st2 := s.createTestEnv(c) 167 defer st2.Close() 168 169 err := st2.RemoveAllBlocksForController() 170 c.Assert(err, jc.ErrorIsNil) 171 172 blocks, err := st2.AllBlocksForController() 173 c.Assert(err, jc.ErrorIsNil) 174 c.Assert(len(blocks), gc.Equals, 0) 175 } 176 177 func (s *blockSuite) TestModelUUID(c *gc.C) { 178 st := s.Factory.MakeModel(c, nil) 179 defer st.Close() 180 err := st.SwitchBlockOn(state.ChangeBlock, "blocktest") 181 c.Assert(err, jc.ErrorIsNil) 182 183 blocks, err := st.AllBlocks() 184 c.Assert(err, jc.ErrorIsNil) 185 c.Assert(len(blocks), gc.Equals, 1) 186 c.Assert(blocks[0].ModelUUID(), gc.Equals, st.ModelUUID()) 187 } 188 189 func (s *blockSuite) createTestEnv(c *gc.C) (*state.Model, *state.State) { 190 uuid, err := utils.NewUUID() 191 c.Assert(err, jc.ErrorIsNil) 192 cfg := testing.CustomModelConfig(c, testing.Attrs{ 193 "name": "testing", 194 "uuid": uuid.String(), 195 }) 196 owner := names.NewUserTag("test@remote") 197 env, st, err := s.State.NewModel(state.ModelArgs{Config: cfg, Owner: owner}) 198 c.Assert(err, jc.ErrorIsNil) 199 return env, st 200 } 201 202 func (s *blockSuite) TestConcurrentBlocked(c *gc.C) { 203 switchBlockOn := func() { 204 msg := "" 205 t := state.DestroyBlock 206 err := s.State.SwitchBlockOn(t, msg) 207 c.Assert(err, jc.ErrorIsNil) 208 assertEnvHasBlock(c, s.State, t, msg) 209 } 210 defer state.SetBeforeHooks(c, s.State, switchBlockOn).Check() 211 msg := "concurrency tst" 212 t := state.RemoveBlock 213 err := s.State.SwitchBlockOn(t, msg) 214 c.Assert(err, jc.ErrorIsNil) 215 assertEnvHasBlock(c, s.State, t, msg) 216 }