package formatter import ( "bytes" "testing" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/testutil/assert" ) func TestContainerStatsContext(t *testing.T) { containerID := stringid.GenerateRandomID() var ctx containerStatsContext tt := []struct { stats StatsEntry expValue string expHeader string call func() string }{ {StatsEntry{Name: containerID}, containerID, containerHeader, ctx.Container}, {StatsEntry{CPUPercentage: 5.5}, "5.50%", cpuPercHeader, ctx.CPUPerc}, {StatsEntry{CPUPercentage: 5.5, IsInvalid: true}, "--", cpuPercHeader, ctx.CPUPerc}, {StatsEntry{NetworkRx: 0.31, NetworkTx: 12.3}, "0.31 B / 12.3 B", netIOHeader, ctx.NetIO}, {StatsEntry{NetworkRx: 0.31, NetworkTx: 12.3, IsInvalid: true}, "--", netIOHeader, ctx.NetIO}, {StatsEntry{BlockRead: 0.1, BlockWrite: 2.3}, "0.1 B / 2.3 B", blockIOHeader, ctx.BlockIO}, {StatsEntry{BlockRead: 0.1, BlockWrite: 2.3, IsInvalid: true}, "--", blockIOHeader, ctx.BlockIO}, {StatsEntry{MemoryPercentage: 10.2}, "10.20%", memPercHeader, ctx.MemPerc}, {StatsEntry{MemoryPercentage: 10.2, IsInvalid: true}, "--", memPercHeader, ctx.MemPerc}, {StatsEntry{MemoryPercentage: 10.2, OSType: "windows"}, "--", memPercHeader, ctx.MemPerc}, {StatsEntry{Memory: 24, MemoryLimit: 30}, "24 B / 30 B", memUseHeader, ctx.MemUsage}, {StatsEntry{Memory: 24, MemoryLimit: 30, IsInvalid: true}, "-- / --", memUseHeader, ctx.MemUsage}, {StatsEntry{Memory: 24, MemoryLimit: 30, OSType: "windows"}, "24 B", winMemUseHeader, ctx.MemUsage}, {StatsEntry{PidsCurrent: 10}, "10", pidsHeader, ctx.PIDs}, {StatsEntry{PidsCurrent: 10, IsInvalid: true}, "--", pidsHeader, ctx.PIDs}, {StatsEntry{PidsCurrent: 10, OSType: "windows"}, "--", pidsHeader, ctx.PIDs}, } for _, te := range tt { ctx = containerStatsContext{s: te.stats} if v := te.call(); v != te.expValue { t.Fatalf("Expected %q, got %q", te.expValue, v) } h := ctx.FullHeader() if h != te.expHeader { t.Fatalf("Expected %q, got %q", te.expHeader, h) } } } func TestContainerStatsContextWrite(t *testing.T) { tt := []struct { context Context expected string }{ { Context{Format: "{{InvalidFunction}}"}, `Template parsing error: template: :1: function "InvalidFunction" not defined `, }, { Context{Format: "{{nil}}"}, `Template parsing error: template: :1:2: executing "" at : nil is not a command `, }, { Context{Format: "table {{.MemUsage}}"}, `MEM USAGE / LIMIT 20 B / 20 B -- / -- `, }, { Context{Format: "{{.Container}} {{.CPUPerc}}"}, `container1 20.00% container2 -- `, }, } for _, te := range tt { stats := []StatsEntry{ { Name: "container1", CPUPercentage: 20, Memory: 20, MemoryLimit: 20, MemoryPercentage: 20, NetworkRx: 20, NetworkTx: 20, BlockRead: 20, BlockWrite: 20, PidsCurrent: 2, IsInvalid: false, OSType: "linux", }, { Name: "container2", CPUPercentage: 30, Memory: 30, MemoryLimit: 30, MemoryPercentage: 30, NetworkRx: 30, NetworkTx: 30, BlockRead: 30, BlockWrite: 30, PidsCurrent: 3, IsInvalid: true, OSType: "linux", }, } var out bytes.Buffer te.context.Output = &out err := ContainerStatsWrite(te.context, stats) if err != nil { assert.Error(t, err, te.expected) } else { assert.Equal(t, out.String(), te.expected) } } } func TestContainerStatsContextWriteWindows(t *testing.T) { tt := []struct { context Context expected string }{ { Context{Format: "table {{.MemUsage}}"}, `PRIV WORKING SET 20 B -- / -- `, }, { Context{Format: "{{.Container}} {{.CPUPerc}}"}, `container1 20.00% container2 -- `, }, { Context{Format: "{{.Container}} {{.MemPerc}} {{.PIDs}}"}, `container1 -- -- container2 -- -- `, }, } for _, te := range tt { stats := []StatsEntry{ { Name: "container1", CPUPercentage: 20, Memory: 20, MemoryLimit: 20, MemoryPercentage: 20, NetworkRx: 20, NetworkTx: 20, BlockRead: 20, BlockWrite: 20, PidsCurrent: 2, IsInvalid: false, OSType: "windows", }, { Name: "container2", CPUPercentage: 30, Memory: 30, MemoryLimit: 30, MemoryPercentage: 30, NetworkRx: 30, NetworkTx: 30, BlockRead: 30, BlockWrite: 30, PidsCurrent: 3, IsInvalid: true, OSType: "windows", }, } var out bytes.Buffer te.context.Output = &out err := ContainerStatsWrite(te.context, stats) if err != nil { assert.Error(t, err, te.expected) } else { assert.Equal(t, out.String(), te.expected) } } } func TestContainerStatsContextWriteWithNoStats(t *testing.T) { var out bytes.Buffer contexts := []struct { context Context expected string }{ { Context{ Format: "{{.Container}}", Output: &out, }, "", }, { Context{ Format: "table {{.Container}}", Output: &out, }, "CONTAINER\n", }, { Context{ Format: "table {{.Container}}\t{{.CPUPerc}}", Output: &out, }, "CONTAINER CPU %\n", }, } for _, context := range contexts { ContainerStatsWrite(context.context, []StatsEntry{}) assert.Equal(t, context.expected, out.String()) // Clean buffer out.Reset() } }