From 115b132e5f12538676258c96ed335b062ac26985 Mon Sep 17 00:00:00 2001 From: Nan Deng Date: Tue, 8 Jul 2014 13:55:09 -0700 Subject: [PATCH] stats time precesion affects the test results --- client/client_test.go | 42 ++++++++++++++++++++++++----- info/container.go | 62 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 7 deletions(-) diff --git a/client/client_test.go b/client/client_test.go index 0e3d7cc7..62c0f8e4 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -37,7 +37,7 @@ func testGetJsonData( return fmt.Errorf("unable to retrieve data: %v", err) } if !reflect.DeepEqual(reply, expected) { - return fmt.Errorf("retrieved wrong data: %v != %v", pretty.Sprintf("%# v", reply), pretty.Sprintf("% #v", expected)) + return pretty.Errorf("retrieved wrong data: %# v != %# v", reply, expected) } return nil } @@ -82,12 +82,13 @@ func TestGetMachineinfo(t *testing.T) { t.Fatalf("unable to get a client %v", err) } defer server.Close() - err = testGetJsonData(minfo, func() (interface{}, error) { - return client.MachineInfo() - }) + returned, err := client.MachineInfo() if err != nil { t.Fatal(err) } + if !reflect.DeepEqual(returned, minfo) { + t.Fatalf("received unexpected machine info") + } } func TestGetContainerInfo(t *testing.T) { @@ -104,10 +105,37 @@ func TestGetContainerInfo(t *testing.T) { t.Fatalf("unable to get a client %v", err) } defer server.Close() - err = testGetJsonData(cinfo, func() (interface{}, error) { - return client.ContainerInfo(containerName, query) - }) + returned, err := client.ContainerInfo(containerName, query) if err != nil { t.Fatal(err) } + + // We cannot use DeepEqual() to compare them directly, + // because json en/decoded time may have preceision issues. + if !reflect.DeepEqual(returned.ContainerReference, cinfo.ContainerReference) { + t.Errorf("received unexpected container ref") + } + if !reflect.DeepEqual(returned.Subcontainers, cinfo.Subcontainers) { + t.Errorf("received unexpected subcontainers") + } + if !reflect.DeepEqual(returned.Spec, cinfo.Spec) { + t.Errorf("received unexpected spec") + } + if !reflect.DeepEqual(returned.StatsPercentiles, cinfo.StatsPercentiles) { + t.Errorf("received unexpected spec") + } + + for i, expectedStats := range cinfo.Stats { + returnedStats := returned.Stats[i] + if !expectedStats.Eq(returnedStats) { + t.Errorf("received unexpected stats") + } + } + + for i, expectedSample := range cinfo.Samples { + returnedSample := returned.Samples[i] + if !expectedSample.Eq(returnedSample) { + t.Errorf("received unexpected sample") + } + } } diff --git a/info/container.go b/info/container.go index 702fe316..55410a79 100644 --- a/info/container.go +++ b/info/container.go @@ -16,6 +16,7 @@ package info import ( "fmt" + "reflect" "sort" "time" ) @@ -247,6 +248,67 @@ type ContainerStatsSample struct { } `json:"memory"` } +func timeEq(t1, t2 time.Time, tolerance time.Duration) bool { + // t1 should not be later than t2 + if t1.After(t2) { + t1, t2 = t2, t1 + } + diff := t2.Sub(t1) + if diff <= tolerance { + return true + } + return false +} + +func durationEq(a, b time.Duration, tolerance time.Duration) bool { + if a > b { + a, b = b, a + } + diff := a - b + if diff <= tolerance { + return true + } + return false +} + +const ( + // 10ms, i.e. 0.01s + timePrecision time.Duration = 10 * time.Millisecond +) + +// This function is useful because we do not require precise time +// representation. +func (a *ContainerStats) Eq(b *ContainerStats) bool { + if !timeEq(a.Timestamp, b.Timestamp, timePrecision) { + return false + } + if !reflect.DeepEqual(a.Cpu, b.Cpu) { + return false + } + if !reflect.DeepEqual(a.Memory, b.Memory) { + return false + } + return true +} + +// This function is useful because we do not require precise time +// representation. +func (a *ContainerStatsSample) Eq(b *ContainerStatsSample) bool { + if !timeEq(a.Timestamp, b.Timestamp, timePrecision) { + return false + } + if !durationEq(a.Duration, b.Duration, timePrecision) { + return false + } + if !reflect.DeepEqual(a.Cpu, b.Cpu) { + return false + } + if !reflect.DeepEqual(a.Memory, b.Memory) { + return false + } + return true +} + type Percentile struct { Percentage int `json:"percentage"` Value uint64 `json:"value"`