DockerCLI/cli/command/formatter/stats_test.go

301 lines
6.9 KiB
Go
Raw Normal View History

package formatter
import (
"bytes"
"testing"
"github.com/docker/docker/pkg/stringid"
"github.com/stretchr/testify/assert"
)
func TestContainerStatsContext(t *testing.T) {
containerID := stringid.GenerateRandomID()
var ctx containerStatsContext
tt := []struct {
stats StatsEntry
osType string
expValue string
expHeader string
call func() string
}{
{StatsEntry{Container: 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.31B / 12.3B", netIOHeader, ctx.NetIO},
{StatsEntry{NetworkRx: 0.31, NetworkTx: 12.3, IsInvalid: true}, "", "--", netIOHeader, ctx.NetIO},
{StatsEntry{BlockRead: 0.1, BlockWrite: 2.3}, "", "0.1B / 2.3B", 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}, "windows", "--", memPercHeader, ctx.MemPerc},
{StatsEntry{Memory: 24, MemoryLimit: 30}, "", "24B / 30B", memUseHeader, ctx.MemUsage},
{StatsEntry{Memory: 24, MemoryLimit: 30, IsInvalid: true}, "", "-- / --", memUseHeader, ctx.MemUsage},
{StatsEntry{Memory: 24, MemoryLimit: 30}, "windows", "24B", winMemUseHeader, ctx.MemUsage},
{StatsEntry{PidsCurrent: 10}, "", "10", pidsHeader, ctx.PIDs},
{StatsEntry{PidsCurrent: 10, IsInvalid: true}, "", "--", pidsHeader, ctx.PIDs},
{StatsEntry{PidsCurrent: 10}, "windows", "--", pidsHeader, ctx.PIDs},
}
for _, te := range tt {
ctx = containerStatsContext{s: te.stats, os: te.osType}
if v := te.call(); v != te.expValue {
t.Fatalf("Expected %q, got %q", te.expValue, v)
}
}
}
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>: nil is not a command
`,
},
{
Context{Format: "table {{.MemUsage}}"},
`MEM USAGE / LIMIT
20B / 20B
-- / --
Fix panic of "docker stats --format {{.Name}} --all" This commit fixes panic when execute stats command: * use --format {{.Name}} with --all when there're exited containers. * use --format {{.Name}} while stating exited container. The root cause is when stating an exited container, the result from the api didn't contain the Name and ID field, which will make format process panic. Panic log is like this: ``` panic: runtime error: slice bounds out of range [recovered] panic: runtime error: slice bounds out of range goroutine 1 [running]: panic(0xb20f80, 0xc420014110) /usr/local/go/src/runtime/panic.go:500 +0x1a1 text/template.errRecover(0xc4201773e8) /usr/local/go/src/text/template/exec.go:140 +0x2ad panic(0xb20f80, 0xc420014110) /usr/local/go/src/runtime/panic.go:458 +0x243 github.com/docker/docker/cli/command/formatter.(*containerStatsContext).Name(0xc420430160, 0x0, 0x0) /go/src/github.com/docker/docker/cli/command/formatter/stats.go:148 +0x86 reflect.Value.call(0xb9a3a0, 0xc420430160, 0x2213, 0xbe3657, 0x4, 0x11bc9f8, 0x0, 0x0, 0x4d75b3, 0x1198940, ...) /usr/local/go/src/reflect/value.go:434 +0x5c8 reflect.Value.Call(0xb9a3a0, 0xc420430160, 0x2213, 0x11bc9f8, 0x0, 0x0, 0xc420424028, 0xb, 0xb) /usr/local/go/src/reflect/value.go:302 +0xa4 text/template.(*state).evalCall(0xc420177368, 0xb9a3a0, 0xc420430160, 0x16, 0xb9a3a0, 0xc420430160, 0x2213, 0x1178fa0, 0xc4203ea330, 0xc4203de283, ...) /usr/local/go/src/text/template/exec.go:658 +0x530 ``` Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
2017-02-06 21:27:40 -05:00
`,
},
{
Context{Format: "{{.Container}} {{.ID}} {{.Name}}"},
`container1 abcdef foo
container2 --
`,
},
{
Context{Format: "{{.Container}} {{.CPUPerc}}"},
`container1 20.00%
container2 --
`,
},
}
for _, te := range tt {
stats := []StatsEntry{
{
Container: "container1",
Fix panic of "docker stats --format {{.Name}} --all" This commit fixes panic when execute stats command: * use --format {{.Name}} with --all when there're exited containers. * use --format {{.Name}} while stating exited container. The root cause is when stating an exited container, the result from the api didn't contain the Name and ID field, which will make format process panic. Panic log is like this: ``` panic: runtime error: slice bounds out of range [recovered] panic: runtime error: slice bounds out of range goroutine 1 [running]: panic(0xb20f80, 0xc420014110) /usr/local/go/src/runtime/panic.go:500 +0x1a1 text/template.errRecover(0xc4201773e8) /usr/local/go/src/text/template/exec.go:140 +0x2ad panic(0xb20f80, 0xc420014110) /usr/local/go/src/runtime/panic.go:458 +0x243 github.com/docker/docker/cli/command/formatter.(*containerStatsContext).Name(0xc420430160, 0x0, 0x0) /go/src/github.com/docker/docker/cli/command/formatter/stats.go:148 +0x86 reflect.Value.call(0xb9a3a0, 0xc420430160, 0x2213, 0xbe3657, 0x4, 0x11bc9f8, 0x0, 0x0, 0x4d75b3, 0x1198940, ...) /usr/local/go/src/reflect/value.go:434 +0x5c8 reflect.Value.Call(0xb9a3a0, 0xc420430160, 0x2213, 0x11bc9f8, 0x0, 0x0, 0xc420424028, 0xb, 0xb) /usr/local/go/src/reflect/value.go:302 +0xa4 text/template.(*state).evalCall(0xc420177368, 0xb9a3a0, 0xc420430160, 0x16, 0xb9a3a0, 0xc420430160, 0x2213, 0x1178fa0, 0xc4203ea330, 0xc4203de283, ...) /usr/local/go/src/text/template/exec.go:658 +0x530 ``` Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
2017-02-06 21:27:40 -05:00
ID: "abcdef",
Name: "/foo",
CPUPercentage: 20,
Memory: 20,
MemoryLimit: 20,
MemoryPercentage: 20,
NetworkRx: 20,
NetworkTx: 20,
BlockRead: 20,
BlockWrite: 20,
PidsCurrent: 2,
IsInvalid: false,
},
{
Container: "container2",
CPUPercentage: 30,
Memory: 30,
MemoryLimit: 30,
MemoryPercentage: 30,
NetworkRx: 30,
NetworkTx: 30,
BlockRead: 30,
BlockWrite: 30,
PidsCurrent: 3,
IsInvalid: true,
},
}
var out bytes.Buffer
te.context.Output = &out
Add --no-trunc option to docker container stats This patch adds a `--no-trunc` option to `docker container stats`; With this patch applied, the default output is: CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b95a83497c91 awesome_brattain 0.28% 5.629MiB / 1.952GiB 0.28% 916B / 0B 147kB / 0B 9 67b2525d8ad1 foobar 0.00% 1.727MiB / 1.952GiB 0.09% 2.48kB / 0B 4.11MB / 0B 2 e5c383697914 test-1951.1.kay7x1lh1twk9c0oig50sd5tr 0.00% 196KiB / 1.952GiB 0.01% 71.2kB / 0B 770kB / 0B 1 4bda148efbc0 random.1.vnc8on831idyr42slu578u3cr 0.00% 1.672MiB / 1.952GiB 0.08% 110kB / 0B 578kB / 0B 2 84e3deaa45b2 registry 0.01% 3.402MiB / 1.952GiB 0.17% 127kB / 378B 233kB / 0B 10 2ed915778ceb foo.1.lsmxrefn5yp9c9ijz1hzgdq4u 0.00% 1.727MiB / 1.952GiB 0.09% 166kB / 7.76kB 614kB / 0B 2 Addin the `--no-trunc` option, changes the output to: CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc awesome_brattain 0.25% 5.75MiB / 1.952GiB 0.29% 648B / 0B 147kB / 0B 10 67b2525d8ad10bb236a49960e93c09993b0baabeef12c2d46cd5f4fbb6f4808c foobar 0.00% 1.727MiB / 1.952GiB 0.09% 2.35kB / 0B 4.11MB / 0B 2 e5c383697914b98b10cbbc9d0bd324b7b927099ac584f031057b8208d2fba9b1 test-1951.1.kay7x1lh1twk9c0oig50sd5tr 0.00% 196KiB / 1.952GiB 0.01% 71.1kB / 0B 770kB / 0B 1 4bda148efbc006b0063373c3678083159af89f8cc83a6a28def14cb0dd171f70 random.1.vnc8on831idyr42slu578u3cr 0.00% 1.672MiB / 1.952GiB 0.08% 110kB / 0B 578kB / 0B 2 84e3deaa45b2fc363e06167df9b90ab59f88d4f101e3f9b8df03a62a8f6783e1 registry 0.00% 3.387MiB / 1.952GiB 0.17% 127kB / 378B 233kB / 0B 10 2ed915778cebddf9ec69263a75cfdcf00962a5198d94d42cda75d5cd45bb82f2 foo.1.lsmxrefn5yp9c9ijz1hzgdq4u 0.00% 1.727MiB / 1.952GiB 0.09% 166kB / 7.76kB 614kB / 0B 2 Which is the same as the default before this patch was applied. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-09-27 12:24:26 -04:00
err := ContainerStatsWrite(te.context, stats, "linux", false)
if err != nil {
assert.EqualError(t, err, te.expected)
} else {
assert.Equal(t, te.expected, out.String())
}
}
}
func TestContainerStatsContextWriteWindows(t *testing.T) {
tt := []struct {
context Context
expected string
}{
{
Context{Format: "table {{.MemUsage}}"},
`PRIV WORKING SET
20B
-- / --
`,
},
{
Context{Format: "{{.Container}} {{.CPUPerc}}"},
`container1 20.00%
container2 --
`,
},
{
Context{Format: "{{.Container}} {{.MemPerc}} {{.PIDs}}"},
`container1 -- --
container2 -- --
`,
},
}
for _, te := range tt {
stats := []StatsEntry{
{
Container: "container1",
CPUPercentage: 20,
Memory: 20,
MemoryLimit: 20,
MemoryPercentage: 20,
NetworkRx: 20,
NetworkTx: 20,
BlockRead: 20,
BlockWrite: 20,
PidsCurrent: 2,
IsInvalid: false,
},
{
Container: "container2",
CPUPercentage: 30,
Memory: 30,
MemoryLimit: 30,
MemoryPercentage: 30,
NetworkRx: 30,
NetworkTx: 30,
BlockRead: 30,
BlockWrite: 30,
PidsCurrent: 3,
IsInvalid: true,
},
}
var out bytes.Buffer
te.context.Output = &out
Add --no-trunc option to docker container stats This patch adds a `--no-trunc` option to `docker container stats`; With this patch applied, the default output is: CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b95a83497c91 awesome_brattain 0.28% 5.629MiB / 1.952GiB 0.28% 916B / 0B 147kB / 0B 9 67b2525d8ad1 foobar 0.00% 1.727MiB / 1.952GiB 0.09% 2.48kB / 0B 4.11MB / 0B 2 e5c383697914 test-1951.1.kay7x1lh1twk9c0oig50sd5tr 0.00% 196KiB / 1.952GiB 0.01% 71.2kB / 0B 770kB / 0B 1 4bda148efbc0 random.1.vnc8on831idyr42slu578u3cr 0.00% 1.672MiB / 1.952GiB 0.08% 110kB / 0B 578kB / 0B 2 84e3deaa45b2 registry 0.01% 3.402MiB / 1.952GiB 0.17% 127kB / 378B 233kB / 0B 10 2ed915778ceb foo.1.lsmxrefn5yp9c9ijz1hzgdq4u 0.00% 1.727MiB / 1.952GiB 0.09% 166kB / 7.76kB 614kB / 0B 2 Addin the `--no-trunc` option, changes the output to: CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc awesome_brattain 0.25% 5.75MiB / 1.952GiB 0.29% 648B / 0B 147kB / 0B 10 67b2525d8ad10bb236a49960e93c09993b0baabeef12c2d46cd5f4fbb6f4808c foobar 0.00% 1.727MiB / 1.952GiB 0.09% 2.35kB / 0B 4.11MB / 0B 2 e5c383697914b98b10cbbc9d0bd324b7b927099ac584f031057b8208d2fba9b1 test-1951.1.kay7x1lh1twk9c0oig50sd5tr 0.00% 196KiB / 1.952GiB 0.01% 71.1kB / 0B 770kB / 0B 1 4bda148efbc006b0063373c3678083159af89f8cc83a6a28def14cb0dd171f70 random.1.vnc8on831idyr42slu578u3cr 0.00% 1.672MiB / 1.952GiB 0.08% 110kB / 0B 578kB / 0B 2 84e3deaa45b2fc363e06167df9b90ab59f88d4f101e3f9b8df03a62a8f6783e1 registry 0.00% 3.387MiB / 1.952GiB 0.17% 127kB / 378B 233kB / 0B 10 2ed915778cebddf9ec69263a75cfdcf00962a5198d94d42cda75d5cd45bb82f2 foo.1.lsmxrefn5yp9c9ijz1hzgdq4u 0.00% 1.727MiB / 1.952GiB 0.09% 166kB / 7.76kB 614kB / 0B 2 Which is the same as the default before this patch was applied. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-09-27 12:24:26 -04:00
err := ContainerStatsWrite(te.context, stats, "windows", false)
if err != nil {
assert.EqualError(t, err, te.expected)
} else {
assert.Equal(t, te.expected, out.String())
}
}
}
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 {
Add --no-trunc option to docker container stats This patch adds a `--no-trunc` option to `docker container stats`; With this patch applied, the default output is: CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b95a83497c91 awesome_brattain 0.28% 5.629MiB / 1.952GiB 0.28% 916B / 0B 147kB / 0B 9 67b2525d8ad1 foobar 0.00% 1.727MiB / 1.952GiB 0.09% 2.48kB / 0B 4.11MB / 0B 2 e5c383697914 test-1951.1.kay7x1lh1twk9c0oig50sd5tr 0.00% 196KiB / 1.952GiB 0.01% 71.2kB / 0B 770kB / 0B 1 4bda148efbc0 random.1.vnc8on831idyr42slu578u3cr 0.00% 1.672MiB / 1.952GiB 0.08% 110kB / 0B 578kB / 0B 2 84e3deaa45b2 registry 0.01% 3.402MiB / 1.952GiB 0.17% 127kB / 378B 233kB / 0B 10 2ed915778ceb foo.1.lsmxrefn5yp9c9ijz1hzgdq4u 0.00% 1.727MiB / 1.952GiB 0.09% 166kB / 7.76kB 614kB / 0B 2 Addin the `--no-trunc` option, changes the output to: CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc awesome_brattain 0.25% 5.75MiB / 1.952GiB 0.29% 648B / 0B 147kB / 0B 10 67b2525d8ad10bb236a49960e93c09993b0baabeef12c2d46cd5f4fbb6f4808c foobar 0.00% 1.727MiB / 1.952GiB 0.09% 2.35kB / 0B 4.11MB / 0B 2 e5c383697914b98b10cbbc9d0bd324b7b927099ac584f031057b8208d2fba9b1 test-1951.1.kay7x1lh1twk9c0oig50sd5tr 0.00% 196KiB / 1.952GiB 0.01% 71.1kB / 0B 770kB / 0B 1 4bda148efbc006b0063373c3678083159af89f8cc83a6a28def14cb0dd171f70 random.1.vnc8on831idyr42slu578u3cr 0.00% 1.672MiB / 1.952GiB 0.08% 110kB / 0B 578kB / 0B 2 84e3deaa45b2fc363e06167df9b90ab59f88d4f101e3f9b8df03a62a8f6783e1 registry 0.00% 3.387MiB / 1.952GiB 0.17% 127kB / 378B 233kB / 0B 10 2ed915778cebddf9ec69263a75cfdcf00962a5198d94d42cda75d5cd45bb82f2 foo.1.lsmxrefn5yp9c9ijz1hzgdq4u 0.00% 1.727MiB / 1.952GiB 0.09% 166kB / 7.76kB 614kB / 0B 2 Which is the same as the default before this patch was applied. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-09-27 12:24:26 -04:00
ContainerStatsWrite(context.context, []StatsEntry{}, "linux", false)
assert.Equal(t, context.expected, out.String())
// Clean buffer
out.Reset()
}
}
func TestContainerStatsContextWriteWithNoStatsWindows(t *testing.T) {
var out bytes.Buffer
contexts := []struct {
context Context
expected string
}{
{
Context{
Format: "{{.Container}}",
Output: &out,
},
"",
},
{
Context{
Format: "table {{.Container}}\t{{.MemUsage}}",
Output: &out,
},
"CONTAINER PRIV WORKING SET\n",
},
{
Context{
Format: "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}",
Output: &out,
},
"CONTAINER CPU % PRIV WORKING SET\n",
},
}
for _, context := range contexts {
Add --no-trunc option to docker container stats This patch adds a `--no-trunc` option to `docker container stats`; With this patch applied, the default output is: CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b95a83497c91 awesome_brattain 0.28% 5.629MiB / 1.952GiB 0.28% 916B / 0B 147kB / 0B 9 67b2525d8ad1 foobar 0.00% 1.727MiB / 1.952GiB 0.09% 2.48kB / 0B 4.11MB / 0B 2 e5c383697914 test-1951.1.kay7x1lh1twk9c0oig50sd5tr 0.00% 196KiB / 1.952GiB 0.01% 71.2kB / 0B 770kB / 0B 1 4bda148efbc0 random.1.vnc8on831idyr42slu578u3cr 0.00% 1.672MiB / 1.952GiB 0.08% 110kB / 0B 578kB / 0B 2 84e3deaa45b2 registry 0.01% 3.402MiB / 1.952GiB 0.17% 127kB / 378B 233kB / 0B 10 2ed915778ceb foo.1.lsmxrefn5yp9c9ijz1hzgdq4u 0.00% 1.727MiB / 1.952GiB 0.09% 166kB / 7.76kB 614kB / 0B 2 Addin the `--no-trunc` option, changes the output to: CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc awesome_brattain 0.25% 5.75MiB / 1.952GiB 0.29% 648B / 0B 147kB / 0B 10 67b2525d8ad10bb236a49960e93c09993b0baabeef12c2d46cd5f4fbb6f4808c foobar 0.00% 1.727MiB / 1.952GiB 0.09% 2.35kB / 0B 4.11MB / 0B 2 e5c383697914b98b10cbbc9d0bd324b7b927099ac584f031057b8208d2fba9b1 test-1951.1.kay7x1lh1twk9c0oig50sd5tr 0.00% 196KiB / 1.952GiB 0.01% 71.1kB / 0B 770kB / 0B 1 4bda148efbc006b0063373c3678083159af89f8cc83a6a28def14cb0dd171f70 random.1.vnc8on831idyr42slu578u3cr 0.00% 1.672MiB / 1.952GiB 0.08% 110kB / 0B 578kB / 0B 2 84e3deaa45b2fc363e06167df9b90ab59f88d4f101e3f9b8df03a62a8f6783e1 registry 0.00% 3.387MiB / 1.952GiB 0.17% 127kB / 378B 233kB / 0B 10 2ed915778cebddf9ec69263a75cfdcf00962a5198d94d42cda75d5cd45bb82f2 foo.1.lsmxrefn5yp9c9ijz1hzgdq4u 0.00% 1.727MiB / 1.952GiB 0.09% 166kB / 7.76kB 614kB / 0B 2 Which is the same as the default before this patch was applied. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-09-27 12:24:26 -04:00
ContainerStatsWrite(context.context, []StatsEntry{}, "windows", false)
assert.Equal(t, context.expected, out.String())
// Clean buffer
out.Reset()
}
}
func TestContainerStatsContextWriteTrunc(t *testing.T) {
var out bytes.Buffer
contexts := []struct {
context Context
trunc bool
expected string
}{
{
Context{
Format: "{{.ID}}",
Output: &out,
},
false,
"b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc\n",
},
{
Context{
Format: "{{.ID}}",
Output: &out,
},
true,
"b95a83497c91\n",
},
}
for _, context := range contexts {
ContainerStatsWrite(context.context, []StatsEntry{{ID: "b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc"}}, "linux", context.trunc)
assert.Equal(t, context.expected, out.String())
// Clean buffer
out.Reset()
}
}