@@ -608,6 +608,140 @@ def test_create_from_list_in_multi_resource_yaml_namespaced(self):
608608 app_api .delete_namespaced_deployment (
609609 name = "mock" , namespace = self .test_namespace , body = {})
610610
611+ def test_get_metrics_from_cluster (self ):
612+ """
613+ Should be able to fetch node and pod metrics from the cluster.
614+ This test requires metrics-server to be installed in the cluster.
615+ """
616+ k8s_client = client .api_client .ApiClient (configuration = self .config )
617+ core_api = client .CoreV1Api (k8s_client )
618+
619+ # Create a test pod for metrics
620+ utils .create_from_yaml (
621+ k8s_client , self .path_prefix + "core-pod.yaml" ,
622+ namespace = self .test_namespace )
623+
624+ # Wait for pod to be running (with timeout)
625+ import time
626+ max_wait = 60
627+ waited = 0
628+ pod_running = False
629+ while waited < max_wait :
630+ try :
631+ pod = core_api .read_namespaced_pod (
632+ name = "myapp-pod" , namespace = self .test_namespace )
633+ if pod .status .phase == "Running" :
634+ pod_running = True
635+ break
636+ except ApiException :
637+ pass
638+ time .sleep (2 )
639+ waited += 2
640+
641+ # Skip test if pod didn't start (cluster might be slow)
642+ if not pod_running :
643+ core_api .delete_namespaced_pod (
644+ name = "myapp-pod" , namespace = self .test_namespace , body = {})
645+ raise unittest .SkipTest ("Pod did not reach Running state in time" )
646+
647+ # Wait a bit more for metrics to be available
648+ time .sleep (10 )
649+
650+ # Test node metrics retrieval
651+ try :
652+ node_metrics = utils .get_nodes_metrics (k8s_client )
653+ self .assertIsNotNone (node_metrics )
654+ self .assertEqual (node_metrics ['kind' ], 'NodeMetricsList' )
655+ self .assertIn ('items' , node_metrics )
656+ # We should have at least one node in the cluster
657+ self .assertGreater (len (node_metrics ['items' ]), 0 )
658+ # Check structure of first node metric
659+ if len (node_metrics ['items' ]) > 0 :
660+ node = node_metrics ['items' ][0 ]
661+ self .assertIn ('metadata' , node )
662+ self .assertIn ('name' , node ['metadata' ])
663+ self .assertIn ('usage' , node )
664+ self .assertIn ('cpu' , node ['usage' ])
665+ self .assertIn ('memory' , node ['usage' ])
666+ except ApiException as e :
667+ # If metrics-server is not installed, skip this test
668+ if e .status == 404 :
669+ core_api .delete_namespaced_pod (
670+ name = "myapp-pod" , namespace = self .test_namespace , body = {})
671+ raise unittest .SkipTest ("Metrics server not available in cluster" )
672+ raise
673+
674+ # Test pod metrics retrieval
675+ try :
676+ pod_metrics = utils .get_pods_metrics (
677+ k8s_client , self .test_namespace )
678+ self .assertIsNotNone (pod_metrics )
679+ self .assertEqual (pod_metrics ['kind' ], 'PodMetricsList' )
680+ self .assertIn ('items' , pod_metrics )
681+ # We should have our test pod
682+ self .assertGreater (len (pod_metrics ['items' ]), 0 )
683+ # Check structure of pod metrics
684+ found_test_pod = False
685+ for pod in pod_metrics ['items' ]:
686+ if pod ['metadata' ]['name' ] == 'myapp-pod' :
687+ found_test_pod = True
688+ self .assertIn ('containers' , pod )
689+ self .assertGreater (len (pod ['containers' ]), 0 )
690+ container = pod ['containers' ][0 ]
691+ self .assertIn ('name' , container )
692+ self .assertIn ('usage' , container )
693+ self .assertIn ('cpu' , container ['usage' ])
694+ self .assertIn ('memory' , container ['usage' ])
695+ # Our test pod should appear in metrics
696+ self .assertTrue (found_test_pod , "Test pod not found in metrics" )
697+ except ApiException as e :
698+ if e .status == 404 :
699+ core_api .delete_namespaced_pod (
700+ name = "myapp-pod" , namespace = self .test_namespace , body = {})
701+ raise unittest .SkipTest ("Metrics server not available in cluster" )
702+ raise
703+
704+ # Test pod metrics with label selector
705+ try :
706+ filtered_metrics = utils .get_pods_metrics (
707+ k8s_client , self .test_namespace , label_selector = 'app=myapp' )
708+ self .assertIsNotNone (filtered_metrics )
709+ self .assertEqual (filtered_metrics ['kind' ], 'PodMetricsList' )
710+ self .assertIn ('items' , filtered_metrics )
711+ # Should have our pod with the matching label
712+ self .assertGreater (len (filtered_metrics ['items' ]), 0 )
713+ for pod in filtered_metrics ['items' ]:
714+ # All returned pods should have the label we filtered for
715+ self .assertEqual (pod ['metadata' ]['name' ], 'myapp-pod' )
716+ except ApiException as e :
717+ if e .status == 404 :
718+ core_api .delete_namespaced_pod (
719+ name = "myapp-pod" , namespace = self .test_namespace , body = {})
720+ raise unittest .SkipTest ("Metrics server not available in cluster" )
721+ raise
722+
723+ # Test multi-namespace metrics collection
724+ try :
725+ multi_ns_metrics = utils .get_pods_metrics_in_all_namespaces (
726+ k8s_client , [self .test_namespace , 'default' ])
727+ self .assertIsNotNone (multi_ns_metrics )
728+ self .assertIn (self .test_namespace , multi_ns_metrics )
729+ self .assertIn ('default' , multi_ns_metrics )
730+ # Our test namespace should have metrics
731+ test_ns_result = multi_ns_metrics [self .test_namespace ]
732+ self .assertNotIn ('error' , test_ns_result )
733+ self .assertEqual (test_ns_result ['kind' ], 'PodMetricsList' )
734+ except ApiException as e :
735+ if e .status == 404 :
736+ core_api .delete_namespaced_pod (
737+ name = "myapp-pod" , namespace = self .test_namespace , body = {})
738+ raise unittest .SkipTest ("Metrics server not available in cluster" )
739+ raise
740+
741+ # Cleanup
742+ core_api .delete_namespaced_pod (
743+ name = "myapp-pod" , namespace = self .test_namespace , body = {})
744+
611745
612746class TestUtilsUnitTests (unittest .TestCase ):
613747
0 commit comments