@@ -23,57 +23,119 @@ import (
23
23
24
24
batchv1 "k8s.io/api/batch/v1"
25
25
corev1 "k8s.io/api/core/v1"
26
+ rbacv1 "k8s.io/api/rbac/v1"
26
27
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28
+ "k8s.io/apimachinery/pkg/labels"
29
+
30
+ rayv1alpha1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1alpha1"
27
31
28
32
. "github.com/project-codeflare/codeflare-operator/test/support"
33
+ mcadv1beta1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/apis/controller/v1beta1"
29
34
)
30
35
31
36
func TestMNISTRayClusterSDK (t * testing.T ) {
32
37
test := With (t )
33
38
test .T ().Parallel ()
34
39
35
- test .T ().Skip ("Requires https://github.com/project-codeflare/codeflare-sdk/pull/146" )
40
+ if ! IsOpenShift (test ) {
41
+ test .T ().Skip ("Requires https://github.com/project-codeflare/codeflare-sdk/pull/146" )
42
+ }
36
43
37
44
// Create a namespace
38
45
namespace := test .NewTestNamespace ()
39
46
40
- // SDK script
41
- sdk := & corev1.ConfigMap {
47
+ // Test configuration
48
+ configMap := & corev1.ConfigMap {
42
49
TypeMeta : metav1.TypeMeta {
43
50
APIVersion : corev1 .SchemeGroupVersion .String (),
44
51
Kind : "ConfigMap" ,
45
52
},
46
53
ObjectMeta : metav1.ObjectMeta {
47
- Name : "sdk" ,
54
+ Name : "mnist-raycluster- sdk" ,
48
55
Namespace : namespace .Name ,
49
56
},
50
57
BinaryData : map [string ][]byte {
51
- "sdk.py" : ReadFile (test , "sdk.py" ),
58
+ // SDK script
59
+ "mnist_raycluster_sdk.py" : ReadFile (test , "mnist_raycluster_sdk.py" ),
60
+ // pip requirements
61
+ "requirements.txt" : ReadFile (test , "requirements.txt" ),
62
+ // MNIST training script
63
+ "mnist.py" : ReadFile (test , "mnist.py" ),
52
64
},
53
65
Immutable : Ptr (true ),
54
66
}
55
- sdk , err := test .Client ().Core ().CoreV1 ().ConfigMaps (namespace .Name ).Create (test .Ctx (), sdk , metav1.CreateOptions {})
67
+ configMap , err := test .Client ().Core ().CoreV1 ().ConfigMaps (namespace .Name ).Create (test .Ctx (), configMap , metav1.CreateOptions {})
56
68
test .Expect (err ).NotTo (HaveOccurred ())
57
- test .T ().Logf ("Created ConfigMap %s/%s successfully" , sdk .Namespace , sdk .Name )
69
+ test .T ().Logf ("Created ConfigMap %s/%s successfully" , configMap .Namespace , configMap .Name )
58
70
59
- // pip requirements
60
- requirements := & corev1.ConfigMap {
71
+ // SDK client RBAC
72
+ serviceAccount := & corev1.ServiceAccount {
61
73
TypeMeta : metav1.TypeMeta {
62
74
APIVersion : corev1 .SchemeGroupVersion .String (),
63
- Kind : "ConfigMap " ,
75
+ Kind : "ServiceAccount " ,
64
76
},
65
77
ObjectMeta : metav1.ObjectMeta {
66
- Name : "requirements " ,
78
+ Name : "sdk-user " ,
67
79
Namespace : namespace .Name ,
68
80
},
69
- BinaryData : map [string ][]byte {
70
- "requirements.txt" : ReadFile (test , "requirements.txt" ),
81
+ }
82
+ serviceAccount , err = test .Client ().Core ().CoreV1 ().ServiceAccounts (namespace .Name ).Create (test .Ctx (), serviceAccount , metav1.CreateOptions {})
83
+ test .Expect (err ).NotTo (HaveOccurred ())
84
+
85
+ role := & rbacv1.Role {
86
+ TypeMeta : metav1.TypeMeta {
87
+ APIVersion : rbacv1 .SchemeGroupVersion .String (),
88
+ Kind : "Role" ,
89
+ },
90
+ ObjectMeta : metav1.ObjectMeta {
91
+ Name : "sdk" ,
92
+ Namespace : namespace .Name ,
93
+ },
94
+ Rules : []rbacv1.PolicyRule {
95
+ {
96
+ Verbs : []string {"get" , "create" , "delete" , "list" , "patch" , "update" },
97
+ APIGroups : []string {mcadv1beta1 .GroupName },
98
+ Resources : []string {"appwrappers" },
99
+ },
100
+ {
101
+ Verbs : []string {"get" , "list" },
102
+ APIGroups : []string {rayv1alpha1 .GroupVersion .Group },
103
+ Resources : []string {"rayclusters" , "rayclusters/status" },
104
+ },
105
+ {
106
+ Verbs : []string {"get" , "list" },
107
+ APIGroups : []string {"route.openshift.io" },
108
+ Resources : []string {"routes" },
109
+ },
71
110
},
72
- Immutable : Ptr (true ),
73
111
}
74
- requirements , err = test .Client ().Core ().CoreV1 ().ConfigMaps (namespace .Name ).Create (test .Ctx (), requirements , metav1.CreateOptions {})
112
+ role , err = test .Client ().Core ().RbacV1 ().Roles (namespace .Name ).Create (test .Ctx (), role , metav1.CreateOptions {})
113
+ test .Expect (err ).NotTo (HaveOccurred ())
114
+
115
+ roleBinding := & rbacv1.RoleBinding {
116
+ TypeMeta : metav1.TypeMeta {
117
+ APIVersion : rbacv1 .SchemeGroupVersion .String (),
118
+ Kind : "RoleBinding" ,
119
+ },
120
+ ObjectMeta : metav1.ObjectMeta {
121
+ Name : "sdk" ,
122
+ },
123
+ RoleRef : rbacv1.RoleRef {
124
+ APIGroup : rbacv1 .SchemeGroupVersion .Group ,
125
+ Kind : "Role" ,
126
+ Name : role .Name ,
127
+ },
128
+ Subjects : []rbacv1.Subject {
129
+ {
130
+ Kind : "ServiceAccount" ,
131
+ APIGroup : corev1 .SchemeGroupVersion .Group ,
132
+ Name : serviceAccount .Name ,
133
+ Namespace : serviceAccount .Namespace ,
134
+ },
135
+ },
136
+ }
137
+ _ , err = test .Client ().Core ().RbacV1 ().RoleBindings (namespace .Name ).Create (test .Ctx (), roleBinding , metav1.CreateOptions {})
75
138
test .Expect (err ).NotTo (HaveOccurred ())
76
- test .T ().Logf ("Created ConfigMap %s/%s successfully" , requirements .Namespace , requirements .Name )
77
139
78
140
job := & batchv1.Job {
79
141
TypeMeta : metav1.TypeMeta {
@@ -92,54 +154,62 @@ func TestMNISTRayClusterSDK(t *testing.T) {
92
154
Spec : corev1.PodSpec {
93
155
Containers : []corev1.Container {
94
156
{
95
- Name : "sdk " ,
157
+ Name : "test " ,
96
158
Image : "quay.io/opendatahub/notebooks:jupyter-minimal-ubi8-python-3.8-4c8f26e" ,
97
- Command : []string {"/bin/sh" , "-c" , "pip install -r /test/runtime/requirements.txt && python /test/job/sdk .py" },
159
+ Command : []string {"/bin/sh" , "-c" , "pip install codeflare-sdk==0.4.4 && cp /test/* . && python mnist_raycluster_sdk .py" + " " + namespace . Name },
98
160
VolumeMounts : []corev1.VolumeMount {
99
161
{
100
- Name : "sdk" ,
101
- MountPath : "/test/job" ,
102
- },
103
- {
104
- Name : "requirements" ,
105
- MountPath : "/test/runtime" ,
162
+ Name : "test" ,
163
+ MountPath : "/test" ,
106
164
},
107
165
},
108
166
},
109
167
},
110
168
Volumes : []corev1.Volume {
111
169
{
112
- Name : "sdk" ,
113
- VolumeSource : corev1.VolumeSource {
114
- ConfigMap : & corev1.ConfigMapVolumeSource {
115
- LocalObjectReference : corev1.LocalObjectReference {
116
- Name : sdk .Name ,
117
- },
118
- },
119
- },
120
- },
121
- {
122
- Name : "requirements" ,
170
+ Name : "test" ,
123
171
VolumeSource : corev1.VolumeSource {
124
172
ConfigMap : & corev1.ConfigMapVolumeSource {
125
173
LocalObjectReference : corev1.LocalObjectReference {
126
- Name : requirements .Name ,
174
+ Name : configMap .Name ,
127
175
},
128
176
},
129
177
},
130
178
},
131
179
},
132
- RestartPolicy : corev1 .RestartPolicyNever ,
180
+ RestartPolicy : corev1 .RestartPolicyNever ,
181
+ ServiceAccountName : serviceAccount .Name ,
133
182
},
134
183
},
135
184
},
136
185
}
137
186
job , err = test .Client ().Core ().BatchV1 ().Jobs (namespace .Name ).Create (test .Ctx (), job , metav1.CreateOptions {})
138
187
test .Expect (err ).NotTo (HaveOccurred ())
188
+ test .T ().Logf ("Created Job %s/%s successfully" , job .Namespace , job .Name )
139
189
140
190
defer JobTroubleshooting (test , job )
141
191
142
- test .T ().Logf ("Waiting for Job %s/%s to complete successfully" , job .Namespace , job .Name )
143
- test .Eventually (Job (test , job .Namespace , job .Name ), TestTimeoutMedium ).
144
- Should (WithTransform (ConditionStatus (batchv1 .JobComplete ), Equal (corev1 .ConditionTrue )))
192
+ test .T ().Logf ("Waiting for Job %s/%s to complete" , job .Namespace , job .Name )
193
+ test .Eventually (Job (test , job .Namespace , job .Name ), TestTimeoutLong ).Should (
194
+ Or (
195
+ WithTransform (ConditionStatus (batchv1 .JobComplete ), Equal (corev1 .ConditionTrue )),
196
+ WithTransform (ConditionStatus (batchv1 .JobFailed ), Equal (corev1 .ConditionTrue )),
197
+ ))
198
+
199
+ // Refresh the job to get the generated pod selector
200
+ job = GetJob (test , job .Namespace , job .Name )
201
+
202
+ // Get the job Pod
203
+ pods := GetPods (test , job .Namespace , metav1.ListOptions {
204
+ LabelSelector : labels .FormatLabels (job .Spec .Selector .MatchLabels )},
205
+ )
206
+ test .Expect (pods ).To (HaveLen (1 ))
207
+
208
+ // Print the job logs
209
+ test .T ().Logf ("Printing Job %s/%s logs" , job .Namespace , job .Name )
210
+ test .T ().Log (GetPodLogs (test , & pods [0 ], corev1.PodLogOptions {}))
211
+
212
+ // Assert the job has completed successfully
213
+ test .T ().Logf ("Checking the Job %s/%s has completed successfully" , job .Namespace , job .Name )
214
+ test .Expect (job ).To (WithTransform (ConditionStatus (batchv1 .JobComplete ), Equal (corev1 .ConditionTrue )))
145
215
}
0 commit comments