Skip to content

Commit

Permalink
refactor: codeflare sdk unit tests
Browse files Browse the repository at this point in the history
sort unit tests into individual files and made minor enhancements
  • Loading branch information
Bobbins228 committed Oct 8, 2024
1 parent 73b8cb7 commit e45ee2d
Show file tree
Hide file tree
Showing 27 changed files with 3,451 additions and 3,573 deletions.
166 changes: 166 additions & 0 deletions src/codeflare_sdk/common/kubernetes_cluster/auth_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Copyright 2024 IBM, Red Hat
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from codeflare_sdk.common.kubernetes_cluster import (
Authentication,
KubeConfigFileAuthentication,
TokenAuthentication,
config_check,
)
from kubernetes import client, config
import os
from pathlib import Path
import pytest

parent = Path(__file__).resolve().parents[4] # project directory


def test_token_auth_creation():
try:
token_auth = TokenAuthentication(token="token", server="server")
assert token_auth.token == "token"
assert token_auth.server == "server"
assert token_auth.skip_tls == False
assert token_auth.ca_cert_path == None

token_auth = TokenAuthentication(token="token", server="server", skip_tls=True)
assert token_auth.token == "token"
assert token_auth.server == "server"
assert token_auth.skip_tls == True
assert token_auth.ca_cert_path == None

os.environ["CF_SDK_CA_CERT_PATH"] = "/etc/pki/tls/custom-certs/ca-bundle.crt"
token_auth = TokenAuthentication(token="token", server="server", skip_tls=False)
assert token_auth.token == "token"
assert token_auth.server == "server"
assert token_auth.skip_tls == False
assert token_auth.ca_cert_path == "/etc/pki/tls/custom-certs/ca-bundle.crt"
os.environ.pop("CF_SDK_CA_CERT_PATH")

token_auth = TokenAuthentication(
token="token",
server="server",
skip_tls=False,
ca_cert_path=f"{parent}/tests/auth-test.crt",
)
assert token_auth.token == "token"
assert token_auth.server == "server"
assert token_auth.skip_tls == False
assert token_auth.ca_cert_path == f"{parent}/tests/auth-test.crt"

except Exception:
assert 0 == 1


def test_token_auth_login_logout(mocker):
mocker.patch.object(client, "ApiClient")

token_auth = TokenAuthentication(
token="testtoken", server="testserver:6443", skip_tls=False, ca_cert_path=None
)
assert token_auth.login() == ("Logged into testserver:6443")
assert token_auth.logout() == ("Successfully logged out of testserver:6443")


def test_token_auth_login_tls(mocker):
mocker.patch.object(client, "ApiClient")

token_auth = TokenAuthentication(
token="testtoken", server="testserver:6443", skip_tls=True, ca_cert_path=None
)
assert token_auth.login() == ("Logged into testserver:6443")
token_auth = TokenAuthentication(
token="testtoken", server="testserver:6443", skip_tls=False, ca_cert_path=None
)
assert token_auth.login() == ("Logged into testserver:6443")
token_auth = TokenAuthentication(
token="testtoken",
server="testserver:6443",
skip_tls=False,
ca_cert_path=f"{parent}/tests/auth-test.crt",
)
assert token_auth.login() == ("Logged into testserver:6443")

os.environ["CF_SDK_CA_CERT_PATH"] = f"{parent}/tests/auth-test.crt"
token_auth = TokenAuthentication(
token="testtoken",
server="testserver:6443",
skip_tls=False,
)
assert token_auth.login() == ("Logged into testserver:6443")


def test_config_check_no_config_file(mocker):
mocker.patch("os.path.expanduser", return_value="/mock/home/directory")
mocker.patch("os.path.isfile", return_value=False)
mocker.patch("codeflare_sdk.common.kubernetes_cluster.auth.config_path", None)
mocker.patch("codeflare_sdk.common.kubernetes_cluster.auth.api_client", None)

with pytest.raises(PermissionError):
config_check()


def test_config_check_with_incluster_config(mocker):
mocker.patch("os.path.expanduser", return_value="/mock/home/directory")
mocker.patch("os.path.isfile", return_value=False)
mocker.patch.dict(os.environ, {"KUBERNETES_PORT": "number"})
mocker.patch("kubernetes.config.load_incluster_config", side_effect=None)
mocker.patch("codeflare_sdk.common.kubernetes_cluster.auth.config_path", None)
mocker.patch("codeflare_sdk.common.kubernetes_cluster.auth.api_client", None)

result = config_check()
assert result == None


def test_config_check_with_existing_config_file(mocker):
mocker.patch("os.path.expanduser", return_value="/mock/home/directory")
mocker.patch("os.path.isfile", return_value=True)
mocker.patch("kubernetes.config.load_kube_config", side_effect=None)
mocker.patch("codeflare_sdk.common.kubernetes_cluster.auth.config_path", None)
mocker.patch("codeflare_sdk.common.kubernetes_cluster.auth.api_client", None)

result = config_check()
assert result == None


def test_config_check_with_config_path_and_no_api_client(mocker):
mocker.patch(
"codeflare_sdk.common.kubernetes_cluster.auth.config_path", "/mock/config/path"
)
mocker.patch("codeflare_sdk.common.kubernetes_cluster.auth.api_client", None)
result = config_check()
assert result == "/mock/config/path"


def test_load_kube_config(mocker):
mocker.patch.object(config, "load_kube_config")
kube_config_auth = KubeConfigFileAuthentication(
kube_config_path="/path/to/your/config"
)
response = kube_config_auth.load_kube_config()

assert (
response
== "Loaded user config file at path %s" % kube_config_auth.kube_config_path
)

