diff --git a/test/pytest.ini b/test/pytest.ini index b9b8c12e4781334b10deeb3c748cc42a38a40d64..a32f20b33542a3888e4887864e4f5556700e5383 100644 --- a/test/pytest.ini +++ b/test/pytest.ini @@ -1,13 +1,13 @@ [pytest] # Register custom markers, see https://docs.pytest.org/en/latest/mark.html markers = - app: Run all tests for a specific app (apps_running, certs, helmreleases) + app: Run all tests for a specific app certs: Run tests related to TLS certificates testinfra: Run testinfra tests (test OS/package versions etc) prometheus: Test prometheus helmreleases: Test deployed helmreleases installed by flux kustomizations: Test that flux kustomizations are ready - apps_running: Test if all the pods for the helmreleases are running + deployments: Test if all deployments are ready dns: Check if cluster domain resolves at all nameservers # https://docs.pytest.org/en/latest/warnings.html diff --git a/test/pytest/test_app_deployments.py b/test/pytest/test_app_deployments.py index 5f38162254915a04adf595f9841754770615b9fe..7ddf634e43d561d04601f9b524fc9fda789b74ef 100644 --- a/test/pytest/test_app_deployments.py +++ b/test/pytest/test_app_deployments.py @@ -3,7 +3,7 @@ This module contains tests for: - test_kustomizations: Test if all kustomizations are ready - test_helmreleases: Test if all the helmreleases are ready -- test_apps_running: Test if all deployments are ready +- test_deployments: Test if all deployments are ready Documentation for the kubernetes client: * https://github.com/kubernetes-client/python/blob/master/kubernetes/README.md @@ -15,57 +15,33 @@ from kubernetes.client.rest import ApiException import pytest +# Helper functions -def get_kustomization_status(api, name, namespace='flux-system'): - """Returns status contition for kustomization `name` in `namespace`""" - print('Testing kustomization %s in namespace %s ...' % (name, namespace), end='') +def get_resource_status(api, api_group, api_version, plural, name, namespace='flux-system'): + """Returns status contition for resource in given namespace""" + print(f'Resource {name} in namespace {namespace} ' + f'api version: {api_group}/{api_version}): ', end='') try: - kustomization = api.get_namespaced_custom_object( - group="kustomize.toolkit.fluxcd.io", - version="v1beta1", - plural="kustomizations", + resource = api.get_namespaced_custom_object( + group=api_group, + version=api_version, + plural=plural, name=name, namespace=namespace ) - ks_status = kustomization['status']['conditions'][0]['status'] - print(ks_status) + status = resource['status']['conditions'][0]['status'] + print(status) except ApiException as ex: if ex.status == 404: - ks_status = 'Not found' + status = 'Not found' else: raise - print(f"**** NOT DEPLOYED, status: {ks_status} *****") + print(f"**** NOT ready, status: {status} *****") except KeyError: - ks_status = 'Key error' - print("Kustomization key error: ") - print(kustomization) - return ks_status - -def get_release_status(api, name, namespace): - """Returns release status for release `name` in `namespace`""" - print('Testing helmrelease %s in namespace %s ...' % (name, namespace), end='') - try: - release = api.get_namespaced_custom_object( - group="helm.toolkit.fluxcd.io", - version="v2beta1", - plural="helmreleases", - name=name, - namespace=namespace - ) - # print(release['status']) - release_status = release['status']['conditions'][0]['status'] - print(release_status) - except ApiException as ex: - if ex.status == 404: - release_status = 'not found' - else: - raise - print(f'**** NOT DEPLOYED, status: "{release_status}" *****') - except KeyError: - release_status = 'Key error' - print("HelmRelease key error: ") - print(release) - return release_status + status = 'Key error' + print("resource key error: ") + print(resource) + return status def check_all_pods_running(pods): @@ -94,26 +70,27 @@ def run_around_tests(): config.load_kube_config(config_file=kubeconfig) yield -@pytest.mark.app -@pytest.mark.kustomizations -def test_kustomizations(app, namespace): + +def check_resources(api, api_group, api_version, plural, name, namespace='flux-system'): """ - Checks if all kustomizations installed by weave flux are in - 'Ready' state. + Checks if all resoures of a given kind are ready. """ - custom_objects = client.CustomObjectsApi() failed = 0 - failed_apps = [] + failed_resources = [] print('\n') - if app != 'all': - print(f"Testing single kustomization: {app}") - release_status = get_kustomization_status( - custom_objects, app, namespace) - if release_status != 'True': + if name != 'all': + status = get_resource_status( + api=api, + api_group=api_group, + api_version=api_version, + plural=plural, + name=name, + namespace=namespace) + if status != 'True': failed += 1 - failed_apps.append(app) + failed_resources.append(name) else: # we can't get a list of custom objects from all namespaces, # so we have to iterate over all namespaces. See @@ -122,21 +99,45 @@ def test_kustomizations(app, namespace): namespaces = core_api.list_namespace(watch=False) for namespace_object in namespaces.items: namespace_name = namespace_object.metadata.name - kustomizations = custom_objects.list_namespaced_custom_object( - group="kustomize.toolkit.fluxcd.io", - version="v1beta1", - plural="kustomizations", + custom_objects = api.list_namespaced_custom_object( + group=api_group, + version=api_version, + plural=plural, namespace=namespace_name, watch=False ) - for kustomization_object in kustomizations['items']: - kustomization_name = kustomization_object['metadata']['name'] - kustomization_status = get_kustomization_status( - custom_objects, kustomization_name, namespace_name) - if kustomization_status != 'True': + for custom_object in custom_objects['items']: + resource_name = custom_object['metadata']['name'] + status = get_resource_status( + api=api, + api_group=api_group, + api_version=api_version, + plural=plural, + name=resource_name, + namespace=namespace_name) + if status != 'True': failed += 1 - failed_apps.append(kustomization_name) - assert failed == 0, f"Error: {failed} kustomizations not ready ({failed_apps})!" + failed_resources.append(resource_name) + assert failed == 0, f"Error: {failed} kustomizations not ready ({failed_resources})!" + +# Pytest functions + +@pytest.mark.app +@pytest.mark.kustomizations +def test_kustomizations(app, namespace): + """ + Checks if all kustomizations installed by weave flux are in + 'Ready' state. + """ + + custom_objects = client.CustomObjectsApi() + check_resources( + api=custom_objects, + api_group='kustomize.toolkit.fluxcd.io', + api_version='v1beta1', + plural='kustomizations', + name=app, + namespace=namespace) @pytest.mark.app @@ -147,45 +148,19 @@ def test_helmreleases(app, namespace): 'Ready' state. """ - failed = 0 - failed_apps = [] - print('\n') custom_objects = client.CustomObjectsApi() - - if app != 'all': - release_status = get_release_status( - custom_objects, app, namespace) - if release_status != 'True': - failed += 1 - failed_apps.append(app) - else: - # we can't get a list of custom objects from all namespaces, - # so we have to iterate over all namespaces. See - # https://github.com/kubernetes-client/python/issues/1377 - core_api = client.CoreV1Api() - namespaces = core_api.list_namespace(watch=False) - for namespace_object in namespaces.items: - namespace_name = namespace_object.metadata.name - releases = custom_objects.list_namespaced_custom_object( - group="helm.toolkit.fluxcd.io", - version="v2beta1", - plural="helmreleases", - namespace=namespace_name, - watch=False - ) - for release_object in releases['items']: - release_name = release_object['metadata']['name'] - release_status = get_release_status( - custom_objects, release_name, namespace_name) - if release_status != 'True': - failed += 1 - failed_apps.append(release_name) - assert failed == 0, f"Error: {failed} helmreleases not ready ({failed_apps})!" + check_resources( + api=custom_objects, + api_group='helm.toolkit.fluxcd.io', + api_version='v2beta1', + plural='helmreleases', + name=app, + namespace=namespace) @pytest.mark.app -@pytest.mark.apps_running -def test_apps_running(app): +@pytest.mark.deployments +def test_deployments(app): """ Checks if all the pods related to releases in EXPECTED_RELEASES are ready