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
1=== modified file 'upgrades/lockdirectory.go'
2--- upgrades/lockdirectory.go 2014-02-13 05:54:35 +0000
3+++ upgrades/lockdirectory.go 2014-02-14 09:17:52 +0000
4@@ -21,8 +21,8 @@
5 // we need to change the ownership of the lock directory to ubuntu:ubuntu.
6 // Also we need to make sure that this directory exists on machines with no
7 // units.
8-func ensureLockDirExistsAndUbuntuWritable(context Context) error {
9- lockDir := path.Join(context.AgentConfig().DataDir(), "locks")
10+func ensureLockDirExistsAndUbuntuWritable(context *Context) error {
11+ lockDir := path.Join(context.AgentConfig.DataDir(), "locks")
12 // We only try to change ownership if there is an ubuntu user
13 // defined, and we determine this by the existance of the home dir.
14 command := fmt.Sprintf(""+
15
16=== modified file 'upgrades/lockdirectory_test.go'
17--- upgrades/lockdirectory_test.go 2014-02-13 05:54:35 +0000
18+++ upgrades/lockdirectory_test.go 2014-02-14 09:17:52 +0000
19@@ -23,7 +23,7 @@
20 home string
21 datadir string
22 lockdir string
23- ctx upgrades.Context
24+ ctx *upgrades.Context
25 }
26
27 var _ = gc.Suite(&ensureLockDirSuite{})
28@@ -52,7 +52,9 @@
29
30 s.datadir = c.MkDir()
31 s.lockdir = filepath.Join(s.datadir, "locks")
32- s.ctx = &mockContext{agentConfig: &mockAgentConfig{dataDir: s.datadir}}
33+ s.ctx = &upgrades.Context{
34+ AgentConfig: &mockAgentConfig{dataDir: s.datadir},
35+ }
36 }
37
38 func (s *ensureLockDirSuite) assertChownCalled(c *gc.C) {
39
40=== modified file 'upgrades/operations.go'
41--- upgrades/operations.go 2014-02-13 05:27:59 +0000
42+++ upgrades/operations.go 2014-02-14 09:17:52 +0000
43@@ -5,16 +5,11 @@
44
45 import "launchpad.net/juju-core/version"
46
47-// upgradeOperations returns an ordered slice of sets of operations needed
48+// upgradeOperations holds an ordered slice of sets of operations needed
49 // to upgrade Juju to particular version. The slice is ordered by target
50 // version, so that the sets of operations are executed in order from oldest
51 // version to most recent.
52-var upgradeOperations = func() []UpgradeOperation {
53- steps := []UpgradeOperation{
54- upgradeToVersion{
55- version.MustParse("1.18.0"),
56- stepsFor118(),
57- },
58- }
59- return steps
60-}
61+var upgradeOperations = []UpgradeOperation{{
62+ TargetVersion: version.MustParse("1.18.0"),
63+ Steps: stepsFor118(),
64+}}
65
66=== modified file 'upgrades/rsyslogconf.go'
67--- upgrades/rsyslogconf.go 2014-02-14 00:48:23 +0000
68+++ upgrades/rsyslogconf.go 2014-02-14 09:17:52 +0000
69@@ -9,11 +9,11 @@
70 "launchpad.net/juju-core/log/syslog"
71 )
72
73-func confParams(context Context) (machineTag, namespace string, port int, err error) {
74- namespace = context.AgentConfig().Value(agent.Namespace)
75- machineTag = context.AgentConfig().Tag()
76+func confParams(context *Context) (machineTag, namespace string, port int, err error) {
77+ namespace = context.AgentConfig.Value(agent.Namespace)
78+ machineTag = context.AgentConfig.Tag()
79
80- environment := context.APIState().Environment()
81+ environment := context.APIState.Environment()
82 config, err := environment.EnvironConfig()
83 if err != nil {
84 return "", "", 0, err
85@@ -23,7 +23,7 @@
86 }
87
88 // upgradeStateServerRsyslogConfig upgrades a rsuslog config file on a state server.
89-func upgradeStateServerRsyslogConfig(context Context) (err error) {
90+func upgradeStateServerRsyslogConfig(context *Context) (err error) {
91 machineTag, namespace, syslogPort, err := confParams(context)
92 configRenderer := syslog.NewAccumulateConfig(machineTag, syslogPort, namespace)
93 data, err := configRenderer.Render()
94@@ -34,9 +34,9 @@
95 }
96
97 // upgradeHostMachineRsyslogConfig upgrades a rsuslog config file on a host machine.
98-func upgradeHostMachineRsyslogConfig(context Context) (err error) {
99+func upgradeHostMachineRsyslogConfig(context *Context) (err error) {
100 machineTag, namespace, syslogPort, err := confParams(context)
101- addr, err := context.AgentConfig().APIAddresses()
102+ addr, err := context.AgentConfig.APIAddresses()
103 if err != nil {
104 return err
105 }
106
107=== modified file 'upgrades/rsyslogconf_test.go'
108--- upgrades/rsyslogconf_test.go 2014-02-13 05:54:35 +0000
109+++ upgrades/rsyslogconf_test.go 2014-02-14 09:17:52 +0000
110@@ -20,7 +20,7 @@
111 jujutesting.JujuConnSuite
112
113 syslogPath string
114- ctx upgrades.Context
115+ ctx *upgrades.Context
116 }
117
118 var _ = gc.Suite(&rsyslogSuite{})
119@@ -33,13 +33,13 @@
120 s.PatchValue(&environs.RsyslogConfPath, s.syslogPath)
121
122 apiState, _ := s.OpenAPIAsNewMachine(c, state.JobManageState, state.JobManageEnviron)
123- s.ctx = &mockContext{
124- agentConfig: &mockAgentConfig{
125+ s.ctx = &upgrades.Context{
126+ AgentConfig: &mockAgentConfig{
127 tag: "machine-tag",
128 namespace: "namespace",
129 apiAddresses: []string{"server:1234"},
130 },
131- apiState: apiState,
132+ APIState: apiState,
133 }
134 }
135
136
137=== modified file 'upgrades/steps118.go'
138--- upgrades/steps118.go 2014-02-13 05:22:01 +0000
139+++ upgrades/steps118.go 2014-02-14 09:17:52 +0000
140@@ -5,21 +5,18 @@
141
142 // stepsFor118 returns upgrade steps to upgrade to a Juju 1.18 deployment.
143 func stepsFor118() []UpgradeStep {
144- return []UpgradeStep{
145- &upgradeStep{
146- description: "make $DATADIR/locks owned by ubuntu:ubuntu",
147- targets: []UpgradeTarget{HostMachine},
148- run: ensureLockDirExistsAndUbuntuWritable,
149- },
150- &upgradeStep{
151- description: "upgrade rsyslog config file on state server",
152- targets: []UpgradeTarget{StateServer},
153- run: upgradeStateServerRsyslogConfig,
154- },
155- &upgradeStep{
156- description: "upgrade rsyslog config file on host machine",
157- targets: []UpgradeTarget{HostMachine},
158- run: upgradeHostMachineRsyslogConfig,
159- },
160+ return []UpgradeStep{{
161+ Description: "make $DATADIR/locks owned by ubuntu:ubuntu",
162+ Targets: []UpgradeTarget{HostMachine},
163+ Run: ensureLockDirExistsAndUbuntuWritable,
164+ }, {
165+ Description: "upgrade rsyslog config file on state server",
166+ Targets: []UpgradeTarget{StateServer},
167+ Run: upgradeStateServerRsyslogConfig,
168+ }, {
169+ Description: "upgrade rsyslog config file on host machine",
170+ Targets: []UpgradeTarget{HostMachine},
171+ Run: upgradeHostMachineRsyslogConfig,
172+ },
173 }
174 }
175
176=== modified file 'upgrades/upgrade.go'
177--- upgrades/upgrade.go 2014-02-13 05:27:59 +0000
178+++ upgrades/upgrade.go 2014-02-14 09:17:52 +0000
179@@ -17,27 +17,27 @@
180
181 // UpgradeStep defines an idempotent operation that is run to perform
182 // a specific upgrade step.
183-type UpgradeStep interface {
184+type UpgradeStep struct {
185 // Description is a human readable description of what the upgrade step does.
186- Description() string
187+ Description string
188
189 // Targets returns the target machine types for which the upgrade step is applicable.
190- Targets() []UpgradeTarget
191+ Targets []UpgradeTarget
192
193 // Run executes the upgrade business logic.
194- Run(context Context) error
195+ Run func(context *Context) error
196 }
197
198 // UpgradeOperation defines what steps to perform to upgrade to a target version.
199-type UpgradeOperation interface {
200+type UpgradeOperation struct {
201 // The Juju version for which this operation is applicable.
202 // Upgrade operations designed for versions of Juju earlier
203 // than we are upgrading from are not run since such steps would
204 // already have been used to get to the version we are running now.
205- TargetVersion() version.Number
206+ TargetVersion version.Number
207
208 // Steps to perform during an upgrade.
209- Steps() []UpgradeStep
210+ Steps []UpgradeStep
211 }
212
213 // UpgradeTarget defines the type of machine for which a particular upgrade
214@@ -55,50 +55,17 @@
215 StateServer = UpgradeTarget("stateServer")
216 )
217
218-// upgradeToVersion encapsulates the steps which need to be run to
219-// upgrade any prior version of Juju to targetVersion.
220-type upgradeToVersion struct {
221- targetVersion version.Number
222- steps []UpgradeStep
223-}
224-
225-// Steps is defined on the UpgradeOperation interface.
226-func (u upgradeToVersion) Steps() []UpgradeStep {
227- return u.steps
228-}
229-
230-// TargetVersion is defined on the UpgradeOperation interface.
231-func (u upgradeToVersion) TargetVersion() version.Number {
232- return u.targetVersion
233-}
234-
235 // Context is used give the upgrade steps attributes needed
236 // to do their job.
237-type Context interface {
238+// Work in progress........
239+// Exactly what a context needs is to be determined as the
240+// implementation evolves.
241+type Context struct {
242 // APIState returns an API connection to state.
243- APIState() *api.State
244+ APIState *api.State
245
246 // AgentConfig returns the agent config for the machine that is being upgraded.
247- AgentConfig() agent.Config
248-}
249-
250-// UpgradeContext is a default Context implementation.
251-type UpgradeContext struct {
252- // Work in progress........
253- // Exactly what a context needs is to be determined as the
254- // implementation evolves.
255- st *api.State
256- agentConfig agent.Config
257-}
258-
259-// APIState is defined on the Context interface.
260-func (c *UpgradeContext) APIState() *api.State {
261- return c.st
262-}
263-
264-// AgentConfig is defined on the Context interface.
265-func (c *UpgradeContext) AgentConfig() agent.Config {
266- return c.agentConfig
267+ AgentConfig agent.Config
268 }
269
270 // upgradeError records a description of the step being performed and the error.
271@@ -113,14 +80,14 @@
272
273 // PerformUpgrade runs the business logic needed to upgrade the current "from" version to this
274 // version of Juju on the "target" type of machine.
275-func PerformUpgrade(from version.Number, target UpgradeTarget, context Context) *upgradeError {
276+func PerformUpgrade(from version.Number, target UpgradeTarget, context *Context) *upgradeError {
277 // If from is not known, it is 1.16.
278 if from == version.Zero {
279 from = version.MustParse("1.16.0")
280 }
281- for _, upgradeOps := range upgradeOperations() {
282+ for _, upgradeOps := range upgradeOperations {
283 // Do not run steps for versions of Juju earlier or same as we are upgrading from.
284- if upgradeOps.TargetVersion().LessEqual(from) {
285+ if upgradeOps.TargetVersion.LessEqual(from) {
286 continue
287 }
288 if err := runUpgradeSteps(context, target, upgradeOps); err != nil {
289@@ -132,12 +99,12 @@
290
291 // validTarget returns true if target is in step.Targets().
292 func validTarget(target UpgradeTarget, step UpgradeStep) bool {
293- for _, opTarget := range step.Targets() {
294+ for _, opTarget := range step.Targets {
295 if target == AllMachines || target == opTarget {
296 return true
297 }
298 }
299- return len(step.Targets()) == 0
300+ return len(step.Targets) == 0
301 }
302
303 // runUpgradeSteps runs all the upgrade steps relevant to target.
304@@ -145,38 +112,17 @@
305 // subsequent steps may required successful completion of earlier ones.
306 // The steps must be idempotent so that the entire upgrade operation can
307 // be retried.
308-func runUpgradeSteps(context Context, target UpgradeTarget, upgradeOp UpgradeOperation) *upgradeError {
309- for _, step := range upgradeOp.Steps() {
310+func runUpgradeSteps(context *Context, target UpgradeTarget, upgradeOp UpgradeOperation) *upgradeError {
311+ for _, step := range upgradeOp.Steps {
312 if !validTarget(target, step) {
313 continue
314 }
315 if err := step.Run(context); err != nil {
316 return &upgradeError{
317- description: step.Description(),
318+ description: step.Description,
319 err: err,
320 }
321 }
322 }
323 return nil
324 }
325-
326-type upgradeStep struct {
327- description string
328- targets []UpgradeTarget
329- run func(Context) error
330-}
331-
332-// Description is defined on the UpgradeStep interface.
333-func (step *upgradeStep) Description() string {
334- return step.description
335-}
336-
337-// Targets is defined on the UpgradeStep interface.
338-func (step *upgradeStep) Targets() []UpgradeTarget {
339- return step.targets
340-}
341-
342-// Run is defined on the UpgradeStep interface.
343-func (step *upgradeStep) Run(context Context) error {
344- return step.run(context)
345-}
346
347=== modified file 'upgrades/upgrade_test.go'
348--- upgrades/upgrade_test.go 2014-02-13 05:27:59 +0000
349+++ upgrades/upgrade_test.go 2014-02-14 09:17:52 +0000
350@@ -28,7 +28,7 @@
351 func assertExpectedSteps(c *gc.C, steps []upgrades.UpgradeStep, expectedSteps []string) {
352 var stepNames = make([]string, len(steps))
353 for i, step := range steps {
354- stepNames[i] = step.Description()
355+ stepNames[i] = step.Description
356 }
357 c.Assert(stepNames, gc.DeepEquals, expectedSteps)
358 }
359@@ -39,38 +39,11 @@
360
361 var _ = gc.Suite(&upgradeSuite{})
362
363-type mockUpgradeOperation struct {
364- targetVersion version.Number
365- steps []upgrades.UpgradeStep
366-}
367-
368-func (m *mockUpgradeOperation) TargetVersion() version.Number {
369- return m.targetVersion
370-}
371-
372-func (m *mockUpgradeOperation) Steps() []upgrades.UpgradeStep {
373- return m.steps
374-}
375-
376-type mockUpgradeStep struct {
377- msg string
378- targets []upgrades.UpgradeTarget
379-}
380-
381-func (u *mockUpgradeStep) Description() string {
382- return u.msg
383-}
384-
385-func (u *mockUpgradeStep) Targets() []upgrades.UpgradeTarget {
386- return u.targets
387-}
388-
389-func (u *mockUpgradeStep) Run(context upgrades.Context) error {
390- if strings.HasSuffix(u.msg, "error") {
391+func runStep(ctx *testContext, u upgrades.UpgradeStep, context *upgrades.Context) error {
392+ if strings.HasSuffix(u.Description, "error") {
393 return errors.New("upgrade error occurred")
394 }
395- ctx := context.(*mockContext)
396- ctx.messages = append(ctx.messages, u.msg)
397+ ctx.messages = append(ctx.messages, u.Description)
398 return nil
399 }
400
401@@ -122,44 +95,72 @@
402 return upgradeTargets
403 }
404
405-func upgradeOperations() []upgrades.UpgradeOperation {
406- steps := []upgrades.UpgradeOperation{
407- &mockUpgradeOperation{
408- targetVersion: version.MustParse("1.12.0"),
409- steps: []upgrades.UpgradeStep{
410- &mockUpgradeStep{"step 1 - 1.12.0", nil},
411- &mockUpgradeStep{"step 2 error", targets(upgrades.HostMachine)},
412- &mockUpgradeStep{"step 3", targets(upgrades.HostMachine)},
413- },
414- },
415- &mockUpgradeOperation{
416- targetVersion: version.MustParse("1.16.0"),
417- steps: []upgrades.UpgradeStep{
418- &mockUpgradeStep{"step 1 - 1.16.0", targets(upgrades.HostMachine)},
419- &mockUpgradeStep{"step 2 - 1.16.0", targets(upgrades.HostMachine)},
420- &mockUpgradeStep{"step 3 - 1.16.0", targets(upgrades.StateServer)},
421- },
422- },
423- &mockUpgradeOperation{
424- targetVersion: version.MustParse("1.17.0"),
425- steps: []upgrades.UpgradeStep{
426- &mockUpgradeStep{"step 1 - 1.17.0", targets(upgrades.HostMachine)},
427- },
428- },
429- &mockUpgradeOperation{
430- targetVersion: version.MustParse("1.17.1"),
431- steps: []upgrades.UpgradeStep{
432- &mockUpgradeStep{"step 1 - 1.17.1", targets(upgrades.HostMachine)},
433- &mockUpgradeStep{"step 2 - 1.17.1", targets(upgrades.StateServer)},
434- },
435- },
436- &mockUpgradeOperation{
437- targetVersion: version.MustParse("1.18.0"),
438- steps: []upgrades.UpgradeStep{
439- &mockUpgradeStep{"step 1 - 1.18.0", targets(upgrades.HostMachine)},
440- &mockUpgradeStep{"step 2 - 1.18.0", targets(upgrades.StateServer)},
441- },
442- },
443+type testContext struct {
444+ messages []string
445+}
446+
447+func upgradeOperations(testCtxt *testContext) []upgrades.UpgradeOperation {
448+ steps := []upgrades.UpgradeOperation{{
449+ TargetVersion: version.MustParse("1.12.0"),
450+ Steps: []upgrades.UpgradeStep{{
451+ Description: "step 1 - 1.12.0",
452+ }, {
453+ Description: "step 2 error",
454+ Targets: targets(upgrades.HostMachine),
455+ }, {
456+ Description: "step 3",
457+ Targets: targets(upgrades.HostMachine),
458+ },
459+ },
460+ }, {
461+ TargetVersion: version.MustParse("1.16.0"),
462+ Steps: []upgrades.UpgradeStep{{
463+ Description: "step 1 - 1.16.0",
464+ Targets: targets(upgrades.HostMachine),
465+ }, {
466+ Description: "step 2 - 1.16.0",
467+ Targets: targets(upgrades.HostMachine),
468+ }, {
469+ Description: "step 3 - 1.16.0",
470+ Targets: targets(upgrades.StateServer),
471+ },
472+ },
473+ }, {
474+ TargetVersion: version.MustParse("1.17.0"),
475+ Steps: []upgrades.UpgradeStep{{
476+ Description: "step 1 - 1.17.0",
477+ Targets: targets(upgrades.HostMachine),
478+ },
479+ },
480+ }, {
481+ TargetVersion: version.MustParse("1.17.1"),
482+ Steps: []upgrades.UpgradeStep{{
483+ Description: "step 1 - 1.17.1",
484+ Targets: targets(upgrades.HostMachine),
485+ }, {
486+ Description: "step 2 - 1.17.1",
487+ Targets: targets(upgrades.StateServer),
488+ },
489+ },
490+ }, {
491+ TargetVersion: version.MustParse("1.18.0"),
492+ Steps: []upgrades.UpgradeStep{{
493+ Description: "step 1 - 1.18.0",
494+ Targets: targets(upgrades.HostMachine),
495+ }, {
496+ Description: "step 2 - 1.18.0",
497+ Targets: targets(upgrades.StateServer),
498+ },
499+ },
500+ },
501+ }
502+ for _, op := range steps {
503+ for i, step := range op.Steps {
504+ step := step
505+ op.Steps[i].Run = func(ctxt *upgrades.Context) error {
506+ return runStep(testCtxt, step, ctxt)
507+ }
508+ }
509 }
510 return steps
511 }
512@@ -213,31 +214,29 @@
513 }
514
515 func (s *upgradeSuite) TestPerformUpgrade(c *gc.C) {
516- s.PatchValue(upgrades.UpgradeOperations, upgradeOperations)
517+ testCtxt := &testContext{}
518+ s.PatchValue(upgrades.UpgradeOperations, upgradeOperations(testCtxt))
519 for i, test := range upgradeTests {
520 c.Logf("%d: %s", i, test.about)
521- var messages []string
522- ctx := &mockContext{
523- messages: messages,
524- }
525+ testCtxt.messages = nil
526 fromVersion := version.Zero
527 if test.fromVersion != "" {
528 fromVersion = version.MustParse(test.fromVersion)
529 }
530- err := upgrades.PerformUpgrade(fromVersion, test.target, ctx)
531+ err := upgrades.PerformUpgrade(fromVersion, test.target, &upgrades.Context{})
532 if test.err == "" {
533 c.Check(err, gc.IsNil)
534 } else {
535 c.Check(err, gc.ErrorMatches, test.err)
536 }
537- c.Check(ctx.messages, jc.DeepEquals, test.expectedSteps)
538+ c.Check(testCtxt.messages, jc.DeepEquals, test.expectedSteps)
539 }
540 }
541
542 func (s *upgradeSuite) TestUpgradeOperationsOrdered(c *gc.C) {
543 var previous version.Number
544- for i, utv := range (*upgrades.UpgradeOperations)() {
545- vers := utv.TargetVersion()
546+ for i, utv := range *upgrades.UpgradeOperations {
547+ vers := utv.TargetVersion
548 if i > 0 {
549 c.Check(previous.Less(vers), jc.IsTrue)
550 }
551@@ -249,8 +248,8 @@
552
553 func (s *upgradeSuite) TestUpgradeOperationsVersions(c *gc.C) {
554 var versions []string
555- for _, utv := range (*upgrades.UpgradeOperations)() {
556- versions = append(versions, utv.TargetVersion().String())
557+ for _, utv := range *upgrades.UpgradeOperations {
558+ versions = append(versions, utv.TargetVersion.String())
559
560 }
561 c.Assert(versions, gc.DeepEquals, expectedVersions)

Subscribers

People subscribed via source and target branches

to status/vote changes: