Merge lp:~rogpeppe/juju-core/502-upgrades-simplify into lp:~go-bot/juju-core/trunk

Proposed by Roger Peppe
Status: Rejected
Rejected by: William Reade
Proposed branch: lp:~rogpeppe/juju-core/502-upgrades-simplify
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 561 lines (+135/-196)
8 files modified
upgrades/lockdirectory.go (+2/-2)
upgrades/lockdirectory_test.go (+4/-2)
upgrades/operations.go (+5/-10)
upgrades/rsyslogconf.go (+7/-7)
upgrades/rsyslogconf_test.go (+4/-4)
upgrades/steps118.go (+13/-16)
upgrades/upgrade.go (+21/-75)
upgrades/upgrade_test.go (+79/-80)
To merge this branch: bzr merge lp:~rogpeppe/juju-core/502-upgrades-simplify
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+206361@code.launchpad.net

Description of the change

upgrades: remove unnecessary indirection layer

The upgrade description is just data - it doesn't
need any behaviour associated with it, so it's
sufficient, simpler and more direct to just use
structs where we can, making the code easier
to understand and shorter.

https://codereview.appspot.com/63530048/

To post a comment you must log in.
Revision history for this message
Roger Peppe (rogpeppe) wrote :

Reviewers: mp+206361_code.launchpad.net,

Message:
Please take a look.

Description:
upgrades: remove unnecessary indirection layer

The upgrade description is just data - it doesn't
need any behaviour associated with it, so it's
sufficient, simpler and more direct to just use
structs where we can, making the code easier
to understand and shorter.

https://code.launchpad.net/~rogpeppe/juju-core/502-upgrades-simplify/+merge/206361

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/63530048/

Affected files (+137, -196 lines):
   A [revision details]
   M upgrades/lockdirectory.go
   M upgrades/lockdirectory_test.go
   M upgrades/operations.go
   M upgrades/rsyslogconf.go
   M upgrades/rsyslogconf_test.go
   M upgrades/steps118.go
   M upgrades/upgrade.go
   M upgrades/upgrade_test.go

Revision history for this message
William Reade (fwereade) wrote :

AFAICS, this just makes the code harder to change. Opinions may
reasonably differ re likelihood of changes that'd cause the interface
implementation to pay off, but IME the aggregated cost of designing for
change is trivial compared to the cost of failing to do so, and so a CL
that just removes flexibility does not lgtm.

https://codereview.appspot.com/63530048/

Revision history for this message
Roger Peppe (rogpeppe) wrote :

On 17 February 2014 10:34, <email address hidden> wrote:
> AFAICS, this just makes the code harder to change. Opinions may
> reasonably differ re likelihood of changes that'd cause the interface
> implementation to pay off, but IME the aggregated cost of designing for
> change is trivial compared to the cost of failing to do so, and so a CL
> that just removes flexibility does not lgtm.

For the record, my view is precisely the opposite in this case.
For methods that simply return some data, it is easier just
to have a field containing the data rather than an extra method
to call that returns the data and an interface type that encapsulates
that.

Adding an extra layer of indirection does *not* make things easier
to change, particularly when we are talking about a package-internal
detail here.

Any change is likely to require changes to the signature of the interface
type, and therefore to the user of that type. Given that, we may as well
just store the data in fields and avoid the need to change all the
interface implementations as *well* as the users of the type.

Unmerged revisions

2328. By Roger Peppe

