github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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 }