github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/uniter/operation/deploy_test.go (about)

     1  // Copyright 2014-2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package operation_test
     5  
     6  import (
     7  	"github.com/juju/charm/v12/hooks"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/loggo"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/worker/uniter/hook"
    15  	"github.com/juju/juju/worker/uniter/operation"
    16  )
    17  
    18  type DeploySuite struct {
    19  	testing.IsolationSuite
    20  }
    21  
    22  var _ = gc.Suite(&DeploySuite{})
    23  
    24  type newDeploy func(operation.Factory, string) (operation.Operation, error)
    25  
    26  func (s *DeploySuite) testPrepareAlreadyDone(
    27  	c *gc.C, newDeploy newDeploy, kind operation.Kind,
    28  ) {
    29  	callbacks := &DeployCallbacks{}
    30  	deployer := &MockDeployer{
    31  		MockNotifyRevert:   &MockNoArgs{},
    32  		MockNotifyResolved: &MockNoArgs{},
    33  	}
    34  	factory := operation.NewFactory(operation.FactoryParams{
    35  		Deployer:  deployer,
    36  		Callbacks: callbacks,
    37  		Logger:    loggo.GetLogger("test"),
    38  	})
    39  	op, err := newDeploy(factory, "ch:quantal/hive-23")
    40  	c.Assert(err, jc.ErrorIsNil)
    41  	newState, err := op.Prepare(operation.State{
    42  		Kind:     kind,
    43  		Step:     operation.Done,
    44  		CharmURL: "ch:quantal/hive-23",
    45  	})
    46  	c.Check(newState, gc.IsNil)
    47  	c.Check(errors.Cause(err), gc.Equals, operation.ErrSkipExecute)
    48  }
    49  
    50  func (s *DeploySuite) TestPrepareAlreadyDone_Install(c *gc.C) {
    51  	s.testPrepareAlreadyDone(c,
    52  		(operation.Factory).NewInstall,
    53  		operation.Install,
    54  	)
    55  }
    56  
    57  func (s *DeploySuite) TestPrepareAlreadyDone_Upgrade(c *gc.C) {
    58  	s.testPrepareAlreadyDone(c,
    59  		(operation.Factory).NewUpgrade,
    60  		operation.Upgrade,
    61  	)
    62  }
    63  
    64  func (s *DeploySuite) TestPrepareAlreadyDone_RevertUpgrade(c *gc.C) {
    65  	s.testPrepareAlreadyDone(c,
    66  		(operation.Factory).NewRevertUpgrade,
    67  		operation.Upgrade,
    68  	)
    69  }
    70  
    71  func (s *DeploySuite) TestPrepareAlreadyDone_ResolvedUpgrade(c *gc.C) {
    72  	s.testPrepareAlreadyDone(c,
    73  		(operation.Factory).NewResolvedUpgrade,
    74  		operation.Upgrade,
    75  	)
    76  }
    77  
    78  func (s *DeploySuite) testPrepareArchiveInfoError(c *gc.C, newDeploy newDeploy) {
    79  	callbacks := &DeployCallbacks{
    80  		MockGetArchiveInfo: &MockGetArchiveInfo{err: errors.New("pew")},
    81  	}
    82  	deployer := &MockDeployer{
    83  		MockNotifyRevert:   &MockNoArgs{},
    84  		MockNotifyResolved: &MockNoArgs{},
    85  	}
    86  	factory := operation.NewFactory(operation.FactoryParams{
    87  		Deployer:  deployer,
    88  		Callbacks: callbacks,
    89  		Logger:    loggo.GetLogger("test"),
    90  	})
    91  	op, err := newDeploy(factory, "ch:quantal/hive-23")
    92  	c.Assert(err, jc.ErrorIsNil)
    93  
    94  	newState, err := op.Prepare(operation.State{})
    95  	c.Check(newState, gc.IsNil)
    96  	c.Check(err, gc.ErrorMatches, "pew")
    97  	c.Check(callbacks.MockGetArchiveInfo.gotCharmURL, gc.Equals, "ch:quantal/hive-23")
    98  }
    99  
   100  func (s *DeploySuite) TestPrepareArchiveInfoError_Install(c *gc.C) {
   101  	s.testPrepareArchiveInfoError(c, (operation.Factory).NewInstall)
   102  }
   103  
   104  func (s *DeploySuite) TestPrepareArchiveInfoError_Upgrade(c *gc.C) {
   105  	s.testPrepareArchiveInfoError(c, (operation.Factory).NewUpgrade)
   106  }
   107  
   108  func (s *DeploySuite) TestPrepareArchiveInfoError_RevertUpgrade(c *gc.C) {
   109  	s.testPrepareArchiveInfoError(c, (operation.Factory).NewRevertUpgrade)
   110  }
   111  
   112  func (s *DeploySuite) TestPrepareArchiveInfoError_ResolvedUpgrade(c *gc.C) {
   113  	s.testPrepareArchiveInfoError(c, (operation.Factory).NewResolvedUpgrade)
   114  }
   115  
   116  func (s *DeploySuite) testPrepareStageError(c *gc.C, newDeploy newDeploy) {
   117  	callbacks := &DeployCallbacks{
   118  		MockGetArchiveInfo: &MockGetArchiveInfo{info: &MockBundleInfo{}},
   119  	}
   120  	deployer := &MockDeployer{
   121  		MockNotifyRevert:   &MockNoArgs{},
   122  		MockNotifyResolved: &MockNoArgs{},
   123  		MockStage:          &MockStage{err: errors.New("squish")},
   124  	}
   125  	var abort <-chan struct{} = make(chan struct{})
   126  	factory := operation.NewFactory(operation.FactoryParams{
   127  		Deployer:  deployer,
   128  		Callbacks: callbacks,
   129  		Abort:     abort,
   130  		Logger:    loggo.GetLogger("test"),
   131  	})
   132  	op, err := newDeploy(factory, "ch:quantal/hive-23")
   133  	c.Assert(err, jc.ErrorIsNil)
   134  
   135  	newState, err := op.Prepare(operation.State{})
   136  	c.Check(newState, gc.IsNil)
   137  	c.Check(err, gc.ErrorMatches, "squish")
   138  	c.Check(*deployer.MockStage.gotInfo, gc.Equals, callbacks.MockGetArchiveInfo.info)
   139  	c.Check(*deployer.MockStage.gotAbort, gc.Equals, abort)
   140  }
   141  
   142  func (s *DeploySuite) TestPrepareStageError_Install(c *gc.C) {
   143  	s.testPrepareStageError(c, (operation.Factory).NewInstall)
   144  }
   145  
   146  func (s *DeploySuite) TestPrepareStageError_Upgrade(c *gc.C) {
   147  	s.testPrepareStageError(c, (operation.Factory).NewUpgrade)
   148  }
   149  
   150  func (s *DeploySuite) TestPrepareStageError_RevertUpgrade(c *gc.C) {
   151  	s.testPrepareStageError(c, (operation.Factory).NewRevertUpgrade)
   152  }
   153  
   154  func (s *DeploySuite) TestPrepareStageError_ResolvedUpgrade(c *gc.C) {
   155  	s.testPrepareStageError(c, (operation.Factory).NewResolvedUpgrade)
   156  }
   157  
   158  func (s *DeploySuite) testPrepareSetCharmError(c *gc.C, newDeploy newDeploy) {
   159  	callbacks := &DeployCallbacks{
   160  		MockGetArchiveInfo:  &MockGetArchiveInfo{},
   161  		MockSetCurrentCharm: &MockSetCurrentCharm{err: errors.New("blargh")},
   162  	}
   163  	deployer := &MockDeployer{
   164  		MockNotifyRevert:   &MockNoArgs{},
   165  		MockNotifyResolved: &MockNoArgs{},
   166  		MockStage:          &MockStage{},
   167  	}
   168  	factory := operation.NewFactory(operation.FactoryParams{
   169  		Deployer:  deployer,
   170  		Callbacks: callbacks,
   171  		Logger:    loggo.GetLogger("test"),
   172  	})
   173  
   174  	op, err := newDeploy(factory, "ch:quantal/hive-23")
   175  	c.Assert(err, jc.ErrorIsNil)
   176  
   177  	newState, err := op.Prepare(operation.State{})
   178  	c.Check(newState, gc.IsNil)
   179  	c.Check(err, gc.ErrorMatches, "blargh")
   180  	c.Check(callbacks.MockSetCurrentCharm.gotCharmURL, gc.Equals, "ch:quantal/hive-23")
   181  }
   182  
   183  func (s *DeploySuite) TestPrepareSetCharmError_Install(c *gc.C) {
   184  	s.testPrepareSetCharmError(c, (operation.Factory).NewInstall)
   185  }
   186  
   187  func (s *DeploySuite) TestPrepareSetCharmError_Upgrade(c *gc.C) {
   188  	s.testPrepareSetCharmError(c, (operation.Factory).NewUpgrade)
   189  }
   190  
   191  func (s *DeploySuite) TestPrepareSetCharmError_RevertUpgrade(c *gc.C) {
   192  	s.testPrepareSetCharmError(c, (operation.Factory).NewRevertUpgrade)
   193  }
   194  
   195  func (s *DeploySuite) TestPrepareSetCharmError_ResolvedUpgrade(c *gc.C) {
   196  	s.testPrepareSetCharmError(c, (operation.Factory).NewResolvedUpgrade)
   197  }
   198  
   199  func (s *DeploySuite) testPrepareSuccess(c *gc.C, newDeploy newDeploy, before, after operation.State) {
   200  	callbacks := NewDeployCallbacks()
   201  	deployer := &MockDeployer{
   202  		MockNotifyRevert:   &MockNoArgs{},
   203  		MockNotifyResolved: &MockNoArgs{},
   204  		MockStage:          &MockStage{},
   205  	}
   206  	factory := operation.NewFactory(operation.FactoryParams{
   207  		Deployer:  deployer,
   208  		Callbacks: callbacks,
   209  		Logger:    loggo.GetLogger("test"),
   210  	})
   211  	op, err := newDeploy(factory, "ch:quantal/nyancat-4")
   212  	c.Assert(err, jc.ErrorIsNil)
   213  
   214  	newState, err := op.Prepare(before)
   215  	c.Check(err, jc.ErrorIsNil)
   216  	c.Check(newState, gc.DeepEquals, &after)
   217  	c.Check(callbacks.MockSetCurrentCharm.gotCharmURL, gc.Equals, "ch:quantal/nyancat-4")
   218  }
   219  
   220  func (s *DeploySuite) TestPrepareSuccess_Install_BlankSlate(c *gc.C) {
   221  	s.testPrepareSuccess(c,
   222  		(operation.Factory).NewInstall,
   223  		operation.State{},
   224  		operation.State{
   225  			Kind:     operation.Install,
   226  			Step:     operation.Pending,
   227  			CharmURL: "ch:quantal/nyancat-4",
   228  		},
   229  	)
   230  }
   231  
   232  func (s *DeploySuite) TestPrepareSuccess_Install_Queued(c *gc.C) {
   233  	s.testPrepareSuccess(c,
   234  		(operation.Factory).NewInstall,
   235  		operation.State{
   236  			Kind:     operation.Install,
   237  			Step:     operation.Queued,
   238  			CharmURL: "ch:quantal/nyancat-4",
   239  		},
   240  		operation.State{
   241  			Kind:     operation.Install,
   242  			Step:     operation.Pending,
   243  			CharmURL: "ch:quantal/nyancat-4",
   244  		},
   245  	)
   246  }
   247  
   248  func (s *DeploySuite) TestPrepareSuccess_Upgrade_PreservePendingHook(c *gc.C) {
   249  	for i, newDeploy := range []newDeploy{
   250  		(operation.Factory).NewUpgrade,
   251  		(operation.Factory).NewRevertUpgrade,
   252  		(operation.Factory).NewResolvedUpgrade,
   253  	} {
   254  		c.Logf("variant %d", i)
   255  		s.testPrepareSuccess(c,
   256  			newDeploy,
   257  			operation.State{
   258  				Kind: operation.RunHook,
   259  				Step: operation.Pending,
   260  				Hook: &hook.Info{Kind: hooks.ConfigChanged},
   261  			},
   262  			operation.State{
   263  				Kind:     operation.Upgrade,
   264  				Step:     operation.Pending,
   265  				CharmURL: "ch:quantal/nyancat-4",
   266  				Hook:     &hook.Info{Kind: hooks.ConfigChanged},
   267  			},
   268  		)
   269  	}
   270  }
   271  
   272  func (s *DeploySuite) TestPrepareSuccess_Upgrade_PreserveOriginalPendingHook(c *gc.C) {
   273  	for i, newDeploy := range []newDeploy{
   274  		(operation.Factory).NewUpgrade,
   275  		(operation.Factory).NewRevertUpgrade,
   276  		(operation.Factory).NewResolvedUpgrade,
   277  	} {
   278  		c.Logf("variant %d", i)
   279  		s.testPrepareSuccess(c,
   280  			newDeploy,
   281  			operation.State{
   282  				Kind:     operation.Upgrade,
   283  				Step:     operation.Pending,
   284  				CharmURL: "ch:quantal/random-23",
   285  				Hook:     &hook.Info{Kind: hooks.ConfigChanged},
   286  			},
   287  			operation.State{
   288  				Kind:     operation.Upgrade,
   289  				Step:     operation.Pending,
   290  				CharmURL: "ch:quantal/nyancat-4",
   291  				Hook:     &hook.Info{Kind: hooks.ConfigChanged},
   292  			},
   293  		)
   294  	}
   295  }
   296  
   297  func (s *DeploySuite) TestPrepareSuccess_Upgrade_PreserveNoHook(c *gc.C) {
   298  	for i, newDeploy := range []newDeploy{
   299  		(operation.Factory).NewUpgrade,
   300  		(operation.Factory).NewRevertUpgrade,
   301  		(operation.Factory).NewResolvedUpgrade,
   302  	} {
   303  		c.Logf("variant %d", i)
   304  		s.testPrepareSuccess(c,
   305  			newDeploy,
   306  			overwriteState,
   307  			operation.State{
   308  				Kind:     operation.Upgrade,
   309  				Step:     operation.Pending,
   310  				CharmURL: "ch:quantal/nyancat-4",
   311  				Started:  true,
   312  			},
   313  		)
   314  	}
   315  }
   316  
   317  func (s *DeploySuite) TestExecuteConflictError_Install(c *gc.C) {
   318  	s.testExecuteError(c, (operation.Factory).NewInstall)
   319  }
   320  
   321  func (s *DeploySuite) TestExecuteConflictError_Upgrade(c *gc.C) {
   322  	s.testExecuteError(c, (operation.Factory).NewUpgrade)
   323  }
   324  
   325  func (s *DeploySuite) TestExecuteConflictError_RevertUpgrade(c *gc.C) {
   326  	s.testExecuteError(c, (operation.Factory).NewRevertUpgrade)
   327  }
   328  
   329  func (s *DeploySuite) TestExecuteConflictError_ResolvedUpgrade(c *gc.C) {
   330  	s.testExecuteError(c, (operation.Factory).NewResolvedUpgrade)
   331  }
   332  
   333  func (s *DeploySuite) testExecuteError(c *gc.C, newDeploy newDeploy) {
   334  	callbacks := NewDeployCallbacks()
   335  	deployer := &MockDeployer{
   336  		MockNotifyRevert:   &MockNoArgs{},
   337  		MockNotifyResolved: &MockNoArgs{},
   338  		MockStage:          &MockStage{},
   339  		MockDeploy:         &MockNoArgs{err: errors.New("rasp")},
   340  	}
   341  	factory := operation.NewFactory(operation.FactoryParams{
   342  		Deployer:  deployer,
   343  		Callbacks: callbacks,
   344  		Logger:    loggo.GetLogger("test"),
   345  	})
   346  	op, err := newDeploy(factory, "ch:quantal/nyancat-4")
   347  	c.Assert(err, jc.ErrorIsNil)
   348  	_, err = op.Prepare(operation.State{})
   349  	c.Assert(err, jc.ErrorIsNil)
   350  
   351  	newState, err := op.Execute(operation.State{})
   352  	c.Check(newState, gc.IsNil)
   353  	c.Check(err, gc.ErrorMatches, "rasp")
   354  	c.Check(deployer.MockDeploy.called, jc.IsTrue)
   355  }
   356  
   357  func (s *DeploySuite) TestExecuteError_Install(c *gc.C) {
   358  	s.testExecuteError(c, (operation.Factory).NewInstall)
   359  }
   360  
   361  func (s *DeploySuite) TestExecuteError_Upgrade(c *gc.C) {
   362  	s.testExecuteError(c, (operation.Factory).NewUpgrade)
   363  }
   364  
   365  func (s *DeploySuite) TestExecuteError_RevertUpgrade(c *gc.C) {
   366  	s.testExecuteError(c, (operation.Factory).NewRevertUpgrade)
   367  }
   368  
   369  func (s *DeploySuite) TestExecuteError_ResolvedUpgrade(c *gc.C) {
   370  	s.testExecuteError(c, (operation.Factory).NewResolvedUpgrade)
   371  }
   372  
   373  func (s *DeploySuite) testExecuteSuccess(
   374  	c *gc.C, newDeploy newDeploy, before, after operation.State,
   375  ) {
   376  	deployer := NewMockDeployer()
   377  	callbacks := NewDeployCallbacks()
   378  	factory := operation.NewFactory(operation.FactoryParams{
   379  		Deployer:  deployer,
   380  		Callbacks: callbacks,
   381  		Logger:    loggo.GetLogger("test"),
   382  	})
   383  	op, err := newDeploy(factory, "ch:quantal/lol-1")
   384  	c.Assert(err, jc.ErrorIsNil)
   385  
   386  	midState, err := op.Prepare(before)
   387  	c.Assert(err, jc.ErrorIsNil)
   388  	c.Assert(midState, gc.NotNil)
   389  
   390  	newState, err := op.Execute(*midState)
   391  	c.Check(err, jc.ErrorIsNil)
   392  	c.Check(newState, gc.DeepEquals, &after)
   393  	c.Check(deployer.MockDeploy.called, jc.IsTrue)
   394  }
   395  
   396  func (s *DeploySuite) TestExecuteSuccess_Install_BlankSlate(c *gc.C) {
   397  	s.testExecuteSuccess(c,
   398  		(operation.Factory).NewInstall,
   399  		operation.State{},
   400  		operation.State{
   401  			Kind:     operation.Install,
   402  			Step:     operation.Done,
   403  			CharmURL: "ch:quantal/lol-1",
   404  		},
   405  	)
   406  }
   407  
   408  func (s *DeploySuite) TestExecuteSuccess_Install_Queued(c *gc.C) {
   409  	s.testExecuteSuccess(c,
   410  		(operation.Factory).NewInstall,
   411  		operation.State{
   412  			Kind:     operation.Install,
   413  			Step:     operation.Queued,
   414  			CharmURL: "ch:quantal/lol-1",
   415  		},
   416  		operation.State{
   417  			Kind:     operation.Install,
   418  			Step:     operation.Done,
   419  			CharmURL: "ch:quantal/lol-1",
   420  		},
   421  	)
   422  }
   423  
   424  func (s *DeploySuite) TestExecuteSuccess_Upgrade_PreservePendingHook(c *gc.C) {
   425  	for i, newDeploy := range []newDeploy{
   426  		(operation.Factory).NewUpgrade,
   427  		(operation.Factory).NewRevertUpgrade,
   428  		(operation.Factory).NewResolvedUpgrade,
   429  	} {
   430  		c.Logf("variant %d", i)
   431  		s.testExecuteSuccess(c,
   432  			newDeploy,
   433  			operation.State{
   434  				Kind: operation.RunHook,
   435  				Step: operation.Pending,
   436  				Hook: &hook.Info{Kind: hooks.ConfigChanged},
   437  			},
   438  			operation.State{
   439  				Kind:     operation.Upgrade,
   440  				Step:     operation.Done,
   441  				CharmURL: "ch:quantal/lol-1",
   442  				Hook:     &hook.Info{Kind: hooks.ConfigChanged},
   443  			},
   444  		)
   445  	}
   446  }
   447  
   448  func (s *DeploySuite) TestExecuteSuccess_Upgrade_PreserveOriginalPendingHook(c *gc.C) {
   449  	for i, newDeploy := range []newDeploy{
   450  		(operation.Factory).NewUpgrade,
   451  		(operation.Factory).NewRevertUpgrade,
   452  		(operation.Factory).NewResolvedUpgrade,
   453  	} {
   454  		c.Logf("variant %d", i)
   455  		s.testExecuteSuccess(c,
   456  			newDeploy,
   457  			operation.State{
   458  				Kind:     operation.Upgrade,
   459  				Step:     operation.Pending,
   460  				CharmURL: "ch:quantal/wild-9",
   461  				Hook:     &hook.Info{Kind: hooks.ConfigChanged},
   462  			},
   463  			operation.State{
   464  				Kind:     operation.Upgrade,
   465  				Step:     operation.Done,
   466  				CharmURL: "ch:quantal/lol-1",
   467  				Hook:     &hook.Info{Kind: hooks.ConfigChanged},
   468  			},
   469  		)
   470  	}
   471  }
   472  
   473  func (s *DeploySuite) TestExecuteSuccess_Upgrade_PreserveNoHook(c *gc.C) {
   474  	for i, newDeploy := range []newDeploy{
   475  		(operation.Factory).NewUpgrade,
   476  		(operation.Factory).NewRevertUpgrade,
   477  		(operation.Factory).NewResolvedUpgrade,
   478  	} {
   479  		c.Logf("variant %d", i)
   480  		s.testExecuteSuccess(c,
   481  			newDeploy,
   482  			overwriteState,
   483  			operation.State{
   484  				Kind:     operation.Upgrade,
   485  				Step:     operation.Done,
   486  				CharmURL: "ch:quantal/lol-1",
   487  				Started:  true,
   488  			},
   489  		)
   490  	}
   491  }
   492  
   493  func (s *DeploySuite) TestCommitQueueInstallHook(c *gc.C) {
   494  	callbacks := NewDeployCommitCallbacks(nil)
   495  	deployer := &MockDeployer{
   496  		MockNotifyRevert:   &MockNoArgs{},
   497  		MockNotifyResolved: &MockNoArgs{},
   498  	}
   499  	factory := operation.NewFactory(operation.FactoryParams{
   500  		Deployer:  deployer,
   501  		Callbacks: callbacks,
   502  		Logger:    loggo.GetLogger("test"),
   503  	})
   504  	op, err := factory.NewInstall("ch:quantal/x-0")
   505  	c.Assert(err, jc.ErrorIsNil)
   506  	newState, err := op.Commit(operation.State{
   507  		Kind:     operation.Install,
   508  		Step:     operation.Done,
   509  		CharmURL: "", // doesn't actually matter here
   510  	})
   511  	c.Check(err, jc.ErrorIsNil)
   512  	c.Check(newState, gc.DeepEquals, &operation.State{
   513  		Kind: operation.RunHook,
   514  		Step: operation.Queued,
   515  		Hook: &hook.Info{Kind: hooks.Install},
   516  	})
   517  }
   518  
   519  func (s *DeploySuite) testCommitQueueUpgradeHook(c *gc.C, newDeploy newDeploy) {
   520  	callbacks := NewDeployCommitCallbacks(nil)
   521  	deployer := &MockDeployer{
   522  		MockNotifyRevert:   &MockNoArgs{},
   523  		MockNotifyResolved: &MockNoArgs{},
   524  	}
   525  	factory := operation.NewFactory(operation.FactoryParams{
   526  		Deployer:  deployer,
   527  		Callbacks: callbacks,
   528  		Logger:    loggo.GetLogger("test"),
   529  	})
   530  
   531  	op, err := newDeploy(factory, "ch:quantal/x-0")
   532  	c.Assert(err, jc.ErrorIsNil)
   533  	newState, err := op.Commit(operation.State{
   534  		Kind:     operation.Upgrade,
   535  		Step:     operation.Done,
   536  		CharmURL: "", // doesn't actually matter here
   537  	})
   538  	c.Check(err, jc.ErrorIsNil)
   539  	c.Check(newState, gc.DeepEquals, &operation.State{
   540  		Kind: operation.RunHook,
   541  		Step: operation.Queued,
   542  		Hook: &hook.Info{Kind: hooks.UpgradeCharm},
   543  	})
   544  }
   545  
   546  func (s *DeploySuite) TestCommitQueueUpgradeHook_Upgrade(c *gc.C) {
   547  	s.testCommitQueueUpgradeHook(c, (operation.Factory).NewUpgrade)
   548  }
   549  
   550  func (s *DeploySuite) TestCommitQueueUpgradeHook_RevertUpgrade(c *gc.C) {
   551  	s.testCommitQueueUpgradeHook(c, (operation.Factory).NewRevertUpgrade)
   552  }
   553  
   554  func (s *DeploySuite) TestCommitQueueUpgradeHook_ResolvedUpgrade(c *gc.C) {
   555  	s.testCommitQueueUpgradeHook(c, (operation.Factory).NewResolvedUpgrade)
   556  }
   557  
   558  func (s *DeploySuite) testCommitInterruptedHook(c *gc.C, newDeploy newDeploy) {
   559  	callbacks := NewDeployCommitCallbacks(nil)
   560  	deployer := &MockDeployer{
   561  		MockNotifyRevert:   &MockNoArgs{},
   562  		MockNotifyResolved: &MockNoArgs{},
   563  	}
   564  	factory := operation.NewFactory(operation.FactoryParams{
   565  		Deployer:  deployer,
   566  		Callbacks: callbacks,
   567  		Logger:    loggo.GetLogger("test"),
   568  	})
   569  
   570  	op, err := newDeploy(factory, "ch:quantal/x-0")
   571  	c.Assert(err, jc.ErrorIsNil)
   572  	hookStep := operation.Done
   573  	newState, err := op.Commit(operation.State{
   574  		Kind:     operation.Upgrade,
   575  		Step:     operation.Done,
   576  		CharmURL: "", // doesn't actually matter here
   577  		Hook:     &hook.Info{Kind: hooks.ConfigChanged},
   578  		HookStep: &hookStep,
   579  	})
   580  	c.Check(err, jc.ErrorIsNil)
   581  	c.Check(newState, gc.DeepEquals, &operation.State{
   582  		Kind:     operation.RunHook,
   583  		Step:     operation.Pending,
   584  		Hook:     &hook.Info{Kind: hooks.ConfigChanged},
   585  		HookStep: &hookStep,
   586  	})
   587  }
   588  
   589  func (s *DeploySuite) TestCommitInterruptedHook_Upgrade(c *gc.C) {
   590  	s.testCommitInterruptedHook(c, (operation.Factory).NewUpgrade)
   591  }
   592  
   593  func (s *DeploySuite) TestCommitInterruptedHook_RevertUpgrade(c *gc.C) {
   594  	s.testCommitInterruptedHook(c, (operation.Factory).NewRevertUpgrade)
   595  }
   596  
   597  func (s *DeploySuite) TestCommitInterruptedHook_ResolvedUpgrade(c *gc.C) {
   598  	s.testCommitInterruptedHook(c, (operation.Factory).NewResolvedUpgrade)
   599  }
   600  
   601  func (s *DeploySuite) testDoesNotNeedGlobalMachineLock(c *gc.C, newDeploy newDeploy) {
   602  	deployer := &MockDeployer{
   603  		MockNotifyRevert:   &MockNoArgs{},
   604  		MockNotifyResolved: &MockNoArgs{},
   605  	}
   606  	factory := operation.NewFactory(operation.FactoryParams{
   607  		Deployer: deployer,
   608  		Logger:   loggo.GetLogger("test"),
   609  	})
   610  	op, err := newDeploy(factory, "ch:quantal/x-0")
   611  	c.Assert(err, jc.ErrorIsNil)
   612  	c.Assert(op.NeedsGlobalMachineLock(), jc.IsFalse)
   613  }
   614  
   615  func (s *DeploySuite) TestDoesNotNeedGlobalMachineLock_Install(c *gc.C) {
   616  	s.testDoesNotNeedGlobalMachineLock(c, (operation.Factory).NewInstall)
   617  }
   618  
   619  func (s *DeploySuite) TestDoesNotNeedGlobalMachineLock_Upgrade(c *gc.C) {
   620  	s.testDoesNotNeedGlobalMachineLock(c, (operation.Factory).NewUpgrade)
   621  }
   622  
   623  func (s *DeploySuite) TestDoesNotNeedGlobalMachineLock_RevertUpgrade(c *gc.C) {
   624  	s.testDoesNotNeedGlobalMachineLock(c, (operation.Factory).NewRevertUpgrade)
   625  }
   626  
   627  func (s *DeploySuite) TestDoesNotNeedGlobalMachineLock_ResolvedUpgrade(c *gc.C) {
   628  	s.testDoesNotNeedGlobalMachineLock(c, (operation.Factory).NewResolvedUpgrade)
   629  }