diff --git a/discovery/discovery.go b/discovery/discovery.go index e9e44adb77..f1440e044e 100644 --- a/discovery/discovery.go +++ b/discovery/discovery.go @@ -52,6 +52,35 @@ func (e Entries) Equals(cmp Entries) bool { return true } +// Contains returns true if the Entries contain a given Entry. +func (e Entries) Contains(entry *Entry) bool { + for _, curr := range e { + if curr.Equals(entry) { + return true + } + } + return false +} + +// Diff compares two entries and returns the added and removed entries. +func (e Entries) Diff(cmp Entries) (Entries, Entries) { + added := Entries{} + for _, entry := range cmp { + if !e.Contains(entry) { + added = append(added, entry) + } + } + + removed := Entries{} + for _, entry := range e { + if !cmp.Contains(entry) { + removed = append(removed, entry) + } + } + + return added, removed +} + // The Discovery interface is implemented by Discovery backends which // manage swarm host entries. type Discovery interface { diff --git a/discovery/discovery_test.go b/discovery/discovery_test.go index 0c5127473c..c799416561 100644 --- a/discovery/discovery_test.go +++ b/discovery/discovery_test.go @@ -80,3 +80,34 @@ func TestEntriesEquality(t *testing.T) { &Entry{Host: "127.0.0.42", Port: "2375"}, })) } + +func TestEntriesDiff(t *testing.T) { + entry1 := &Entry{Host: "1.1.1.1", Port: "1111"} + entry2 := &Entry{Host: "2.2.2.2", Port: "2222"} + entry3 := &Entry{Host: "3.3.3.3", Port: "3333"} + entries := Entries{entry1, entry2} + + // No diff + added, removed := entries.Diff(Entries{entry2, entry1}) + assert.Empty(t, added) + assert.Empty(t, removed) + + // Add + added, removed = entries.Diff(Entries{entry2, entry3, entry1}) + assert.Len(t, added, 1) + assert.True(t, added.Contains(entry3)) + assert.Empty(t, removed) + + // Remove + added, removed = entries.Diff(Entries{entry2}) + assert.Empty(t, added) + assert.Len(t, removed, 1) + assert.True(t, removed.Contains(entry1)) + + // Add and remove + added, removed = entries.Diff(Entries{entry1, entry3}) + assert.Len(t, added, 1) + assert.True(t, added.Contains(entry3)) + assert.Len(t, removed, 1) + assert.True(t, removed.Contains(entry2)) +}