Files
Oliver BählerandGitHub 34262c5536 fix: improve rules api (#1961)
* fix(controller): decode old object for delete requests

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: modernize golang

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: modernize golang

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: modernize golang

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* fix: preserve ca-bundles injected from external providers

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: improve rules api

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: improve rules api

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: improve rules api

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: improve rules api

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: improve rules api

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: improve rules api

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: improve rules api

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: improve rules api

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

---------

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
2026-06-10 00:18:40 +02:00

334 lines
7.5 KiB
Go

// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0
package quota
import (
"strings"
"testing"
"k8s.io/apimachinery/pkg/api/resource"
)
func TestValidateQuantity(t *testing.T) {
t.Parallel()
tests := []struct {
name string
quantity resource.Quantity
wantErr bool
errContain string
}{
{
name: "positive integer quantity is valid",
quantity: resource.MustParse("1"),
wantErr: false,
},
{
name: "positive milli quantity is valid",
quantity: resource.MustParse("100m"),
wantErr: false,
},
{
name: "positive binary memory quantity is valid",
quantity: resource.MustParse("128Mi"),
wantErr: false,
},
{
name: "positive decimal memory quantity is valid",
quantity: resource.MustParse("1Gi"),
wantErr: false,
},
{
name: "zero quantity is invalid",
quantity: resource.MustParse("0"),
wantErr: true,
errContain: "quantity must not be negative or 0",
},
{
name: "negative integer quantity is invalid",
quantity: resource.MustParse("-1"),
wantErr: true,
errContain: "quantity must not be negative or 0",
},
{
name: "negative milli quantity is invalid",
quantity: resource.MustParse("-100m"),
wantErr: true,
errContain: "quantity must not be negative or 0",
},
{
name: "negative binary quantity is invalid",
quantity: resource.MustParse("-128Mi"),
wantErr: true,
errContain: "quantity must not be negative or 0",
},
{
name: "very small positive milli quantity is valid",
quantity: resource.MustParse("1m"),
wantErr: false,
},
{
name: "large positive quantity is valid",
quantity: resource.MustParse("999999999999"),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := ValidateQuantity(tt.quantity)
if tt.wantErr {
if err == nil {
t.Fatal("expected error, got nil")
}
if tt.errContain != "" && !strings.Contains(err.Error(), tt.errContain) {
t.Fatalf("expected error to contain %q, got %q", tt.errContain, err.Error())
}
return
}
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
})
}
}
func TestClampQuantityToZero(t *testing.T) {
t.Parallel()
tests := []struct {
name string
in resource.Quantity
want resource.Quantity
}{
{
name: "positive quantity is unchanged",
in: resource.MustParse("5"),
want: resource.MustParse("5"),
},
{
name: "positive milli quantity is unchanged",
in: resource.MustParse("250m"),
want: resource.MustParse("250m"),
},
{
name: "zero quantity is unchanged",
in: resource.MustParse("0"),
want: resource.MustParse("0"),
},
{
name: "negative integer quantity is clamped to zero",
in: resource.MustParse("-5"),
want: resource.MustParse("0"),
},
{
name: "negative milli quantity is clamped to zero",
in: resource.MustParse("-250m"),
want: resource.MustParse("0"),
},
{
name: "negative memory quantity is clamped to zero",
in: resource.MustParse("-1Gi"),
want: resource.MustParse("0"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := tt.in.DeepCopy()
ClampQuantityToZero(&got)
if !QuantityEqual(got, tt.want) {
t.Fatalf("expected %q, got %q", tt.want.String(), got.String())
}
})
}
}
func TestNegateQuantity(t *testing.T) {
t.Parallel()
tests := []struct {
name string
in resource.Quantity
want resource.Quantity
}{
{
name: "positive integer becomes negative",
in: resource.MustParse("5"),
want: resource.MustParse("-5"),
},
{
name: "negative integer becomes positive",
in: resource.MustParse("-5"),
want: resource.MustParse("5"),
},
{
name: "zero remains zero",
in: resource.MustParse("0"),
want: resource.MustParse("0"),
},
{
name: "positive milli becomes negative",
in: resource.MustParse("250m"),
want: resource.MustParse("-250m"),
},
{
name: "negative milli becomes positive",
in: resource.MustParse("-250m"),
want: resource.MustParse("250m"),
},
{
name: "positive binary memory becomes negative",
in: resource.MustParse("1Gi"),
want: resource.MustParse("-1Gi"),
},
{
name: "negative binary memory becomes positive",
in: resource.MustParse("-1Gi"),
want: resource.MustParse("1Gi"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
original := tt.in.DeepCopy()
got := NegateQuantity(tt.in)
if !QuantityEqual(got, tt.want) {
t.Fatalf("expected %q, got %q", tt.want.String(), got.String())
}
if !QuantityEqual(tt.in, original) {
t.Fatalf("NegateQuantity mutated input: expected original %q, got %q", original.String(), tt.in.String())
}
})
}
}
func TestQuantityEqual(t *testing.T) {
t.Parallel()
tests := []struct {
name string
a resource.Quantity
b resource.Quantity
want bool
}{
{
name: "same integer quantities are equal",
a: resource.MustParse("1"),
b: resource.MustParse("1"),
want: true,
},
{
name: "equivalent decimal and milli quantities are equal",
a: resource.MustParse("1"),
b: resource.MustParse("1000m"),
want: true,
},
{
name: "equivalent binary quantities are equal",
a: resource.MustParse("1Gi"),
b: resource.MustParse("1024Mi"),
want: true,
},
{
name: "different integer quantities are not equal",
a: resource.MustParse("1"),
b: resource.MustParse("2"),
want: false,
},
{
name: "positive and negative quantities are not equal",
a: resource.MustParse("1"),
b: resource.MustParse("-1"),
want: false,
},
{
name: "zero quantities are equal",
a: resource.MustParse("0"),
b: resource.MustParse("0"),
want: true,
},
{
name: "equivalent CPU quantities are equal",
a: resource.MustParse("500m"),
b: resource.MustParse("0.5"),
want: true,
},
{
name: "nearby milli quantities are not equal",
a: resource.MustParse("500m"),
b: resource.MustParse("501m"),
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := QuantityEqual(tt.a, tt.b)
if got != tt.want {
t.Fatalf("expected %t for %q and %q, got %t", tt.want, tt.a.String(), tt.b.String(), got)
}
})
}
}
func TestClampQuantityToZeroMutatesOnlyNegativeInput(t *testing.T) {
t.Parallel()
q := resource.MustParse("-10")
ClampQuantityToZero(&q)
if !QuantityEqual(q, resource.MustParse("0")) {
t.Fatalf("expected quantity to be clamped to zero, got %q", q.String())
}
q = resource.MustParse("10")
ClampQuantityToZero(&q)
if !QuantityEqual(q, resource.MustParse("10")) {
t.Fatalf("expected positive quantity to remain unchanged, got %q", q.String())
}
}
func TestNegateQuantityReturnsIndependentCopy(t *testing.T) {
t.Parallel()
in := resource.MustParse("10")
out := NegateQuantity(in)
if !QuantityEqual(in, resource.MustParse("10")) {
t.Fatalf("expected input to remain unchanged, got %q", in.String())
}
if !QuantityEqual(out, resource.MustParse("-10")) {
t.Fatalf("expected output to be negated, got %q", out.String())
}
ClampQuantityToZero(&out)
if !QuantityEqual(out, resource.MustParse("0")) {
t.Fatalf("expected output to be clampable independently, got %q", out.String())
}
if !QuantityEqual(in, resource.MustParse("10")) {
t.Fatalf("expected input to remain unchanged after mutating output, got %q", in.String())
}
}