@@ -222,120 +222,6 @@ func (c *mcpContext) withKubeConfig(rc *rest.Config) *clientcmdapi.Config {
222222 return fakeConfig
223223}
224224
225- // withEnvTest sets up the environment for kubeconfig to be used with envTest
226- func (c * mcpContext ) withEnvTest () {
227- c .withKubeConfig (envTestRestConfig )
228- }
229-
230- // inOpenShift sets up the kubernetes environment to seem to be running OpenShift
231- func inOpenShift (c * mcpContext ) {
232- c .withEnvTest ()
233- crdTemplate := `
234- {
235- "apiVersion": "apiextensions.k8s.io/v1",
236- "kind": "CustomResourceDefinition",
237- "metadata": {"name": "%s"},
238- "spec": {
239- "group": "%s",
240- "versions": [{
241- "name": "v1","served": true,"storage": true,
242- "schema": {"openAPIV3Schema": {"type": "object","x-kubernetes-preserve-unknown-fields": true}}
243- }],
244- "scope": "%s",
245- "names": {"plural": "%s","singular": "%s","kind": "%s"}
246- }
247- }`
248- tasks , _ := errgroup .WithContext (c .ctx )
249- tasks .Go (func () error {
250- return c .crdApply (fmt .Sprintf (crdTemplate , "projects.project.openshift.io" , "project.openshift.io" ,
251- "Cluster" , "projects" , "project" , "Project" ))
252- })
253- tasks .Go (func () error {
254- return c .crdApply (fmt .Sprintf (crdTemplate , "routes.route.openshift.io" , "route.openshift.io" ,
255- "Namespaced" , "routes" , "route" , "Route" ))
256- })
257- if err := tasks .Wait (); err != nil {
258- panic (err )
259- }
260- }
261-
262- // inOpenShiftClear clears the kubernetes environment so it no longer seems to be running OpenShift
263- func inOpenShiftClear (c * mcpContext ) {
264- tasks , _ := errgroup .WithContext (c .ctx )
265- tasks .Go (func () error { return c .crdDelete ("projects.project.openshift.io" ) })
266- tasks .Go (func () error { return c .crdDelete ("routes.route.openshift.io" ) })
267- if err := tasks .Wait (); err != nil {
268- panic (err )
269- }
270- }
271-
272- // newKubernetesClient creates a new Kubernetes client with the envTest kubeconfig
273- func (c * mcpContext ) newKubernetesClient () * kubernetes.Clientset {
274- return kubernetes .NewForConfigOrDie (envTestRestConfig )
275- }
276-
277- // newApiExtensionsClient creates a new ApiExtensions client with the envTest kubeconfig
278- func (c * mcpContext ) newApiExtensionsClient () * apiextensionsv1.ApiextensionsV1Client {
279- return apiextensionsv1 .NewForConfigOrDie (envTestRestConfig )
280- }
281-
282- // crdApply creates a CRD from the provided resource string and waits for it to be established
283- func (c * mcpContext ) crdApply (resource string ) error {
284- apiExtensionsV1Client := c .newApiExtensionsClient ()
285- var crd = & apiextensionsv1spec.CustomResourceDefinition {}
286- err := json .Unmarshal ([]byte (resource ), crd )
287- if err != nil {
288- return fmt .Errorf ("failed to create CRD %v" , err )
289- }
290- _ , err = apiExtensionsV1Client .CustomResourceDefinitions ().Create (c .ctx , crd , metav1.CreateOptions {})
291- if err != nil {
292- return fmt .Errorf ("failed to create CRD %v" , err )
293- }
294- c .crdWaitUntilReady (crd .Name )
295- return nil
296- }
297-
298- // crdDelete deletes a CRD by name and waits for it to be removed
299- func (c * mcpContext ) crdDelete (name string ) error {
300- apiExtensionsV1Client := c .newApiExtensionsClient ()
301- err := apiExtensionsV1Client .CustomResourceDefinitions ().Delete (c .ctx , name , metav1.DeleteOptions {
302- GracePeriodSeconds : ptr .To (int64 (0 )),
303- })
304- iteration := 0
305- for iteration < 100 {
306- if _ , derr := apiExtensionsV1Client .CustomResourceDefinitions ().Get (c .ctx , name , metav1.GetOptions {}); derr != nil {
307- break
308- }
309- time .Sleep (5 * time .Millisecond )
310- iteration ++
311- }
312- if err != nil {
313- return errors .Wrap (err , "failed to delete CRD" )
314- }
315- return nil
316- }
317-
318- // crdWaitUntilReady waits for a CRD to be established
319- func (c * mcpContext ) crdWaitUntilReady (name string ) {
320- watcher , err := c .newApiExtensionsClient ().CustomResourceDefinitions ().Watch (c .ctx , metav1.ListOptions {
321- FieldSelector : "metadata.name=" + name ,
322- })
323- if err != nil {
324- panic (fmt .Errorf ("failed to watch CRD %v" , err ))
325- }
326- _ , err = toolswatch .UntilWithoutRetry (c .ctx , watcher , func (event watch.Event ) (bool , error ) {
327- for _ , c := range event .Object .(* apiextensionsv1spec.CustomResourceDefinition ).Status .Conditions {
328- if c .Type == apiextensionsv1spec .Established && c .Status == apiextensionsv1spec .ConditionTrue {
329- return true , nil
330- }
331- }
332- return false , nil
333- })
334- if err != nil {
335- panic (fmt .Errorf ("failed to wait for CRD %v" , err ))
336- }
337- }
338-
339225// callTool helper function to call a tool by name with arguments
340226func (c * mcpContext ) callTool (name string , args map [string ]interface {}) (* mcp.CallToolResult , error ) {
341227 callToolRequest := mcp.CallToolRequest {}
@@ -446,20 +332,97 @@ func (s *BaseMcpSuite) InitMcpClient(options ...transport.StreamableHTTPCOption)
446332 s .McpClient = test .NewMcpClient (s .T (), s .mcpServer .ServeHTTP (nil ), options ... )
447333}
448334
449- // CrdWaitUntilReady waits for a CRD to be established
450- func (s * BaseMcpSuite ) CrdWaitUntilReady (name string ) {
335+ // EnvTestInOpenShift sets up the kubernetes environment to seem to be running OpenShift
336+ func EnvTestInOpenShift (ctx context.Context ) error {
337+ crdTemplate := `
338+ {
339+ "apiVersion": "apiextensions.k8s.io/v1",
340+ "kind": "CustomResourceDefinition",
341+ "metadata": {"name": "%s"},
342+ "spec": {
343+ "group": "%s",
344+ "versions": [{
345+ "name": "v1","served": true,"storage": true,
346+ "schema": {"openAPIV3Schema": {"type": "object","x-kubernetes-preserve-unknown-fields": true}}
347+ }],
348+ "scope": "%s",
349+ "names": {"plural": "%s","singular": "%s","kind": "%s"}
350+ }
351+ }`
352+ tasks , _ := errgroup .WithContext (ctx )
353+ tasks .Go (func () error {
354+ return EnvTestCrdApply (ctx , fmt .Sprintf (crdTemplate , "projects.project.openshift.io" , "project.openshift.io" ,
355+ "Cluster" , "projects" , "project" , "Project" ))
356+ })
357+ tasks .Go (func () error {
358+ return EnvTestCrdApply (ctx , fmt .Sprintf (crdTemplate , "routes.route.openshift.io" , "route.openshift.io" ,
359+ "Namespaced" , "routes" , "route" , "Route" ))
360+ })
361+ return tasks .Wait ()
362+ }
363+
364+ // EnvTestInOpenShiftClear clears the kubernetes environment so it no longer seems to be running OpenShift
365+ func EnvTestInOpenShiftClear (ctx context.Context ) error {
366+ tasks , _ := errgroup .WithContext (ctx )
367+ tasks .Go (func () error { return EnvTestCrdDelete (ctx , "projects.project.openshift.io" ) })
368+ tasks .Go (func () error { return EnvTestCrdDelete (ctx , "routes.route.openshift.io" ) })
369+ return tasks .Wait ()
370+ }
371+
372+ // EnvTestCrdWaitUntilReady waits for a CRD to be established
373+ func EnvTestCrdWaitUntilReady (ctx context.Context , name string ) error {
451374 apiExtensionClient := apiextensionsv1 .NewForConfigOrDie (envTestRestConfig )
452- watcher , err := apiExtensionClient .CustomResourceDefinitions ().Watch (s . T (). Context () , metav1.ListOptions {
375+ watcher , err := apiExtensionClient .CustomResourceDefinitions ().Watch (ctx , metav1.ListOptions {
453376 FieldSelector : "metadata.name=" + name ,
454377 })
455- s .Require ().NoError (err , "failed to watch CRD" )
456- _ , err = toolswatch .UntilWithoutRetry (s .T ().Context (), watcher , func (event watch.Event ) (bool , error ) {
378+ if err != nil {
379+ return fmt .Errorf ("unable to watch CRDs: %w" , err )
380+ }
381+ _ , err = toolswatch .UntilWithoutRetry (ctx , watcher , func (event watch.Event ) (bool , error ) {
457382 for _ , c := range event .Object .(* apiextensionsv1spec.CustomResourceDefinition ).Status .Conditions {
458383 if c .Type == apiextensionsv1spec .Established && c .Status == apiextensionsv1spec .ConditionTrue {
459384 return true , nil
460385 }
461386 }
462387 return false , nil
463388 })
464- s .Require ().NoError (err , "failed to wait for CRD" )
389+ if err != nil {
390+ return fmt .Errorf ("failed to wait for CRD: %w" , err )
391+ }
392+ return nil
393+ }
394+
395+ // EnvTestCrdApply creates a CRD from the provided resource string and waits for it to be established
396+ func EnvTestCrdApply (ctx context.Context , resource string ) error {
397+ apiExtensionsV1Client := apiextensionsv1 .NewForConfigOrDie (envTestRestConfig )
398+ var crd = & apiextensionsv1spec.CustomResourceDefinition {}
399+ err := json .Unmarshal ([]byte (resource ), crd )
400+ if err != nil {
401+ return fmt .Errorf ("failed to create CRD %v" , err )
402+ }
403+ _ , err = apiExtensionsV1Client .CustomResourceDefinitions ().Create (ctx , crd , metav1.CreateOptions {})
404+ if err != nil {
405+ return fmt .Errorf ("failed to create CRD %v" , err )
406+ }
407+ return EnvTestCrdWaitUntilReady (ctx , crd .Name )
408+ }
409+
410+ // crdDelete deletes a CRD by name and waits for it to be removed
411+ func EnvTestCrdDelete (ctx context.Context , name string ) error {
412+ apiExtensionsV1Client := apiextensionsv1 .NewForConfigOrDie (envTestRestConfig )
413+ err := apiExtensionsV1Client .CustomResourceDefinitions ().Delete (ctx , name , metav1.DeleteOptions {
414+ GracePeriodSeconds : ptr .To (int64 (0 )),
415+ })
416+ iteration := 0
417+ for iteration < 100 {
418+ if _ , derr := apiExtensionsV1Client .CustomResourceDefinitions ().Get (ctx , name , metav1.GetOptions {}); derr != nil {
419+ break
420+ }
421+ time .Sleep (5 * time .Millisecond )
422+ iteration ++
423+ }
424+ if err != nil {
425+ return errors .Wrap (err , "failed to delete CRD" )
426+ }
427+ return nil
465428}
0 commit comments