github.com/openshift/moby-moby@v1.13.2-0.20170601211448-f5ec1e2936dc/cli/command/formatter/stats_test.go (about) 1 package formatter 2 3 import ( 4 "bytes" 5 "testing" 6 7 "github.com/docker/docker/pkg/stringid" 8 "github.com/docker/docker/pkg/testutil/assert" 9 ) 10 11 func TestContainerStatsContext(t *testing.T) { 12 containerID := stringid.GenerateRandomID() 13 14 var ctx containerStatsContext 15 tt := []struct { 16 stats StatsEntry 17 expValue string 18 expHeader string 19 call func() string 20 }{ 21 {StatsEntry{Container: containerID}, containerID, containerHeader, ctx.Container}, 22 {StatsEntry{CPUPercentage: 5.5}, "5.50%", cpuPercHeader, ctx.CPUPerc}, 23 {StatsEntry{CPUPercentage: 5.5, IsInvalid: true}, "--", cpuPercHeader, ctx.CPUPerc}, 24 {StatsEntry{NetworkRx: 0.31, NetworkTx: 12.3}, "0.31 B / 12.3 B", netIOHeader, ctx.NetIO}, 25 {StatsEntry{NetworkRx: 0.31, NetworkTx: 12.3, IsInvalid: true}, "--", netIOHeader, ctx.NetIO}, 26 {StatsEntry{BlockRead: 0.1, BlockWrite: 2.3}, "0.1 B / 2.3 B", blockIOHeader, ctx.BlockIO}, 27 {StatsEntry{BlockRead: 0.1, BlockWrite: 2.3, IsInvalid: true}, "--", blockIOHeader, ctx.BlockIO}, 28 {StatsEntry{MemoryPercentage: 10.2}, "10.20%", memPercHeader, ctx.MemPerc}, 29 {StatsEntry{MemoryPercentage: 10.2, IsInvalid: true}, "--", memPercHeader, ctx.MemPerc}, 30 {StatsEntry{MemoryPercentage: 10.2, OSType: "windows"}, "--", memPercHeader, ctx.MemPerc}, 31 {StatsEntry{Memory: 24, MemoryLimit: 30}, "24 B / 30 B", memUseHeader, ctx.MemUsage}, 32 {StatsEntry{Memory: 24, MemoryLimit: 30, IsInvalid: true}, "-- / --", memUseHeader, ctx.MemUsage}, 33 {StatsEntry{Memory: 24, MemoryLimit: 30, OSType: "windows"}, "24 B", winMemUseHeader, ctx.MemUsage}, 34 {StatsEntry{PidsCurrent: 10}, "10", pidsHeader, ctx.PIDs}, 35 {StatsEntry{PidsCurrent: 10, IsInvalid: true}, "--", pidsHeader, ctx.PIDs}, 36 {StatsEntry{PidsCurrent: 10, OSType: "windows"}, "--", pidsHeader, ctx.PIDs}, 37 } 38 39 for _, te := range tt { 40 ctx = containerStatsContext{s: te.stats} 41 if v := te.call(); v != te.expValue { 42 t.Fatalf("Expected %q, got %q", te.expValue, v) 43 } 44 45 h := ctx.FullHeader() 46 if h != te.expHeader { 47 t.Fatalf("Expected %q, got %q", te.expHeader, h) 48 } 49 } 50 } 51 52 func TestContainerStatsContextWrite(t *testing.T) { 53 tt := []struct { 54 context Context 55 expected string 56 }{ 57 { 58 Context{Format: "{{InvalidFunction}}"}, 59 `Template parsing error: template: :1: function "InvalidFunction" not defined 60 `, 61 }, 62 { 63 Context{Format: "{{nil}}"}, 64 `Template parsing error: template: :1:2: executing "" at <nil>: nil is not a command 65 `, 66 }, 67 { 68 Context{Format: "table {{.MemUsage}}"}, 69 `MEM USAGE / LIMIT 70 20 B / 20 B 71 -- / -- 72 `, 73 }, 74 { 75 Context{Format: "{{.Container}} {{.ID}} {{.Name}}"}, 76 `container1 abcdef foo 77 container2 -- 78 `, 79 }, 80 { 81 Context{Format: "{{.Container}} {{.CPUPerc}}"}, 82 `container1 20.00% 83 container2 -- 84 `, 85 }, 86 } 87 88 for _, te := range tt { 89 stats := []StatsEntry{ 90 { 91 Container: "container1", 92 ID: "abcdef", 93 Name: "/foo", 94 CPUPercentage: 20, 95 Memory: 20, 96 MemoryLimit: 20, 97 MemoryPercentage: 20, 98 NetworkRx: 20, 99 NetworkTx: 20, 100 BlockRead: 20, 101 BlockWrite: 20, 102 PidsCurrent: 2, 103 IsInvalid: false, 104 OSType: "linux", 105 }, 106 { 107 Container: "container2", 108 CPUPercentage: 30, 109 Memory: 30, 110 MemoryLimit: 30, 111 MemoryPercentage: 30, 112 NetworkRx: 30, 113 NetworkTx: 30, 114 BlockRead: 30, 115 BlockWrite: 30, 116 PidsCurrent: 3, 117 IsInvalid: true, 118 OSType: "linux", 119 }, 120 } 121 var out bytes.Buffer 122 te.context.Output = &out 123 err := ContainerStatsWrite(te.context, stats) 124 if err != nil { 125 assert.Error(t, err, te.expected) 126 } else { 127 assert.Equal(t, out.String(), te.expected) 128 } 129 } 130 } 131 132 func TestContainerStatsContextWriteWindows(t *testing.T) { 133 tt := []struct { 134 context Context 135 expected string 136 }{ 137 { 138 Context{Format: "table {{.MemUsage}}"}, 139 `PRIV WORKING SET 140 20 B 141 -- / -- 142 `, 143 }, 144 { 145 Context{Format: "{{.Container}} {{.CPUPerc}}"}, 146 `container1 20.00% 147 container2 -- 148 `, 149 }, 150 { 151 Context{Format: "{{.Container}} {{.MemPerc}} {{.PIDs}}"}, 152 `container1 -- -- 153 container2 -- -- 154 `, 155 }, 156 } 157 158 for _, te := range tt { 159 stats := []StatsEntry{ 160 { 161 Container: "container1", 162 CPUPercentage: 20, 163 Memory: 20, 164 MemoryLimit: 20, 165 MemoryPercentage: 20, 166 NetworkRx: 20, 167 NetworkTx: 20, 168 BlockRead: 20, 169 BlockWrite: 20, 170 PidsCurrent: 2, 171 IsInvalid: false, 172 OSType: "windows", 173 }, 174 { 175 Container: "container2", 176 CPUPercentage: 30, 177 Memory: 30, 178 MemoryLimit: 30, 179 MemoryPercentage: 30, 180 NetworkRx: 30, 181 NetworkTx: 30, 182 BlockRead: 30, 183 BlockWrite: 30, 184 PidsCurrent: 3, 185 IsInvalid: true, 186 OSType: "windows", 187 }, 188 } 189 var out bytes.Buffer 190 te.context.Output = &out 191 err := ContainerStatsWrite(te.context, stats) 192 if err != nil { 193 assert.Error(t, err, te.expected) 194 } else { 195 assert.Equal(t, out.String(), te.expected) 196 } 197 } 198 } 199 200 func TestContainerStatsContextWriteWithNoStats(t *testing.T) { 201 var out bytes.Buffer 202 203 contexts := []struct { 204 context Context 205 expected string 206 }{ 207 { 208 Context{ 209 Format: "{{.Container}}", 210 Output: &out, 211 }, 212 "", 213 }, 214 { 215 Context{ 216 Format: "table {{.Container}}", 217 Output: &out, 218 }, 219 "CONTAINER\n", 220 }, 221 { 222 Context{ 223 Format: "table {{.Container}}\t{{.CPUPerc}}", 224 Output: &out, 225 }, 226 "CONTAINER CPU %\n", 227 }, 228 } 229 230 for _, context := range contexts { 231 ContainerStatsWrite(context.context, []StatsEntry{}) 232 assert.Equal(t, context.expected, out.String()) 233 // Clean buffer 234 out.Reset() 235 } 236 }