Skip to content

Commit 9f5bde6

Browse files
sutaakaropenshift-merge-bot[bot]
authored andcommitted
Adjust env tests for RayCluster controller
1 parent 4a7cb60 commit 9f5bde6

File tree

4 files changed

+168
-123
lines changed

4 files changed

+168
-123
lines changed
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Component tests
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
- 'release-*'
8+
paths-ignore:
9+
- 'docs/**'
10+
- '**.adoc'
11+
- '**.md'
12+
- 'LICENSE'
13+
push:
14+
branches:
15+
- main
16+
- 'release-*'
17+
paths-ignore:
18+
- 'docs/**'
19+
- '**.adoc'
20+
- '**.md'
21+
- 'LICENSE'
22+
23+
concurrency:
24+
group: ${{ github.head_ref }}-${{ github.workflow }}
25+
cancel-in-progress: true
26+
27+
jobs:
28+
kubernetes-component:
29+
30+
runs-on: ubuntu-latest
31+
32+
steps:
33+
- name: Checkout code
34+
uses: actions/checkout@v4
35+
36+
- name: Set Go
37+
uses: actions/setup-go@v5
38+
with:
39+
go-version: v1.20
40+
41+
- name: Run component tests
42+
run: |
43+
make test-component

Makefile

+10
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ $(LOCALBIN):
205205
KUSTOMIZE ?= $(LOCALBIN)/kustomize
206206
YQ ?= $(LOCALBIN)/yq
207207
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
208+
GINKGO ?= $(LOCALBIN)/ginkgo
208209
ENVTEST ?= $(LOCALBIN)/setup-envtest
209210
OPENSHIFT-GOIMPORTS ?= $(LOCALBIN)/openshift-goimports
210211
OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk
@@ -241,6 +242,11 @@ controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessar
241242
$(CONTROLLER_GEN): $(LOCALBIN)
242243
test -s $(LOCALBIN)/controller-gen || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
243244

245+
.PHONY: ginkgo
246+
ginkgo: $(GINKGO) ## Download ginkgo locally if necessary.
247+
$(GINKGO): $(LOCALBIN)
248+
test -s $(LOCALBIN)/ginkgo || GOBIN=$(LOCALBIN) go install github.com/onsi/ginkgo/v2/ginkgo
249+
244250
.PHONY: install-yq
245251
install-yq: $(YQ) ## Download yq locally if necessary
246252
$(YQ): $(LOCALBIN)
@@ -350,6 +356,10 @@ catalog-push: ## Push a catalog image.
350356
test-unit: manifests fmt vet envtest ## Run unit tests.
351357
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $(go list ./... | grep -v /test/) -coverprofile cover.out
352358

359+
.PHONY: test-component
360+
test-component: envtest ginkgo ## Run component tests.
361+
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" $(GINKGO) -v ./pkg/controllers/
362+
353363
.PHONY: test-e2e
354364
test-e2e: manifests fmt vet ## Run e2e tests.
355365
go test -timeout 30m -v ./test/e2e

pkg/controllers/raycluster_controller_test.go

+95-111
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ limitations under the License.
1717
package controllers
1818

