From efd483eb2271b5dae98818ca5daf9fe525b34302 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Thu, 23 Oct 2025 17:39:07 +0100 Subject: [PATCH 01/65] feat: Upgrade schemathesis --- .../cloudharness_utils/testing/api.py | 5 +++-- .../cloudharness_utils/testing/util.py | 6 ++++++ .../cloudharness_test/apitest_init.py | 19 ++++++++----------- tools/cloudharness-test/requirements.txt | 2 +- tools/cloudharness-test/setup.py | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py index 6506804b..b59fdcb2 100644 --- a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py +++ b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py @@ -12,11 +12,12 @@ def get_api_filename(app_dir): def get_schemathesis_command(api_filename, app_config: ApplicationHarnessConfig, app_domain: str): - return ["st", "--pre-run", "cloudharness_test.apitest_init", "run", api_filename, *get_schemathesis_params(app_config, app_domain)] + # Make sure to set SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init in environment to use the custom hooks + return ["st", "run", api_filename, *get_schemathesis_params(app_config, app_domain)] def get_schemathesis_params(app_config: ApplicationHarnessConfig, app_domain: str): - params = ["--base-url", app_domain] + params = ["--url", app_domain] api_config: ApiTestsConfig = app_config.test.api if api_config.checks: for c in api_config.checks: diff --git a/libraries/cloudharness-utils/cloudharness_utils/testing/util.py b/libraries/cloudharness-utils/cloudharness_utils/testing/util.py index 7bb66558..f89194f8 100644 --- a/libraries/cloudharness-utils/cloudharness_utils/testing/util.py +++ b/libraries/cloudharness-utils/cloudharness_utils/testing/util.py @@ -18,8 +18,14 @@ def get_app_environment(app_config: ApplicationHarnessConfig, app_domain, use_lo password = get_user_password(main_user) my_env["USERNAME"] = main_user.username my_env["PASSWORD"] = password + test_config: ApplicationTestConfig = app_config.test + api_config = test_config.api e2e_config: E2ETestsConfig = test_config.e2e + + if api_config.enabled or api_config.autotest: + my_env["SCHEMATHESIS_HOOKS"] = "cloudharness_test.apitest_init" + if not e2e_config.smoketest: my_env["SKIP_SMOKETEST"] = "true" if e2e_config.ignore_console_errors: diff --git a/tools/cloudharness-test/cloudharness_test/apitest_init.py b/tools/cloudharness-test/cloudharness_test/apitest_init.py index 64d3544e..42d8d9f1 100644 --- a/tools/cloudharness-test/cloudharness_test/apitest_init.py +++ b/tools/cloudharness-test/cloudharness_test/apitest_init.py @@ -6,7 +6,6 @@ from cloudharness.auth import get_token -st.experimental.OPEN_API_3_1.enable() if "APP_URL" or "APP_SCHEMA_FILE" in os.environ: app_schema = os.environ.get("APP_SCHEMA_FILE", None) @@ -22,9 +21,9 @@ # First, attempt to load the local file if provided if app_schema: try: - schema = st.from_file(app_schema) + schema = st.openapi.from_file(app_schema) logging.info("Successfully loaded schema from local file: %s", app_schema) - except st.exceptions.SchemaError: + except st.errors.LoaderError: logging.exception("The local schema file %s cannot be loaded. Attempting loading from URL", app_schema) # If no schema from file, then loop over URL candidates @@ -36,10 +35,10 @@ for candidate in candidates: try: logging.info("Attempting to load schema from URI: %s", candidate) - schema = st.from_uri(candidate) + schema = st.openapi.from_url(candidate) logging.info("Successfully loaded schema from %s", candidate) break # Exit loop on successful load - except st.exceptions.SchemaError as e: + except st.errors.LoaderError as e: logging.warning("Failed to load schema from %s: %s", candidate, e) except Exception as e: logging.error("Unexpected error when loading schema from %s: %s", candidate, e) @@ -49,10 +48,9 @@ if "USERNAME" in os.environ and "PASSWORD" in os.environ: logging.info("Setting token from username and password") - @st.auth.register() + @st.auth() class TokenAuth: - def get(self, context): - + def get(self, case, ctx): username = os.environ["USERNAME"] password = os.environ["PASSWORD"] @@ -63,10 +61,9 @@ def set(self, case, data, context): case.headers["Authorization"] = f"Bearer {data}" case.headers["Cookie"] = f"kc-access={data}" else: - @st.auth.register() + @st.auth() class TokenAuth: - def get(self, context): - + def get(self, case, ctx): return "" def set(self, case, data, context): diff --git a/tools/cloudharness-test/requirements.txt b/tools/cloudharness-test/requirements.txt index a9240f4e..8ff49955 100644 --- a/tools/cloudharness-test/requirements.txt +++ b/tools/cloudharness-test/requirements.txt @@ -1,3 +1,3 @@ openapi-spec-validator==0.5.1 -schemathesis<4.0.0 +schemathesis>=4.3.5 cloudharness_model diff --git a/tools/cloudharness-test/setup.py b/tools/cloudharness-test/setup.py index 01064fa8..4c375643 100644 --- a/tools/cloudharness-test/setup.py +++ b/tools/cloudharness-test/setup.py @@ -24,7 +24,7 @@ 'requests', 'cloudharness_model', 'cloudharness', - 'schemathesis<4.0.0', + 'schemathesis>=4.3.5', ] From 8b82aa5cc2af73aa55a5aa39b1b4b4f1fec46c82 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Thu, 23 Oct 2025 23:04:45 +0100 Subject: [PATCH 02/65] chore: Simplify schemathesis tests on workflows and common apps --- applications/common/deploy/values.yaml | 7 +++++++ applications/workflows/deploy/values.yaml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/applications/common/deploy/values.yaml b/applications/common/deploy/values.yaml index 256492ad..2e3a0e8a 100644 --- a/applications/common/deploy/values.yaml +++ b/applications/common/deploy/values.yaml @@ -23,5 +23,12 @@ harness: api: enabled: true autotest: true + runParams: + - --phases + - examples + - --mode + - positive + - --max-examples + - "10" checks: - all \ No newline at end of file diff --git a/applications/workflows/deploy/values.yaml b/applications/workflows/deploy/values.yaml index 15c8706a..6411e257 100644 --- a/applications/workflows/deploy/values.yaml +++ b/applications/workflows/deploy/values.yaml @@ -16,5 +16,12 @@ harness: api: enabled: true autotest: true + runParams: + - --mode + - positive + - --max-examples + - "5" + - --exclude-checks + - response_schema_conformance,positive_data_acceptance checks: - all From b8c65c2b5cc45d3ef3e3d496103c0f564827aab7 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Fri, 24 Oct 2025 00:06:50 +0100 Subject: [PATCH 03/65] chore: Update parametrize parameters --- application-templates/base/test/api/test_st.py | 2 +- application-templates/django-base/api/test_st.py | 2 +- applications/samples/test/api/test_st.py | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/application-templates/base/test/api/test_st.py b/application-templates/base/test/api/test_st.py index 902e2bd5..4702b2c0 100644 --- a/application-templates/base/test/api/test_st.py +++ b/application-templates/base/test/api/test_st.py @@ -10,7 +10,7 @@ schema = st.from_uri(app_url + "/openapi.json") -@schema.parametrize(endpoint="/ping") +@schema.include(path="/ping").parametrize() def test_ping(case): response = case.call() pprint(response.__dict__) diff --git a/application-templates/django-base/api/test_st.py b/application-templates/django-base/api/test_st.py index a7527b80..5eced3d1 100644 --- a/application-templates/django-base/api/test_st.py +++ b/application-templates/django-base/api/test_st.py @@ -14,7 +14,7 @@ schema = st.from_uri(app_url.replace("/api", "") + "/openapi.json") -@schema.parametrize(endpoint="/ping") +@schema.include(path="/ping").parametrize() def test_ping(case): response = case.call() pprint(response.__dict__) diff --git a/applications/samples/test/api/test_st.py b/applications/samples/test/api/test_st.py index e67cb3e5..2f91eb12 100644 --- a/applications/samples/test/api/test_st.py +++ b/applications/samples/test/api/test_st.py @@ -10,27 +10,27 @@ schema = st.from_uri(app_url + "/openapi.json") -@schema.parametrize(endpoint="/error") +@schema.include(path="/error").parametrize() def test_api(case): response = case.call() pprint(response.__dict__) assert response.status_code >= 500, "this api errors on purpose" -@schema.parametrize(endpoint="/valid") +@schema.include(path="/valid").parametrize() def test_bearer(case): response = case.call() case.validate_response(response, checks=(response_schema_conformance,)) -@schema.parametrize(endpoint="/valid-cookie") +@schema.include(path="/valid-cookie").parametrize() def test_cookie(case): response = case.call() case.validate_response(response, checks=(response_schema_conformance,)) -@schema.parametrize(endpoint="/sampleresources", method="POST") +@schema.include(path="/sampleresources", method="POST").parametrize() def test_response(case): response = case.call() case.validate_response(response, checks=(response_schema_conformance,)) From 6d3d2fd612888f909ce1683b00fea779c7f0bade Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Fri, 24 Oct 2025 00:26:11 +0100 Subject: [PATCH 04/65] chore: Remove deprecated __dict__ print --- application-templates/base/test/api/test_st.py | 1 - application-templates/django-base/api/test_st.py | 1 - applications/samples/test/api/test_st.py | 2 -- 3 files changed, 4 deletions(-) diff --git a/application-templates/base/test/api/test_st.py b/application-templates/base/test/api/test_st.py index 4702b2c0..d8a91676 100644 --- a/application-templates/base/test/api/test_st.py +++ b/application-templates/base/test/api/test_st.py @@ -13,5 +13,4 @@ @schema.include(path="/ping").parametrize() def test_ping(case): response = case.call() - pprint(response.__dict__) assert response.status_code == 200, "this api errors on purpose" diff --git a/application-templates/django-base/api/test_st.py b/application-templates/django-base/api/test_st.py index 5eced3d1..8e9cd37e 100644 --- a/application-templates/django-base/api/test_st.py +++ b/application-templates/django-base/api/test_st.py @@ -17,7 +17,6 @@ @schema.include(path="/ping").parametrize() def test_ping(case): response = case.call() - pprint(response.__dict__) assert response.status_code == 200, "this api errors on purpose" diff --git a/applications/samples/test/api/test_st.py b/applications/samples/test/api/test_st.py index 2f91eb12..29860fe6 100644 --- a/applications/samples/test/api/test_st.py +++ b/applications/samples/test/api/test_st.py @@ -13,14 +13,12 @@ @schema.include(path="/error").parametrize() def test_api(case): response = case.call() - pprint(response.__dict__) assert response.status_code >= 500, "this api errors on purpose" @schema.include(path="/valid").parametrize() def test_bearer(case): response = case.call() - case.validate_response(response, checks=(response_schema_conformance,)) From 4e29a215dbcbad48c478c502601b7c88f25527cf Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Fri, 24 Oct 2025 00:39:00 +0100 Subject: [PATCH 05/65] chore: Update parametrize parameters --- application-templates/base/test/api/test_st.py | 2 +- application-templates/django-base/api/test_st.py | 2 +- applications/samples/test/api/test_st.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/application-templates/base/test/api/test_st.py b/application-templates/base/test/api/test_st.py index d8a91676..10b02338 100644 --- a/application-templates/base/test/api/test_st.py +++ b/application-templates/base/test/api/test_st.py @@ -10,7 +10,7 @@ schema = st.from_uri(app_url + "/openapi.json") -@schema.include(path="/ping").parametrize() +@schema.include(path="/ping", method="GET").parametrize() def test_ping(case): response = case.call() assert response.status_code == 200, "this api errors on purpose" diff --git a/application-templates/django-base/api/test_st.py b/application-templates/django-base/api/test_st.py index 8e9cd37e..ddba7068 100644 --- a/application-templates/django-base/api/test_st.py +++ b/application-templates/django-base/api/test_st.py @@ -14,7 +14,7 @@ schema = st.from_uri(app_url.replace("/api", "") + "/openapi.json") -@schema.include(path="/ping").parametrize() +@schema.include(path="/ping", method="GET").parametrize() def test_ping(case): response = case.call() assert response.status_code == 200, "this api errors on purpose" diff --git a/applications/samples/test/api/test_st.py b/applications/samples/test/api/test_st.py index 29860fe6..f1705a53 100644 --- a/applications/samples/test/api/test_st.py +++ b/applications/samples/test/api/test_st.py @@ -10,19 +10,19 @@ schema = st.from_uri(app_url + "/openapi.json") -@schema.include(path="/error").parametrize() +@schema.include(path="/error", method="GET").parametrize() def test_api(case): response = case.call() assert response.status_code >= 500, "this api errors on purpose" -@schema.include(path="/valid").parametrize() +@schema.include(path="/valid", method="GET").parametrize() def test_bearer(case): response = case.call() case.validate_response(response, checks=(response_schema_conformance,)) -@schema.include(path="/valid-cookie").parametrize() +@schema.include(path="/valid-cookie", method="GET").parametrize() def test_cookie(case): response = case.call() case.validate_response(response, checks=(response_schema_conformance,)) From 783d59d64201970d877a63af8f3c3465ace5ae7c Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Fri, 24 Oct 2025 00:40:36 +0100 Subject: [PATCH 06/65] chore: Update codefresh assert --- tools/deployment-cli-tools/tests/test_codefresh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/deployment-cli-tools/tests/test_codefresh.py b/tools/deployment-cli-tools/tests/test_codefresh.py index b1b8e1c5..06bdd043 100644 --- a/tools/deployment-cli-tools/tests/test_codefresh.py +++ b/tools/deployment-cli-tools/tests/test_codefresh.py @@ -241,7 +241,7 @@ def test_create_codefresh_configuration_tests(): assert len(test_step["commands"]) == 2, "Both default and custom api tests should be run" st_cmd = test_step["commands"][0] - assert "--pre-run cloudharness_test.apitest_init" in st_cmd, "Prerun hook must be specified in schemathesis command" + assert any("SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init" in env for env in test_step['environment']), "Prerun hook must be specified in environment" assert "api/openapi.yaml" in st_cmd, "Openapi file must be passed to the schemathesis command" assert "-c all" in st_cmd, "Default check loaded is `all` on schemathesis command" From 2479095325b185c29f7b9c15aeb864749ab09c58 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Fri, 24 Oct 2025 15:26:00 +0100 Subject: [PATCH 07/65] chore: Update test codefresh pipeline --- deployment/codefresh-test.yaml | 304 +++++++++++++++++---------------- 1 file changed, 161 insertions(+), 143 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index e9699e95..7c32df67 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -13,13 +13,26 @@ steps: repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' revision: '${{CF_BRANCH}}' git: github + post_main_clone: + title: Post main clone + type: parallel + stage: prepare + steps: + clone_cloud_harness: + title: Cloning cloud-harness repository... + type: git-clone + stage: prepare + repo: https://github.com/MetaCell/cloud-harness.git + revision: '${{CLOUDHARNESS_BRANCH}}' + working_directory: . + git: github prepare_deployment: title: Prepare helm chart image: python:3.12 stage: prepare working_directory: . commands: - - bash ./install.sh + - bash cloud-harness/install.sh - harness-deployment . -n test-${{NAMESPACE_BASENAME}} -d ${{DOMAIN}} -r ${{REGISTRY}} -rs ${{REGISTRY_SECRET}} -e test --write-env --cache-url '${{IMAGE_CACHE_URL}}' -N -i samples @@ -60,27 +73,28 @@ steps: == true forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') == false - cloudharness-base: + test-e2e: type: build stage: build - dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-base - title: Cloudharness base - working_directory: ./. + image_name: cloud-harness/test-e2e + title: Test e2e + working_directory: ./test/test-e2e tags: - - '${{CLOUDHARNESS_BASE_TAG}}' + - '${{TEST_E2E_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') == false cloudharness-frontend-build: type: build @@ -104,28 +118,27 @@ steps: '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false - test-e2e: + cloudharness-base: type: build stage: build - dockerfile: Dockerfile + dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/test-e2e - title: Test e2e - working_directory: ./test/test-e2e + image_name: cloud-harness/cloudharness-base + title: Cloudharness base + working_directory: ./. tags: - - '${{TEST_E2E_TAG}}' + - '${{CLOUDHARNESS_BASE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false title: Build parallel step 1 build_application_images_1: @@ -155,30 +168,31 @@ steps: == true forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + test-api: type: build stage: build - dockerfile: Dockerfile + dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/test-api + title: Test api + working_directory: ./. tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{TEST_API_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - workflows-notify-queue: + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + == false + workflows-send-result-event: type: build stage: build dockerfile: Dockerfile @@ -187,21 +201,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false - samples-print-file: + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -210,21 +224,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') == false - workflows-send-result-event: + samples-sum: type: build stage: build dockerfile: Dockerfile @@ -233,45 +247,44 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - test-api: + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + == false + samples-print-file: type: build stage: build - dockerfile: test/test-api/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/test-api - title: Test api - working_directory: ./. + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{TEST_API_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - samples-secret: + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -280,20 +293,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false cloudharness-flask: type: build stage: build @@ -317,7 +330,7 @@ steps: == true forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false - samples-sum: + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -326,26 +339,26 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false title: Build parallel step 2 build_application_images_2: type: parallel stage: build steps: - samples: + common: type: build stage: build dockerfile: Dockerfile @@ -353,23 +366,22 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/samples - title: Samples - working_directory: ./applications/samples + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{SAMPLES_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false - common: + workflows: type: build stage: build dockerfile: Dockerfile @@ -378,21 +390,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{COMMON_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false - volumemanager: + samples: type: build stage: build dockerfile: Dockerfile @@ -400,22 +412,23 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/volumemanager - title: Volumemanager - working_directory: ./applications/volumemanager/server + image_name: cloud-harness/samples + title: Samples + working_directory: ./applications/samples tags: - - '${{VOLUMEMANAGER_TAG}}' + - '${{SAMPLES_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') == true - forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false - workflows: + volumemanager: type: build stage: build dockerfile: Dockerfile @@ -424,19 +437,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/volumemanager + title: Volumemanager + working_directory: ./applications/volumemanager/server tags: - - '${{WORKFLOWS_TAG}}' + - '${{VOLUMEMANAGER_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 tests_unit: @@ -472,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/volumemanager - kubectl rollout status deployment/workflows + - kubectl rollout status deployment/argo-gk + - kubectl rollout status deployment/accounts + - kubectl rollout status deployment/volumemanager - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk - - kubectl rollout status deployment/accounts - kubectl rollout status deployment/common - - kubectl rollout status deployment/argo-gk - sleep 60 tests_api: stage: qa @@ -489,18 +502,17 @@ steps: commands: - echo $APP_NAME scale: - volumemanager_api_test: - title: volumemanager api test + workflows_api_test: + title: workflows api test volumes: - - '${{CF_REPO_NAME}}/applications/volumemanager:/home/test' + - '${{CF_REPO_NAME}}/applications/workflows:/home/test' - '${{CF_REPO_NAME}}/deployment/helm/values.yaml:/opt/cloudharness/resources/allvalues.yaml' environment: - - APP_URL=https://volumemanager.${{DOMAIN}}/api - - USERNAME=volumes@testuser.com - - PASSWORD=test + - APP_URL=https://workflows.${{DOMAIN}}/api + - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url - https://volumemanager.${{DOMAIN}}/api -c all + - st run api/openapi.yaml --url https://workflows.${{DOMAIN}}/api -c all --mode + positive --max-examples 5 --exclude-checks response_schema_conformance,positive_data_acceptance samples_api_test: title: samples api test volumes: @@ -510,33 +522,37 @@ steps: - APP_URL=https://samples.${{DOMAIN}}/api - USERNAME=sample@testuser.com - PASSWORD=test + - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url - https://samples.${{DOMAIN}}/api -c all --skip-deprecated-operations --exclude-operation-id=submit_sync - --exclude-operation-id=submit_sync_with_results --exclude-operation-id=error - --hypothesis-suppress-health-check=too_slow --hypothesis-deadline=180000 - --request-timeout=180000 --hypothesis-max-examples=2 --show-trace --exclude-checks=ignored_auth + - st run api/openapi.yaml --url https://samples.${{DOMAIN}}/api -c all --skip-deprecated-operations + --exclude-operation-id=submit_sync --exclude-operation-id=submit_sync_with_results + --exclude-operation-id=error --hypothesis-suppress-health-check=too_slow + --hypothesis-deadline=180000 --request-timeout=180000 --hypothesis-max-examples=2 + --show-trace --exclude-checks=ignored_auth - pytest -v test/api - common_api_test: - title: common api test + volumemanager_api_test: + title: volumemanager api test volumes: - - '${{CF_REPO_NAME}}/applications/common:/home/test' + - '${{CF_REPO_NAME}}/applications/volumemanager:/home/test' - '${{CF_REPO_NAME}}/deployment/helm/values.yaml:/opt/cloudharness/resources/allvalues.yaml' environment: - - APP_URL=https://common.${{DOMAIN}}/api + - APP_URL=https://volumemanager.${{DOMAIN}}/api + - USERNAME=volumes@testuser.com + - PASSWORD=test + - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url - https://common.${{DOMAIN}}/api -c all - workflows_api_test: - title: workflows api test + - st run api/openapi.yaml --url https://volumemanager.${{DOMAIN}}/api -c all + common_api_test: + title: common api test volumes: - - '${{CF_REPO_NAME}}/applications/workflows:/home/test' + - '${{CF_REPO_NAME}}/applications/common:/home/test' - '${{CF_REPO_NAME}}/deployment/helm/values.yaml:/opt/cloudharness/resources/allvalues.yaml' environment: - - APP_URL=https://workflows.${{DOMAIN}}/api + - APP_URL=https://common.${{DOMAIN}}/api + - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url - https://workflows.${{DOMAIN}}/api -c all + - st run api/openapi.yaml --url https://common.${{DOMAIN}}/api -c all --phases + examples --mode positive --max-examples 10 hooks: on_fail: exec: @@ -553,12 +569,6 @@ steps: - npx puppeteer browsers install chrome - yarn test scale: - jupyterhub_e2e_test: - title: jupyterhub e2e test - volumes: - - '${{CF_REPO_NAME}}/applications/jupyterhub/test/e2e:/home/test/__tests__/jupyterhub' - environment: - - APP_URL=https://hub.${{DOMAIN}} samples_e2e_test: title: samples e2e test volumes: @@ -567,6 +577,14 @@ steps: - APP_URL=https://samples.${{DOMAIN}} - USERNAME=sample@testuser.com - PASSWORD=test + - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init + jupyterhub_e2e_test: + title: jupyterhub e2e test + volumes: + - '${{CF_REPO_NAME}}/applications/jupyterhub/test/e2e:/home/test/__tests__/jupyterhub' + environment: + - APP_URL=https://hub.${{DOMAIN}} + - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init hooks: on_fail: exec: From 89c842557a375fd2ad5aba4e5e831ec51d63ee0b Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Fri, 24 Oct 2025 16:20:07 +0100 Subject: [PATCH 08/65] chore: Update runParams --- applications/common/deploy/values.yaml | 7 ------- applications/samples/deploy/values.yaml | 10 ++++------ applications/workflows/deploy/values.yaml | 7 ------- tools/deployment-cli-tools/tests/test_codefresh.py | 4 ++-- 4 files changed, 6 insertions(+), 22 deletions(-) diff --git a/applications/common/deploy/values.yaml b/applications/common/deploy/values.yaml index 2e3a0e8a..256492ad 100644 --- a/applications/common/deploy/values.yaml +++ b/applications/common/deploy/values.yaml @@ -23,12 +23,5 @@ harness: api: enabled: true autotest: true - runParams: - - --phases - - examples - - --mode - - positive - - --max-examples - - "10" checks: - all \ No newline at end of file diff --git a/applications/samples/deploy/values.yaml b/applications/samples/deploy/values.yaml index 1006e7a1..8f7e0aad 100644 --- a/applications/samples/deploy/values.yaml +++ b/applications/samples/deploy/values.yaml @@ -78,16 +78,14 @@ harness: checks: - all runParams: - - "--skip-deprecated-operations" + - "--exclude-deprecated" - "--exclude-operation-id=submit_sync" - "--exclude-operation-id=submit_sync_with_results" - "--exclude-operation-id=error" - - "--hypothesis-suppress-health-check=too_slow" - - "--hypothesis-deadline=180000" + - "--suppress-health-check=too_slow" - "--request-timeout=180000" - - "--hypothesis-max-examples=2" - - "--show-trace" - - "--exclude-checks=ignored_auth" # ignored_auth is not working on schemathesis 3.36.0 + - "--max-examples=2" + - "--exclude-checks=ignored_auth" dockerfile: buildArgs: diff --git a/applications/workflows/deploy/values.yaml b/applications/workflows/deploy/values.yaml index 6411e257..15c8706a 100644 --- a/applications/workflows/deploy/values.yaml +++ b/applications/workflows/deploy/values.yaml @@ -16,12 +16,5 @@ harness: api: enabled: true autotest: true - runParams: - - --mode - - positive - - --max-examples - - "5" - - --exclude-checks - - response_schema_conformance,positive_data_acceptance checks: - all diff --git a/tools/deployment-cli-tools/tests/test_codefresh.py b/tools/deployment-cli-tools/tests/test_codefresh.py index 06bdd043..7ad4af39 100644 --- a/tools/deployment-cli-tools/tests/test_codefresh.py +++ b/tools/deployment-cli-tools/tests/test_codefresh.py @@ -241,11 +241,11 @@ def test_create_codefresh_configuration_tests(): assert len(test_step["commands"]) == 2, "Both default and custom api tests should be run" st_cmd = test_step["commands"][0] - assert any("SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init" in env for env in test_step['environment']), "Prerun hook must be specified in environment" + assert any("SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init" in env for env in test_step['environment']), "SCHEMATHESIS_HOOKS hook must be specified in environment" assert "api/openapi.yaml" in st_cmd, "Openapi file must be passed to the schemathesis command" assert "-c all" in st_cmd, "Default check loaded is `all` on schemathesis command" - assert "--hypothesis-deadline=" in st_cmd, "Custom parameters are loaded from values.yaml" + assert "--exclude-deprecated" in st_cmd, "Custom parameters are loaded from values.yaml" test_step = api_steps["common_api_test"] for volume in test_step["volumes"]: From a0f03d2cdc836337c8a08052ba00b97decbcbd00 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Fri, 24 Oct 2025 16:59:02 +0100 Subject: [PATCH 09/65] chore: Update testing docs --- deployment/codefresh-test.yaml | 231 ++++++++++++++++----------------- docs/testing.md | 8 +- 2 files changed, 117 insertions(+), 122 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 7c32df67..0f973624 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -96,56 +96,56 @@ steps: == true forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') == false - cloudharness-frontend-build: + cloudharness-base: type: build stage: build - dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile + dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-frontend-build - title: Cloudharness frontend build + image_name: cloud-harness/cloudharness-base + title: Cloudharness base working_directory: ./. tags: - - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' + - '${{CLOUDHARNESS_BASE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false - cloudharness-base: + buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') + == false + cloudharness-frontend-build: type: build stage: build - dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile + dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-base - title: Cloudharness base + image_name: cloud-harness/cloudharness-frontend-build + title: Cloudharness frontend build working_directory: ./. tags: - - '${{CLOUDHARNESS_BASE_TAG}}' + - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') - == true - forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true + forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false title: Build parallel step 1 build_application_images_1: type: parallel stage: build steps: - jupyterhub: + workflows-send-result-event: type: build stage: build dockerfile: Dockerfile @@ -154,20 +154,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event tags: - - '${{JUPYTERHUB_TAG}}' + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') - == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false test-api: type: build stage: build @@ -192,7 +192,7 @@ steps: == true forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') == false - workflows-send-result-event: + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -201,21 +201,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - samples-secret: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -224,21 +224,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - samples-sum: + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -247,21 +247,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') - == false - samples-print-file: + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -270,21 +270,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + cloudharness-flask: type: build stage: build dockerfile: Dockerfile @@ -293,21 +293,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - cloudharness-flask: + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + == false + jupyterhub: type: build stage: build dockerfile: Dockerfile @@ -316,21 +316,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') == false - workflows-notify-queue: + samples-sum: type: build stage: build dockerfile: Dockerfile @@ -339,26 +339,26 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + == false title: Build parallel step 2 build_application_images_2: type: parallel stage: build steps: - common: + samples: type: build stage: build dockerfile: Dockerfile @@ -366,22 +366,23 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/samples + title: Samples + working_directory: ./applications/samples tags: - - '${{COMMON_TAG}}' + - '${{SAMPLES_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false - workflows: + common: type: build stage: build dockerfile: Dockerfile @@ -390,21 +391,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{WORKFLOWS_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false - samples: + workflows: type: build stage: build dockerfile: Dockerfile @@ -412,21 +413,20 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/samples - title: Samples - working_directory: ./applications/samples + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{SAMPLES_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false volumemanager: type: build @@ -485,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/workflows - - kubectl rollout status deployment/argo-gk - kubectl rollout status deployment/accounts - - kubectl rollout status deployment/volumemanager - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk - kubectl rollout status deployment/common + - kubectl rollout status deployment/volumemanager + - kubectl rollout status deployment/argo-gk + - kubectl rollout status deployment/workflows - sleep 60 tests_api: stage: qa @@ -511,8 +511,7 @@ steps: - APP_URL=https://workflows.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st run api/openapi.yaml --url https://workflows.${{DOMAIN}}/api -c all --mode - positive --max-examples 5 --exclude-checks response_schema_conformance,positive_data_acceptance + - st run api/openapi.yaml --url https://workflows.${{DOMAIN}}/api -c all samples_api_test: title: samples api test volumes: @@ -524,11 +523,10 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st run api/openapi.yaml --url https://samples.${{DOMAIN}}/api -c all --skip-deprecated-operations + - st run api/openapi.yaml --url https://samples.${{DOMAIN}}/api -c all --exclude-deprecated --exclude-operation-id=submit_sync --exclude-operation-id=submit_sync_with_results - --exclude-operation-id=error --hypothesis-suppress-health-check=too_slow - --hypothesis-deadline=180000 --request-timeout=180000 --hypothesis-max-examples=2 - --show-trace --exclude-checks=ignored_auth + --exclude-operation-id=error --suppress-health-check=too_slow --request-timeout=180000 + --max-examples=2 --exclude-checks=ignored_auth - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -551,8 +549,7 @@ steps: - APP_URL=https://common.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st run api/openapi.yaml --url https://common.${{DOMAIN}}/api -c all --phases - examples --mode positive --max-examples 10 + - st run api/openapi.yaml --url https://common.${{DOMAIN}}/api -c all hooks: on_fail: exec: diff --git a/docs/testing.md b/docs/testing.md index 0a941f90..fab39c15 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -78,12 +78,10 @@ harness: checks: - all runParams: - - "--skip-deprecated-operations" - - "--hypothesis-suppress-health-check=too_slow" - - "--hypothesis-deadline=60000" + - "--exclude-deprecated" + - "--suppress-health-check=too_slow" - "--request-timeout=60000" - - "--hypothesis-max-examples=2" - - "--show-trace" + - "--max-examples=2" ``` See [the model documentation](model/ApiTestsConfig.md) for more insights about test parameters. From b95378f4c47eb9d39262c5d3815058baac5327ee Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Fri, 24 Oct 2025 18:12:53 +0100 Subject: [PATCH 10/65] chore: Prevent trace requests on st tests --- applications/common/schemathesis.toml | 2 + applications/samples/schemathesis.toml | 2 + applications/volumemanager/schemathesis.toml | 2 + applications/workflows/schemathesis.toml | 2 + deployment/codefresh-test.yaml | 236 +++++++++---------- 5 files changed, 126 insertions(+), 118 deletions(-) create mode 100644 applications/common/schemathesis.toml create mode 100644 applications/samples/schemathesis.toml create mode 100644 applications/volumemanager/schemathesis.toml create mode 100644 applications/workflows/schemathesis.toml diff --git a/applications/common/schemathesis.toml b/applications/common/schemathesis.toml new file mode 100644 index 00000000..377648b5 --- /dev/null +++ b/applications/common/schemathesis.toml @@ -0,0 +1,2 @@ +[phases.coverage] +unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] \ No newline at end of file diff --git a/applications/samples/schemathesis.toml b/applications/samples/schemathesis.toml new file mode 100644 index 00000000..377648b5 --- /dev/null +++ b/applications/samples/schemathesis.toml @@ -0,0 +1,2 @@ +[phases.coverage] +unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] \ No newline at end of file diff --git a/applications/volumemanager/schemathesis.toml b/applications/volumemanager/schemathesis.toml new file mode 100644 index 00000000..377648b5 --- /dev/null +++ b/applications/volumemanager/schemathesis.toml @@ -0,0 +1,2 @@ +[phases.coverage] +unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] \ No newline at end of file diff --git a/applications/workflows/schemathesis.toml b/applications/workflows/schemathesis.toml new file mode 100644 index 00000000..377648b5 --- /dev/null +++ b/applications/workflows/schemathesis.toml @@ -0,0 +1,2 @@ +[phases.coverage] +unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] \ No newline at end of file diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 0f973624..7f4e9560 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -51,6 +51,28 @@ steps: type: parallel stage: build steps: + cloudharness-base: + type: build + stage: build + dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + image_name: cloud-harness/cloudharness-base + title: Cloudharness base + working_directory: ./. + tags: + - '${{CLOUDHARNESS_BASE_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') + == false accounts: type: build stage: build @@ -96,28 +118,6 @@ steps: == true forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') == false - cloudharness-base: - type: build - stage: build - dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-base - title: Cloudharness base - working_directory: ./. - tags: - - '${{CLOUDHARNESS_BASE_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') - == true - forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') - == false cloudharness-frontend-build: type: build stage: build @@ -145,7 +145,7 @@ steps: type: parallel stage: build steps: - workflows-send-result-event: + samples-sum: type: build stage: build dockerfile: Dockerfile @@ -154,45 +154,44 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - test-api: + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + == false + workflows-extract-download: type: build stage: build - dockerfile: test/test-api/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/test-api - title: Test api - working_directory: ./. + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{TEST_API_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') - == true - forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') - == false - workflows-extract-download: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + jupyterhub: type: build stage: build dockerfile: Dockerfile @@ -201,44 +200,45 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - samples-print-file: + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') + == true + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') + == false + test-api: type: build stage: build - dockerfile: Dockerfile + dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/test-api + title: Test api + working_directory: ./. tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{TEST_API_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') == false - workflows-notify-queue: + workflows-send-result-event: type: build stage: build dockerfile: Dockerfile @@ -247,20 +247,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false samples-secret: type: build stage: build @@ -284,7 +284,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') == false - cloudharness-flask: + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -293,21 +293,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - jupyterhub: + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -316,21 +316,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{JUPYTERHUB_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') - == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') - == false - samples-sum: + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + cloudharness-flask: type: build stage: build dockerfile: Dockerfile @@ -339,19 +339,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false title: Build parallel step 2 build_application_images_2: @@ -382,7 +382,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false - common: + volumemanager: type: build stage: build dockerfile: Dockerfile @@ -391,21 +391,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/volumemanager + title: Volumemanager + working_directory: ./applications/volumemanager/server tags: - - '${{COMMON_TAG}}' + - '${{VOLUMEMANAGER_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false - workflows: + common: type: build stage: build dockerfile: Dockerfile @@ -414,21 +414,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{WORKFLOWS_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false - volumemanager: + workflows: type: build stage: build dockerfile: Dockerfile @@ -437,19 +437,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/volumemanager - title: Volumemanager - working_directory: ./applications/volumemanager/server + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{VOLUMEMANAGER_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 tests_unit: @@ -485,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/accounts - - kubectl rollout status deployment/samples - - kubectl rollout status deployment/samples-gk - - kubectl rollout status deployment/common - kubectl rollout status deployment/volumemanager - kubectl rollout status deployment/argo-gk + - kubectl rollout status deployment/samples + - kubectl rollout status deployment/samples-gk - kubectl rollout status deployment/workflows + - kubectl rollout status deployment/accounts + - kubectl rollout status deployment/common - sleep 60 tests_api: stage: qa @@ -526,7 +526,7 @@ steps: - st run api/openapi.yaml --url https://samples.${{DOMAIN}}/api -c all --exclude-deprecated --exclude-operation-id=submit_sync --exclude-operation-id=submit_sync_with_results --exclude-operation-id=error --suppress-health-check=too_slow --request-timeout=180000 - --max-examples=2 --exclude-checks=ignored_auth + --max-examples=2 --exclude-checks=ignored_auth --exclude-method=TRACE - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -549,7 +549,7 @@ steps: - APP_URL=https://common.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st run api/openapi.yaml --url https://common.${{DOMAIN}}/api -c all + - st run api/openapi.yaml --url https://common.${{DOMAIN}}/api -c all --exclude-method=TRACE hooks: on_fail: exec: From 70346b40428ef804ca180e6c75aba6ef33fb811b Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 12:52:16 +0000 Subject: [PATCH 11/65] fix: Update samples api --- .../samples/backend/samples/controllers/auth_controller.py | 4 ++++ .../backend/samples/controllers/resource_controller.py | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/applications/samples/backend/samples/controllers/auth_controller.py b/applications/samples/backend/samples/controllers/auth_controller.py index e144a976..554e92f9 100644 --- a/applications/samples/backend/samples/controllers/auth_controller.py +++ b/applications/samples/backend/samples/controllers/auth_controller.py @@ -15,6 +15,8 @@ def valid_token(): # noqa: E501 """ from cloudharness.middleware import get_authentication_token token = get_authentication_token() + if not token: + return 'Unauthorized', 401 return 'OK!' @@ -29,5 +31,7 @@ def valid_cookie(): # noqa: E501 from cloudharness.middleware import get_authentication_token from cloudharness.auth import decode_token token = get_authentication_token() + if not token: + return 'Unauthorized', 401 assert decode_token(token) return 'OK' diff --git a/applications/samples/backend/samples/controllers/resource_controller.py b/applications/samples/backend/samples/controllers/resource_controller.py index 4f17d3da..4ed23dab 100644 --- a/applications/samples/backend/samples/controllers/resource_controller.py +++ b/applications/samples/backend/samples/controllers/resource_controller.py @@ -44,7 +44,7 @@ def delete_sample_resource(sampleresource_id): # noqa: E501 except resource_service.ResourceNotFound: return "Resource not found", 404 except ValueError: - return "sampleresource_id must be integer", 400 + return "Resource not found", 404 return 'OK', 204 @@ -64,7 +64,7 @@ def get_sample_resource(sampleresource_id): # noqa: E501 except resource_service.ResourceNotFound: return "Resource not found", 404 except ValueError: - return "sampleresource_id must be integer", 400 + return "Resource not found", 404 def get_sample_resources(): # noqa: E501 @@ -101,4 +101,4 @@ def update_sample_resource(sampleresource_id, sample_resource=None): # noqa: E5 except resource_service.ResourceNotFound: return "Resource not found", 404 except ValueError: - return "sampleresource_id must be integer", 400 + return "Resource not found", 404 From 93bff9adc1532e50c2a0faaec732d1847772bc7e Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 13:30:10 +0000 Subject: [PATCH 12/65] fix: Update workflows api --- applications/workflows/api/openapi.yaml | 5 ++--- .../controllers/create_and_access_controller.py | 3 +++ .../workflows/server/workflows_api/openapi/openapi.yaml | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/applications/workflows/api/openapi.yaml b/applications/workflows/api/openapi.yaml index b2d674d6..f996c87f 100644 --- a/applications/workflows/api/openapi.yaml +++ b/applications/workflows/api/openapi.yaml @@ -79,7 +79,7 @@ paths: parameters: - examples: e1: - value: '"my-operation"' + value: my-operation e2: value: my-operation-122a name: name @@ -103,8 +103,7 @@ paths: in: query - examples: example1: - value: >- - "eyJ2IjoibWV0YS5rOHMuaW8vdjEiLCJydiI6NDUzMDMzOCwic3RhcnQiOiJoZWxsby13b3JsZC05YnE2ZFx1MDAwMCJ8" + value: eyJ2IjoibWV0YS5rOHMuaW8vdjEiLCJydiI6NDUzMDMzOCwic3RhcnQiOiJoZWxsby13b3JsZC05YnE2ZFx1MDAwMCJ8 name: previous_search_token description: continue previous search (pagination chunks) schema: diff --git a/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py b/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py index 561b20af..0d127a79 100644 --- a/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py +++ b/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py @@ -90,3 +90,6 @@ def log_operation(name): # noqa: E501 return workflow_service.log_operation(name) except OperationNotFound as e: return (f'{name} not found', 404) + except OperationException as e: + log.error(f'Unhandled remote exception while retrieving workflow logs for {name}', exc_info=e) + return f'Unexpected error', e.status diff --git a/applications/workflows/server/workflows_api/openapi/openapi.yaml b/applications/workflows/server/workflows_api/openapi/openapi.yaml index 638b9f9a..4bdbaed1 100644 --- a/applications/workflows/server/workflows_api/openapi/openapi.yaml +++ b/applications/workflows/server/workflows_api/openapi/openapi.yaml @@ -32,7 +32,7 @@ paths: - description: continue previous search (pagination chunks) examples: example1: - value: '"eyJ2IjoibWV0YS5rOHMuaW8vdjEiLCJydiI6NDUzMDMzOCwic3RhcnQiOiJoZWxsby13b3JsZC05YnE2ZFx1MDAwMCJ8"' + value: eyJ2IjoibWV0YS5rOHMuaW8vdjEiLCJydiI6NDUzMDMzOCwic3RhcnQiOiJoZWxsby13b3JsZC05YnE2ZFx1MDAwMCJ8 explode: true in: query name: previous_search_token @@ -124,7 +124,7 @@ paths: parameters: - examples: e1: - value: '"my-operation"' + value: my-operation e2: value: my-operation-122a explode: false From f179fa7c255a8eeaa5dedeb8e3f47f77f5d54533 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 13:34:04 +0000 Subject: [PATCH 13/65] fix: Update volumemanager api --- .../volumemanager/server/volumemanager/openapi/openapi.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/applications/volumemanager/server/volumemanager/openapi/openapi.yaml b/applications/volumemanager/server/volumemanager/openapi/openapi.yaml index f27b03d8..821b753c 100644 --- a/applications/volumemanager/server/volumemanager/openapi/openapi.yaml +++ b/applications/volumemanager/server/volumemanager/openapi/openapi.yaml @@ -31,6 +31,10 @@ paths: description: Save successful. "400": description: The Persistent Volume Claim already exists. + "401": + description: Unauthorized - No authorization token provided. + "500": + description: Internal server error. security: - bearerAuth: [] summary: Create a Persistent Volume Claim in Kubernetes @@ -56,6 +60,8 @@ paths: schema: $ref: '#/components/schemas/PersistentVolumeClaim' description: The Persistent Volume Claim. + "401": + description: Unauthorized - No authorization token provided. "404": description: The Persistent Volume Claim was not found. security: From d5ae87e5655a5bcaad2e966168000721c2c74a21 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 13:38:40 +0000 Subject: [PATCH 14/65] fix: Update common api --- .../common/server/common/controllers/sentry_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/common/server/common/controllers/sentry_controller.py b/applications/common/server/common/controllers/sentry_controller.py index 4d072782..e63bf3c0 100644 --- a/applications/common/server/common/controllers/sentry_controller.py +++ b/applications/common/server/common/controllers/sentry_controller.py @@ -26,7 +26,7 @@ def getdsn(appname): # noqa: E501 try: ch_app = applications.get_configuration(appname) except applications.ConfigurationCallException as e: - return {"error": f"Application `{appname}` does not exist"}, 400 + return {"error": f"Application `{appname}` does not exist"}, 404 if ch_app.is_sentry_enabled(): if global_dsn: # if a global dsn env var is set and not empty then use this From fcb2ae97c666c01cf801ee7f7333e9e610ae70dc Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 13:52:05 +0000 Subject: [PATCH 15/65] fix: Update common api --- applications/common/server/common/openapi/openapi.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/applications/common/server/common/openapi/openapi.yaml b/applications/common/server/common/openapi/openapi.yaml index 02e7b77f..d74212f7 100644 --- a/applications/common/server/common/openapi/openapi.yaml +++ b/applications/common/server/common/openapi/openapi.yaml @@ -57,13 +57,16 @@ paths: description: Sentry not configured for the given application "404": content: + application/json: + schema: + type: object application/problem+json: schema: type: object text/html: schema: type: string - description: Sentry not configured for the given application + description: Application not found summary: Gets the Sentry DSN for a given application tags: - Sentry From 2152d7438192c2f01473a4cbe19f0516fa5af589 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 14:08:53 +0000 Subject: [PATCH 16/65] fix: Update volumemanager api --- applications/volumemanager/api/openapi.yaml | 6 ++++++ .../controllers/rest_controller.py | 21 ++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/applications/volumemanager/api/openapi.yaml b/applications/volumemanager/api/openapi.yaml index 50fcc805..35517486 100644 --- a/applications/volumemanager/api/openapi.yaml +++ b/applications/volumemanager/api/openapi.yaml @@ -32,6 +32,10 @@ paths: description: Save successful. "400": description: The Persistent Volume Claim already exists. + "401": + description: Unauthorized - No authorization token provided. + "500": + description: Internal server error. security: - bearerAuth: [] summary: Create a Persistent Volume Claim in Kubernetes @@ -57,6 +61,8 @@ paths: schema: $ref: '#/components/schemas/PersistentVolumeClaim' description: The Persistent Volume Claim. + "401": + description: Unauthorized - No authorization token provided. "404": description: The Persistent Volume Claim was not found. security: diff --git a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py index 5eb30a4f..d66639f4 100644 --- a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py +++ b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py @@ -1,6 +1,7 @@ import connexion import six import flask +import kubernetes.client.rest from cloudharness.service.pvc import create_persistent_volume_claim, get_persistent_volume_claim @@ -44,8 +45,18 @@ def pvc_post(): # noqa: E501 """ if connexion.request.is_json: persistent_volume_claim_create = PersistentVolumeClaimCreate.from_dict(connexion.request.get_json()) # noqa: E501 - create_persistent_volume_claim( - name=persistent_volume_claim_create.name, - size=persistent_volume_claim_create.size, - logger=flask.current_app.logger) - return 'Saved!' + try: + create_persistent_volume_claim( + name=persistent_volume_claim_create.name, + size=persistent_volume_claim_create.size, + logger=flask.current_app.logger) + except kubernetes.client.rest.ApiException as e: + # Kubernetes returns 409 Conflict when resource already exists + if e.status == 409: + return {'description': 'The Persistent Volume Claim already exists.'}, 400 + flask.current_app.logger.error(f"Error creating PVC: {e}") + return {'description': f'Failed to create Persistent Volume Claim: {e.reason}'}, 500 + except Exception as e: + flask.current_app.logger.error(f"Error creating PVC: {e}") + return {'description': f'Failed to create Persistent Volume Claim: {str(e)}'}, 500 + return 'Saved!', 201 From 82de3bcc94979dc1f4cc94e57757b322e1428caf Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 14:16:43 +0000 Subject: [PATCH 17/65] fix: Update workflows api --- applications/workflows/api/openapi.yaml | 7 +------ .../workflows/server/workflows_api/openapi/openapi.yaml | 5 ----- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/applications/workflows/api/openapi.yaml b/applications/workflows/api/openapi.yaml index f996c87f..bd4e6fc5 100644 --- a/applications/workflows/api/openapi.yaml +++ b/applications/workflows/api/openapi.yaml @@ -52,7 +52,6 @@ paths: parameters: - name: name schema: - pattern: '^[0-9A-Za-z\s\-]+$' type: string in: path required: true @@ -84,7 +83,6 @@ paths: value: my-operation-122a name: name schema: - pattern: '^[0-9A-Za-z\s\-]+$' type: string in: path required: true @@ -101,10 +99,7 @@ paths: schema: $ref: "#/components/schemas/OperationStatus" in: query - - examples: - example1: - value: eyJ2IjoibWV0YS5rOHMuaW8vdjEiLCJydiI6NDUzMDMzOCwic3RhcnQiOiJoZWxsby13b3JsZC05YnE2ZFx1MDAwMCJ8 - name: previous_search_token + - name: previous_search_token description: continue previous search (pagination chunks) schema: type: string diff --git a/applications/workflows/server/workflows_api/openapi/openapi.yaml b/applications/workflows/server/workflows_api/openapi/openapi.yaml index 4bdbaed1..b19f2964 100644 --- a/applications/workflows/server/workflows_api/openapi/openapi.yaml +++ b/applications/workflows/server/workflows_api/openapi/openapi.yaml @@ -30,9 +30,6 @@ paths: $ref: '#/components/schemas/OperationStatus' style: form - description: continue previous search (pagination chunks) - examples: - example1: - value: eyJ2IjoibWV0YS5rOHMuaW8vdjEiLCJydiI6NDUzMDMzOCwic3RhcnQiOiJoZWxsby13b3JsZC05YnE2ZFx1MDAwMCJ8 explode: true in: query name: previous_search_token @@ -96,7 +93,6 @@ paths: name: name required: true schema: - pattern: "^[0-9A-Za-z\\s\\-]+$" type: string style: simple responses: @@ -132,7 +128,6 @@ paths: name: name required: true schema: - pattern: "^[0-9A-Za-z\\s\\-]+$" type: string style: simple responses: From 383a25f431506cb39e8bd3937a4a345eda78d5de Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 14:35:55 +0000 Subject: [PATCH 18/65] fix: Update samples api --- applications/samples/api/openapi.yaml | 4 ++++ .../backend/samples/controllers/security_controller_.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/applications/samples/api/openapi.yaml b/applications/samples/api/openapi.yaml index f51b328d..9462b1c6 100644 --- a/applications/samples/api/openapi.yaml +++ b/applications/samples/api/openapi.yaml @@ -54,6 +54,8 @@ paths: schema: type: string description: Check if token is valid + "400": + description: Bad request "401": description: "invalid token, unauthorized" security: @@ -74,6 +76,8 @@ paths: schema: type: string description: Check if token is valid + "400": + description: Bad request "401": description: "invalid token, unauthorized" security: diff --git a/applications/samples/backend/samples/controllers/security_controller_.py b/applications/samples/backend/samples/controllers/security_controller_.py index c052e680..1ee232e9 100644 --- a/applications/samples/backend/samples/controllers/security_controller_.py +++ b/applications/samples/backend/samples/controllers/security_controller_.py @@ -12,4 +12,6 @@ def info_from_bearerAuth(token): :return: Decoded token information or None if token is invalid :rtype: dict | None """ + if token is None: + return None return {'uid': 'user_id'} From 61314a2b6fb96509270e8c06d6a5388518c0f6f5 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 14:45:23 +0000 Subject: [PATCH 19/65] fix: Update volumemanager examples --- applications/volumemanager/api/openapi.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/applications/volumemanager/api/openapi.yaml b/applications/volumemanager/api/openapi.yaml index 35517486..3256d6d3 100644 --- a/applications/volumemanager/api/openapi.yaml +++ b/applications/volumemanager/api/openapi.yaml @@ -75,7 +75,7 @@ components: schemas: PersistentVolumeClaimCreate: example: - size: 2Gi (see also https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/resources.md#resource-quantities) + size: 2Gi name: pvc-1 properties: name: @@ -84,12 +84,12 @@ components: type: string size: description: The size of the Persistent Volume Claim to create. - example: 2Gi (see also https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/resources.md#resource-quantities) + example: 2Gi type: string type: object PersistentVolumeClaim: example: - size: 2Gi (see also https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/resources.md#resource-quantities) + size: 2Gi name: pvc-1 namespace: ch accessmode: ReadWriteMany @@ -108,7 +108,7 @@ components: type: string size: description: The size of the Persistent Volume Claim. - example: 2Gi (see also https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/resources.md#resource-quantities) + example: 2Gi type: string type: object securitySchemes: From 4c028def27fcf9b2eebc4dc6a7ea7c00ee719648 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 14:47:36 +0000 Subject: [PATCH 20/65] fix: Update common api --- applications/common/api/openapi.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/applications/common/api/openapi.yaml b/applications/common/api/openapi.yaml index 33c2b91a..0ded9c81 100644 --- a/applications/common/api/openapi.yaml +++ b/applications/common/api/openapi.yaml @@ -32,13 +32,16 @@ paths: description: Sentry not configured for the given application '404': content: + application/json: + schema: + type: object application/problem+json: schema: type: object text/html: schema: type: string - description: Sentry not configured for the given application + description: Application not found operationId: getdsn summary: Gets the Sentry DSN for a given application description: Gets the Sentry DSN for a given application From e6fb26f70b845383ece821d472d76e2749c92365 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 15:24:09 +0000 Subject: [PATCH 21/65] fix: Ignore problematic workflow tests --- applications/workflows/schemathesis.toml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/applications/workflows/schemathesis.toml b/applications/workflows/schemathesis.toml index 377648b5..9fec79c4 100644 --- a/applications/workflows/schemathesis.toml +++ b/applications/workflows/schemathesis.toml @@ -1,2 +1,12 @@ [phases.coverage] -unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] \ No newline at end of file +unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] + +# Disable negative testing - don't test with unknown/invalid properties +[phases.negative] +enabled = false + +# Set previous_search_token to empty/null to avoid invalid token generation +# Since this is an optional parameter used for pagination, not providing it is valid +[[parameters.query]] +name = "previous_search_token" +value = null \ No newline at end of file From 4f422998b50770dcce0fdecdb75c7cb1d07f3e2e Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 15:42:52 +0000 Subject: [PATCH 22/65] fix: Ignore problematic sample operations --- applications/samples/deploy/values.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/applications/samples/deploy/values.yaml b/applications/samples/deploy/values.yaml index 8f7e0aad..e4c3b42a 100644 --- a/applications/samples/deploy/values.yaml +++ b/applications/samples/deploy/values.yaml @@ -82,6 +82,8 @@ harness: - "--exclude-operation-id=submit_sync" - "--exclude-operation-id=submit_sync_with_results" - "--exclude-operation-id=error" + - "--exclude-operation-id=valid_token" + - "--exclude-operation-id=valid_cookie" - "--suppress-health-check=too_slow" - "--request-timeout=180000" - "--max-examples=2" From ff727d50e26683bf3d23e89c9854c6c3e099e3ec Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 15:46:38 +0000 Subject: [PATCH 23/65] chore: Correct schemathesis toml syntax --- applications/workflows/schemathesis.toml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/applications/workflows/schemathesis.toml b/applications/workflows/schemathesis.toml index 9fec79c4..eac1a14e 100644 --- a/applications/workflows/schemathesis.toml +++ b/applications/workflows/schemathesis.toml @@ -5,8 +5,7 @@ unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] [phases.negative] enabled = false -# Set previous_search_token to empty/null to avoid invalid token generation -# Since this is an optional parameter used for pagination, not providing it is valid -[[parameters.query]] -name = "previous_search_token" -value = null \ No newline at end of file +# Set previous_search_token to empty to avoid invalid token generation +# Since this is an optional parameter used for pagination, omitting it is valid +[parameters] +previous_search_token = null \ No newline at end of file From c3048e4383f9d15182996f399c4b1513c1c59973 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 15:54:50 +0000 Subject: [PATCH 24/65] fix: Update volumemanager api --- applications/volumemanager/api/openapi.yaml | 3 ++- .../server/volumemanager/controllers/rest_controller.py | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/applications/volumemanager/api/openapi.yaml b/applications/volumemanager/api/openapi.yaml index 3256d6d3..4875f6af 100644 --- a/applications/volumemanager/api/openapi.yaml +++ b/applications/volumemanager/api/openapi.yaml @@ -28,7 +28,8 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/PersistentVolumeClaim' + type: string + example: "Saved!" description: Save successful. "400": description: The Persistent Volume Claim already exists. diff --git a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py index d66639f4..8c9b0177 100644 --- a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py +++ b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py @@ -45,6 +45,11 @@ def pvc_post(): # noqa: E501 """ if connexion.request.is_json: persistent_volume_claim_create = PersistentVolumeClaimCreate.from_dict(connexion.request.get_json()) # noqa: E501 + + # Validate required fields + if not persistent_volume_claim_create.name or not persistent_volume_claim_create.size: + return {'description': 'Name and size are required fields.'}, 400 + try: create_persistent_volume_claim( name=persistent_volume_claim_create.name, From 7ca0725366d1f8a881ed991a88d40cbd30781415 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 15:57:37 +0000 Subject: [PATCH 25/65] fix: Suppress filter_too_much check on common --- applications/common/schemathesis.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/applications/common/schemathesis.toml b/applications/common/schemathesis.toml index 377648b5..509c4381 100644 --- a/applications/common/schemathesis.toml +++ b/applications/common/schemathesis.toml @@ -1,2 +1,5 @@ [phases.coverage] -unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] \ No newline at end of file +unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] + +[hypothesis] +suppress_health_check = ["filter_too_much"] \ No newline at end of file From bdeefb85d7bbb470e75faedd86d42dd6a02673fb Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 16:06:05 +0000 Subject: [PATCH 26/65] chore: Correct schemathesis toml syntax --- applications/workflows/schemathesis.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/workflows/schemathesis.toml b/applications/workflows/schemathesis.toml index eac1a14e..71a664b4 100644 --- a/applications/workflows/schemathesis.toml +++ b/applications/workflows/schemathesis.toml @@ -7,5 +7,5 @@ enabled = false # Set previous_search_token to empty to avoid invalid token generation # Since this is an optional parameter used for pagination, omitting it is valid -[parameters] +[parameters.query] previous_search_token = null \ No newline at end of file From 36049d124feff8b799020e01bee2053ce6a74a68 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 16:12:15 +0000 Subject: [PATCH 27/65] fix: Update volumemanager api --- applications/volumemanager/api/openapi.yaml | 6 ++++++ .../server/volumemanager/controllers/rest_controller.py | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/applications/volumemanager/api/openapi.yaml b/applications/volumemanager/api/openapi.yaml index 4875f6af..c756094c 100644 --- a/applications/volumemanager/api/openapi.yaml +++ b/applications/volumemanager/api/openapi.yaml @@ -54,6 +54,9 @@ paths: required: true schema: type: string + pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' + minLength: 1 + maxLength: 253 style: simple responses: "200": @@ -87,6 +90,9 @@ components: description: The size of the Persistent Volume Claim to create. example: 2Gi type: string + required: + - name + - size type: object PersistentVolumeClaim: example: diff --git a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py index 8c9b0177..d66639f4 100644 --- a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py +++ b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py @@ -45,11 +45,6 @@ def pvc_post(): # noqa: E501 """ if connexion.request.is_json: persistent_volume_claim_create = PersistentVolumeClaimCreate.from_dict(connexion.request.get_json()) # noqa: E501 - - # Validate required fields - if not persistent_volume_claim_create.name or not persistent_volume_claim_create.size: - return {'description': 'Name and size are required fields.'}, 400 - try: create_persistent_volume_claim( name=persistent_volume_claim_create.name, From bdcfd45e55554eeb6ddb2aab4150fe45f7927355 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 16:16:55 +0000 Subject: [PATCH 28/65] chore: Move schemathesis config to run param --- applications/common/deploy/values.yaml | 4 +++- applications/common/schemathesis.toml | 5 +---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/applications/common/deploy/values.yaml b/applications/common/deploy/values.yaml index 256492ad..2952c546 100644 --- a/applications/common/deploy/values.yaml +++ b/applications/common/deploy/values.yaml @@ -24,4 +24,6 @@ harness: enabled: true autotest: true checks: - - all \ No newline at end of file + - all + runParams: + - "--suppress-health-check=filter_too_much" \ No newline at end of file diff --git a/applications/common/schemathesis.toml b/applications/common/schemathesis.toml index 509c4381..377648b5 100644 --- a/applications/common/schemathesis.toml +++ b/applications/common/schemathesis.toml @@ -1,5 +1,2 @@ [phases.coverage] -unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] - -[hypothesis] -suppress_health_check = ["filter_too_much"] \ No newline at end of file +unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] \ No newline at end of file From 77dab73a70f93f45290f5050f3f70117dd6c0a00 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 16:31:26 +0000 Subject: [PATCH 29/65] chore: Correct schemathesis toml syntax --- applications/workflows/schemathesis.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/workflows/schemathesis.toml b/applications/workflows/schemathesis.toml index 71a664b4..8ecdc28b 100644 --- a/applications/workflows/schemathesis.toml +++ b/applications/workflows/schemathesis.toml @@ -8,4 +8,4 @@ enabled = false # Set previous_search_token to empty to avoid invalid token generation # Since this is an optional parameter used for pagination, omitting it is valid [parameters.query] -previous_search_token = null \ No newline at end of file +previous_search_token = "" \ No newline at end of file From a7d206f9ca19bb423e049dde6e9025434be15971 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 16:35:41 +0000 Subject: [PATCH 30/65] chore: Update codefresh test pipeline --- deployment/codefresh-test.yaml | 205 +++++++++++++++++---------------- 1 file changed, 103 insertions(+), 102 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 7f4e9560..eb4265e0 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -73,28 +73,6 @@ steps: == true forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false - accounts: - type: build - stage: build - dockerfile: Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/accounts - title: Accounts - working_directory: ./applications/accounts - tags: - - '${{ACCOUNTS_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{ACCOUNTS_TAG_EXISTS}}', '{{ACCOUNTS_TAG_EXISTS}}') - == true - forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') - == false test-e2e: type: build stage: build @@ -140,11 +118,56 @@ steps: '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false + accounts: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + image_name: cloud-harness/accounts + title: Accounts + working_directory: ./applications/accounts + tags: + - '${{ACCOUNTS_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{ACCOUNTS_TAG_EXISTS}}', '{{ACCOUNTS_TAG_EXISTS}}') + == true + forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') + == false title: Build parallel step 1 build_application_images_1: type: parallel stage: build steps: + workflows-notify-queue: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue + tags: + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false samples-sum: type: build stage: build @@ -168,7 +191,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -177,20 +200,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + == false jupyterhub: type: build stage: build @@ -238,30 +261,7 @@ steps: == true forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') == false - workflows-send-result-event: - type: build - stage: build - dockerfile: Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event - tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - samples-secret: + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -270,20 +270,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false samples-print-file: type: build stage: build @@ -307,7 +307,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - workflows-notify-queue: + cloudharness-flask: type: build stage: build dockerfile: Dockerfile @@ -316,21 +316,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false - cloudharness-flask: + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + == false + workflows-send-result-event: type: build stage: build dockerfile: Dockerfile @@ -339,20 +339,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') - == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false title: Build parallel step 2 build_application_images_2: type: parallel @@ -382,7 +382,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false - volumemanager: + common: type: build stage: build dockerfile: Dockerfile @@ -391,21 +391,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/volumemanager - title: Volumemanager - working_directory: ./applications/volumemanager/server + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{VOLUMEMANAGER_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false - common: + volumemanager: type: build stage: build dockerfile: Dockerfile @@ -414,19 +414,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/volumemanager + title: Volumemanager + working_directory: ./applications/volumemanager/server tags: - - '${{COMMON_TAG}}' + - '${{VOLUMEMANAGER_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false workflows: type: build @@ -485,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/volumemanager - - kubectl rollout status deployment/argo-gk + - kubectl rollout status deployment/common + - kubectl rollout status deployment/workflows - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk - - kubectl rollout status deployment/workflows + - kubectl rollout status deployment/volumemanager + - kubectl rollout status deployment/argo-gk - kubectl rollout status deployment/accounts - - kubectl rollout status deployment/common - sleep 60 tests_api: stage: qa @@ -525,8 +525,9 @@ steps: commands: - st run api/openapi.yaml --url https://samples.${{DOMAIN}}/api -c all --exclude-deprecated --exclude-operation-id=submit_sync --exclude-operation-id=submit_sync_with_results - --exclude-operation-id=error --suppress-health-check=too_slow --request-timeout=180000 - --max-examples=2 --exclude-checks=ignored_auth --exclude-method=TRACE + --exclude-operation-id=error --exclude-operation-id=valid_token --exclude-operation-id=valid_cookie + --suppress-health-check=too_slow --request-timeout=180000 --max-examples=2 + --exclude-checks=ignored_auth - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -549,7 +550,7 @@ steps: - APP_URL=https://common.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st run api/openapi.yaml --url https://common.${{DOMAIN}}/api -c all --exclude-method=TRACE + - st run api/openapi.yaml --url https://common.${{DOMAIN}}/api -c all --suppress-health-check=filter_too_much hooks: on_fail: exec: From 1ae316bb72607cd7f5707fccab068bb96ee9091e Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 16:38:54 +0000 Subject: [PATCH 31/65] fix: Update volume manager api --- applications/volumemanager/api/openapi.yaml | 9 ++++++++- .../volumemanager/controllers/rest_controller.py | 12 +++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/applications/volumemanager/api/openapi.yaml b/applications/volumemanager/api/openapi.yaml index c756094c..016964d3 100644 --- a/applications/volumemanager/api/openapi.yaml +++ b/applications/volumemanager/api/openapi.yaml @@ -32,7 +32,7 @@ paths: example: "Saved!" description: Save successful. "400": - description: The Persistent Volume Claim already exists. + description: Bad request - invalid or missing required fields. "401": description: Unauthorized - No authorization token provided. "500": @@ -65,6 +65,8 @@ paths: schema: $ref: '#/components/schemas/PersistentVolumeClaim' description: The Persistent Volume Claim. + "400": + description: Bad request - invalid path parameter or headers. "401": description: Unauthorized - No authorization token provided. "404": @@ -86,14 +88,19 @@ components: description: Unique name for the Persisten Volume Claim to create. example: pvc-1 type: string + minLength: 1 + pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' size: description: The size of the Persistent Volume Claim to create. example: 2Gi type: string + minLength: 1 + pattern: '^[0-9]+(Ei|Pi|Ti|Gi|Mi|Ki|E|P|T|G|M|K)?$' required: - name - size type: object + additionalProperties: false PersistentVolumeClaim: example: size: 2Gi diff --git a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py index d66639f4..4df3529e 100644 --- a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py +++ b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py @@ -1,7 +1,6 @@ import connexion import six import flask -import kubernetes.client.rest from cloudharness.service.pvc import create_persistent_volume_claim, get_persistent_volume_claim @@ -45,17 +44,16 @@ def pvc_post(): # noqa: E501 """ if connexion.request.is_json: persistent_volume_claim_create = PersistentVolumeClaimCreate.from_dict(connexion.request.get_json()) # noqa: E501 + + # Additional validation for empty strings (backup if Connexion doesn't catch it) + if not persistent_volume_claim_create.name or not persistent_volume_claim_create.size: + return {'description': 'Name and size are required and cannot be empty.'}, 400 + try: create_persistent_volume_claim( name=persistent_volume_claim_create.name, size=persistent_volume_claim_create.size, logger=flask.current_app.logger) - except kubernetes.client.rest.ApiException as e: - # Kubernetes returns 409 Conflict when resource already exists - if e.status == 409: - return {'description': 'The Persistent Volume Claim already exists.'}, 400 - flask.current_app.logger.error(f"Error creating PVC: {e}") - return {'description': f'Failed to create Persistent Volume Claim: {e.reason}'}, 500 except Exception as e: flask.current_app.logger.error(f"Error creating PVC: {e}") return {'description': f'Failed to create Persistent Volume Claim: {str(e)}'}, 500 From 1f5ae79c76996864599019a9ed49a87fc7f8c6ad Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 16:56:21 +0000 Subject: [PATCH 32/65] fix: Update volume manager api --- applications/volumemanager/api/openapi.yaml | 2 +- applications/volumemanager/schemathesis.toml | 6 +++++- .../server/volumemanager/controllers/rest_controller.py | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/applications/volumemanager/api/openapi.yaml b/applications/volumemanager/api/openapi.yaml index 016964d3..25dc5468 100644 --- a/applications/volumemanager/api/openapi.yaml +++ b/applications/volumemanager/api/openapi.yaml @@ -95,7 +95,7 @@ components: example: 2Gi type: string minLength: 1 - pattern: '^[0-9]+(Ei|Pi|Ti|Gi|Mi|Ki|E|P|T|G|M|K)?$' + pattern: '^[1-9][0-9]*(Ei|Pi|Ti|Gi|Mi|Ki|E|P|T|G|M|K)?$' required: - name - size diff --git a/applications/volumemanager/schemathesis.toml b/applications/volumemanager/schemathesis.toml index 377648b5..17672013 100644 --- a/applications/volumemanager/schemathesis.toml +++ b/applications/volumemanager/schemathesis.toml @@ -1,2 +1,6 @@ [phases.coverage] -unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] \ No newline at end of file +unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] + +# Disable negative testing - don't test with unknown/invalid properties +[phases.negative] +enabled = false \ No newline at end of file diff --git a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py index 4df3529e..7e692f78 100644 --- a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py +++ b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py @@ -45,7 +45,7 @@ def pvc_post(): # noqa: E501 if connexion.request.is_json: persistent_volume_claim_create = PersistentVolumeClaimCreate.from_dict(connexion.request.get_json()) # noqa: E501 - # Additional validation for empty strings (backup if Connexion doesn't catch it) + # Validate required fields (backup if Connexion doesn't catch it) if not persistent_volume_claim_create.name or not persistent_volume_claim_create.size: return {'description': 'Name and size are required and cannot be empty.'}, 400 From 45146da40ff0faa442be404cedf7c6bf9c426c22 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 18:11:24 +0000 Subject: [PATCH 33/65] fix: Update st check imports --- application-templates/base/test/api/test_st.py | 2 +- application-templates/django-base/api/test_st.py | 2 +- applications/samples/test/api/test_st.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/application-templates/base/test/api/test_st.py b/application-templates/base/test/api/test_st.py index 10b02338..9a631eee 100644 --- a/application-templates/base/test/api/test_st.py +++ b/application-templates/base/test/api/test_st.py @@ -1,7 +1,7 @@ import os from pprint import pprint import schemathesis as st -from schemathesis.checks import response_schema_conformance, not_a_server_error +from schemathesis.specs.openapi.checks import response_schema_conformance, not_a_server_error from cloudharness_test import apitest_init # include to perform default authorization diff --git a/application-templates/django-base/api/test_st.py b/application-templates/django-base/api/test_st.py index ddba7068..529dc744 100644 --- a/application-templates/django-base/api/test_st.py +++ b/application-templates/django-base/api/test_st.py @@ -1,7 +1,7 @@ import os from pprint import pprint import schemathesis as st -from schemathesis.checks import response_schema_conformance, not_a_server_error +from schemathesis.specs.openapi.checks import response_schema_conformance, not_a_server_error from cloudharness_test import apitest_init # include to perform default authorization diff --git a/applications/samples/test/api/test_st.py b/applications/samples/test/api/test_st.py index f1705a53..2069dee4 100644 --- a/applications/samples/test/api/test_st.py +++ b/applications/samples/test/api/test_st.py @@ -1,7 +1,7 @@ import os from pprint import pprint import schemathesis as st -from schemathesis.checks import response_schema_conformance, not_a_server_error +from schemathesis.specs.openapi.checks import response_schema_conformance, not_a_server_error from cloudharness_test import apitest_init # include to perform default authorization From 3c52e6f77c8d2e1c70dde2bf395909f1800fbd53 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 18:16:45 +0000 Subject: [PATCH 34/65] chore: Update st configurations --- applications/volumemanager/schemathesis.toml | 5 ++--- applications/workflows/schemathesis.toml | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/applications/volumemanager/schemathesis.toml b/applications/volumemanager/schemathesis.toml index 17672013..339b5ef3 100644 --- a/applications/volumemanager/schemathesis.toml +++ b/applications/volumemanager/schemathesis.toml @@ -1,6 +1,5 @@ [phases.coverage] unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] -# Disable negative testing - don't test with unknown/invalid properties -[phases.negative] -enabled = false \ No newline at end of file +[checks] +negative_data_rejection.enabled = false \ No newline at end of file diff --git a/applications/workflows/schemathesis.toml b/applications/workflows/schemathesis.toml index 8ecdc28b..52c057b1 100644 --- a/applications/workflows/schemathesis.toml +++ b/applications/workflows/schemathesis.toml @@ -1,11 +1,9 @@ [phases.coverage] unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] -# Disable negative testing - don't test with unknown/invalid properties -[phases.negative] -enabled = false +[checks] +negative_data_rejection.enabled = false # Set previous_search_token to empty to avoid invalid token generation -# Since this is an optional parameter used for pagination, omitting it is valid [parameters.query] previous_search_token = "" \ No newline at end of file From 9805990021f8009e2b9b9defd56c13e9609d4581 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 18:36:15 +0000 Subject: [PATCH 35/65] chore: Remove unused imports --- application-templates/base/test/api/test_st.py | 3 --- application-templates/django-base/api/test_st.py | 3 --- applications/samples/test/api/test_st.py | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/application-templates/base/test/api/test_st.py b/application-templates/base/test/api/test_st.py index 9a631eee..df75d4c9 100644 --- a/application-templates/base/test/api/test_st.py +++ b/application-templates/base/test/api/test_st.py @@ -1,8 +1,5 @@ import os -from pprint import pprint import schemathesis as st -from schemathesis.specs.openapi.checks import response_schema_conformance, not_a_server_error - from cloudharness_test import apitest_init # include to perform default authorization app_url = os.environ.get("APP_URL", "http://samples.ch.local/api") diff --git a/application-templates/django-base/api/test_st.py b/application-templates/django-base/api/test_st.py index 529dc744..b455cfb5 100644 --- a/application-templates/django-base/api/test_st.py +++ b/application-templates/django-base/api/test_st.py @@ -1,8 +1,5 @@ import os -from pprint import pprint import schemathesis as st -from schemathesis.specs.openapi.checks import response_schema_conformance, not_a_server_error - from cloudharness_test import apitest_init # include to perform default authorization app_url = os.environ.get("APP_URL", "http://samples.ch.local/api") diff --git a/applications/samples/test/api/test_st.py b/applications/samples/test/api/test_st.py index 2069dee4..f062d7a8 100644 --- a/applications/samples/test/api/test_st.py +++ b/applications/samples/test/api/test_st.py @@ -1,7 +1,7 @@ import os from pprint import pprint import schemathesis as st -from schemathesis.specs.openapi.checks import response_schema_conformance, not_a_server_error +from schemathesis.specs.openapi.checks import response_schema_conformance from cloudharness_test import apitest_init # include to perform default authorization From a511aae9286142297bd58de9adb040d3f3016013 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 18:41:48 +0000 Subject: [PATCH 36/65] fix: Add validation to volumeManager params --- .../controllers/rest_controller.py | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py index 7e692f78..b6818179 100644 --- a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py +++ b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py @@ -1,6 +1,7 @@ import connexion import six import flask +import re from cloudharness.service.pvc import create_persistent_volume_claim, get_persistent_volume_claim @@ -23,13 +24,16 @@ def pvc_name_get(name): # noqa: E501 if not pvc: return f"Persistent Volume Claim with name {name} not found.", 404 - pvc = PersistentVolumeClaim( + # Extract access mode safely + access_mode = pvc.status.access_modes[0] if pvc.status.access_modes else '' + + pvc_response = PersistentVolumeClaim( name=pvc.metadata.name, namespace=pvc.metadata.namespace, - accessmode=pvc.status.access_modes[0], + accessmode=access_mode, size=pvc.status.capacity.get('storage', '') ) - return pvc + return pvc_response def pvc_post(): # noqa: E501 @@ -45,10 +49,20 @@ def pvc_post(): # noqa: E501 if connexion.request.is_json: persistent_volume_claim_create = PersistentVolumeClaimCreate.from_dict(connexion.request.get_json()) # noqa: E501 - # Validate required fields (backup if Connexion doesn't catch it) + # Validate required fields if not persistent_volume_claim_create.name or not persistent_volume_claim_create.size: return {'description': 'Name and size are required and cannot be empty.'}, 400 + # Validate name format (Kubernetes DNS-1123 subdomain) + name_pattern = re.compile(r'^[a-z0-9]([-a-z0-9]*[a-z0-9])?$') + if not name_pattern.match(persistent_volume_claim_create.name) or len(persistent_volume_claim_create.name) > 253: + return {'description': 'Name must be a valid DNS-1123 subdomain (lowercase alphanumeric characters, "-", and must start and end with an alphanumeric character, max 253 characters).'}, 400 + + # Validate size format + size_pattern = re.compile(r'^[1-9][0-9]*(Ei|Pi|Ti|Gi|Mi|Ki|E|P|T|G|M|K)?$') + if not size_pattern.match(persistent_volume_claim_create.size): + return {'description': 'Size must be a valid Kubernetes resource quantity (e.g., 2Gi, 500Mi).'}, 400 + try: create_persistent_volume_claim( name=persistent_volume_claim_create.name, From 1dcefc3d6cfdf0486da1466e445268186a9c6fd8 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 18:47:32 +0000 Subject: [PATCH 37/65] fix: Set emtpy string previous_search_token to None --- .../workflows_api/controllers/create_and_access_controller.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py b/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py index 0d127a79..d0734874 100644 --- a/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py +++ b/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py @@ -65,6 +65,9 @@ def list_operations(status=None, previous_search_token=None, limit=None): # noq :rtype: OperationSearchResult """ + if previous_search_token == "": + previous_search_token = None + try: return workflow_service.list_operations(status, continue_token=previous_search_token, limit=limit) except BadParam as e: From 4e261e2c9f183b11ad8bf0525195d3c85260add6 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 19:01:04 +0000 Subject: [PATCH 38/65] fix: Update from_uri calls --- application-templates/base/test/api/test_st.py | 2 +- application-templates/django-base/api/test_st.py | 4 ++-- applications/samples/test/api/test_st.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/application-templates/base/test/api/test_st.py b/application-templates/base/test/api/test_st.py index df75d4c9..3edef511 100644 --- a/application-templates/base/test/api/test_st.py +++ b/application-templates/base/test/api/test_st.py @@ -4,7 +4,7 @@ app_url = os.environ.get("APP_URL", "http://samples.ch.local/api") -schema = st.from_uri(app_url + "/openapi.json") +schema = st.openapi.from_url(app_url + "/openapi.json") @schema.include(path="/ping", method="GET").parametrize() diff --git a/application-templates/django-base/api/test_st.py b/application-templates/django-base/api/test_st.py index b455cfb5..0c52e9f9 100644 --- a/application-templates/django-base/api/test_st.py +++ b/application-templates/django-base/api/test_st.py @@ -5,10 +5,10 @@ app_url = os.environ.get("APP_URL", "http://samples.ch.local/api") try: - schema = st.from_uri(app_url + "/openapi.json") + schema = st.openapi.from_url(app_url + "/openapi.json") except: # support alternative schema location - schema = st.from_uri(app_url.replace("/api", "") + "/openapi.json") + schema = st.openapi.from_url(app_url.replace("/api", "") + "/openapi.json") @schema.include(path="/ping", method="GET").parametrize() diff --git a/applications/samples/test/api/test_st.py b/applications/samples/test/api/test_st.py index f062d7a8..ceeb205f 100644 --- a/applications/samples/test/api/test_st.py +++ b/applications/samples/test/api/test_st.py @@ -7,7 +7,7 @@ app_url = os.environ.get("APP_URL", "http://samples.ch.local/api") -schema = st.from_uri(app_url + "/openapi.json") +schema = st.openapi.from_url(app_url + "/openapi.json") @schema.include(path="/error", method="GET").parametrize() From 044ec683a493c6fb685a48c90501a730e0866fb4 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 19:04:48 +0000 Subject: [PATCH 39/65] fix: Update volume manager api --- .../volumemanager/controllers/rest_controller.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py index b6818179..c895300f 100644 --- a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py +++ b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py @@ -2,6 +2,7 @@ import six import flask import re +from kubernetes.client.rest import ApiException from cloudharness.service.pvc import create_persistent_volume_claim, get_persistent_volume_claim @@ -25,13 +26,18 @@ def pvc_name_get(name): # noqa: E501 return f"Persistent Volume Claim with name {name} not found.", 404 # Extract access mode safely - access_mode = pvc.status.access_modes[0] if pvc.status.access_modes else '' + access_mode = pvc.status.access_modes[0] if pvc.status and pvc.status.access_modes else '' + + # Extract size safely + size = '' + if pvc.status and pvc.status.capacity: + size = pvc.status.capacity.get('storage', '') pvc_response = PersistentVolumeClaim( name=pvc.metadata.name, namespace=pvc.metadata.namespace, accessmode=access_mode, - size=pvc.status.capacity.get('storage', '') + size=size ) return pvc_response @@ -68,6 +74,12 @@ def pvc_post(): # noqa: E501 name=persistent_volume_claim_create.name, size=persistent_volume_claim_create.size, logger=flask.current_app.logger) + except ApiException as e: + flask.current_app.logger.error(f"Kubernetes API error creating PVC: {e}") + # Return 400 for client errors (bad request to k8s), 500 for server errors + if e.status >= 400 and e.status < 500: + return {'description': f'Invalid PVC configuration: {e.reason}'}, 400 + return {'description': f'Failed to create Persistent Volume Claim: {e.reason}'}, 500 except Exception as e: flask.current_app.logger.error(f"Error creating PVC: {e}") return {'description': f'Failed to create Persistent Volume Claim: {str(e)}'}, 500 From b10f9772686ca74d45e1511bb5a7d96d638aa639 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 19:16:30 +0000 Subject: [PATCH 40/65] chore: Update schemathesis config --- applications/workflows/schemathesis.toml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/applications/workflows/schemathesis.toml b/applications/workflows/schemathesis.toml index 52c057b1..414ad939 100644 --- a/applications/workflows/schemathesis.toml +++ b/applications/workflows/schemathesis.toml @@ -4,6 +4,7 @@ unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] [checks] negative_data_rejection.enabled = false -# Set previous_search_token to empty to avoid invalid token generation -[parameters.query] -previous_search_token = "" \ No newline at end of file + +[[operations]] +include-name = "GET /operations" +parameters = { previous_search_token = "" } From c6ac8bd1b3e32d302ff1563833c5f87262b0271b Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 19:34:45 +0000 Subject: [PATCH 41/65] chore: Update runParams --- applications/samples/deploy/values.yaml | 1 + applications/workflows/deploy/values.yaml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/applications/samples/deploy/values.yaml b/applications/samples/deploy/values.yaml index e4c3b42a..67efed6c 100644 --- a/applications/samples/deploy/values.yaml +++ b/applications/samples/deploy/values.yaml @@ -85,6 +85,7 @@ harness: - "--exclude-operation-id=valid_token" - "--exclude-operation-id=valid_cookie" - "--suppress-health-check=too_slow" + - "--suppress-health-check=filter_too_much" - "--request-timeout=180000" - "--max-examples=2" - "--exclude-checks=ignored_auth" diff --git a/applications/workflows/deploy/values.yaml b/applications/workflows/deploy/values.yaml index 15c8706a..d9b4531e 100644 --- a/applications/workflows/deploy/values.yaml +++ b/applications/workflows/deploy/values.yaml @@ -18,3 +18,5 @@ harness: autotest: true checks: - all + runParams: + - "--suppress-health-check=filter_too_much" \ No newline at end of file From da0533fd77c664d2eb8dd401800751e4904f74a4 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 20:02:02 +0000 Subject: [PATCH 42/65] chore: Add debug messages --- applications/samples/test/api/test_st.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/applications/samples/test/api/test_st.py b/applications/samples/test/api/test_st.py index ceeb205f..b9f03613 100644 --- a/applications/samples/test/api/test_st.py +++ b/applications/samples/test/api/test_st.py @@ -12,8 +12,27 @@ @schema.include(path="/error", method="GET").parametrize() def test_api(case): - response = case.call() - assert response.status_code >= 500, "this api errors on purpose" + try: + response = case.call() + debug_info = ( + f"[DEBUG] Request URL: {getattr(response.request, 'url', None)}\n" + f"[DEBUG] Request method: {getattr(response.request, 'method', None)}\n" + f"[DEBUG] Response status: {getattr(response, 'status_code', None)}\n" + f"[DEBUG] Response headers: {dict(getattr(response, 'headers', {}))}\n" + f"[DEBUG] Response body: {getattr(response, 'text', None)}\n" + ) + print(debug_info) + assert response.status_code >= 500, "this api errors on purpose" + except Exception as e: + # Print debug info even if assertion fails + if 'response' in locals(): + print("[EXCEPTION DEBUG] Request URL:", getattr(response.request, 'url', None)) + print("[EXCEPTION DEBUG] Request method:", getattr(response.request, 'method', None)) + print("[EXCEPTION DEBUG] Response status:", getattr(response, 'status_code', None)) + print("[EXCEPTION DEBUG] Response headers:", dict(getattr(response, 'headers', {}))) + print("[EXCEPTION DEBUG] Response body:", getattr(response, 'text', None)) + print("[EXCEPTION]", e) + raise @schema.include(path="/valid", method="GET").parametrize() From a63cfefebe43d7a2698903f0ef3f6491efab50ed Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 20:25:30 +0000 Subject: [PATCH 43/65] chore: Override size parameter --- applications/volumemanager/schemathesis.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/applications/volumemanager/schemathesis.toml b/applications/volumemanager/schemathesis.toml index 339b5ef3..68d1e3f5 100644 --- a/applications/volumemanager/schemathesis.toml +++ b/applications/volumemanager/schemathesis.toml @@ -2,4 +2,8 @@ unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] [checks] -negative_data_rejection.enabled = false \ No newline at end of file +negative_data_rejection.enabled = false + +[[operations]] +include-name = "POST /pvc" +parameters = { size = "2Gi" } \ No newline at end of file From 632f8dd270fc9c052a5073ee8ee7797080e6fc70 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 23:20:56 +0000 Subject: [PATCH 44/65] fix: Update samples test --- applications/samples/test/api/test_st.py | 32 ++++++++---------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/applications/samples/test/api/test_st.py b/applications/samples/test/api/test_st.py index b9f03613..253a6619 100644 --- a/applications/samples/test/api/test_st.py +++ b/applications/samples/test/api/test_st.py @@ -12,27 +12,17 @@ @schema.include(path="/error", method="GET").parametrize() def test_api(case): - try: - response = case.call() - debug_info = ( - f"[DEBUG] Request URL: {getattr(response.request, 'url', None)}\n" - f"[DEBUG] Request method: {getattr(response.request, 'method', None)}\n" - f"[DEBUG] Response status: {getattr(response, 'status_code', None)}\n" - f"[DEBUG] Response headers: {dict(getattr(response, 'headers', {}))}\n" - f"[DEBUG] Response body: {getattr(response, 'text', None)}\n" - ) - print(debug_info) - assert response.status_code >= 500, "this api errors on purpose" - except Exception as e: - # Print debug info even if assertion fails - if 'response' in locals(): - print("[EXCEPTION DEBUG] Request URL:", getattr(response.request, 'url', None)) - print("[EXCEPTION DEBUG] Request method:", getattr(response.request, 'method', None)) - print("[EXCEPTION DEBUG] Response status:", getattr(response, 'status_code', None)) - print("[EXCEPTION DEBUG] Response headers:", dict(getattr(response, 'headers', {}))) - print("[EXCEPTION DEBUG] Response body:", getattr(response, 'text', None)) - print("[EXCEPTION]", e) - raise + response = case.call() + + if case.method == "GET": + # Assert that this endpoint returns a 500 error as expected + assert response.status_code == 500, f"Expected 500 error, got {response.status_code}. This api errors on purpose." + elif case.method == "OPTIONS": + # OPTIONS requests typically return 200 OK + assert response.status_code == 200, f"Expected 200 OK for OPTIONS, got {response.status_code}." + else: + # Other methods should return 405 (Method Not Allowed) + assert response.status_code == 405, f"Expected 405 (Method Not Allowed) for {case.method}, got {response.status_code}." @schema.include(path="/valid", method="GET").parametrize() From 0f0ccd10cc7e8de7b7321bdb40ef2f74a048381f Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 27 Oct 2025 23:52:37 +0000 Subject: [PATCH 45/65] chore: Limit volumemanager tests to examples only --- applications/volumemanager/deploy/values.yaml | 5 +- applications/volumemanager/schemathesis.toml | 4 - .../controllers/rest_controller.py | 11 - deployment/codefresh-test.yaml | 274 +++++++++--------- 4 files changed, 142 insertions(+), 152 deletions(-) diff --git a/applications/volumemanager/deploy/values.yaml b/applications/volumemanager/deploy/values.yaml index 0b10b02d..e2e6e00f 100644 --- a/applications/volumemanager/deploy/values.yaml +++ b/applications/volumemanager/deploy/values.yaml @@ -18,4 +18,7 @@ harness: enabled: true autotest: true checks: - - all \ No newline at end of file + - all + runParams: + - "--phases=examples" + - "--max-examples=1" \ No newline at end of file diff --git a/applications/volumemanager/schemathesis.toml b/applications/volumemanager/schemathesis.toml index 68d1e3f5..fc9bd19e 100644 --- a/applications/volumemanager/schemathesis.toml +++ b/applications/volumemanager/schemathesis.toml @@ -3,7 +3,3 @@ unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] [checks] negative_data_rejection.enabled = false - -[[operations]] -include-name = "POST /pvc" -parameters = { size = "2Gi" } \ No newline at end of file diff --git a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py index c895300f..81eab15f 100644 --- a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py +++ b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py @@ -58,17 +58,6 @@ def pvc_post(): # noqa: E501 # Validate required fields if not persistent_volume_claim_create.name or not persistent_volume_claim_create.size: return {'description': 'Name and size are required and cannot be empty.'}, 400 - - # Validate name format (Kubernetes DNS-1123 subdomain) - name_pattern = re.compile(r'^[a-z0-9]([-a-z0-9]*[a-z0-9])?$') - if not name_pattern.match(persistent_volume_claim_create.name) or len(persistent_volume_claim_create.name) > 253: - return {'description': 'Name must be a valid DNS-1123 subdomain (lowercase alphanumeric characters, "-", and must start and end with an alphanumeric character, max 253 characters).'}, 400 - - # Validate size format - size_pattern = re.compile(r'^[1-9][0-9]*(Ei|Pi|Ti|Gi|Mi|Ki|E|P|T|G|M|K)?$') - if not size_pattern.match(persistent_volume_claim_create.size): - return {'description': 'Size must be a valid Kubernetes resource quantity (e.g., 2Gi, 500Mi).'}, 400 - try: create_persistent_volume_claim( name=persistent_volume_claim_create.name, diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index eb4265e0..359430bb 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -51,29 +51,7 @@ steps: type: parallel stage: build steps: - cloudharness-base: - type: build - stage: build - dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-base - title: Cloudharness base - working_directory: ./. - tags: - - '${{CLOUDHARNESS_BASE_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') - == true - forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') - == false - test-e2e: + accounts: type: build stage: build dockerfile: Dockerfile @@ -81,20 +59,19 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/test-e2e - title: Test e2e - working_directory: ./test/test-e2e + image_name: cloud-harness/accounts + title: Accounts + working_directory: ./applications/accounts tags: - - '${{TEST_E2E_TAG}}' + - '${{ACCOUNTS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') + buildDoesNotExist: includes('${{ACCOUNTS_TAG_EXISTS}}', '{{ACCOUNTS_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') == false cloudharness-frontend-build: type: build @@ -118,34 +95,29 @@ steps: '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false - accounts: + cloudharness-base: type: build stage: build - dockerfile: Dockerfile + dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/accounts - title: Accounts - working_directory: ./applications/accounts + image_name: cloud-harness/cloudharness-base + title: Cloudharness base + working_directory: ./. tags: - - '${{ACCOUNTS_TAG}}' + - '${{CLOUDHARNESS_BASE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{ACCOUNTS_TAG_EXISTS}}', '{{ACCOUNTS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') == true - forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false - title: Build parallel step 1 - build_application_images_1: - type: parallel - stage: build - steps: - workflows-notify-queue: + test-e2e: type: build stage: build dockerfile: Dockerfile @@ -153,22 +125,27 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/test-e2e + title: Test e2e + working_directory: ./test/test-e2e tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{TEST_E2E_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false - samples-sum: + buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') + == false + title: Build parallel step 1 + build_application_images_1: + type: parallel + stage: build + steps: + cloudharness-flask: type: build stage: build dockerfile: Dockerfile @@ -177,21 +154,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false - samples-secret: + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -200,67 +177,67 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - jupyterhub: + test-api: type: build stage: build - dockerfile: Dockerfile + dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/test-api + title: Test api + working_directory: ./. tags: - - '${{JUPYTERHUB_TAG}}' + - '${{TEST_API_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') == false - test-api: + workflows-notify-queue: type: build stage: build - dockerfile: test/test-api/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/test-api - title: Test api - working_directory: ./. + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{TEST_API_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') - == true - forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false workflows-extract-download: type: build stage: build @@ -284,7 +261,7 @@ steps: '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - samples-print-file: + workflows-send-result-event: type: build stage: build dockerfile: Dockerfile @@ -293,21 +270,44 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false + jupyterhub: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub + tags: + - '${{JUPYTERHUB_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') == false - cloudharness-flask: + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -316,21 +316,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') == false - workflows-send-result-event: + samples-sum: type: build stage: build dockerfile: Dockerfile @@ -339,26 +339,26 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + == false title: Build parallel step 2 build_application_images_2: type: parallel stage: build steps: - samples: + common: type: build stage: build dockerfile: Dockerfile @@ -366,23 +366,22 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/samples - title: Samples - working_directory: ./applications/samples + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{SAMPLES_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false - common: + workflows: type: build stage: build dockerfile: Dockerfile @@ -391,19 +390,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{COMMON_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false volumemanager: type: build @@ -428,7 +427,7 @@ steps: == true forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false - workflows: + samples: type: build stage: build dockerfile: Dockerfile @@ -436,20 +435,21 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/samples + title: Samples + working_directory: ./applications/samples tags: - - '${{WORKFLOWS_TAG}}' + - '${{SAMPLES_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 tests_unit: @@ -486,11 +486,11 @@ steps: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - kubectl rollout status deployment/common - - kubectl rollout status deployment/workflows + - kubectl rollout status deployment/volumemanager - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk - - kubectl rollout status deployment/volumemanager - kubectl rollout status deployment/argo-gk + - kubectl rollout status deployment/workflows - kubectl rollout status deployment/accounts - sleep 60 tests_api: @@ -511,7 +511,7 @@ steps: - APP_URL=https://workflows.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st run api/openapi.yaml --url https://workflows.${{DOMAIN}}/api -c all + - st run api/openapi.yaml --url https://workflows.${{DOMAIN}}/api -c all --suppress-health-check=filter_too_much samples_api_test: title: samples api test volumes: @@ -526,8 +526,8 @@ steps: - st run api/openapi.yaml --url https://samples.${{DOMAIN}}/api -c all --exclude-deprecated --exclude-operation-id=submit_sync --exclude-operation-id=submit_sync_with_results --exclude-operation-id=error --exclude-operation-id=valid_token --exclude-operation-id=valid_cookie - --suppress-health-check=too_slow --request-timeout=180000 --max-examples=2 - --exclude-checks=ignored_auth + --suppress-health-check=too_slow --suppress-health-check=filter_too_much + --request-timeout=180000 --max-examples=2 --exclude-checks=ignored_auth - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -541,6 +541,8 @@ steps: - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - st run api/openapi.yaml --url https://volumemanager.${{DOMAIN}}/api -c all + --phases=examples --max-examples=1 + - pytest -v test/api common_api_test: title: common api test volumes: From 92f93db5d1fcd7b5feddeeb0426616c84852153a Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Tue, 28 Oct 2025 00:11:20 +0000 Subject: [PATCH 46/65] chore: Update codefresh pipeline --- deployment/codefresh-test.yaml | 211 ++++++++++++++++----------------- 1 file changed, 105 insertions(+), 106 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 359430bb..2ce8315e 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -73,6 +73,29 @@ steps: == true forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') == false + test-e2e: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + image_name: cloud-harness/test-e2e + title: Test e2e + working_directory: ./test/test-e2e + tags: + - '${{TEST_E2E_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest + when: + condition: + any: + buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') + == false cloudharness-frontend-build: type: build stage: build @@ -117,35 +140,12 @@ steps: == true forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false - test-e2e: - type: build - stage: build - dockerfile: Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/test-e2e - title: Test e2e - working_directory: ./test/test-e2e - tags: - - '${{TEST_E2E_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest - when: - condition: - any: - buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') - == true - forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') - == false title: Build parallel step 1 build_application_images_1: type: parallel stage: build steps: - cloudharness-flask: + samples-sum: type: build stage: build dockerfile: Dockerfile @@ -154,21 +154,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') == false - samples-print-file: + jupyterhub: type: build stage: build dockerfile: Dockerfile @@ -177,19 +177,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') == false test-api: type: build @@ -215,7 +215,7 @@ steps: == true forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') == false - workflows-notify-queue: + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -224,21 +224,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + == false + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -247,20 +247,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + == false workflows-send-result-event: type: build stage: build @@ -284,7 +284,7 @@ steps: '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - jupyterhub: + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -293,21 +293,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{JUPYTERHUB_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') - == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') - == false - samples-secret: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -316,21 +316,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') - == false - samples-sum: + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + cloudharness-flask: type: build stage: build dockerfile: Dockerfile @@ -339,26 +339,26 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false title: Build parallel step 2 build_application_images_2: type: parallel stage: build steps: - common: + volumemanager: type: build stage: build dockerfile: Dockerfile @@ -367,21 +367,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/volumemanager + title: Volumemanager + working_directory: ./applications/volumemanager/server tags: - - '${{COMMON_TAG}}' + - '${{VOLUMEMANAGER_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false - workflows: + common: type: build stage: build dockerfile: Dockerfile @@ -390,21 +390,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{WORKFLOWS_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false - volumemanager: + workflows: type: build stage: build dockerfile: Dockerfile @@ -413,19 +413,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/volumemanager - title: Volumemanager - working_directory: ./applications/volumemanager/server + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{VOLUMEMANAGER_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false samples: type: build @@ -485,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/common + - kubectl rollout status deployment/argo-gk + - kubectl rollout status deployment/accounts - kubectl rollout status deployment/volumemanager + - kubectl rollout status deployment/common + - kubectl rollout status deployment/workflows - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk - - kubectl rollout status deployment/argo-gk - - kubectl rollout status deployment/workflows - - kubectl rollout status deployment/accounts - sleep 60 tests_api: stage: qa @@ -542,7 +542,6 @@ steps: commands: - st run api/openapi.yaml --url https://volumemanager.${{DOMAIN}}/api -c all --phases=examples --max-examples=1 - - pytest -v test/api common_api_test: title: common api test volumes: From 5c5b2d2dc2469cbe57017379290eb0df11442b45 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Tue, 28 Oct 2025 09:39:04 +0000 Subject: [PATCH 47/65] chore: Update schemathesis config --- applications/samples/deploy/values.yaml | 2 - applications/samples/schemathesis.toml | 12 +- deployment/codefresh-test.yaml | 231 ++++++++++++------------ 3 files changed, 126 insertions(+), 119 deletions(-) diff --git a/applications/samples/deploy/values.yaml b/applications/samples/deploy/values.yaml index 67efed6c..1b527d55 100644 --- a/applications/samples/deploy/values.yaml +++ b/applications/samples/deploy/values.yaml @@ -82,8 +82,6 @@ harness: - "--exclude-operation-id=submit_sync" - "--exclude-operation-id=submit_sync_with_results" - "--exclude-operation-id=error" - - "--exclude-operation-id=valid_token" - - "--exclude-operation-id=valid_cookie" - "--suppress-health-check=too_slow" - "--suppress-health-check=filter_too_much" - "--request-timeout=180000" diff --git a/applications/samples/schemathesis.toml b/applications/samples/schemathesis.toml index 377648b5..1b6ff3fc 100644 --- a/applications/samples/schemathesis.toml +++ b/applications/samples/schemathesis.toml @@ -1,2 +1,12 @@ [phases.coverage] -unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] \ No newline at end of file +unexpected-methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] + +[[operations]] +include-operation-id = "valid_token" +[operations.checks] +negative_data_rejection.enabled = false + +[[operations]] +include-operation-id = "valid_cookie" +[operations.checks] +negative_data_rejection.enabled = false \ No newline at end of file diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 2ce8315e..b99c6d31 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -73,28 +73,27 @@ steps: == true forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') == false - test-e2e: + cloudharness-base: type: build stage: build - dockerfile: Dockerfile + dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/test-e2e - title: Test e2e - working_directory: ./test/test-e2e + image_name: cloud-harness/cloudharness-base + title: Cloudharness base + working_directory: ./. tags: - - '${{TEST_E2E_TAG}}' + - '${{CLOUDHARNESS_BASE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false cloudharness-frontend-build: type: build @@ -118,34 +117,35 @@ steps: '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false - cloudharness-base: + test-e2e: type: build stage: build - dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-base - title: Cloudharness base - working_directory: ./. + image_name: cloud-harness/test-e2e + title: Test e2e + working_directory: ./test/test-e2e tags: - - '${{CLOUDHARNESS_BASE_TAG}}' + - '${{TEST_E2E_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') == false title: Build parallel step 1 build_application_images_1: type: parallel stage: build steps: - samples-sum: + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -154,21 +154,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - jupyterhub: + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -177,20 +177,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{JUPYTERHUB_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') - == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false test-api: type: build stage: build @@ -215,30 +215,7 @@ steps: == true forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') == false - samples-print-file: - type: build - stage: build - dockerfile: Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file - tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') - == false - samples-secret: + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -247,20 +224,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false workflows-send-result-event: type: build stage: build @@ -284,7 +261,7 @@ steps: '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -293,21 +270,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - workflows-notify-queue: + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + == false + jupyterhub: type: build stage: build dockerfile: Dockerfile @@ -316,20 +293,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') + == true + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') + == false cloudharness-flask: type: build stage: build @@ -353,12 +330,7 @@ steps: == true forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false - title: Build parallel step 2 - build_application_images_2: - type: parallel - stage: build - steps: - volumemanager: + samples-sum: type: build stage: build dockerfile: Dockerfile @@ -366,22 +338,27 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/volumemanager - title: Volumemanager - working_directory: ./applications/volumemanager/server + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{VOLUMEMANAGER_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') == true - forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') == false - common: + title: Build parallel step 2 + build_application_images_2: + type: parallel + stage: build + steps: + samples: type: build stage: build dockerfile: Dockerfile @@ -389,20 +366,21 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/samples + title: Samples + working_directory: ./applications/samples tags: - - '${{COMMON_TAG}}' + - '${{SAMPLES_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false workflows: type: build @@ -427,7 +405,7 @@ steps: == true forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false - samples: + volumemanager: type: build stage: build dockerfile: Dockerfile @@ -435,21 +413,43 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/samples - title: Samples - working_directory: ./applications/samples + image_name: cloud-harness/volumemanager + title: Volumemanager + working_directory: ./applications/volumemanager/server tags: - - '${{SAMPLES_TAG}}' + - '${{VOLUMEMANAGER_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') + buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + == false + common: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server + tags: + - '${{COMMON_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + == true + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 tests_unit: @@ -485,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/argo-gk - - kubectl rollout status deployment/accounts + - kubectl rollout status deployment/workflows - kubectl rollout status deployment/volumemanager + - kubectl rollout status deployment/accounts - kubectl rollout status deployment/common - - kubectl rollout status deployment/workflows - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk + - kubectl rollout status deployment/argo-gk - sleep 60 tests_api: stage: qa @@ -525,8 +525,7 @@ steps: commands: - st run api/openapi.yaml --url https://samples.${{DOMAIN}}/api -c all --exclude-deprecated --exclude-operation-id=submit_sync --exclude-operation-id=submit_sync_with_results - --exclude-operation-id=error --exclude-operation-id=valid_token --exclude-operation-id=valid_cookie - --suppress-health-check=too_slow --suppress-health-check=filter_too_much + --exclude-operation-id=error --suppress-health-check=too_slow --suppress-health-check=filter_too_much --request-timeout=180000 --max-examples=2 --exclude-checks=ignored_auth - pytest -v test/api volumemanager_api_test: From d095a3d935dc5750323932dbd1fdde5f4fe92d79 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Tue, 28 Oct 2025 12:12:58 +0000 Subject: [PATCH 48/65] feat(api tests): switch schemathesis invocation to harness-test; move auth header generation into get_schemathesis_command and remove TokenAuth hooks --- .../cloudharness_utils/testing/api.py | 60 +++++++++++++++++-- .../cloudharness_test/api.py | 2 +- .../cloudharness_test/apitest_init.py | 28 +-------- .../ch_cli_tools/codefresh.py | 14 ++++- 4 files changed, 68 insertions(+), 36 deletions(-) diff --git a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py index b59fdcb2..e9c3bea3 100644 --- a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py +++ b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py @@ -1,8 +1,10 @@ import os +import logging from ruamel.yaml import YAML from cloudharness_model.models import ApiTestsConfig, ApplicationHarnessConfig +from cloudharness.auth import get_token yaml = YAML(typ='safe') @@ -11,19 +13,67 @@ def get_api_filename(app_dir): return os.path.join(app_dir, "api", "openapi.yaml") -def get_schemathesis_command(api_filename, app_config: ApplicationHarnessConfig, app_domain: str): - # Make sure to set SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init in environment to use the custom hooks - return ["st", "run", api_filename, *get_schemathesis_params(app_config, app_domain)] +def get_schemathesis_command(api_filename, app_config: ApplicationHarnessConfig, app_domain: str, app_env: dict | None = None): + """ + Build the schemathesis command for running API tests. + Extended to support runtime authentication header generation directly in the command instead of relying on hooks. + """ + return ["st", "run", api_filename, *get_schemathesis_params(app_config, app_domain, app_env)] -def get_schemathesis_params(app_config: ApplicationHarnessConfig, app_domain: str): + +def _get_auth_headers(app_env: dict): + """Return list of CLI flags setting auth & headers based on environment. + + Supported: + - USERNAME/PASSWORD -> basic auth OR bearer token if token retrievable + - API_KEY -> X-API-Key header + - BEARER_TOKEN explicit -> Authorization header + Priority order: + 1. Explicit BEARER_TOKEN + 2. USERNAME/PASSWORD -> try get_token (Keycloak) then fallback to --auth basic + 3. API_KEY header + """ + if not app_env: + return [] + flags = [] + + bearer = app_env.get("BEARER_TOKEN") + username = app_env.get("USERNAME") + password = app_env.get("PASSWORD") + api_key = app_env.get("API_KEY") + + if bearer: + flags += ["--header", f"Authorization: Bearer {bearer}"] + elif username and password: + # Attempt to retrieve token; if fails, fallback to basic auth + try: + token = get_token(username, password) + if token: + flags += ["--header", f"Authorization: Bearer {token}"] + # also cookie header if needed by backend + flags += ["--header", f"Cookie: kc-access={token}"] + else: + flags += ["--auth", f"{username}:{password}"] + except Exception as e: + logging.warning("Failed to retrieve bearer token; fallback to basic auth: %s", e) + flags += ["--auth", f"{username}:{password}"] + + if api_key: + flags += ["--header", f"X-API-Key: {api_key}"] + return flags + + +def get_schemathesis_params(app_config: ApplicationHarnessConfig, app_domain: str, app_env: dict | None = None): params = ["--url", app_domain] api_config: ApiTestsConfig = app_config.test.api if api_config.checks: for c in api_config.checks: params += ["-c", c] - return [*params, *api_config.run_params] + params.extend(api_config.run_params) + params.extend(_get_auth_headers(app_env or {})) + return params def get_urls_from_api_file(api_filename): diff --git a/tools/cloudharness-test/cloudharness_test/api.py b/tools/cloudharness-test/cloudharness_test/api.py index af80f6bd..09ed8e2d 100644 --- a/tools/cloudharness-test/cloudharness_test/api.py +++ b/tools/cloudharness-test/cloudharness_test/api.py @@ -69,7 +69,7 @@ def run_api_tests(root_paths, helm_values: HarnessMainConfig, base_domain, inclu if api_config.autotest: logging.info("Running auto api tests") - cmd = get_schemathesis_command(api_filename, app_config, app_domain) + cmd = get_schemathesis_command(api_filename, app_config, app_domain, app_env) logging.info("Running: %s", " ".join(cmd)) result = subprocess.run(cmd, env=app_env, cwd=app_dir) diff --git a/tools/cloudharness-test/cloudharness_test/apitest_init.py b/tools/cloudharness-test/cloudharness_test/apitest_init.py index 42d8d9f1..aa9a795e 100644 --- a/tools/cloudharness-test/cloudharness_test/apitest_init.py +++ b/tools/cloudharness-test/cloudharness_test/apitest_init.py @@ -4,8 +4,6 @@ import schemathesis as st from schemathesis.hooks import HookContext -from cloudharness.auth import get_token - if "APP_URL" or "APP_SCHEMA_FILE" in os.environ: app_schema = os.environ.get("APP_SCHEMA_FILE", None) @@ -45,31 +43,7 @@ if not schema: raise Exception("Cannot setup API tests: No valid schema found. Check your deployment and configuration.") - if "USERNAME" in os.environ and "PASSWORD" in os.environ: - logging.info("Setting token from username and password") - - @st.auth() - class TokenAuth: - def get(self, case, ctx): - username = os.environ["USERNAME"] - password = os.environ["PASSWORD"] - - return get_token(username, password) - - def set(self, case, data, context): - case.headers = case.headers or {} - case.headers["Authorization"] = f"Bearer {data}" - case.headers["Cookie"] = f"kc-access={data}" - else: - @st.auth() - class TokenAuth: - def get(self, case, ctx): - return "" - - def set(self, case, data, context): - case.headers = case.headers or {} - case.headers["Authorization"] = f"Bearer {data}" - case.headers["Cookie"] = f"kc-access={data}" + # Authentication headers are now passed directly via CLI flags; no auth hook required. UNSAFE_VALUES = ("%", ) diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index e644470a..4898c9a9 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -450,13 +450,21 @@ def codefresh_template_spec(template_path, **kwargs): def api_tests_commands(app_config: ApplicationHarnessConfig, run_custom_tests, api_url): + """Return commands to execute API tests for Codefresh pipeline. + + Harness-test is now the unified entrypoint; it internally builds schemathesis command with headers. + We invoke harness-test with -a flag targeting only API tests & include specific app. + Custom pytest tests run separately inside the same container. + """ api_config: ApiTestsConfig = app_config.test.api commands = [] + app_name = app_config.name if api_config.autotest: - commands.append(" ".join(get_schemathesis_command( - get_api_filename(""), app_config, api_url))) + # harness-test requires values.yaml generated & domain; Codefresh sets environment accordingly. + # We limit to the specific app using -i and run only api tests with -a + commands.append(f"harness-test . -i {app_name} -a") if run_custom_tests: - commands.append(f"pytest -v test/api") + commands.append("pytest -v test/api") return commands From b7c03db41fd361836a252c60fa9d3cd25b35e884 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Tue, 28 Oct 2025 12:24:15 +0000 Subject: [PATCH 49/65] refactor(api tests): simplify _get_auth_headers to only USERNAME/PASSWORD token retrieval --- .../cloudharness_utils/testing/api.py | 50 ++++++------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py index e9c3bea3..921b1154 100644 --- a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py +++ b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py @@ -23,45 +23,27 @@ def get_schemathesis_command(api_filename, app_config: ApplicationHarnessConfig, def _get_auth_headers(app_env: dict): - """Return list of CLI flags setting auth & headers based on environment. - - Supported: - - USERNAME/PASSWORD -> basic auth OR bearer token if token retrievable - - API_KEY -> X-API-Key header - - BEARER_TOKEN explicit -> Authorization header - Priority order: - 1. Explicit BEARER_TOKEN - 2. USERNAME/PASSWORD -> try get_token (Keycloak) then fallback to --auth basic - 3. API_KEY header + """Return schemathesis CLI flags for auth. + + Only support retrieving a bearer token via USERNAME/PASSWORD and setting + Authorization & Cookie headers as previously implemented in hooks. + If token retrieval fails, no auth headers are added (mirrors prior silent failure behavior). """ if not app_env: return [] - flags = [] - - bearer = app_env.get("BEARER_TOKEN") username = app_env.get("USERNAME") password = app_env.get("PASSWORD") - api_key = app_env.get("API_KEY") - - if bearer: - flags += ["--header", f"Authorization: Bearer {bearer}"] - elif username and password: - # Attempt to retrieve token; if fails, fallback to basic auth - try: - token = get_token(username, password) - if token: - flags += ["--header", f"Authorization: Bearer {token}"] - # also cookie header if needed by backend - flags += ["--header", f"Cookie: kc-access={token}"] - else: - flags += ["--auth", f"{username}:{password}"] - except Exception as e: - logging.warning("Failed to retrieve bearer token; fallback to basic auth: %s", e) - flags += ["--auth", f"{username}:{password}"] - - if api_key: - flags += ["--header", f"X-API-Key: {api_key}"] - return flags + if not (username and password): + return [] + try: + token = get_token(username, password) + if not token: + logging.warning("Token retrieval returned empty token for user %s", username) + return [] + return ["--header", f"Authorization: Bearer {token}", "--header", f"Cookie: kc-access={token}"] + except Exception as e: + logging.warning("Failed to retrieve bearer token for user %s: %s", username, e) + return [] def get_schemathesis_params(app_config: ApplicationHarnessConfig, app_domain: str, app_env: dict | None = None): From aca9b795338ebd37ce5a2cb34ee49c1c32cde92f Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Tue, 28 Oct 2025 12:53:00 +0000 Subject: [PATCH 50/65] chore: Update codefresh spec --- deployment/codefresh-test.yaml | 228 ++++++++++++++++----------------- 1 file changed, 112 insertions(+), 116 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index b99c6d31..18781819 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -51,6 +51,28 @@ steps: type: parallel stage: build steps: + cloudharness-frontend-build: + type: build + stage: build + dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + image_name: cloud-harness/cloudharness-frontend-build + title: Cloudharness frontend build + working_directory: ./. + tags: + - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true + forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false accounts: type: build stage: build @@ -95,28 +117,6 @@ steps: == true forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false - cloudharness-frontend-build: - type: build - stage: build - dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-frontend-build - title: Cloudharness frontend build - working_directory: ./. - tags: - - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false test-e2e: type: build stage: build @@ -145,7 +145,7 @@ steps: type: parallel stage: build steps: - samples-print-file: + cloudharness-flask: type: build stage: build dockerfile: Dockerfile @@ -154,21 +154,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false - workflows-notify-queue: + jupyterhub: type: build stage: build dockerfile: Dockerfile @@ -177,45 +177,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue - tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false - test-api: - type: build - stage: build - dockerfile: test/test-api/Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/test-api - title: Test api - working_directory: ./. + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{TEST_API_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -224,20 +200,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false workflows-send-result-event: type: build stage: build @@ -284,7 +260,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') == false - jupyterhub: + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -293,43 +269,67 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{JUPYTERHUB_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - cloudharness-flask: + test-api: type: build stage: build - dockerfile: Dockerfile + dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/test-api + title: Test api + working_directory: ./. tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{TEST_API_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') == false + workflows-extract-download: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download + tags: + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false samples-sum: type: build stage: build @@ -382,7 +382,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false - workflows: + common: type: build stage: build dockerfile: Dockerfile @@ -391,21 +391,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{WORKFLOWS_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false - volumemanager: + workflows: type: build stage: build dockerfile: Dockerfile @@ -414,21 +414,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/volumemanager - title: Volumemanager - working_directory: ./applications/volumemanager/server + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{VOLUMEMANAGER_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false - common: + volumemanager: type: build stage: build dockerfile: Dockerfile @@ -437,19 +437,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/volumemanager + title: Volumemanager + working_directory: ./applications/volumemanager/server tags: - - '${{COMMON_TAG}}' + - '${{VOLUMEMANAGER_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 tests_unit: @@ -485,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/workflows + - kubectl rollout status deployment/common - kubectl rollout status deployment/volumemanager + - kubectl rollout status deployment/workflows + - kubectl rollout status deployment/argo-gk - kubectl rollout status deployment/accounts - - kubectl rollout status deployment/common - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk - - kubectl rollout status deployment/argo-gk - sleep 60 tests_api: stage: qa @@ -511,7 +511,7 @@ steps: - APP_URL=https://workflows.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st run api/openapi.yaml --url https://workflows.${{DOMAIN}}/api -c all --suppress-health-check=filter_too_much + - harness-test . -i workflows -a samples_api_test: title: samples api test volumes: @@ -523,10 +523,7 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st run api/openapi.yaml --url https://samples.${{DOMAIN}}/api -c all --exclude-deprecated - --exclude-operation-id=submit_sync --exclude-operation-id=submit_sync_with_results - --exclude-operation-id=error --suppress-health-check=too_slow --suppress-health-check=filter_too_much - --request-timeout=180000 --max-examples=2 --exclude-checks=ignored_auth + - harness-test . -i samples -a - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -539,8 +536,7 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st run api/openapi.yaml --url https://volumemanager.${{DOMAIN}}/api -c all - --phases=examples --max-examples=1 + - harness-test . -i volumemanager -a common_api_test: title: common api test volumes: @@ -550,7 +546,7 @@ steps: - APP_URL=https://common.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - st run api/openapi.yaml --url https://common.${{DOMAIN}}/api -c all --suppress-health-check=filter_too_much + - harness-test . -i common -a hooks: on_fail: exec: From 2a6d132b40445b9a8cc8fb25983dfc061b03b394 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Tue, 28 Oct 2025 13:15:51 +0000 Subject: [PATCH 51/65] fix: Add auth hooks to custom tests --- .../base/test/api/test_st.py | 3 +- .../django-base/api/test_st.py | 3 +- applications/samples/test/api/test_st.py | 3 +- .../cloudharness_utils/testing/api.py | 7 +-- .../cloudharness_test/apitest_auth_hooks.py | 63 +++++++++++++++++++ .../cloudharness_test/apitest_init.py | 2 - .../ch_cli_tools/codefresh.py | 2 +- 7 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py diff --git a/application-templates/base/test/api/test_st.py b/application-templates/base/test/api/test_st.py index 3edef511..20ebd222 100644 --- a/application-templates/base/test/api/test_st.py +++ b/application-templates/base/test/api/test_st.py @@ -1,6 +1,7 @@ import os import schemathesis as st -from cloudharness_test import apitest_init # include to perform default authorization +from cloudharness_test import apitest_init # include to register default hooks +from cloudharness_test import apitest_auth_hooks # include to register authentication hooks app_url = os.environ.get("APP_URL", "http://samples.ch.local/api") diff --git a/application-templates/django-base/api/test_st.py b/application-templates/django-base/api/test_st.py index 0c52e9f9..e466808e 100644 --- a/application-templates/django-base/api/test_st.py +++ b/application-templates/django-base/api/test_st.py @@ -1,6 +1,7 @@ import os import schemathesis as st -from cloudharness_test import apitest_init # include to perform default authorization +from cloudharness_test import apitest_init # include to register default hooks +from cloudharness_test import apitest_auth_hooks # include to register authentication hooks app_url = os.environ.get("APP_URL", "http://samples.ch.local/api") diff --git a/applications/samples/test/api/test_st.py b/applications/samples/test/api/test_st.py index 253a6619..721fccc4 100644 --- a/applications/samples/test/api/test_st.py +++ b/applications/samples/test/api/test_st.py @@ -3,7 +3,8 @@ import schemathesis as st from schemathesis.specs.openapi.checks import response_schema_conformance -from cloudharness_test import apitest_init # include to perform default authorization +from cloudharness_test import apitest_init # include to register default hooks +from cloudharness_test import apitest_auth_hooks # include to register authentication hooks app_url = os.environ.get("APP_URL", "http://samples.ch.local/api") diff --git a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py index 921b1154..9ac35fbb 100644 --- a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py +++ b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py @@ -23,12 +23,7 @@ def get_schemathesis_command(api_filename, app_config: ApplicationHarnessConfig, def _get_auth_headers(app_env: dict): - """Return schemathesis CLI flags for auth. - - Only support retrieving a bearer token via USERNAME/PASSWORD and setting - Authorization & Cookie headers as previously implemented in hooks. - If token retrieval fails, no auth headers are added (mirrors prior silent failure behavior). - """ + """Return schemathesis CLI flags for auth.""" if not app_env: return [] username = app_env.get("USERNAME") diff --git a/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py b/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py new file mode 100644 index 00000000..0bc08480 --- /dev/null +++ b/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py @@ -0,0 +1,63 @@ +import os +import logging +import schemathesis as st +from cloudharness.auth import get_token + + +@st.auth.register() +class TokenAuth: + """ + Schemathesis authentication hook that retrieves a bearer token + using Keycloak credentials and sets both Authorization header and Cookie. + + Requires USERNAME and PASSWORD environment variables to be set. + """ + + def get(self, context): + """ + Retrieve the authentication token using username and password from environment. + + Args: + context: Schemathesis hook context + + Returns: + str: The bearer token + + Raises: + ValueError: If USERNAME or PASSWORD environment variables are not set + Exception: If token retrieval fails + """ + username = os.environ.get("USERNAME") + password = os.environ.get("PASSWORD") + + if not username or not password: + logging.warning("USERNAME and/or PASSWORD environment variables not set. Skipping authentication.") + return None + + try: + token = get_token(username, password) + if not token: + logging.warning("Token retrieval returned empty token for user %s", username) + return None + logging.info("Successfully retrieved authentication token for user %s", username) + return token + except Exception as e: + logging.error("Failed to retrieve bearer token for user %s: %s", username, e) + raise + + def set(self, case, data, context): + """ + Set the authentication token in the request headers and cookies. + + Args: + case: Schemathesis test case + data: The authentication token + context: Schemathesis hook context + """ + if not data: + return + + case.headers = case.headers or {} + case.headers["Authorization"] = f"Bearer {data}" + case.headers["Cookie"] = f"kc-access={data}" + diff --git a/tools/cloudharness-test/cloudharness_test/apitest_init.py b/tools/cloudharness-test/cloudharness_test/apitest_init.py index aa9a795e..f246dc0e 100644 --- a/tools/cloudharness-test/cloudharness_test/apitest_init.py +++ b/tools/cloudharness-test/cloudharness_test/apitest_init.py @@ -43,8 +43,6 @@ if not schema: raise Exception("Cannot setup API tests: No valid schema found. Check your deployment and configuration.") - # Authentication headers are now passed directly via CLI flags; no auth hook required. - UNSAFE_VALUES = ("%", ) @st.hook diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index 4898c9a9..c2e6a8ef 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -13,7 +13,7 @@ from .configurationgenerator import KEY_APPS, KEY_TASK_IMAGES, KEY_TEST_IMAGES from .utils import check_image_exists_in_registry, clean_image_name, find_dockerfiles_paths, get_app_relative_to_base_path, guess_build_dependencies_from_dockerfile, \ get_image_name, get_template, dict_merge, app_name_from_path, clean_path -from cloudharness_utils.testing.api import get_api_filename, get_schemathesis_command, get_urls_from_api_file +from cloudharness_utils.testing.api import get_api_filename, get_urls_from_api_file logging.getLogger().setLevel(logging.INFO) From 6f49096551df53b0ddac76310434119a9f3e718a Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Tue, 28 Oct 2025 13:19:53 +0000 Subject: [PATCH 52/65] fix: Update test api docker image --- test/test-api/.dockerignore | 23 +++++++++++++++++++++++ test/test-api/Dockerfile | 6 ++++++ 2 files changed, 29 insertions(+) create mode 100644 test/test-api/.dockerignore diff --git a/test/test-api/.dockerignore b/test/test-api/.dockerignore new file mode 100644 index 00000000..9c06dbcc --- /dev/null +++ b/test/test-api/.dockerignore @@ -0,0 +1,23 @@ +**/node_modules +.tox +docs +/applications +/infrastructure +/blueprint +/test +.github +.git +.vscode +/deployment +skaffold.yaml +*.egg-info +__pycache__ +.hypothesis +.coverage +.pytest_cache +/application-templates +/deployment-configuration +/cloud-harness +.openapi-generator +docker-compose.yaml +.history \ No newline at end of file diff --git a/test/test-api/Dockerfile b/test/test-api/Dockerfile index 06f43942..d0c3beec 100644 --- a/test/test-api/Dockerfile +++ b/test/test-api/Dockerfile @@ -5,11 +5,17 @@ FROM $CLOUDHARNESS_BASE COPY libraries/cloudharness-utils/requirements.txt /libraries/cloudharness-utils/requirements.txt RUN pip install -r /libraries/cloudharness-utils/requirements.txt --no-cache-dir +COPY tools/deployment-cli-tools/requirements.txt /tools/deployment-cli-tools/requirements.txt +RUN pip install -r /tools/deployment-cli-tools/requirements.txt --no-cache-dir + COPY tools/cloudharness-test/requirements.txt /tools/cloudharness-test/requirements.txt RUN pip install -r /tools/cloudharness-test/requirements.txt --no-cache-dir COPY libraries/cloudharness-utils /libraries/cloudharness-utils RUN pip install -e /libraries/cloudharness-utils +COPY tools/deployment-cli-tools /tools/deployment-cli-tools +RUN pip install -e /tools/deployment-cli-tools + COPY tools/cloudharness-test /tools/cloudharness-test RUN pip install -e /tools/cloudharness-test \ No newline at end of file From 7386779c67916c7256fc0990393ae777a4869858 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Tue, 28 Oct 2025 13:39:23 +0000 Subject: [PATCH 53/65] fix: Update dockerignore --- .dockerignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index ae23cfe6..efaff757 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,7 +5,6 @@ docs /infrastructure /blueprint test -/tools/deployment-cli-tools .github .git .vscode From 7df59dc9c597a0fcb705842c9decd76d92433819 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Tue, 28 Oct 2025 14:21:13 +0000 Subject: [PATCH 54/65] fix: Update test api docker image --- test/test-api/Dockerfile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/test-api/Dockerfile b/test/test-api/Dockerfile index d0c3beec..709dd23a 100644 --- a/test/test-api/Dockerfile +++ b/test/test-api/Dockerfile @@ -2,20 +2,17 @@ ARG CLOUDHARNESS_BASE FROM $CLOUDHARNESS_BASE +# Install cloudharness-utils first (required by other packages) COPY libraries/cloudharness-utils/requirements.txt /libraries/cloudharness-utils/requirements.txt RUN pip install -r /libraries/cloudharness-utils/requirements.txt --no-cache-dir -COPY tools/deployment-cli-tools/requirements.txt /tools/deployment-cli-tools/requirements.txt -RUN pip install -r /tools/deployment-cli-tools/requirements.txt --no-cache-dir - -COPY tools/cloudharness-test/requirements.txt /tools/cloudharness-test/requirements.txt -RUN pip install -r /tools/cloudharness-test/requirements.txt --no-cache-dir - COPY libraries/cloudharness-utils /libraries/cloudharness-utils RUN pip install -e /libraries/cloudharness-utils +# Install deployment-cli-tools (depends on cloudharness-utils) COPY tools/deployment-cli-tools /tools/deployment-cli-tools RUN pip install -e /tools/deployment-cli-tools +# Install cloudharness-test (depends on both above) COPY tools/cloudharness-test /tools/cloudharness-test RUN pip install -e /tools/cloudharness-test \ No newline at end of file From be05ea3d1ba54ae57806f8207370ab9c30b99315 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Thu, 30 Oct 2025 10:42:58 +0000 Subject: [PATCH 55/65] fix: Set CH_VALUES_PATH location --- deployment/codefresh-test.yaml | 264 ++++++++++-------- test/test-api/Dockerfile | 2 + .../ch_cli_tools/codefresh.py | 6 +- 3 files changed, 147 insertions(+), 125 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 18781819..8a249c1b 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -51,28 +51,29 @@ steps: type: parallel stage: build steps: - cloudharness-frontend-build: + test-e2e: type: build stage: build - dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-frontend-build - title: Cloudharness frontend build - working_directory: ./. + image_name: cloud-harness/test-e2e + title: Test e2e + working_directory: ./test/test-e2e tags: - - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' + - '${{TEST_E2E_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') + == false accounts: type: build stage: build @@ -117,58 +118,58 @@ steps: == true forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false - test-e2e: + cloudharness-frontend-build: type: build stage: build - dockerfile: Dockerfile + dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/test-e2e - title: Test e2e - working_directory: ./test/test-e2e + image_name: cloud-harness/cloudharness-frontend-build + title: Cloudharness frontend build + working_directory: ./. tags: - - '${{TEST_E2E_TAG}}' + - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') - == true - forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true + forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false title: Build parallel step 1 build_application_images_1: type: parallel stage: build steps: - cloudharness-flask: + test-api: type: build stage: build - dockerfile: Dockerfile + dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/test-api + title: Test api + working_directory: ./. tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{TEST_API_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') == false - jupyterhub: + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -177,21 +178,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{JUPYTERHUB_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') - == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') - == false - workflows-notify-queue: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -200,20 +201,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + == false workflows-send-result-event: type: build stage: build @@ -237,7 +238,7 @@ steps: '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - samples-secret: + cloudharness-flask: type: build stage: build dockerfile: Dockerfile @@ -246,21 +247,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false - samples-print-file: + jupyterhub: type: build stage: build dockerfile: Dockerfile @@ -269,45 +270,44 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') == false - test-api: + samples-sum: type: build stage: build - dockerfile: test/test-api/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/test-api - title: Test api - working_directory: ./. + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{TEST_API_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -316,21 +316,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - samples-sum: + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + == false + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -339,26 +339,26 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false title: Build parallel step 2 build_application_images_2: type: parallel stage: build steps: - samples: + workflows: type: build stage: build dockerfile: Dockerfile @@ -366,23 +366,22 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/samples - title: Samples - working_directory: ./applications/samples + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{SAMPLES_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false - common: + samples: type: build stage: build dockerfile: Dockerfile @@ -390,22 +389,23 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/samples + title: Samples + working_directory: ./applications/samples tags: - - '${{COMMON_TAG}}' + - '${{SAMPLES_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false - workflows: + volumemanager: type: build stage: build dockerfile: Dockerfile @@ -414,21 +414,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/volumemanager + title: Volumemanager + working_directory: ./applications/volumemanager/server tags: - - '${{WORKFLOWS_TAG}}' + - '${{VOLUMEMANAGER_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false - volumemanager: + common: type: build stage: build dockerfile: Dockerfile @@ -437,19 +437,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/volumemanager - title: Volumemanager - working_directory: ./applications/volumemanager/server + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{VOLUMEMANAGER_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 tests_unit: @@ -485,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/common + - kubectl rollout status deployment/accounts - kubectl rollout status deployment/volumemanager - kubectl rollout status deployment/workflows - - kubectl rollout status deployment/argo-gk - - kubectl rollout status deployment/accounts - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk + - kubectl rollout status deployment/argo-gk + - kubectl rollout status deployment/common - sleep 60 tests_api: stage: qa @@ -511,7 +511,11 @@ steps: - APP_URL=https://workflows.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -i workflows -a + - echo $CH_VALUES_PATH + - ls -la $CH_VALUES_PATH + - ls -la $CH_VALUES_PATH/deployment + - ls -la $CH_VALUES_PATH/deployment/helm + - harness-test /codefresh/volume/cloud-harness -i workflows -a samples_api_test: title: samples api test volumes: @@ -523,7 +527,11 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -i samples -a + - echo $CH_VALUES_PATH + - ls -la $CH_VALUES_PATH + - ls -la $CH_VALUES_PATH/deployment + - ls -la $CH_VALUES_PATH/deployment/helm + - harness-test /codefresh/volume/cloud-harness -i samples -a - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -536,7 +544,11 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -i volumemanager -a + - echo $CH_VALUES_PATH + - ls -la $CH_VALUES_PATH + - ls -la $CH_VALUES_PATH/deployment + - ls -la $CH_VALUES_PATH/deployment/helm + - harness-test /codefresh/volume/cloud-harness -i volumemanager -a common_api_test: title: common api test volumes: @@ -546,7 +558,11 @@ steps: - APP_URL=https://common.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -i common -a + - echo $CH_VALUES_PATH + - ls -la $CH_VALUES_PATH + - ls -la $CH_VALUES_PATH/deployment + - ls -la $CH_VALUES_PATH/deployment/helm + - harness-test /codefresh/volume/cloud-harness -i common -a hooks: on_fail: exec: diff --git a/test/test-api/Dockerfile b/test/test-api/Dockerfile index 709dd23a..6f2dccba 100644 --- a/test/test-api/Dockerfile +++ b/test/test-api/Dockerfile @@ -2,6 +2,8 @@ ARG CLOUDHARNESS_BASE FROM $CLOUDHARNESS_BASE +ENV CH_VALUES_PATH=/codefresh/volume/cloud-harness + # Install cloudharness-utils first (required by other packages) COPY libraries/cloudharness-utils/requirements.txt /libraries/cloudharness-utils/requirements.txt RUN pip install -r /libraries/cloudharness-utils/requirements.txt --no-cache-dir diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index c2e6a8ef..b292d575 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -462,7 +462,11 @@ def api_tests_commands(app_config: ApplicationHarnessConfig, run_custom_tests, a if api_config.autotest: # harness-test requires values.yaml generated & domain; Codefresh sets environment accordingly. # We limit to the specific app using -i and run only api tests with -a - commands.append(f"harness-test . -i {app_name} -a") + commands.append(f"echo $CH_VALUES_PATH") + commands.append(f"ls -la $CH_VALUES_PATH") + commands.append(f"ls -la $CH_VALUES_PATH/deployment") + commands.append(f"ls -la $CH_VALUES_PATH/deployment/helm") + commands.append(f"harness-test /codefresh/volume/cloud-harness -i {app_name} -a") if run_custom_tests: commands.append("pytest -v test/api") return commands From 52b6c0fa16af38f460328d2f1e0b3a1ac5858e2e Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Thu, 30 Oct 2025 16:54:14 +0000 Subject: [PATCH 56/65] fix: Update harness-test working dir --- deployment/codefresh-test.yaml | 242 +++++++++--------- .../ch_cli_tools/codefresh.py | 7 +- 2 files changed, 122 insertions(+), 127 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 8a249c1b..3b41842b 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -51,29 +51,28 @@ steps: type: parallel stage: build steps: - test-e2e: + cloudharness-frontend-build: type: build stage: build - dockerfile: Dockerfile + dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/test-e2e - title: Test e2e - working_directory: ./test/test-e2e + image_name: cloud-harness/cloudharness-frontend-build + title: Cloudharness frontend build + working_directory: ./. tags: - - '${{TEST_E2E_TAG}}' + - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') - == true - forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true + forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false accounts: type: build stage: build @@ -96,80 +95,80 @@ steps: == true forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') == false - cloudharness-base: + test-e2e: type: build stage: build - dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-base - title: Cloudharness base - working_directory: ./. + image_name: cloud-harness/test-e2e + title: Test e2e + working_directory: ./test/test-e2e tags: - - '${{CLOUDHARNESS_BASE_TAG}}' + - '${{TEST_E2E_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') == false - cloudharness-frontend-build: + cloudharness-base: type: build stage: build - dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile + dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-frontend-build - title: Cloudharness frontend build + image_name: cloud-harness/cloudharness-base + title: Cloudharness base working_directory: ./. tags: - - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' + - '${{CLOUDHARNESS_BASE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') + == false title: Build parallel step 1 build_application_images_1: type: parallel stage: build steps: - test-api: + cloudharness-flask: type: build stage: build - dockerfile: test/test-api/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/test-api - title: Test api - working_directory: ./. + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{TEST_API_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + samples-sum: type: build stage: build dockerfile: Dockerfile @@ -178,21 +177,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - samples-print-file: + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + == false + workflows-send-result-event: type: build stage: build dockerfile: Dockerfile @@ -201,21 +200,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') - == false - workflows-send-result-event: + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -224,21 +223,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - cloudharness-flask: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -247,21 +246,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') == false - jupyterhub: + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -270,21 +269,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{JUPYTERHUB_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') - == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') - == false - samples-sum: + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + jupyterhub: type: build stage: build dockerfile: Dockerfile @@ -293,21 +292,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') == false - samples-secret: + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -316,43 +315,44 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - workflows-notify-queue: + test-api: type: build stage: build - dockerfile: Dockerfile + dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/test-api + title: Test api + working_directory: ./. tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{TEST_API_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + == false title: Build parallel step 2 build_application_images_2: type: parallel @@ -485,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} + - kubectl rollout status deployment/argo-gk + - kubectl rollout status deployment/common - kubectl rollout status deployment/accounts - - kubectl rollout status deployment/volumemanager - kubectl rollout status deployment/workflows - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk - - kubectl rollout status deployment/argo-gk - - kubectl rollout status deployment/common + - kubectl rollout status deployment/volumemanager - sleep 60 tests_api: stage: qa @@ -512,10 +512,9 @@ steps: - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - echo $CH_VALUES_PATH - - ls -la $CH_VALUES_PATH - - ls -la $CH_VALUES_PATH/deployment - - ls -la $CH_VALUES_PATH/deployment/helm - - harness-test /codefresh/volume/cloud-harness -i workflows -a + - cd $CH_VALUES_PATH + - ls -la + - harness-test . -i workflows -a samples_api_test: title: samples api test volumes: @@ -528,10 +527,9 @@ steps: - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - echo $CH_VALUES_PATH - - ls -la $CH_VALUES_PATH - - ls -la $CH_VALUES_PATH/deployment - - ls -la $CH_VALUES_PATH/deployment/helm - - harness-test /codefresh/volume/cloud-harness -i samples -a + - cd $CH_VALUES_PATH + - ls -la + - harness-test . -i samples -a - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -545,10 +543,9 @@ steps: - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - echo $CH_VALUES_PATH - - ls -la $CH_VALUES_PATH - - ls -la $CH_VALUES_PATH/deployment - - ls -la $CH_VALUES_PATH/deployment/helm - - harness-test /codefresh/volume/cloud-harness -i volumemanager -a + - cd $CH_VALUES_PATH + - ls -la + - harness-test . -i volumemanager -a common_api_test: title: common api test volumes: @@ -559,10 +556,9 @@ steps: - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - echo $CH_VALUES_PATH - - ls -la $CH_VALUES_PATH - - ls -la $CH_VALUES_PATH/deployment - - ls -la $CH_VALUES_PATH/deployment/helm - - harness-test /codefresh/volume/cloud-harness -i common -a + - cd $CH_VALUES_PATH + - ls -la + - harness-test . -i common -a hooks: on_fail: exec: diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index b292d575..57659f4c 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -463,10 +463,9 @@ def api_tests_commands(app_config: ApplicationHarnessConfig, run_custom_tests, a # harness-test requires values.yaml generated & domain; Codefresh sets environment accordingly. # We limit to the specific app using -i and run only api tests with -a commands.append(f"echo $CH_VALUES_PATH") - commands.append(f"ls -la $CH_VALUES_PATH") - commands.append(f"ls -la $CH_VALUES_PATH/deployment") - commands.append(f"ls -la $CH_VALUES_PATH/deployment/helm") - commands.append(f"harness-test /codefresh/volume/cloud-harness -i {app_name} -a") + commands.append(f"cd $CH_VALUES_PATH") + commands.append(f"ls -la") + commands.append(f"harness-test . -i {app_name} -a") if run_custom_tests: commands.append("pytest -v test/api") return commands From 9feb464e1043eb20efdf01c69cf55d5fdc6b89cd Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Sun, 2 Nov 2025 21:00:44 +0000 Subject: [PATCH 57/65] fix: Move get_token to local import --- libraries/cloudharness-utils/cloudharness_utils/testing/api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py index 9ac35fbb..7a62240a 100644 --- a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py +++ b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py @@ -4,7 +4,6 @@ from ruamel.yaml import YAML from cloudharness_model.models import ApiTestsConfig, ApplicationHarnessConfig -from cloudharness.auth import get_token yaml = YAML(typ='safe') @@ -23,6 +22,8 @@ def get_schemathesis_command(api_filename, app_config: ApplicationHarnessConfig, def _get_auth_headers(app_env: dict): + from cloudharness.auth import get_token + """Return schemathesis CLI flags for auth.""" if not app_env: return [] From 0ccb92dad79748ef49c6de0e06bafa021e33b413 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Sun, 2 Nov 2025 21:08:54 +0000 Subject: [PATCH 58/65] fix: Adapt tests to match with new api testing strategy --- .../ch_cli_tools/codefresh.py | 2 -- .../tests/test_codefresh.py | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index 57659f4c..d3e83423 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -462,9 +462,7 @@ def api_tests_commands(app_config: ApplicationHarnessConfig, run_custom_tests, a if api_config.autotest: # harness-test requires values.yaml generated & domain; Codefresh sets environment accordingly. # We limit to the specific app using -i and run only api tests with -a - commands.append(f"echo $CH_VALUES_PATH") commands.append(f"cd $CH_VALUES_PATH") - commands.append(f"ls -la") commands.append(f"harness-test . -i {app_name} -a") if run_custom_tests: commands.append("pytest -v test/api") diff --git a/tools/deployment-cli-tools/tests/test_codefresh.py b/tools/deployment-cli-tools/tests/test_codefresh.py index 7ad4af39..9c0faa01 100644 --- a/tools/deployment-cli-tools/tests/test_codefresh.py +++ b/tools/deployment-cli-tools/tests/test_codefresh.py @@ -238,14 +238,17 @@ def test_create_codefresh_configuration_tests(): assert any("allvalues.yaml" in v for v in test_step['volumes']) - assert len(test_step["commands"]) == 2, "Both default and custom api tests should be run" - - st_cmd = test_step["commands"][0] - assert any("SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init" in env for env in test_step['environment']), "SCHEMATHESIS_HOOKS hook must be specified in environment" - assert "api/openapi.yaml" in st_cmd, "Openapi file must be passed to the schemathesis command" - - assert "-c all" in st_cmd, "Default check loaded is `all` on schemathesis command" - assert "--exclude-deprecated" in st_cmd, "Custom parameters are loaded from values.yaml" + assert len(test_step["commands"]) == 3, "Both default and custom api tests should be run" + + # First command should change to the values path + assert test_step["commands"][0] == "cd $CH_VALUES_PATH", "First command should change to values directory" + # Second command should run harness-test with api flag and specific app + harness_test_cmd = test_step["commands"][1] + assert "harness-test" in harness_test_cmd, "harness-test should be used for api tests" + assert "-i samples" in harness_test_cmd, "App name should be included with -i flag" + assert "-a" in harness_test_cmd, "API tests should be run with -a flag" + # Third command should run custom pytest tests + assert "pytest -v test/api" in test_step["commands"][2], "Custom pytest tests should be run" test_step = api_steps["common_api_test"] for volume in test_step["volumes"]: From b2bc66a65f22314da5855fd4ee8306b17626f447 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Sun, 2 Nov 2025 21:46:27 +0000 Subject: [PATCH 59/65] feat: Connect -c flag of harness-test --- tools/cloudharness-test/harness-test | 5 +++-- .../deployment-cli-tools/ch_cli_tools/codefresh.py | 5 +---- tools/deployment-cli-tools/tests/test_codefresh.py | 13 ++++++------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/tools/cloudharness-test/harness-test b/tools/cloudharness-test/harness-test index fa69ddf8..9f06856d 100644 --- a/tools/cloudharness-test/harness-test +++ b/tools/cloudharness-test/harness-test @@ -35,7 +35,7 @@ if __name__ == "__main__": parser.add_argument('-i', '--include', dest='include', action="append", default=[], help='Specify the applications to include and exclude the rest. ' 'Omit to test all application included by harness-deployment.') - parser.add_argument('-c', '--helm-chart', dest='helm_chart_path', action="store", default=HELM_DIR, + parser.add_argument('-c', '--helm-chart', dest='helm_chart_path', action="store", default=None, help=f'Specify helm chart base path (default `{HELM_DIR}`') parser.add_argument('-e', '--e2e', dest='run_e2e', action="store_const", default=None, const=True, help=f'Run only end to end tests (default: run both api and end to end tests') @@ -52,7 +52,8 @@ if __name__ == "__main__": print('There are unknown args. Make sure to call the script with the accepted args. Try --help') print(f'unknown: {unknown}') else: - helm_values_path = os.path.join(HELM_DIR, 'values.yaml') + helm_chart_dir = args.helm_chart_path or HELM_DIR + helm_values_path = os.path.join(helm_chart_dir, 'values.yaml') if not os.path.exists(helm_values_path): logging.error( "Could not find helm installation. Have you run harness-deployment already?") diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index d3e83423..1cfa399a 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -460,10 +460,7 @@ def api_tests_commands(app_config: ApplicationHarnessConfig, run_custom_tests, a commands = [] app_name = app_config.name if api_config.autotest: - # harness-test requires values.yaml generated & domain; Codefresh sets environment accordingly. - # We limit to the specific app using -i and run only api tests with -a - commands.append(f"cd $CH_VALUES_PATH") - commands.append(f"harness-test . -i {app_name} -a") + commands.append(f"harness-test . -c $CH_VALUES_PATH -i {app_name} -a") if run_custom_tests: commands.append("pytest -v test/api") return commands diff --git a/tools/deployment-cli-tools/tests/test_codefresh.py b/tools/deployment-cli-tools/tests/test_codefresh.py index 9c0faa01..569b3a72 100644 --- a/tools/deployment-cli-tools/tests/test_codefresh.py +++ b/tools/deployment-cli-tools/tests/test_codefresh.py @@ -238,17 +238,16 @@ def test_create_codefresh_configuration_tests(): assert any("allvalues.yaml" in v for v in test_step['volumes']) - assert len(test_step["commands"]) == 3, "Both default and custom api tests should be run" + assert len(test_step["commands"]) == 2, "Both default and custom api tests should be run" - # First command should change to the values path - assert test_step["commands"][0] == "cd $CH_VALUES_PATH", "First command should change to values directory" - # Second command should run harness-test with api flag and specific app - harness_test_cmd = test_step["commands"][1] + # First command should run harness-test with api flag, specific app, and helm chart path + harness_test_cmd = test_step["commands"][0] assert "harness-test" in harness_test_cmd, "harness-test should be used for api tests" + assert "-c $CH_VALUES_PATH" in harness_test_cmd, "Helm chart path should be specified with -c flag" assert "-i samples" in harness_test_cmd, "App name should be included with -i flag" assert "-a" in harness_test_cmd, "API tests should be run with -a flag" - # Third command should run custom pytest tests - assert "pytest -v test/api" in test_step["commands"][2], "Custom pytest tests should be run" + # Second command should run custom pytest tests + assert "pytest -v test/api" in test_step["commands"][1], "Custom pytest tests should be run" test_step = api_steps["common_api_test"] for volume in test_step["volumes"]: From 8ba18e42b3bf22c3ca45c8f2abea08eb44330f1e Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Sun, 2 Nov 2025 21:52:53 +0000 Subject: [PATCH 60/65] chore: Update codefresh specification --- deployment/codefresh-test.yaml | 208 +++++++++--------- .../cloudharness_test/apitest_auth_hooks.py | 2 +- 2 files changed, 99 insertions(+), 111 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 3b41842b..737de581 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -95,29 +95,6 @@ steps: == true forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') == false - test-e2e: - type: build - stage: build - dockerfile: Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/test-e2e - title: Test e2e - working_directory: ./test/test-e2e - tags: - - '${{TEST_E2E_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest - when: - condition: - any: - buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') - == true - forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') - == false cloudharness-base: type: build stage: build @@ -140,12 +117,7 @@ steps: == true forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false - title: Build parallel step 1 - build_application_images_1: - type: parallel - stage: build - steps: - cloudharness-flask: + test-e2e: type: build stage: build dockerfile: Dockerfile @@ -153,21 +125,26 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/test-e2e + title: Test e2e + working_directory: ./test/test-e2e tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{TEST_E2E_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') == false + title: Build parallel step 1 + build_application_images_1: + type: parallel + stage: build + steps: samples-sum: type: build stage: build @@ -191,29 +168,30 @@ steps: == true forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') == false - workflows-send-result-event: + test-api: type: build stage: build - dockerfile: Dockerfile + dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event + image_name: cloud-harness/test-api + title: Test api + working_directory: ./. tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + - '${{TEST_API_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + == false workflows-extract-download: type: build stage: build @@ -260,6 +238,29 @@ steps: == true forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') == false + cloudharness-flask: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask + tags: + - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + == false workflows-notify-queue: type: build stage: build @@ -283,7 +284,7 @@ steps: '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false - jupyterhub: + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -292,21 +293,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{JUPYTERHUB_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - samples-print-file: + workflows-send-result-event: type: build stage: build dockerfile: Dockerfile @@ -315,50 +316,49 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') - == false - test-api: + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false + jupyterhub: type: build stage: build - dockerfile: test/test-api/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/test-api - title: Test api - working_directory: ./. + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{TEST_API_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') == false title: Build parallel step 2 build_application_images_2: type: parallel stage: build steps: - workflows: + volumemanager: type: build stage: build dockerfile: Dockerfile @@ -367,19 +367,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/volumemanager + title: Volumemanager + working_directory: ./applications/volumemanager/server tags: - - '${{WORKFLOWS_TAG}}' + - '${{VOLUMEMANAGER_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false samples: type: build @@ -405,7 +405,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false - volumemanager: + common: type: build stage: build dockerfile: Dockerfile @@ -414,21 +414,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/volumemanager - title: Volumemanager - working_directory: ./applications/volumemanager/server + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{VOLUMEMANAGER_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false - common: + workflows: type: build stage: build dockerfile: Dockerfile @@ -437,19 +437,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{COMMON_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 tests_unit: @@ -486,12 +486,12 @@ steps: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - kubectl rollout status deployment/argo-gk - - kubectl rollout status deployment/common - kubectl rollout status deployment/accounts - - kubectl rollout status deployment/workflows - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk + - kubectl rollout status deployment/common - kubectl rollout status deployment/volumemanager + - kubectl rollout status deployment/workflows - sleep 60 tests_api: stage: qa @@ -511,10 +511,7 @@ steps: - APP_URL=https://workflows.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - echo $CH_VALUES_PATH - - cd $CH_VALUES_PATH - - ls -la - - harness-test . -i workflows -a + - harness-test . -c $CH_VALUES_PATH -i workflows -a samples_api_test: title: samples api test volumes: @@ -526,10 +523,7 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - echo $CH_VALUES_PATH - - cd $CH_VALUES_PATH - - ls -la - - harness-test . -i samples -a + - harness-test . -c $CH_VALUES_PATH -i samples -a - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -542,10 +536,7 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - echo $CH_VALUES_PATH - - cd $CH_VALUES_PATH - - ls -la - - harness-test . -i volumemanager -a + - harness-test . -c $CH_VALUES_PATH -i volumemanager -a common_api_test: title: common api test volumes: @@ -555,10 +546,7 @@ steps: - APP_URL=https://common.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - echo $CH_VALUES_PATH - - cd $CH_VALUES_PATH - - ls -la - - harness-test . -i common -a + - harness-test . -c $CH_VALUES_PATH -i common -a hooks: on_fail: exec: diff --git a/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py b/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py index 0bc08480..5f7648db 100644 --- a/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py +++ b/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py @@ -4,7 +4,7 @@ from cloudharness.auth import get_token -@st.auth.register() +@st.auth() class TokenAuth: """ Schemathesis authentication hook that retrieves a bearer token From 35b4221f731cf1d26ee3f8786c35b8733a5efd85 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Sun, 2 Nov 2025 22:16:48 +0000 Subject: [PATCH 61/65] fix: Correct helm chart location --- deployment/codefresh-test.yaml | 242 +++++++++--------- .../ch_cli_tools/codefresh.py | 2 +- .../tests/test_codefresh.py | 2 +- 3 files changed, 123 insertions(+), 123 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 737de581..997cee26 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -51,6 +51,28 @@ steps: type: parallel stage: build steps: + cloudharness-base: + type: build + stage: build + dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + image_name: cloud-harness/cloudharness-base + title: Cloudharness base + working_directory: ./. + tags: + - '${{CLOUDHARNESS_BASE_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') + == false cloudharness-frontend-build: type: build stage: build @@ -95,28 +117,6 @@ steps: == true forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') == false - cloudharness-base: - type: build - stage: build - dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-base - title: Cloudharness base - working_directory: ./. - tags: - - '${{CLOUDHARNESS_BASE_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') - == true - forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') - == false test-e2e: type: build stage: build @@ -145,7 +145,7 @@ steps: type: parallel stage: build steps: - samples-sum: + workflows-send-result-event: type: build stage: build dockerfile: Dockerfile @@ -154,45 +154,44 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') - == false - test-api: + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false + cloudharness-flask: type: build stage: build - dockerfile: test/test-api/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/test-api - title: Test api - working_directory: ./. + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{TEST_API_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + jupyterhub: type: build stage: build dockerfile: Dockerfile @@ -201,21 +200,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - samples-secret: + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') + == true + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') + == false + samples-sum: type: build stage: build dockerfile: Dockerfile @@ -224,21 +223,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') == false - cloudharness-flask: + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -247,44 +246,45 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - workflows-notify-queue: + test-api: type: build stage: build - dockerfile: Dockerfile + dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/test-api + title: Test api + working_directory: ./. tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{TEST_API_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false - samples-print-file: + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + == false + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -293,21 +293,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') - == false - workflows-send-result-event: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -316,21 +316,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - jupyterhub: + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + == false + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -339,20 +339,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{JUPYTERHUB_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') - == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false title: Build parallel step 2 build_application_images_2: type: parallel @@ -405,7 +405,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false - common: + workflows: type: build stage: build dockerfile: Dockerfile @@ -414,21 +414,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{COMMON_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false - workflows: + common: type: build stage: build dockerfile: Dockerfile @@ -437,19 +437,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{WORKFLOWS_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 tests_unit: @@ -485,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/argo-gk - - kubectl rollout status deployment/accounts + - kubectl rollout status deployment/workflows - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk + - kubectl rollout status deployment/accounts + - kubectl rollout status deployment/argo-gk - kubectl rollout status deployment/common - kubectl rollout status deployment/volumemanager - - kubectl rollout status deployment/workflows - sleep 60 tests_api: stage: qa @@ -511,7 +511,7 @@ steps: - APP_URL=https://workflows.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -c $CH_VALUES_PATH -i workflows -a + - harness-test . -c $CH_VALUES_PATH/deployment/helm -i workflows -a samples_api_test: title: samples api test volumes: @@ -523,7 +523,7 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -c $CH_VALUES_PATH -i samples -a + - harness-test . -c $CH_VALUES_PATH/deployment/helm -i samples -a - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -536,7 +536,7 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -c $CH_VALUES_PATH -i volumemanager -a + - harness-test . -c $CH_VALUES_PATH/deployment/helm -i volumemanager -a common_api_test: title: common api test volumes: @@ -546,7 +546,7 @@ steps: - APP_URL=https://common.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -c $CH_VALUES_PATH -i common -a + - harness-test . -c $CH_VALUES_PATH/deployment/helm -i common -a hooks: on_fail: exec: diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index 1cfa399a..db18f44f 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -460,7 +460,7 @@ def api_tests_commands(app_config: ApplicationHarnessConfig, run_custom_tests, a commands = [] app_name = app_config.name if api_config.autotest: - commands.append(f"harness-test . -c $CH_VALUES_PATH -i {app_name} -a") + commands.append(f"harness-test . -c $CH_VALUES_PATH/deployment/helm -i {app_name} -a") if run_custom_tests: commands.append("pytest -v test/api") return commands diff --git a/tools/deployment-cli-tools/tests/test_codefresh.py b/tools/deployment-cli-tools/tests/test_codefresh.py index 569b3a72..740ebad9 100644 --- a/tools/deployment-cli-tools/tests/test_codefresh.py +++ b/tools/deployment-cli-tools/tests/test_codefresh.py @@ -243,7 +243,7 @@ def test_create_codefresh_configuration_tests(): # First command should run harness-test with api flag, specific app, and helm chart path harness_test_cmd = test_step["commands"][0] assert "harness-test" in harness_test_cmd, "harness-test should be used for api tests" - assert "-c $CH_VALUES_PATH" in harness_test_cmd, "Helm chart path should be specified with -c flag" + assert "-c $CH_VALUES_PATH/deployment/helm" in harness_test_cmd, "Helm chart path should be specified with -c flag" assert "-i samples" in harness_test_cmd, "App name should be included with -i flag" assert "-a" in harness_test_cmd, "API tests should be run with -a flag" # Second command should run custom pytest tests From 16d1290507227eb937482a66036034b807a2a6a4 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Sun, 2 Nov 2025 22:18:57 +0000 Subject: [PATCH 62/65] style: Run linter --- applications/samples/test/api/test_st.py | 2 +- .../controllers/rest_controller.py | 6 +++--- .../create_and_access_controller.py | 2 +- .../cloudharness_test/apitest_auth_hooks.py | 21 +++++++++---------- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/applications/samples/test/api/test_st.py b/applications/samples/test/api/test_st.py index 721fccc4..f7887461 100644 --- a/applications/samples/test/api/test_st.py +++ b/applications/samples/test/api/test_st.py @@ -14,7 +14,7 @@ @schema.include(path="/error", method="GET").parametrize() def test_api(case): response = case.call() - + if case.method == "GET": # Assert that this endpoint returns a 500 error as expected assert response.status_code == 500, f"Expected 500 error, got {response.status_code}. This api errors on purpose." diff --git a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py index 81eab15f..23b289ec 100644 --- a/applications/volumemanager/server/volumemanager/controllers/rest_controller.py +++ b/applications/volumemanager/server/volumemanager/controllers/rest_controller.py @@ -27,12 +27,12 @@ def pvc_name_get(name): # noqa: E501 # Extract access mode safely access_mode = pvc.status.access_modes[0] if pvc.status and pvc.status.access_modes else '' - + # Extract size safely size = '' if pvc.status and pvc.status.capacity: size = pvc.status.capacity.get('storage', '') - + pvc_response = PersistentVolumeClaim( name=pvc.metadata.name, namespace=pvc.metadata.namespace, @@ -54,7 +54,7 @@ def pvc_post(): # noqa: E501 """ if connexion.request.is_json: persistent_volume_claim_create = PersistentVolumeClaimCreate.from_dict(connexion.request.get_json()) # noqa: E501 - + # Validate required fields if not persistent_volume_claim_create.name or not persistent_volume_claim_create.size: return {'description': 'Name and size are required and cannot be empty.'}, 400 diff --git a/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py b/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py index d0734874..a148016e 100644 --- a/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py +++ b/applications/workflows/server/workflows_api/controllers/create_and_access_controller.py @@ -67,7 +67,7 @@ def list_operations(status=None, previous_search_token=None, limit=None): # noq """ if previous_search_token == "": previous_search_token = None - + try: return workflow_service.list_operations(status, continue_token=previous_search_token, limit=limit) except BadParam as e: diff --git a/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py b/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py index 5f7648db..5cac3f44 100644 --- a/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py +++ b/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py @@ -9,31 +9,31 @@ class TokenAuth: """ Schemathesis authentication hook that retrieves a bearer token using Keycloak credentials and sets both Authorization header and Cookie. - + Requires USERNAME and PASSWORD environment variables to be set. """ - + def get(self, context): """ Retrieve the authentication token using username and password from environment. - + Args: context: Schemathesis hook context - + Returns: str: The bearer token - + Raises: ValueError: If USERNAME or PASSWORD environment variables are not set Exception: If token retrieval fails """ username = os.environ.get("USERNAME") password = os.environ.get("PASSWORD") - + if not username or not password: logging.warning("USERNAME and/or PASSWORD environment variables not set. Skipping authentication.") return None - + try: token = get_token(username, password) if not token: @@ -44,11 +44,11 @@ def get(self, context): except Exception as e: logging.error("Failed to retrieve bearer token for user %s: %s", username, e) raise - + def set(self, case, data, context): """ Set the authentication token in the request headers and cookies. - + Args: case: Schemathesis test case data: The authentication token @@ -56,8 +56,7 @@ def set(self, case, data, context): """ if not data: return - + case.headers = case.headers or {} case.headers["Authorization"] = f"Bearer {data}" case.headers["Cookie"] = f"kc-access={data}" - From ea3e32dd4ce9945438f293ea28da407149d82f62 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Sun, 2 Nov 2025 22:30:23 +0000 Subject: [PATCH 63/65] fix: Correct harness-test ch location --- deployment/codefresh-test.yaml | 240 +++++++++--------- .../ch_cli_tools/codefresh.py | 2 +- 2 files changed, 123 insertions(+), 119 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 997cee26..c1b705ad 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -73,28 +73,6 @@ steps: == true forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false - cloudharness-frontend-build: - type: build - stage: build - dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-frontend-build - title: Cloudharness frontend build - working_directory: ./. - tags: - - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false accounts: type: build stage: build @@ -140,12 +118,34 @@ steps: == true forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') == false + cloudharness-frontend-build: + type: build + stage: build + dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + image_name: cloud-harness/cloudharness-frontend-build + title: Cloudharness frontend build + working_directory: ./. + tags: + - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true + forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false title: Build parallel step 1 build_application_images_1: type: parallel stage: build steps: - workflows-send-result-event: + samples-sum: type: build stage: build dockerfile: Dockerfile @@ -154,21 +154,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - cloudharness-flask: + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + == false + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -177,21 +177,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') == false - jupyterhub: + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -200,21 +200,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{JUPYTERHUB_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - samples-sum: + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -223,21 +223,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') - == false - samples-print-file: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + cloudharness-flask: type: build stage: build dockerfile: Dockerfile @@ -246,45 +246,44 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false - test-api: + jupyterhub: type: build stage: build - dockerfile: test/test-api/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/test-api - title: Test api - working_directory: ./. + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{TEST_API_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -293,21 +292,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - samples-secret: + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + workflows-send-result-event: type: build stage: build dockerfile: Dockerfile @@ -316,49 +315,50 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') - == false - workflows-notify-queue: + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false + test-api: type: build stage: build - dockerfile: Dockerfile + dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/test-api + title: Test api + working_directory: ./. tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{TEST_API_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + == false title: Build parallel step 2 build_application_images_2: type: parallel stage: build steps: - volumemanager: + common: type: build stage: build dockerfile: Dockerfile @@ -367,19 +367,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/volumemanager - title: Volumemanager - working_directory: ./applications/volumemanager/server + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{VOLUMEMANAGER_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false samples: type: build @@ -428,7 +428,7 @@ steps: == true forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false - common: + volumemanager: type: build stage: build dockerfile: Dockerfile @@ -437,19 +437,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/volumemanager + title: Volumemanager + working_directory: ./applications/volumemanager/server tags: - - '${{COMMON_TAG}}' + - '${{VOLUMEMANAGER_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 tests_unit: @@ -485,13 +485,13 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/workflows - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk - kubectl rollout status deployment/accounts - kubectl rollout status deployment/argo-gk - - kubectl rollout status deployment/common - kubectl rollout status deployment/volumemanager + - kubectl rollout status deployment/common + - kubectl rollout status deployment/workflows - sleep 60 tests_api: stage: qa @@ -511,7 +511,8 @@ steps: - APP_URL=https://workflows.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -c $CH_VALUES_PATH/deployment/helm -i workflows -a + - harness-test $CH_VALUES_PATH -c $CH_VALUES_PATH/deployment/helm -i workflows + -a samples_api_test: title: samples api test volumes: @@ -523,7 +524,8 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -c $CH_VALUES_PATH/deployment/helm -i samples -a + - harness-test $CH_VALUES_PATH -c $CH_VALUES_PATH/deployment/helm -i samples + -a - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -536,7 +538,8 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -c $CH_VALUES_PATH/deployment/helm -i volumemanager -a + - harness-test $CH_VALUES_PATH -c $CH_VALUES_PATH/deployment/helm -i volumemanager + -a common_api_test: title: common api test volumes: @@ -546,7 +549,8 @@ steps: - APP_URL=https://common.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test . -c $CH_VALUES_PATH/deployment/helm -i common -a + - harness-test $CH_VALUES_PATH -c $CH_VALUES_PATH/deployment/helm -i common + -a hooks: on_fail: exec: diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index db18f44f..c3361cb7 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -460,7 +460,7 @@ def api_tests_commands(app_config: ApplicationHarnessConfig, run_custom_tests, a commands = [] app_name = app_config.name if api_config.autotest: - commands.append(f"harness-test . -c $CH_VALUES_PATH/deployment/helm -i {app_name} -a") + commands.append(f"harness-test $CH_VALUES_PATH -c $CH_VALUES_PATH/deployment/helm -i {app_name} -a") if run_custom_tests: commands.append("pytest -v test/api") return commands From cfb4191169c90134096c109a3babc351b2d9f354 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Sun, 2 Nov 2025 22:59:49 +0000 Subject: [PATCH 64/65] fix: Update schemathesis hooks signature --- .../cloudharness_test/apitest_auth_hooks.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py b/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py index 5cac3f44..fe5e14bc 100644 --- a/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py +++ b/tools/cloudharness-test/cloudharness_test/apitest_auth_hooks.py @@ -13,12 +13,13 @@ class TokenAuth: Requires USERNAME and PASSWORD environment variables to be set. """ - def get(self, context): + def get(self, case, ctx): """ Retrieve the authentication token using username and password from environment. Args: - context: Schemathesis hook context + case: Schemathesis test case + ctx: Schemathesis hook context Returns: str: The bearer token From 30c894e90217a37421d29de58e797b00396bf890 Mon Sep 17 00:00:00 2001 From: afonso pinto Date: Mon, 3 Nov 2025 10:14:24 +0000 Subject: [PATCH 65/65] feat: Use first root path as default helm chart root folder --- deployment/codefresh-test.yaml | 246 +++++++++--------- tools/cloudharness-test/harness-test | 5 +- .../ch_cli_tools/codefresh.py | 2 +- 3 files changed, 124 insertions(+), 129 deletions(-) diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index c1b705ad..91bfca97 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -51,101 +51,101 @@ steps: type: parallel stage: build steps: - cloudharness-base: + test-e2e: type: build stage: build - dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-base - title: Cloudharness base - working_directory: ./. + image_name: cloud-harness/test-e2e + title: Test e2e + working_directory: ./test/test-e2e tags: - - '${{CLOUDHARNESS_BASE_TAG}}' + - '${{TEST_E2E_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') == false - accounts: + cloudharness-frontend-build: type: build stage: build - dockerfile: Dockerfile + dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/accounts - title: Accounts - working_directory: ./applications/accounts + image_name: cloud-harness/cloudharness-frontend-build + title: Cloudharness frontend build + working_directory: ./. tags: - - '${{ACCOUNTS_TAG}}' + - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{ACCOUNTS_TAG_EXISTS}}', '{{ACCOUNTS_TAG_EXISTS}}') - == true - forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') - == false - test-e2e: + buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true + forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false + cloudharness-base: type: build stage: build - dockerfile: Dockerfile + dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/test-e2e - title: Test e2e - working_directory: ./test/test-e2e + image_name: cloud-harness/cloudharness-base + title: Cloudharness base + working_directory: ./. tags: - - '${{TEST_E2E_TAG}}' + - '${{CLOUDHARNESS_BASE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false - cloudharness-frontend-build: + accounts: type: build stage: build - dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-frontend-build - title: Cloudharness frontend build - working_directory: ./. + image_name: cloud-harness/accounts + title: Accounts + working_directory: ./applications/accounts tags: - - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' + - '${{ACCOUNTS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false + buildDoesNotExist: includes('${{ACCOUNTS_TAG_EXISTS}}', '{{ACCOUNTS_TAG_EXISTS}}') + == true + forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') + == false title: Build parallel step 1 build_application_images_1: type: parallel stage: build steps: - samples-sum: + cloudharness-flask: type: build stage: build dockerfile: Dockerfile @@ -154,21 +154,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{SAMPLES_SUM_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') == false - samples-secret: + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -177,20 +177,20 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') - == false + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false samples-print-file: type: build stage: build @@ -214,7 +214,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - workflows-extract-download: + samples-sum: type: build stage: build dockerfile: Dockerfile @@ -223,21 +223,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - cloudharness-flask: + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + == false + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -246,20 +246,43 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') == false + workflows-send-result-event: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event + tags: + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false jupyterhub: type: build stage: build @@ -306,29 +329,6 @@ steps: '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false - workflows-send-result-event: - type: build - stage: build - dockerfile: Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event - tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false test-api: type: build stage: build @@ -381,7 +381,7 @@ steps: == true forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false - samples: + volumemanager: type: build stage: build dockerfile: Dockerfile @@ -389,23 +389,22 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/samples - title: Samples - working_directory: ./applications/samples + image_name: cloud-harness/volumemanager + title: Volumemanager + working_directory: ./applications/volumemanager/server tags: - - '${{SAMPLES_TAG}}' + - '${{VOLUMEMANAGER_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') + buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false - workflows: + samples: type: build stage: build dockerfile: Dockerfile @@ -413,22 +412,23 @@ steps: buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} + - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloud-harness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/samples + title: Samples + working_directory: ./applications/samples tags: - - '${{WORKFLOWS_TAG}}' + - '${{SAMPLES_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false - volumemanager: + workflows: type: build stage: build dockerfile: Dockerfile @@ -437,19 +437,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/volumemanager - title: Volumemanager - working_directory: ./applications/volumemanager/server + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{VOLUMEMANAGER_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{VOLUMEMANAGER_TAG_EXISTS}}', '{{VOLUMEMANAGER_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 tests_unit: @@ -485,12 +485,12 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/samples - - kubectl rollout status deployment/samples-gk - kubectl rollout status deployment/accounts + - kubectl rollout status deployment/common - kubectl rollout status deployment/argo-gk - kubectl rollout status deployment/volumemanager - - kubectl rollout status deployment/common + - kubectl rollout status deployment/samples + - kubectl rollout status deployment/samples-gk - kubectl rollout status deployment/workflows - sleep 60 tests_api: @@ -511,8 +511,7 @@ steps: - APP_URL=https://workflows.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test $CH_VALUES_PATH -c $CH_VALUES_PATH/deployment/helm -i workflows - -a + - harness-test $CH_VALUES_PATH -i workflows -a samples_api_test: title: samples api test volumes: @@ -524,8 +523,7 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test $CH_VALUES_PATH -c $CH_VALUES_PATH/deployment/helm -i samples - -a + - harness-test $CH_VALUES_PATH -i samples -a - pytest -v test/api volumemanager_api_test: title: volumemanager api test @@ -538,8 +536,7 @@ steps: - PASSWORD=test - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test $CH_VALUES_PATH -c $CH_VALUES_PATH/deployment/helm -i volumemanager - -a + - harness-test $CH_VALUES_PATH -i volumemanager -a common_api_test: title: common api test volumes: @@ -549,8 +546,7 @@ steps: - APP_URL=https://common.${{DOMAIN}}/api - SCHEMATHESIS_HOOKS=cloudharness_test.apitest_init commands: - - harness-test $CH_VALUES_PATH -c $CH_VALUES_PATH/deployment/helm -i common - -a + - harness-test $CH_VALUES_PATH -i common -a hooks: on_fail: exec: diff --git a/tools/cloudharness-test/harness-test b/tools/cloudharness-test/harness-test index 9f06856d..770ea03d 100644 --- a/tools/cloudharness-test/harness-test +++ b/tools/cloudharness-test/harness-test @@ -17,8 +17,6 @@ yaml = YAML(typ='safe') HERE = os.path.dirname(os.path.realpath(__file__)).replace(os.path.sep, '/') ROOT = os.path.dirname(os.path.dirname(HERE)).replace(os.path.sep, '/') -HELM_DIR = os.path.join('./deployment/helm') - if __name__ == "__main__": import argparse @@ -36,7 +34,7 @@ if __name__ == "__main__": help='Specify the applications to include and exclude the rest. ' 'Omit to test all application included by harness-deployment.') parser.add_argument('-c', '--helm-chart', dest='helm_chart_path', action="store", default=None, - help=f'Specify helm chart base path (default `{HELM_DIR}`') + help='Specify helm chart base path (default: deployment/helm relative to first path)') parser.add_argument('-e', '--e2e', dest='run_e2e', action="store_const", default=None, const=True, help=f'Run only end to end tests (default: run both api and end to end tests') parser.add_argument('-a', '--api', dest='run_api', action="store_const", default=None, const=True, @@ -47,6 +45,7 @@ if __name__ == "__main__": args, unknown = parser.parse_known_args(sys.argv[1:]) root_paths = [os.path.join(os.getcwd(), path) for path in args.paths] + HELM_DIR = os.path.join(root_paths[0], 'deployment/helm') if unknown: print('There are unknown args. Make sure to call the script with the accepted args. Try --help') diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index c3361cb7..85dd07b1 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -460,7 +460,7 @@ def api_tests_commands(app_config: ApplicationHarnessConfig, run_custom_tests, a commands = [] app_name = app_config.name if api_config.autotest: - commands.append(f"harness-test $CH_VALUES_PATH -c $CH_VALUES_PATH/deployment/helm -i {app_name} -a") + commands.append(f"harness-test $CH_VALUES_PATH -i {app_name} -a") if run_custom_tests: commands.append("pytest -v test/api") return commands