From 91ee069ae3a173572382c139af034d6a3ff49f3c Mon Sep 17 00:00:00 2001 From: Yifan Gu Date: Tue, 9 Feb 2016 15:06:50 +0800 Subject: [PATCH] schema/resource isolator: Allow either 'limit' or 'request' to be empty. NewResourceMemoryIsolator/NewResourceCPUIsolator If 'limit' is empty, 'request' is set to 'limit', vice versa. If both are empty, then functions return error. --- schema/types/isolator_resources.go | 12 +++++ schema/types/isolator_resources_test.go | 72 ++++++++++++++++++++++++- spec/ace.md | 1 + 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/schema/types/isolator_resources.go b/schema/types/isolator_resources.go index 82f71904..80ca4940 100644 --- a/schema/types/isolator_resources.go +++ b/schema/types/isolator_resources.go @@ -144,6 +144,12 @@ func (r ResourceCPU) AsIsolator() Isolator { } func NewResourceCPUIsolator(request, limit string) (*ResourceCPU, error) { + if request == "" { + request = limit + } else if limit == "" { + limit = request + } + req, err := resource.ParseQuantity(request) if err != nil { return nil, fmt.Errorf("error parsing request: %v", err) @@ -198,6 +204,12 @@ func (r ResourceMemory) AsIsolator() Isolator { } func NewResourceMemoryIsolator(request, limit string) (*ResourceMemory, error) { + if request == "" { + request = limit + } else if limit == "" { + limit = request + } + req, err := resource.ParseQuantity(request) if err != nil { return nil, fmt.Errorf("error parsing request: %v", err) diff --git a/schema/types/isolator_resources_test.go b/schema/types/isolator_resources_test.go index 7ff9c7d6..a5f3b03f 100644 --- a/schema/types/isolator_resources_test.go +++ b/schema/types/isolator_resources_test.go @@ -48,6 +48,44 @@ func TestResourceMemoryIsolator(t *testing.T) { }, false, }, + // only empty request is valid. + { + "100M", + "", + + &ResourceMemory{ + ResourceBase{ + resourceValue{ + Request: mustQuantity("100M"), + Limit: mustQuantity("100M"), + }, + }, + }, + false, + }, + // only empty limit is valid. + { + "", + "200M", + + &ResourceMemory{ + ResourceBase{ + resourceValue{ + Request: mustQuantity("200M"), + Limit: mustQuantity("200M"), + }, + }, + }, + false, + }, + // both empty limit is invalid. + { + "", + "", + + nil, + true, + }, } for i, tt := range tests { gres, err := NewResourceMemoryIsolator(tt.inreq, tt.inlim) @@ -68,14 +106,44 @@ func TestResourceCPUIsolator(t *testing.T) { wres *ResourceCPU werr bool }{ - // empty is not valid + // both empty is not valid { "", - "2", + "", nil, true, }, + // only empty request is valid. + { + "1", + "", + + &ResourceCPU{ + ResourceBase{ + resourceValue{ + Request: mustQuantity("1"), + Limit: mustQuantity("1"), + }, + }, + }, + false, + }, + // only empty limit is valid. + { + "", + "2", + + &ResourceCPU{ + ResourceBase{ + resourceValue{ + Request: mustQuantity("2"), + Limit: mustQuantity("2"), + }, + }, + }, + false, + }, // garbage value { "1", diff --git a/spec/ace.md b/spec/ace.md index 94b7d6a9..306107b2 100644 --- a/spec/ace.md +++ b/spec/ace.md @@ -162,6 +162,7 @@ If **request** is omitted, it defaults to the value of **limit**. - **limit** is the maximum amount of a resource available to the app/pod. If the app/pod consumes a resource in excess of its limit, it must be terminated or throttled to no more than the limit. +If **limit** is ommitted, it defaults to the value of **request**. Limit and request quantities must always be represented internally (i.e. for encoding and any processing) as an integer value (i.e. NOT floating point) in a resource type's natural base units (e.g., bytes, not megabytes or gigabytes). For convenience, when specified by users quantities may either be unsuffixed, have metric suffices (E, P, T, G, M, K) or binary (power-of-two) suffices (Ei, Pi, Ti, Gi, Mi, Ki).