1919
import (
20-
"context"
21-
"math/rand"
2220
"time"
2321

2422
. "github.com/onsi/ginkgo/v2"
@@ -29,158 +27,144 @@ import (
2927
rbacv1 "k8s.io/api/rbac/v1"
3028
"k8s.io/apimachinery/pkg/api/errors"
3129
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
32-
"k8s.io/apimachinery/pkg/types"
3330

3431
routev1 "github.com/openshift/api/route/v1"
3532
)
3633

37-
func stringInList(l []string, s string) bool {
38-
for _, i := range l {
39-
if i == s {
40-
return true
41-
}
42-
}
43-
return false
44-
}
45-
46-
var letters = []rune("abcdefghijklmnopqrstuvwxyz")
47-
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
48-
49-
func randSeq(n int) string {
50-
b := make([]rune, n)
51-
for i := range b {
52-
b[i] = letters[r.Intn(len(letters))]
53-
}
54-
return string(b)
55-
}
56-
5734
var _ = Describe("RayCluster controller", func() {
5835
Context("RayCluster controller test", func() {
5936
var rayClusterName = "test-raycluster"
60-
var typeNamespaceName types.NamespacedName
61-
ctx := context.Background()
62-
BeforeEach(func() {
63-
By("Generate random number so each run is creating unique")
64-
rString := randSeq(10)
65-
rayClusterName = rayClusterName + "-" + rString
66-
typeNamespaceName = types.NamespacedName{Name: rayClusterName, Namespace: rayClusterName}
37+
var namespaceName string
38+
BeforeEach(func(ctx SpecContext) {
6739
By("Creating a namespace for running the tests.")
6840
namespace := &corev1.Namespace{
6941
ObjectMeta: metav1.ObjectMeta{
70-
Name: rayClusterName,
42+
GenerateName: "test-",
7143
},
7244
}
73-
var err error
74-
err = k8sClient.Create(ctx, namespace)
75-
Expect(err).To(Not(HaveOccurred()))
45+
namespace, err := k8sClient.CoreV1().Namespaces().Create(ctx, namespace, metav1.CreateOptions{})
46+
Expect(err).NotTo(HaveOccurred())
47+
DeferCleanup(func(ctx SpecContext) {
48+
err := k8sClient.CoreV1().Namespaces().Delete(ctx, namespace.Name, metav1.DeleteOptions{})
49+
Expect(err).To(Not(HaveOccurred()))
50+
})
51+
namespaceName = namespace.Name
7652

7753
By("creating a basic instance of the RayCluster CR")
7854
raycluster := &rayv1.RayCluster{
7955
ObjectMeta: metav1.ObjectMeta{
8056
Name: rayClusterName,
81-
Namespace: rayClusterName,
57+
Namespace: namespace.Name,
8258
},
8359
Spec: rayv1.RayClusterSpec{
8460
HeadGroupSpec: rayv1.HeadGroupSpec{
8561
Template: corev1.PodTemplateSpec{
8662
Spec: corev1.PodSpec{
87-
Containers: []corev1.Container{
88-
corev1.Container{},
89-
},
63+
Containers: []corev1.Container{},
9064
},
9165
},
9266
RayStartParams: map[string]string{},
9367
},
9468
},
9569
}
96-
err = k8sClient.Get(ctx, typeNamespaceName, &rayv1.RayCluster{})
97-
Expect(errors.IsNotFound(err)).To(Equal(true))
98-
err = k8sClient.Create(ctx, raycluster)
70+
_, err = rayClient.RayV1().RayClusters(namespace.Name).Create(ctx, raycluster, metav1.CreateOptions{})
9971
Expect(err).To(Not(HaveOccurred()))
10072
})
10173

102-
AfterEach(func() {
103-
By("removing the instance of the RayCluster used")
104-
// err := clientSet.CoreV1().Namespaces().Delete(ctx, RayClusterName, metav1.DeleteOptions{})
105-
foundRayCluster := rayv1.RayCluster{}
106-
err := k8sClient.Get(ctx, typeNamespaceName, &foundRayCluster)
107-
if err != nil {
108-
Expect(errors.IsNotFound(err)).To(Equal(true))
109-
} else {
74+
AfterEach(func(ctx SpecContext) {
75+
By("removing instances of the RayClusters used")
76+
rayClusters, err := rayClient.RayV1().RayClusters(namespaceName).List(ctx, metav1.ListOptions{})
77+
Expect(err).To(Not(HaveOccurred()))
78+
79+
for _, rayCluster := range rayClusters.Items {
80+
err = rayClient.RayV1().RayClusters(namespaceName).Delete(ctx, rayCluster.Name, metav1.DeleteOptions{})
11081
Expect(err).To(Not(HaveOccurred()))
111-
_ = k8sClient.Delete(ctx, &foundRayCluster)
11282
}
113-
Eventually(func() bool {
114-
err := k8sClient.Get(ctx, typeNamespaceName, &foundRayCluster)
115-
return errors.IsNotFound(err)
116-
}, SpecTimeout(time.Second*10)).Should(Equal(true))
117-
})
11883

119-
It("should have oauth finalizer set", func() {
120-
foundRayCluster := rayv1.RayCluster{}
121-
Eventually(func() bool {
122-
err := k8sClient.Get(ctx, typeNamespaceName, &foundRayCluster)
123-
Expect(err).To(Not(HaveOccurred()))
124-
return stringInList(foundRayCluster.Finalizers, oAuthFinalizer)
125-
}, SpecTimeout(time.Second*10)).Should(Equal(true))
84+
Eventually(func() ([]rayv1.RayCluster, error) {
85+
rayClusters, err := rayClient.RayV1().RayClusters(namespaceName).List(ctx, metav1.ListOptions{})
86+
return rayClusters.Items, err
87+
}).WithTimeout(time.Second * 10).Should(BeEmpty())
12688
})
12789

128-
It("should create all oauth resources", func() {
129-
Eventually(func() error {
130-
foundRayCluster := rayv1.RayCluster{}
131-
err := k8sClient.Get(ctx, typeNamespaceName, &foundRayCluster)
132-
if err != nil {
133-
return err
134-
}
135-
err = k8sClient.Get(ctx, types.NamespacedName{Name: oauthSecretNameFromCluster(&foundRayCluster), Namespace: foundRayCluster.Namespace}, &corev1.Secret{})
136-
if err != nil {
137-
return err
138-
}
139-
err = k8sClient.Get(ctx, types.NamespacedName{Name: oauthServiceNameFromCluster(&foundRayCluster), Namespace: foundRayCluster.Namespace}, &corev1.Service{})
140-
if err != nil {
141-
return err
142-
}
143-
err = k8sClient.Get(ctx, types.NamespacedName{Name: foundRayCluster.Name, Namespace: foundRayCluster.Namespace}, &corev1.ServiceAccount{})
144-
if err != nil {
145-
return err
146-
}
147-
err = k8sClient.Get(ctx, types.NamespacedName{Name: crbNameFromCluster(&foundRayCluster)}, &rbacv1.ClusterRoleBinding{})
148-
if err != nil {
149-
return err
150-
}
151-
err = k8sClient.Get(ctx, types.NamespacedName{Name: foundRayCluster.Name, Namespace: foundRayCluster.Namespace}, &routev1.Route{})
152-
if err != nil {
153-
return err
154-
}
155-
return nil
156-
}, SpecTimeout(time.Second*10)).Should(Not(HaveOccurred()))
157-
})
90+
It("should have oauth finalizer set", func(ctx SpecContext) {
91+
Eventually(func() ([]string, error) {
92+
foundRayCluster, err := rayClient.RayV1().RayClusters(namespaceName).Get(ctx, rayClusterName, metav1.GetOptions{})
93+
return foundRayCluster.Finalizers, err
94+
}).WithTimeout(time.Second * 10).Should(ContainElement(oAuthFinalizer))
95+
}, SpecTimeout(time.Second*10))
15896

159-
It("should set owner references for all resources", func() {
160-
foundRayCluster := rayv1.RayCluster{}
161-
err := k8sClient.Get(ctx, typeNamespaceName, &foundRayCluster)
162-
Expect(err).ToNot(HaveOccurred())
163-
err = k8sClient.Get(ctx, types.NamespacedName{Name: oauthSecretNameFromCluster(&foundRayCluster), Namespace: foundRayCluster.Namespace}, &corev1.Secret{})
164-
Expect(err).To(Not(HaveOccurred()))
165-
err = k8sClient.Get(ctx, types.NamespacedName{Name: oauthServiceNameFromCluster(&foundRayCluster), Namespace: foundRayCluster.Namespace}, &corev1.Service{})
97+
It("should create all oauth resources", func(ctx SpecContext) {
98+
foundRayCluster, err := rayClient.RayV1().RayClusters(namespaceName).Get(ctx, rayClusterName, metav1.GetOptions{})
16699
Expect(err).To(Not(HaveOccurred()))
167-
err = k8sClient.Get(ctx, types.NamespacedName{Name: foundRayCluster.Name, Namespace: foundRayCluster.Namespace}, &corev1.ServiceAccount{})
168-
Expect(err).To(Not(HaveOccurred()))
169-
err = k8sClient.Get(ctx, types.NamespacedName{Name: crbNameFromCluster(&foundRayCluster)}, &rbacv1.ClusterRoleBinding{})
170-
Expect(err).To(Not(HaveOccurred()))
171-
err = k8sClient.Get(ctx, types.NamespacedName{Name: foundRayCluster.Name, Namespace: foundRayCluster.Namespace}, &routev1.Route{})
100+
101+
Eventually(func() (*corev1.Secret, error) {
102+
return k8sClient.CoreV1().Secrets(namespaceName).Get(ctx, oauthSecretNameFromCluster(foundRayCluster), metav1.GetOptions{})
103+
}).WithTimeout(time.Second * 10).ShouldNot(BeNil())
104+
Eventually(func() (*corev1.Service, error) {
105+
return k8sClient.CoreV1().Services(namespaceName).Get(ctx, oauthServiceNameFromCluster(foundRayCluster), metav1.GetOptions{})
106+
}).WithTimeout(time.Second * 10).ShouldNot(BeNil())
107+
Eventually(func() (*corev1.ServiceAccount, error) {
108+
return k8sClient.CoreV1().ServiceAccounts(namespaceName).Get(ctx, oauthServiceAccountNameFromCluster(foundRayCluster), metav1.GetOptions{})
109+
}).WithTimeout(time.Second * 10).ShouldNot(BeNil())
110+
Eventually(func() (*rbacv1.ClusterRoleBinding, error) {
111+
return k8sClient.RbacV1().ClusterRoleBindings().Get(ctx, crbNameFromCluster(foundRayCluster), metav1.GetOptions{})
112+
}).WithTimeout(time.Second * 10).ShouldNot(BeNil())
113+
Eventually(func() (*routev1.Route, error) {
114+
return routeClient.RouteV1().Routes(namespaceName).Get(ctx, dashboardNameFromCluster(foundRayCluster), metav1.GetOptions{})
115+
}).WithTimeout(time.Second * 10).ShouldNot(BeNil())
116+
})
117+
118+
It("should set owner references for all resources", func(ctx SpecContext) {
119+
foundRayCluster, err := rayClient.RayV1().RayClusters(namespaceName).Get(ctx, rayClusterName, metav1.GetOptions{})
172120
Expect(err).To(Not(HaveOccurred()))
121+
122+
Eventually(func() (*corev1.Secret, error) {
123+
return k8sClient.CoreV1().Secrets(namespaceName).Get(ctx, oauthSecretNameFromCluster(foundRayCluster), metav1.GetOptions{})
124+
}).WithTimeout(time.Second * 10).Should(WithTransform(OwnerReferenceKind, Equal("RayCluster")))
125+
Eventually(func() (*corev1.Secret, error) {
126+
return k8sClient.CoreV1().Secrets(namespaceName).Get(ctx, oauthSecretNameFromCluster(foundRayCluster), metav1.GetOptions{})
127+
}).WithTimeout(time.Second * 10).Should(WithTransform(OwnerReferenceName, Equal(foundRayCluster.Name)))
128+
Eventually(func() (*corev1.Service, error) {
129+
return k8sClient.CoreV1().Services(namespaceName).Get(ctx, oauthServiceNameFromCluster(foundRayCluster), metav1.GetOptions{})
130+
}).WithTimeout(time.Second * 10).Should(WithTransform(OwnerReferenceKind, Equal("RayCluster")))
131+
Eventually(func() (*corev1.Service, error) {
132+
return k8sClient.CoreV1().Services(namespaceName).Get(ctx, oauthServiceNameFromCluster(foundRayCluster), metav1.GetOptions{})
133+
}).WithTimeout(time.Second * 10).Should(WithTransform(OwnerReferenceName, Equal(foundRayCluster.Name)))
134+
Eventually(func() (*corev1.ServiceAccount, error) {
135+
return k8sClient.CoreV1().ServiceAccounts(namespaceName).Get(ctx, oauthServiceAccountNameFromCluster(foundRayCluster), metav1.GetOptions{})
136+
}).WithTimeout(time.Second * 10).Should(WithTransform(OwnerReferenceKind, Equal("RayCluster")))
137+
Eventually(func() (*corev1.ServiceAccount, error) {
138+
return k8sClient.CoreV1().ServiceAccounts(namespaceName).Get(ctx, oauthServiceAccountNameFromCluster(foundRayCluster), metav1.GetOptions{})
139+
}).WithTimeout(time.Second * 10).Should(WithTransform(OwnerReferenceName, Equal(foundRayCluster.Name)))
140+
Eventually(func() (*routev1.Route, error) {
141+
return routeClient.RouteV1().Routes(namespaceName).Get(ctx, dashboardNameFromCluster(foundRayCluster), metav1.GetOptions{})
142+
}).WithTimeout(time.Second * 10).Should(WithTransform(OwnerReferenceKind, Equal("RayCluster")))
143+
Eventually(func() (*routev1.Route, error) {
144+
return routeClient.RouteV1().Routes(namespaceName).Get(ctx, dashboardNameFromCluster(foundRayCluster), metav1.GetOptions{})
145+
}).WithTimeout(time.Second * 10).Should(WithTransform(OwnerReferenceName, Equal(foundRayCluster.Name)))
173146
})
174147

175-
It("should remove CRB when the RayCluster is deleted", func() {
176-
foundRayCluster := rayv1.RayCluster{}
177-
err := k8sClient.Get(ctx, typeNamespaceName, &foundRayCluster)
148+
It("should remove CRB when the RayCluster is deleted", func(ctx SpecContext) {
149+
foundRayCluster, err := rayClient.RayV1().RayClusters(namespaceName).Get(ctx, rayClusterName, metav1.GetOptions{})
178150
Expect(err).To(Not(HaveOccurred()))
179-
err = k8sClient.Delete(ctx, &foundRayCluster)
151+
152+
err = rayClient.RayV1().RayClusters(namespaceName).Delete(ctx, foundRayCluster.Name, metav1.DeleteOptions{})
180153
Expect(err).To(Not(HaveOccurred()))
181-
Eventually(func() bool {
182-
return errors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Name: crbNameFromCluster(&foundRayCluster)}, &rbacv1.ClusterRoleBinding{}))
183-
}, SpecTimeout(time.Second*10)).Should(Equal(true))
154+
155+
Eventually(func() error {
156+
_, err := k8sClient.RbacV1().ClusterRoleBindings().Get(ctx, crbNameFromCluster(foundRayCluster), metav1.GetOptions{})
157+
return err
158+
}).WithTimeout(time.Second * 10).Should(Satisfy(errors.IsNotFound))
184159
})
160+
185161
})
186162
})
163+
164+
func OwnerReferenceKind(meta metav1.Object) string {
165+
return meta.GetOwnerReferences()[0].Kind
166+
}
167+
168+
func OwnerReferenceName(meta metav1.Object) string {
169+
return meta.GetOwnerReferences()[0].Name
170+
}

0 commit comments

Comments
 (0)