Move topology diff to render package.

This commit is contained in:
Tom Wilkie
2015-06-15 17:12:23 +00:00
parent ae9ea5c97f
commit 4726b48f4e
5 changed files with 63 additions and 53 deletions

41
render/topology_diff.go Normal file
View File

@@ -0,0 +1,41 @@
package render
import (
"reflect"
"github.com/weaveworks/scope/report"
)
// Diff is returned by TopoDiff. It represents the changes between two
// RenderableNode maps.
type Diff struct {
Add []report.RenderableNode `json:"add"`
Update []report.RenderableNode `json:"update"`
Remove []string `json:"remove"`
}
// TopoDiff gives you the diff to get from A to B.
func TopoDiff(a, b report.RenderableNodes) Diff {
diff := Diff{}
notSeen := map[string]struct{}{}
for k := range a {
notSeen[k] = struct{}{}
}
for k, node := range b {
if _, ok := a[k]; !ok {
diff.Add = append(diff.Add, node)
} else if !reflect.DeepEqual(node, a[k]) {
diff.Update = append(diff.Update, node)
}
delete(notSeen, k)
}
// leftover keys
for k := range notSeen {
diff.Remove = append(diff.Remove, k)
}
return diff
}

View File

@@ -0,0 +1,93 @@
package render
import (
"reflect"
"sort"
"testing"
"github.com/weaveworks/scope/report"
)
// ByID is a sort interface for a RenderableNode slice.
type ByID []report.RenderableNode
func (r ByID) Len() int { return len(r) }
func (r ByID) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
func (r ByID) Less(i, j int) bool { return r[i].ID < r[j].ID }
func TestTopoDiff(t *testing.T) {
nodea := report.RenderableNode{
ID: "nodea",
LabelMajor: "Node A",
LabelMinor: "'ts an a",
Pseudo: false,
Adjacency: []string{
"nodeb",
},
}
nodeap := nodea
nodeap.Adjacency = []string{
"nodeb",
"nodeq", // not the same anymore
}
nodeb := report.RenderableNode{
ID: "nodeb",
LabelMajor: "Node B",
}
// Helper to make RenderableNode maps.
nodes := func(ns ...report.RenderableNode) report.RenderableNodes {
r := report.RenderableNodes{}
for _, n := range ns {
r[n.ID] = n
}
return r
}
for _, c := range []struct {
label string
have, want Diff
}{
{
label: "basecase: empty -> something",
have: TopoDiff(nodes(), nodes(nodea, nodeb)),
want: Diff{
Add: []report.RenderableNode{nodea, nodeb},
},
},
{
label: "basecase: something -> empty",
have: TopoDiff(nodes(nodea, nodeb), nodes()),
want: Diff{
Remove: []string{"nodea", "nodeb"},
},
},
{
label: "add and remove",
have: TopoDiff(nodes(nodea), nodes(nodeb)),
want: Diff{
Add: []report.RenderableNode{nodeb},
Remove: []string{"nodea"},
},
},
{
label: "no change",
have: TopoDiff(nodes(nodea), nodes(nodea)),
want: Diff{},
},
{
label: "change a single node",
have: TopoDiff(nodes(nodea), nodes(nodeap)),
want: Diff{
Update: []report.RenderableNode{nodeap},
},
},
} {
sort.Strings(c.have.Remove)
sort.Sort(ByID(c.have.Add))
sort.Sort(ByID(c.have.Update))
if !reflect.DeepEqual(c.want, c.have) {
t.Errorf("%s - %s", c.label, diff(c.want, c.have))
}
}
}