From 6968a4e0df1f1d063e9ef531b774c8e6dae5df9e Mon Sep 17 00:00:00 2001 From: derekwaynecarr Date: Mon, 1 Jun 2015 23:29:23 -0400 Subject: [PATCH] Improve quota describe output --- pkg/api/resource/quantity.go | 9 ++++++++- pkg/api/resource/quantity_test.go | 20 +++++++++++++++++++ pkg/api/v1beta3/conversion_test.go | 32 ++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/pkg/api/resource/quantity.go b/pkg/api/resource/quantity.go index 66a3ef2dcdd..64c882cbe3d 100644 --- a/pkg/api/resource/quantity.go +++ b/pkg/api/resource/quantity.go @@ -190,7 +190,9 @@ func ParseQuantity(str string) (*Quantity, error) { // of an amount. // Arguably, this should be inf.RoundHalfUp (normal rounding), but // that would have the side effect of rounding values < .5m to zero. - amount.Round(amount, 3, inf.RoundUp) + if v, ok := amount.Unscaled(); v != int64(0) || !ok { + amount.Round(amount, 3, inf.RoundUp) + } // The max is just a simple cap. if amount.Cmp(maxAllowed) > 0 { @@ -237,6 +239,11 @@ func (q *Quantity) Canonicalize() (string, suffix) { return "0", "" } + // zero is zero always + if q.Amount.Cmp(&inf.Dec{}) == 0 { + return "0", "" + } + format := q.Format switch format { case DecimalExponent, DecimalSI: diff --git a/pkg/api/resource/quantity_test.go b/pkg/api/resource/quantity_test.go index 6da6d93515b..b9024bfa66e 100644 --- a/pkg/api/resource/quantity_test.go +++ b/pkg/api/resource/quantity_test.go @@ -57,6 +57,26 @@ func TestDec(t *testing.T) { } } +// TestQuantityParseZero ensures that when a 0 quantity is passed, its string value is 0 +func TestQuantityParseZero(t *testing.T) { + zero := MustParse("0") + if expected, actual := "0", zero.String(); expected != actual { + t.Errorf("Expected %v, actual %v", expected, actual) + } +} + +// Verifies that you get 0 as canonical value if internal value is 0, and not 0 +func TestQuantityCanocicalizeZero(t *testing.T) { + val := MustParse("1000m") + x := val.Amount + y := dec(1, 0) + z := val.Amount.Sub(x, y) + zero := Quantity{z, DecimalSI} + if expected, actual := "0", zero.String(); expected != actual { + t.Errorf("Expected %v, actual %v", expected, actual) + } +} + func TestQuantityParse(t *testing.T) { table := []struct { input string diff --git a/pkg/api/v1beta3/conversion_test.go b/pkg/api/v1beta3/conversion_test.go index a7772d3475e..c9433cba8a9 100644 --- a/pkg/api/v1beta3/conversion_test.go +++ b/pkg/api/v1beta3/conversion_test.go @@ -20,9 +20,41 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" versioned "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3" ) +func TestResourceQuotaStatusConversion(t *testing.T) { + // should serialize as "0" + expected := resource.NewQuantity(int64(0), resource.DecimalSI) + if "0" != expected.String() { + t.Errorf("Expected: 0, Actual: %v, do not require units", expected.String()) + } + + parsed := resource.MustParse("0") + if "0" != parsed.String() { + t.Errorf("Expected: 0, Actual: %v, do not require units", parsed.String()) + } + + quota := &api.ResourceQuota{} + quota.Status = api.ResourceQuotaStatus{} + quota.Status.Hard = api.ResourceList{} + quota.Status.Used = api.ResourceList{} + quota.Status.Hard[api.ResourcePods] = *expected + + // round-trip the object + data, _ := versioned.Codec.Encode(quota) + object, _ := versioned.Codec.Decode(data) + after := object.(*api.ResourceQuota) + actualQuantity := after.Status.Hard[api.ResourcePods] + actual := &actualQuantity + + // should be "0", but was "0m" + if expected.String() != actual.String() { + t.Errorf("Expected %v, Actual %v", expected.String(), actual.String()) + } +} + func TestNodeConversion(t *testing.T) { obj, err := versioned.Codec.Decode([]byte(`{"kind":"Minion","apiVersion":"v1beta3"}`)) if err != nil {