# Path: libcloudforensics/providers/kubernetes/base.py
# class K8sClient(metaclass=abc.ABCMeta):
# class K8sResource(K8sClient, metaclass=abc.ABCMeta):
# class K8sNamespacedResource(K8sResource, metaclass=abc.ABCMeta):
# class K8sNode(K8sResource):
# class K8sWorkload(K8sNamespacedResource):
# class K8sPod(K8sWorkload):
#   T = TypeVar('T')
#   def __init__(self, api_client: client.ApiClient) -> None:
#   def _Api(self, api_class: Callable[[client.ApiClient], T]) -> T:
#   def __init__(self, api_client: client.ApiClient, name: str) -> None:
#   def Read(self) -> object:
#   def __init__(
#       self, api_client: client.ApiClient, name: str, namespace: str) -> None:
#   def Delete(self, cascade: bool = True) -> None:
#   def Read(self) -> client.V1Node:
#   def Cordon(self) -> None:
#   def Drain(self, pod_filter: Callable[['K8sPod'], bool]) -> None:
#   def ListPods(self, namespace: Optional[str] = None) -> List['K8sPod']:
#   def ExternalIps(self) -> List[str]:
#   def InternalIps(self) -> List[str]:
#   def GetCoveredPods(self) -> List['K8sPod']:
#   def GetCoveredNodes(self) -> List[K8sNode]:
#   def IsCoveringPod(self, pod: 'K8sPod') -> bool:
#   def gcp_protopayload_methodname(self) -> str:
#   def GcpClusterLogsQuerySupplement(self) -> str:
#   def GcpContainerLogsQuerySupplement(self) -> str:
#   def OrphanPods(self) -> None:
#   def gcp_protopayload_methodname(self) -> str:
#   def GcpContainerLogsQuerySupplement(self) -> str:
#   def OrphanPods(self) -> None:
#   def GetCoveredPods(self) -> List['K8sPod']:
#   def IsCoveringPod(self, pod: 'K8sPod') -> bool:
#   def Read(self) -> client.V1Pod:
#   def GetNode(self) -> K8sNode:
#   def ListContainers(self) -> List[container.K8sContainer]:
#   def ListVolumes(self) -> List[volume.K8sVolume]:
#   def GetLabels(self) -> Dict[str, str]:
#   def Delete(self, cascade: bool = True) -> None:
#   def AddLabels(self, labels: Dict[str, str]) -> None:
# 
# Path: tests/providers/kubernetes/k8s_mocks.py
# MOCK_API_CLIENT = mock.Mock()
# def V1ObjectMeta(
#     name: Optional[str] = None,
#     namespace: Optional[str] = None,
#     labels: Optional[Labels] = None) -> client.V1ObjectMeta:
# def V1NodeList(amount: int) -> client.V1NodeList:
# def V1PodList(amount: int) -> client.V1PodList:
# def V1NetworkPolicyList(
#     amount: int, namespace: str) -> client.V1NetworkPolicyList:
# def V1NetworkPolicy(name: str, namespace: str) -> client.V1NetworkPolicy:
# def V1Service(selector_labels: Labels) -> client.V1Service:
# def V1Node(name: str) -> client.V1Node:
# def V1Pod(
#     name: Optional[str] = None,
#     namespace: Optional[str] = None,
#     node_name: Optional[str] = None,
#     labels: Optional[Labels] = None) -> client.V1Pod:
# def V1PodTemplateSpec(labels: Labels) -> client.V1PodTemplateSpec:
# def V1ReplicaSet(
#     name: Optional[str] = None,
#     namespace: Optional[str] = None,
#     template_spec_labels: Optional[Labels] = None) -> client.V1ReplicaSet:
# def V1Deployment(
#     name: Optional[str] = None,
#     namespace: Optional[str] = None,
#     template_spec_labels: Optional[Labels] = None,
#     match_labels: Optional[Labels] = None) -> client.V1Deployment:


import typing
import unittest
import mock
import libcloudforensics.providers.kubernetes.cluster as k8s_cluster
from kubernetes import client
from libcloudforensics.providers.kubernetes import base
from tests.providers.kubernetes import k8s_mocks
    mock_k8s_api_func.return_value = mock_pods

    pods = base.K8sNode(k8s_mocks.MOCK_API_CLIENT, 'fake-node-name').ListPods()

    # Assert API and corresponding function was called appropriately
    mock_k8s_api.assert_called_with(k8s_mocks.MOCK_API_CLIENT)
    mock_k8s_api_func.assert_called()
    kwargs = mock_k8s_api_func.call_args.kwargs
    self.assertIn('field_selector', kwargs)
    self.assertIn('fake-node-name', kwargs['field_selector'])
    # Assert returned pods correspond to provided response
    self.assertEqual(
        set(pod.name for pod in pods),
        set(pod.metadata.name for pod in mock_pods.items))


class K8sPodTest(unittest.TestCase):
  """Test K8sPod functionality, mainly checking API calls."""

  @typing.no_type_check
  @mock.patch('kubernetes.client.CoreV1Api')
  def testPodGetNode(self, mock_k8s_api):
    """Test that the returned node of a pod is correct."""
    mock_pod = k8s_mocks.V1Pod(
        name='fake-pod-name',
        namespace='fake-namespace',
        node_name='fake-node-name')
    mock_k8s_api_func = mock_k8s_api.return_value.read_namespaced_pod
    mock_k8s_api_func.return_value = mock_pod