upgrades: simplify

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'upgrades/lockdirectory.go'
--- upgrades/lockdirectory.go 2014-02-13 05:54:35 +0000
+++ upgrades/lockdirectory.go 2014-02-14 09:17:52 +0000
@@ -21,8 +21,8 @@
21// we need to change the ownership of the lock directory to ubuntu:ubuntu.21// we need to change the ownership of the lock directory to ubuntu:ubuntu.
22// Also we need to make sure that this directory exists on machines with no22// Also we need to make sure that this directory exists on machines with no
23// units.23// units.
24func ensureLockDirExistsAndUbuntuWritable(context Context) error {24func ensureLockDirExistsAndUbuntuWritable(context *Context) error {
25 lockDir := path.Join(context.AgentConfig().DataDir(), "locks")25 lockDir := path.Join(context.AgentConfig.DataDir(), "locks")
26 // We only try to change ownership if there is an ubuntu user26 // We only try to change ownership if there is an ubuntu user
27 // defined, and we determine this by the existance of the home dir.27 // defined, and we determine this by the existance of the home dir.
28 command := fmt.Sprintf(""+28 command := fmt.Sprintf(""+
2929
=== modified file 'upgrades/lockdirectory_test.go'
--- upgrades/lockdirectory_test.go 2014-02-13 05:54:35 +0000
+++ upgrades/lockdirectory_test.go 2014-02-14 09:17:52 +0000
@@ -23,7 +23,7 @@
23 home string23 home string
24 datadir string24 datadir string
25 lockdir string25 lockdir string
26 ctx upgrades.Context26 ctx *upgrades.Context
27}27}
2828
29var _ = gc.Suite(&ensureLockDirSuite{})29var _ = gc.Suite(&ensureLockDirSuite{})
@@ -52,7 +52,9 @@
5252
53 s.datadir = c.MkDir()53 s.datadir = c.MkDir()
54 s.lockdir = filepath.Join(s.datadir, "locks")54 s.lockdir = filepath.Join(s.datadir, "locks")
55 s.ctx = &mockContext{agentConfig: &mockAgentConfig{dataDir: s.datadir}}55 s.ctx = &upgrades.Context{
56 AgentConfig: &mockAgentConfig{dataDir: s.datadir},
57 }
56}58}
5759
58func (s *ensureLockDirSuite) assertChownCalled(c *gc.C) {60func (s *ensureLockDirSuite) assertChownCalled(c *gc.C) {
5961
=== modified file 'upgrades/operations.go'
--- upgrades/operations.go 2014-02-13 05:27:59 +0000
+++ upgrades/operations.go 2014-02-14 09:17:52 +0000
@@ -5,16 +5,11 @@
55
6import "launchpad.net/juju-core/version"6import "launchpad.net/juju-core/version"
77
8// upgradeOperations returns an ordered slice of sets of operations needed8// upgradeOperations holds an ordered slice of sets of operations needed
9// to upgrade Juju to particular version. The slice is ordered by target9// to upgrade Juju to particular version. The slice is ordered by target
10// version, so that the sets of operations are executed in order from oldest10// version, so that the sets of operations are executed in order from oldest
11// version to most recent.11// version to most recent.
12var upgradeOperations = func() []UpgradeOperation {12var upgradeOperations = []UpgradeOperation{{
13 steps := []UpgradeOperation{13 TargetVersion: version.MustParse("1.18.0"),
14 upgradeToVersion{14 Steps: stepsFor118(),
15 version.MustParse("1.18.0"),15}}
16 stepsFor118(),
17 },
18 }
19 return steps
20}
2116
=== modified file 'upgrades/rsyslogconf.go'
--- upgrades/rsyslogconf.go 2014-02-14 00:48:23 +0000
+++ upgrades/rsyslogconf.go 2014-02-14 09:17:52 +0000
@@ -9,11 +9,11 @@
9 "launchpad.net/juju-core/log/syslog"9 "launchpad.net/juju-core/log/syslog"
10)10)
1111
12func confParams(context Context) (machineTag, namespace string, port int, err error) {12func confParams(context *Context) (machineTag, namespace string, port int, err error) {
13 namespace = context.AgentConfig().Value(agent.Namespace)13 namespace = context.AgentConfig.Value(agent.Namespace)
14 machineTag = context.AgentConfig().Tag()14 machineTag = context.AgentConfig.Tag()
1515
16 environment := context.APIState().Environment()16 environment := context.APIState.Environment()
17 config, err := environment.EnvironConfig()17 config, err := environment.EnvironConfig()
18 if err != nil {18 if err != nil {
19 return "", "", 0, err19 return "", "", 0, err
@@ -23,7 +23,7 @@
23}23}
2424
25// upgradeStateServerRsyslogConfig upgrades a rsuslog config file on a state server.25// upgradeStateServerRsyslogConfig upgrades a rsuslog config file on a state server.
26func upgradeStateServerRsyslogConfig(context Context) (err error) {26func upgradeStateServerRsyslogConfig(context *Context) (err error) {
27 machineTag, namespace, syslogPort, err := confParams(context)27 machineTag, namespace, syslogPort, err := confParams(context)
28 configRenderer := syslog.NewAccumulateConfig(machineTag, syslogPort, namespace)28 configRenderer := syslog.NewAccumulateConfig(machineTag, syslogPort, namespace)
29 data, err := configRenderer.Render()29 data, err := configRenderer.Render()
@@ -34,9 +34,9 @@
34}34}
3535
36// upgradeHostMachineRsyslogConfig upgrades a rsuslog config file on a host machine.36// upgradeHostMachineRsyslogConfig upgrades a rsuslog config file on a host machine.
37func upgradeHostMachineRsyslogConfig(context Context) (err error) {37func upgradeHostMachineRsyslogConfig(context *Context) (err error) {
38 machineTag, namespace, syslogPort, err := confParams(context)38 machineTag, namespace, syslogPort, err := confParams(context)
39 addr, err := context.AgentConfig().APIAddresses()39 addr, err := context.AgentConfig.APIAddresses()
40 if err != nil {40 if err != nil {
41 return err41 return err
42 }42 }
4343
=== modified file 'upgrades/rsyslogconf_test.go'
--- upgrades/rsyslogconf_test.go 2014-02-13 05:54:35 +0000
+++ upgrades/rsyslogconf_test.go 2014-02-14 09:17:52 +0000
@@ -20,7 +20,7 @@
20 jujutesting.JujuConnSuite20 jujutesting.JujuConnSuite
2121
22 syslogPath string22 syslogPath string
23 ctx upgrades.Context23 ctx *upgrades.Context
24}24}
2525
26var _ = gc.Suite(&rsyslogSuite{})26var _ = gc.Suite(&rsyslogSuite{})
@@ -33,13 +33,13 @@
33 s.PatchValue(&environs.RsyslogConfPath, s.syslogPath)33 s.PatchValue(&environs.RsyslogConfPath, s.syslogPath)
3434
35 apiState, _ := s.OpenAPIAsNewMachine(c, state.JobManageState, state.JobManageEnviron)35 apiState, _ := s.OpenAPIAsNewMachine(c, state.JobManageState, state.JobManageEnviron)
36 s.ctx = &mockContext{36 s.ctx = &upgrades.Context{
37 agentConfig: &mockAgentConfig{37 AgentConfig: &mockAgentConfig{
38 tag: "machine-tag",38 tag: "machine-tag",
39 namespace: "namespace",39 namespace: "namespace",
40 apiAddresses: []string{"server:1234"},40 apiAddresses: []string{"server:1234"},
41 },41 },
42 apiState: apiState,42 APIState: apiState,
43 }43 }
44}44}
4545
4646
=== modified file 'upgrades/steps118.go'
--- upgrades/steps118.go 2014-02-13 05:22:01 +0000
+++ upgrades/steps118.go 2014-02-14 09:17:52 +0000
@@ -5,21 +5,18 @@
55
6// stepsFor118 returns upgrade steps to upgrade to a Juju 1.18 deployment.6// stepsFor118 returns upgrade steps to upgrade to a Juju 1.18 deployment.
7func stepsFor118() []UpgradeStep {7func stepsFor118() []UpgradeStep {
8 return []UpgradeStep{8 return []UpgradeStep{{
9 &upgradeStep{9 Description: "make $DATADIR/locks owned by ubuntu:ubuntu",
10 description: "make $DATADIR/locks owned by ubuntu:ubuntu",10 Targets: []UpgradeTarget{HostMachine},
11 targets: []UpgradeTarget{HostMachine},11 Run: ensureLockDirExistsAndUbuntuWritable,
12 run: ensureLockDirExistsAndUbuntuWritable,12 }, {
13 },13 Description: "upgrade rsyslog config file on state server",
14 &upgradeStep{14 Targets: []UpgradeTarget{StateServer},
15 description: "upgrade rsyslog config file on state server",15 Run: upgradeStateServerRsyslogConfig,
16 targets: []UpgradeTarget{StateServer},16 }, {
17 run: upgradeStateServerRsyslogConfig,17 Description: "upgrade rsyslog config file on host machine",
18 },18 Targets: []UpgradeTarget{HostMachine},
19 &upgradeStep{19 Run: upgradeHostMachineRsyslogConfig,
20 description: "upgrade rsyslog config file on host machine",20 },
21 targets: []UpgradeTarget{HostMachine},
22 run: upgradeHostMachineRsyslogConfig,
23 },
24 }21 }
25}22}
2623
=== modified file 'upgrades/upgrade.go'
--- upgrades/upgrade.go 2014-02-13 05:27:59 +0000
+++ upgrades/upgrade.go 2014-02-14 09:17:52 +0000
@@ -17,27 +17,27 @@
1717
18// UpgradeStep defines an idempotent operation that is run to perform18// UpgradeStep defines an idempotent operation that is run to perform
19// a specific upgrade step.19// a specific upgrade step.
20type UpgradeStep interface {20type UpgradeStep struct {
21 // Description is a human readable description of what the upgrade step does.21 // Description is a human readable description of what the upgrade step does.
22 Description() string22 Description string
2323
24 // Targets returns the target machine types for which the upgrade step is applicable.24 // Targets returns the target machine types for which the upgrade step is applicable.
25 Targets() []UpgradeTarget25 Targets []UpgradeTarget
2626
27 // Run executes the upgrade business logic.27 // Run executes the upgrade business logic.
28 Run(context Context) error28 Run func(context *Context) error
29}29}
3030
31// UpgradeOperation defines what steps to perform to upgrade to a target version.31// UpgradeOperation defines what steps to perform to upgrade to a target version.
32type UpgradeOperation interface {32type UpgradeOperation struct {
33 // The Juju version for which this operation is applicable.33 // The Juju version for which this operation is applicable.
34 // Upgrade operations designed for versions of Juju earlier34 // Upgrade operations designed for versions of Juju earlier
35 // than we are upgrading from are not run since such steps would35 // than we are upgrading from are not run since such steps would
36 // already have been used to get to the version we are running now.36 // already have been used to get to the version we are running now.
37 TargetVersion() version.Number37 TargetVersion version.Number
3838
39 // Steps to perform during an upgrade.39 // Steps to perform during an upgrade.
40 Steps() []UpgradeStep40 Steps []UpgradeStep
41}41}
4242
43// UpgradeTarget defines the type of machine for which a particular upgrade43// UpgradeTarget defines the type of machine for which a particular upgrade
@@ -55,50 +55,17 @@
55 StateServer = UpgradeTarget("stateServer")55 StateServer = UpgradeTarget("stateServer")
56)56)
5757
58// upgradeToVersion encapsulates the steps which need to be run to
59// upgrade any prior version of Juju to targetVersion.
60type upgradeToVersion struct {
61 targetVersion version.Number
62 steps []UpgradeStep
63}
64
65// Steps is defined on the UpgradeOperation interface.
66func (u upgradeToVersion) Steps() []UpgradeStep {
67 return u.steps
68}
69
70// TargetVersion is defined on the UpgradeOperation interface.
71func (u upgradeToVersion) TargetVersion() version.Number {
72 return u.targetVersion
73}
74
75// Context is used give the upgrade steps attributes needed58// Context is used give the upgrade steps attributes needed
76// to do their job.59// to do their job.
77type Context interface {60// Work in progress........
61// Exactly what a context needs is to be determined as the
62// implementation evolves.
63type Context struct {
78 // APIState returns an API connection to state.64 // APIState returns an API connection to state.
79 APIState() *api.State65 APIState *api.State
8066
81 // AgentConfig returns the agent config for the machine that is being upgraded.67 // AgentConfig returns the agent config for the machine that is being upgraded.
82 AgentConfig() agent.Config68 AgentConfig agent.Config
83}
84
85// UpgradeContext is a default Context implementation.
86type UpgradeContext struct {
87 // Work in progress........
88 // Exactly what a context needs is to be determined as the
89 // implementation evolves.
90 st *api.State
91 agentConfig agent.Config
92}
93
94// APIState is defined on the Context interface.
95func (c *UpgradeContext) APIState() *api.State {
96 return c.st
97}
98
99// AgentConfig is defined on the Context interface.
100func (c *UpgradeContext) AgentConfig() agent.Config {
101 return c.agentConfig
102}69}
10370
104// upgradeError records a description of the step being performed and the error.71// upgradeError records a description of the step being performed and the error.
@@ -113,14 +80,14 @@
11380
114// PerformUpgrade runs the business logic needed to upgrade the current "from" version to this81// PerformUpgrade runs the business logic needed to upgrade the current "from" version to this
115// version of Juju on the "target" type of machine.82// version of Juju on the "target" type of machine.
116func PerformUpgrade(from version.Number, target UpgradeTarget, context Context) *upgradeError {83func PerformUpgrade(from version.Number, target UpgradeTarget, context *Context) *upgradeError {
117 // If from is not known, it is 1.16.84 // If from is not known, it is 1.16.
118 if from == version.Zero {85 if from == version.Zero {
119 from = version.MustParse("1.16.0")86 from = version.MustParse("1.16.0")
120 }87 }
121 for _, upgradeOps := range upgradeOperations() {88 for _, upgradeOps := range upgradeOperations {
122 // Do not run steps for versions of Juju earlier or same as we are upgrading from.89 // Do not run steps for versions of Juju earlier or same as we are upgrading from.
123 if upgradeOps.TargetVersion().LessEqual(from) {90 if upgradeOps.TargetVersion.LessEqual(from) {
124 continue91 continue
125 }92 }
126 if err := runUpgradeSteps(context, target, upgradeOps); err != nil {93 if err := runUpgradeSteps(context, target, upgradeOps); err != nil {
@@ -132,12 +99,12 @@
13299
133// validTarget returns true if target is in step.Targets().100// validTarget returns true if target is in step.Targets().
134func validTarget(target UpgradeTarget, step UpgradeStep) bool {101func validTarget(target UpgradeTarget, step UpgradeStep) bool {
135 for _, opTarget := range step.Targets() {102 for _, opTarget := range step.Targets {
136 if target == AllMachines || target == opTarget {103 if target == AllMachines || target == opTarget {
137 return true104 return true
138 }105 }
139 }106 }
140 return len(step.Targets()) == 0107 return len(step.Targets) == 0
141}108}
142109
143// runUpgradeSteps runs all the upgrade steps relevant to target.110// runUpgradeSteps runs all the upgrade steps relevant to target.
@@ -145,38 +112,17 @@
145// subsequent steps may required successful completion of earlier ones.112// subsequent steps may required successful completion of earlier ones.
146// The steps must be idempotent so that the entire upgrade operation can113// The steps must be idempotent so that the entire upgrade operation can
147// be retried.114// be retried.
148func runUpgradeSteps(context Context, target UpgradeTarget, upgradeOp UpgradeOperation) *upgradeError {115func runUpgradeSteps(context *Context, target UpgradeTarget, upgradeOp UpgradeOperation) *upgradeError {
149 for _, step := range upgradeOp.Steps() {116 for _, step := range upgradeOp.Steps {
150 if !validTarget(target, step) {117 if !validTarget(target, step) {
151 continue118 continue
152 }119 }
153 if err := step.Run(context); err != nil {120 if err := step.Run(context); err != nil {
154 return &upgradeError{121 return &upgradeError{
155 description: step.Description(),122 description: step.Description,
156 err: err,123 err: err,
157 }124 }
158 }125 }
159 }126 }
160 return nil127 return nil
161}128}
162
163type upgradeStep struct {
164 description string
165 targets []UpgradeTarget
166 run func(Context) error
167}
168
169// Description is defined on the UpgradeStep interface.
170func (step *upgradeStep) Description() string {
171 return step.description
172}
173
174// Targets is defined on the UpgradeStep interface.
175func (step *upgradeStep) Targets() []UpgradeTarget {
176 return step.targets
177}
178
179// Run is defined on the UpgradeStep interface.
180func (step *upgradeStep) Run(context Context) error {
181 return step.run(context)
182}
183129
=== modified file 'upgrades/upgrade_test.go'
--- upgrades/upgrade_test.go 2014-02-13 05:27:59 +0000
+++ upgrades/upgrade_test.go 2014-02-14 09:17:52 +0000
@@ -28,7 +28,7 @@
28func assertExpectedSteps(c *gc.C, steps []upgrades.UpgradeStep, expectedSteps []string) {28func assertExpectedSteps(c *gc.C, steps []upgrades.UpgradeStep, expectedSteps []string) {
29 var stepNames = make([]string, len(steps))29 var stepNames = make([]string, len(steps))
30 for i, step := range steps {30 for i, step := range steps {
31 stepNames[i] = step.Description()31 stepNames[i] = step.Description
32 }32 }
33 c.Assert(stepNames, gc.DeepEquals, expectedSteps)33 c.Assert(stepNames, gc.DeepEquals, expectedSteps)
34}34}
@@ -39,38 +39,11 @@
3939
40var _ = gc.Suite(&upgradeSuite{})40var _ = gc.Suite(&upgradeSuite{})
4141
42type mockUpgradeOperation struct {42func runStep(ctx *testContext, u upgrades.UpgradeStep, context *upgrades.Context) error {
43 targetVersion version.Number43 if strings.HasSuffix(u.Description, "error") {
44 steps []upgrades.UpgradeStep
45}
46
47func (m *mockUpgradeOperation) TargetVersion() version.Number {
48 return m.targetVersion
49}
50
51func (m *mockUpgradeOperation) Steps() []upgrades.UpgradeStep {
52 return m.steps
53}
54
55type mockUpgradeStep struct {
56 msg string
57 targets []upgrades.UpgradeTarget
58}
59
60func (u *mockUpgradeStep) Description() string {
61 return u.msg
62}
63
64func (u *mockUpgradeStep) Targets() []upgrades.UpgradeTarget {
65 return u.targets
66}
67
68func (u *mockUpgradeStep) Run(context upgrades.Context) error {
69 if strings.HasSuffix(u.msg, "error") {
70 return errors.New("upgrade error occurred")44 return errors.New("upgrade error occurred")
71 }45 }
72 ctx := context.(*mockContext)46 ctx.messages = append(ctx.messages, u.Description)
73 ctx.messages = append(ctx.messages, u.msg)
74 return nil47 return nil
75}48}
7649
@@ -122,44 +95,72 @@
122 return upgradeTargets95 return upgradeTargets
123}96}
12497
125func upgradeOperations() []upgrades.UpgradeOperation {98type testContext struct {
126 steps := []upgrades.UpgradeOperation{99 messages []string
127 &mockUpgradeOperation{100}
128 targetVersion: version.MustParse("1.12.0"),101
129 steps: []upgrades.UpgradeStep{102func upgradeOperations(testCtxt *testContext) []upgrades.UpgradeOperation {
130 &mockUpgradeStep{"step 1 - 1.12.0", nil},103 steps := []upgrades.UpgradeOperation{{
131 &mockUpgradeStep{"step 2 error", targets(upgrades.HostMachine)},104 TargetVersion: version.MustParse("1.12.0"),
132 &mockUpgradeStep{"step 3", targets(upgrades.HostMachine)},105 Steps: []upgrades.UpgradeStep{{
133 },106 Description: "step 1 - 1.12.0",
134 },107 }, {
135 &mockUpgradeOperation{108 Description: "step 2 error",
136 targetVersion: version.MustParse("1.16.0"),109 Targets: targets(upgrades.HostMachine),
137 steps: []upgrades.UpgradeStep{110 }, {
138 &mockUpgradeStep{"step 1 - 1.16.0", targets(upgrades.HostMachine)},111 Description: "step 3",
139 &mockUpgradeStep{"step 2 - 1.16.0", targets(upgrades.HostMachine)},112 Targets: targets(upgrades.HostMachine),
140 &mockUpgradeStep{"step 3 - 1.16.0", targets(upgrades.StateServer)},113 },
141 },114 },
142 },115 }, {
143 &mockUpgradeOperation{116 TargetVersion: version.MustParse("1.16.0"),
144 targetVersion: version.MustParse("1.17.0"),117 Steps: []upgrades.UpgradeStep{{
145 steps: []upgrades.UpgradeStep{118 Description: "step 1 - 1.16.0",
146 &mockUpgradeStep{"step 1 - 1.17.0", targets(upgrades.HostMachine)},119 Targets: targets(upgrades.HostMachine),
147 },120 }, {
148 },121 Description: "step 2 - 1.16.0",
149 &mockUpgradeOperation{122 Targets: targets(upgrades.HostMachine),
150 targetVersion: version.MustParse("1.17.1"),123 }, {
151 steps: []upgrades.UpgradeStep{124 Description: "step 3 - 1.16.0",
152 &mockUpgradeStep{"step 1 - 1.17.1", targets(upgrades.HostMachine)},125 Targets: targets(upgrades.StateServer),
153 &mockUpgradeStep{"step 2 - 1.17.1", targets(upgrades.StateServer)},126 },
154 },127 },
155 },128 }, {
156 &mockUpgradeOperation{129 TargetVersion: version.MustParse("1.17.0"),
157 targetVersion: version.MustParse("1.18.0"),130 Steps: []upgrades.UpgradeStep{{
158 steps: []upgrades.UpgradeStep{131 Description: "step 1 - 1.17.0",
159 &mockUpgradeStep{"step 1 - 1.18.0", targets(upgrades.HostMachine)},132 Targets: targets(upgrades.HostMachine),
160 &mockUpgradeStep{"step 2 - 1.18.0", targets(upgrades.StateServer)},133 },
161 },134 },
162 },135 }, {
136 TargetVersion: version.MustParse("1.17.1"),
137 Steps: []upgrades.UpgradeStep{{
138 Description: "step 1 - 1.17.1",
139 Targets: targets(upgrades.HostMachine),
140 }, {
141 Description: "step 2 - 1.17.1",
142 Targets: targets(upgrades.StateServer),
143 },
144 },
145 }, {
146 TargetVersion: version.MustParse("1.18.0"),
147 Steps: []upgrades.UpgradeStep{{
148 Description: "step 1 - 1.18.0",
149 Targets: targets(upgrades.HostMachine),
150 }, {
151 Description: "step 2 - 1.18.0",
152 Targets: targets(upgrades.StateServer),
153 },
154 },
155 },
156 }
157 for _, op := range steps {
158 for i, step := range op.Steps {
159 step := step
160 op.Steps[i].Run = func(ctxt *upgrades.Context) error {
161 return runStep(testCtxt, step, ctxt)
162 }
163 }
163 }164 }
164 return steps165 return steps
165}166}
@@ -213,31 +214,29 @@
213}214}
214215
215func (s *upgradeSuite) TestPerformUpgrade(c *gc.C) {216func (s *upgradeSuite) TestPerformUpgrade(c *gc.C) {
216 s.PatchValue(upgrades.UpgradeOperations, upgradeOperations)217 testCtxt := &testContext{}
218 s.PatchValue(upgrades.UpgradeOperations, upgradeOperations(testCtxt))
217 for i, test := range upgradeTests {219 for i, test := range upgradeTests {
218 c.Logf("%d: %s", i, test.about)220 c.Logf("%d: %s", i, test.about)
219 var messages []string221 testCtxt.messages = nil
220 ctx := &mockContext{
221 messages: messages,
222 }
223 fromVersion := version.Zero222 fromVersion := version.Zero
224 if test.fromVersion != "" {223 if test.fromVersion != "" {
225 fromVersion = version.MustParse(test.fromVersion)224 fromVersion = version.MustParse(test.fromVersion)
226 }225 }
227 err := upgrades.PerformUpgrade(fromVersion, test.target, ctx)226 err := upgrades.PerformUpgrade(fromVersion, test.target, &upgrades.Context{})
228 if test.err == "" {227 if test.err == "" {
229 c.Check(err, gc.IsNil)228 c.Check(err, gc.IsNil)
230 } else {229 } else {
231 c.Check(err, gc.ErrorMatches, test.err)230 c.Check(err, gc.ErrorMatches, test.err)
232 }231 }
233 c.Check(ctx.messages, jc.DeepEquals, test.expectedSteps)232 c.Check(testCtxt.messages, jc.DeepEquals, test.expectedSteps)
234 }233 }
235}234}
236235
237func (s *upgradeSuite) TestUpgradeOperationsOrdered(c *gc.C) {236func (s *upgradeSuite) TestUpgradeOperationsOrdered(c *gc.C) {
238 var previous version.Number237 var previous version.Number
239 for i, utv := range (*upgrades.UpgradeOperations)() {238 for i, utv := range *upgrades.UpgradeOperations {
240 vers := utv.TargetVersion()239 vers := utv.TargetVersion
241 if i > 0 {240 if i > 0 {
242 c.Check(previous.Less(vers), jc.IsTrue)241 c.Check(previous.Less(vers), jc.IsTrue)
243 }242 }
@@ -249,8 +248,8 @@
249248
250func (s *upgradeSuite) TestUpgradeOperationsVersions(c *gc.C) {249func (s *upgradeSuite) TestUpgradeOperationsVersions(c *gc.C) {
251 var versions []string250 var versions []string
252 for _, utv := range (*upgrades.UpgradeOperations)() {251 for _, utv := range *upgrades.UpgradeOperations {
253 versions = append(versions, utv.TargetVersion().String())252 versions = append(versions, utv.TargetVersion.String())
254253
255 }254 }
256 c.Assert(versions, gc.DeepEquals, expectedVersions)255 c.Assert(versions, gc.DeepEquals, expectedVersions)

Subscribers

People subscribed via source and target branches

to status/vote changes: