github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/worker/uniter/upgrade123_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package uniter_test
     5  
     6  import (
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/juju/names"
    11  	jc "github.com/juju/testing/checkers"
    12  	"github.com/juju/utils"
    13  	gc "gopkg.in/check.v1"
    14  	"gopkg.in/juju/charm.v6-unstable"
    15  	"gopkg.in/juju/charm.v6-unstable/hooks"
    16  
    17  	"github.com/juju/juju/worker/uniter"
    18  	"github.com/juju/juju/worker/uniter/hook"
    19  	"github.com/juju/juju/worker/uniter/operation"
    20  )
    21  
    22  type upgradeStateContextSuite struct {
    23  	datadir         string
    24  	unitTag         names.UnitTag
    25  	uniterStateFile string
    26  	statefile       *operation.StateFile
    27  }
    28  
    29  var _ = gc.Suite(&upgradeStateContextSuite{})
    30  
    31  func (s *upgradeStateContextSuite) SetUpTest(c *gc.C) {
    32  	s.datadir = c.MkDir()
    33  	s.statefile = nil
    34  	s.initializeContext(c, names.NewUnitTag("mysql/0"))
    35  }
    36  
    37  func (s *upgradeStateContextSuite) TestContextUpgradeWithUnitTag(c *gc.C) {
    38  	given, expectUpgrade :=
    39  		&oldState{
    40  			Kind: operation.Continue,
    41  			Step: operation.Pending,
    42  			Hook: &hook.Info{
    43  				Kind: hooks.Stop,
    44  			}},
    45  		&operation.State{
    46  			Kind:    operation.Continue,
    47  			Step:    operation.Pending,
    48  			Stopped: true}
    49  
    50  	s.confirmUpgrade(c, given, expectUpgrade)
    51  }
    52  
    53  func (s *upgradeStateContextSuite) TestUpgradeNoStopHookNoChange(c *gc.C) {
    54  	given, expectNoChange := &oldState{
    55  		Kind: operation.Continue,
    56  		Step: operation.Pending,
    57  	}, &operation.State{
    58  		Kind: operation.Continue,
    59  		Step: operation.Pending,
    60  	}
    61  
    62  	s.confirmUpgrade(c, given, expectNoChange)
    63  }
    64  
    65  func (s *upgradeStateContextSuite) TestUpgradeRunHookNoChange(c *gc.C) {
    66  	given, expectNoChange := &oldState{
    67  		Kind: operation.RunHook,
    68  		Step: operation.Pending,
    69  		Hook: &hook.Info{
    70  			Kind: hooks.Stop,
    71  		},
    72  	}, &operation.State{
    73  		Kind: operation.RunHook,
    74  		Step: operation.Pending,
    75  		Hook: &hook.Info{
    76  			Kind: hooks.Stop,
    77  		},
    78  	}
    79  
    80  	s.confirmUpgrade(c, given, expectNoChange)
    81  }
    82  
    83  func (s *upgradeStateContextSuite) TestUpgradeInstallOpNoChange(c *gc.C) {
    84  	given, expectNoChange := &oldState{
    85  		Kind:     operation.Install,
    86  		Step:     operation.Pending,
    87  		CharmURL: &charm.URL{},
    88  	}, &operation.State{
    89  		Kind:     operation.Install,
    90  		Step:     operation.Pending,
    91  		CharmURL: &charm.URL{},
    92  	}
    93  
    94  	s.confirmUpgrade(c, given, expectNoChange)
    95  }
    96  
    97  func (s *upgradeStateContextSuite) TestUpgradeUpgradeOpNoChange(c *gc.C) {
    98  	given, expectNoChange := &oldState{
    99  		Kind:     operation.Upgrade,
   100  		Step:     operation.Pending,
   101  		CharmURL: &charm.URL{},
   102  	}, &operation.State{
   103  		Kind:     operation.Upgrade,
   104  		Step:     operation.Pending,
   105  		CharmURL: &charm.URL{},
   106  	}
   107  
   108  	s.confirmUpgrade(c, given, expectNoChange)
   109  }
   110  
   111  func (s *upgradeStateContextSuite) TestUpgradeIdempotent(c *gc.C) {
   112  	given, expectUpgrade :=
   113  		&oldState{
   114  			Kind: operation.Continue,
   115  			Step: operation.Pending,
   116  			Hook: &hook.Info{
   117  				Kind: hooks.Stop,
   118  			}},
   119  		&operation.State{
   120  			Kind:    operation.Continue,
   121  			Step:    operation.Pending,
   122  			Stopped: true}
   123  
   124  	s.confirmUpgradeIdempotent(c, given, expectUpgrade)
   125  }
   126  
   127  func (s *upgradeStateContextSuite) TestUpgradeMissingStateFile(c *gc.C) {
   128  	s.confirmUniterStateFileMissing(c)
   129  	s.confirmUpgradeNoErrors(c)
   130  	s.confirmUniterStateFileMissing(c)
   131  }
   132  
   133  func (s *upgradeStateContextSuite) confirmUpgrade(c *gc.C, given *oldState, expect *operation.State) {
   134  	s.writeOldState(c, given)
   135  
   136  	s.confirmUpgradeNoErrors(c)
   137  	s.confirmUniterStateFileMatches(c, expect)
   138  }
   139  
   140  func (s *upgradeStateContextSuite) confirmUpgradeIdempotent(c *gc.C, given *oldState, expect *operation.State) {
   141  	s.writeOldState(c, given)
   142  
   143  	s.confirmUpgradeNoErrors(c)
   144  	s.confirmUniterStateFileMatches(c, expect)
   145  
   146  	s.confirmUpgradeNoErrors(c)
   147  	s.confirmUniterStateFileMatches(c, expect)
   148  }
   149  
   150  func (s *upgradeStateContextSuite) writeOldState(c *gc.C, state *oldState) {
   151  	err := utils.WriteYaml(s.uniterStateFile, state)
   152  	c.Assert(err, jc.ErrorIsNil)
   153  }
   154  
   155  func (s *upgradeStateContextSuite) readState(c *gc.C) *operation.State {
   156  	state, err := s.statefile.Read()
   157  	c.Assert(err, jc.ErrorIsNil)
   158  	return state
   159  }
   160  
   161  func (s *upgradeStateContextSuite) confirmUpgradeNoErrors(c *gc.C) {
   162  	err := uniter.AddStoppedFieldToUniterState(s.unitTag, s.datadir)
   163  	c.Assert(err, jc.ErrorIsNil)
   164  }
   165  
   166  func (s *upgradeStateContextSuite) confirmUniterStateFileMatches(c *gc.C, expect *operation.State) {
   167  	after := s.readState(c)
   168  	c.Assert(after, jc.DeepEquals, expect)
   169  }
   170  
   171  func (s *upgradeStateContextSuite) confirmUniterStateFileMissing(c *gc.C) {
   172  	_, err := s.statefile.Read()
   173  	c.Assert(err, gc.ErrorMatches, "uniter state file does not exist")
   174  }
   175  
   176  func (s *upgradeStateContextSuite) initializeContext(c *gc.C, utag names.UnitTag) {
   177  	paths := uniter.NewPaths(s.datadir, utag)
   178  	s.uniterStateFile = paths.State.OperationsFile
   179  	s.statefile = operation.NewStateFile(s.uniterStateFile)
   180  	c.Assert(os.MkdirAll(filepath.Dir(s.uniterStateFile), 0755), gc.IsNil)
   181  	s.unitTag = utag
   182  }
   183  
   184  // oldState is a surrogate type to imitate the relevant parts of the
   185  // pre-1.23 operation.State struct.
   186  type oldState struct {
   187  	Kind     operation.Kind `yaml:"op"`
   188  	Step     operation.Step `yaml:"opstep"`
   189  	Hook     *hook.Info     `yaml:"hook,omitempty"`
   190  	CharmURL *charm.URL     `yaml:"charm,omitempty"`
   191  }