1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
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.v5"
15
"gopkg.in/juju/charm.v5/hooks"
17
"github.com/juju/juju/worker/uniter"
18
"github.com/juju/juju/worker/uniter/hook"
19
"github.com/juju/juju/worker/uniter/operation"
22
type upgradeStateContextSuite struct {
25
uniterStateFile string
26
statefile *operation.StateFile
29
var _ = gc.Suite(&upgradeStateContextSuite{})
31
func (s *upgradeStateContextSuite) SetUpTest(c *gc.C) {
34
s.initializeContext(c, names.NewUnitTag("mysql/0"))
37
func (s *upgradeStateContextSuite) TestContextUpgradeWithUnitTag(c *gc.C) {
38
given, expectUpgrade :=
40
Kind: operation.Continue,
41
Step: operation.Pending,
46
Kind: operation.Continue,
47
Step: operation.Pending,
50
s.confirmUpgrade(c, given, expectUpgrade)
53
func (s *upgradeStateContextSuite) TestUpgradeNoStopHookNoChange(c *gc.C) {
54
given, expectNoChange := &oldState{
55
Kind: operation.Continue,
56
Step: operation.Pending,
58
Kind: operation.Continue,
59
Step: operation.Pending,
62
s.confirmUpgrade(c, given, expectNoChange)
65
func (s *upgradeStateContextSuite) TestUpgradeRunHookNoChange(c *gc.C) {
66
given, expectNoChange := &oldState{
67
Kind: operation.RunHook,
68
Step: operation.Pending,
73
Kind: operation.RunHook,
74
Step: operation.Pending,
80
s.confirmUpgrade(c, given, expectNoChange)
83
func (s *upgradeStateContextSuite) TestUpgradeInstallOpNoChange(c *gc.C) {
84
given, expectNoChange := &oldState{
85
Kind: operation.Install,
86
Step: operation.Pending,
87
CharmURL: &charm.URL{},
89
Kind: operation.Install,
90
Step: operation.Pending,
91
CharmURL: &charm.URL{},
94
s.confirmUpgrade(c, given, expectNoChange)
97
func (s *upgradeStateContextSuite) TestUpgradeUpgradeOpNoChange(c *gc.C) {
98
given, expectNoChange := &oldState{
99
Kind: operation.Upgrade,
100
Step: operation.Pending,
101
CharmURL: &charm.URL{},
103
Kind: operation.Upgrade,
104
Step: operation.Pending,
105
CharmURL: &charm.URL{},
108
s.confirmUpgrade(c, given, expectNoChange)
111
func (s *upgradeStateContextSuite) TestUpgradeIdempotent(c *gc.C) {
112
given, expectUpgrade :=
114
Kind: operation.Continue,
115
Step: operation.Pending,
120
Kind: operation.Continue,
121
Step: operation.Pending,
124
s.confirmUpgradeIdempotent(c, given, expectUpgrade)
127
func (s *upgradeStateContextSuite) TestUpgradeMissingStateFile(c *gc.C) {
128
s.confirmUniterStateFileMissing(c)
129
s.confirmUpgradeNoErrors(c)
130
s.confirmUniterStateFileMissing(c)
133
func (s *upgradeStateContextSuite) confirmUpgrade(c *gc.C, given *oldState, expect *operation.State) {
134
s.writeOldState(c, given)
136
s.confirmUpgradeNoErrors(c)
137
s.confirmUniterStateFileMatches(c, expect)
140
func (s *upgradeStateContextSuite) confirmUpgradeIdempotent(c *gc.C, given *oldState, expect *operation.State) {
141
s.writeOldState(c, given)
143
s.confirmUpgradeNoErrors(c)
144
s.confirmUniterStateFileMatches(c, expect)
146
s.confirmUpgradeNoErrors(c)
147
s.confirmUniterStateFileMatches(c, expect)
150
func (s *upgradeStateContextSuite) writeOldState(c *gc.C, state *oldState) {
151
err := utils.WriteYaml(s.uniterStateFile, state)
152
c.Assert(err, jc.ErrorIsNil)
155
func (s *upgradeStateContextSuite) readState(c *gc.C) *operation.State {
156
state, err := s.statefile.Read()
157
c.Assert(err, jc.ErrorIsNil)
161
func (s *upgradeStateContextSuite) confirmUpgradeNoErrors(c *gc.C) {
162
err := uniter.AddStoppedFieldToUniterState(s.unitTag, s.datadir)
163
c.Assert(err, jc.ErrorIsNil)
166
func (s *upgradeStateContextSuite) confirmUniterStateFileMatches(c *gc.C, expect *operation.State) {
167
after := s.readState(c)
168
c.Assert(after, jc.DeepEquals, expect)
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")
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)
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"`