Skip to content

Commit

Permalink
Move topology diff to render package.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Wilkie committed Jun 16, 2015
1 parent ae9ea5c commit 4726b48
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 53 deletions.
3 changes: 2 additions & 1 deletion app/api_topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/gorilla/mux"
"github.com/gorilla/websocket"

"github.com/weaveworks/scope/render"
"github.com/weaveworks/scope/report"
)

Expand Down Expand Up @@ -116,7 +117,7 @@ func handleWebsocket(
)
for {
newTopo := t.renderer.Render(rep.Report())
diff := report.TopoDiff(previousTopo, newTopo)
diff := render.TopoDiff(previousTopo, newTopo)
previousTopo = newTopo

if err := conn.SetWriteDeadline(time.Now().Add(websocketTimeout)); err != nil {
Expand Down
3 changes: 2 additions & 1 deletion app/api_topology_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/gorilla/websocket"

"github.com/weaveworks/scope/render"
"github.com/weaveworks/scope/report"
)

Expand Down Expand Up @@ -146,7 +147,7 @@ func TestAPITopologyWebsocket(t *testing.T) {

_, p, err := ws.ReadMessage()
ok(t, err)
var d report.Diff
var d render.Diff
if err := json.Unmarshal(p, &d); err != nil {
t.Fatalf("JSON parse error: %s", err)
}
Expand Down
41 changes: 41 additions & 0 deletions render/topology_diff.go
Original file line number Diff line number Diff line change
@@ -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
}
27 changes: 18 additions & 9 deletions report/topology_test.go → render/topology_diff_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
package report
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 := RenderableNode{
nodea := report.RenderableNode{
ID: "nodea",
LabelMajor: "Node A",
LabelMinor: "'ts an a",
Expand All @@ -21,14 +30,14 @@ func TestTopoDiff(t *testing.T) {
"nodeb",
"nodeq", // not the same anymore
}
nodeb := RenderableNode{
nodeb := report.RenderableNode{
ID: "nodeb",
LabelMajor: "Node B",
}

// Helper to make RenderableNode maps.
nodes := func(ns ...RenderableNode) RenderableNodes {
r := RenderableNodes{}
nodes := func(ns ...report.RenderableNode) report.RenderableNodes {
r := report.RenderableNodes{}
for _, n := range ns {
r[n.ID] = n
}
Expand All @@ -43,7 +52,7 @@ func TestTopoDiff(t *testing.T) {
label: "basecase: empty -> something",
have: TopoDiff(nodes(), nodes(nodea, nodeb)),
want: Diff{
Add: []RenderableNode{nodea, nodeb},
Add: []report.RenderableNode{nodea, nodeb},
},
},
{
Expand All @@ -57,7 +66,7 @@ func TestTopoDiff(t *testing.T) {
label: "add and remove",
have: TopoDiff(nodes(nodea), nodes(nodeb)),
want: Diff{
Add: []RenderableNode{nodeb},
Add: []report.RenderableNode{nodeb},
Remove: []string{"nodea"},
},
},
Expand All @@ -70,15 +79,15 @@ func TestTopoDiff(t *testing.T) {
label: "change a single node",
have: TopoDiff(nodes(nodea), nodes(nodeap)),
want: Diff{
Update: []RenderableNode{nodeap},
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 - want:%s have:%s", c.label, c.want, c.have)
t.Errorf("%s - %s", c.label, diff(c.want, c.have))
}
}
}
42 changes: 0 additions & 42 deletions report/topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package report
import (
"fmt"
"net"
"reflect"
"strings"
)

Expand Down Expand Up @@ -119,47 +118,6 @@ func netsContain(nets []*net.IPNet, ip net.IP) bool {
return false
}

// Diff is returned by TopoDiff. It represents the changes between two
// RenderableNode maps.
type Diff struct {
Add []RenderableNode `json:"add"`
Update []RenderableNode `json:"update"`
Remove []string `json:"remove"`
}

// TopoDiff gives you the diff to get from A to B.
func TopoDiff(a, b 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
}

// ByID is a sort interface for a RenderableNode slice.
type ByID []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 }

// Validate checks the topology for various inconsistencies.
func (t Topology) Validate() error {
// Check all edge metadata keys must have the appropriate entries in
Expand Down

0 comments on commit 4726b48

Please sign in to comment.