# Path: libcloudforensics/providers/kubernetes/base.py
# class K8sClient(metaclass=abc.ABCMeta):
# class K8sResource(K8sClient, metaclass=abc.ABCMeta):
# class K8sNamespacedResource(K8sResource, metaclass=abc.ABCMeta):
# class K8sNode(K8sResource):
# class K8sWorkload(K8sNamespacedResource):
# class K8sPod(K8sWorkload):
#   T = TypeVar('T')
#   def __init__(self, api_client: client.ApiClient) -> None:
#   def _Api(self, api_class: Callable[[client.ApiClient], T]) -> T:
#   def __init__(self, api_client: client.ApiClient, name: str) -> None:
#   def Read(self) -> object:
#   def __init__(
#       self, api_client: client.ApiClient, name: str, namespace: str) -> None:
#   def Delete(self, cascade: bool = True) -> None:
#   def Read(self) -> client.V1Node:
#   def Cordon(self) -> None:
#   def Drain(self, pod_filter: Callable[['K8sPod'], bool]) -> None:
#   def ListPods(self, namespace: Optional[str] = None) -> List['K8sPod']:
#   def ExternalIps(self) -> List[str]:
#   def InternalIps(self) -> List[str]:
#   def GetCoveredPods(self) -> List['K8sPod']:
#   def GetCoveredNodes(self) -> List[K8sNode]:
#   def IsCoveringPod(self, pod: 'K8sPod') -> bool:
#   def gcp_protopayload_methodname(self) -> str:
#   def GcpClusterLogsQuerySupplement(self) -> str:
#   def GcpContainerLogsQuerySupplement(self) -> str:
#   def OrphanPods(self) -> None:
#   def gcp_protopayload_methodname(self) -> str:
#   def GcpContainerLogsQuerySupplement(self) -> str:
#   def OrphanPods(self) -> None:
#   def GetCoveredPods(self) -> List['K8sPod']:
#   def IsCoveringPod(self, pod: 'K8sPod') -> bool:
#   def Read(self) -> client.V1Pod:
#   def GetNode(self) -> K8sNode:
#   def ListContainers(self) -> List[container.K8sContainer]:
#   def ListVolumes(self) -> List[volume.K8sVolume]:
#   def GetLabels(self) -> Dict[str, str]:
#   def Delete(self, cascade: bool = True) -> None:
#   def AddLabels(self, labels: Dict[str, str]) -> None:
# 
# Path: tests/providers/kubernetes/k8s_mocks.py
# MOCK_API_CLIENT = mock.Mock()
# def V1ObjectMeta(
#     name: Optional[str] = None,
#     namespace: Optional[str] = None,
#     labels: Optional[Labels] = None) -> client.V1ObjectMeta:
# def V1NodeList(amount: int) -> client.V1NodeList:
# def V1PodList(amount: int) -> client.V1PodList:
# def V1NetworkPolicyList(
#     amount: int, namespace: str) -> client.V1NetworkPolicyList:
# def V1NetworkPolicy(name: str, namespace: str) -> client.V1NetworkPolicy:
# def V1Service(selector_labels: Labels) -> client.V1Service:
# def V1Node(name: str) -> client.V1Node:
# def V1Pod(
#     name: Optional[str] = None,
#     namespace: Optional[str] = None,
#     node_name: Optional[str] = None,
#     labels: Optional[Labels] = None) -> client.V1Pod:
# def V1PodTemplateSpec(labels: Labels) -> client.V1PodTemplateSpec:
# def V1ReplicaSet(
#     name: Optional[str] = None,
#     namespace: Optional[str] = None,
#     template_spec_labels: Optional[Labels] = None) -> client.V1ReplicaSet:
# def V1Deployment(
#     name: Optional[str] = None,
#     namespace: Optional[str] = None,
#     template_spec_labels: Optional[Labels] = None,
#     match_labels: Optional[Labels] = None) -> client.V1Deployment:


# Path: tests/providers/kubernetes/test_base.py
import typing
import unittest
import mock
import libcloudforensics.providers.kubernetes.cluster as k8s_cluster
from kubernetes import client
from libcloudforensics.providers.kubernetes import base
from tests.providers.kubernetes import k8s_mocks

    mock_k8s_api_func.return_value = mock_pods

    pods = base.K8sNode(k8s_mocks.MOCK_API_CLIENT, 'fake-node-name').ListPods()

    # Assert API and corresponding function was called appropriately
    mock_k8s_api.assert_called_with(k8s_mocks.MOCK_API_CLIENT)
    mock_k8s_api_func.assert_called()
    kwargs = mock_k8s_api_func.call_args.kwargs
    self.assertIn('field_selector', kwargs)
    self.assertIn('fake-node-name', kwargs['field_selector'])
    # Assert returned pods correspond to provided response
    self.assertEqual(
        set(pod.name for pod in pods),
        set(pod.metadata.name for pod in mock_pods.items))


class K8sPodTest(unittest.TestCase):
  """Test K8sPod functionality, mainly checking API calls."""

  @typing.no_type_check
  @mock.patch('kubernetes.client.CoreV1Api')
  def testPodGetNode(self, mock_k8s_api):
    """Test that the returned node of a pod is correct."""
    mock_pod = k8s_mocks.V1Pod(
        name='fake-pod-name',
        namespace='fake-namespace',
        node_name='fake-node-name')
    mock_k8s_api_func = mock_k8s_api.return_value.read_namespaced_pod
    mock_k8s_api_func.return_value = mock_pod


    node = base.K8sPod(