github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/environs/simplestreams/testing/testing.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package testing 5 6 // Provides a TestDataSuite which creates and provides http access to sample simplestreams metadata. 7 8 import ( 9 "fmt" 10 "net/http" 11 12 gc "launchpad.net/gocheck" 13 14 "github.com/juju/juju/environs/jujutest" 15 "github.com/juju/juju/environs/simplestreams" 16 "github.com/juju/juju/testing" 17 "github.com/juju/juju/version/ubuntu" 18 ) 19 20 var PrivateKeyPassphrase = "12345" 21 22 var SignedMetadataPrivateKey = ` 23 -----BEGIN PGP PRIVATE KEY BLOCK----- 24 Version: GnuPG v1.4.12 (GNU/Linux) 25 26 lQH+BFJCk2EBBAC4wo3+aJ0PSeE54sv+GYNYckqysjazcZfJSdPK1GCN+Teat7ey 27 9dwlLhUIS34H29V+0/RcXmmRV+dObSkXzCx5ltKPSnuDsxvqiDEP0CgWdyFxhDf0 28 TbQuKK5OXcZ9rOTSFmnMxGaAzaV7T1IyuqA9HqntTIfC2tL4Y+QN41gS+QARAQAB 29 /gMDAjYGIOoxe8CYYGwpat1V7NGuphvvZRpqeP0RrJ6h4vHV3hXu5NK3tn6LZF0n 30 Qp31LfTH4BHF091UTiebexuuF1/ixLVihtv45mEVejFG1U3G298+WkWUP6AYA/5c 31 QRzXGiuTXlsBUuFVTGn1mvxRmG3yVoLkDj0l5rN9Tq3Ir4BACIWyxjBv1n8fqw+x 32 ti4b7YoE35FpIXQqLOdfdcKTOqUJt+5c+bed4Yx82BsLiY2/huqG2dLnbwln80Dz 33 iYudtG8xLJ1AeHBBFB0nVdyO+mPzXgLNEbP3zle2W+rUfz+s6te7y+rlV0gad2VG 34 tBAvUy08T9rDk0DNQl7jMq/3cGfDI1Zi/nzf2BuuBu2ddgIRmsXgKYly+Fq6eIpa 35 nM+P1hd1Fa3rQwUSJc/zrl48tukf8sdPLDk/+nMhLHy86jp+NeXyXPLvsMAlF5kR 36 eFjxEjHOnJlo4uIUxvlUuePyEOEl0XkQfZs+VWAPo+l2tB5UZXN0IFVzZXIgPHRl 37 c3RAc29tZXdoZXJlLmNvbT6IuAQTAQIAIgUCUkKTYQIbAwYLCQgHAwIGFQgCCQoL 38 BBYCAwECHgECF4AACgkQuK3uqWB66vCVugP/eJFir6Qdcvl+y9/HuP4q2iECi8ny 39 z9tC3YC9DcJePyoBnt1LJO3HvaquZh1AIr6hgMFaujjx6cCb7YEgE0pJ4m74dvtS 40 Y03MUPQ+Ok4cYV66zaDZLk6zpYJXZhxP7ZhlBvwQRES/rudBEQMfBcU9PrduFU39 41 iI+2ojHI4lsnMQE= 42 =UUIf 43 -----END PGP PRIVATE KEY BLOCK----- 44 ` 45 46 var SignedMetadataPublicKey = ` 47 -----BEGIN PGP PUBLIC KEY BLOCK----- 48 Version: GnuPG v1.4.12 (GNU/Linux) 49 50 mI0EUkKTYQEEALjCjf5onQ9J4Tniy/4Zg1hySrKyNrNxl8lJ08rUYI35N5q3t7L1 51 3CUuFQhLfgfb1X7T9FxeaZFX505tKRfMLHmW0o9Ke4OzG+qIMQ/QKBZ3IXGEN/RN 52 tC4ork5dxn2s5NIWaczEZoDNpXtPUjK6oD0eqe1Mh8La0vhj5A3jWBL5ABEBAAG0 53 HlRlc3QgVXNlciA8dGVzdEBzb21ld2hlcmUuY29tPoi4BBMBAgAiBQJSQpNhAhsD 54 BgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRC4re6pYHrq8JW6A/94kWKvpB1y 55 +X7L38e4/iraIQKLyfLP20LdgL0Nwl4/KgGe3Usk7ce9qq5mHUAivqGAwVq6OPHp 56 wJvtgSATSknibvh2+1JjTcxQ9D46ThxhXrrNoNkuTrOlgldmHE/tmGUG/BBERL+u 57 50ERAx8FxT0+t24VTf2Ij7aiMcjiWycxAQ== 58 =zBYH 59 -----END PGP PUBLIC KEY BLOCK-----` 60 61 var imageData = map[string]string{ 62 "/daily/streams/v1/index.json": ` 63 { 64 "index": { 65 "com.ubuntu.cloud:released:raring": { 66 "updated": "Wed, 01 May 2013 13:31:26 +0000", 67 "clouds": [ 68 { 69 "region": "us-east-1", 70 "endpoint": "https://ec2.us-east-1.amazonaws.com" 71 } 72 ], 73 "cloudname": "aws", 74 "datatype": "image-ids", 75 "format": "products:1.0", 76 "products": [ 77 "com.ubuntu.cloud:server:13.04:amd64" 78 ], 79 "path": "streams/v1/raring_metadata.json" 80 } 81 }, 82 "updated": "Wed, 01 May 2013 13:31:26 +0000", 83 "format": "index:1.0" 84 } 85 `, 86 "/streams/v1/index.json": ` 87 { 88 "index": { 89 "com.ubuntu.cloud:released:precise": { 90 "updated": "Wed, 01 May 2013 13:31:26 +0000", 91 "clouds": [ 92 { 93 "region": "us-east-1", 94 "endpoint": "https://ec2.us-east-1.amazonaws.com" 95 } 96 ], 97 "cloudname": "aws", 98 "datatype": "image-ids", 99 "format": "products:1.0", 100 "products": [ 101 "com.ubuntu.cloud:server:12.04:amd64", 102 "com.ubuntu.cloud:server:12.04:arm" 103 ], 104 "path": "streams/v1/image_metadata.json" 105 }, 106 "com.ubuntu.cloud:released:raring": { 107 "updated": "Wed, 01 May 2013 13:31:26 +0000", 108 "clouds": [ 109 { 110 "region": "us-east-1", 111 "endpoint": "https://ec2.us-east-1.amazonaws.com" 112 } 113 ], 114 "cloudname": "aws", 115 "datatype": "image-ids", 116 "format": "products:1.0", 117 "products": [ 118 "com.ubuntu.cloud:server:13.04:amd64" 119 ], 120 "path": "streams/v1/raring_metadata.json" 121 }, 122 "com.ubuntu.cloud:released:download": { 123 "datatype": "content-download", 124 "path": "streams/v1/com.ubuntu.cloud:released:download.json", 125 "updated": "Wed, 01 May 2013 13:30:37 +0000", 126 "products": [ 127 "com.ubuntu.cloud:server:12.10:amd64", 128 "com.ubuntu.cloud:server:13.04:amd64" 129 ], 130 "format": "products:1.0" 131 }, 132 "com.ubuntu.juju:released:tools": { 133 "updated": "Mon, 05 Aug 2013 11:07:04 +0000", 134 "datatype": "content-download", 135 "format": "products:1.0", 136 "products": [ 137 "com.ubuntu.juju:12.04:amd64", 138 "com.ubuntu.juju:12.04:arm", 139 "com.ubuntu.juju:13.04:amd64", 140 "com.ubuntu.juju:13.04:arm" 141 ], 142 "path": "streams/v1/tools_metadata.json" 143 } 144 }, 145 "updated": "Wed, 01 May 2013 13:31:26 +0000", 146 "format": "index:1.0" 147 } 148 `, 149 "/streams/v1/mirrors.json": ` 150 { 151 "mirrors": { 152 "com.ubuntu.juju:released:tools": [ 153 { 154 "datatype": "content-download", 155 "path": "streams/v1/tools_metadata:public-mirrors.json", 156 "clouds": [ 157 { 158 "region": "us-east-2", 159 "endpoint": "https://ec2.us-east-2.amazonaws.com" 160 }, 161 { 162 "region": "us-west-2", 163 "endpoint": "https://ec2.us-west-2.amazonaws.com" 164 } 165 ], 166 "updated": "Wed, 14 Aug 2013 13:46:17 +0000", 167 "format": "mirrors:1.0" 168 }, 169 { 170 "datatype": "content-download", 171 "path": "streams/v1/tools_metadata:more-mirrors.json", 172 "updated": "Wed, 14 Aug 2013 13:46:17 +0000", 173 "format": "mirrors:1.0" 174 } 175 ] 176 }, 177 "updated": "Wed, 01 May 2013 13:31:26 +0000", 178 "format": "index:1.0" 179 } 180 `, 181 "/streams/v1/tools_metadata.json": ` 182 { 183 "content_id": "com.ubuntu.juju:tools", 184 "datatype": "content-download", 185 "updated": "Tue, 04 Jun 2013 13:50:31 +0000", 186 "format": "products:1.0", 187 "products": { 188 "com.ubuntu.juju:12.04:amd64": { 189 "arch": "amd64", 190 "release": "precise", 191 "versions": { 192 "20130806": { 193 "items": { 194 "1130preciseamd64": { 195 "version": "1.13.0", 196 "size": 2973595, 197 "path": "tools/releases/20130806/juju-1.13.0-precise-amd64.tgz", 198 "ftype": "tar.gz", 199 "sha256": "447aeb6a934a5eaec4f703eda4ef2dde" 200 } 201 } 202 } 203 } 204 }, 205 "com.ubuntu.juju:13.04:amd64": { 206 "arch": "amd64", 207 "release": "raring", 208 "versions": { 209 "20130806": { 210 "items": { 211 "1130raringamd64": { 212 "version": "1.13.0", 213 "size": 2973173, 214 "path": "tools/releases/20130806/juju-1.13.0-raring-amd64.tgz", 215 "ftype": "tar.gz", 216 "sha256": "df07ac5e1fb4232d4e9aa2effa57918a" 217 }, 218 "1140raringamd64": { 219 "version": "1.14.0", 220 "size": 2973173, 221 "path": "tools/releases/20130806/juju-1.14.0-raring-amd64.tgz", 222 "ftype": "tar.gz", 223 "sha256": "df07ac5e1fb4232d4e9aa2effa57918a" 224 } 225 } 226 } 227 } 228 }, 229 "com.ubuntu.juju:12.04:arm": { 230 "arch": "arm", 231 "release": "precise", 232 "versions": { 233 "20130806": { 234 "items": { 235 "201precisearm": { 236 "version": "2.0.1", 237 "size": 1951096, 238 "path": "tools/releases/20130806/juju-2.0.1-precise-arm.tgz", 239 "ftype": "tar.gz", 240 "sha256": "f65a92b3b41311bdf398663ee1c5cd0c" 241 }, 242 "1114precisearm": { 243 "version": "1.11.4", 244 "size": 1951096, 245 "path": "tools/releases/20130806/juju-1.11.4-precise-arm.tgz", 246 "ftype": "tar.gz", 247 "sha256": "f65a92b3b41311bdf398663ee1c5cd0c" 248 } 249 } 250 }, 251 "20130803": { 252 "items": { 253 "1114precisearm": { 254 "version": "1.11.4", 255 "size": 2851541, 256 "path": "tools/releases/20130803/juju-1.11.4-precise-arm.tgz", 257 "ftype": "tar.gz", 258 "sha256": "df07ac5e1fb4232d4e9aa2effa57918a" 259 }, 260 "1115precisearm": { 261 "version": "1.11.5", 262 "size": 2031281, 263 "path": "tools/releases/20130803/juju-1.11.5-precise-arm.tgz", 264 "ftype": "tar.gz", 265 "sha256": "df07ac5e1fb4232d4e9aa2effa57918a" 266 } 267 } 268 } 269 } 270 }, 271 "com.ubuntu.juju:13.04:arm": { 272 "arch": "arm", 273 "release": "raring", 274 "versions": { 275 "20130806": { 276 "items": { 277 "1114raringarm": { 278 "version": "1.11.4", 279 "size": 1950327, 280 "path": "tools/releases/20130806/juju-1.11.4-raring-arm.tgz", 281 "ftype": "tar.gz", 282 "sha256": "6472014e3255e3fe7fbd3550ef3f0a11" 283 }, 284 "201raringarm": { 285 "version": "2.0.1", 286 "size": 1950327, 287 "path": "tools/releases/20130806/juju-2.0.1-raring-arm.tgz", 288 "ftype": "tar.gz", 289 "sha256": "6472014e3255e3fe7fbd3550ef3f0a11" 290 } 291 } 292 } 293 } 294 } 295 } 296 } 297 `, 298 "/streams/v1/mirrored-tools-metadata.json": ` 299 { 300 "content_id": "com.ubuntu.juju:tools", 301 "datatype": "content-download", 302 "updated": "Tue, 04 Jun 2013 13:50:31 +0000", 303 "format": "products:1.0", 304 "products": { 305 "com.ubuntu.juju:12.04:amd64": { 306 "arch": "amd64", 307 "release": "precise", 308 "versions": { 309 "20130806": { 310 "items": { 311 "1130preciseamd64": { 312 "version": "1.13.0", 313 "size": 2973595, 314 "path": "mirrored-path/juju-1.13.0-precise-amd64.tgz", 315 "ftype": "tar.gz", 316 "sha256": "447aeb6a934a5eaec4f703eda4ef2dde" 317 } 318 } 319 } 320 } 321 } 322 } 323 } 324 `, 325 "/streams/v1/tools_metadata:public-mirrors.json": ` 326 { 327 "mirrors": { 328 "com.ubuntu.juju:released:tools": [ 329 { 330 "mirror": "http://some-mirror/", 331 "path": "com.ubuntu.juju:download.json", 332 "format": "products:1.0", 333 "clouds": [ 334 { 335 "endpoint": "https://ec2.us-east-2.amazonaws.com", 336 "region": "us-east-2" 337 } 338 ] 339 }, 340 { 341 "mirror": "test:/", 342 "path": "streams/v1/mirrored-tools-metadata.json", 343 "format": "products:1.0", 344 "clouds": [ 345 { 346 "endpoint": "https://ec2.us-west-2.amazonaws.com", 347 "region": "us-west-2" 348 } 349 ] 350 }, 351 { 352 "mirror": "http://another-mirror/", 353 "path": "com.ubuntu.juju:download.json", 354 "format": "products:1.0", 355 "clouds": [ 356 { 357 "endpoint": "https://ec2.us-west-1.amazonaws.com", 358 "region": "us-west-1" 359 } 360 ] 361 } 362 ] 363 }, 364 "format": "mirrors:1.0", 365 "updated": "Mon, 05 Aug 2013 11:07:04 +0000" 366 } 367 `, 368 "/streams/v1/tools_metadata:more-mirrors.json": ` 369 { 370 "mirrors": { 371 "com.ubuntu.juju:released:tools": [ 372 { 373 "mirror": "http://big-mirror/", 374 "path": "big:download.json", 375 "clouds": [ 376 { 377 "endpoint": "https://some-endpoint.com", 378 "region": "some-region" 379 } 380 ] 381 } 382 ] 383 }, 384 "format": "mirrors:1.0", 385 "updated": "Mon, 05 Aug 2013 11:07:04 +0000" 386 } 387 `, 388 "/streams/v1/image_metadata.json": ` 389 { 390 "updated": "Wed, 01 May 2013 13:31:26 +0000", 391 "content_id": "com.ubuntu.cloud:released:aws", 392 "products": { 393 "com.ubuntu.cloud:server:12.04:amd64": { 394 "release": "precise", 395 "version": "12.04", 396 "arch": "amd64", 397 "region": "au-east-1", 398 "endpoint": "https://somewhere", 399 "versions": { 400 "20121218": { 401 "region": "au-east-2", 402 "endpoint": "https://somewhere-else", 403 "items": { 404 "usww1pe": { 405 "root_store": "ebs", 406 "virt": "pv", 407 "id": "ami-26745463" 408 }, 409 "usww2he": { 410 "root_store": "ebs", 411 "virt": "hvm", 412 "id": "ami-442ea674", 413 "region": "us-east-1", 414 "endpoint": "https://ec2.us-east-1.amazonaws.com" 415 }, 416 "usww3he": { 417 "root_store": "ebs", 418 "virt": "hvm", 419 "crsn": "uswest3", 420 "id": "ami-442ea675" 421 } 422 }, 423 "pubname": "ubuntu-precise-12.04-amd64-server-20121218", 424 "label": "release" 425 }, 426 "20111111": { 427 "items": { 428 "usww3pe": { 429 "root_store": "ebs", 430 "virt": "pv", 431 "id": "ami-26745464" 432 }, 433 "usww2pe": { 434 "root_store": "instance", 435 "virt": "pv", 436 "id": "ami-442ea684", 437 "region": "us-east-1", 438 "endpoint": "https://ec2.us-east-1.amazonaws.com" 439 } 440 }, 441 "pubname": "ubuntu-precise-12.04-amd64-server-20111111", 442 "label": "release" 443 } 444 } 445 }, 446 "com.ubuntu.cloud:server:12.04:arm": { 447 "release": "precise", 448 "version": "12.04", 449 "arch": "arm", 450 "region": "us-east-1", 451 "endpoint": "https://ec2.us-east-1.amazonaws.com", 452 "versions": { 453 "20121219": { 454 "items": { 455 "usww2he": { 456 "root_store": "ebs", 457 "virt": "pv", 458 "id": "ami-442ea699" 459 } 460 }, 461 "pubname": "ubuntu-precise-12.04-arm-server-20121219", 462 "label": "release" 463 } 464 } 465 } 466 }, 467 "_aliases": { 468 "crsn": { 469 "uswest3": { 470 "region": "us-west-3", 471 "endpoint": "https://ec2.us-west-3.amazonaws.com" 472 } 473 } 474 }, 475 "format": "products:1.0" 476 } 477 `, 478 } 479 480 var testRoundTripper *jujutest.ProxyRoundTripper 481 482 func init() { 483 testRoundTripper = &jujutest.ProxyRoundTripper{} 484 testRoundTripper.RegisterForScheme("test") 485 } 486 487 type TestDataSuite struct{} 488 489 func (s *TestDataSuite) SetUpSuite(c *gc.C) { 490 testRoundTripper.Sub = jujutest.NewCannedRoundTripper( 491 imageData, map[string]int{"test://unauth": http.StatusUnauthorized}) 492 } 493 494 func (s *TestDataSuite) TearDownSuite(c *gc.C) { 495 testRoundTripper.Sub = nil 496 } 497 498 func AssertExpectedSources(c *gc.C, obtained []simplestreams.DataSource, baseURLs []string) { 499 var obtainedURLs = make([]string, len(baseURLs)) 500 for i, source := range obtained { 501 url, err := source.URL("") 502 c.Assert(err, gc.IsNil) 503 obtainedURLs[i] = url 504 } 505 c.Assert(obtainedURLs, gc.DeepEquals, baseURLs) 506 } 507 508 type LocalLiveSimplestreamsSuite struct { 509 testing.BaseSuite 510 Source simplestreams.DataSource 511 RequireSigned bool 512 DataType string 513 ValidConstraint simplestreams.LookupConstraint 514 } 515 516 func (s *LocalLiveSimplestreamsSuite) SetUpSuite(c *gc.C) { 517 s.BaseSuite.SetUpSuite(c) 518 } 519 520 func (s *LocalLiveSimplestreamsSuite) TearDownSuite(c *gc.C) { 521 s.BaseSuite.TearDownSuite(c) 522 } 523 524 const ( 525 Index_v1 = "index:1.0" 526 Product_v1 = "products:1.0" 527 Mirror_v1 = "mirrors:1.0" 528 ) 529 530 type testConstraint struct { 531 simplestreams.LookupParams 532 } 533 534 func NewTestConstraint(params simplestreams.LookupParams) *testConstraint { 535 return &testConstraint{LookupParams: params} 536 } 537 538 func (tc *testConstraint) Ids() ([]string, error) { 539 version, err := ubuntu.SeriesVersion(tc.Series[0]) 540 if err != nil { 541 return nil, err 542 } 543 ids := make([]string, len(tc.Arches)) 544 for i, arch := range tc.Arches { 545 ids[i] = fmt.Sprintf("com.ubuntu.cloud:server:%s:%s", version, arch) 546 } 547 return ids, nil 548 } 549 550 func init() { 551 // Ensure out test struct can have its tags extracted. 552 simplestreams.RegisterStructTags(TestItem{}) 553 } 554 555 type TestItem struct { 556 Id string `json:"id"` 557 Storage string `json:"root_store"` 558 VirtType string `json:"virt"` 559 Arch string `json:"arch"` 560 RegionAlias string `json:"crsn"` 561 RegionName string `json:"region"` 562 Endpoint string `json:"endpoint"` 563 } 564 565 func (s *LocalLiveSimplestreamsSuite) IndexPath() string { 566 if s.RequireSigned { 567 return simplestreams.DefaultIndexPath + ".sjson" 568 } 569 return simplestreams.UnsignedIndex 570 } 571 572 func (s *LocalLiveSimplestreamsSuite) TestGetIndex(c *gc.C) { 573 indexRef, err := s.GetIndexRef(Index_v1) 574 c.Assert(err, gc.IsNil) 575 c.Assert(indexRef.Format, gc.Equals, Index_v1) 576 c.Assert(indexRef.Source, gc.Equals, s.Source) 577 c.Assert(len(indexRef.Indexes) > 0, gc.Equals, true) 578 } 579 580 func (s *LocalLiveSimplestreamsSuite) GetIndexRef(format string) (*simplestreams.IndexReference, error) { 581 params := simplestreams.ValueParams{ 582 DataType: s.DataType, 583 ValueTemplate: TestItem{}, 584 } 585 return simplestreams.GetIndexWithFormat( 586 s.Source, s.IndexPath(), format, s.RequireSigned, s.ValidConstraint.Params().CloudSpec, params) 587 } 588 589 func (s *LocalLiveSimplestreamsSuite) TestGetIndexWrongFormat(c *gc.C) { 590 _, err := s.GetIndexRef("bad") 591 c.Assert(err, gc.NotNil) 592 } 593 594 func (s *LocalLiveSimplestreamsSuite) TestGetProductsPathExists(c *gc.C) { 595 indexRef, err := s.GetIndexRef(Index_v1) 596 c.Assert(err, gc.IsNil) 597 path, err := indexRef.GetProductsPath(s.ValidConstraint) 598 c.Assert(err, gc.IsNil) 599 c.Assert(path, gc.Not(gc.Equals), "") 600 } 601 602 func (s *LocalLiveSimplestreamsSuite) TestGetProductsPathInvalidCloudSpec(c *gc.C) { 603 indexRef, err := s.GetIndexRef(Index_v1) 604 c.Assert(err, gc.IsNil) 605 ic := NewTestConstraint(simplestreams.LookupParams{ 606 CloudSpec: simplestreams.CloudSpec{"bad", "spec"}, 607 Series: []string{"precise"}, 608 }) 609 _, err = indexRef.GetProductsPath(ic) 610 c.Assert(err, gc.NotNil) 611 } 612 613 func (s *LocalLiveSimplestreamsSuite) TestGetProductsPathInvalidProductSpec(c *gc.C) { 614 indexRef, err := s.GetIndexRef(Index_v1) 615 c.Assert(err, gc.IsNil) 616 ic := NewTestConstraint(simplestreams.LookupParams{ 617 CloudSpec: s.ValidConstraint.Params().CloudSpec, 618 Series: []string{"precise"}, 619 Arches: []string{"bad"}, 620 Stream: "spec", 621 }) 622 _, err = indexRef.GetProductsPath(ic) 623 c.Assert(err, gc.NotNil) 624 } 625 626 func (s *LocalLiveSimplestreamsSuite) AssertGetMetadata(c *gc.C) *simplestreams.CloudMetadata { 627 indexRef, err := s.GetIndexRef(Index_v1) 628 c.Assert(err, gc.IsNil) 629 metadata, err := indexRef.GetCloudMetadataWithFormat(s.ValidConstraint, Product_v1, s.RequireSigned) 630 c.Assert(err, gc.IsNil) 631 c.Assert(metadata.Format, gc.Equals, Product_v1) 632 c.Assert(len(metadata.Products) > 0, gc.Equals, true) 633 return metadata 634 } 635 636 func (s *LocalLiveSimplestreamsSuite) TestGetCloudMetadataWithFormat(c *gc.C) { 637 s.AssertGetMetadata(c) 638 } 639 640 func (s *LocalLiveSimplestreamsSuite) AssertGetItemCollections(c *gc.C, version string) *simplestreams.ItemCollection { 641 metadata := s.AssertGetMetadata(c) 642 metadataCatalog := metadata.Products["com.ubuntu.cloud:server:12.04:amd64"] 643 ic := metadataCatalog.Items[version] 644 return ic 645 }