kube_config_auth = KubeConfigFileAuthentication(kube_config_path=None)
response = kube_config_auth.load_kube_config()
assert response == "Please specify a config file path"


def test_auth_coverage():
abstract = Authentication()
abstract.login()
abstract.logout()
137 changes: 137 additions & 0 deletions src/codeflare_sdk/common/kueue/kueue_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Copyright 2024 IBM, Red Hat
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ..utils.unit_test_support import get_local_queue, createClusterConfig
from unittest.mock import patch
from codeflare_sdk.ray.cluster.cluster import Cluster, ClusterConfiguration
import yaml
import os
import filecmp
from pathlib import Path

parent = Path(__file__).resolve().parents[4] # project directory
aw_dir = os.path.expanduser("~/.codeflare/resources/")


def test_none_local_queue(mocker):
mocker.patch("kubernetes.client.CustomObjectsApi.list_namespaced_custom_object")
config = ClusterConfiguration(name="unit-test-aw-kueue", namespace="ns")
config.name = "unit-test-aw-kueue"
config.local_queue = None

cluster = Cluster(config)
assert cluster.config.local_queue == None


def test_cluster_creation_no_aw_local_queue(mocker):
# With written resources
# Create Ray Cluster with local queue specified
mocker.patch("kubernetes.client.ApisApi.get_api_versions")
mocker.patch(
"kubernetes.client.CustomObjectsApi.get_cluster_custom_object",
return_value={"spec": {"domain": "apps.cluster.awsroute.org"}},
)
mocker.patch(
"kubernetes.client.CustomObjectsApi.list_namespaced_custom_object",
return_value=get_local_queue("kueue.x-k8s.io", "v1beta1", "ns", "localqueues"),
)
config = createClusterConfig()
config.name = "unit-test-cluster-kueue"
config.write_to_file = True
config.local_queue = "local-queue-default"
cluster = Cluster(config)
assert cluster.app_wrapper_yaml == f"{aw_dir}unit-test-cluster-kueue.yaml"
assert cluster.app_wrapper_name == "unit-test-cluster-kueue"
assert filecmp.cmp(
f"{aw_dir}unit-test-cluster-kueue.yaml",
f"{parent}/tests/test_cluster_yamls/kueue/ray_cluster_kueue.yaml",
shallow=True,
)

# With resources loaded in memory, no Local Queue specified.
config = createClusterConfig()
config.name = "unit-test-cluster-kueue"
config.write_to_file = False
cluster = Cluster(config)

test_rc = yaml.load(cluster.app_wrapper_yaml, Loader=yaml.FullLoader)
with open(f"{parent}/tests/test_cluster_yamls/kueue/ray_cluster_kueue.yaml") as f:
expected_rc = yaml.load(f, Loader=yaml.FullLoader)
assert test_rc == expected_rc


def test_aw_creation_local_queue(mocker):
mocker.patch("kubernetes.client.ApisApi.get_api_versions")
mocker.patch(
"kubernetes.client.CustomObjectsApi.get_cluster_custom_object",
return_value={"spec": {"domain": "apps.cluster.awsroute.org"}},
)
mocker.patch(
"kubernetes.client.CustomObjectsApi.list_namespaced_custom_object",
return_value=get_local_queue("kueue.x-k8s.io", "v1beta1", "ns", "localqueues"),
)
config = createClusterConfig()
config.name = "unit-test-aw-kueue"
config.appwrapper = True
config.write_to_file = True
config.local_queue = "local-queue-default"
cluster = Cluster(config)
assert cluster.app_wrapper_yaml == f"{aw_dir}unit-test-aw-kueue.yaml"
assert cluster.app_wrapper_name == "unit-test-aw-kueue"
assert filecmp.cmp(
f"{aw_dir}unit-test-aw-kueue.yaml",
f"{parent}/tests/test_cluster_yamls/kueue/aw_kueue.yaml",
shallow=True,
)

# With resources loaded in memory, no Local Queue specified.
config = createClusterConfig()
config.name = "unit-test-aw-kueue"
config.appwrapper = True
config.write_to_file = False
cluster = Cluster(config)

test_rc = yaml.load(cluster.app_wrapper_yaml, Loader=yaml.FullLoader)
with open(f"{parent}/tests/test_cluster_yamls/kueue/aw_kueue.yaml") as f:
expected_rc = yaml.load(f, Loader=yaml.FullLoader)
assert test_rc == expected_rc


def test_get_local_queue_exists_fail(mocker):
mocker.patch("kubernetes.client.ApisApi.get_api_versions")
mocker.patch(
"kubernetes.client.CustomObjectsApi.get_cluster_custom_object",
return_value={"spec": {"domain": "apps.cluster.awsroute.org"}},
)
mocker.patch(
"kubernetes.client.CustomObjectsApi.list_namespaced_custom_object",
return_value=get_local_queue("kueue.x-k8s.io", "v1beta1", "ns", "localqueues"),
)
config = createClusterConfig()
config.name = "unit-test-aw-kueue"
config.appwrapper = True
config.write_to_file = True
config.local_queue = "local_queue_doesn't_exist"
try:
Cluster(config)
except ValueError as e:
assert (
str(e)
== "local_queue provided does not exist or is not in this namespace. Please provide the correct local_queue name in Cluster Configuration"
)


# Make sure to always keep this function last
def test_cleanup():
os.remove(f"{aw_dir}unit-test-cluster-kueue.yaml")
os.remove(f"{aw_dir}unit-test-aw-kueue.yaml")
Loading

0 comments on commit e45ee2d

Please sign in to comment.