github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/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, "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.RestoreFinished)
   124  }
   125  
   126  func (s *RestoreInfoSuite) TestNotActiveSetFinished(c *gc.C) {
   127  	s.checkBadSetStatus(c, state.RestoreFinished)
   128  }
   129  
   130  func (s *RestoreInfoSuite) TestNotActiveSetChecked(c *gc.C) {
   131  	s.checkBadSetStatus(c, state.RestoreChecked)
   132  }
   133  
   134  func (s *RestoreInfoSuite) TestNotActiveSetFailed(c *gc.C) {
   135  	s.checkBadSetStatus(c, state.RestoreFailed)
   136  }
   137  
   138  //--------------------------------------
   139  // Test Pending -> ? transitions
   140  func (s *RestoreInfoSuite) setupPending(c *gc.C) {
   141  	s.checkSetStatus(c, state.RestorePending)
   142  }
   143  
   144  func (s *RestoreInfoSuite) TestPendingSetNotActive(c *gc.C) {
   145  	s.setupPending(c)
   146  	s.checkBadSetStatus(c, state.RestoreNotActive)
   147  }
   148  
   149  func (s *RestoreInfoSuite) TestPendingSetPending(c *gc.C) {
   150  	s.setupPending(c)
   151  	s.checkSetStatus(c, state.RestorePending)
   152  }
   153  
   154  func (s *RestoreInfoSuite) TestPendingSetInProgress(c *gc.C) {
   155  	s.setupPending(c)
   156  	s.checkSetStatus(c, state.RestoreInProgress)
   157  }
   158  
   159  func (s *RestoreInfoSuite) TestPendingSetFinished(c *gc.C) {
   160  	s.setupPending(c)
   161  	s.checkBadSetStatus(c, state.RestoreFinished)
   162  }
   163  
   164  func (s *RestoreInfoSuite) TestPendingSetChecked(c *gc.C) {
   165  	s.setupPending(c)
   166  	s.checkBadSetStatus(c, state.RestoreChecked)
   167  }
   168  
   169  func (s *RestoreInfoSuite) TestPendingSetFailed(c *gc.C) {
   170  	s.setupPending(c)
   171  	s.checkSetStatus(c, state.RestoreFailed)
   172  }
   173  
   174  //--------------------------------------
   175  // Test InProgress -> ? transitions
   176  func (s *RestoreInfoSuite) setupInProgress(c *gc.C) {
   177  	s.checkSetStatus(c, state.RestorePending)
   178  	s.checkSetStatus(c, state.RestoreInProgress)
   179  }
   180  
   181  func (s *RestoreInfoSuite) TestInProgressSetNotActive(c *gc.C) {
   182  	s.setupInProgress(c)
   183  	s.checkBadSetStatus(c, state.RestoreNotActive)
   184  }
   185  
   186  func (s *RestoreInfoSuite) TestInProgressSetPending(c *gc.C) {
   187  	s.setupInProgress(c)
   188  	s.checkBadSetStatus(c, state.RestorePending)
   189  }
   190  
   191  func (s *RestoreInfoSuite) TestInProgressSetInProgress(c *gc.C) {
   192  	s.setupInProgress(c)
   193  	s.checkSetStatus(c, state.RestoreInProgress)
   194  }
   195  
   196  func (s *RestoreInfoSuite) TestInProgressSetFinished(c *gc.C) {
   197  	s.setupInProgress(c)
   198  	s.checkSetStatus(c, state.RestoreFinished)
   199  }
   200  
   201  func (s *RestoreInfoSuite) TestInProgressSetChecked(c *gc.C) {
   202  	s.setupInProgress(c)
   203  	s.checkBadSetStatus(c, state.RestoreChecked)
   204  }
   205  
   206  func (s *RestoreInfoSuite) TestInProgressSetFailed(c *gc.C) {
   207  	s.setupInProgress(c)
   208  	s.checkSetStatus(c, state.RestoreFailed)
   209  }
   210  
   211  //--------------------------------------
   212  // Test Finished -> ? transitions
   213  func (s *RestoreInfoSuite) setupFinished(c *gc.C) {
   214  	s.checkSetStatus(c, state.RestorePending)
   215  	s.checkSetStatus(c, state.RestoreInProgress)
   216  	s.checkSetStatus(c, state.RestoreFinished)
   217  }
   218  
   219  func (s *RestoreInfoSuite) TestFinishedSetNotActive(c *gc.C) {
   220  	s.setupFinished(c)
   221  	s.checkBadSetStatus(c, state.RestoreNotActive)
   222  }
   223  
   224  func (s *RestoreInfoSuite) TestFinishedSetPending(c *gc.C) {
   225  	s.setupFinished(c)
   226  	s.checkBadSetStatus(c, state.RestorePending)
   227  }
   228  
   229  func (s *RestoreInfoSuite) TestFinishedSetInProgress(c *gc.C) {
   230  	s.setupFinished(c)
   231  	s.checkBadSetStatus(c, state.RestoreInProgress)
   232  }
   233  
   234  func (s *RestoreInfoSuite) TestFinishedSetFinished(c *gc.C) {
   235  	s.setupFinished(c)
   236  	s.checkSetStatus(c, state.RestoreFinished)
   237  }
   238  
   239  func (s *RestoreInfoSuite) TestFinishedSetChecked(c *gc.C) {
   240  	s.setupFinished(c)
   241  	s.checkSetStatus(c, state.RestoreChecked)
   242  }
   243  
   244  func (s *RestoreInfoSuite) TestFinishedSetFailed(c *gc.C) {
   245  	s.setupFinished(c)
   246  	s.checkSetStatus(c, state.RestoreFailed)
   247  }
   248  
   249  //--------------------------------------
   250  // Test Checked -> ? transitions
   251  func (s *RestoreInfoSuite) setupChecked(c *gc.C) {
   252  	s.checkSetStatus(c, state.RestorePending)
   253  	s.checkSetStatus(c, state.RestoreInProgress)
   254  	s.checkSetStatus(c, state.RestoreFinished)
   255  	s.checkSetStatus(c, state.RestoreChecked)
   256  }
   257  
   258  func (s *RestoreInfoSuite) TestCheckedSetNotActive(c *gc.C) {
   259  	s.setupChecked(c)
   260  	s.checkBadSetStatus(c, state.RestoreNotActive)
   261  }
   262  
   263  func (s *RestoreInfoSuite) TestCheckedSetPending(c *gc.C) {
   264  	s.setupChecked(c)
   265  	s.checkSetStatus(c, state.RestorePending)
   266  }
   267  
   268  func (s *RestoreInfoSuite) TestCheckedSetInProgress(c *gc.C) {
   269  	s.setupChecked(c)
   270  	s.checkBadSetStatus(c, state.RestoreInProgress)
   271  }
   272  
   273  func (s *RestoreInfoSuite) TestCheckedSetFinished(c *gc.C) {
   274  	s.setupChecked(c)
   275  	s.checkBadSetStatus(c, state.RestoreFinished)
   276  }
   277  
   278  func (s *RestoreInfoSuite) TestCheckedSetChecked(c *gc.C) {
   279  	s.setupChecked(c)
   280  	s.checkSetStatus(c, state.RestoreChecked)
   281  }
   282  
   283  func (s *RestoreInfoSuite) TestCheckedSetFailed(c *gc.C) {
   284  	s.setupChecked(c)
   285  	s.checkBadSetStatus(c, state.RestoreFailed)
   286  }
   287  
   288  //--------------------------------------
   289  // Test Failed -> ? transitions
   290  func (s *RestoreInfoSuite) setupFailed(c *gc.C) {
   291  	s.checkSetStatus(c, state.RestorePending)
   292  	s.checkSetStatus(c, state.RestoreFailed)
   293  }
   294  
   295  func (s *RestoreInfoSuite) TestFailedSetNotActive(c *gc.C) {
   296  	s.setupFailed(c)
   297  	s.checkBadSetStatus(c, state.RestoreNotActive)
   298  }
   299  
   300  func (s *RestoreInfoSuite) TestFailedSetPending(c *gc.C) {
   301  	s.setupFailed(c)
   302  	s.checkSetStatus(c, state.RestorePending)
   303  }
   304  
   305  func (s *RestoreInfoSuite) TestFailedSetInProgress(c *gc.C) {
   306  	s.setupFailed(c)
   307  	s.checkBadSetStatus(c, state.RestoreInProgress)
   308  }
   309  
   310  func (s *RestoreInfoSuite) TestFailedSetFinished(c *gc.C) {
   311  	s.setupFailed(c)
   312  	s.checkBadSetStatus(c, state.RestoreFinished)
   313  }
   314  
   315  func (s *RestoreInfoSuite) TestFailedSetChecked(c *gc.C) {
   316  	s.setupFailed(c)
   317  	s.checkBadSetStatus(c, state.RestoreChecked)
   318  }
   319  
   320  func (s *RestoreInfoSuite) TestFailedSetFailed(c *gc.C) {
   321  	s.setupFailed(c)
   322  	s.checkSetStatus(c, state.RestoreFailed)
   323  }
   324  
   325  //--------------------
   326  
   327  func (s *RestoreInfoSuite) checkStatus(c *gc.C, expect state.RestoreStatus) {
   328  	actual, err := s.info.Status()
   329  	c.Check(err, jc.ErrorIsNil)
   330  	c.Check(actual, gc.Equals, expect)
   331  }
   332  
   333  func (s *RestoreInfoSuite) checkSetStatus(c *gc.C, status state.RestoreStatus) {
   334  	err := s.info.SetStatus(status)
   335  	c.Check(err, jc.ErrorIsNil)
   336  	s.checkStatus(c, status)
   337  }
   338  
   339  func (s *RestoreInfoSuite) checkBadSetStatus(c *gc.C, status state.RestoreStatus) {
   340  	err := s.info.SetStatus(status)
   341  	expect := fmt.Sprintf("invalid restore transition: [-A-Z]+ => %s", status)
   342  	c.Check(err, gc.ErrorMatches, expect)
   343  }