Skip to content

Commit 7d23ad1

Browse files
committed
test(ws): Ensure test files exist in backend for any executed code #381
Signed-off-by: Hen Schwartz (EXT-Nokia) <[email protected]>
1 parent b2bee1d commit 7d23ad1

File tree

6 files changed

+963
-9
lines changed

6 files changed

+963
-9
lines changed

workspaces/backend/internal/models/health_check/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,10 @@ const (
3131
ServiceStatusHealthy ServiceStatus = "Healthy"
3232
ServiceStatusUnhealthy ServiceStatus = "Unhealthy"
3333
)
34+
35+
func NewHealthCheck(status ServiceStatus, version string) HealthCheck {
36+
return HealthCheck{
37+
Status: status,
38+
SystemInfo: SystemInfo{Version: version},
39+
}
40+
}
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
/*
2+
Copyright 2024.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package workspacekinds_test
18+
19+
import (
20+
"testing"
21+
22+
kubefloworgv1beta1 "github.com/kubeflow/notebooks/workspaces/controller/api/v1beta1"
23+
. "github.com/onsi/ginkgo/v2"
24+
. "github.com/onsi/gomega"
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
"k8s.io/utils/ptr"
27+
28+
workspacekinds "github.com/kubeflow/notebooks/workspaces/backend/internal/models/workspacekinds"
29+
)
30+
31+
func TestWorkspaceKinds(t *testing.T) {
32+
RegisterFailHandler(Fail)
33+
RunSpecs(t, "WorkspaceKinds Suite")
34+
}
35+
36+
type workspaceKindTestCase struct {
37+
name string
38+
workspaceKind *kubefloworgv1beta1.WorkspaceKind
39+
expectedName string
40+
expectedDisplayName string
41+
expectedDescription string
42+
expectedDeprecated bool
43+
expectedDeprecationMsg string
44+
expectedHidden bool
45+
expectedIconURL string
46+
expectedLogoURL string
47+
expectedPodLabels map[string]string
48+
expectedPodAnnotations map[string]string
49+
additionalValidations func(result workspacekinds.WorkspaceKind)
50+
}
51+
52+
var _ = Describe("WorkspaceKind Types", func() {
53+
Describe("NewWorkspaceKindModelFromWorkspaceKind", func() {
54+
DescribeTable("should create WorkspaceKind models correctly",
55+
func(tc workspaceKindTestCase) {
56+
result := workspacekinds.NewWorkspaceKindModelFromWorkspaceKind(tc.workspaceKind)
57+
58+
// Basic assertions that apply to all test cases
59+
Expect(result).ToNot(BeNil())
60+
Expect(result.Name).To(Equal(tc.expectedName))
61+
Expect(result.DisplayName).To(Equal(tc.expectedDisplayName))
62+
Expect(result.Description).To(Equal(tc.expectedDescription))
63+
Expect(result.Deprecated).To(Equal(tc.expectedDeprecated))
64+
Expect(result.DeprecationMessage).To(Equal(tc.expectedDeprecationMsg))
65+
Expect(result.Hidden).To(Equal(tc.expectedHidden))
66+
Expect(result.Icon.URL).To(Equal(tc.expectedIconURL))
67+
Expect(result.Logo.URL).To(Equal(tc.expectedLogoURL))
68+
69+
// Pod metadata assertions
70+
if tc.expectedPodLabels != nil {
71+
for key, value := range tc.expectedPodLabels {
72+
Expect(result.PodTemplate.PodMetadata.Labels).To(HaveKeyWithValue(key, value))
73+
}
74+
}
75+
if tc.expectedPodAnnotations != nil {
76+
for key, value := range tc.expectedPodAnnotations {
77+
Expect(result.PodTemplate.PodMetadata.Annotations).To(HaveKeyWithValue(key, value))
78+
}
79+
}
80+
81+
// Run any additional custom validations
82+
if tc.additionalValidations != nil {
83+
tc.additionalValidations(result)
84+
}
85+
},
86+
87+
Entry("complete WorkspaceKind with all fields", workspaceKindTestCase{
88+
name: "complete WorkspaceKind",
89+
workspaceKind: &kubefloworgv1beta1.WorkspaceKind{
90+
ObjectMeta: metav1.ObjectMeta{
91+
Name: "test-workspacekind",
92+
Namespace: "kubeflow",
93+
Labels: map[string]string{
94+
"app": "workspacekind",
95+
"version": "v1",
96+
},
97+
Annotations: map[string]string{
98+
"description": "Complete workspacekind",
99+
},
100+
},
101+
Spec: kubefloworgv1beta1.WorkspaceKindSpec{
102+
Spawner: kubefloworgv1beta1.WorkspaceKindSpawner{
103+
DisplayName: "Complete Workspacekind",
104+
Description: "A complete test workspacekind with all features",
105+
Deprecated: ptr.To(false),
106+
Hidden: ptr.To(false),
107+
Icon: kubefloworgv1beta1.WorkspaceKindIcon{
108+
Url: ptr.To("/workspaces/backend/api/v1/workspacekinds/test-workspacekind/assets/icon"),
109+
},
110+
Logo: kubefloworgv1beta1.WorkspaceKindIcon{
111+
Url: ptr.To("/workspaces/backend/api/v1/workspacekinds/test-workspacekind/assets/logo"),
112+
},
113+
},
114+
PodTemplate: kubefloworgv1beta1.WorkspaceKindPodTemplate{
115+
PodMetadata: &kubefloworgv1beta1.WorkspaceKindPodMetadata{
116+
Labels: map[string]string{
117+
"app": "test-workspacekind",
118+
},
119+
Annotations: map[string]string{
120+
"annotation-key": "annotation-value",
121+
},
122+
},
123+
},
124+
},
125+
},
126+
expectedName: "test-workspacekind",
127+
expectedDisplayName: "Complete Workspacekind",
128+
expectedDescription: "A complete test workspacekind with all features",
129+
expectedDeprecated: false,
130+
expectedDeprecationMsg: "",
131+
expectedHidden: false,
132+
expectedIconURL: "/workspaces/backend/api/v1/workspacekinds/test-workspacekind/assets/icon",
133+
expectedLogoURL: "/workspaces/backend/api/v1/workspacekinds/test-workspacekind/assets/logo",
134+
expectedPodLabels: map[string]string{"app": "test-workspacekind"},
135+
expectedPodAnnotations: map[string]string{"annotation-key": "annotation-value"},
136+
}),
137+
138+
Entry("empty strings in required fields", workspaceKindTestCase{
139+
name: "empty strings in required fields",
140+
workspaceKind: &kubefloworgv1beta1.WorkspaceKind{
141+
ObjectMeta: metav1.ObjectMeta{
142+
Name: "empty-fields-workspace",
143+
},
144+
Spec: kubefloworgv1beta1.WorkspaceKindSpec{
145+
Spawner: kubefloworgv1beta1.WorkspaceKindSpawner{
146+
DisplayName: "",
147+
Description: "",
148+
},
149+
},
150+
},
151+
expectedName: "empty-fields-workspace",
152+
expectedDisplayName: "",
153+
expectedDescription: "",
154+
expectedDeprecated: false,
155+
expectedDeprecationMsg: "",
156+
expectedHidden: false,
157+
expectedIconURL: "/workspaces/backend/api/v1/workspacekinds/empty-fields-workspace/assets/icon",
158+
expectedLogoURL: "/workspaces/backend/api/v1/workspacekinds/empty-fields-workspace/assets/logo",
159+
}),
160+
161+
Entry("special characters in names", workspaceKindTestCase{
162+
name: "special characters in names",
163+
workspaceKind: &kubefloworgv1beta1.WorkspaceKind{
164+
ObjectMeta: metav1.ObjectMeta{
165+
Name: "special-chars_workspace-123",
166+
},
167+
Spec: kubefloworgv1beta1.WorkspaceKindSpec{
168+
Spawner: kubefloworgv1beta1.WorkspaceKindSpawner{
169+
DisplayName: "Special-Chars_Workspace 123!",
170+
Description: "Workspace with special characters in name",
171+
},
172+
},
173+
},
174+
expectedName: "special-chars_workspace-123",
175+
expectedDisplayName: "Special-Chars_Workspace 123!",
176+
expectedDescription: "Workspace with special characters in name",
177+
expectedDeprecated: false,
178+
expectedDeprecationMsg: "",
179+
expectedHidden: false,
180+
expectedIconURL: "/workspaces/backend/api/v1/workspacekinds/special-chars_workspace-123/assets/icon",
181+
expectedLogoURL: "/workspaces/backend/api/v1/workspacekinds/special-chars_workspace-123/assets/logo",
182+
}),
183+
184+
Entry("long descriptions", workspaceKindTestCase{
185+
name: "long descriptions",
186+
workspaceKind: &kubefloworgv1beta1.WorkspaceKind{
187+
ObjectMeta: metav1.ObjectMeta{
188+
Name: "long-description-workspace",
189+
},
190+
Spec: kubefloworgv1beta1.WorkspaceKindSpec{
191+
Spawner: kubefloworgv1beta1.WorkspaceKindSpawner{
192+
DisplayName: "Long Description Workspace",
193+
Description: "This is a very long description that contains multiple sentences. " +
194+
"It describes a workspace kind that has many features and capabilities. " +
195+
"The description should be preserved exactly as provided without truncation. " +
196+
"This tests the ability to handle larger text fields in the workspace kind model.",
197+
},
198+
},
199+
},
200+
expectedName: "long-description-workspace",
201+
expectedDisplayName: "Long Description Workspace",
202+
expectedDescription: "This is a very long description that contains multiple sentences. " +
203+
"It describes a workspace kind that has many features and capabilities. " +
204+
"The description should be preserved exactly as provided without truncation. " +
205+
"This tests the ability to handle larger text fields in the workspace kind model.",
206+
expectedDeprecated: false,
207+
expectedDeprecationMsg: "",
208+
expectedHidden: false,
209+
expectedIconURL: "/workspaces/backend/api/v1/workspacekinds/long-description-workspace/assets/icon",
210+
expectedLogoURL: "/workspaces/backend/api/v1/workspacekinds/long-description-workspace/assets/logo",
211+
additionalValidations: func(result workspacekinds.WorkspaceKind) {
212+
Expect(len(result.Description)).To(BeNumerically(">", 200))
213+
},
214+
}),
215+
216+
Entry("deprecated WorkspaceKind", workspaceKindTestCase{
217+
name: "deprecated WorkspaceKind",
218+
workspaceKind: &kubefloworgv1beta1.WorkspaceKind{
219+
ObjectMeta: metav1.ObjectMeta{
220+
Name: "deprecated-workspace",
221+
},
222+
Spec: kubefloworgv1beta1.WorkspaceKindSpec{
223+
Spawner: kubefloworgv1beta1.WorkspaceKindSpawner{
224+
DisplayName: "Deprecated Workspace",
225+
Description: "This workspace kind is deprecated",
226+
Deprecated: ptr.To(true),
227+
DeprecationMessage: ptr.To("Use new-workspace instead"),
228+
},
229+
},
230+
},
231+
expectedName: "deprecated-workspace",
232+
expectedDisplayName: "Deprecated Workspace",
233+
expectedDescription: "This workspace kind is deprecated",
234+
expectedDeprecated: true,
235+
expectedDeprecationMsg: "Use new-workspace instead",
236+
expectedHidden: false,
237+
expectedIconURL: "/workspaces/backend/api/v1/workspacekinds/deprecated-workspace/assets/icon",
238+
expectedLogoURL: "/workspaces/backend/api/v1/workspacekinds/deprecated-workspace/assets/logo",
239+
}),
240+
241+
Entry("hidden WorkspaceKind", workspaceKindTestCase{
242+
name: "hidden WorkspaceKind",
243+
workspaceKind: &kubefloworgv1beta1.WorkspaceKind{
244+
ObjectMeta: metav1.ObjectMeta{
245+
Name: "hidden-workspace",
246+
},
247+
Spec: kubefloworgv1beta1.WorkspaceKindSpec{
248+
Spawner: kubefloworgv1beta1.WorkspaceKindSpawner{
249+
DisplayName: "Hidden Workspace",
250+
Description: "This workspace kind is hidden from UI",
251+
Hidden: ptr.To(true),
252+
},
253+
},
254+
},
255+
expectedName: "hidden-workspace",
256+
expectedDisplayName: "Hidden Workspace",
257+
expectedDescription: "This workspace kind is hidden from UI",
258+
expectedDeprecated: false,
259+
expectedDeprecationMsg: "",
260+
expectedHidden: true,
261+
expectedIconURL: "/workspaces/backend/api/v1/workspacekinds/hidden-workspace/assets/icon",
262+
expectedLogoURL: "/workspaces/backend/api/v1/workspacekinds/hidden-workspace/assets/logo",
263+
}),
264+
265+
Entry("minimal WorkspaceKind with only required fields", workspaceKindTestCase{
266+
name: "minimal WorkspaceKind",
267+
workspaceKind: &kubefloworgv1beta1.WorkspaceKind{
268+
ObjectMeta: metav1.ObjectMeta{
269+
Name: "minimal-workspace",
270+
},
271+
Spec: kubefloworgv1beta1.WorkspaceKindSpec{
272+
Spawner: kubefloworgv1beta1.WorkspaceKindSpawner{
273+
DisplayName: "Minimal Workspace",
274+
},
275+
},
276+
},
277+
expectedName: "minimal-workspace",
278+
expectedDisplayName: "Minimal Workspace",
279+
expectedDescription: "",
280+
expectedDeprecated: false,
281+
expectedDeprecationMsg: "",
282+
expectedHidden: false,
283+
expectedIconURL: "/workspaces/backend/api/v1/workspacekinds/minimal-workspace/assets/icon",
284+
expectedLogoURL: "/workspaces/backend/api/v1/workspacekinds/minimal-workspace/assets/logo",
285+
}),
286+
)
287+
})
288+
})

0 commit comments

Comments
 (0)