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  }