Beispiel #1
0
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))
}
Beispiel #2
0
// 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
}
Beispiel #3
0
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))
}
Beispiel #4
0
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)
}
Beispiel #5
0
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))
}
Beispiel #6
0
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)
}
Beispiel #7
0
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)
}
Beispiel #8
0
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,
	})
}
Beispiel #9
0
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
}
Beispiel #10
0
// 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
}
Beispiel #11
0
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)
}
Beispiel #12
0
// 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()
}
Beispiel #13
0
// 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)
}
Beispiel #14
0
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)
}
Beispiel #15
0
// 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
	}
}
Beispiel #16
0
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
}
Beispiel #17
0
func (s tagSetSuite) TestInitialValues(c *gc.C) {
	t := set.NewTags(s.foo, s.bar)
	c.Assert(t.Size(), gc.Equals, 2)
}
Beispiel #18
0
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})
}
Beispiel #19
0
func (tagSetSuite) TestEmpty(c *gc.C) {
	t := set.NewTags()
	c.Assert(t.Size(), gc.Equals, 0)
}
Beispiel #20
0
func (s tagSetSuite) TestRemoveNonExistent(c *gc.C) {
	t := set.NewTags()
	t.Remove(s.foo)
	c.Assert(t.Size(), gc.Equals, 0)
}
Beispiel #21
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)
}