diff --git a/fs/types.go b/fs/types.go index aed6926b6..7b4267c21 100644 --- a/fs/types.go +++ b/fs/types.go @@ -340,7 +340,8 @@ func NewUsageValue[T interface { int64 | uint64 | float64 }](value T) *int64 { p := new(int64) - if value > T(int64(math.MaxInt64)) { + // float64(math.MaxInt64) rounds up to 2**63 which doesn't fit in an int64 + if value >= T(int64(math.MaxInt64)) { *p = math.MaxInt64 } else { *p = int64(value) diff --git a/fs/types_test.go b/fs/types_test.go new file mode 100644 index 000000000..cd47bfcdb --- /dev/null +++ b/fs/types_test.go @@ -0,0 +1,53 @@ +package fs + +import ( + "math" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewUsageValueInt64(t *testing.T) { + for _, test := range []struct { + in int64 + want int64 + }{ + {0, 0}, + {1 << 60, 1 << 60}, + {math.MaxInt64, math.MaxInt64}, + } { + assert.Equal(t, test.want, *NewUsageValue(test.in), "in=%d", test.in) + } +} + +func TestNewUsageValueUint64(t *testing.T) { + for _, test := range []struct { + in uint64 + want int64 + }{ + {0, 0}, + {math.MaxInt64, math.MaxInt64}, + {math.MaxInt64 + 1, math.MaxInt64}, + {math.MaxUint64, math.MaxInt64}, + } { + assert.Equal(t, test.want, *NewUsageValue(test.in), "in=%d", test.in) + } +} + +func TestNewUsageValueFloat64(t *testing.T) { + // Largest float64 strictly below 2**63 - this still fits in an int64. + const belowMax = float64(9223372036854773760) + for _, test := range []struct { + in float64 + want int64 + }{ + {0, 0}, + {1e18, 1000000000000000000}, // Box reports space_amount like this + {belowMax, 9223372036854773760}, + {float64(math.MaxInt64), math.MaxInt64}, // rounds up to 2**63 + {1e19, math.MaxInt64}, + {math.Inf(1), math.MaxInt64}, + } { + assert.Equal(t, test.want, *NewUsageValue(test.in), "in=%v", test.in) + } +}