github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/state/cloudimagemetadata/image_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cloudimagemetadata_test 5 6 import ( 7 "regexp" 8 "time" 9 10 "github.com/juju/errors" 11 "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 "github.com/juju/txn" 14 txntesting "github.com/juju/txn/testing" 15 gc "gopkg.in/check.v1" 16 "gopkg.in/mgo.v2" 17 "gopkg.in/mgo.v2/bson" 18 19 "github.com/juju/juju/mongo" 20 "github.com/juju/juju/state/cloudimagemetadata" 21 coretesting "github.com/juju/juju/testing" 22 ) 23 24 type cloudImageMetadataSuite struct { 25 testing.IsolatedMgoSuite 26 27 access *TestMongo 28 storage cloudimagemetadata.Storage 29 } 30 31 var _ = gc.Suite(&cloudImageMetadataSuite{}) 32 33 const ( 34 collectionName = "test-collection" 35 ) 36 37 func (s *cloudImageMetadataSuite) SetUpTest(c *gc.C) { 38 s.IsolatedMgoSuite.SetUpTest(c) 39 40 db := s.MgoSuite.Session.DB("juju") 41 42 s.access = NewTestMongo(db) 43 s.storage = cloudimagemetadata.NewStorage(collectionName, s.access) 44 } 45 46 func (s *cloudImageMetadataSuite) TestSaveMetadata(c *gc.C) { 47 attrs1 := cloudimagemetadata.MetadataAttributes{ 48 Stream: "stream", 49 Region: "region-test", 50 Version: "14.04", 51 Series: "trusty", 52 Arch: "arch", 53 VirtType: "virtType-test", 54 RootStorageType: "rootStorageType-test", 55 Source: "test", 56 } 57 attrs2 := cloudimagemetadata.MetadataAttributes{ 58 Stream: "chalk", 59 Region: "nether", 60 Version: "12.04", 61 Series: "precise", 62 Arch: "amd64", 63 Source: "test", 64 } 65 added := []cloudimagemetadata.Metadata{ 66 {attrs1, 0, "1", 0}, 67 {attrs2, 0, "2", 0}, 68 } 69 s.assertRecordMetadata(c, added[0]) 70 s.assertRecordMetadata(c, added[1]) 71 s.assertMetadataRecorded(c, cloudimagemetadata.MetadataAttributes{}, added...) 72 } 73 74 func (s *cloudImageMetadataSuite) TestSaveMetadataWithDateCreated(c *gc.C) { 75 attrs := cloudimagemetadata.MetadataAttributes{ 76 Stream: "stream", 77 Region: "region-test", 78 Version: "14.04", 79 Series: "trusty", 80 Arch: "arch", 81 VirtType: "virtType-test", 82 RootStorageType: "rootStorageType-test", 83 Source: "test", 84 } 85 now := coretesting.NonZeroTime().UnixNano() 86 metadata := cloudimagemetadata.Metadata{attrs, 0, "1", now} 87 s.assertRecordMetadata(c, metadata) 88 s.assertMetadataRecorded(c, cloudimagemetadata.MetadataAttributes{}, metadata) 89 } 90 91 func (s *cloudImageMetadataSuite) TestSaveMetadataExpiry(c *gc.C) { 92 s.assertSaveMetadataExpiry(c, true) 93 } 94 95 func (s *cloudImageMetadataSuite) TestSaveMetadataNoExpiry(c *gc.C) { 96 s.assertSaveMetadataExpiry(c, false) 97 } 98 99 func (s *cloudImageMetadataSuite) assertSaveMetadataExpiry(c *gc.C, expires bool) { 100 attrs := cloudimagemetadata.MetadataAttributes{ 101 Stream: "stream", 102 Region: "region-test", 103 Version: "14.04", 104 Series: "trusty", 105 Arch: "arch", 106 VirtType: "virtType-test", 107 RootStorageType: "rootStorageType-test", 108 Source: "test", 109 } 110 now := coretesting.NonZeroTime().UnixNano() 111 metadata := []cloudimagemetadata.Metadata{{attrs, 0, "1", now}} 112 s.assertNoMetadata(c) 113 114 var err error 115 if expires { 116 err = s.storage.SaveMetadata(metadata) 117 } else { 118 err = s.storage.SaveMetadataNoExpiry(metadata) 119 } 120 c.Assert(err, jc.ErrorIsNil) 121 coll, closer := s.access.GetCollection(collectionName) 122 defer closer() 123 124 var all []bson.M 125 err = coll.Find(nil).All(&all) 126 c.Assert(err, jc.ErrorIsNil) 127 for _, record := range all { 128 expiresAt, ok := record["expire-at"].(time.Time) 129 c.Assert(ok, gc.Equals, expires) 130 if expires { 131 c.Assert(expiresAt.UnixNano() > now, jc.IsTrue) 132 } 133 } 134 } 135 136 func (s *cloudImageMetadataSuite) TestFindMetadataNotFound(c *gc.C) { 137 s.assertNoMetadata(c) 138 139 // insert something... 140 attrs := cloudimagemetadata.MetadataAttributes{ 141 Stream: "stream", 142 Region: "region", 143 Version: "14.04", 144 Series: "trusty", 145 Arch: "arch", 146 VirtType: "virtType", 147 Source: "test", 148 RootStorageType: "rootStorageType"} 149 m := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 150 s.assertRecordMetadata(c, m) 151 152 // ...but look for something else. 153 none, err := s.storage.FindMetadata(cloudimagemetadata.MetadataFilter{ 154 Stream: "something else", 155 }) 156 // Make sure that we are explicit that we could not find what we wanted. 157 c.Assert(err, jc.Satisfies, errors.IsNotFound) 158 c.Assert(err, gc.ErrorMatches, "matching cloud image metadata not found") 159 c.Assert(none, gc.HasLen, 0) 160 } 161 162 func buildAttributesFilter(attrs cloudimagemetadata.MetadataAttributes) cloudimagemetadata.MetadataFilter { 163 filter := cloudimagemetadata.MetadataFilter{ 164 Stream: attrs.Stream, 165 Region: attrs.Region, 166 VirtType: attrs.VirtType, 167 RootStorageType: attrs.RootStorageType} 168 if attrs.Series != "" { 169 filter.Series = []string{attrs.Series} 170 } 171 if attrs.Arch != "" { 172 filter.Arches = []string{attrs.Arch} 173 } 174 return filter 175 } 176 177 func (s *cloudImageMetadataSuite) TestFindMetadata(c *gc.C) { 178 attrs := cloudimagemetadata.MetadataAttributes{ 179 Stream: "stream", 180 Region: "region", 181 Version: "14.04", 182 Series: "trusty", 183 Arch: "arch", 184 VirtType: "virtType", 185 Source: "test", 186 RootStorageType: "rootStorageType"} 187 188 m := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 189 190 _, err := s.storage.FindMetadata(buildAttributesFilter(attrs)) 191 c.Assert(err, jc.Satisfies, errors.IsNotFound) 192 193 s.assertRecordMetadata(c, m) 194 expected := []cloudimagemetadata.Metadata{m} 195 s.assertMetadataRecorded(c, attrs, expected...) 196 197 attrs.Stream = "another_stream" 198 m = cloudimagemetadata.Metadata{attrs, 0, "2", 0} 199 s.assertRecordMetadata(c, m) 200 201 expected = append(expected, m) 202 // Should find both 203 s.assertMetadataRecorded(c, cloudimagemetadata.MetadataAttributes{Region: "region"}, expected...) 204 } 205 206 func (s *cloudImageMetadataSuite) TestSaveMetadataUpdateSameAttrsAndImages(c *gc.C) { 207 attrs := cloudimagemetadata.MetadataAttributes{ 208 Stream: "stream", 209 Version: "14.04", 210 Series: "trusty", 211 Arch: "arch", 212 Source: "test", 213 Region: "wonder", 214 } 215 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 216 metadata1 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 217 218 s.assertRecordMetadata(c, metadata0) 219 s.assertRecordMetadata(c, metadata1) 220 s.assertMetadataRecorded(c, attrs, metadata1) 221 } 222 223 func (s *cloudImageMetadataSuite) TestSaveMetadataUpdateSameAttrsDiffImages(c *gc.C) { 224 attrs := cloudimagemetadata.MetadataAttributes{ 225 Stream: "stream", 226 Version: "14.04", 227 Series: "trusty", 228 Arch: "arch", 229 Source: "test", 230 Region: "wonder", 231 } 232 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 233 metadata1 := cloudimagemetadata.Metadata{attrs, 0, "12", 0} 234 235 s.assertRecordMetadata(c, metadata0) 236 s.assertMetadataRecorded(c, attrs, metadata0) 237 s.assertRecordMetadata(c, metadata1) 238 s.assertMetadataRecorded(c, attrs, metadata1) 239 s.assertMetadataRecorded(c, cloudimagemetadata.MetadataAttributes{}, metadata1) 240 } 241 242 func (s *cloudImageMetadataSuite) TestSaveMetadataDuplicates(c *gc.C) { 243 attrs := cloudimagemetadata.MetadataAttributes{ 244 Stream: "stream", 245 Version: "14.04", 246 Series: "trusty", 247 Arch: "arch", 248 Source: "test", 249 Region: "wonder", 250 VirtType: "lxd", 251 } 252 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 253 err := s.storage.SaveMetadata([]cloudimagemetadata.Metadata{metadata0, metadata0}) 254 c.Assert(err, gc.ErrorMatches, ".*"+regexp.QuoteMeta(`duplicate metadata record for image id 1 (key="stream:wonder:trusty:arch:lxd::test")`)) 255 } 256 257 func (s *cloudImageMetadataSuite) TestSaveDiffMetadataConcurrentlyAndOrderByDateCreated(c *gc.C) { 258 attrs := cloudimagemetadata.MetadataAttributes{ 259 Stream: "stream", 260 Version: "14.04", 261 Series: "trusty", 262 Arch: "arch", 263 Region: "wonder", 264 Source: "test", 265 } 266 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "0", 0} 267 metadata1 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 268 metadata1.Stream = "scream" 269 270 s.assertConcurrentSave(c, 271 metadata0, // add this one 272 metadata1, // add this one 273 // last added should be first as order is by date created 274 metadata1, // verify it's in the list 275 metadata0, // verify it's in the list 276 ) 277 } 278 279 func (s *cloudImageMetadataSuite) TestSaveSameMetadataDiffImageConcurrently(c *gc.C) { 280 attrs := cloudimagemetadata.MetadataAttributes{ 281 Stream: "stream", 282 Version: "14.04", 283 Series: "trusty", 284 Arch: "arch", 285 Source: "test", 286 Region: "wonder", 287 } 288 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "0", 0} 289 metadata1 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 290 291 s.assertConcurrentSave(c, 292 metadata0, // add this one 293 metadata1, // overwrite it with this one 294 metadata1, // verify only the last one is in the list 295 ) 296 } 297 298 func (s *cloudImageMetadataSuite) TestSaveSameMetadataSameImageConcurrently(c *gc.C) { 299 attrs := cloudimagemetadata.MetadataAttributes{ 300 Stream: "stream", 301 Version: "14.04", 302 Series: "trusty", 303 Arch: "arch", 304 Source: "test", 305 Region: "wonder", 306 } 307 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "0", 0} 308 309 s.assertConcurrentSave(c, 310 metadata0, // add this one 311 metadata0, // add it again 312 metadata0, // varify only one is in the list 313 ) 314 } 315 316 func (s *cloudImageMetadataSuite) TestSaveSameMetadataSameImageDiffSourceConcurrently(c *gc.C) { 317 attrs := cloudimagemetadata.MetadataAttributes{ 318 Stream: "stream", 319 Version: "14.04", 320 Series: "trusty", 321 Arch: "arch", 322 Source: "public", 323 Region: "wonder", 324 } 325 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "0", 0} 326 327 attrs.Source = "custom" 328 metadata1 := cloudimagemetadata.Metadata{attrs, 0, "0", 0} 329 330 s.assertConcurrentSave(c, 331 metadata0, 332 metadata1, 333 metadata0, 334 metadata1, 335 ) 336 } 337 338 func (s *cloudImageMetadataSuite) TestSaveMetadataNoVersionPassed(c *gc.C) { 339 attrs := cloudimagemetadata.MetadataAttributes{ 340 Stream: "stream", 341 Series: "trusty", 342 Arch: "arch", 343 Source: "test", 344 Region: "wonder", 345 } 346 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 347 s.assertRecordMetadata(c, metadata0) 348 } 349 350 func (s *cloudImageMetadataSuite) TestSaveMetadataNoSeriesPassed(c *gc.C) { 351 attrs := cloudimagemetadata.MetadataAttributes{ 352 Stream: "stream", 353 Arch: "arch", 354 Source: "test", 355 Region: "wonder", 356 } 357 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 358 err := s.storage.SaveMetadata([]cloudimagemetadata.Metadata{metadata0}) 359 c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`missing series: metadata for image 1 not valid`)) 360 } 361 362 func (s *cloudImageMetadataSuite) TestSaveMetadataUnsupportedSeriesPassed(c *gc.C) { 363 attrs := cloudimagemetadata.MetadataAttributes{ 364 Stream: "stream", 365 Series: "blah", 366 Arch: "arch", 367 Source: "test", 368 } 369 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 370 err := s.storage.SaveMetadata([]cloudimagemetadata.Metadata{metadata0}) 371 c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`unknown version for series: "blah"`)) 372 } 373 374 func (s *cloudImageMetadataSuite) TestSaveMetadataNoStreamPassed(c *gc.C) { 375 attrs := cloudimagemetadata.MetadataAttributes{ 376 Arch: "arch", 377 Source: "test", 378 Series: "trusty", 379 Region: "wonder", 380 } 381 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 382 err := s.storage.SaveMetadata([]cloudimagemetadata.Metadata{metadata0}) 383 c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`missing stream: metadata for image 1 not valid`)) 384 } 385 386 func (s *cloudImageMetadataSuite) TestSaveMetadataNoSourcePassed(c *gc.C) { 387 attrs := cloudimagemetadata.MetadataAttributes{ 388 Stream: "stream", 389 Arch: "arch", 390 Series: "trusty", 391 Region: "wonder", 392 } 393 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 394 err := s.storage.SaveMetadata([]cloudimagemetadata.Metadata{metadata0}) 395 c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`missing source: metadata for image 1 not valid`)) 396 } 397 398 func (s *cloudImageMetadataSuite) TestSaveMetadataNoArchitecturePassed(c *gc.C) { 399 attrs := cloudimagemetadata.MetadataAttributes{ 400 Stream: "stream", 401 Source: "test", 402 Series: "trusty", 403 Region: "wonder", 404 } 405 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 406 err := s.storage.SaveMetadata([]cloudimagemetadata.Metadata{metadata0}) 407 c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`missing architecture: metadata for image 1 not valid`)) 408 } 409 410 func (s *cloudImageMetadataSuite) TestSaveMetadataNoRegionPassed(c *gc.C) { 411 attrs := cloudimagemetadata.MetadataAttributes{ 412 Stream: "stream", 413 Arch: "arch", 414 Source: "test", 415 Series: "trusty", 416 } 417 metadata0 := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 418 err := s.storage.SaveMetadata([]cloudimagemetadata.Metadata{metadata0}) 419 c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`missing region: metadata for image 1 not valid`)) 420 } 421 422 func (s *cloudImageMetadataSuite) assertConcurrentSave(c *gc.C, metadata0, metadata1 cloudimagemetadata.Metadata, expected ...cloudimagemetadata.Metadata) { 423 addMetadata := func() { 424 s.assertRecordMetadata(c, metadata0) 425 } 426 defer txntesting.SetBeforeHooks(c, s.access.runner, addMetadata).Check() 427 s.assertRecordMetadata(c, metadata1) 428 s.assertMetadataRecorded(c, cloudimagemetadata.MetadataAttributes{}, expected...) 429 } 430 431 func (s *cloudImageMetadataSuite) assertRecordMetadata(c *gc.C, m ...cloudimagemetadata.Metadata) { 432 err := s.storage.SaveMetadata(m) 433 c.Assert(err, jc.ErrorIsNil) 434 } 435 436 func (s *cloudImageMetadataSuite) assertMetadataRecorded( 437 c *gc.C, 438 criteria cloudimagemetadata.MetadataAttributes, 439 expected ...cloudimagemetadata.Metadata, 440 ) { 441 metadata, err := s.storage.FindMetadata(buildAttributesFilter(criteria)) 442 c.Assert(err, jc.ErrorIsNil) 443 444 // Collate expected into a map 445 groups := make(map[string][]cloudimagemetadata.Metadata) 446 for _, expectedMetadata := range expected { 447 groups[expectedMetadata.Source] = append(groups[expectedMetadata.Source], expectedMetadata) 448 } 449 450 // Compare maps by key; order of slices does not matter 451 c.Assert(groups, gc.HasLen, len(metadata)) 452 for source, expectedMetadata := range groups { 453 actual := metadata[source] 454 if len(actual) == len(expectedMetadata) { 455 for i, image := range actual { 456 if expectedMetadata[i].DateCreated == 0 { 457 // Copy the creation date across as this will have been 458 // generated. 459 expectedMetadata[i].DateCreated = image.DateCreated 460 } 461 } 462 } 463 c.Assert(actual, jc.SameContents, expectedMetadata) 464 } 465 } 466 467 func (s *cloudImageMetadataSuite) TestSupportedArchitectures(c *gc.C) { 468 stream := "stream" 469 region := "region-test" 470 471 arch1 := "arch" 472 attrs := cloudimagemetadata.MetadataAttributes{ 473 Stream: stream, 474 Region: region, 475 Version: "14.04", 476 Series: "trusty", 477 Arch: arch1, 478 VirtType: "virtType-test", 479 Source: "test", 480 RootStorageType: "rootStorageType-test"} 481 482 added := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 483 s.assertRecordMetadata(c, added) 484 s.assertMetadataRecorded(c, attrs, added) 485 486 addedNonUnique := cloudimagemetadata.Metadata{attrs, 0, "21", 0} 487 s.assertRecordMetadata(c, addedNonUnique) 488 s.assertMetadataRecorded(c, attrs, addedNonUnique) 489 490 arch2 := "anotherArch" 491 attrs.Arch = arch2 492 added2 := cloudimagemetadata.Metadata{attrs, 0, "21", 0} 493 s.assertRecordMetadata(c, added2) 494 s.assertMetadataRecorded(c, attrs, added2) 495 496 expected := []string{arch1, arch2} 497 uniqueArches, err := s.storage.SupportedArchitectures( 498 cloudimagemetadata.MetadataFilter{Stream: stream, Region: region}) 499 c.Assert(err, jc.ErrorIsNil) 500 c.Assert(uniqueArches, gc.DeepEquals, expected) 501 } 502 503 func (s *cloudImageMetadataSuite) TestSupportedArchitecturesUnmatchedStreams(c *gc.C) { 504 stream := "stream" 505 region := "region-test" 506 507 attrs := cloudimagemetadata.MetadataAttributes{ 508 Stream: "new-stream", 509 Region: region, 510 Version: "14.04", 511 Series: "trusty", 512 Arch: "arch", 513 VirtType: "virtType-test", 514 Source: "test", 515 RootStorageType: "rootStorageType-test"} 516 517 added := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 518 s.assertRecordMetadata(c, added) 519 s.assertMetadataRecorded(c, attrs, added) 520 521 uniqueArches, err := s.storage.SupportedArchitectures( 522 cloudimagemetadata.MetadataFilter{Stream: stream, Region: region}) 523 c.Assert(err, jc.ErrorIsNil) 524 c.Assert(uniqueArches, gc.DeepEquals, []string{}) 525 } 526 527 func (s *cloudImageMetadataSuite) TestSupportedArchitecturesUnmatchedRegions(c *gc.C) { 528 stream := "stream" 529 region := "region-test" 530 531 attrs := cloudimagemetadata.MetadataAttributes{ 532 Stream: stream, 533 Region: "new-region", 534 Version: "14.04", 535 Series: "trusty", 536 Arch: "arch", 537 VirtType: "virtType-test", 538 Source: "test", 539 RootStorageType: "rootStorageType-test"} 540 541 added := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 542 s.assertRecordMetadata(c, added) 543 s.assertMetadataRecorded(c, attrs, added) 544 545 uniqueArches, err := s.storage.SupportedArchitectures( 546 cloudimagemetadata.MetadataFilter{Stream: stream, Region: region}) 547 c.Assert(err, jc.ErrorIsNil) 548 c.Assert(uniqueArches, gc.DeepEquals, []string{}) 549 } 550 551 func (s *cloudImageMetadataSuite) TestSupportedArchitecturesUnmatchedStreamsAndRegions(c *gc.C) { 552 stream := "stream" 553 region := "region-test" 554 555 attrs := cloudimagemetadata.MetadataAttributes{ 556 Stream: "new-stream", 557 Region: "new-region", 558 Version: "14.04", 559 Series: "trusty", 560 Arch: "arch", 561 VirtType: "virtType-test", 562 Source: "test", 563 RootStorageType: "rootStorageType-test"} 564 565 added := cloudimagemetadata.Metadata{attrs, 0, "1", 0} 566 s.assertRecordMetadata(c, added) 567 s.assertMetadataRecorded(c, attrs, added) 568 569 uniqueArches, err := s.storage.SupportedArchitectures( 570 cloudimagemetadata.MetadataFilter{Stream: stream, Region: region}) 571 c.Assert(err, jc.ErrorIsNil) 572 c.Assert(uniqueArches, gc.DeepEquals, []string{}) 573 } 574 575 func (s *cloudImageMetadataSuite) TestDeleteMetadata(c *gc.C) { 576 imageId := "ok-to-delete" 577 s.addTestImageMetadata(c, imageId) 578 s.assertDeleteMetadata(c, imageId) 579 s.assertNoMetadata(c) 580 581 // calling delete on it again should be a no-op 582 s.assertDeleteMetadata(c, imageId) 583 // make sure log has "nothing to delete" message 584 c.Assert(c.GetTestLog(), jc.Contains, "no metadata for image ID ok-to-delete to delete") 585 } 586 587 func (s *cloudImageMetadataSuite) TestDeleteDiffMetadataConcurrently(c *gc.C) { 588 imageId := "ok-to-delete" 589 s.addTestImageMetadata(c, imageId) 590 591 diffImageId := "ok-to-delete-too" 592 s.addTestImageMetadata(c, diffImageId) 593 594 s.assertConcurrentDelete(c, imageId, diffImageId) 595 } 596 597 func (s *cloudImageMetadataSuite) TestDeleteSameMetadataConcurrently(c *gc.C) { 598 imageId := "ok-to-delete" 599 s.addTestImageMetadata(c, imageId) 600 601 s.assertConcurrentDelete(c, imageId, imageId) 602 } 603 604 func (s *cloudImageMetadataSuite) assertConcurrentDelete(c *gc.C, imageId0, imageId1 string) { 605 deleteMetadata := func() { 606 s.assertDeleteMetadata(c, imageId0) 607 } 608 defer txntesting.SetBeforeHooks(c, s.access.runner, deleteMetadata).Check() 609 s.assertDeleteMetadata(c, imageId1) 610 s.assertNoMetadata(c) 611 } 612 613 func (s *cloudImageMetadataSuite) addTestImageMetadata(c *gc.C, imageId string) { 614 attrs := cloudimagemetadata.MetadataAttributes{ 615 Stream: "stream", 616 Region: "region-test", 617 Version: "14.04", 618 Series: "trusty", 619 Arch: "arch", 620 VirtType: "virtType-test", 621 Source: "test", 622 RootStorageType: "rootStorageType-test"} 623 624 added := cloudimagemetadata.Metadata{attrs, 0, imageId, 0} 625 s.assertRecordMetadata(c, added) 626 s.assertMetadataRecorded(c, attrs, added) 627 } 628 629 func (s *cloudImageMetadataSuite) assertDeleteMetadata(c *gc.C, imageId string) { 630 err := s.storage.DeleteMetadata(imageId) 631 c.Assert(err, jc.ErrorIsNil) 632 } 633 634 func (s *cloudImageMetadataSuite) assertNoMetadata(c *gc.C) { 635 // No metadata should be in store. 636 // So when looking for all and none is found, err. 637 found, err := s.storage.FindMetadata(cloudimagemetadata.MetadataFilter{}) 638 c.Assert(err, jc.Satisfies, errors.IsNotFound) 639 c.Assert(err, gc.ErrorMatches, "matching cloud image metadata not found") 640 c.Assert(found, gc.HasLen, 0) 641 } 642 643 type TestMongo struct { 644 database *mgo.Database 645 runner txn.Runner 646 } 647 648 func NewTestMongo(database *mgo.Database) *TestMongo { 649 return &TestMongo{ 650 database: database, 651 runner: txn.NewRunner(txn.RunnerParams{ 652 Database: database, 653 }), 654 } 655 } 656 657 func (m *TestMongo) GetCollection(name string) (mongo.Collection, func()) { 658 return mongo.CollectionFromName(m.database, name) 659 } 660 661 func (m *TestMongo) RunTransaction(getTxn txn.TransactionSource) error { 662 return m.runner.Run(getTxn) 663 }