diff --git a/report/marshal_test.go b/report/marshal_test.go index 19af7b7fe..28615f129 100644 --- a/report/marshal_test.go +++ b/report/marshal_test.go @@ -5,8 +5,11 @@ import ( "compress/gzip" "reflect" "testing" + "time" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/report" + s_reflect "github.com/weaveworks/scope/test/reflect" ) func TestRoundtrip(t *testing.T) { @@ -30,6 +33,59 @@ func TestRoundtrip(t *testing.T) { } } +// Create a Report for test purposes that contains about one of +// everything interesting. Not more than one, to avoid different +// ordering comparing unequal +func makeTestReport() report.Report { + // Note: why doesn't Scope generally force all times to UTC? + nowTime := time.Date(2016, 12, 25, 7, 37, 0, 0, time.UTC) + t1 := nowTime.Add(-time.Minute) + t2 := t1.Add(time.Second) + mtime.NowForce(nowTime) + r := report.MakeReport() + r.ID = "3894069658342253419" + r.Endpoint.AddNode(report.MakeNode(";172.20.1.168;41582"). + WithTopology("endpoint"). + WithSet("snooped_dns_names", report.MakeStringSet("ip-172-20-1-168.ec2.internal")). + WithControls("docker_remove_container"). + WithLatestActiveControls("docker_pause_container"). + WithLatest("addr", t1, "127.0.0.1"), + ) + r.Process.WithShape("square").WithLabel("process", "processes"). + AddNode(report.MakeNode("ip-172-20-1-168;10446"). + WithTopology("process"). + WithParents(report.MakeSets().Add("host", report.MakeStringSet("ip-172-20-1-168;"))). + WithLatest("pid", t1, "10446"). + WithMetrics(report.Metrics{"process_cpu_usage_percent": report.MakeMetric([]report.Sample{{Timestamp: t1, Value: 0.1}, {Timestamp: t2, Value: 0.2}})})) + r.Pod.WithShape("heptagon").WithLabel("pod", "pods"). + AddNode(report.MakeNode("fceef9592ec3cf1a8e1d178fdd0de41a;"). + WithTopology("pod"). + WithControls("kubernetes_delete_pod"). + WithLatestControls(map[string]report.NodeControlData{"kubernetes_get_logs": {Dead: true}}). + WithLatest("host_node_id", t1, "ip-172-20-1-168;")) + r.Overlay.WithMetadataTemplates(report.MetadataTemplates{ + "weave_encryption": report.MetadataTemplate{ID: "weave_encryption", Label: "Encryption", Priority: 4, From: "latest"}, + }). + AddNode(report.MakeNode("#docker_peer_ip-172-20-1-168"). + WithTopology("overlay"). + WithSet("local_networks", report.MakeStringSet("172.18.0.0/16"))) + mtime.NowReset() + return r +} + +func TestBiggerRoundtrip(t *testing.T) { + var buf bytes.Buffer + r1 := makeTestReport() + r1.WriteBinary(&buf, gzip.BestCompression) + r2, err := report.MakeFromBinary(&buf) + if err != nil { + t.Error(err) + } + if !s_reflect.DeepEqual(r1, *r2) { + t.Errorf("%v != %v", r1, *r2) + } +} + func TestRoundtripNoCompression(t *testing.T) { // Make sure that we can use our standard routines for decompressing // something with '0' level compression. diff --git a/report/node.go b/report/node.go index 5fabaa55a..94fcb5c58 100644 --- a/report/node.go +++ b/report/node.go @@ -18,7 +18,7 @@ type Node struct { Controls NodeControls `json:"controls,omitempty"` LatestControls NodeControlDataLatestMap `json:"latestControls,omitempty"` Latest StringLatestMap `json:"latest,omitempty"` - Metrics Metrics `json:"metrics,omitempty"` + Metrics Metrics `json:"metrics,omitempty" deepequal:"nil==empty"` Parents Sets `json:"parents,omitempty"` Children NodeSet `json:"children,omitempty"` } diff --git a/report/topology.go b/report/topology.go index 2b82d90a5..83baa0f94 100644 --- a/report/topology.go +++ b/report/topology.go @@ -13,7 +13,7 @@ type Topology struct { Label string `json:"label,omitempty"` LabelPlural string `json:"label_plural,omitempty"` Nodes Nodes `json:"nodes"` - Controls Controls `json:"controls,omitempty"` + Controls Controls `json:"controls,omitempty" deepequal:"nil==empty"` MetadataTemplates MetadataTemplates `json:"metadata_templates,omitempty"` MetricTemplates MetricTemplates `json:"metric_templates,omitempty"` TableTemplates TableTemplates `json:"table_templates,omitempty"` diff --git a/test/reflect/deepequal.go b/test/reflect/deepequal.go index f465f5c61..05d7d531c 100644 --- a/test/reflect/deepequal.go +++ b/test/reflect/deepequal.go @@ -146,6 +146,11 @@ func structEq(v1, v2 reflect.Value, visited map[visit]bool, depth int) bool { if v1.Type().Field(i).Tag.Get("deepequal") == "skip" { continue } + if v1.Type().Field(i).Tag.Get("deepequal") == "nil==empty" { + if v1.Field(i).IsNil() && v2.Field(i).Len() == 0 || v2.Field(i).IsNil() && v1.Field(i).Len() == 0 { + continue + } + } if !deepValueEqual(v1.Field(i), v2.Field(i), visited, depth+1) { return false }