func (s tagSetSuite) TestDifference(c *gc.C) { t1 := set.NewTags(s.foo, s.bar) t2 := set.NewTags(s.foo, s.baz, s.bang) diff1 := t1.Difference(t2) diff2 := t2.Difference(t1) c.Assert(diff1, gc.DeepEquals, set.NewTags(s.bar)) c.Assert(diff2, gc.DeepEquals, set.NewTags(s.baz, s.bang)) }
// MinionReports implements ModelMigration. func (mig *modelMigration) MinionReports() (*MinionReports, error) { all, err := mig.getAllAgents() if err != nil { return nil, errors.Trace(err) } phase, err := mig.Phase() if err != nil { return nil, errors.Annotate(err, "retrieving phase") } coll, closer := mig.st.getCollection(migrationsMinionSyncC) defer closer() query := coll.Find(bson.M{"_id": bson.M{ "$regex": "^" + mig.minionReportId(phase, ".+"), }}) query = query.Select(bson.M{ "entity-key": 1, "success": 1, }) var docs []bson.M if err := query.All(&docs); err != nil { return nil, errors.Annotate(err, "retrieving minion reports") } succeeded := set.NewTags() failed := set.NewTags() for _, doc := range docs { entityKey, ok := doc["entity-key"].(string) if !ok { return nil, errors.Errorf("unexpected entity-key %v", doc["entity-key"]) } tag, err := globalKeyToAgentTag(entityKey) if err != nil { return nil, errors.Trace(err) } success, ok := doc["success"].(bool) if !ok { return nil, errors.Errorf("unexpected success value: %v", doc["success"]) } if success { succeeded.Add(tag) } else { failed.Add(tag) } } unknown := all.Difference(succeeded).Difference(failed) return &MinionReports{ Succeeded: succeeded.Values(), Failed: failed.Values(), Unknown: unknown.Values(), }, nil }
func (s tagSetSuite) TestUnion(c *gc.C) { t1 := set.NewTags(s.foo, s.bar) t2 := set.NewTags(s.foo, s.baz, s.bang) union1 := t1.Union(t2) union2 := t2.Union(t1) c.Assert(union1.Size(), gc.Equals, 4) c.Assert(union2.Size(), gc.Equals, 4) c.Assert(union1, gc.DeepEquals, union2) c.Assert(union1, gc.DeepEquals, set.NewTags(s.foo, s.bar, s.baz, s.bang)) }
func (s tagSetSuite) TestIsEmpty(c *gc.C) { // Empty sets are empty. t := set.NewTags() c.Assert(t.IsEmpty(), gc.Equals, true) // Non-empty sets are not empty. t = set.NewTags(s.foo) c.Assert(t.IsEmpty(), gc.Equals, false) // Newly empty sets work too. t.Remove(s.foo) c.Assert(t.IsEmpty(), gc.Equals, true) }
func (s tagSetSuite) TestIntersection(c *gc.C) { t1 := set.NewTags(s.foo, s.bar) t2 := set.NewTags(s.foo, s.baz, s.bang) int1 := t1.Intersection(t2) int2 := t2.Intersection(t1) c.Assert(int1.Size(), gc.Equals, 1) c.Assert(int2.Size(), gc.Equals, 1) c.Assert(int1, gc.DeepEquals, int2) c.Assert(int1, gc.DeepEquals, set.NewTags(s.foo)) }
func (s tagSetSuite) TestRemove(c *gc.C) { t := set.NewTags(s.foo, s.bar) t.Remove(s.foo) c.Assert(t.Contains(s.foo), gc.Equals, false) c.Assert(t.Contains(s.bar), gc.Equals, true) }
func (s tagSetSuite) TestAddDuplicate(c *gc.C) { t := set.NewTags() t.Add(s.foo) t.Add(s.bar) t.Add(s.bar) c.Assert(t.Size(), gc.Equals, 2) }
func (s *attachmentsSuite) TestAttachmentsUpdateShortCircuitDeath(c *gc.C) { stateDir := c.MkDir() unitTag := names.NewUnitTag("mysql/0") abort := make(chan struct{}) storageTag0 := names.NewStorageTag("data/0") storageTag1 := names.NewStorageTag("data/1") removed := set.NewTags() st := &mockStorageAccessor{ unitStorageAttachments: func(u names.UnitTag) ([]params.StorageAttachmentId, error) { return nil, nil }, remove: func(s names.StorageTag, u names.UnitTag) error { c.Assert(u, gc.Equals, unitTag) removed.Add(s) return nil }, } att, err := storage.NewAttachments(st, unitTag, stateDir, abort) c.Assert(err, jc.ErrorIsNil) r := storage.NewResolver(att) // First make sure we create a storage-attached hook operation for // data/0. We do this to show that until the hook is *committed*, // we will still short-circuit removal. localState := resolver.LocalState{State: operation.State{ Kind: operation.Continue, }} _, err = r.NextOp(localState, remotestate.Snapshot{ Life: params.Alive, Storage: map[names.StorageTag]remotestate.StorageSnapshot{ storageTag0: { Life: params.Alive, Kind: params.StorageKindBlock, Location: "/dev/sdb", Attached: true, }, }, }, &mockOperations{}) c.Assert(err, jc.ErrorIsNil) for _, storageTag := range []names.StorageTag{storageTag0, storageTag1} { _, err = r.NextOp(localState, remotestate.Snapshot{ Life: params.Alive, Storage: map[names.StorageTag]remotestate.StorageSnapshot{ storageTag: {Life: params.Dying}, }, }, nil) c.Assert(err, gc.Equals, resolver.ErrNoOperation) } c.Assert(removed.SortedValues(), jc.DeepEquals, []names.Tag{ storageTag0, storageTag1, }) }
func (s *storageContextAccessor) StorageTags() []names.StorageTag { tags := set.NewTags() for tag := range s.storage { tags.Add(tag) } storageTags := make([]names.StorageTag, len(tags)) for i, tag := range tags.SortedValues() { storageTags[i] = tag.(names.StorageTag) } return storageTags }
// StorageTags returns the names.StorageTags for the active storage attachments. func (a *Attachments) StorageTags() []names.StorageTag { tags := set.NewTags() for tag := range a.storagers { tags.Add(tag) } storageTags := make([]names.StorageTag, tags.Size()) for i, tag := range tags.SortedValues() { storageTags[i] = tag.(names.StorageTag) } return storageTags }
func (tagSetSuite) TestSize(c *gc.C) { // Empty sets are empty. s := set.NewTags() c.Assert(s.Size(), gc.Equals, 0) s, err := set.NewTagsFromStrings( "unit-wordpress-0", "unit-rabbitmq-server-0", ) c.Assert(err, gc.IsNil) c.Assert(s.Size(), gc.Equals, 2) }
// StorageTags implements jujuc.ContextStorage. func (c *ContextStorage) StorageTags() ([]names.StorageTag, error) { c.stub.AddCall("StorageTags") tags := set.NewTags() for tag := range c.info.Storage { tags.Add(tag) } storageTags := make([]names.StorageTag, tags.Size()) for i, tag := range tags.SortedValues() { storageTags[i] = tag.(names.StorageTag) } return storageTags, c.stub.NextErr() }
// processPendingVolumeBlockDevices is called before waiting for any events, // to force a block-device query for any volumes for which we have not // previously observed block devices. func processPendingVolumeBlockDevices(ctx *context) error { if len(ctx.pendingVolumeBlockDevices) == 0 { logger.Tracef("no pending volume block devices") return nil } volumeTags := make([]names.VolumeTag, len(ctx.pendingVolumeBlockDevices)) for i, tag := range ctx.pendingVolumeBlockDevices.SortedValues() { volumeTags[i] = tag.(names.VolumeTag) } // Clear out the pending set, so we don't force-refresh again. ctx.pendingVolumeBlockDevices = set.NewTags() return refreshVolumeBlockDevices(ctx, volumeTags) }
func (tagSetSuite) TestSizeDuplicate(c *gc.C) { // Empty sets are empty. s := set.NewTags() c.Assert(s.Size(), gc.Equals, 0) // Size returns number of unique values. s, err := set.NewTagsFromStrings( "unit-wordpress-0", "unit-rabbitmq-server-0", "unit-wordpress-0", ) c.Assert(err, gc.IsNil) c.Assert(s.Size(), gc.Equals, 2) }
// storageChanged responds to unit storage changes. func (f *filter) storageChanged(changed []names.StorageTag) { tags := set.NewTags() // f.storage is []StorageTag, not []Tag for _, tag := range f.storage { tags.Add(tag) } for _, tag := range changed { tags.Add(tag) } if len(f.storage) != len(tags) { storage := make([]names.StorageTag, len(tags)) for i, tag := range tags.SortedValues() { storage[i] = tag.(names.StorageTag) } f.storage = storage f.outStorage = f.outStorageOn } }
func (mig *modelMigration) loadAgentTags(collName, fieldName string, convert func(string) names.Tag) ( set.Tags, error, ) { // During migrations we know that nothing there are no machines or // units being provisioned or destroyed so a simple query of the // collections will do. coll, closer := mig.st.getCollection(collName) defer closer() var docs []bson.M err := coll.Find(nil).Select(bson.M{fieldName: 1}).All(&docs) if err != nil { return nil, errors.Trace(err) } out := set.NewTags() for _, doc := range docs { v, ok := doc[fieldName].(string) if !ok { return nil, errors.Errorf("invalid %s value: %v", fieldName, doc[fieldName]) } out.Add(convert(v)) } return out, nil }
func (s tagSetSuite) TestInitialValues(c *gc.C) { t := set.NewTags(s.foo, s.bar) c.Assert(t.Size(), gc.Equals, 2) }
func (s tagSetSuite) TestSortedValues(c *gc.C) { t := set.NewTags(s.foo, s.bang, s.baz, s.bar) values := t.SortedValues() c.Assert(values, gc.DeepEquals, []names.Tag{s.bang, s.baz, s.bar, s.foo}) }
func (tagSetSuite) TestEmpty(c *gc.C) { t := set.NewTags() c.Assert(t.Size(), gc.Equals, 0) }
func (s tagSetSuite) TestRemoveNonExistent(c *gc.C) { t := set.NewTags() t.Remove(s.foo) c.Assert(t.Size(), gc.Equals, 0) }
func (s tagSetSuite) TestAdd(c *gc.C) { t := set.NewTags() t.Add(s.foo) c.Assert(t.Size(), gc.Equals, 1) c.Assert(t.Contains(s.foo), gc.Equals, true) }