Add 'latest' CRDT; use it to store container state.

Also use same technique to merge the controls, returning the latest
set of controls instead of the union.
This commit is contained in:
Tom Wilkie
2015-11-05 18:00:15 +00:00
parent f7c75f9cd3
commit 43d0ce986f
23 changed files with 867 additions and 43 deletions

View File

@@ -207,7 +207,7 @@ func controlsFor(topology report.Topology, nodeID string) []ControlInstance {
return result
}
for _, id := range node.Controls {
for _, id := range node.Controls.Controls {
if control, ok := topology.Controls[id]; ok {
result = append(result, ControlInstance{
ProbeID: node.Metadata[report.ProbeID],
@@ -347,6 +347,13 @@ func containerOriginTable(nmd report.Node, addHostTag bool) (Table, bool) {
rows := []Row{}
for _, tuple := range []struct{ key, human string }{
{docker.ContainerState, "State"},
} {
if val, ok := nmd.Latest.Lookup(tuple.key); ok && val != "" {
rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""})
}
}
for _, tuple := range []struct{ key, human string }{
{docker.ContainerID, "ID"},
{docker.ImageID, "Image ID"},
{docker.ContainerPorts, "Ports"},

View File

@@ -58,6 +58,7 @@ func TestOriginTable(t *testing.T) {
Rank: 3,
Rows: []render.Row{
{"Host", fixture.ServerHostID, "", false},
{"State", "running", "", false},
{"ID", fixture.ServerContainerID, "", false},
{"Image ID", fixture.ServerContainerImageID, "", false},
{fmt.Sprintf(`Label %q`, render.AmazonECSContainerNameLabel), `server`, "", false},
@@ -161,6 +162,7 @@ func TestMakeDetailedContainerNode(t *testing.T) {
Numeric: false,
Rank: 3,
Rows: []render.Row{
{"State", "running", "", false},
{"ID", fixture.ServerContainerID, "", false},
{"Image ID", fixture.ServerContainerImageID, "", false},
{fmt.Sprintf(`Label %q`, render.AmazonECSContainerNameLabel), `server`, "", false},

View File

@@ -138,8 +138,8 @@ func FilterStopped(r Renderer) Renderer {
return Filter{
Renderer: r,
FilterFunc: func(node RenderableNode) bool {
containerState := node.Metadata[docker.ContainerState]
return containerState != docker.StateStopped
containerState, ok := node.Latest.Lookup(docker.ContainerState)
return !ok || containerState != docker.StateStopped
},
}
}

View File

@@ -190,7 +190,7 @@ func TestFilterRender(t *testing.T) {
want := render.RenderableNodes{
"foo": {ID: "foo", Origins: report.IDList{}, Node: report.MakeNode().WithAdjacent("bar")},
"bar": {ID: "bar", Origins: report.IDList{}, Node: report.MakeNode().WithAdjacent("foo")},
}
}.Prune()
have := renderer.Render(report.MakeReport()).Prune()
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
@@ -212,7 +212,7 @@ func TestFilterRender2(t *testing.T) {
want := render.RenderableNodes{
"foo": {ID: "foo", Origins: report.IDList{}, Node: report.MakeNode()},
"baz": {ID: "baz", Origins: report.IDList{}, Node: report.MakeNode()},
}
}.Prune()
have := renderer.Render(report.MakeReport()).Prune()
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
@@ -253,7 +253,7 @@ func TestFilterUnconnectedPesudoNodes(t *testing.T) {
}
want := render.RenderableNodes{
"foo": {ID: "foo", Origins: report.IDList{}, Node: report.MakeNode()},
}
}.Prune()
have := renderer.Render(report.MakeReport()).Prune()
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
@@ -272,7 +272,7 @@ func TestFilterUnconnectedPesudoNodes(t *testing.T) {
}
want := render.RenderableNodes{
"foo": {ID: "foo", Origins: report.IDList{}, Node: report.MakeNode()},
}
}.Prune()
have := renderer.Render(report.MakeReport()).Prune()
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))

View File

@@ -134,10 +134,12 @@ func (rn RenderableNode) Copy() RenderableNode {
// Specifically, that means cutting out parts of the Node.
func (rn RenderableNode) Prune() RenderableNode {
cp := rn.Copy()
cp.Node.Metadata = report.Metadata{} // snip
cp.Node.Counters = report.Counters{} // snip
cp.Node.Edges = report.EdgeMetadatas{} // snip
cp.Node.Sets = report.Sets{} // snip
cp.Node.Metadata = report.Metadata{} // snip
cp.Node.Counters = report.Counters{} // snip
cp.Node.Edges = report.EdgeMetadatas{} // snip
cp.Node.Sets = report.Sets{} // snip
cp.Node.Controls = report.NodeControls{} // snip
cp.Node.Latest = report.LatestMap{} // snip
return cp
}

View File

@@ -23,7 +23,7 @@ func TestMergeRenderableNodes(t *testing.T) {
"bar": render.NewRenderableNode("bar"),
"baz": render.NewRenderableNode("baz"),
}).Prune()
have := nodes1.Merge(nodes2)
have := nodes1.Merge(nodes2).Prune()
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
}
@@ -57,8 +57,8 @@ func TestMergeRenderableNode(t *testing.T) {
Node: report.MakeNode().WithAdjacent("a1").WithAdjacent("a2"),
Origins: report.MakeIDList("o1", "o2"),
EdgeMetadata: report.EdgeMetadata{},
}
have := node1.Merge(node2)
}.Prune()
have := node1.Merge(node2).Prune()
if !reflect.DeepEqual(want, have) {
t.Error(test.Diff(want, have))
}