Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(436)

Side by Side Diff: state/action_test.go

Issue 92630043: cleanup code to remove pending Actions (Closed)
Patch Set: cleanup code to remove pending Actions Created 10 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « state/action.go ('k') | state/cleanup.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 Canonical Ltd. 1 // Copyright 2014 Canonical Ltd.
2 // Licensed under the AGPLv3, see LICENCE file for details. 2 // Licensed under the AGPLv3, see LICENCE file for details.
3 3
4 package state_test 4 package state_test
5 5
6 import ( 6 import (
7 "github.com/juju/loggo"
7 jc "github.com/juju/testing/checkers" 8 jc "github.com/juju/testing/checkers"
8 gc "launchpad.net/gocheck" 9 gc "launchpad.net/gocheck"
9 10
10 "launchpad.net/juju-core/state" 11 "launchpad.net/juju-core/state"
11 ) 12 )
12 13
13 type ActionSuite struct { 14 type ActionSuite struct {
14 ConnSuite 15 ConnSuite
15 charm *state.Charm 16 charm *state.Charm
16 service *state.Service 17 service *state.Service
17 unit *state.Unit 18 unit *state.Unit
18 } 19 }
19 20
20 var _ = gc.Suite(&ActionSuite{}) 21 var _ = gc.Suite(&ActionSuite{})
21 22
22 func (s *ActionSuite) SetUpTest(c *gc.C) { 23 func (s *ActionSuite) SetUpTest(c *gc.C) {
23 s.ConnSuite.SetUpTest(c) 24 s.ConnSuite.SetUpTest(c)
24 s.charm = s.AddTestingCharm(c, "wordpress") 25 s.charm = s.AddTestingCharm(c, "wordpress")
25 var err error 26 var err error
26 s.service = s.AddTestingService(c, "wordpress", s.charm) 27 s.service = s.AddTestingService(c, "wordpress", s.charm)
27 c.Assert(err, gc.IsNil) 28 c.Assert(err, gc.IsNil)
28 s.unit, err = s.service.AddUnit() 29 s.unit, err = s.service.AddUnit()
29 c.Assert(err, gc.IsNil) 30 c.Assert(err, gc.IsNil)
30 c.Assert(s.unit.Series(), gc.Equals, "quantal") 31 c.Assert(s.unit.Series(), gc.Equals, "quantal")
31 } 32 }
32 33
33 func (s *ActionSuite) TestAddAction(c *gc.C) { 34 func (s *ActionSuite) TestAddAction(c *gc.C) {
34 » actionName := "fakeaction" 35 » name := "fakeaction"
35 » actionParams := map[string]interface{}{"outfile": "outfile.tar.bz2"} 36 » params := map[string]interface{}{"outfile": "outfile.tar.bz2"}
36 37
37 // verify can add an Action 38 // verify can add an Action
38 » actionId, err := s.unit.AddAction(actionName, actionParams) 39 » id, err := s.unit.AddAction(name, params)
39 c.Assert(err, gc.IsNil) 40 c.Assert(err, gc.IsNil)
40 » assertSaneActionId(c, actionId, s.unit.Name()) 41 » assertSaneActionId(c, id, s.unit.Name())
41 42
42 // verify we can get it back out by Id 43 // verify we can get it back out by Id
43 » action, err := s.State.Action(actionId) 44 » action, err := s.State.Action(id)
44 c.Assert(err, gc.IsNil) 45 c.Assert(err, gc.IsNil)
45 c.Assert(action, gc.NotNil) 46 c.Assert(action, gc.NotNil)
46 » c.Assert(action.Id(), gc.Equals, actionId) 47 » c.Assert(action.Id(), gc.Equals, id)
47 48
48 // verify we get out what we put in 49 // verify we get out what we put in
49 » c.Assert(action.Name(), gc.Equals, actionName) 50 » c.Assert(action.Name(), gc.Equals, name)
50 » c.Assert(action.Payload(), jc.DeepEquals, actionParams) 51 » c.Assert(action.Payload(), jc.DeepEquals, params)
52 }
53
54 func (s *ActionSuite) TestAddActionAcceptsDuplicateNames(c *gc.C) {
55 » name := "fakeaction"
56 » params_1 := map[string]interface{}{"outfile": "outfile.tar.bz2"}
57 » params_2 := map[string]interface{}{"infile": "infile.zip"}
58
59 » // verify can add two actions with same name
60 » id_1, err := s.unit.AddAction(name, params_1)
61 » c.Assert(err, gc.IsNil)
62 » assertSaneActionId(c, id_1, s.unit.Name())
63
64 » id_2, err := s.unit.AddAction(name, params_2)
65 » c.Assert(err, gc.IsNil)
66 » assertSaneActionId(c, id_2, s.unit.Name())
67
68 » c.Assert(id_1, gc.Not(gc.Equals), id_2)
69
70 » // verify both actually got added
71 » actions, err := s.State.UnitActions(s.unit.Name())
72 » c.Assert(err, gc.IsNil)
73 » c.Assert(len(actions), gc.Equals, 2)
74
75 » // verify we can Fail one, retrieve the other, and they're not mixed up
76 » action_1, err := s.State.Action(id_1)
77 » c.Assert(err, gc.IsNil)
78 » err = action_1.Fail("")
79 » c.Assert(err, gc.IsNil)
80
81 » action_2, err := s.State.Action(id_2)
82 » c.Assert(err, gc.IsNil)
83 » c.Assert(action_2.Payload(), gc.DeepEquals, params_2)
84
85 » // verify only one left, and it's the expected one
86 » actions, err = s.State.UnitActions(s.unit.Name())
87 » c.Assert(err, gc.IsNil)
88 » c.Assert(len(actions), gc.Equals, 1)
89 » c.Assert(actions[0].Id(), gc.Equals, id_2)
51 } 90 }
52 91
53 func (s *ActionSuite) TestAddActionLifecycle(c *gc.C) { 92 func (s *ActionSuite) TestAddActionLifecycle(c *gc.C) {
54 unit, err := s.State.Unit(s.unit.Name()) 93 unit, err := s.State.Unit(s.unit.Name())
55 c.Assert(err, gc.IsNil) 94 c.Assert(err, gc.IsNil)
56 preventUnitDestroyRemove(c, unit) 95 preventUnitDestroyRemove(c, unit)
57 96
58 // make unit state Dying 97 // make unit state Dying
59 err = unit.Destroy() 98 err = unit.Destroy()
60 c.Assert(err, gc.IsNil) 99 c.Assert(err, gc.IsNil)
61 100
62 // can add action to a dying unit 101 // can add action to a dying unit
63 » actionId, err := unit.AddAction("fakeaction1", map[string]interface{}{}) 102 » id, err := unit.AddAction("fakeaction1", map[string]interface{}{})
64 c.Assert(err, gc.IsNil) 103 c.Assert(err, gc.IsNil)
65 » assertSaneActionId(c, actionId, s.unit.Name()) 104 » assertSaneActionId(c, id, s.unit.Name())
66 105
67 // make sure unit is dead 106 // make sure unit is dead
68 err = unit.EnsureDead() 107 err = unit.EnsureDead()
69 c.Assert(err, gc.IsNil) 108 c.Assert(err, gc.IsNil)
70 109
71 // cannot add action to a dead unit 110 // cannot add action to a dead unit
72 _, err = unit.AddAction("fakeaction2", map[string]interface{}{}) 111 _, err = unit.AddAction("fakeaction2", map[string]interface{}{})
73 c.Assert(err, gc.ErrorMatches, "unit .* is dead") 112 c.Assert(err, gc.ErrorMatches, "unit .* is dead")
74 } 113 }
75 114
76 func (s *ActionSuite) TestAddActionFailsOnDeadUnitInTransaction(c *gc.C) { 115 func (s *ActionSuite) TestAddActionFailsOnDeadUnitInTransaction(c *gc.C) {
77 unit, err := s.State.Unit(s.unit.Name()) 116 unit, err := s.State.Unit(s.unit.Name())
78 c.Assert(err, gc.IsNil) 117 c.Assert(err, gc.IsNil)
79 preventUnitDestroyRemove(c, unit) 118 preventUnitDestroyRemove(c, unit)
80 119
81 killUnit := state.TransactionHook{ 120 killUnit := state.TransactionHook{
82 Before: func() { 121 Before: func() {
83 c.Assert(unit.Destroy(), gc.IsNil) 122 c.Assert(unit.Destroy(), gc.IsNil)
84 c.Assert(unit.EnsureDead(), gc.IsNil) 123 c.Assert(unit.EnsureDead(), gc.IsNil)
85 }, 124 },
86 } 125 }
87 defer state.SetTransactionHooks(c, s.State, killUnit).Check() 126 defer state.SetTransactionHooks(c, s.State, killUnit).Check()
88 127
89 _, err = unit.AddAction("fakeaction", map[string]interface{}{}) 128 _, err = unit.AddAction("fakeaction", map[string]interface{}{})
90 c.Assert(err, gc.ErrorMatches, "unit .* is dead") 129 c.Assert(err, gc.ErrorMatches, "unit .* is dead")
91 } 130 }
92 131
93 // assertSaneActionId verifies that the actionId is of the expected 132 func (s *ActionSuite) TestFail(c *gc.C) {
133 » // TODO(jcw4): when action results are implemented we should be
134 » // checking for a Fail result after calling Fail(), rather than
135 » // sniffing the logs
136 » defer loggo.ResetWriters()
137 » logger := loggo.GetLogger("test")
138 » logger.SetLogLevel(loggo.DEBUG)
139 » tw := &loggo.TestWriter{}
140 » c.Assert(loggo.RegisterWriter("actions-tester", tw, loggo.DEBUG), gc.IsN il)
141
142 » // get unit, add an action, retrieve that action
143 » unit, err := s.State.Unit(s.unit.Name())
144 » c.Assert(err, gc.IsNil)
145 » preventUnitDestroyRemove(c, unit)
146
147 » id, err := unit.AddAction("action1", nil)
148 » c.Assert(err, gc.IsNil)
149
150 » action, err := s.State.Action(id)
151 » c.Assert(err, gc.IsNil)
152
153 » // fail the action, and verify that it succeeds (right now, just by
154 » // sniffing the logs)
155 » reason := "test fail reason"
156 » err = action.Fail(reason)
157 » c.Assert(err, gc.IsNil)
158 » // TODO(jcw4): replace with action results check when they're implemente d
159 » c.Assert(tw.Log, jc.LogMatches, jc.SimpleMessages{{loggo.WARNING, reason }})
160
161 » // validate that a failed action is no longer returned by UnitActions.
162 » actions, err := s.State.UnitActions(unit.Name())
163 » c.Assert(err, gc.IsNil)
164 » c.Assert(len(actions), gc.Equals, 0)
165 }
166
167 // assertSaneActionId verifies that the id is of the expected
94 // form (unit id prefix + sequence) 168 // form (unit id prefix + sequence)
95 // This is a temporary assertion, we shouldn't be leaking the actual 169 // This is a temporary assertion, we shouldn't be leaking the actual
96 // mongo _id 170 // mongo _id
97 func assertSaneActionId(c *gc.C, actionId, unitName string) { 171 func assertSaneActionId(c *gc.C, id, unitName string) {
98 » c.Assert(actionId, gc.Matches, "^u#"+unitName+"#\\d+") 172 » c.Assert(id, gc.Matches, "^u#"+unitName+"#a#\\d+")
99 } 173 }
OLDNEW
« no previous file with comments | « state/action.go ('k') | state/cleanup.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b