mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-02-14 18:09:58 +00:00
feat: diverse performance improvements (#1861)
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
This commit is contained in:
@@ -77,6 +77,7 @@ var _ = Describe("creating a Namespace for a Tenant with additional metadata", L
|
||||
for k, v := range tnt.Spec.NamespaceOptions.AdditionalMetadata.Labels {
|
||||
Expect(ns.Labels).To(HaveKeyWithValue(k, v))
|
||||
}
|
||||
|
||||
return
|
||||
})
|
||||
By("checking additional annotations", func() {
|
||||
126
e2e/namespace_required_metadata_test.go
Normal file
126
e2e/namespace_required_metadata_test.go
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright 2020-2023 Project Capsule Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
)
|
||||
|
||||
var _ = Describe("creating a Namespace for a Tenant with required metadata", Label("namespace", "metadata", "me"), func() {
|
||||
tnt := &capsulev1beta2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "tenant-metadata-required",
|
||||
},
|
||||
Spec: capsulev1beta2.TenantSpec{
|
||||
Owners: api.OwnerListSpec{
|
||||
{
|
||||
CoreOwnerSpec: api.CoreOwnerSpec{
|
||||
UserSpec: api.UserSpec{
|
||||
Name: "gatsby",
|
||||
Kind: "User",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
NamespaceOptions: &capsulev1beta2.NamespaceOptions{
|
||||
RequiredMetadata: &capsulev1beta2.RequiredMetadata{
|
||||
Labels: map[string]string{
|
||||
"environment": "^(prod|test|dev)$",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"example.corp/cost-center": "^INV-[0-9]{4}$",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
JustBeforeEach(func() {
|
||||
EventuallyCreation(func() error {
|
||||
return k8sClient.Create(context.TODO(), tnt)
|
||||
}).Should(Succeed())
|
||||
})
|
||||
JustAfterEach(func() {
|
||||
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
|
||||
})
|
||||
|
||||
It("should contain required Namespace metadata", func() {
|
||||
By("creating without required label", func() {
|
||||
ns := NewNamespace("")
|
||||
|
||||
NamespaceCreation(ns, tnt.Spec.Owners[0].UserSpec, defaultTimeoutInterval).ShouldNot(Succeed())
|
||||
TenantNamespaceList(tnt, defaultTimeoutInterval).ShouldNot(ContainElement(ns.GetName()))
|
||||
})
|
||||
|
||||
By("creating with required label, without annotation", func() {
|
||||
ns := NewNamespace("", map[string]string{
|
||||
"environment": "prod",
|
||||
})
|
||||
ns.SetAnnotations(map[string]string{})
|
||||
|
||||
NamespaceCreation(ns, tnt.Spec.Owners[0].UserSpec, defaultTimeoutInterval).ShouldNot(Succeed())
|
||||
TenantNamespaceList(tnt, defaultTimeoutInterval).ShouldNot(ContainElement(ns.GetName()))
|
||||
})
|
||||
|
||||
By("creating with required label and annotation", func() {
|
||||
ns := NewNamespace("", map[string]string{
|
||||
"environment": "prod",
|
||||
})
|
||||
ns.SetAnnotations(map[string]string{
|
||||
"example.corp/cost-center": "INV-1234",
|
||||
})
|
||||
|
||||
NamespaceCreation(ns, tnt.Spec.Owners[0].UserSpec, defaultTimeoutInterval).Should(Succeed())
|
||||
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
|
||||
|
||||
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: ns.GetName()}, ns)).Should(Succeed())
|
||||
ns.SetLabels(map[string]string{
|
||||
"environment": "UAT",
|
||||
})
|
||||
|
||||
ns.SetAnnotations(map[string]string{
|
||||
"example.corp/cost-center": "INV-1",
|
||||
})
|
||||
|
||||
c := impersonationClient(tnt.Spec.Owners[0].UserSpec.Name, withDefaultGroups(nil))
|
||||
|
||||
err := c.Update(context.TODO(), ns)
|
||||
Expect(err).ShouldNot(Succeed(), "expected failure")
|
||||
|
||||
})
|
||||
|
||||
By("creating with required label (wrong value) and annotation", func() {
|
||||
ns := NewNamespace("", map[string]string{
|
||||
"environment": "UAT",
|
||||
})
|
||||
ns.SetAnnotations(map[string]string{
|
||||
"example.corp/cost-center": "INV-1234",
|
||||
})
|
||||
|
||||
NamespaceCreation(ns, tnt.Spec.Owners[0].UserSpec, defaultTimeoutInterval).ShouldNot(Succeed())
|
||||
TenantNamespaceList(tnt, defaultTimeoutInterval).ShouldNot(ContainElement(ns.GetName()))
|
||||
})
|
||||
|
||||
By("creating with required label and annotation (wrong value)", func() {
|
||||
ns := NewNamespace("", map[string]string{
|
||||
"environment": "prod",
|
||||
})
|
||||
ns.SetAnnotations(map[string]string{
|
||||
"example.corp/cost-center": "INV-1",
|
||||
})
|
||||
|
||||
NamespaceCreation(ns, tnt.Spec.Owners[0].UserSpec, defaultTimeoutInterval).ShouldNot(Succeed())
|
||||
TenantNamespaceList(tnt, defaultTimeoutInterval).ShouldNot(ContainElement(ns.GetName()))
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
|
||||
)
|
||||
|
||||
var _ = Describe("enforcing a Runtime Class", Label("pod", "classes", "current"), func() {
|
||||
var _ = Describe("enforcing a Runtime Class", Label("pod", "classes"), func() {
|
||||
tntWithDefault := &capsulev1beta2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "e2e-runtime-selection",
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
|
||||
capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
|
||||
"github.com/projectcapsule/capsule/pkg/api/meta"
|
||||
"github.com/projectcapsule/capsule/pkg/api/misc"
|
||||
"github.com/projectcapsule/capsule/pkg/runtime/selectors"
|
||||
"github.com/projectcapsule/capsule/pkg/utils"
|
||||
)
|
||||
|
||||
@@ -85,7 +85,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
},
|
||||
},
|
||||
Spec: capsulev1beta2.ResourcePoolSpec{
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -243,7 +243,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Create(context.TODO(), claim1)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim1)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim1)
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim1)
|
||||
|
||||
claim2 := &capsulev1beta2.ResourcePoolClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -260,7 +260,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err = k8sClient.Create(context.TODO(), claim2)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim2)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim2)
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim2)
|
||||
|
||||
claim3 := &capsulev1beta2.ResourcePoolClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -524,7 +524,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
},
|
||||
},
|
||||
Spec: capsulev1beta2.ResourcePoolSpec{
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -696,7 +696,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
},
|
||||
},
|
||||
Spec: capsulev1beta2.ResourcePoolSpec{
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -769,7 +769,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Create(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
By("Verify Status was correctly initialized", func() {
|
||||
@@ -834,16 +834,16 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
conditions := extractResourcePoolMessage(claim.Status.Condition.Message)
|
||||
expected := []string{
|
||||
"requested.requests.cpu=4",
|
||||
"available.requests.cpu=2",
|
||||
}
|
||||
|
||||
Expect(containsAll(conditions, expected)).To(BeTrue(), "Actual message"+claim.Status.Condition.Message)
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.PoolExhaustedReason))
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionFalse))
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.BoundCondition))
|
||||
exhausted := claim.Status.Conditions.GetConditionByType(meta.ExhaustedCondition)
|
||||
Expect(containsAll(extractResourcePoolMessage(exhausted.Message), expected)).To(BeTrue(), "Actual message"+exhausted.Message)
|
||||
Expect(exhausted.Reason).To(Equal(meta.PoolExhaustedReason))
|
||||
Expect(exhausted.Status).To(Equal(metav1.ConditionTrue))
|
||||
Expect(exhausted.Type).To(Equal(meta.ExhaustedCondition))
|
||||
})
|
||||
|
||||
By("Create claim for request.memory", func() {
|
||||
@@ -862,7 +862,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Create(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
By("Verify Status was correctly initialized", func() {
|
||||
@@ -905,7 +905,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Create(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
By("Verify Status was correctly initialized", func() {
|
||||
@@ -942,16 +942,15 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
conditions := extractResourcePoolMessage(claim.Status.Condition.Message)
|
||||
exhausted := claim.Status.Conditions.GetConditionByType(meta.ExhaustedCondition)
|
||||
expected := []string{
|
||||
"requested.requests.cpu=4",
|
||||
"available.requests.cpu=0",
|
||||
}
|
||||
|
||||
Expect(containsAll(conditions, expected)).To(BeTrue(), "Actual message"+claim.Status.Condition.Message)
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.PoolExhaustedReason))
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionFalse))
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.BoundCondition))
|
||||
Expect(containsAll(extractResourcePoolMessage(exhausted.Message), expected)).To(BeTrue(), "Actual message"+claim.Status.Condition.Message)
|
||||
Expect(exhausted.Reason).To(Equal(meta.PoolExhaustedReason))
|
||||
Expect(exhausted.Status).To(Equal(metav1.ConditionTrue))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -964,7 +963,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
},
|
||||
},
|
||||
Spec: capsulev1beta2.ResourcePoolSpec{
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -1037,7 +1036,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Create(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
By("Create claim for requests.requests", func() {
|
||||
@@ -1056,7 +1055,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Create(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
By("Verify Status was correctly initialized", func() {
|
||||
@@ -1104,16 +1103,15 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
conditions := extractResourcePoolMessage(claim.Status.Condition.Message)
|
||||
exhausted := claim.Status.Conditions.GetConditionByType(meta.ExhaustedCondition)
|
||||
expected := []string{
|
||||
"requested.requests.cpu=4",
|
||||
"available.requests.cpu=2",
|
||||
}
|
||||
|
||||
Expect(containsAll(conditions, expected)).To(BeTrue(), "Actual message"+claim.Status.Condition.Message)
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.PoolExhaustedReason))
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionFalse))
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.BoundCondition))
|
||||
Expect(containsAll(extractResourcePoolMessage(exhausted.Message), expected)).To(BeTrue(), "Actual message"+exhausted.Message)
|
||||
Expect(exhausted.Reason).To(Equal(meta.PoolExhaustedReason))
|
||||
Expect(exhausted.Status).To(Equal(metav1.ConditionTrue))
|
||||
})
|
||||
|
||||
By("Create claim exhausting limits.cpu", func() {
|
||||
@@ -1137,16 +1135,15 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
conditions := extractResourcePoolMessage(claim.Status.Condition.Message)
|
||||
exhausted := claim.Status.Conditions.GetConditionByType(meta.ExhaustedCondition)
|
||||
expected := []string{
|
||||
"requested.limits.cpu=4",
|
||||
"available.limits.cpu=2",
|
||||
}
|
||||
|
||||
Expect(containsAll(conditions, expected)).To(BeTrue(), "Actual message"+claim.Status.Condition.Message)
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.PoolExhaustedReason))
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionFalse))
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.BoundCondition))
|
||||
Expect(containsAll(extractResourcePoolMessage(exhausted.Message), expected)).To(BeTrue(), "Actual message"+exhausted.Message)
|
||||
Expect(exhausted.Reason).To(Equal(meta.PoolExhaustedReason))
|
||||
Expect(exhausted.Status).To(Equal(metav1.ConditionTrue))
|
||||
})
|
||||
|
||||
By("Create claim for requests.cpu (attempt to skip exhausting one)", func() {
|
||||
@@ -1171,7 +1168,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
conditions := extractResourcePoolMessage(claim.Status.Condition.Message)
|
||||
exhausted := claim.Status.Conditions.GetConditionByType(meta.ExhaustedCondition)
|
||||
expected := []string{
|
||||
"requested.limits.cpu=2",
|
||||
"queued.limits.cpu=4",
|
||||
@@ -1179,10 +1176,9 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
"queued.requests.cpu=4",
|
||||
}
|
||||
|
||||
Expect(containsAll(conditions, expected)).To(BeTrue(), "Actual message"+claim.Status.Condition.Message)
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.QueueExhaustedReason))
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionFalse))
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.BoundCondition))
|
||||
Expect(containsAll(extractResourcePoolMessage(exhausted.Message), expected)).To(BeTrue(), "Actual message"+exhausted.Message)
|
||||
Expect(exhausted.Reason).To(Equal(meta.QueueExhaustedReason))
|
||||
Expect(exhausted.Status).To(Equal(metav1.ConditionTrue))
|
||||
})
|
||||
|
||||
By("Verify ResourceQuotas for namespaces", func() {
|
||||
@@ -1257,7 +1253,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: "simple-2", Namespace: "ns-2-pool-ordered"}, claim)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
By("Verify queued claim can be allocated", func() {
|
||||
@@ -1266,7 +1262,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: "simple-3", Namespace: "ns-1-pool-ordered"}, claim)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
By("Verify ResourceQuotas for namespaces", func() {
|
||||
@@ -1309,7 +1305,8 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
conditions := extractResourcePoolMessage(claim.Status.Condition.Message)
|
||||
|
||||
exhausted := claim.Status.Conditions.GetConditionByType(meta.ExhaustedCondition)
|
||||
expected := []string{
|
||||
"requested.limits.cpu=2",
|
||||
"available.limits.cpu=0",
|
||||
@@ -1317,10 +1314,9 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
"available.requests.cpu=0",
|
||||
}
|
||||
|
||||
Expect(containsAll(conditions, expected)).To(BeTrue(), "Actual message"+claim.Status.Condition.Message)
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.PoolExhaustedReason))
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionFalse))
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.BoundCondition))
|
||||
Expect(containsAll(extractResourcePoolMessage(exhausted.Message), expected)).To(BeTrue(), "Actual message"+exhausted.Message)
|
||||
Expect(exhausted.Reason).To(Equal(meta.PoolExhaustedReason))
|
||||
Expect(exhausted.Status).To(Equal(metav1.ConditionTrue))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1333,7 +1329,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
},
|
||||
},
|
||||
Spec: capsulev1beta2.ResourcePoolSpec{
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -1414,14 +1410,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Create(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.SucceededReason))
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionTrue))
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.BoundCondition))
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
By("Create claim non matching namespace", func() {
|
||||
@@ -1446,9 +1435,11 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.FailedReason))
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionFalse))
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.AssignedCondition))
|
||||
assigned := claim.Status.Conditions.GetConditionByType(meta.ReadyCondition)
|
||||
|
||||
Expect(assigned.Reason).To(Equal(meta.FailedReason))
|
||||
Expect(assigned.Status).To(Equal(metav1.ConditionFalse))
|
||||
Expect(assigned.Type).To(Equal(meta.ReadyCondition))
|
||||
})
|
||||
|
||||
By("Update Namespace Labels to become matching", func() {
|
||||
@@ -1477,7 +1468,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
})
|
||||
@@ -1491,7 +1482,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
},
|
||||
},
|
||||
Spec: capsulev1beta2.ResourcePoolSpec{
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -1599,7 +1590,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
},
|
||||
},
|
||||
Spec: capsulev1beta2.ResourcePoolSpec{
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -1707,7 +1698,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
},
|
||||
},
|
||||
Spec: capsulev1beta2.ResourcePoolSpec{
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -1779,14 +1770,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Create(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.SucceededReason))
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionTrue))
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.BoundCondition))
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
By("Create claims", func() {
|
||||
@@ -1805,14 +1789,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Create(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Failed to create Claim %s", claim)
|
||||
|
||||
isSuccessfullyBoundToPool(pool, claim)
|
||||
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.SucceededReason))
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionTrue))
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.BoundCondition))
|
||||
isSuccessfullyBoundAndUnsedToPool(pool, claim)
|
||||
})
|
||||
|
||||
By("Verify ResourcePool Status Allocation", func() {
|
||||
@@ -2026,7 +2003,7 @@ var _ = Describe("ResourcePool Tests", Label("resourcepool"), func() {
|
||||
})
|
||||
})
|
||||
|
||||
func isSuccessfullyBoundToPool(pool *capsulev1beta2.ResourcePool, claim *capsulev1beta2.ResourcePoolClaim) {
|
||||
func isSuccessfullyBoundAndUnsedToPool(pool *capsulev1beta2.ResourcePool, claim *capsulev1beta2.ResourcePoolClaim) {
|
||||
fetchedPool := &capsulev1beta2.ResourcePool{}
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: pool.Name}, fetchedPool)
|
||||
Expect(err).Should(Succeed())
|
||||
@@ -2040,9 +2017,32 @@ func isSuccessfullyBoundToPool(pool *capsulev1beta2.ResourcePool, claim *capsule
|
||||
Expect(fetchedClaim.Status.Pool.Name.String()).To(Equal(fetchedPool.Name))
|
||||
Expect(fetchedClaim.Status.Pool.UID).To(Equal(fetchedPool.GetUID()))
|
||||
|
||||
Expect(fetchedClaim.Status.Condition.Type).To(Equal(meta.BoundCondition))
|
||||
Expect(fetchedClaim.Status.Condition.Status).To(Equal(metav1.ConditionTrue))
|
||||
Expect(fetchedClaim.Status.Condition.Reason).To(Equal(meta.SucceededReason))
|
||||
bound := fetchedClaim.Status.Conditions.GetConditionByType(meta.BoundCondition)
|
||||
|
||||
Expect(bound.Type).To(Equal(meta.BoundCondition))
|
||||
Expect(bound.Status).To(Equal(metav1.ConditionFalse))
|
||||
Expect(bound.Reason).To(Equal(meta.UnusedReason))
|
||||
}
|
||||
|
||||
func isSuccessfullyBoundAndUsedToPool(pool *capsulev1beta2.ResourcePool, claim *capsulev1beta2.ResourcePoolClaim) {
|
||||
fetchedPool := &capsulev1beta2.ResourcePool{}
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: pool.Name}, fetchedPool)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
fetchedClaim := &capsulev1beta2.ResourcePoolClaim{}
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, fetchedClaim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
isBoundToPool(fetchedPool, fetchedClaim)
|
||||
|
||||
Expect(fetchedClaim.Status.Pool.Name.String()).To(Equal(fetchedPool.Name))
|
||||
Expect(fetchedClaim.Status.Pool.UID).To(Equal(fetchedPool.GetUID()))
|
||||
|
||||
bound := fetchedClaim.Status.Conditions.GetConditionByType(meta.BoundCondition)
|
||||
|
||||
Expect(bound.Type).To(Equal(meta.BoundCondition))
|
||||
Expect(bound.Status).To(Equal(metav1.ConditionTrue))
|
||||
Expect(bound.Reason).To(Equal(meta.InUseReason))
|
||||
}
|
||||
|
||||
func isBoundToPool(pool *capsulev1beta2.ResourcePool, claim *capsulev1beta2.ResourcePoolClaim) bool {
|
||||
|
||||
@@ -5,10 +5,12 @@ package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/utils/ptr"
|
||||
@@ -17,7 +19,7 @@ import (
|
||||
capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
"github.com/projectcapsule/capsule/pkg/api/meta"
|
||||
"github.com/projectcapsule/capsule/pkg/api/misc"
|
||||
"github.com/projectcapsule/capsule/pkg/runtime/selectors"
|
||||
)
|
||||
|
||||
var _ = Describe("ResourcePoolClaim Tests", Label("resourcepool"), func() {
|
||||
@@ -102,7 +104,7 @@ var _ = Describe("ResourcePoolClaim Tests", Label("resourcepool"), func() {
|
||||
},
|
||||
},
|
||||
Spec: capsulev1beta2.ResourcePoolSpec{
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -230,16 +232,7 @@ var _ = Describe("ResourcePoolClaim Tests", Label("resourcepool"), func() {
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim1.Name, Namespace: claim1.Namespace}, claim1)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
isSuccessfullyBoundToPool(pool1, claim1)
|
||||
|
||||
expectedPool := api.StatusNameUID{
|
||||
Name: api.Name(pool1.Name),
|
||||
UID: pool1.GetUID(),
|
||||
}
|
||||
Expect(claim1.Status.Pool).To(Equal(expectedPool), "expected pool name to match")
|
||||
Expect(claim1.Status.Condition.Status).To(Equal(metav1.ConditionTrue), "failed to verify condition status")
|
||||
Expect(claim1.Status.Condition.Type).To(Equal(meta.BoundCondition), "failed to verify condition type")
|
||||
Expect(claim1.Status.Condition.Reason).To(Equal(meta.SucceededReason), "failed to verify condition reason")
|
||||
isSuccessfullyBoundAndUnsedToPool(pool1, claim1)
|
||||
})
|
||||
|
||||
By("Create a second claim and verify binding", func() {
|
||||
@@ -249,16 +242,7 @@ var _ = Describe("ResourcePoolClaim Tests", Label("resourcepool"), func() {
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim2.Name, Namespace: claim2.Namespace}, claim2)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
isSuccessfullyBoundToPool(pool1, claim2)
|
||||
|
||||
expectedPool := api.StatusNameUID{
|
||||
Name: api.Name(pool1.Name),
|
||||
UID: pool1.GetUID(),
|
||||
}
|
||||
Expect(claim2.Status.Pool).To(Equal(expectedPool), "expected pool name to match")
|
||||
Expect(claim2.Status.Condition.Status).To(Equal(metav1.ConditionTrue), "failed to verify condition status")
|
||||
Expect(claim2.Status.Condition.Type).To(Equal(meta.BoundCondition), "failed to verify condition type")
|
||||
Expect(claim2.Status.Condition.Reason).To(Equal(meta.SucceededReason), "failed to verify condition reason")
|
||||
isSuccessfullyBoundAndUnsedToPool(pool1, claim2)
|
||||
})
|
||||
|
||||
By("Create a third claim and verify error", func() {
|
||||
@@ -284,12 +268,15 @@ var _ = Describe("ResourcePoolClaim Tests", Label("resourcepool"), func() {
|
||||
err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
expectedPool := api.StatusNameUID{}
|
||||
expectedPool := meta.LocalRFC1123ObjectReferenceWithUID{}
|
||||
Expect(claim.Status.Pool).To(Equal(expectedPool), "expected pool name to be empty")
|
||||
|
||||
Expect(claim.Status.Condition.Status).To(Equal(metav1.ConditionFalse), "failed to verify condition status")
|
||||
Expect(claim.Status.Condition.Type).To(Equal(meta.AssignedCondition), "failed to verify condition type")
|
||||
Expect(claim.Status.Condition.Reason).To(Equal(meta.FailedReason), "failed to verify condition reason")
|
||||
Expect(len(claim.Status.Conditions)).To(Equal(1), "expected single condition")
|
||||
Expect(len(claim.OwnerReferences)).To(Equal(0), "expected no ownerreferences")
|
||||
assigned := claim.Status.Conditions.GetConditionByType(meta.ReadyCondition)
|
||||
Expect(assigned.Status).To(Equal(metav1.ConditionFalse), "failed to verify condition status")
|
||||
Expect(assigned.Type).To(Equal(meta.ReadyCondition), "failed to verify condition type")
|
||||
Expect(assigned.Reason).To(Equal(meta.FailedReason), "failed to verify condition reason")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -305,7 +292,7 @@ var _ = Describe("ResourcePoolClaim Tests", Label("resourcepool"), func() {
|
||||
Config: capsulev1beta2.ResourcePoolSpecConfiguration{
|
||||
DeleteBoundResources: ptr.To(false),
|
||||
},
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -373,20 +360,56 @@ var _ = Describe("ResourcePoolClaim Tests", Label("resourcepool"), func() {
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
expectedPool := api.StatusNameUID{
|
||||
Name: api.Name(pool.Name),
|
||||
expectedPool := meta.LocalRFC1123ObjectReferenceWithUID{
|
||||
Name: meta.RFC1123Name(pool.Name),
|
||||
UID: pool.GetUID(),
|
||||
}
|
||||
|
||||
isBoundCondition(claim)
|
||||
isBoundAndUnusedCondition(claim)
|
||||
Expect(claim.Status.Pool).To(Equal(expectedPool), "expected pool name to match")
|
||||
})
|
||||
|
||||
By("Error on deleting bound claim", func() {
|
||||
By("Create a pod with resource requests/limits", func() {
|
||||
pod := &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "claim-pod",
|
||||
Namespace: claim.Namespace,
|
||||
Labels: map[string]string{
|
||||
"e2e": "claim-pod",
|
||||
},
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
// optional: helps schedule quickly, avoid restarts
|
||||
RestartPolicy: corev1.RestartPolicyNever,
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "pause",
|
||||
Image: "registry.k8s.io/pause:3.9",
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
corev1.ResourceCPU: resource.MustParse("10m"),
|
||||
corev1.ResourceMemory: resource.MustParse("16Mi"),
|
||||
},
|
||||
Limits: corev1.ResourceList{
|
||||
corev1.ResourceCPU: resource.MustParse("20m"),
|
||||
corev1.ResourceMemory: resource.MustParse("32Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Expect(k8sClient.Create(context.TODO(), pod)).To(Succeed())
|
||||
})
|
||||
|
||||
By("Verify the claim is used", func() {
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
isBoundCondition(claim)
|
||||
isBoundAndUsedCondition(claim)
|
||||
|
||||
err = k8sClient.Delete(context.TODO(), claim)
|
||||
Expect(err).ShouldNot(Succeed())
|
||||
@@ -432,6 +455,82 @@ var _ = Describe("ResourcePoolClaim Tests", Label("resourcepool"), func() {
|
||||
Expect(err).ShouldNot(Succeed(), "Expected error when updating resources in bound state %s", claim)
|
||||
})
|
||||
|
||||
By("Make the claim unused", func() {
|
||||
key := client.ObjectKey{Name: "claim-pod", Namespace: claim.Namespace}
|
||||
|
||||
pod := &corev1.Pod{}
|
||||
err := k8sClient.Get(context.TODO(), key, pod)
|
||||
Expect(err).To(Succeed(), "pod must exist before deleting")
|
||||
|
||||
Expect(k8sClient.Delete(context.TODO(), pod, &client.DeleteOptions{
|
||||
GracePeriodSeconds: ptr.To(int64(0)),
|
||||
})).To(Succeed())
|
||||
|
||||
Eventually(func() bool {
|
||||
p := &corev1.Pod{}
|
||||
err := k8sClient.Get(
|
||||
context.TODO(),
|
||||
key,
|
||||
p,
|
||||
)
|
||||
return apierrors.IsNotFound(err)
|
||||
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
|
||||
|
||||
})
|
||||
|
||||
By("Bind a claim", func() {
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
expectedPool := meta.LocalRFC1123ObjectReferenceWithUID{
|
||||
Name: meta.RFC1123Name(pool.Name),
|
||||
UID: pool.GetUID(),
|
||||
}
|
||||
|
||||
isBoundAndUnusedCondition(claim)
|
||||
Expect(claim.Status.Pool).To(Equal(expectedPool), "expected pool name to match")
|
||||
})
|
||||
|
||||
By("Allow on patching resources for claim (Increase)", func() {
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
claim.Spec.ResourceClaims = corev1.ResourceList{
|
||||
corev1.ResourceLimitsCPU: resource.MustParse("2"),
|
||||
corev1.ResourceLimitsMemory: resource.MustParse("2Gi"),
|
||||
corev1.ResourceRequestsCPU: resource.MustParse("2"),
|
||||
corev1.ResourceRequestsMemory: resource.MustParse("2Gi"),
|
||||
}
|
||||
|
||||
err = k8sClient.Update(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Expected error when updating resources in bound state %s", claim)
|
||||
})
|
||||
|
||||
By("Allow on patching resources for claim (Decrease)", func() {
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
claim.Spec.ResourceClaims = corev1.ResourceList{
|
||||
corev1.ResourceLimitsCPU: resource.MustParse("0"),
|
||||
corev1.ResourceLimitsMemory: resource.MustParse("0Gi"),
|
||||
corev1.ResourceRequestsCPU: resource.MustParse("0"),
|
||||
corev1.ResourceRequestsMemory: resource.MustParse("0Gi"),
|
||||
}
|
||||
|
||||
err = k8sClient.Update(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Expected error when updating resources in bound state %s", claim)
|
||||
})
|
||||
|
||||
By("Allow on patching pool name", func() {
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, claim)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
claim.Spec.Pool = "some-random-pool"
|
||||
|
||||
err = k8sClient.Update(context.TODO(), claim)
|
||||
Expect(err).Should(Succeed(), "Expected error when updating resources in bound state %s", claim)
|
||||
})
|
||||
|
||||
By("Delete Pool", func() {
|
||||
err := k8sClient.Delete(context.TODO(), pool)
|
||||
Expect(err).Should(Succeed())
|
||||
@@ -495,7 +594,7 @@ var _ = Describe("ResourcePoolClaim Tests", Label("resourcepool"), func() {
|
||||
Config: capsulev1beta2.ResourcePoolSpecConfiguration{
|
||||
DeleteBoundResources: ptr.To(false),
|
||||
},
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -524,7 +623,7 @@ var _ = Describe("ResourcePoolClaim Tests", Label("resourcepool"), func() {
|
||||
Config: capsulev1beta2.ResourcePoolSpecConfiguration{
|
||||
DeleteBoundResources: ptr.To(false),
|
||||
},
|
||||
Selectors: []misc.NamespaceSelector{
|
||||
Selectors: []selectors.NamespaceSelector{
|
||||
{
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
@@ -666,17 +765,33 @@ func isUnassignedCondition(claim *capsulev1beta2.ResourcePoolClaim) {
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, cl)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
Expect(cl.Status.Condition.Status).To(Equal(metav1.ConditionFalse), "failed to verify condition status")
|
||||
Expect(cl.Status.Condition.Type).To(Equal(meta.AssignedCondition), "failed to verify condition type")
|
||||
Expect(cl.Status.Condition.Reason).To(Equal(meta.FailedReason), "failed to verify condition reason")
|
||||
assigned := cl.Status.Conditions.GetConditionByType(meta.ReadyCondition)
|
||||
|
||||
Expect(assigned.Status).To(Equal(metav1.ConditionFalse), "failed to verify condition status")
|
||||
Expect(assigned.Type).To(Equal(meta.ReadyCondition), "failed to verify condition type")
|
||||
Expect(assigned.Reason).To(Equal(meta.FailedReason), "failed to verify condition reason")
|
||||
}
|
||||
|
||||
func isBoundCondition(claim *capsulev1beta2.ResourcePoolClaim) {
|
||||
func isBoundAndUnusedCondition(claim *capsulev1beta2.ResourcePoolClaim) {
|
||||
cl := &capsulev1beta2.ResourcePoolClaim{}
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, cl)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
Expect(cl.Status.Condition.Status).To(Equal(metav1.ConditionTrue), "failed to verify condition status")
|
||||
Expect(cl.Status.Condition.Type).To(Equal(meta.BoundCondition), "failed to verify condition type")
|
||||
Expect(cl.Status.Condition.Reason).To(Equal(meta.SucceededReason), "failed to verify condition reason")
|
||||
bound := cl.Status.Conditions.GetConditionByType(meta.BoundCondition)
|
||||
|
||||
Expect(bound.Type).To(Equal(meta.BoundCondition), "failed to verify condition type")
|
||||
Expect(bound.Reason).To(Equal(meta.UnusedReason), "failed to verify condition reason")
|
||||
Expect(bound.Status).To(Equal(metav1.ConditionFalse), "failed to verify condition status")
|
||||
}
|
||||
|
||||
func isBoundAndUsedCondition(claim *capsulev1beta2.ResourcePoolClaim) {
|
||||
cl := &capsulev1beta2.ResourcePoolClaim{}
|
||||
err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: claim.Name, Namespace: claim.Namespace}, cl)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
bound := cl.Status.Conditions.GetConditionByType(meta.BoundCondition)
|
||||
|
||||
Expect(bound.Status).To(Equal(metav1.ConditionTrue), "failed to verify condition status")
|
||||
Expect(bound.Type).To(Equal(meta.BoundCondition), "failed to verify condition type")
|
||||
Expect(bound.Reason).To(Equal(meta.InUseReason), "failed to verify condition reason")
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ var _ = Describe("Promoting ServiceAccounts to Owners", Label("config"), Label("
|
||||
if saCopy.Labels == nil {
|
||||
saCopy.Labels = map[string]string{}
|
||||
}
|
||||
saCopy.Labels[meta.OwnerPromotionLabel] = meta.OwnerPromotionLabelTrigger
|
||||
saCopy.Labels[meta.OwnerPromotionLabel] = meta.ValueTrue
|
||||
|
||||
return tc.client.Update(context.TODO(), saCopy)
|
||||
}, defaultTimeoutInterval, defaultPollInterval).Should(tc.matcher, "persona=%s", name)
|
||||
@@ -212,7 +212,7 @@ var _ = Describe("Promoting ServiceAccounts to Owners", Label("config"), Label("
|
||||
if saCopy.Labels == nil {
|
||||
saCopy.Labels = map[string]string{}
|
||||
}
|
||||
saCopy.Labels[meta.OwnerPromotionLabel] = meta.OwnerPromotionLabelTrigger
|
||||
saCopy.Labels[meta.OwnerPromotionLabel] = meta.ValueTrue
|
||||
|
||||
return tc.client.Update(context.TODO(), saCopy)
|
||||
}, defaultTimeoutInterval, defaultPollInterval).Should(tc.matcher, "persona=%s", name)
|
||||
@@ -271,7 +271,7 @@ var _ = Describe("Promoting ServiceAccounts to Owners", Label("config"), Label("
|
||||
if saCopy.Labels == nil {
|
||||
saCopy.Labels = map[string]string{}
|
||||
}
|
||||
saCopy.Labels[meta.OwnerPromotionLabel] = meta.OwnerPromotionLabelTrigger
|
||||
saCopy.Labels[meta.OwnerPromotionLabel] = meta.ValueTrue
|
||||
|
||||
return tc.client.Update(context.TODO(), saCopy)
|
||||
}, defaultTimeoutInterval, defaultPollInterval).Should(tc.matcher, "persona=%s", name)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -49,6 +50,7 @@ var _ = Describe("verify scalability", Label("scalability"), func() {
|
||||
|
||||
It("verify lifecycle (scalability)", func() {
|
||||
const amount = 50
|
||||
const podsPerNamespace int32 = 1
|
||||
|
||||
getTenant := func() *capsulev1beta2.Tenant {
|
||||
t := &capsulev1beta2.Tenant{}
|
||||
@@ -123,6 +125,15 @@ var _ = Describe("verify scalability", Label("scalability"), func() {
|
||||
waitSize(uint(i + 1))
|
||||
waitInstancePresent(ns)
|
||||
|
||||
// --- NEW: create low-impact traffic pods in the namespace ---
|
||||
dep := newTrafficDeployment(ns.GetName(), podsPerNamespace)
|
||||
EventuallyCreation(func() error {
|
||||
return k8sClient.Create(context.TODO(), dep)
|
||||
}).Should(Succeed())
|
||||
|
||||
// Wait until pods are actually scheduled & ready
|
||||
waitDeploymentReady(context.TODO(), ns.GetName(), dep.Name, podsPerNamespace)
|
||||
|
||||
namespaces = append(namespaces, ns)
|
||||
}
|
||||
|
||||
@@ -139,3 +150,56 @@ var _ = Describe("verify scalability", Label("scalability"), func() {
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
func newTrafficDeployment(ns string, replicas int32) *appsv1.Deployment {
|
||||
labels := map[string]string{"app": "traffic-pause"}
|
||||
|
||||
return &appsv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "traffic-pause",
|
||||
Namespace: ns,
|
||||
},
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: &replicas,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: labels},
|
||||
Template: corev1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: labels},
|
||||
Spec: corev1.PodSpec{
|
||||
// pause container keeps footprint tiny
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "pause",
|
||||
Image: "registry.k8s.io/pause:3.9",
|
||||
// No resources specified => requests/limits default to zero.
|
||||
// Resources: corev1.ResourceRequirements{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func scaleDeployment(ctx context.Context, ns, name string, replicas int32) {
|
||||
Eventually(func() error {
|
||||
d := &appsv1.Deployment{}
|
||||
if err := k8sClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, d); err != nil {
|
||||
return err
|
||||
}
|
||||
*d.Spec.Replicas = replicas
|
||||
return k8sClient.Update(ctx, d)
|
||||
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
|
||||
|
||||
waitDeploymentReady(ctx, ns, name, replicas)
|
||||
}
|
||||
|
||||
func waitDeploymentReady(ctx context.Context, ns, name string, replicas int32) {
|
||||
Eventually(func() (int32, error) {
|
||||
d := &appsv1.Deployment{}
|
||||
err := k8sClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, d)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return d.Status.ReadyReplicas, nil
|
||||
}, defaultTimeoutInterval, defaultPollInterval).Should(Equal(replicas))
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
|
||||
)
|
||||
|
||||
var _ = Describe("changing Tenant managed Kubernetes resources", Label("tenant"), func() {
|
||||
var _ = Describe("changing Tenant managed Kubernetes resources", Label("tenant", "managed", "current"), func() {
|
||||
tnt := &capsulev1beta2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "tenant-resources-changes",
|
||||
@@ -184,6 +184,10 @@ var _ = Describe("changing Tenant managed Kubernetes resources", Label("tenant")
|
||||
return k8sClient.Get(context.TODO(), types.NamespacedName{Name: n, Namespace: ns}, lr)
|
||||
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
|
||||
|
||||
cs := ownerClient(tnt.Spec.Owners[0].UserSpec)
|
||||
err := cs.CoreV1().LimitRanges(ns).Delete(context.TODO(), n, metav1.DeleteOptions{})
|
||||
Expect(err).To(HaveOccurred())
|
||||
|
||||
c := lr.DeepCopy()
|
||||
c.Spec.Limits = []corev1.LimitRangeItem{}
|
||||
Expect(k8sClient.Update(context.TODO(), c, &client.UpdateOptions{})).Should(Succeed())
|
||||
@@ -203,6 +207,10 @@ var _ = Describe("changing Tenant managed Kubernetes resources", Label("tenant")
|
||||
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
|
||||
Expect(np.Spec).Should(Equal(s))
|
||||
|
||||
cs := ownerClient(tnt.Spec.Owners[0].UserSpec)
|
||||
err := cs.NetworkingV1().NetworkPolicies(ns).Delete(context.TODO(), n, metav1.DeleteOptions{})
|
||||
Expect(err).To(HaveOccurred())
|
||||
|
||||
c := np.DeepCopy()
|
||||
c.Spec.Egress = []networkingv1.NetworkPolicyEgressRule{}
|
||||
c.Spec.Ingress = []networkingv1.NetworkPolicyIngressRule{}
|
||||
@@ -222,6 +230,10 @@ var _ = Describe("changing Tenant managed Kubernetes resources", Label("tenant")
|
||||
return k8sClient.Get(context.TODO(), types.NamespacedName{Name: n, Namespace: ns}, rq)
|
||||
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
|
||||
|
||||
cs := ownerClient(tnt.Spec.Owners[0].UserSpec)
|
||||
err := cs.CoreV1().ResourceQuotas(ns).Delete(context.TODO(), n, metav1.DeleteOptions{})
|
||||
Expect(err).To(HaveOccurred())
|
||||
|
||||
c := rq.DeepCopy()
|
||||
c.Spec.Hard = map[corev1.ResourceName]resource.Quantity{}
|
||||
Expect(k8sClient.Update(context.TODO(), c, &client.UpdateOptions{})).Should(Succeed())
|
||||
|
||||
Reference in New Issue
Block a user