diff --git a/helpers/templates/convert_to_float.go b/helpers/templates/convert_to_float.go deleted file mode 100644 index b0102e98..00000000 --- a/helpers/templates/convert_to_float.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2024 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package templates - -import ( - "fmt" - "strconv" - "time" -) - -func convertToFloat(i interface{}) (float64, error) { - switch v := i.(type) { - case float64: - return v, nil - case string: - return strconv.ParseFloat(v, 64) - case int: - return float64(v), nil - case uint: - return float64(v), nil - case int64: - return float64(v), nil - case uint64: - return float64(v), nil - case time.Duration: - return v.Seconds(), nil - default: - return 0, fmt.Errorf("can't convert %T to float", v) - } -} diff --git a/helpers/templates/humamize_duration_test.go b/helpers/templates/humamize_duration_test.go deleted file mode 100644 index 426a5977..00000000 --- a/helpers/templates/humamize_duration_test.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2024 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package templates - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestHumanizeDurationSecondsFloat64(t *testing.T) { - input := []float64{0, 1, 60, 3600, 86400, 86400 + 3600, -(86400*2 + 3600*3 + 60*4 + 5), 899.99} - expected := []string{"0s", "1s", "1m 0s", "1h 0m 0s", "1d 0h 0m 0s", "1d 1h 0m 0s", "-2d 3h 4m 5s", "14m 59s"} - - for index, value := range input { - result, err := HumanizeDuration(value) - require.NoError(t, err) - require.Equal(t, expected[index], result) - } -} - -func TestHumanizeDurationSubsecondAndFractionalSecondsFloat64(t *testing.T) { - input := []float64{.1, .0001, .12345, 60.1, 60.5, 1.2345, 12.345} - expected := []string{"100ms", "100us", "123.5ms", "1m 0s", "1m 0s", "1.234s", "12.35s"} - - for index, value := range input { - result, err := HumanizeDuration(value) - require.NoError(t, err) - require.Equal(t, expected[index], result) - } -} - -func TestHumanizeDurationErrorString(t *testing.T) { - _, err := HumanizeDuration("one") - require.Error(t, err) -} - -func TestHumanizeDurationSecondsString(t *testing.T) { - input := []string{"0", "1", "60", "3600", "86400"} - expected := []string{"0s", "1s", "1m 0s", "1h 0m 0s", "1d 0h 0m 0s"} - - for index, value := range input { - result, err := HumanizeDuration(value) - require.NoError(t, err) - require.Equal(t, expected[index], result) - } -} - -func TestHumanizeDurationSubsecondAndFractionalSecondsString(t *testing.T) { - input := []string{".1", ".0001", ".12345", "60.1", "60.5", "1.2345", "12.345"} - expected := []string{"100ms", "100us", "123.5ms", "1m 0s", "1m 0s", "1.234s", "12.35s"} - - for index, value := range input { - result, err := HumanizeDuration(value) - require.NoError(t, err) - require.Equal(t, expected[index], result) - } -} - -func TestHumanizeDurationSecondsInt(t *testing.T) { - input := []int{0, -1, 1, 1234567} - expected := []string{"0s", "-1s", "1s", "14d 6h 56m 7s"} - - for index, value := range input { - result, err := HumanizeDuration(value) - require.NoError(t, err) - require.Equal(t, expected[index], result) - } -} diff --git a/helpers/templates/humanize_duration.go b/helpers/templates/time.go similarity index 79% rename from helpers/templates/humanize_duration.go rename to helpers/templates/time.go index be53fac7..266c8c99 100644 --- a/helpers/templates/humanize_duration.go +++ b/helpers/templates/time.go @@ -16,8 +16,31 @@ package templates import ( "fmt" "math" + "strconv" + "time" ) +func convertToFloat(i interface{}) (float64, error) { + switch v := i.(type) { + case float64: + return v, nil + case string: + return strconv.ParseFloat(v, 64) + case int: + return float64(v), nil + case uint: + return float64(v), nil + case int64: + return float64(v), nil + case uint64: + return float64(v), nil + case time.Duration: + return v.Seconds(), nil + default: + return 0, fmt.Errorf("can't convert %T to float", v) + } +} + func HumanizeDuration(i interface{}) (string, error) { v, err := convertToFloat(i) if err != nil { diff --git a/helpers/templates/time_test.go b/helpers/templates/time_test.go new file mode 100644 index 00000000..8c59b21b --- /dev/null +++ b/helpers/templates/time_test.go @@ -0,0 +1,141 @@ +// Copyright 2024 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package templates + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestHumanizeDurationSecondsFloat64(t *testing.T) { + tc := []struct { + name string + input float64 + expected string + }{ + {name: "zero", input: 0, expected: "0s"}, + {name: "one second", input: 1, expected: "1s"}, + {name: "one minute", input: 60, expected: "1m 0s"}, + {name: "one hour", input: 3600, expected: "1h 0m 0s"}, + {name: "one day", input: 86400, expected: "1d 0h 0m 0s"}, + {name: "one day and one hour", input: 86400 + 3600, expected: "1d 1h 0m 0s"}, + {name: "negative duration", input: -(86400*2 + 3600*3 + 60*4 + 5), expected: "-2d 3h 4m 5s"}, + {name: "using a float", input: 899.99, expected: "14m 59s"}, + } + + for _, tt := range tc { + t.Run(tt.name, func(t *testing.T) { + result, err := HumanizeDuration(tt.input) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestHumanizeDurationSubsecondAndFractionalSecondsFloat64(t *testing.T) { + tc := []struct { + name string + input float64 + expected string + }{ + {name: "millseconds", input: .1, expected: "100ms"}, + {name: "nanoseconds", input: .0001, expected: "100us"}, + {name: "milliseconds + nanoseconds", input: .12345, expected: "123.5ms"}, + {name: "minute + millisecond", input: 60.1, expected: "1m 0s"}, + {name: "minute + milliseconds", input: 60.5, expected: "1m 0s"}, + {name: "second + milliseconds", input: 1.2345, expected: "1.234s"}, + {name: "second + milliseconds rounded", input: 12.345, expected: "12.35s"}, + } + + for _, tt := range tc { + t.Run(tt.name, func(t *testing.T) { + result, err := HumanizeDuration(tt.input) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestHumanizeDurationErrorString(t *testing.T) { + _, err := HumanizeDuration("one") + require.Error(t, err) +} + +func TestHumanizeDurationSecondsString(t *testing.T) { + tc := []struct { + name string + input string + expected string + }{ + {name: "zero", input: "0", expected: "0s"}, + {name: "second", input: "1", expected: "1s"}, + {name: "minute", input: "60", expected: "1m 0s"}, + {name: "hour", input: "3600", expected: "1h 0m 0s"}, + {name: "day", input: "86400", expected: "1d 0h 0m 0s"}, + } + + for _, tt := range tc { + t.Run(tt.name, func(t *testing.T) { + result, err := HumanizeDuration(tt.input) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestHumanizeDurationSubsecondAndFractionalSecondsString(t *testing.T) { + tc := []struct { + name string + input string + expected string + }{ + {name: "millseconds", input: ".1", expected: "100ms"}, + {name: "nanoseconds", input: ".0001", expected: "100us"}, + {name: "milliseconds + nanoseconds", input: ".12345", expected: "123.5ms"}, + {name: "minute + millisecond", input: "60.1", expected: "1m 0s"}, + {name: "minute + milliseconds", input: "60.5", expected: "1m 0s"}, + {name: "second + milliseconds", input: "1.2345", expected: "1.234s"}, + {name: "second + milliseconds rounded", input: "12.345", expected: "12.35s"}, + } + + for _, tt := range tc { + t.Run(tt.name, func(t *testing.T) { + result, err := HumanizeDuration(tt.input) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestHumanizeDurationSecondsInt(t *testing.T) { + tc := []struct { + name string + input int + expected string + }{ + {name: "zero", input: 0, expected: "0s"}, + {name: "negative", input: -1, expected: "-1s"}, + {name: "second", input: 1, expected: "1s"}, + {name: "days", input: 1234567, expected: "14d 6h 56m 7s"}, + } + + for _, tt := range tc { + t.Run(tt.name, func(t *testing.T) { + result, err := HumanizeDuration(tt.input) + require.NoError(t, err) + require.Equal(t, tt.expected, result) + }) + } +}