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

Side by Side Diff: cmd/jujud/upgrade_test.go

Issue 6490067: state: remove ProposedTools.
Patch Set: state: remove ProposedTools. Created 12 years, 7 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 | « cmd/jujud/upgrade.go ('k') | environs/jujutest/livetests.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 package main 1 package main
2 2
3 import ( 3 import (
4 "bytes" 4 "bytes"
5 "fmt" 5 "fmt"
6 "io/ioutil" 6 "io/ioutil"
7 . "launchpad.net/gocheck" 7 . "launchpad.net/gocheck"
8 "launchpad.net/juju-core/environs" 8 "launchpad.net/juju-core/environs"
9 "launchpad.net/juju-core/environs/config"
9 "launchpad.net/juju-core/juju/testing" 10 "launchpad.net/juju-core/juju/testing"
10 "launchpad.net/juju-core/state" 11 "launchpad.net/juju-core/state"
11 coretesting "launchpad.net/juju-core/testing" 12 coretesting "launchpad.net/juju-core/testing"
12 "launchpad.net/juju-core/version" 13 "launchpad.net/juju-core/version"
13 "launchpad.net/tomb" 14 "launchpad.net/tomb"
14 "net"
15 "net/http" 15 "net/http"
16 "path/filepath" 16 "path/filepath"
17 "time" 17 "time"
18 ) 18 )
19 19
20 var _ = Suite(&upgraderSuite{}) 20 var _ = Suite(&upgraderSuite{})
21 21
22 type upgraderSuite struct { 22 type upgraderSuite struct {
23 testing.JujuConnSuite 23 testing.JujuConnSuite
24 oldVarDir string 24 oldVarDir string
25 } 25 }
26 26
27 func (s *upgraderSuite) SetUpTest(c *C) { 27 func (s *upgraderSuite) SetUpTest(c *C) {
28 s.JujuConnSuite.SetUpTest(c) 28 s.JujuConnSuite.SetUpTest(c)
29 s.oldVarDir = environs.VarDir 29 s.oldVarDir = environs.VarDir
30 environs.VarDir = c.MkDir() 30 environs.VarDir = c.MkDir()
31 } 31 }
32 32
33 func (s *upgraderSuite) TearDownTest(c *C) { 33 func (s *upgraderSuite) TearDownTest(c *C) {
34 environs.VarDir = s.oldVarDir 34 environs.VarDir = s.oldVarDir
35 s.JujuConnSuite.TearDownTest(c) 35 s.JujuConnSuite.TearDownTest(c)
36 } 36 }
37 37
38 func (s *upgraderSuite) TestUpgraderError(c *C) { 38 func (s *upgraderSuite) TestUpgraderError(c *C) {
39 st, err := state.Open(s.StateInfo(c)) 39 st, err := state.Open(s.StateInfo(c))
40 c.Assert(err, IsNil) 40 c.Assert(err, IsNil)
41 » m, err := st.AddMachine() 41 » _, as, upgraderDone := startUpgrader(st)
42 » c.Assert(err, IsNil)
43 » _, as, upgraderDone := startUpgrader(m)
44 // We have no installed tools, so the logic should set the agent 42 // We have no installed tools, so the logic should set the agent
45 // tools anyway, but with no URL. 43 // tools anyway, but with no URL.
46 assertEvent(c, as.event, fmt.Sprintf("SetAgentTools %s ", version.Curren t)) 44 assertEvent(c, as.event, fmt.Sprintf("SetAgentTools %s ", version.Curren t))
47 assertEvent(c, as.event, "WatchProposedTools")
48 45
49 // Close the state under the watcher and check that the upgrader dies. 46 // Close the state under the watcher and check that the upgrader dies.
50 st.Close() 47 st.Close()
51 select { 48 select {
52 case err := <-upgraderDone: 49 case err := <-upgraderDone:
53 c.Assert(err, Not(FitsTypeOf), &UpgradedError{}) 50 c.Assert(err, Not(FitsTypeOf), &UpgradedError{})
54 c.Assert(err, NotNil) 51 c.Assert(err, NotNil)
55 case <-time.After(500 * time.Millisecond): 52 case <-time.After(500 * time.Millisecond):
56 c.Fatalf("upgrader did not stop as expected") 53 c.Fatalf("upgrader did not stop as expected")
57 } 54 }
58 } 55 }
59 56
60 func (s *upgraderSuite) TestUpgraderStop(c *C) { 57 func (s *upgraderSuite) TestUpgraderStop(c *C) {
61 » m, err := s.State.AddMachine() 58 » u, as, upgraderDone := startUpgrader(s.State)
62 » c.Assert(err, IsNil)
63 » u, as, upgraderDone := startUpgrader(m)
64 assertEvent(c, as.event, fmt.Sprintf("SetAgentTools %s ", version.Curren t)) 59 assertEvent(c, as.event, fmt.Sprintf("SetAgentTools %s ", version.Curren t))
65 assertEvent(c, as.event, "WatchProposedTools")
66 60
67 » err = u.Stop() 61 » err := u.Stop()
68 c.Assert(err, IsNil) 62 c.Assert(err, IsNil)
69 63
70 select { 64 select {
71 case err := <-upgraderDone: 65 case err := <-upgraderDone:
72 c.Assert(err, IsNil) 66 c.Assert(err, IsNil)
73 case <-time.After(500 * time.Millisecond): 67 case <-time.After(500 * time.Millisecond):
74 c.Fatalf("upgrader did not stop as expected") 68 c.Fatalf("upgrader did not stop as expected")
75 } 69 }
76 } 70 }
77 71
78 // startUpgrader starts the upgrader using the given machine 72 // startUpgrader starts the upgrader using the given machine
79 // for observing and changing agent tools. 73 // for observing and changing agent tools.
80 func startUpgrader(m *state.Machine) (u *Upgrader, as *testAgentState, upgraderD one <-chan error) { 74 func startUpgrader(st *state.State) (u *Upgrader, as *testAgentState, upgraderDo ne <-chan error) {
81 » as = newTestAgentState(m) 75 » as = newTestAgentState()
82 » u = NewUpgrader("testagent", as) 76 » u = NewUpgrader(st, "testagent", as)
83 done := make(chan error, 1) 77 done := make(chan error, 1)
84 go func() { 78 go func() {
85 done <- u.Wait() 79 done <- u.Wait()
86 }() 80 }()
87 upgraderDone = done 81 upgraderDone = done
88 return 82 return
89 } 83 }
90 84
85 func (s *upgraderSuite) proposeVersion(c *C, vers version.Number) {
86 cfg, err := s.State.EnvironConfig()
87 c.Assert(err, IsNil)
88 attrs := cfg.AllAttrs()
89 attrs["agent-version"] = vers.String()
90 newCfg, err := config.New(attrs)
91 c.Assert(err, IsNil)
92 err = s.State.SetEnvironConfig(newCfg)
93 c.Assert(err, IsNil)
94 }
95
96 func (s *upgraderSuite) uploadTools(c *C, vers version.Binary) (path string, too ls *state.Tools) {
97 tgz := coretesting.TarGz(
98 coretesting.NewTarFile("juju", 0777, "juju contents "+vers.Strin g()),
99 coretesting.NewTarFile("jujuc", 0777, "jujuc contents "+vers.Str ing()),
100 coretesting.NewTarFile("jujud", 0777, "jujud contents "+vers.Str ing()),
101 )
102 storage := s.Conn.Environ.Storage()
103 err := storage.Put(environs.ToolsStoragePath(vers), bytes.NewReader(tgz) , int64(len(tgz)))
104 c.Assert(err, IsNil)
105 path = environs.ToolsStoragePath(vers)
106 url, err := s.Conn.Environ.Storage().URL(path)
107 c.Assert(err, IsNil)
108 return path, &state.Tools{URL: url, Binary: vers}
109 }
110
91 func (s *upgraderSuite) TestUpgrader(c *C) { 111 func (s *upgraderSuite) TestUpgrader(c *C) {
112
92 // Set up the current version and tools. 113 // Set up the current version and tools.
93 » v1 := &state.Tools{ 114 » version.Current = version.MustParseBinary("1.0.1-foo-bar")
94 » » URL: "http://oldurl.tgz", 115 » v1path, v1tools := s.uploadTools(c, version.Current)
95 » » Binary: version.MustParseBinary("1.0.1-foo-bar"), 116
96 » } 117 » // Unpack the "current" version of the tools, and delete them from
97 » version.Current = v1.Binary 118 » // the storage so that we're sure that the uploader isn't trying
98 » // unpack the "current" version of the tools. 119 » // to fetch them.
99 » v1tools := coretesting.TarGz( 120 » resp, err := http.Get(v1tools.URL)
100 » » coretesting.NewTarFile("juju", 0777, "juju contents v1"), 121 » c.Assert(err, IsNil)
101 » » coretesting.NewTarFile("jujuc", 0777, "jujuc contents v1"), 122 » err = environs.UnpackTools(v1tools, resp.Body)
102 » » coretesting.NewTarFile("jujud", 0777, "jujud contents v1"), 123 » c.Assert(err, IsNil)
103 » ) 124 » err = s.Conn.Environ.Storage().Remove(v1path)
104 » err := environs.UnpackTools(v1, bytes.NewReader(v1tools))
105 c.Assert(err, IsNil) 125 c.Assert(err, IsNil)
106 126
107 » // Upload a new version of the tools to the environ's storage. 127 » // Start the upgrader going and check that the tools are those
108 » // We'll test upgrading to these tools. 128 » // that we set up.
109 » v2tools := coretesting.TarGz( 129 » _, as, upgraderDone := startUpgrader(s.State)
110 » » coretesting.NewTarFile("juju", 0777, "juju contents v2"), 130 » assertEvent(c, as.event, "SetAgentTools 1.0.1-foo-bar "+v1tools.URL)
111 » » coretesting.NewTarFile("jujuc", 0777, "jujuc contents v2"),
112 » » coretesting.NewTarFile("jujud", 0777, "jujud contents v2"),
113 » )
114 » v2 := &state.Tools{
115 » » Binary: version.MustParseBinary("1.0.2-foo-bar"),
116 » }
117 » storage := s.Conn.Environ.Storage()
118 » err = storage.Put(environs.ToolsStoragePath(v2.Binary), bytes.NewReader( v2tools), int64(len(v2tools)))
119 » c.Assert(err, IsNil)
120 » v2.URL, err = s.Conn.Environ.Storage().URL(environs.ToolsStoragePath(v2. Binary))
121 » c.Assert(err, IsNil)
122 131
123 » m, err := s.State.AddMachine() 132 » // Propose some tools that are not there.
124 » c.Assert(err, IsNil) 133 » s.proposeVersion(c, version.MustParse("1.0.2"))
134 » assertNothingHappens(c, upgraderDone)
125 135
126 » _, as, upgraderDone := startUpgrader(m) 136 » // Upload the current tools again.
127 » assertEvent(c, as.event, "SetAgentTools 1.0.1-foo-bar http://oldurl.tgz" ) 137 » v1path, v1tools = s.uploadTools(c, version.Current)
128 » assertEvent(c, as.event, "WatchProposedTools") 138 » s.proposeVersion(c, version.MustParse("1.0.3"))
139 » assertNothingHappens(c, upgraderDone)
129 140
130 » // Propose some invalid tools then check that 141 » // Upload two new versions of the tools. We'll test upgrading to these t ools.
131 » // the URL is fetched and that nothing happens. 142 » _, v5tools := s.uploadTools(c, version.MustParseBinary("1.0.5-foo-bar"))
132 » delayedURL, started := delayedFetch() 143 » _, v6tools := s.uploadTools(c, version.MustParseBinary("1.0.6-foo-bar"))
133 » as.proposeTools(&state.Tools{
134 » » URL: delayedURL,
135 » » Binary: v2.Binary,
136 » })
137 » <-started
138 144
139 » as.proposeTools(v2) 145 » // Check that it won't choose tools with a greater version number.
140 » assertNoEvent(c, as.event) 146 » s.proposeVersion(c, version.MustParse("1.0.4"))
147 » assertNothingHappens(c, upgraderDone)
141 148
149 s.proposeVersion(c, v6tools.Number)
142 select { 150 select {
143 case err := <-upgraderDone: 151 case err := <-upgraderDone:
144 » » c.Assert(err, DeepEquals, &UpgradedError{v2}) 152 » » c.Assert(err, DeepEquals, &UpgradedError{v6tools})
145 case <-time.After(500 * time.Millisecond): 153 case <-time.After(500 * time.Millisecond):
146 c.Fatalf("upgrader did not stop as expected") 154 c.Fatalf("upgrader did not stop as expected")
147 } 155 }
148 156
149 // Check that the upgraded version was really downloaded. 157 // Check that the upgraded version was really downloaded.
150 » data, err := ioutil.ReadFile(filepath.Join(environs.ToolsDir(v2.Binary), "jujud")) 158 » data, err := ioutil.ReadFile(filepath.Join(environs.ToolsDir(v6tools.Bin ary), "jujud"))
151 c.Assert(err, IsNil) 159 c.Assert(err, IsNil)
152 » c.Assert(string(data), Equals, "jujud contents v2") 160 » c.Assert(string(data), Equals, "jujud contents 1.0.6-foo-bar")
153 161
154 » _, as, upgraderDone = startUpgrader(m) 162 » version.Current = v6tools.Binary
155 » assertEvent(c, as.event, "SetAgentTools 1.0.1-foo-bar http://oldurl.tgz" ) 163 » // Check that we can start again.
156 » assertEvent(c, as.event, "WatchProposedTools") 164 » _, as, upgraderDone = startUpgrader(s.State)
165 » assertEvent(c, as.event, "SetAgentTools 1.0.6-foo-bar "+v6tools.URL)
157 166
158 » // Use delayedURL but don't make it respond - if the upgrade 167 » // Check that we can downgrade.
159 » // succeeds then we know that it has (correctly) not tried to 168 » s.proposeVersion(c, v5tools.Number)
160 » // fetch the URL 169
161 » as.proposeTools(&state.Tools{
162 » » URL: delayedURL,
163 » » Binary: v2.Binary,
164 » })
165 » assertNoEvent(c, as.event)
166 select { 170 select {
167 case tools := <-upgraderDone: 171 case tools := <-upgraderDone:
168 » » c.Assert(tools, DeepEquals, &UpgradedError{v2}) 172 » » c.Assert(tools, DeepEquals, &UpgradedError{v5tools})
169 case <-time.After(500 * time.Millisecond): 173 case <-time.After(500 * time.Millisecond):
170 c.Fatalf("upgrader did not stop as expected") 174 c.Fatalf("upgrader did not stop as expected")
171 } 175 }
172 } 176 }
173 177
178 func assertNothingHappens(c *C, upgraderDone <-chan error) {
179 select {
180 case got := <-upgraderDone:
181 c.Fatalf("expected nothing to happen, got %v", got)
182 case <-time.After(100 * time.Millisecond):
183 }
184 }
185
174 func assertEvent(c *C, event <-chan string, want string) { 186 func assertEvent(c *C, event <-chan string, want string) {
175 select { 187 select {
176 case got := <-event: 188 case got := <-event:
177 c.Assert(got, Equals, want) 189 c.Assert(got, Equals, want)
178 case <-time.After(500 * time.Millisecond): 190 case <-time.After(500 * time.Millisecond):
179 c.Fatalf("no event received; expected %q", want) 191 c.Fatalf("no event received; expected %q", want)
180 } 192 }
181 } 193 }
182 194
183 func assertNoEvent(c *C, event <-chan string) {
184 select {
185 case got := <-event:
186 c.Fatalf("expected no event; got %q", got)
187 case <-time.After(100 * time.Millisecond):
188 }
189 }
190
191 func delayedFetch() (url string, started chan bool) {
192 l, err := net.Listen("tcp", "localhost:0")
193 if err != nil {
194 panic(err)
195 }
196 started = make(chan bool)
197 go http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, r *http.Re quest) {
198 started <- true
199 http.NotFound(w, r)
200 r.Body.Close()
201 }))
202 return fmt.Sprintf("http://%s/delayed", l.Addr()), started
203 }
204
205 type testAgentState struct { 195 type testAgentState struct {
206 tomb.Tomb 196 tomb.Tomb
207 event chan string 197 event chan string
208 m *state.Machine
209 } 198 }
210 199
211 func newTestAgentState(m *state.Machine) *testAgentState { 200 func newTestAgentState() *testAgentState {
212 return &testAgentState{ 201 return &testAgentState{
213 event: make(chan string), 202 event: make(chan string),
214 m: m,
215 } 203 }
216 } 204 }
217 205
218 func (t *testAgentState) SetAgentTools(tools *state.Tools) error { 206 func (t *testAgentState) SetAgentTools(tools *state.Tools) error {
219 t.event <- fmt.Sprintf("SetAgentTools %v %s", tools.Binary, tools.URL) 207 t.event <- fmt.Sprintf("SetAgentTools %v %s", tools.Binary, tools.URL)
220 » return t.m.SetAgentTools(tools) 208 » return nil
221 } 209 }
222
223 func (t *testAgentState) WatchProposedAgentTools() *state.AgentToolsWatcher {
224 t.event <- "WatchProposedTools"
225 return t.m.WatchProposedAgentTools()
226 }
227
228 func (t *testAgentState) proposeTools(tools *state.Tools) {
229 err := t.m.ProposeAgentTools(tools)
230 if err != nil {
231 panic(err)
232 }
233 }
OLDNEW
« no previous file with comments | « cmd/jujud/upgrade.go ('k') | environs/jujutest/livetests.go » ('j') | no next file with comments »

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