Making tests less flaky (#172)

This commit is contained in:
Dario Tranchitella
2020-12-20 23:29:54 +01:00
committed by GitHub
parent 03eb6e633e
commit 82bbd238fb
23 changed files with 308 additions and 270 deletions
+4 -2
View File
@@ -30,7 +30,7 @@ import (
"github.com/clastix/capsule/api/v1alpha1"
)
var _ = Describe("creating a Namespace with additional Role Binding", func() {
var _ = Describe("creating a Namespace with an additional Role Binding", func() {
tnt := &v1alpha1.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: "additional-role-binding",
@@ -54,6 +54,7 @@ var _ = Describe("creating a Namespace with additional Role Binding", func() {
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
@@ -63,7 +64,8 @@ var _ = Describe("creating a Namespace with additional Role Binding", func() {
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should be assigned on each Namespace", func() {
It("should be assigned to each Namespace", func() {
for _, ns := range []string{"rb-1", "rb-2", "rb-3"} {
ns := NewNamespace(ns)
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
+7 -3
View File
@@ -30,7 +30,7 @@ import (
"github.com/clastix/capsule/api/v1alpha1"
)
var _ = Describe("enforcing an allowed set of Service External IPs", func() {
var _ = Describe("enforcing an allowed set of Service external IPs", func() {
tnt := &v1alpha1.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: "allowed-external-ip",
@@ -48,14 +48,17 @@ var _ = Describe("enforcing an allowed set of Service External IPs", func() {
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), tnt.DeepCopy())
tnt.ResourceVersion = ""
return k8sClient.Create(context.TODO(), tnt)
}).Should(Succeed())
})
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt.DeepCopy())).Should(Succeed())
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should fail creating an evil service", func() {
ns := NewNamespace("evil-service")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
@@ -88,6 +91,7 @@ var _ = Describe("enforcing an allowed set of Service External IPs", func() {
return err
}).ShouldNot(Succeed())
})
It("should allow the first CIDR block", func() {
ns := NewNamespace("allowed-service-cidr")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
+19 -32
View File
@@ -33,7 +33,7 @@ import (
var _ = Describe("enforcing a Container Registry", func() {
tnt := &v1alpha1.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: "additional-role-binding",
Name: "container-registry",
},
Spec: v1alpha1.TenantSpec{
Owner: v1alpha1.OwnerSpec{
@@ -44,51 +44,36 @@ var _ = Describe("enforcing a Container Registry", func() {
Allowed: []string{"docker.io", "docker.tld"},
AllowedRegex: `quay\.\w+`,
},
NamespacesMetadata: v1alpha1.AdditionalMetadata{},
ServicesMetadata: v1alpha1.AdditionalMetadata{},
StorageClasses: &v1alpha1.StorageClassesSpec{},
IngressClasses: &v1alpha1.IngressClassesSpec{},
LimitRanges: []corev1.LimitRangeSpec{},
NodeSelector: map[string]string{},
ResourceQuota: []corev1.ResourceQuotaSpec{},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), tnt.DeepCopy())
tnt.ResourceVersion = ""
return k8sClient.Create(context.TODO(), tnt)
}).Should(Succeed())
})
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt.DeepCopy())).Should(Succeed())
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should add labels to Namespace", func() {
ns := NewNamespace("registry-labels")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
Eventually(func() bool {
if err := k8sClient.Get(context.Background(), types.NamespacedName{Name: ns.Name}, ns); err != nil {
return false
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.Background(), types.NamespacedName{Name: ns.Name}, ns)).Should(Succeed())
ok, _ = HaveKeyWithValue("capsule.clastix.io/allowed-registries", "docker.io,docker.tld").Match(ns.Annotations)
if !ok {
return
}
for a, expected := range map[string]string{
"capsule.clastix.io/allowed-registries": "docker.io,docker.tld",
"capsule.clastix.io/allowed-registries-regexp": `quay\.\w+`,
} {
var v string
var ok bool
v, ok = ns.Annotations[a]
if !ok {
return false
}
if ok = v == expected; !ok {
return false
}
ok, _ = HaveKeyWithValue("capsule.clastix.io/allowed-registries-regexp", `quay\.\w+`).Match(ns.Annotations)
if !ok {
return
}
return true
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
})
It("should deny running a gcr.io container", func() {
ns := NewNamespace("registry-deny")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
@@ -110,7 +95,8 @@ var _ = Describe("enforcing a Container Registry", func() {
_, err := cs.CoreV1().Pods(ns.Name).Create(context.Background(), pod, metav1.CreateOptions{})
Expect(err).ShouldNot(Succeed())
})
It("should allow using an item in the list", func() {
It("should allow using an exact match", func() {
ns := NewNamespace("registry-list")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
@@ -134,7 +120,8 @@ var _ = Describe("enforcing a Container Registry", func() {
return err
}).Should(Succeed())
})
It("should allow using a registry from regex", func() {
It("should allow using a regex match", func() {
ns := NewNamespace("registry-regex")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
+4 -2
View File
@@ -40,6 +40,7 @@ var _ = Describe("creating a Namespace as Tenant owner with custom --capsule-gro
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
@@ -49,19 +50,20 @@ var _ = Describe("creating a Namespace as Tenant owner with custom --capsule-gro
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should fail", func() {
It("should fail using a User non matching the capsule-user-group flag", func() {
args := append(defaulManagerPodArgs, []string{"--capsule-user-group=test"}...)
ModifyCapsuleManagerPodArgs(args)
CapsuleClusterGroupParam(podRecreationTimeoutInterval).Should(BeIdenticalTo("test"))
ns := NewNamespace("cg-namespace-fail")
NamespaceCreation(ns, tnt, podRecreationTimeoutInterval).ShouldNot(Succeed())
})
It("should succeed and be available in Tenant namespaces list", func() {
ModifyCapsuleManagerPodArgs(defaulManagerPodArgs)
CapsuleClusterGroupParam(podRecreationTimeoutInterval).Should(BeIdenticalTo("capsule.clastix.io"))
ns := NewNamespace("cg-namespace")
NamespaceCreation(ns, tnt, podRecreationTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
})
})
+6 -2
View File
@@ -51,6 +51,7 @@ var _ = Describe("creating a Namespace with --force-tenant-name flag", func() {
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
t1.ResourceVersion = ""
@@ -67,15 +68,18 @@ var _ = Describe("creating a Namespace with --force-tenant-name flag", func() {
Expect(k8sClient.Delete(context.TODO(), t2)).Should(Succeed())
ModifyCapsuleManagerPodArgs(defaulManagerPodArgs)
})
It("should fail with missing prefix", func() {
It("should fail when non using prefix", func() {
ns := NewNamespace("awesome")
NamespaceCreation(ns, t1, defaultTimeoutInterval).ShouldNot(Succeed())
})
It("should succeed using prefix", func() {
ns := NewNamespace("awesome-namespace")
NamespaceCreation(ns, t1, defaultTimeoutInterval).Should(Succeed())
})
It("should be assigned according closest match", func() {
It("should succeed and assigned according to closest match", func() {
ns1 := NewNamespace("awesome-tenant")
ns2 := NewNamespace("awesome-tenant-namespace")
+17 -8
View File
@@ -2,10 +2,13 @@
/*
Copyright 2020 Clastix Labs.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -47,6 +50,7 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
@@ -56,14 +60,15 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should block non allowed Ingress class", func() {
It("should block a non allowed class", func() {
ns := NewNamespace("ingress-class-disallowed")
cs := ownerClient(tnt)
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
By("non-specifying the class", func() {
By("non-specifying at all", func() {
Eventually(func() (err error) {
i := &extensionsv1beta1.Ingress{
ObjectMeta: metav1.ObjectMeta{
@@ -80,7 +85,7 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
return
}, defaultTimeoutInterval, defaultPollInterval).ShouldNot(Succeed())
})
By("using a forbidden class as Annotation", func() {
By("defining as deprecated annotation", func() {
Eventually(func() (err error) {
i := &extensionsv1beta1.Ingress{
ObjectMeta: metav1.ObjectMeta{
@@ -100,7 +105,7 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
return
}, defaultTimeoutInterval, defaultPollInterval).ShouldNot(Succeed())
})
By("specifying a forbidden class", func() {
By("using the ingressClassName", func() {
Eventually(func() (err error) {
i := &extensionsv1beta1.Ingress{
ObjectMeta: metav1.ObjectMeta{
@@ -119,7 +124,8 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
}, defaultTimeoutInterval, defaultPollInterval).ShouldNot(Succeed())
})
})
It("should allow enabled Ingress class using the deprecated Annotation", func() {
It("should allow enabled class using the deprecated annotation", func() {
ns := NewNamespace("ingress-class-allowed-annotation")
cs := ownerClient(tnt)
@@ -147,7 +153,8 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
}
})
It("should allow enabled Ingress class using the IngressClassName field", func() {
It("should allow enabled class using the ingressClassName field", func() {
ns := NewNamespace("ingress-class-allowed-annotation")
cs := ownerClient(tnt)
@@ -178,7 +185,8 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
}
})
It("should allow enabled Ingress class regexp using the deprecated Annotation", func() {
It("should allow enabled Ingress by regex using the deprecated annotation", func() {
ns := NewNamespace("ingress-class-allowed-annotation")
cs := ownerClient(tnt)
ingressClass := "oil-ingress"
@@ -205,7 +213,8 @@ var _ = Describe("when Tenant handles Ingress classes", func() {
return
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
It("should allow enabled Ingress class regexp using the IngressClassName field", func() {
It("should allow enabled Ingress by regex using the ingressClassName field", func() {
ns := NewNamespace("ingress-class-allowed-annotation")
cs := ownerClient(tnt)
ingressClass := "oil-haproxy"
+1 -1
View File
@@ -28,7 +28,7 @@ import (
"github.com/clastix/capsule/api/v1alpha1"
)
var _ = Describe("Namespace creation with no Tenant assigned", func() {
var _ = Describe("creating a Namespace creation with no Tenant assigned", func() {
It("should fail", func() {
tnt := &v1alpha1.Tenant{
Spec: v1alpha1.TenantSpec{
+9 -5
View File
@@ -42,14 +42,17 @@ var _ = Describe("creating several Namespaces for a Tenant", func() {
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), tnt.DeepCopy())
tnt.ResourceVersion = ""
return k8sClient.Create(context.TODO(), tnt)
}).Should(Succeed())
})
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should contains the default Capsule label", func() {
namespaces := []*v1.Namespace{
NewNamespace("first-capsule-ns"),
@@ -58,10 +61,11 @@ var _ = Describe("creating several Namespaces for a Tenant", func() {
}
for _, ns := range namespaces {
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, defaultTimeoutInterval).Should(ContainElement(ns.GetName()))
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: ns.GetName()}, ns)).Should(Succeed())
Expect(ns.Labels).Should(HaveKeyWithValue("capsule.clastix.io/tenant", tnt.Name))
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: ns.GetName()}, ns)).Should(Succeed())
ok, _ = HaveKeyWithValue("capsule.clastix.io/tenant", tnt.Name).Match(ns.Labels)
return
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
}
})
})
+21 -8
View File
@@ -51,6 +51,7 @@ var _ = Describe("creating a Namespace for a Tenant with additional metadata", f
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), tnt)
@@ -59,21 +60,33 @@ var _ = Describe("creating a Namespace for a Tenant with additional metadata", f
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should contains additional Namespace metadata", func() {
It("should contain additional Namespace metadata", func() {
ns := NewNamespace("namespace-metadata")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: ns.GetName()}, ns)).Should(Succeed())
By("checking additional labels", func() {
for _, l := range tnt.Spec.NamespacesMetadata.AdditionalLabels {
Expect(ns.Labels).Should(ContainElement(l))
}
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: ns.GetName()}, ns)).Should(Succeed())
for k, v := range tnt.Spec.NamespacesMetadata.AdditionalLabels {
if ok = Expect(ns.Labels).Should(HaveKeyWithValue(k, v)); !ok {
return
}
}
return
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
})
By("checking additional annotations", func() {
for _, a := range tnt.Spec.NamespacesMetadata.AdditionalAnnotations {
Expect(ns.Annotations).Should(ContainElement(a))
}
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: ns.GetName()}, ns)).Should(Succeed())
for k, v := range tnt.Spec.NamespacesMetadata.AdditionalAnnotations {
if ok = Expect(ns.Annotations).Should(HaveKeyWithValue(k, v)); !ok {
return
}
}
return
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
})
})
})
+2
View File
@@ -40,6 +40,7 @@ var _ = Describe("creating a Namespace as Tenant owner", func() {
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), tnt)
@@ -48,6 +49,7 @@ var _ = Describe("creating a Namespace as Tenant owner", func() {
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should be available in Tenant namespaces list", func() {
ns := NewNamespace("new-namespace")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
+3 -1
View File
@@ -29,7 +29,7 @@ import (
"github.com/clastix/capsule/api/v1alpha1"
)
var _ = Describe("creating a Namespace over-quota", func() {
var _ = Describe("creating a Namespace in over-quota of three", func() {
tnt := &v1alpha1.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: "over-quota-tenant",
@@ -42,6 +42,7 @@ var _ = Describe("creating a Namespace over-quota", func() {
NamespaceQuota: pointer.Int32Ptr(3),
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), tnt)
@@ -50,6 +51,7 @@ var _ = Describe("creating a Namespace over-quota", func() {
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should fail", func() {
By("creating three Namespaces", func() {
for _, name := range []string{"bob-dev", "bob-staging", "bob-production"} {
+9 -6
View File
@@ -104,6 +104,7 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should disallow deletions", func() {
By("blocking Capsule Limit ranges", func() {
ns := NewNamespace("limit-range-disallow")
@@ -133,7 +134,7 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
cs := ownerClient(tnt)
Expect(cs.NetworkingV1().NetworkPolicies(ns.GetName()).Delete(context.TODO(), np.Name, metav1.DeleteOptions{})).ShouldNot(Succeed())
})
By("blocking blocking Capsule Resource Quota", func() {
By("blocking Capsule Resource Quota", func() {
ns := NewNamespace("resource-quota-disallow")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
@@ -148,8 +149,9 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
Expect(cs.NetworkingV1().NetworkPolicies(ns.GetName()).Delete(context.TODO(), rq.Name, metav1.DeleteOptions{})).ShouldNot(Succeed())
})
})
It("should allow listing", func() {
By("Limit Range resources", func() {
It("should allow", func() {
By("listing Limit Range", func() {
ns := NewNamespace("limit-range-list")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
@@ -160,7 +162,7 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
return
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
By("Network Policy resources", func() {
By("listing Network Policy", func() {
ns := NewNamespace("network-policy-list")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
@@ -171,7 +173,7 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
return
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
By("Resource Quota resources", func() {
By("listin Resource Quota", func() {
ns := NewNamespace("resource-quota-list")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
@@ -183,7 +185,8 @@ var _ = Describe("when Tenant owner interacts with the webhooks", func() {
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
})
It("should allow all actions to Tenant owner Network Policy resources", func() {
It("should allow all actions to Tenant owner Network Policy", func() {
ns := NewNamespace("network-policy-allow")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
+4 -1
View File
@@ -40,6 +40,7 @@ var _ = Describe("creating a Namespace with --protected-namespace-regex enabled"
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
@@ -49,6 +50,7 @@ var _ = Describe("creating a Namespace with --protected-namespace-regex enabled"
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should succeed and be available in Tenant namespaces list", func() {
args := append(defaulManagerPodArgs, []string{"--protected-namespace-regex=^.*[-.]system$"}...)
ModifyCapsuleManagerPodArgs(args)
@@ -56,7 +58,8 @@ var _ = Describe("creating a Namespace with --protected-namespace-regex enabled"
NamespaceCreation(ns, tnt, podRecreationTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
})
It("should fail", func() {
It("should fail using a value non matching the regex", func() {
ns := NewNamespace("test-system")
NamespaceCreation(ns, tnt, podRecreationTimeoutInterval).ShouldNot(Succeed())
ModifyCapsuleManagerPodArgs(defaulManagerPodArgs)
+19 -40
View File
@@ -21,7 +21,6 @@ package e2e
import (
"context"
"fmt"
"time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -35,7 +34,7 @@ import (
"github.com/clastix/capsule/api/v1alpha1"
)
var _ = Describe("exceeding Tenant resource quota", func() {
var _ = Describe("exceeding a Tenant resource quota", func() {
tnt := &v1alpha1.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: "tenant-resources-changes",
@@ -115,6 +114,7 @@ var _ = Describe("exceeding Tenant resource quota", func() {
},
},
}
nsl := []string{"easy", "peasy"}
JustBeforeEach(func() {
EventuallyCreation(func() error {
@@ -132,7 +132,8 @@ var _ = Describe("exceeding Tenant resource quota", func() {
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should block new Pods if limit is reached", func() {
It("should block new Pods", func() {
cs := ownerClient(tnt)
for _, namespace := range nsl {
Eventually(func() (err error) {
@@ -166,7 +167,7 @@ var _ = Describe("exceeding Tenant resource quota", func() {
}
_, err = cs.AppsV1().Deployments(namespace).Create(context.TODO(), d, metav1.CreateOptions{})
return
}, 15*time.Second, time.Second).Should(Succeed())
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
}
for _, ns := range nsl {
n := fmt.Sprintf("capsule-%s-1", tnt.GetName())
@@ -174,55 +175,33 @@ var _ = Describe("exceeding Tenant resource quota", func() {
By("retrieving the Resource Quota", func() {
Eventually(func() error {
return k8sClient.Get(context.TODO(), types.NamespacedName{Name: n, Namespace: ns}, rq)
}, 15*time.Second, time.Second).Should(Succeed())
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
By("ensuring the status has been blocked with actual usage", func() {
Eventually(func() corev1.ResourceList {
_ = k8sClient.Get(context.TODO(), types.NamespacedName{Name: n, Namespace: ns}, rq)
return rq.Status.Hard
}, 15*time.Second, time.Second).Should(Equal(rq.Status.Used))
}, defaultTimeoutInterval, defaultPollInterval).Should(Equal(rq.Status.Used))
})
By("creating an exceeded Pod", func() {
d := &v1.Deployment{
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "my-exceeded",
Name: "container",
},
Spec: v1.DeploymentSpec{
Replicas: pointer.Int32Ptr(5),
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "exceeded",
},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": "exceeded",
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "my-exceeded",
Image: "gcr.io/google_containers/pause-amd64:3.0",
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "container",
Image: "quay.io/google-containers/pause-amd64:3.0",
},
},
},
}
_, err := cs.AppsV1().Deployments(ns).Create(context.TODO(), d, metav1.CreateOptions{})
Expect(err).Should(Succeed())
Eventually(func() (condition *v1.DeploymentCondition) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: d.GetName(), Namespace: ns}, d)).Should(Succeed())
for _, i := range d.Status.Conditions {
if i.Type == v1.DeploymentReplicaFailure {
condition = &i
break
}
}
return
}, 30*time.Second, time.Second).ShouldNot(BeNil())
cs := ownerClient(tnt)
EventuallyCreation(func() error {
_, err := cs.CoreV1().Pods(ns).Create(context.Background(), pod, metav1.CreateOptions{})
return err
}).ShouldNot(Succeed())
})
}
})
+3 -1
View File
@@ -41,6 +41,7 @@ var _ = Describe("creating a Namespace trying to select a third Tenant", func()
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), tnt)
@@ -49,6 +50,7 @@ var _ = Describe("creating a Namespace trying to select a third Tenant", func()
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should fail", func() {
var ns *corev1.Namespace
@@ -64,6 +66,6 @@ var _ = Describe("creating a Namespace trying to select a third Tenant", func()
cs := ownerClient(&v1alpha1.Tenant{Spec: v1alpha1.TenantSpec{Owner: v1alpha1.OwnerSpec{Name: "dale", Kind: "User"}}})
_, err := cs.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})
Expect(err).ShouldNot(Succeed())
Expect(err).To(HaveOccurred())
})
})
+9 -9
View File
@@ -73,19 +73,20 @@ var _ = Describe("creating a Namespace without a Tenant selector when user owns
},
},
}
It("should fail", func() {
ns := NewNamespace("fail-ns")
By("user owns 2 tenants", func() {
Expect(k8sClient.Create(context.TODO(), t1)).Should(Succeed())
Expect(k8sClient.Create(context.TODO(), t2)).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t1)}).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t2)}).Should(Succeed())
NamespaceCreation(ns, t1, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t2, defaultTimeoutInterval).ShouldNot(Succeed())
Expect(k8sClient.Delete(context.TODO(), t1)).Should(Succeed())
Expect(k8sClient.Delete(context.TODO(), t2)).Should(Succeed())
})
By("group owns 2 tenants", func() {
Expect(k8sClient.Create(context.TODO(), t3)).Should(Succeed())
Expect(k8sClient.Create(context.TODO(), t4)).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t3)}).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t4)}).Should(Succeed())
NamespaceCreation(ns, t3, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t4, defaultTimeoutInterval).ShouldNot(Succeed())
Expect(k8sClient.Delete(context.TODO(), t3)).Should(Succeed())
@@ -93,10 +94,10 @@ var _ = Describe("creating a Namespace without a Tenant selector when user owns
})
By("user and group owns 4 tenants", func() {
t1.ResourceVersion, t2.ResourceVersion, t3.ResourceVersion, t4.ResourceVersion = "", "", "", ""
Expect(k8sClient.Create(context.TODO(), t1)).Should(Succeed())
Expect(k8sClient.Create(context.TODO(), t2)).Should(Succeed())
Expect(k8sClient.Create(context.TODO(), t3)).Should(Succeed())
Expect(k8sClient.Create(context.TODO(), t4)).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t1)}).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t2)}).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t3)}).Should(Succeed())
EventuallyCreation(func() error { return k8sClient.Create(context.TODO(), t4)}).Should(Succeed())
NamespaceCreation(ns, t1, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t2, defaultTimeoutInterval).ShouldNot(Succeed())
NamespaceCreation(ns, t3, defaultTimeoutInterval).ShouldNot(Succeed())
@@ -107,5 +108,4 @@ var _ = Describe("creating a Namespace without a Tenant selector when user owns
Expect(k8sClient.Delete(context.TODO(), t4)).Should(Succeed())
})
})
})
+2
View File
@@ -51,6 +51,7 @@ var _ = Describe("creating a Namespace with Tenant selector when user owns multi
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), t1)
@@ -63,6 +64,7 @@ var _ = Describe("creating a Namespace with Tenant selector when user owns multi
Expect(k8sClient.Delete(context.TODO(), t1)).Should(Succeed())
Expect(k8sClient.Delete(context.TODO(), t2)).Should(Succeed())
})
It("should be assigned to the selected Tenant", func() {
ns := NewNamespace("tenant-2-ns")
By("assigning to the Namespace the Capsule Tenant label", func() {
+148 -136
View File
@@ -2,10 +2,13 @@
/*
Copyright 2020 Clastix Labs.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -26,12 +29,12 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/controller-runtime/pkg/client"
"k8s.io/utils/pointer"
"github.com/clastix/capsule/api/v1alpha1"
)
var _ = Describe("creating a Service/Endpoint/EndpointSlice for a Tenant with additional metadata", func() {
var _ = Describe("adding metadata to Service objects", func() {
tnt := &v1alpha1.Tenant{
ObjectMeta: metav1.ObjectMeta{
Name: "service-metadata",
@@ -51,49 +54,40 @@ var _ = Describe("creating a Service/Endpoint/EndpointSlice for a Tenant with ad
"clastix.io/custom-annotation": "buzz",
},
},
},
}
epsCR := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "epsCR",
Labels: map[string]string{
"rbac.authorization.k8s.io/aggregate-to-admin": "true",
},
},
Rules: []rbacv1.PolicyRule{
{
APIGroups: []string{"discovery.k8s.io"},
Resources: []string{"endpointslices"},
Verbs: []string{"get", "list", "watch", "create", "update", "patch", "delete"},
AdditionalRoleBindings: []v1alpha1.AdditionalRoleBindings{
{
ClusterRoleName: "system:controller:endpointslice-controller",
Subjects: []rbacv1.Subject{
{
Kind: "User",
Name: "gatsby",
},
},
},
},
},
}
JustBeforeEach(func() {
Expect(k8sClient.Create(context.TODO(), tnt)).Should(Succeed())
Expect(k8sClient.Create(context.TODO(), epsCR)).Should(Succeed())
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
return k8sClient.Create(context.TODO(), tnt)
}).Should(Succeed())
})
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
Expect(k8sClient.Delete(context.TODO(), epsCR)).Should(Succeed())
})
It("service objects should contain additional metadata", func() {
ns := NewNamespace("serivce-metadata")
It("should apply them to Service", func() {
ns := NewNamespace("service-metadata")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
meta := metav1.ObjectMeta{
Name: "test-svc",
Namespace: ns.GetName(),
Labels: map[string]string{
"k8s.io/custom-label": "wrong",
},
Annotations: map[string]string{
"clastix.io/annotation": "baz",
},
}
svc := &corev1.Service{
ObjectMeta: meta,
ObjectMeta: metav1.ObjectMeta{
Name: "service-metadata",
Namespace: ns.GetName(),
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
Ports: []corev1.ServicePort{
@@ -108,9 +102,46 @@ var _ = Describe("creating a Service/Endpoint/EndpointSlice for a Tenant with ad
},
},
}
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), svc)
}).Should(Succeed())
By("checking additional labels", func() {
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: svc.GetName(), Namespace: ns.GetName()}, svc)).Should(Succeed())
for k, v := range tnt.Spec.ServicesMetadata.AdditionalLabels {
ok, _ = HaveKeyWithValue(k, v).Match(svc.Labels)
if !ok {
return false
}
}
return true
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
})
By("checking additional annotations", func() {
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: svc.GetName(), Namespace: ns.GetName()}, svc)).Should(Succeed())
for k, v := range tnt.Spec.ServicesMetadata.AdditionalAnnotations {
ok, _ = HaveKeyWithValue(k, v).Match(svc.Annotations)
if !ok {
return false
}
}
return true
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
})
})
It("should apply them to Endpoints", func() {
ns := NewNamespace("endpoints-metadata")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
ep := &corev1.Endpoints{
ObjectMeta: meta,
ObjectMeta: metav1.ObjectMeta{
Name: "endpoints-metadata",
Namespace: ns.GetName(),
},
Subsets: []corev1.EndpointSubset{
{
Addresses: []corev1.EndpointAddress{
@@ -127,110 +158,91 @@ var _ = Describe("creating a Service/Endpoint/EndpointSlice for a Tenant with ad
},
},
}
cs := ownerClient(tnt)
Eventually(func() (err error) {
_, err = cs.CoreV1().Services(ns.GetName()).Create(context.TODO(), svc, metav1.CreateOptions{})
return
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
Eventually(func() (err error) {
_, err = cs.CoreV1().Endpoints(ns.GetName()).Create(context.TODO(), ep, metav1.CreateOptions{})
return
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
By("checking number of labels on service", func() {
Eventually(func() (labelsCnt int) {
k8sClient.Get(context.TODO(), types.NamespacedName{Name: svc.GetName(), Namespace: ns.GetName()}, svc)
return len(svc.GetLabels())
}, defaultTimeoutInterval, defaultPollInterval).Should(Equal(2))
})
By("checking additional labels on service", func() {
for _, l := range tnt.Spec.ServicesMetadata.AdditionalLabels {
Expect(svc.Labels).Should(ContainElement(l))
}
})
By("checking number of annotations on service", func() {
Eventually(func() (labelsCnt int) {
k8sClient.Get(context.TODO(), types.NamespacedName{Name: svc.GetName(), Namespace: ns.GetName()}, svc)
return len(svc.GetAnnotations())
}, defaultTimeoutInterval, defaultPollInterval).Should(Equal(3))
})
By("checking additional annotations service", func() {
for _, a := range tnt.Spec.NamespacesMetadata.AdditionalAnnotations {
Expect(svc.Annotations).Should(ContainElement(a))
}
})
By("checking number of labels on endpoint", func() {
Eventually(func() (labelsCnt int) {
k8sClient.Get(context.TODO(), types.NamespacedName{Name: ep.GetName(), Namespace: ns.GetName()}, ep)
return len(ep.GetLabels())
}, defaultTimeoutInterval, defaultPollInterval).Should(Equal(2))
})
By("checking additional labels on endpoint", func() {
for _, l := range tnt.Spec.ServicesMetadata.AdditionalLabels {
Expect(ep.Labels).Should(ContainElement(l))
}
})
By("checking number of annotations on endpoint", func() {
Eventually(func() (labelsCnt int) {
k8sClient.Get(context.TODO(), types.NamespacedName{Name: ep.GetName(), Namespace: ns.GetName()}, ep)
return len(ep.GetAnnotations())
}, defaultTimeoutInterval, defaultPollInterval).Should(Equal(3))
})
By("checking additional annotations endpoint", func() {
for _, a := range tnt.Spec.NamespacesMetadata.AdditionalAnnotations {
Expect(ep.Annotations).Should(ContainElement(a))
}
})
epsName := "foo"
epsPort := int32(9999)
var eps client.Object
maj, min, _ := GetKubernetesSemVer()
if maj == 1 && min > 16 {
eps = &discoveryv1beta1.EndpointSlice{
ObjectMeta: meta,
AddressType: discoveryv1beta1.AddressTypeIPv4,
Endpoints: []discoveryv1beta1.Endpoint{
{
Addresses: []string{"10.10.1.1"},
},
},
Ports: []discoveryv1beta1.EndpointPort{
{
Name: &epsName,
Port: &epsPort,
},
},
}
Eventually(func() (err error) {
_, err = cs.DiscoveryV1beta1().EndpointSlices(ns.GetName()).Create(context.TODO(), eps.(*discoveryv1beta1.EndpointSlice), metav1.CreateOptions{})
return
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
By("checking number of labels on endpointslice", func() {
Eventually(func() (labelsCnt int) {
k8sClient.Get(context.TODO(), types.NamespacedName{Name: eps.GetName(), Namespace: ns.GetName()}, eps)
return len(eps.GetLabels())
}, defaultTimeoutInterval, defaultPollInterval).Should(Equal(2))
})
By("checking additional annotations endpointslices", func() {
for _, a := range tnt.Spec.NamespacesMetadata.AdditionalAnnotations {
Expect(eps.GetAnnotations()).Should(ContainElement(a))
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), ep)
}).Should(Succeed())
By("checking additional labels", func() {
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: ep.GetName(), Namespace: ns.GetName()}, ep)).Should(Succeed())
for k, v := range tnt.Spec.ServicesMetadata.AdditionalLabels {
ok, _ = HaveKeyWithValue(k, v).Match(ep.Labels)
if !ok {
return false
}
}
})
By("checking number of annotations on endpointslice", func() {
Eventually(func() (labelsCnt int) {
k8sClient.Get(context.TODO(), types.NamespacedName{Name: eps.GetName(), Namespace: ns.GetName()}, eps)
return len(eps.GetAnnotations())
}, defaultTimeoutInterval, defaultPollInterval).Should(Equal(3))
})
By("checking additional labels on endpointslices", func() {
for _, l := range tnt.Spec.ServicesMetadata.AdditionalLabels {
Expect(eps.GetLabels()).Should(ContainElement(l))
return true
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
})
By("checking additional annotations", func() {
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: ep.GetName(), Namespace: ns.GetName()}, ep)).Should(Succeed())
for k, v := range tnt.Spec.ServicesMetadata.AdditionalAnnotations {
ok, _ = HaveKeyWithValue(k, v).Match(ep.Annotations)
if !ok {
return false
}
}
})
return true
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
})
})
It("should apply them to EndpointSlice", func() {
maj, min, v := GetKubernetesSemVer()
if maj == 1 && min <= 16 {
Skip("Running test on Kubernetes " + v + ", doesn't provide EndpointSlice resource")
}
ns := NewNamespace("endpointslice-metadata")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
eps := &discoveryv1beta1.EndpointSlice{
ObjectMeta: metav1.ObjectMeta{
Name: "endpointslice-metadata",
Namespace: ns.GetName(),
},
AddressType: discoveryv1beta1.AddressTypeIPv4,
Endpoints: []discoveryv1beta1.Endpoint{
{
Addresses: []string{"10.10.1.1"},
},
},
Ports: []discoveryv1beta1.EndpointPort{
{
Name: pointer.StringPtr("foo"),
Port: pointer.Int32Ptr(9999),
},
},
}
EventuallyCreation(func() error {
return k8sClient.Create(context.TODO(), eps)
}).Should(Succeed())
By("checking additional annotations EndpointSlice", func() {
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: eps.GetName(), Namespace: ns.GetName()}, eps)).Should(Succeed())
for k, v := range tnt.Spec.ServicesMetadata.AdditionalAnnotations {
ok, _ = HaveKeyWithValue(k, v).Match(eps.Annotations)
if !ok {
return false
}
}
return true
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
})
By("checking additional labels on EndpointSlice", func() {
Eventually(func() (ok bool) {
Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: eps.GetName(), Namespace: ns.GetName()}, eps)).Should(Succeed())
for k, v := range tnt.Spec.ServicesMetadata.AdditionalLabels {
ok, _ = HaveKeyWithValue(k, v).Match(eps.Labels)
if !ok {
return false
}
}
return true
}, defaultTimeoutInterval, defaultPollInterval).Should(BeTrue())
})
})
})
+12 -7
View File
@@ -2,10 +2,13 @@
/*
Copyright 2020 Clastix Labs.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -47,6 +50,7 @@ var _ = Describe("when Tenant handles Storage classes", func() {
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
@@ -56,12 +60,13 @@ var _ = Describe("when Tenant handles Storage classes", func() {
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should block non allowed Storage Class", func() {
It("should fails", func() {
ns := NewNamespace("storage-class-disallowed")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
By("non-specifying the class", func() {
By("non-specifying it", func() {
Eventually(func() (err error) {
cs := ownerClient(tnt)
p := &corev1.PersistentVolumeClaim{
@@ -81,7 +86,7 @@ var _ = Describe("when Tenant handles Storage classes", func() {
return
}, defaultTimeoutInterval, defaultPollInterval).ShouldNot(Succeed())
})
By("specifying a forbidden class", func() {
By("specifying a forbidden one", func() {
Eventually(func() (err error) {
cs := ownerClient(tnt)
p := &corev1.PersistentVolumeClaim{
@@ -102,13 +107,14 @@ var _ = Describe("when Tenant handles Storage classes", func() {
}, defaultTimeoutInterval, defaultPollInterval).ShouldNot(Succeed())
})
})
It("should allow enabled Storage Class", func() {
It("should allow", func() {
ns := NewNamespace("storage-class-allowed")
cs := ownerClient(tnt)
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
TenantNamespaceList(tnt, podRecreationTimeoutInterval).Should(ContainElement(ns.GetName()))
By("using allowed storageClass names", func() {
By("using exact matches", func() {
for _, c := range tnt.Spec.StorageClasses.Allowed {
Eventually(func() (err error) {
p := &corev1.PersistentVolumeClaim{
@@ -130,7 +136,7 @@ var _ = Describe("when Tenant handles Storage classes", func() {
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
}
})
By("using allowed storageClass regexp", func() {
By("using a regex match", func() {
allowedClass := "oil-storage"
Eventually(func() (err error) {
p := &corev1.PersistentVolumeClaim{
@@ -150,7 +156,6 @@ var _ = Describe("when Tenant handles Storage classes", func() {
_, err = cs.CoreV1().PersistentVolumeClaims(ns.GetName()).Create(context.TODO(), p, metav1.CreateOptions{})
return
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
})
})
})
+1
View File
@@ -40,6 +40,7 @@ var _ = Describe("creating a Tenant with wrong name", func() {
},
},
}
It("should fail", func() {
Expect(k8sClient.Create(context.TODO(), tnt)).ShouldNot(Succeed())
})
+2
View File
@@ -40,6 +40,7 @@ var _ = Describe("creating a Namespace with group Tenant owner", func() {
},
},
}
JustBeforeEach(func() {
EventuallyCreation(func() error {
tnt.ResourceVersion = ""
@@ -49,6 +50,7 @@ var _ = Describe("creating a Namespace with group Tenant owner", func() {
JustAfterEach(func() {
Expect(k8sClient.Delete(context.TODO(), tnt)).Should(Succeed())
})
It("should succeed and be available in Tenant namespaces list", func() {
ns := NewNamespace("gto-namespace")
NamespaceCreation(ns, tnt, defaultTimeoutInterval).Should(Succeed())
+3 -3
View File
@@ -180,7 +180,7 @@ var _ = Describe("changing Tenant managed Kubernetes resources", func() {
})
It("should reapply the original resources upon third party change", func() {
for _, ns := range nsl {
By("changing Limit Range resources", func() {
By("changing Limit Range", func() {
for i, s := range tnt.Spec.LimitRanges {
n := fmt.Sprintf("capsule-%s-%d", tnt.GetName(), i)
lr := &corev1.LimitRange{}
@@ -198,7 +198,7 @@ var _ = Describe("changing Tenant managed Kubernetes resources", func() {
}, defaultTimeoutInterval, defaultPollInterval).Should(Equal(s))
}
})
By("changing Network Policy resources", func() {
By("changing Network Policy", func() {
for i, s := range tnt.Spec.NetworkPolicies {
n := fmt.Sprintf("capsule-%s-%d", tnt.GetName(), i)
np := &networkingv1.NetworkPolicy{}
@@ -218,7 +218,7 @@ var _ = Describe("changing Tenant managed Kubernetes resources", func() {
}, defaultTimeoutInterval, defaultPollInterval).Should(Equal(s))
}
})
By("changing Resource Quota resources", func() {
By("changing Resource Quota", func() {
for i, s := range tnt.Spec.ResourceQuota {
n := fmt.Sprintf("capsule-%s-%d", tnt.GetName(), i)
rq := &corev1.ResourceQuota{}
+3 -3
View File
@@ -180,7 +180,7 @@ var _ = Describe("creating namespaces within a Tenant with resources", func() {
})
It("should contains all replicated resources", func() {
for _, name := range nsl {
By("checking Limit Range resources", func() {
By("checking Limit Range", func() {
for i, s := range tnt.Spec.LimitRanges {
n := fmt.Sprintf("capsule-%s-%d", tnt.GetName(), i)
lr := &corev1.LimitRange{}
@@ -190,7 +190,7 @@ var _ = Describe("creating namespaces within a Tenant with resources", func() {
Expect(lr.Spec).Should(Equal(s))
}
})
By("checking Network Policy resources", func() {
By("checking Network Policy", func() {
for i, s := range tnt.Spec.NetworkPolicies {
n := fmt.Sprintf("capsule-%s-%d", tnt.GetName(), i)
np := &networkingv1.NetworkPolicy{}
@@ -211,7 +211,7 @@ var _ = Describe("creating namespaces within a Tenant with resources", func() {
return ns.GetAnnotations()["scheduler.alpha.kubernetes.io/node-selector"]
}, 10*time.Second, time.Second).Should(Equal(strings.Join(selector, ",")))
})
By("checking the Resource Quota resources", func() {
By("checking the Resource Quota", func() {
for i, s := range tnt.Spec.ResourceQuota {
n := fmt.Sprintf("capsule-%s-%d", tnt.GetName(), i)
rq := &corev1.ResourceQuota{}