github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/upgrade_test.go (about)

     1  // Copyright 2014 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  	jc "github.com/juju/testing/checkers"
    11  	"github.com/juju/version/v2"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/core/constraints"
    15  	"github.com/juju/juju/core/instance"
    16  	"github.com/juju/juju/core/status"
    17  	"github.com/juju/juju/state"
    18  	statetesting "github.com/juju/juju/state/testing"
    19  	"github.com/juju/juju/testing/factory"
    20  )
    21  
    22  type UpgradeSuite struct {
    23  	ConnSuite
    24  	serverIdA string
    25  }
    26  
    27  var _ = gc.Suite(&UpgradeSuite{})
    28  
    29  func vers(s string) version.Number {
    30  	return version.MustParse(s)
    31  }
    32  
    33  func (s *UpgradeSuite) provision(c *gc.C, machineIds ...string) {
    34  	for _, machineId := range machineIds {
    35  		machine, err := s.State.Machine(machineId)
    36  		c.Assert(err, jc.ErrorIsNil)
    37  		err = machine.SetProvisioned(
    38  			instance.Id(fmt.Sprintf("instance-%s", machineId)),
    39  			"",
    40  			fmt.Sprintf("nonce-%s", machineId),
    41  			nil,
    42  		)
    43  		c.Assert(err, jc.ErrorIsNil)
    44  	}
    45  }
    46  
    47  func (s *UpgradeSuite) addControllers(c *gc.C) (machineId1, machineId2 string) {
    48  	changes, err := s.State.EnableHA(3, constraints.Value{}, state.UbuntuBase("12.04"), nil)
    49  	c.Assert(err, jc.ErrorIsNil)
    50  	return changes.Added[0], changes.Added[1]
    51  }
    52  
    53  func (s *UpgradeSuite) assertUpgrading(c *gc.C, expect bool) {
    54  	upgrading, err := s.State.IsUpgrading()
    55  	c.Assert(err, jc.ErrorIsNil)
    56  	c.Assert(upgrading, gc.Equals, expect)
    57  }
    58  
    59  func (s *UpgradeSuite) SetUpTest(c *gc.C) {
    60  	s.ConnSuite.SetUpTest(c)
    61  	controller, err := s.State.AddMachine(state.UbuntuBase("12.10"), state.JobManageModel)
    62  	c.Assert(err, jc.ErrorIsNil)
    63  	s.serverIdA = controller.Id()
    64  	s.provision(c, s.serverIdA)
    65  }
    66  
    67  func (s *UpgradeSuite) assertEnsureUpgradeInfo(c *gc.C, st *state.State, controllerId string) {
    68  	vPrevious := vers("1.2.3")
    69  	vTarget := vers("2.3.4")
    70  	vMismatch := vers("1.9.1")
    71  
    72  	// create
    73  	info, err := st.EnsureUpgradeInfo(controllerId, vPrevious, vTarget)
    74  	c.Assert(err, jc.ErrorIsNil)
    75  	c.Assert(info.PreviousVersion(), gc.DeepEquals, vPrevious)
    76  	c.Assert(info.TargetVersion(), gc.DeepEquals, vTarget)
    77  	c.Assert(info.Status(), gc.Equals, state.UpgradePending)
    78  	c.Assert(info.Started().IsZero(), jc.IsFalse)
    79  	c.Assert(info.ControllersReady(), gc.DeepEquals, []string{controllerId})
    80  	c.Assert(info.ControllersDone(), gc.HasLen, 0)
    81  
    82  	// retrieve existing
    83  	info, err = st.EnsureUpgradeInfo(controllerId, vPrevious, vTarget)
    84  	c.Assert(err, jc.ErrorIsNil)
    85  	c.Assert(info.PreviousVersion(), gc.DeepEquals, vPrevious)
    86  	c.Assert(info.TargetVersion(), gc.DeepEquals, vTarget)
    87  
    88  	// mismatching previous
    89  	info, err = st.EnsureUpgradeInfo(controllerId, vMismatch, vTarget)
    90  	c.Assert(err, gc.ErrorMatches, "current upgrade info mismatch: expected previous version 1.9.1, got 1.2.3")
    91  	c.Assert(info, gc.IsNil)
    92  
    93  	// mismatching target
    94  	info, err = st.EnsureUpgradeInfo(controllerId, vPrevious, vMismatch)
    95  	c.Assert(err, gc.ErrorMatches, "current upgrade info mismatch: expected target version 1.9.1, got 2.3.4")
    96  	c.Assert(info, gc.IsNil)
    97  }
    98  
    99  func (s *UpgradeSuite) TestEnsureUpgradeInfo(c *gc.C) {
   100  	s.assertEnsureUpgradeInfo(c, s.State, s.serverIdA)
   101  }
   102  
   103  func (s *UpgradeSuite) TestCAASEnsureUpgradeInfo(c *gc.C) {
   104  	st := s.Factory.MakeModel(c, &factory.ModelParams{
   105  		Name: "caas-model",
   106  		Type: state.ModelTypeCAAS,
   107  	})
   108  	defer st.Close()
   109  	node, err := st.AddControllerNode()
   110  	c.Assert(err, jc.ErrorIsNil)
   111  
   112  	s.assertEnsureUpgradeInfo(c, st, node.Id())
   113  }
   114  
   115  func (s *UpgradeSuite) TestControllersReadyCopies(c *gc.C) {
   116  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, vers("1.2.3"), vers("2.4.5"))
   117  	c.Assert(err, jc.ErrorIsNil)
   118  	controllersReady := info.ControllersReady()
   119  	c.Assert(controllersReady, gc.DeepEquals, []string{"0"})
   120  	controllersReady[0] = "lol"
   121  	controllersReady = info.ControllersReady()
   122  	c.Assert(controllersReady, gc.DeepEquals, []string{"0"})
   123  }
   124  
   125  func (s *UpgradeSuite) TestControllersDoneCopies(c *gc.C) {
   126  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, vers("1.2.3"), vers("2.4.5"))
   127  	c.Assert(err, jc.ErrorIsNil)
   128  	s.setToRunning(c, info)
   129  	err = info.SetControllerDone("0")
   130  	c.Assert(err, jc.ErrorIsNil)
   131  
   132  	info = s.getOneUpgradeInfo(c)
   133  	controllersDone := info.ControllersDone()
   134  	c.Assert(controllersDone, gc.DeepEquals, []string{"0"})
   135  	controllersDone[0] = "lol"
   136  	controllersDone = info.ControllersReady()
   137  	c.Assert(controllersDone, gc.DeepEquals, []string{"0"})
   138  }
   139  
   140  func (s *UpgradeSuite) TestEnsureUpgradeInfoDowngrade(c *gc.C) {
   141  	v123 := vers("1.2.3")
   142  	v111 := vers("1.1.1")
   143  
   144  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v123, v111)
   145  	c.Assert(err, gc.ErrorMatches, "cannot upgrade from 1.2.3 to 1.1.1")
   146  	c.Assert(info, gc.IsNil)
   147  
   148  	info, err = s.State.EnsureUpgradeInfo(s.serverIdA, v123, v123)
   149  	c.Assert(err, gc.ErrorMatches, "cannot upgrade from 1.2.3 to 1.2.3")
   150  	c.Assert(info, gc.IsNil)
   151  }
   152  
   153  func (s *UpgradeSuite) TestEnsureUpgradeInfoNonController(c *gc.C) {
   154  	info, err := s.State.EnsureUpgradeInfo("2345678", vers("1.2.3"), vers("2.3.4"))
   155  	c.Assert(err, gc.ErrorMatches, `machine "2345678" is not a controller`)
   156  	c.Assert(info, gc.IsNil)
   157  }
   158  
   159  func (s *UpgradeSuite) TestEnsureUpgradeInfoNotProvisioned(c *gc.C) {
   160  	serverIdB, _ := s.addControllers(c)
   161  	_, err := s.State.EnsureUpgradeInfo(serverIdB, vers("1.1.1"), vers("1.2.3"))
   162  	expectErr := fmt.Sprintf("machine %s is not provisioned and should not be participating in upgrades", serverIdB)
   163  	c.Assert(err, gc.ErrorMatches, expectErr)
   164  }
   165  
   166  func (s *UpgradeSuite) TestEnsureUpgradeInfoMultipleServers(c *gc.C) {
   167  	serverIdB, serverIdC := s.addControllers(c)
   168  	s.provision(c, serverIdB, serverIdC)
   169  
   170  	v111 := vers("1.1.1")
   171  	v123 := vers("1.2.3")
   172  	_, err := s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   173  	c.Assert(err, jc.ErrorIsNil)
   174  
   175  	// add first new controller with bad version
   176  	info, err := s.State.EnsureUpgradeInfo(serverIdB, v111, vers("1.2.4"))
   177  	c.Assert(err, gc.ErrorMatches, "current upgrade info mismatch: expected target version 1.2.4, got 1.2.3")
   178  	c.Assert(info, gc.IsNil)
   179  
   180  	// add first new controller properly
   181  	info, err = s.State.EnsureUpgradeInfo(serverIdB, v111, v123)
   182  	c.Assert(err, jc.ErrorIsNil)
   183  	expectReady := []string{s.serverIdA, serverIdB}
   184  	c.Assert(info.ControllersReady(), jc.SameContents, expectReady)
   185  
   186  	// add second new controller
   187  	info, err = s.State.EnsureUpgradeInfo(serverIdC, v111, v123)
   188  	c.Assert(err, jc.ErrorIsNil)
   189  	expectReady = append(expectReady, serverIdC)
   190  	c.Assert(info.ControllersReady(), jc.SameContents, expectReady)
   191  
   192  	// add second new controller again
   193  	info, err = s.State.EnsureUpgradeInfo(serverIdC, v111, v123)
   194  	c.Assert(err, jc.ErrorIsNil)
   195  	c.Assert(info.ControllersReady(), jc.SameContents, expectReady)
   196  }
   197  
   198  func (s *UpgradeSuite) TestEnsureUpgradeInfoRace(c *gc.C) {
   199  	v100 := vers("1.0.0")
   200  	v200 := vers("2.0.0")
   201  
   202  	_, err := s.State.EnsureUpgradeInfo(s.serverIdA, v100, v200)
   203  	c.Assert(err, jc.ErrorIsNil)
   204  
   205  	defer state.SetAfterHooks(c, s.State, func() {
   206  		err := s.State.ClearUpgradeInfo()
   207  		c.Assert(err, jc.ErrorIsNil)
   208  	}).Check()
   209  
   210  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v100, v200)
   211  	c.Assert(err, gc.ErrorMatches, "current upgrade info not found")
   212  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   213  	c.Assert(info, gc.IsNil)
   214  }
   215  
   216  func (s *UpgradeSuite) TestEnsureUpgradeInfoMultipleServersRace1(c *gc.C) {
   217  	serverIdB, serverIdC := s.addControllers(c)
   218  	s.provision(c, serverIdB, serverIdC)
   219  
   220  	v111 := vers("1.1.1")
   221  	v123 := vers("1.2.3")
   222  	defer state.SetBeforeHooks(c, s.State, func() {
   223  		_, err := s.State.EnsureUpgradeInfo(serverIdC, v111, v123)
   224  		c.Assert(err, jc.ErrorIsNil)
   225  	}).Check()
   226  
   227  	info, err := s.State.EnsureUpgradeInfo(serverIdB, v111, v123)
   228  	c.Assert(err, jc.ErrorIsNil)
   229  	expectReady := []string{serverIdB, serverIdC}
   230  	c.Assert(info.ControllersReady(), jc.SameContents, expectReady)
   231  }
   232  
   233  func (s *UpgradeSuite) TestEnsureUpgradeInfoMultipleServersRace2(c *gc.C) {
   234  	serverIdB, serverIdC := s.addControllers(c)
   235  	s.provision(c, serverIdB, serverIdC)
   236  
   237  	v111 := vers("1.1.1")
   238  	v123 := vers("1.2.3")
   239  	_, err := s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   240  	c.Assert(err, jc.ErrorIsNil)
   241  
   242  	defer state.SetAfterHooks(c, s.State, func() {
   243  		_, err := s.State.EnsureUpgradeInfo(serverIdC, v111, v123)
   244  		c.Assert(err, jc.ErrorIsNil)
   245  	}).Check()
   246  
   247  	info, err := s.State.EnsureUpgradeInfo(serverIdB, v111, v123)
   248  	c.Assert(err, jc.ErrorIsNil)
   249  	expectReady := []string{s.serverIdA, serverIdB, serverIdC}
   250  	c.Assert(info.ControllersReady(), jc.SameContents, expectReady)
   251  }
   252  
   253  func (s *UpgradeSuite) TestEnsureUpgradeInfoMultipleServersRace3(c *gc.C) {
   254  	serverIdB, serverIdC := s.addControllers(c)
   255  	s.provision(c, serverIdB, serverIdC)
   256  
   257  	v111 := vers("1.1.1")
   258  	v123 := vers("1.2.3")
   259  	v124 := vers("1.2.4")
   260  	_, err := s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   261  	c.Assert(err, jc.ErrorIsNil)
   262  
   263  	defer state.SetBeforeHooks(c, s.State, nil, func() {
   264  		err := s.State.ClearUpgradeInfo()
   265  		c.Assert(err, jc.ErrorIsNil)
   266  		_, err = s.State.EnsureUpgradeInfo(serverIdC, v111, v124)
   267  		c.Assert(err, jc.ErrorIsNil)
   268  	}).Check()
   269  
   270  	_, err = s.State.EnsureUpgradeInfo(serverIdB, v111, v123)
   271  	c.Assert(err, gc.ErrorMatches, "upgrade info changed during update")
   272  }
   273  
   274  func (s *UpgradeSuite) TestEnsureUpgradeInfoMultipleServersRace4(c *gc.C) {
   275  	serverIdB, serverIdC := s.addControllers(c)
   276  	s.provision(c, serverIdB, serverIdC)
   277  
   278  	v111 := vers("1.1.1")
   279  	v123 := vers("1.2.3")
   280  	v124 := vers("1.2.4")
   281  	_, err := s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   282  	c.Assert(err, jc.ErrorIsNil)
   283  
   284  	defer state.SetAfterHooks(c, s.State, nil, func() {
   285  		err := s.State.ClearUpgradeInfo()
   286  		c.Assert(err, jc.ErrorIsNil)
   287  		_, err = s.State.EnsureUpgradeInfo(serverIdC, v111, v124)
   288  		c.Assert(err, jc.ErrorIsNil)
   289  	}).Check()
   290  
   291  	_, err = s.State.EnsureUpgradeInfo(serverIdB, v111, v123)
   292  	c.Assert(err, gc.ErrorMatches, "current upgrade info mismatch: expected target version 1.2.3, got 1.2.4")
   293  }
   294  
   295  func (s *UpgradeSuite) TestRefresh(c *gc.C) {
   296  	v111 := vers("1.1.1")
   297  	v123 := vers("1.2.3")
   298  	serverIdB, _ := s.addControllers(c)
   299  	s.provision(c, serverIdB)
   300  
   301  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   302  	c.Assert(err, jc.ErrorIsNil)
   303  	info2, err := s.State.EnsureUpgradeInfo(serverIdB, v111, v123)
   304  	c.Assert(err, jc.ErrorIsNil)
   305  
   306  	err = info2.SetStatus(state.UpgradeDBComplete)
   307  	c.Assert(err, jc.ErrorIsNil)
   308  
   309  	c.Assert(info.ControllersReady(), jc.SameContents, []string{s.serverIdA})
   310  	c.Assert(info.Status(), gc.Equals, state.UpgradePending)
   311  
   312  	err = info.Refresh()
   313  	c.Assert(err, jc.ErrorIsNil)
   314  
   315  	c.Assert(info.ControllersReady(), jc.SameContents, []string{s.serverIdA, serverIdB})
   316  	c.Assert(info.Status(), gc.Equals, state.UpgradeDBComplete)
   317  }
   318  
   319  func (s *UpgradeSuite) TestWatch(c *gc.C) {
   320  	v111 := vers("1.1.1")
   321  	v123 := vers("1.2.3")
   322  	serverIdB, serverIdC := s.addControllers(c)
   323  	s.provision(c, serverIdB, serverIdC)
   324  
   325  	w := s.State.WatchUpgradeInfo()
   326  	defer statetesting.AssertStop(c, w)
   327  
   328  	// initial event
   329  	wc := statetesting.NewNotifyWatcherC(c, w)
   330  	wc.AssertOneChange()
   331  
   332  	// single change is reported
   333  	_, err := s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   334  	c.Assert(err, jc.ErrorIsNil)
   335  	wc.AssertOneChange()
   336  
   337  	// non-change is not reported
   338  	_, err = s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   339  	c.Assert(err, jc.ErrorIsNil)
   340  	wc.AssertNoChange()
   341  
   342  	// changes are coalesced
   343  	_, err = s.State.EnsureUpgradeInfo(serverIdB, v111, v123)
   344  	c.Assert(err, jc.ErrorIsNil)
   345  	// TODO(quiescence): these two changes should be one event.
   346  	wc.AssertOneChange()
   347  	_, err = s.State.EnsureUpgradeInfo(serverIdC, v111, v123)
   348  	c.Assert(err, jc.ErrorIsNil)
   349  	wc.AssertOneChange()
   350  
   351  	// closed on stop
   352  	statetesting.AssertStop(c, w)
   353  	wc.AssertClosed()
   354  }
   355  
   356  func (s *UpgradeSuite) TestWatchMethod(c *gc.C) {
   357  	v111 := vers("1.1.1")
   358  	v123 := vers("1.2.3")
   359  	serverIdB, serverIdC := s.addControllers(c)
   360  	s.provision(c, serverIdB, serverIdC)
   361  
   362  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   363  	c.Assert(err, jc.ErrorIsNil)
   364  	// Ensure that all the creation events have flowed through the system.
   365  	s.WaitForModelWatchersIdle(c, s.Model.UUID())
   366  
   367  	w := info.Watch()
   368  	defer statetesting.AssertStop(c, w)
   369  
   370  	// initial event
   371  	wc := statetesting.NewNotifyWatcherC(c, w)
   372  	wc.AssertOneChange()
   373  
   374  	// single change is reported
   375  	info, err = s.State.EnsureUpgradeInfo(serverIdB, v111, v123)
   376  	c.Assert(err, jc.ErrorIsNil)
   377  	wc.AssertOneChange()
   378  
   379  	// non-change is not reported
   380  	info, err = s.State.EnsureUpgradeInfo(serverIdB, v111, v123)
   381  	c.Assert(err, jc.ErrorIsNil)
   382  	wc.AssertNoChange()
   383  
   384  	// changes are coalesced
   385  	_, err = s.State.EnsureUpgradeInfo(serverIdC, v111, v123)
   386  	c.Assert(err, jc.ErrorIsNil)
   387  	// TODO(quiescence): these two changes should be one event.
   388  	wc.AssertOneChange()
   389  	err = info.SetStatus(state.UpgradeDBComplete)
   390  	c.Assert(err, jc.ErrorIsNil)
   391  	wc.AssertOneChange()
   392  
   393  	err = info.SetStatus(state.UpgradeRunning)
   394  	c.Assert(err, jc.ErrorIsNil)
   395  	wc.AssertOneChange()
   396  
   397  	// closed on stop
   398  	statetesting.AssertStop(c, w)
   399  	wc.AssertClosed()
   400  }
   401  
   402  func (s *UpgradeSuite) TestAllProvisionedControllersReady(c *gc.C) {
   403  	serverIdB, serverIdC := s.addControllers(c)
   404  	s.provision(c, serverIdB)
   405  
   406  	v111 := vers("1.1.1")
   407  	v123 := vers("1.2.3")
   408  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   409  	c.Assert(err, jc.ErrorIsNil)
   410  
   411  	assertReady := func(expect bool) {
   412  		ok, err := info.AllProvisionedControllersReady()
   413  		c.Assert(err, jc.ErrorIsNil)
   414  		c.Assert(ok, gc.Equals, expect)
   415  	}
   416  	assertReady(false)
   417  
   418  	info, err = s.State.EnsureUpgradeInfo(serverIdB, v111, v123)
   419  	c.Assert(err, jc.ErrorIsNil)
   420  	assertReady(true)
   421  
   422  	s.provision(c, serverIdC)
   423  	assertReady(false)
   424  
   425  	info, err = s.State.EnsureUpgradeInfo(serverIdC, v111, v123)
   426  	c.Assert(err, jc.ErrorIsNil)
   427  	assertReady(true)
   428  }
   429  
   430  func (s *UpgradeSuite) TestSetStatusSetsModelStatus(c *gc.C) {
   431  	v123 := vers("1.2.3")
   432  	v234 := vers("2.3.4")
   433  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v123, v234)
   434  	c.Assert(err, jc.ErrorIsNil)
   435  
   436  	assertStatus := func(expect state.UpgradeStatus) {
   437  		info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v123, v234)
   438  		c.Assert(err, jc.ErrorIsNil)
   439  		c.Assert(info.Status(), gc.Equals, expect)
   440  	}
   441  
   442  	m, err := s.State.Model()
   443  	c.Assert(err, jc.ErrorIsNil)
   444  	st, err := m.Status()
   445  	c.Assert(err, jc.ErrorIsNil)
   446  	c.Assert(st.Status, gc.Equals, status.Available)
   447  	c.Assert(st.Message, gc.Equals, "")
   448  
   449  	err = info.SetStatus(state.UpgradeDBComplete)
   450  	c.Assert(err, jc.ErrorIsNil)
   451  	err = info.SetStatus(state.UpgradeRunning)
   452  	c.Assert(err, jc.ErrorIsNil)
   453  	assertStatus(state.UpgradeRunning)
   454  
   455  	st, err = m.Status()
   456  	c.Assert(err, jc.ErrorIsNil)
   457  	c.Assert(st.Status, gc.Equals, status.Busy)
   458  	c.Assert(st.Message, jc.HasPrefix, "upgrade in progress since")
   459  
   460  	err = info.SetControllerDone(s.serverIdA)
   461  	c.Assert(err, jc.ErrorIsNil)
   462  	st, err = m.Status()
   463  	c.Assert(err, jc.ErrorIsNil)
   464  	c.Assert(st.Status, gc.Equals, status.Available)
   465  	c.Assert(st.Message, jc.HasPrefix, "upgraded on")
   466  }
   467  
   468  func (s *UpgradeSuite) TestSetStatusSuccess(c *gc.C) {
   469  	v123 := vers("1.2.3")
   470  	v234 := vers("2.3.4")
   471  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v123, v234)
   472  	c.Assert(err, jc.ErrorIsNil)
   473  
   474  	assertStatus := func(expect state.UpgradeStatus) {
   475  		info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v123, v234)
   476  		c.Assert(err, jc.ErrorIsNil)
   477  		c.Assert(info.Status(), gc.Equals, expect)
   478  	}
   479  
   480  	err = info.SetStatus(state.UpgradeDBComplete)
   481  	c.Assert(err, jc.ErrorIsNil)
   482  	assertStatus(state.UpgradeDBComplete)
   483  
   484  	err = info.SetStatus(state.UpgradeRunning)
   485  	c.Assert(err, jc.ErrorIsNil)
   486  	assertStatus(state.UpgradeRunning)
   487  
   488  	// Test idempotency for when multiple controllers commence upgrade steps.
   489  	err = info.SetStatus(state.UpgradeRunning)
   490  	c.Assert(err, jc.ErrorIsNil)
   491  	assertStatus(state.UpgradeRunning)
   492  }
   493  
   494  func (s *UpgradeSuite) TestSetStatusErrors(c *gc.C) {
   495  	v123 := vers("1.2.3")
   496  	v234 := vers("2.3.4")
   497  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v123, v234)
   498  	c.Assert(err, jc.ErrorIsNil)
   499  
   500  	assertStatus := func(expect state.UpgradeStatus) {
   501  		info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v123, v234)
   502  		c.Assert(err, jc.ErrorIsNil)
   503  		c.Assert(info.Status(), gc.Equals, expect)
   504  	}
   505  
   506  	err = info.SetStatus(state.UpgradePending)
   507  	c.Assert(err, gc.ErrorMatches, `cannot explicitly set upgrade status to "pending"`)
   508  	assertStatus(state.UpgradePending)
   509  
   510  	err = info.SetStatus(state.UpgradeComplete)
   511  	c.Assert(err, gc.ErrorMatches, `cannot explicitly set upgrade status to "complete"`)
   512  	assertStatus(state.UpgradePending)
   513  
   514  	err = info.SetStatus(state.UpgradeAborted)
   515  	c.Assert(err, gc.ErrorMatches, `cannot explicitly set upgrade status to "aborted"`)
   516  	assertStatus(state.UpgradePending)
   517  
   518  	err = info.SetStatus("lol")
   519  	c.Assert(err, gc.ErrorMatches, "unknown upgrade status: lol")
   520  	assertStatus(state.UpgradePending)
   521  
   522  	err = info.SetStatus(state.UpgradeRunning)
   523  	c.Assert(err, gc.ErrorMatches, `setting upgrade status to "running": `+
   524  		`upgrade status transition from "pending" to "running" not valid`)
   525  }
   526  
   527  func (s *UpgradeSuite) TestSetControllerDone(c *gc.C) {
   528  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, vers("1.2.3"), vers("2.3.4"))
   529  	c.Assert(err, jc.ErrorIsNil)
   530  
   531  	err = info.SetControllerDone(s.serverIdA)
   532  	c.Assert(err, gc.ErrorMatches, "cannot complete upgrade: upgrade has not yet run")
   533  
   534  	err = info.SetStatus(state.UpgradeDBComplete)
   535  	c.Assert(err, jc.ErrorIsNil)
   536  
   537  	err = info.SetControllerDone(s.serverIdA)
   538  	c.Assert(err, gc.ErrorMatches, "cannot complete upgrade: upgrade has not yet run")
   539  
   540  	err = info.SetStatus(state.UpgradeRunning)
   541  	c.Assert(err, jc.ErrorIsNil)
   542  
   543  	err = info.SetControllerDone(s.serverIdA)
   544  	c.Assert(err, jc.ErrorIsNil)
   545  	s.assertUpgrading(c, false)
   546  
   547  	s.checkUpgradeInfoArchived(c, info, state.UpgradeComplete, 1)
   548  }
   549  
   550  func (s *UpgradeSuite) TestSetControllerDoneMultipleServers(c *gc.C) {
   551  	v111 := vers("1.1.1")
   552  	v123 := vers("1.2.3")
   553  	serverIdB, serverIdC := s.addControllers(c)
   554  	s.provision(c, serverIdB, serverIdC)
   555  	for _, id := range []string{serverIdB, serverIdC} {
   556  		_, err := s.State.EnsureUpgradeInfo(id, v111, v123)
   557  		c.Assert(err, jc.ErrorIsNil)
   558  	}
   559  
   560  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   561  	c.Assert(err, jc.ErrorIsNil)
   562  	s.setToRunning(c, info)
   563  
   564  	err = info.SetControllerDone(s.serverIdA)
   565  	c.Assert(err, jc.ErrorIsNil)
   566  	s.assertUpgrading(c, true)
   567  
   568  	err = info.SetControllerDone(s.serverIdA)
   569  	c.Assert(err, jc.ErrorIsNil)
   570  	s.assertUpgrading(c, true)
   571  
   572  	err = info.SetControllerDone(serverIdB)
   573  	c.Assert(err, jc.ErrorIsNil)
   574  	s.assertUpgrading(c, true)
   575  
   576  	err = info.SetControllerDone(serverIdC)
   577  	c.Assert(err, jc.ErrorIsNil)
   578  	s.assertUpgrading(c, false)
   579  
   580  	s.checkUpgradeInfoArchived(c, info, state.UpgradeComplete, 3)
   581  }
   582  
   583  func (s *UpgradeSuite) TestSetControllerDoneMultipleServersRace(c *gc.C) {
   584  	v100 := vers("1.0.0")
   585  	v200 := vers("2.0.0")
   586  	serverIdB, serverIdC := s.addControllers(c)
   587  	s.provision(c, serverIdB, serverIdC)
   588  
   589  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v100, v200)
   590  	c.Assert(err, jc.ErrorIsNil)
   591  	_, err = s.State.EnsureUpgradeInfo(serverIdB, v100, v200)
   592  	c.Assert(err, jc.ErrorIsNil)
   593  	_, err = s.State.EnsureUpgradeInfo(serverIdC, v100, v200)
   594  	c.Assert(err, jc.ErrorIsNil)
   595  	s.setToRunning(c, info)
   596  
   597  	// Interrupt the transaction for controller A twice with calls
   598  	// from the other machines.
   599  	defer state.SetBeforeHooks(c, s.State, func() {
   600  		err = info.SetControllerDone(serverIdB)
   601  		c.Assert(err, jc.ErrorIsNil)
   602  	}, func() {
   603  		err = info.SetControllerDone(serverIdC)
   604  		c.Assert(err, jc.ErrorIsNil)
   605  	}).Check()
   606  	err = info.SetControllerDone(s.serverIdA)
   607  	c.Assert(err, jc.ErrorIsNil)
   608  	s.assertUpgrading(c, false)
   609  
   610  	info = s.getOneUpgradeInfo(c)
   611  	c.Assert(info.Status(), gc.Equals, state.UpgradeComplete)
   612  	c.Assert(info.ControllersDone(), jc.SameContents, []string{"0", "1", "2"})
   613  }
   614  
   615  func (s *UpgradeSuite) TestAbort(c *gc.C) {
   616  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, vers("1.2.3"), vers("2.3.4"))
   617  	c.Assert(err, jc.ErrorIsNil)
   618  
   619  	err = info.Abort()
   620  	c.Assert(err, jc.ErrorIsNil)
   621  
   622  	s.checkUpgradeInfoArchived(c, info, state.UpgradeAborted, 0)
   623  }
   624  
   625  func (s *UpgradeSuite) TestAbortRace(c *gc.C) {
   626  	info, err := s.State.EnsureUpgradeInfo(s.serverIdA, vers("1.2.3"), vers("2.3.4"))
   627  	c.Assert(err, jc.ErrorIsNil)
   628  
   629  	defer state.SetBeforeHooks(c, s.State, func() {
   630  		err = info.Abort()
   631  		c.Assert(err, jc.ErrorIsNil)
   632  	}).Check()
   633  	err = info.Abort()
   634  	c.Assert(err, jc.ErrorIsNil)
   635  
   636  	s.checkUpgradeInfoArchived(c, info, state.UpgradeAborted, 0)
   637  }
   638  
   639  func (s *UpgradeSuite) checkUpgradeInfoArchived(
   640  	c *gc.C,
   641  	initialInfo *state.UpgradeInfo,
   642  	expectedStatus state.UpgradeStatus,
   643  	expectedControllers int,
   644  ) {
   645  	info := s.getOneUpgradeInfo(c)
   646  	c.Assert(info.Status(), gc.Equals, expectedStatus)
   647  	c.Assert(info.PreviousVersion(), gc.Equals, initialInfo.PreviousVersion())
   648  	c.Assert(info.TargetVersion(), gc.Equals, initialInfo.TargetVersion())
   649  	c.Assert(info.Started().Equal(truncateDBTime(initialInfo.Started())), jc.IsTrue)
   650  	c.Assert(len(info.ControllersDone()), gc.Equals, expectedControllers)
   651  	if expectedControllers > 0 {
   652  		c.Assert(info.ControllersDone(), jc.SameContents, info.ControllersReady())
   653  	}
   654  }
   655  
   656  func (s *UpgradeSuite) getOneUpgradeInfo(c *gc.C) *state.UpgradeInfo {
   657  	upgradeInfos, err := state.GetAllUpgradeInfos(s.State)
   658  	c.Assert(err, jc.ErrorIsNil)
   659  	c.Assert(len(upgradeInfos), gc.Equals, 1)
   660  	return upgradeInfos[0]
   661  }
   662  
   663  func (s *UpgradeSuite) TestAbortCurrentUpgrade(c *gc.C) {
   664  	// First try with nothing to abort.
   665  	err := s.State.AbortCurrentUpgrade()
   666  	c.Assert(err, jc.ErrorIsNil)
   667  
   668  	upgradeInfos, err := state.GetAllUpgradeInfos(s.State)
   669  	c.Assert(err, jc.ErrorIsNil)
   670  	c.Assert(len(upgradeInfos), gc.Equals, 0)
   671  
   672  	// Now create a UpgradeInfo to abort.
   673  	_, err = s.State.EnsureUpgradeInfo(s.serverIdA, vers("1.1.1"), vers("1.2.3"))
   674  	c.Assert(err, jc.ErrorIsNil)
   675  
   676  	err = s.State.AbortCurrentUpgrade()
   677  	c.Assert(err, jc.ErrorIsNil)
   678  
   679  	info := s.getOneUpgradeInfo(c)
   680  	c.Check(info.Status(), gc.Equals, state.UpgradeAborted)
   681  
   682  	// It should now be possible to start another upgrade.
   683  	_, err = s.State.EnsureUpgradeInfo(s.serverIdA, vers("1.2.3"), vers("1.3.0"))
   684  	c.Check(err, jc.ErrorIsNil)
   685  }
   686  
   687  func (s *UpgradeSuite) TestClearUpgradeInfo(c *gc.C) {
   688  	v111 := vers("1.1.1")
   689  	v123 := vers("1.2.3")
   690  	v153 := vers("1.5.3")
   691  
   692  	s.assertUpgrading(c, false)
   693  	_, err := s.State.EnsureUpgradeInfo(s.serverIdA, v111, v123)
   694  	c.Assert(err, jc.ErrorIsNil)
   695  	s.assertUpgrading(c, true)
   696  
   697  	err = s.State.ClearUpgradeInfo()
   698  	c.Assert(err, jc.ErrorIsNil)
   699  	s.assertUpgrading(c, false)
   700  
   701  	_, err = s.State.EnsureUpgradeInfo(s.serverIdA, v111, v153)
   702  	c.Assert(err, jc.ErrorIsNil)
   703  	s.assertUpgrading(c, true)
   704  }
   705  
   706  func (s *UpgradeSuite) TestApplicationUnitSeqToSequence(c *gc.C) {
   707  	v123 := vers("1.2.3")
   708  	v124 := vers("1.2.4")
   709  
   710  	s.assertUpgrading(c, false)
   711  	_, err := s.State.EnsureUpgradeInfo(s.serverIdA, v123, v124)
   712  	c.Assert(err, jc.ErrorIsNil)
   713  	s.assertUpgrading(c, true)
   714  }
   715  
   716  func (s *UpgradeSuite) setToRunning(c *gc.C, info *state.UpgradeInfo) {
   717  	err := info.SetStatus(state.UpgradeDBComplete)
   718  	c.Assert(err, jc.ErrorIsNil)
   719  	err = info.SetStatus(state.UpgradeRunning)
   720  	c.Assert(err, jc.ErrorIsNil)
   721  }