github.com/olljanat/moby@v1.13.1/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}} {{.CPUPerc}}"}, 76 `container1 20.00% 77 container2 -- 78 `, 79 }, 80 } 81 82 for _, te := range tt { 83 stats := []StatsEntry{ 84 { 85 Container: "container1", 86 CPUPercentage: 20, 87 Memory: 20, 88 MemoryLimit: 20, 89 MemoryPercentage: 20, 90 NetworkRx: 20, 91 NetworkTx: 20, 92 BlockRead: 20, 93 BlockWrite: 20, 94 PidsCurrent: 2, 95 IsInvalid: false, 96 OSType: "linux", 97 }, 98 { 99 Container: "container2", 100 CPUPercentage: 30, 101 Memory: 30, 102 MemoryLimit: 30, 103 MemoryPercentage: 30, 104 NetworkRx: 30, 105 NetworkTx: 30, 106 BlockRead: 30, 107 BlockWrite: 30, 108 PidsCurrent: 3, 109 IsInvalid: true, 110 OSType: "linux", 111 }, 112 } 113 var out bytes.Buffer 114 te.context.Output = &out 115 err := ContainerStatsWrite(te.context, stats) 116 if err != nil { 117 assert.Error(t, err, te.expected) 118 } else { 119 assert.Equal(t, out.String(), te.expected) 120 } 121 } 122 } 123 124 func TestContainerStatsContextWriteWindows(t *testing.T) { 125 tt := []struct { 126 context Context 127 expected string 128 }{ 129 { 130 Context{Format: "table {{.MemUsage}}"}, 131 `PRIV WORKING SET 132 20 B 133 -- / -- 134 `, 135 }, 136 { 137 Context{Format: "{{.Container}} {{.CPUPerc}}"}, 138 `container1 20.00% 139 container2 -- 140 `, 141 }, 142 { 143 Context{Format: "{{.Container}} {{.MemPerc}} {{.PIDs}}"}, 144 `container1 -- -- 145 container2 -- -- 146 `, 147 }, 148 } 149 150 for _, te := range tt { 151 stats := []StatsEntry{ 152 { 153 Container: "container1", 154 CPUPercentage: 20, 155 Memory: 20, 156 MemoryLimit: 20, 157 MemoryPercentage: 20, 158 NetworkRx: 20, 159 NetworkTx: 20, 160 BlockRead: 20, 161 BlockWrite: 20, 162 PidsCurrent: 2, 163 IsInvalid: false, 164 OSType: "windows", 165 }, 166 { 167 Container: "container2", 168 CPUPercentage: 30, 169 Memory: 30, 170 MemoryLimit: 30, 171 MemoryPercentage: 30, 172 NetworkRx: 30, 173 NetworkTx: 30, 174 BlockRead: 30, 175 BlockWrite: 30, 176 PidsCurrent: 3, 177 IsInvalid: true, 178 OSType: "windows", 179 }, 180 } 181 var out bytes.Buffer 182 te.context.Output = &out 183 err := ContainerStatsWrite(te.context, stats) 184 if err != nil { 185 assert.Error(t, err, te.expected) 186 } else { 187 assert.Equal(t, out.String(), te.expected) 188 } 189 } 190 } 191 192 func TestContainerStatsContextWriteWithNoStats(t *testing.T) { 193 var out bytes.Buffer 194 195 contexts := []struct { 196 context Context 197 expected string 198 }{ 199 { 200 Context{ 201 Format: "{{.Container}}", 202 Output: &out, 203 }, 204 "", 205 }, 206 { 207 Context{ 208 Format: "table {{.Container}}", 209 Output: &out, 210 }, 211 "CONTAINER\n", 212 }, 213 { 214 Context{ 215 Format: "table {{.Container}}\t{{.CPUPerc}}", 216 Output: &out, 217 }, 218 "CONTAINER CPU %\n", 219 }, 220 } 221 222 for _, context := range contexts { 223 ContainerStatsWrite(context.context, []StatsEntry{}) 224 assert.Equal(t, context.expected, out.String()) 225 // Clean buffer 226 out.Reset() 227 } 228 }