github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/state/restore_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 "fmt" 8 9 jc "github.com/juju/testing/checkers" 10 jujutxn "github.com/juju/txn" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/state" 14 statetesting "github.com/juju/juju/state/testing" 15 ) 16 17 // RestoreInfoSuite is *tremendously* incomplete: this test exists purely to 18 // verify that independent RestoreInfoSetters can be created concurrently. 19 // This says nothing about whether that's a good idea (it's *not*) but it's 20 // what we currently do and we need it to not just arbitrarily fail. 21 // 22 // TODO(fwereade): 2016-03-23 lp:1560920 23 // None of the other functionality is tested, and little of it is reliable or 24 // consistent with the other state code, but that's not for today. 25 type RestoreInfoSuite struct { 26 statetesting.StateSuite 27 info *state.RestoreInfo 28 } 29 30 var _ = gc.Suite(&RestoreInfoSuite{}) 31 32 func (s *RestoreInfoSuite) SetUpTest(c *gc.C) { 33 s.StateSuite.SetUpTest(c) 34 s.info = s.State.RestoreInfo() 35 } 36 37 func (s *RestoreInfoSuite) TestStartsNotActive(c *gc.C) { 38 s.checkStatus(c, state.RestoreNotActive) 39 } 40 41 func (s *RestoreInfoSuite) TestSetBadStatus(c *gc.C) { 42 err := s.info.SetStatus(state.RestoreStatus("LOLLYGAGGING")) 43 c.Check(err, gc.ErrorMatches, "unknown restore status: LOLLYGAGGING") 44 s.checkStatus(c, state.RestoreNotActive) 45 } 46 47 //-------------------------------------- 48 // Whitebox race tests to trigger different paths through the SetStatus 49 // code; use arbitrary sample transitions, full set of valid transitions 50 // are checked further down. 51 func (s *RestoreInfoSuite) TestInsertRaceHarmless(c *gc.C) { 52 defer state.SetBeforeHooks( 53 c, s.State, func() { 54 s.checkSetStatus(c, state.RestorePending) 55 }, 56 ).Check() 57 s.checkSetStatus(c, state.RestorePending) 58 } 59 60 func (s *RestoreInfoSuite) TestInsertRaceFailure(c *gc.C) { 61 defer state.SetBeforeHooks( 62 c, s.State, func() { 63 s.checkSetStatus(c, state.RestorePending) 64 s.checkSetStatus(c, state.RestoreInProgress) 65 }, 66 ).Check() 67 s.checkBadSetStatus(c, state.RestorePending) 68 s.checkStatus(c, state.RestoreInProgress) 69 } 70 71 func (s *RestoreInfoSuite) TestUpdateRaceHarmless(c *gc.C) { 72 s.setupInProgress(c) 73 defer state.SetBeforeHooks( 74 c, s.State, func() { 75 s.checkSetStatus(c, state.RestoreFinished) 76 }, 77 ).Check() 78 s.checkSetStatus(c, state.RestoreFinished) 79 } 80 81 func (s *RestoreInfoSuite) TestUpdateRaceFailure(c *gc.C) { 82 s.setupInProgress(c) 83 defer state.SetBeforeHooks( 84 c, s.State, func() { 85 s.checkSetStatus(c, state.RestoreFailed) 86 }, 87 ).Check() 88 s.checkBadSetStatus(c, state.RestoreFinished) 89 s.checkStatus(c, state.RestoreFailed) 90 } 91 92 func (s *RestoreInfoSuite) TestUpdateRaceExhaustion(c *gc.C) { 93 s.setupPending(c) 94 perturb := jujutxn.TestHook{ 95 Before: func() { 96 s.checkSetStatus(c, state.RestoreFailed) 97 }, 98 After: func() { 99 s.checkSetStatus(c, state.RestorePending) 100 }, 101 } 102 defer state.SetTestHooks( 103 c, s.State, 104 perturb, 105 perturb, 106 perturb, 107 ).Check() 108 err := s.info.SetStatus(state.RestoreInProgress) 109 c.Check(err, gc.ErrorMatches, "setting status \"RESTORING\": state changing too quickly; try again soon") 110 } 111 112 //-------------------------------------- 113 // Test NotActive -> ? transitions 114 func (s *RestoreInfoSuite) TestNotActiveSetNotActive(c *gc.C) { 115 s.checkSetStatus(c, state.RestoreNotActive) 116 } 117 118 func (s *RestoreInfoSuite) TestNotActiveSetPending(c *gc.C) { 119 s.checkSetStatus(c, state.RestorePending) 120 } 121 122 func (s *RestoreInfoSuite) TestNotActiveSetInProgress(c *gc.C) { 123 s.checkBadSetStatus(c, state.RestoreInProgress) 124 } 125 126 func (s *RestoreInfoSuite) TestNotActiveSetChecked(c *gc.C) { 127 s.checkBadSetStatus(c, state.RestoreChecked) 128 } 129 130 func (s *RestoreInfoSuite) TestNotActiveSetFailed(c *gc.C) { 131 s.checkBadSetStatus(c, state.RestoreFailed) 132 } 133 134 //-------------------------------------- 135 // Test Pending -> ? transitions 136 func (s *RestoreInfoSuite) setupPending(c *gc.C) { 137 s.checkSetStatus(c, state.RestorePending) 138 } 139 140 func (s *RestoreInfoSuite) TestPendingSetNotActive(c *gc.C) { 141 s.setupPending(c) 142 s.checkBadSetStatus(c, state.RestoreNotActive) 143 } 144 145 func (s *RestoreInfoSuite) TestPendingSetPending(c *gc.C) { 146 s.setupPending(c) 147 s.checkSetStatus(c, state.RestorePending) 148 } 149 150 func (s *RestoreInfoSuite) TestPendingSetInProgress(c *gc.C) { 151 s.setupPending(c) 152 s.checkSetStatus(c, state.RestoreInProgress) 153 } 154 155 func (s *RestoreInfoSuite) TestPendingSetChecked(c *gc.C) { 156 s.setupPending(c) 157 s.checkBadSetStatus(c, state.RestoreChecked) 158 } 159 160 func (s *RestoreInfoSuite) TestPendingSetFailed(c *gc.C) { 161 s.setupPending(c) 162 s.checkSetStatus(c, state.RestoreFailed) 163 } 164 165 //-------------------------------------- 166 // Test InProgress -> ? transitions 167 func (s *RestoreInfoSuite) setupInProgress(c *gc.C) { 168 s.checkSetStatus(c, state.RestorePending) 169 s.checkSetStatus(c, state.RestoreInProgress) 170 } 171 172 func (s *RestoreInfoSuite) TestInProgressSetNotActive(c *gc.C) { 173 s.setupInProgress(c) 174 s.checkBadSetStatus(c, state.RestoreNotActive) 175 } 176 177 func (s *RestoreInfoSuite) TestInProgressSetPending(c *gc.C) { 178 s.setupInProgress(c) 179 s.checkBadSetStatus(c, state.RestorePending) 180 } 181 182 func (s *RestoreInfoSuite) TestInProgressSetInProgress(c *gc.C) { 183 s.setupInProgress(c) 184 s.checkSetStatus(c, state.RestoreInProgress) 185 } 186 187 func (s *RestoreInfoSuite) TestInProgressSetFinished(c *gc.C) { 188 s.setupInProgress(c) 189 s.checkSetStatus(c, state.RestoreFinished) 190 } 191 192 func (s *RestoreInfoSuite) TestInProgressSetChecked(c *gc.C) { 193 s.setupInProgress(c) 194 s.checkBadSetStatus(c, state.RestoreChecked) 195 } 196 197 func (s *RestoreInfoSuite) TestInProgressSetFailed(c *gc.C) { 198 s.setupInProgress(c) 199 s.checkSetStatus(c, state.RestoreFailed) 200 } 201 202 //-------------------------------------- 203 // Test Finished -> ? transitions 204 func (s *RestoreInfoSuite) setupFinished(c *gc.C) { 205 s.checkSetStatus(c, state.RestorePending) 206 s.checkSetStatus(c, state.RestoreInProgress) 207 s.checkSetStatus(c, state.RestoreFinished) 208 } 209 210 func (s *RestoreInfoSuite) TestFinishedSetNotActive(c *gc.C) { 211 s.setupFinished(c) 212 s.checkBadSetStatus(c, state.RestoreNotActive) 213 } 214 215 func (s *RestoreInfoSuite) TestFinishedSetPending(c *gc.C) { 216 s.setupFinished(c) 217 s.checkBadSetStatus(c, state.RestorePending) 218 } 219 220 func (s *RestoreInfoSuite) TestFinishedSetInProgress(c *gc.C) { 221 s.setupFinished(c) 222 s.checkBadSetStatus(c, state.RestoreInProgress) 223 } 224 225 func (s *RestoreInfoSuite) TestFinishedSetFinished(c *gc.C) { 226 s.setupFinished(c) 227 s.checkSetStatus(c, state.RestoreFinished) 228 } 229 230 func (s *RestoreInfoSuite) TestFinishedSetChecked(c *gc.C) { 231 s.setupFinished(c) 232 s.checkSetStatus(c, state.RestoreChecked) 233 } 234 235 func (s *RestoreInfoSuite) TestFinishedSetFailed(c *gc.C) { 236 s.setupFinished(c) 237 s.checkSetStatus(c, state.RestoreFailed) 238 } 239 240 //-------------------------------------- 241 // Test Checked -> ? transitions 242 func (s *RestoreInfoSuite) setupChecked(c *gc.C) { 243 s.checkSetStatus(c, state.RestorePending) 244 s.checkSetStatus(c, state.RestoreInProgress) 245 s.checkSetStatus(c, state.RestoreFinished) 246 s.checkSetStatus(c, state.RestoreChecked) 247 } 248 249 func (s *RestoreInfoSuite) TestCheckedSetNotActive(c *gc.C) { 250 s.setupChecked(c) 251 s.checkBadSetStatus(c, state.RestoreNotActive) 252 } 253 254 func (s *RestoreInfoSuite) TestCheckedSetPending(c *gc.C) { 255 s.setupChecked(c) 256 s.checkSetStatus(c, state.RestorePending) 257 } 258 259 func (s *RestoreInfoSuite) TestCheckedSetInProgress(c *gc.C) { 260 s.setupChecked(c) 261 s.checkBadSetStatus(c, state.RestoreInProgress) 262 } 263 264 func (s *RestoreInfoSuite) TestCheckedSetChecked(c *gc.C) { 265 s.setupChecked(c) 266 s.checkSetStatus(c, state.RestoreChecked) 267 } 268 269 func (s *RestoreInfoSuite) TestCheckedSetFailed(c *gc.C) { 270 s.setupChecked(c) 271 s.checkBadSetStatus(c, state.RestoreFailed) 272 } 273 274 //-------------------------------------- 275 // Test Failed -> ? transitions 276 func (s *RestoreInfoSuite) setupFailed(c *gc.C) { 277 s.checkSetStatus(c, state.RestorePending) 278 s.checkSetStatus(c, state.RestoreFailed) 279 } 280 281 func (s *RestoreInfoSuite) TestFailedSetNotActive(c *gc.C) { 282 s.setupFailed(c) 283 s.checkBadSetStatus(c, state.RestoreNotActive) 284 } 285 286 func (s *RestoreInfoSuite) TestFailedSetPending(c *gc.C) { 287 s.setupFailed(c) 288 s.checkSetStatus(c, state.RestorePending) 289 } 290 291 func (s *RestoreInfoSuite) TestFailedSetInProgress(c *gc.C) { 292 s.setupFailed(c) 293 s.checkBadSetStatus(c, state.RestoreInProgress) 294 } 295 296 func (s *RestoreInfoSuite) TestFailedSetFinished(c *gc.C) { 297 s.setupFailed(c) 298 s.checkBadSetStatus(c, state.RestoreFinished) 299 } 300 301 func (s *RestoreInfoSuite) TestFailedSetChecked(c *gc.C) { 302 s.setupFailed(c) 303 s.checkBadSetStatus(c, state.RestoreChecked) 304 } 305 306 func (s *RestoreInfoSuite) TestFailedSetFailed(c *gc.C) { 307 s.setupFailed(c) 308 s.checkSetStatus(c, state.RestoreFailed) 309 } 310 311 //-------------------- 312 313 func (s *RestoreInfoSuite) checkStatus(c *gc.C, expect state.RestoreStatus) { 314 actual, err := s.info.Status() 315 c.Check(err, jc.ErrorIsNil) 316 c.Check(actual, gc.Equals, expect) 317 } 318 319 func (s *RestoreInfoSuite) checkSetStatus(c *gc.C, status state.RestoreStatus) { 320 err := s.info.SetStatus(status) 321 c.Check(err, jc.ErrorIsNil) 322 s.checkStatus(c, status) 323 } 324 325 func (s *RestoreInfoSuite) checkBadSetStatus(c *gc.C, status state.RestoreStatus) { 326 err := s.info.SetStatus(status) 327 expect := fmt.Sprintf("setting status %q: invalid restore transition: [-A-Z]+ => %s", status, status) 328 c.Check(err, gc.ErrorMatches, expect) 329 }