mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 08:31:03 +00:00
224 lines
6.5 KiB
Go
224 lines
6.5 KiB
Go
package presentation
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestConvertBigMetricFromSchema(t *testing.T) {
|
|
type scenario struct {
|
|
name string
|
|
data map[string]interface{}
|
|
expected map[string]interface{}
|
|
expectedErr string
|
|
}
|
|
|
|
inJSONBytes, err := os.ReadFile("testdata/stats.json")
|
|
if err != nil {
|
|
t.Fatalf("failed to read testdata/stats.json: %v", err)
|
|
}
|
|
loadInJSON := func() map[string]interface{} {
|
|
var m map[string]interface{}
|
|
if err := json.Unmarshal(inJSONBytes, &m); err != nil {
|
|
t.Fatalf("failed to unmarshal testdata/stats.json: %v", err)
|
|
}
|
|
return m
|
|
}
|
|
setNested := func(m map[string]interface{}, keys []string, val interface{}) {
|
|
for _, k := range keys[:len(keys)-1] {
|
|
m = m[k].(map[string]interface{})
|
|
}
|
|
m[keys[len(keys)-1]] = val
|
|
}
|
|
|
|
inJSONExpected := loadInJSON()
|
|
setNested(inJSONExpected, []string{"ClientStats", "memory_stats", "limit"}, "1.911GB")
|
|
setNested(inJSONExpected, []string{"ClientStats", "memory_stats", "stats", "hierarchical_memory_limit"}, "0")
|
|
setNested(inJSONExpected, []string{"ClientStats", "memory_stats", "stats", "hierarchical_memsw_limit"}, "0")
|
|
setNested(inJSONExpected, []string{"ClientStats", "cpu_stats", "cpu_usage", "total_usage"}, "30.283ms")
|
|
setNested(inJSONExpected, []string{"ClientStats", "cpu_stats", "cpu_usage", "usage_in_kernelmode"}, "15.664ms")
|
|
setNested(inJSONExpected, []string{"ClientStats", "cpu_stats", "cpu_usage", "usage_in_usermode"}, "14.619ms")
|
|
setNested(inJSONExpected, []string{"ClientStats", "cpu_stats", "system_cpu_usage"}, "25.994h")
|
|
setNested(inJSONExpected, []string{"ClientStats", "precpu_stats", "cpu_usage", "total_usage"}, "30.283ms")
|
|
setNested(inJSONExpected, []string{"ClientStats", "precpu_stats", "cpu_usage", "usage_in_kernelmode"}, "15.664ms")
|
|
setNested(inJSONExpected, []string{"ClientStats", "precpu_stats", "cpu_usage", "usage_in_usermode"}, "14.619ms")
|
|
setNested(inJSONExpected, []string{"ClientStats", "precpu_stats", "system_cpu_usage"}, "25.994h")
|
|
|
|
scenarios := []scenario{
|
|
{
|
|
name: "string schema: converts float64 bytes",
|
|
data: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"memory_stats": map[string]interface{}{
|
|
"limit": float64(2048),
|
|
},
|
|
},
|
|
},
|
|
expected: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"memory_stats": map[string]interface{}{
|
|
"limit": "2.000KB",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "string schema: converts int64 nanoseconds",
|
|
data: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"cpu_stats": map[string]interface{}{
|
|
"cpu_usage": map[string]interface{}{
|
|
"total_usage": float64(100000000000),
|
|
"percpu_usage": []float64{50000000000, 50000000000},
|
|
"usage_in_kernelmode": float64(200000),
|
|
"usage_in_usermode": float64(200000),
|
|
},
|
|
"system_cpu_usage": float64(100000000000),
|
|
},
|
|
},
|
|
},
|
|
expected: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"cpu_stats": map[string]interface{}{
|
|
"cpu_usage": map[string]interface{}{
|
|
"total_usage": "100.000s",
|
|
"percpu_usage": []string{"50.000s", "50.000s"},
|
|
"usage_in_kernelmode": "200.000µs",
|
|
"usage_in_usermode": "200.000µs",
|
|
},
|
|
"system_cpu_usage": "100.000s",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "empty data is a no-op",
|
|
data: map[string]interface{}{},
|
|
expected: map[string]interface{}{},
|
|
},
|
|
{
|
|
name: "bytes below unit threshold stays as raw number",
|
|
data: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"memory_stats": map[string]interface{}{
|
|
"limit": float64(500),
|
|
},
|
|
},
|
|
},
|
|
expected: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"memory_stats": map[string]interface{}{
|
|
"limit": "500",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "bytes at MB scale",
|
|
data: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"memory_stats": map[string]interface{}{
|
|
"limit": float64(1500000),
|
|
},
|
|
},
|
|
},
|
|
expected: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"memory_stats": map[string]interface{}{
|
|
"limit": "1.431MB",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "converts deeply nested hierarchical memory limits",
|
|
data: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"memory_stats": map[string]interface{}{
|
|
"stats": map[string]interface{}{
|
|
"hierarchical_memory_limit": float64(1073741824),
|
|
"hierarchical_memsw_limit": float64(2147483648),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"memory_stats": map[string]interface{}{
|
|
"stats": map[string]interface{}{
|
|
"hierarchical_memory_limit": "1.000GB",
|
|
"hierarchical_memsw_limit": "2.000GB",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "converts precpu_stats branch",
|
|
data: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"precpu_stats": map[string]interface{}{
|
|
"cpu_usage": map[string]interface{}{
|
|
"total_usage": float64(1500000),
|
|
"percpu_usage": []float64{1000, 2000000000},
|
|
},
|
|
"system_cpu_usage": float64(1500000000000),
|
|
},
|
|
},
|
|
},
|
|
expected: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"precpu_stats": map[string]interface{}{
|
|
"cpu_usage": map[string]interface{}{
|
|
"total_usage": "1.500ms",
|
|
"percpu_usage": []string{"1.000µs", "2.000s"},
|
|
},
|
|
"system_cpu_usage": "1.500m",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "preserves fields not listed in PATHS_TO_CONVERT_BIGMETRICS",
|
|
data: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"memory_stats": map[string]interface{}{
|
|
"limit": float64(2048),
|
|
"usage": float64(1024),
|
|
},
|
|
"name": "my-container",
|
|
},
|
|
},
|
|
expected: map[string]interface{}{
|
|
"ClientStats": map[string]interface{}{
|
|
"memory_stats": map[string]interface{}{
|
|
"limit": "2.000KB",
|
|
"usage": float64(1024),
|
|
},
|
|
"name": "my-container",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "converts realistic docker stats loaded from testdata/stats.json",
|
|
data: loadInJSON(),
|
|
expected: inJSONExpected,
|
|
},
|
|
}
|
|
|
|
for _, s := range scenarios {
|
|
t.Run(s.name, func(t *testing.T) {
|
|
data := s.data
|
|
err := convertBigMetricFromSchema(&data)
|
|
if s.expectedErr != "" {
|
|
assert.EqualError(t, err, s.expectedErr)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
assert.Equal(t, s.expected, data)
|
|
})
|
|
}
|
|
}
|