Merge lp:~axwalk/juju-core/lp1233924-simplestreams-getmetadata-fallback into lp:~go-bot/juju-core/trunk
- lp1233924-simplestreams-getmetadata-fallback
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Andrew Wilkins |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2028 |
Proposed branch: | lp:~axwalk/juju-core/lp1233924-simplestreams-getmetadata-fallback |
Merge into: | lp:~go-bot/juju-core/trunk |
Diff against target: |
321 lines (+107/-42) 6 files modified
environs/simplestreams/simplestreams.go (+4/-3) environs/simplestreams/simplestreams_test.go (+43/-0) environs/simplestreams/testing/testing.go (+24/-0) environs/tools/tools_test.go (+12/-22) provider/openstack/export_test.go (+2/-4) provider/openstack/local_test.go (+22/-13) |
To merge this branch: | bzr merge lp:~axwalk/juju-core/lp1233924-simplestreams-getmetadata-fallback |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tim Penhey (community) | Approve | ||
Review via email: mp+188758@code.launchpad.net |
Commit message
environs/
GetMetadata was dropping out if a datasource
returned no matching product IDs, without an
error. I've changed it to check that a non-
empty list of products is returned before
bailing out.
Fixes #1233924
Description of the change
environs/
GetMetadata was dropping out if a datasource
returned no matching product IDs, without an
error. I've changed it to check that a non-
empty list of products is returned before
bailing out.
Fixes #1233924
Andrew Wilkins (axwalk) wrote : | # |
Tim Penhey (thumper) wrote : | # |
https:/
File environs/
https:/
environs/
[]string{
What is the never match? precise or arm? Also, perhaps better to give a
region that doesn't exist? Someone may add arm at some stage. Would
that work?
https:/
environs/
append(messages, messages...)
I agree with our IRC chat, ideally we would have a simple mock
datasource. What about...
type countingSource struct {
simplestream
count int
}
func (s *countingSource) URL(path string) (string, error) {
s.count++
return s.DataSource.
}
Then have sources defined by:
first :=
&countingSource
simplestreams.
second :=
&countingSource
simplestreams.
sources := []simplestream.
// do stuff
c.Check(
c.Check(
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
Andrew Wilkins (axwalk) wrote : | # |
https:/
File environs/
https:/
environs/
[]string{
On 2013/10/02 04:02:00, thumper wrote:
> What is the never match? precise or arm? Also, perhaps better to give
a region
> that doesn't exist? Someone may add arm at some stage. Would that
work?
precise, which isn't in the daily stream I added to testing. I can't use
a non-existent region, as that causes GetMetadata to error, which we
don't want.
The series are validated, but architectures aren't. I'll put in an
invalid arch.
https:/
environs/
append(messages, messages...)
On 2013/10/02 04:02:00, thumper wrote:
> I agree with our IRC chat, ideally we would have a simple mock
datasource. What
> about...
> type countingSource struct {
> simplestreams.
> count int
> }
> func (s *countingSource) URL(path string) (string, error) {
> s.count++
> return s.DataSource.
> }
> Then have sources defined by:
> first :=
&countingSource
> simplestreams.
> second :=
&countingSource
> simplestreams.
> sources := []simplestream.
> // do stuff
> c.Check(
> c.Check(
Done, tho I'm reusing a single countingSource.
Andrew Wilkins (axwalk) wrote : | # |
On 2013/10/02 05:07:52, axw1 wrote:
https:/
> File environs/
https:/
> environs/
[]string{
> // never match
> On 2013/10/02 04:02:00, thumper wrote:
> > What is the never match? precise or arm? Also, perhaps better to
give a
> region
> > that doesn't exist? Someone may add arm at some stage. Would that
work?
> precise, which isn't in the daily stream I added to testing. I can't
use a
> non-existent region, as that causes GetMetadata to error, which we
don't want.
> The series are validated, but architectures aren't. I'll put in an
invalid arch.
https:/
> environs/
append(messages,
> messages...)
> On 2013/10/02 04:02:00, thumper wrote:
> > I agree with our IRC chat, ideally we would have a simple mock
datasource.
> What
> > about...
> >
> > type countingSource struct {
> > simplestreams.
> > count int
> > }
> >
> > func (s *countingSource) URL(path string) (string, error) {
> > s.count++
> > return s.DataSource.
> > }
> >
> > Then have sources defined by:
> >
> > first :=
> >
&countingSource
> > simplestreams.
> > second :=
> >
&countingSource
> > simplestreams.
> > sources := []simplestream.
> >
> > // do stuff
> >
> > c.Check(
> > c.Check(
> >
> Done, tho I'm reusing a single countingSource.
So, after discussing with jam, GetMetadata *might* be how it is on
purpose. You might want to populate metadata into your private cloud,
and then expect only to be able to create images that match your private
metadata.
I'll leave this for now, until it's decided how it should be working.
Tim Penhey (thumper) wrote : | # |
> So, after discussing with jam, GetMetadata *might* be how it is on
purpose. You
> might want to populate metadata into your private cloud, and then
expect only to
> be able to create images that match your private metadata.
> I'll leave this for now, until it's decided how it should be working.
I think that it should be a configuration option to specify "don't
fall-back to other sources".
Tim Penhey (thumper) wrote : | # |
LGTM
https:/
File environs/
https:/
environs/
gc.Equals, 2*len(sources))
Much nicer.
Tim Penhey (thumper) : | # |
William Reade (fwereade) wrote : | # |
Fine with the idea, I think the implementation's in the wrong place.
https:/
File environs/
https:/
environs/
!= 0 {
I'm not sure this is the right place for it -- it's a hack-on-a-hack,
instead of removing the original hack in getmaybeSignedM
replaces errors with nil.
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
https:/
File environs/
https:/
environs/
!= 0 {
On 2013/10/04 10:26:42, fwereade wrote:
> I'm not sure this is the right place for it -- it's a hack-on-a-hack,
instead of
> removing the original hack in getmaybeSignedM
errors with
> nil.
I've moved it, but I think it's much the same either way. What we have
is an internal error that is used to communicate that there are no
matching products, for one of several reasons. It can be quashed in
either GetMetadata or getMaybeSignedM
which, I think.
Go Bot (go-bot) wrote : | # |
The attempt to merge lp:~axwalk/juju-core/lp1233924-simplestreams-getmetadata-fallback into lp:juju-core failed. Below is the output from the failed tests.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
-------
FAIL: tools_test.go:290: SimpleStreamsTo
[LOG] 64.15651 INFO juju.provider.dummy reset environment
test 0: no tools at all
[LOG] 64.26877 INFO juju.provider.dummy reset environment
[LOG] 64.37642 INFO juju.environs.tools filtering tools by released version
[LOG] 64.37647 INFO juju.environs.tools reading tools with major.minor version 1.0
[LOG] 64.37649 INFO juju.environs.tools filtering tools by series: precise
[LOG] 64.37651 DEBUG juju.environs.tools no architecture specified when finding tools, looking for any
[LOG] 64.37667 DEBUG juju.environs.
[LOG] 64.37668 DEBUG juju.environs.
[LOG] 64.37674 DEBUG juju.environs.
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
Preview Diff
1 | === modified file 'environs/simplestreams/simplestreams.go' |
2 | --- environs/simplestreams/simplestreams.go 2013-10-29 22:58:43 +0000 |
3 | +++ environs/simplestreams/simplestreams.go 2013-11-05 04:38:36 +0000 |
4 | @@ -431,6 +431,10 @@ |
5 | break |
6 | } |
7 | } |
8 | + if _, ok := err.(*noMatchingProductsError); ok { |
9 | + // no matching products is an internal error only |
10 | + err = nil |
11 | + } |
12 | return items, err |
13 | } |
14 | |
15 | @@ -463,9 +467,6 @@ |
16 | } |
17 | if _, ok := err.(*noMatchingProductsError); ok { |
18 | logger.Debugf("%v", err) |
19 | - // No matching products is not considered an error which will allow another source to be |
20 | - // searched, so return err = nil here. |
21 | - return items, nil |
22 | } |
23 | } |
24 | return items, err |
25 | |
26 | === modified file 'environs/simplestreams/simplestreams_test.go' |
27 | --- environs/simplestreams/simplestreams_test.go 2013-10-24 21:05:33 +0000 |
28 | +++ environs/simplestreams/simplestreams_test.go 2013-11-05 04:38:36 +0000 |
29 | @@ -300,6 +300,49 @@ |
30 | c.Check(dotOFormats, gc.DeepEquals, simplestreams.IndexMetadataSlice{array[0], array[2]}) |
31 | } |
32 | |
33 | +// countingSource is used to check that a DataSource has been queried. |
34 | +type countingSource struct { |
35 | + simplestreams.DataSource |
36 | + count int |
37 | +} |
38 | + |
39 | +func (s *countingSource) URL(path string) (string, error) { |
40 | + s.count++ |
41 | + return s.DataSource.URL(path) |
42 | +} |
43 | + |
44 | +func (s *simplestreamsSuite) TestGetMetadataNoMatching(c *gc.C) { |
45 | + source := &countingSource{ |
46 | + DataSource: simplestreams.NewURLDataSource( |
47 | + "test:/daily", simplestreams.VerifySSLHostnames, |
48 | + ), |
49 | + } |
50 | + sources := []simplestreams.DataSource{source, source, source} |
51 | + params := simplestreams.ValueParams{DataType: "image-ids"} |
52 | + constraint := sstesting.NewTestConstraint(simplestreams.LookupParams{ |
53 | + CloudSpec: simplestreams.CloudSpec{ |
54 | + Region: "us-east-1", |
55 | + Endpoint: "https://ec2.us-east-1.amazonaws.com", |
56 | + }, |
57 | + Series: []string{"precise"}, |
58 | + Arches: []string{"not-a-real-arch"}, // never matches |
59 | + }) |
60 | + |
61 | + items, err := simplestreams.GetMetadata( |
62 | + sources, |
63 | + simplestreams.DefaultIndexPath, |
64 | + constraint, |
65 | + false, |
66 | + params, |
67 | + ) |
68 | + c.Assert(err, gc.IsNil) |
69 | + c.Assert(items, gc.HasLen, 0) |
70 | + |
71 | + // There should be 2 calls to each data-source: |
72 | + // one for .sjson, one for .json. |
73 | + c.Assert(source.count, gc.Equals, 2*len(sources)) |
74 | +} |
75 | + |
76 | func (s *simplestreamsSuite) TestMetadataCatalog(c *gc.C) { |
77 | metadata := s.AssertGetMetadata(c) |
78 | c.Check(len(metadata.Products), gc.Equals, 2) |
79 | |
80 | === modified file 'environs/simplestreams/testing/testing.go' |
81 | --- environs/simplestreams/testing/testing.go 2013-10-24 18:03:53 +0000 |
82 | +++ environs/simplestreams/testing/testing.go 2013-11-05 04:38:36 +0000 |
83 | @@ -58,6 +58,30 @@ |
84 | -----END PGP PUBLIC KEY BLOCK-----` |
85 | |
86 | var imageData = map[string]string{ |
87 | + "/daily/streams/v1/index.json": ` |
88 | + { |
89 | + "index": { |
90 | + "com.ubuntu.cloud:released:raring": { |
91 | + "updated": "Wed, 01 May 2013 13:31:26 +0000", |
92 | + "clouds": [ |
93 | + { |
94 | + "region": "us-east-1", |
95 | + "endpoint": "https://ec2.us-east-1.amazonaws.com" |
96 | + } |
97 | + ], |
98 | + "cloudname": "aws", |
99 | + "datatype": "image-ids", |
100 | + "format": "products:1.0", |
101 | + "products": [ |
102 | + "com.ubuntu.cloud:server:13.04:amd64" |
103 | + ], |
104 | + "path": "streams/v1/raring_metadata.json" |
105 | + } |
106 | + }, |
107 | + "updated": "Wed, 01 May 2013 13:31:26 +0000", |
108 | + "format": "index:1.0" |
109 | + } |
110 | + `, |
111 | "/streams/v1/index.json": ` |
112 | { |
113 | "index": { |
114 | |
115 | === modified file 'environs/tools/tools_test.go' |
116 | --- environs/tools/tools_test.go 2013-11-04 02:01:19 +0000 |
117 | +++ environs/tools/tools_test.go 2013-11-05 04:38:36 +0000 |
118 | @@ -210,9 +210,10 @@ |
119 | }, { |
120 | info: "custom tools completely block public ones", |
121 | major: 1, |
122 | + minor: -1, |
123 | custom: envtesting.V220all, |
124 | public: envtesting.VAll, |
125 | - err: coretools.ErrNoMatches, |
126 | + expect: envtesting.V1all, |
127 | }, { |
128 | info: "tools matching major version only", |
129 | major: 1, |
130 | @@ -235,14 +236,13 @@ |
131 | c.Check(err, jc.Satisfies, errors.IsNotFoundError) |
132 | continue |
133 | } |
134 | - source := custom |
135 | - if len(source) == 0 { |
136 | - // We only use the public tools if there are *no* custom tools. |
137 | - source = public |
138 | - } |
139 | expect := map[version.Binary]string{} |
140 | for _, expected := range test.expect { |
141 | - expect[expected] = source[expected] |
142 | + // If the tools exist in custom, that's preferred. |
143 | + var ok bool |
144 | + if expect[expected], ok = custom[expected]; !ok { |
145 | + expect[expected] = public[expected] |
146 | + } |
147 | } |
148 | c.Check(actual.URLs(), gc.DeepEquals, expect) |
149 | } |
150 | @@ -302,10 +302,6 @@ |
151 | s.reset(c, attrs) |
152 | version.Current = test.CliVersion |
153 | available := s.uploadCustom(c, test.Available...) |
154 | - if len(available) > 0 { |
155 | - // These should never be chosen. |
156 | - s.uploadPublic(c, envtesting.VAll...) |
157 | - } |
158 | |
159 | params := envtools.BootstrapToolsParams{ |
160 | Version: agentVersion, |
161 | @@ -393,10 +389,6 @@ |
162 | "agent-version": test.agentVersion.String(), |
163 | }) |
164 | available := s.uploadCustom(c, test.available...) |
165 | - if len(available) > 0 { |
166 | - // These should never be chosen. |
167 | - s.uploadPublic(c, envtesting.VAll...) |
168 | - } |
169 | |
170 | agentVersion, _ := s.env.Config().AgentVersion() |
171 | actual, err := envtools.FindInstanceTools(s.env, agentVersion, test.series, &test.arch) |
172 | @@ -444,11 +436,10 @@ |
173 | public: []version.Binary{envtesting.V100p64}, |
174 | seek: envtesting.V100p64, |
175 | }, { |
176 | - info: "exact match in public blocked by custom", |
177 | + info: "exact match in public not blocked by custom", |
178 | custom: envtesting.V110all, |
179 | public: []version.Binary{envtesting.V100p64}, |
180 | seek: envtesting.V100p64, |
181 | - err: coretools.ErrNoMatches, |
182 | }} |
183 | |
184 | func (s *SimpleStreamsToolsSuite) TestFindExactTools(c *gc.C) { |
185 | @@ -463,12 +454,11 @@ |
186 | continue |
187 | } |
188 | c.Check(actual.Version, gc.Equals, test.seek) |
189 | - source := custom |
190 | - if len(source) == 0 { |
191 | - // We only use public tools if there are *no* private tools. |
192 | - source = public |
193 | + if _, ok := custom[actual.Version]; ok { |
194 | + c.Check(actual.URL, gc.DeepEquals, custom[actual.Version]) |
195 | + } else { |
196 | + c.Check(actual.URL, gc.DeepEquals, public[actual.Version]) |
197 | } |
198 | - c.Check(actual.URL, gc.DeepEquals, source[actual.Version]) |
199 | } else { |
200 | c.Check(err, jc.Satisfies, errors.IsNotFoundError) |
201 | } |
202 | |
203 | === modified file 'provider/openstack/export_test.go' |
204 | --- provider/openstack/export_test.go 2013-10-24 00:20:59 +0000 |
205 | +++ provider/openstack/export_test.go 2013-11-05 04:38:36 +0000 |
206 | @@ -210,7 +210,7 @@ |
207 | |
208 | const productMetadatafile = "image-metadata/products.json" |
209 | |
210 | -func UseTestImageData(e environs.Environ, cred *identity.Credentials) { |
211 | +func UseTestImageData(stor storage.Storage, cred *identity.Credentials) { |
212 | // Put some image metadata files into the public storage. |
213 | t := template.Must(template.New("").Parse(indexData)) |
214 | var metadata bytes.Buffer |
215 | @@ -218,14 +218,12 @@ |
216 | panic(fmt.Errorf("cannot generate index metdata: %v", err)) |
217 | } |
218 | data := metadata.Bytes() |
219 | - stor := MetadataStorage(e) |
220 | stor.Put(simplestreams.DefaultIndexPath+".json", bytes.NewReader(data), int64(len(data))) |
221 | stor.Put( |
222 | productMetadatafile, strings.NewReader(imagesData), int64(len(imagesData))) |
223 | } |
224 | |
225 | -func RemoveTestImageData(e environs.Environ) { |
226 | - stor := MetadataStorage(e) |
227 | +func RemoveTestImageData(stor storage.Storage) { |
228 | stor.Remove(simplestreams.DefaultIndexPath + ".json") |
229 | stor.Remove(productMetadatafile) |
230 | } |
231 | |
232 | === modified file 'provider/openstack/local_test.go' |
233 | --- provider/openstack/local_test.go 2013-11-04 02:01:19 +0000 |
234 | +++ provider/openstack/local_test.go 2013-11-05 04:38:36 +0000 |
235 | @@ -167,11 +167,11 @@ |
236 | c.Logf("Running live tests using openstack service test double") |
237 | s.srv.start(c, s.cred) |
238 | s.LiveTests.SetUpSuite(c) |
239 | - openstack.UseTestImageData(s.Env, s.cred) |
240 | + openstack.UseTestImageData(openstack.ImageMetadataStorage(s.Env), s.cred) |
241 | } |
242 | |
243 | func (s *localLiveSuite) TearDownSuite(c *gc.C) { |
244 | - openstack.RemoveTestImageData(s.Env) |
245 | + openstack.RemoveTestImageData(openstack.ImageMetadataStorage(s.Env)) |
246 | s.LiveTests.TearDownSuite(c) |
247 | s.srv.stop() |
248 | s.LoggingSuite.TearDownSuite(c) |
249 | @@ -180,6 +180,7 @@ |
250 | func (s *localLiveSuite) SetUpTest(c *gc.C) { |
251 | s.LoggingSuite.SetUpTest(c) |
252 | s.LiveTests.SetUpTest(c) |
253 | + s.PatchValue(&imagemetadata.DefaultBaseURL, "") |
254 | } |
255 | |
256 | func (s *localLiveSuite) TearDownTest(c *gc.C) { |
257 | @@ -194,9 +195,10 @@ |
258 | type localServerSuite struct { |
259 | testbase.LoggingSuite |
260 | jujutest.Tests |
261 | - cred *identity.Credentials |
262 | - srv localServer |
263 | - metadataStorage storage.Storage |
264 | + cred *identity.Credentials |
265 | + srv localServer |
266 | + toolsMetadataStorage storage.Storage |
267 | + imageMetadataStorage storage.Storage |
268 | } |
269 | |
270 | func (s *localServerSuite) SetUpSuite(c *gc.C) { |
271 | @@ -226,18 +228,21 @@ |
272 | s.Tests.SetUpTest(c) |
273 | // For testing, we create a storage instance to which is uploaded tools and image metadata. |
274 | env := s.Prepare(c) |
275 | - s.metadataStorage = openstack.MetadataStorage(env) |
276 | + s.toolsMetadataStorage = openstack.MetadataStorage(env) |
277 | // Put some fake metadata in place so that tests that are simply |
278 | // starting instances without any need to check if those instances |
279 | // are running can find the metadata. |
280 | - envtesting.UploadFakeTools(c, s.metadataStorage) |
281 | - openstack.UseTestImageData(env, s.cred) |
282 | + envtesting.UploadFakeTools(c, s.toolsMetadataStorage) |
283 | + s.imageMetadataStorage = openstack.ImageMetadataStorage(env) |
284 | + openstack.UseTestImageData(s.imageMetadataStorage, s.cred) |
285 | } |
286 | |
287 | func (s *localServerSuite) TearDownTest(c *gc.C) { |
288 | - openstack.RemoveTestImageData(s.Open(c)) |
289 | - if s.metadataStorage != nil { |
290 | - envtesting.RemoveFakeToolsMetadata(c, s.metadataStorage) |
291 | + if s.imageMetadataStorage != nil { |
292 | + openstack.RemoveTestImageData(s.imageMetadataStorage) |
293 | + } |
294 | + if s.toolsMetadataStorage != nil { |
295 | + envtesting.RemoveFakeToolsMetadata(c, s.toolsMetadataStorage) |
296 | } |
297 | s.Tests.TearDownTest(c) |
298 | s.srv.stop() |
299 | @@ -535,7 +540,11 @@ |
300 | } |
301 | |
302 | func (s *localServerSuite) TestFindImageBadDefaultImage(c *gc.C) { |
303 | + // Prevent falling over to the public datasource. |
304 | + s.PatchValue(&imagemetadata.DefaultBaseURL, "") |
305 | + |
306 | env := s.Open(c) |
307 | + |
308 | // An error occurs if no suitable image is found. |
309 | _, err := openstack.FindInstanceSpec(env, "saucy", "amd64", "mem=8G") |
310 | c.Assert(err, gc.ErrorMatches, `no "saucy" images in some-region with arches \[amd64\]`) |
311 | @@ -739,8 +748,8 @@ |
312 | c.Logf("Generating fake tools for: %v", url) |
313 | envtesting.UploadFakeTools(c, metadataStorage) |
314 | defer envtesting.RemoveFakeTools(c, metadataStorage) |
315 | - openstack.UseTestImageData(s.env, s.cred) |
316 | - defer openstack.RemoveTestImageData(s.env) |
317 | + openstack.UseTestImageData(metadataStorage, s.cred) |
318 | + defer openstack.RemoveTestImageData(metadataStorage) |
319 | |
320 | err = bootstrap.Bootstrap(s.env, constraints.Value{}) |
321 | c.Assert(err, gc.IsNil) |
Reviewers: mp+188758_ code.launchpad. net,
Message:
Please take a look.
Description: simplestreams: fix GetMetadata
environs/
GetMetadata was dropping out if a datasource
returned no matching product IDs, without an
error. I've changed it to check that a non-
empty list of products is returned before
bailing out.
Fixes #1233924
https:/ /code.launchpad .net/~axwalk/ juju-core/ lp1233924- simplestreams- getmetadata- fallback/ +merge/ 188758
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/14218044/
Affected files (+71, -2 lines): simplestreams/ simplestreams. go simplestreams/ simplestreams_ test.go simplestreams/ testing/ testing. go
A [revision details]
M environs/
M environs/
M environs/
Index: [revision details] 20131001213504- 4ynrkuya2i22q87 q
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: tarmac-
+New revision: <email address hidden>
Index: environs/ simplestreams/ simplestreams. go simplestreams/ simplestreams. go' simplestreams/ simplestreams. go 2013-09-27 07:05:45 +0000 simplestreams/ simplestreams. go 2013-10-02 03:04:13 +0000 net/loggo"
=== modified file 'environs/
--- environs/
+++ environs/
@@ -17,6 +17,7 @@
"io/ioutil"
"net/http"
"os"
+ "path"
"reflect"
"sort"
"strings"
@@ -25,7 +26,6 @@
"launchpad.
"launchpad. net/juju- core/errors"
- "path"
)
var logger = loggo.GetLogger ("juju. environs. simplestreams" ) etadata( source, baseIndexPath, cons, false,
@@ -403,7 +403,7 @@
if err != nil && len(items) == 0 && !onlySigned {
items, err = getMaybeSignedM
params)
}
- if err == nil {
+ if err == nil && len(items) != 0 {
break
}
}
Index: environs/ simplestreams/ simplestreams_ test.go simplestreams/ simplestreams_ test.go' simplestreams/ simplestreams_ test.go 2013-09-26 04:11:52 +0000 simplestreams/ simplestreams_ test.go 2013-10-02 03:04:13 +0000
=== modified file 'environs/
--- environs/
+++ environs/
@@ -9,9 +9,11 @@
"testing"
gc "launchpad. net/gocheck" net/loggo"
+ "launchpad.
"launchpad. net/juju- core/environs/ simplestreams" net/juju- core/environs/ simplestreams/ testing" net/juju- core/testing/ checkers"
sstesting "launchpad.
+ jc "launchpad.
)
func Test(t *testing.T) { dotOFormats, gc.DeepEquals, IndexMetadataSl ice{array[ 0], array[2]})
@@ -284,6 +286,47 @@
c.Check(
simplestreams.
}
+func (s *simplestreamsS uite) TestGetMetadata NoMatching( c *gc.C) { .DataSource{ NewURLDataSourc e("test: /daily" , VerifySSLHostna mes), NewURLDataSourc e("test: /daily" , VerifySSLHostna mes), ValueParams{ DataType: "image-ids"} NewTestConstrai nt(simplestream s.LookupParams{ CloudSpec{ /ec2.us- east-1. amazonaws. com", "precise" }, // never match loggo.RegisterW riter(" filter- tester" , tw, loggo.DEB...
+ sources := []simplestreams
+ simplestreams.
simplestreams.
+ simplestreams.
simplestreams.
+ }
+ params := simplestreams.
+ constraint := sstesting.
+ CloudSpec: simplestreams.
+ Region: "us-east-1",
+ Endpoint: "https:/
+ },
+ Series: []string{
+ Arches: []string{"arm"},
+ })
+
+ tw := &loggo.TestWriter{}
+ c.Assert(