diff --git a/test/kuttl/tests/tempest-s2i/00-set-s2i-image.yaml b/test/kuttl/tests/tempest-s2i/00-set-s2i-image.yaml new file mode 100644 index 00000000..3f8a08ae --- /dev/null +++ b/test/kuttl/tests/tempest-s2i/00-set-s2i-image.yaml @@ -0,0 +1,12 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + if [ -z "${S2I_TEMPEST_IMAGE}" ]; then + echo "SKIP: S2I_TEMPEST_IMAGE is not set (regular kuttl job)" + exit 0 + fi + echo "Patching test-operator with s2i tempest image: ${S2I_TEMPEST_IMAGE}" + oc -n openstack-operators set env deployment/test-operator-controller-manager \ + RELATED_IMAGE_TEST_TEMPEST_IMAGE_URL_DEFAULT="${S2I_TEMPEST_IMAGE}" + oc -n openstack-operators rollout status deployment/test-operator-controller-manager --timeout=120s diff --git a/test/kuttl/tests/tempest-s2i/01-deploy-tempest.yaml b/test/kuttl/tests/tempest-s2i/01-deploy-tempest.yaml new file mode 100644 index 00000000..6c76a4d1 --- /dev/null +++ b/test/kuttl/tests/tempest-s2i/01-deploy-tempest.yaml @@ -0,0 +1,15 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + if [ -z "${S2I_TEMPEST_IMAGE}" ]; then + echo "SKIP: S2I_TEMPEST_IMAGE is not set (regular kuttl job)" + exit 0 + fi + # kustomize overlay places the CR in the kuttl namespace, not openstack + NS="${NAMESPACE:-test-operator-kuttl-tests}" + oc kustomize ../../../../config/samples/layout/tempest | oc apply -f - + oc -n "${NS}" patch tempest tempest-sample --type=merge \ + -p "{\"spec\":{\"containerImage\":\"${S2I_TEMPEST_IMAGE}\"}}" + oc -n "${NS}" wait tempest tempest-sample \ + --for=condition=Ready --timeout=600s diff --git a/test/kuttl/tests/tempest-s2i/02-verify-s2i-image.yaml b/test/kuttl/tests/tempest-s2i/02-verify-s2i-image.yaml new file mode 100644 index 00000000..dbd50b3b --- /dev/null +++ b/test/kuttl/tests/tempest-s2i/02-verify-s2i-image.yaml @@ -0,0 +1,23 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + if [ -z "${S2I_TEMPEST_IMAGE}" ]; then + echo "SKIP: S2I_TEMPEST_IMAGE is not set (regular kuttl job)" + exit 0 + fi + NS="${NAMESPACE:-test-operator-kuttl-tests}" + POD_IMAGE=$(oc -n "${NS}" get pod -l instanceName=tempest-sample \ + -o jsonpath='{.items[0].spec.containers[0].image}') + echo "Tempest pod image: ${POD_IMAGE}" + echo "Expected S2I image: ${S2I_TEMPEST_IMAGE}" + if [ -z "${POD_IMAGE}" ]; then + echo "ERROR: no tempest-sample pod found in ${NS}" + oc -n "${NS}" get pods,tempest + exit 1 + fi + if [ "${POD_IMAGE}" != "${S2I_TEMPEST_IMAGE}" ]; then + echo "ERROR: Tempest pod is NOT running the S2I image" + exit 1 + fi + echo "Confirmed: Tempest pod is running the S2I image" diff --git a/test/kuttl/tests/tempest-s2i/99-cleanup.yaml b/test/kuttl/tests/tempest-s2i/99-cleanup.yaml new file mode 120000 index 00000000..10247253 --- /dev/null +++ b/test/kuttl/tests/tempest-s2i/99-cleanup.yaml @@ -0,0 +1 @@ +../../common/cleanup-all-tests.yaml \ No newline at end of file diff --git a/test/kuttl/tests/tempest-s2i/99-errors.yaml b/test/kuttl/tests/tempest-s2i/99-errors.yaml new file mode 120000 index 00000000..bf7974ab --- /dev/null +++ b/test/kuttl/tests/tempest-s2i/99-errors.yaml @@ -0,0 +1 @@ +../../common/errors-cleanup.yaml \ No newline at end of file diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml index a8e8f389..80769713 100644 --- a/zuul.d/jobs.yaml +++ b/zuul.d/jobs.yaml @@ -217,3 +217,84 @@ override-checkout: main - name: github.com/openstack-k8s-operators/openstack-must-gather override-checkout: main + +- job: + name: tempest-s2i-content-provider + parent: s2i-openstack-container-content-provider + description: | + Build s2i tempest images for tempest-s2i-tempest. + required-projects: + - name: openstack-k8s-operators/s2i-openstack-containers + override-checkout: main + vars: + s2i_ci_images: + - tempest/tempest + +- job: + name: test-operator-kuttl-s2i + parent: test-operator-kuttl + description: | + KUTTL test using s2i-built test-operator container images. + Currently runs only the tempest-s2i suite: pins the Tempest CR + to the s2i tempest image and asserts the tempest pod is using + that image. Named without a CR-type suffix so Tobiko, + AnsibleTest, and HorizonTest suites can be added later. + + The s2i content provider deploys its own plain Docker registry on + the builder node. CRC is configured to trust it via + cifmw_crc_additional_insecure_registries. + required-projects: + - name: openstack-k8s-operators/s2i-openstack-containers + override-checkout: main + vars: + cifmw_crc_additional_insecure_registries: + - "{{ s2i_content_provider_registry_ip }}:5001" + cifmw_crc_additional_allowed_registries: + - "{{ s2i_content_provider_registry_ip }}:5001" + cifmw_kuttl_tests_env_vars: + PV_NUM: 20 + KUTTL_ARGS: "--test tempest-s2i" + S2I_TEMPEST_IMAGE: >- + {{ s2i_content_provider_registry_ip }}:5001/{{ s2i_ci_content.namespace }}/openstack-tempest:{{ s2i_ci_content.tag }} + +- job: + name: tempest-s2i-tempest + parent: podified-multinode-edpm-deployment-crc-test-operator + description: | + Validate speculatively-built s2i tempest images against a live + OpenStack deployment. The s2i-built openstack-tempest image from + tempest-s2i-content-provider is pinned via cifmw_test_operator_* + image vars (test workload, not an OpenStackVersion field). + required-projects: + - name: openstack-k8s-operators/s2i-openstack-containers + override-checkout: main + vars: + cifmw_crc_additional_insecure_registries: + - "{{ s2i_content_provider_registry_ip }}:5001" + cifmw_crc_additional_allowed_registries: + - "{{ s2i_content_provider_registry_ip }}:5001" + cifmw_test_operator_stages: + - name: tempest + type: tempest + cifmw_test_operator_tempest_registry: >- + {{ s2i_content_provider_registry_ip }}:5001 + cifmw_test_operator_tempest_namespace: "{{ s2i_ci_content.namespace }}" + cifmw_test_operator_tempest_container: openstack-tempest + cifmw_test_operator_tempest_image_tag: "{{ s2i_ci_content.tag }}" + # Workaround: s2i tempest is built from current git, which requests + # project_manager credentials in setUpClass. Dynamic creds look up + # a Keystone role named "manager" and fail with: + # tempest.lib.exceptions.NotFound: No "manager" role found + # This CRC cloud does not bootstrap that role (Keystone added it + # in 2023.2). Drop these once the deployment provides it. + # Also probing test_aggregate_add_host_create_server_with_az + # (Nova AZ scheduling / exhausted hosts on CRC+EDPM). Drop if it + # stays green, exclude if it keeps failing. + # run_tempest.sh matches expected failures with grep -Fx against + # stestr failing --list, so these must be the exact stestr IDs. + cifmw_test_operator_tempest_expected_failures_list: | + setUpClass (tempest.scenario.test_shelve_instance.TestShelveInstance) + setUpClass (tempest.api.compute.admin.test_migrations.MigrationsAdminTest) + setUpClass (tempest.scenario.test_network_advanced_server_ops.TestNetworkAdvancedServerOps) + setUpClass (tempest.scenario.test_network_advanced_server_ops.TestNetworkAdvancedServerMigrationWithHost) + tempest.serial_tests.api.compute.admin.test_aggregates.AggregatesAdminTestJSON.test_aggregate_add_host_create_server_with_az diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml index 50a2c727..7a84c7fe 100644 --- a/zuul.d/projects.yaml +++ b/zuul.d/projects.yaml @@ -12,3 +12,15 @@ - podified-multinode-edpm-deployment-crc-test-operator: dependencies: - openstack-k8s-operators-content-provider + - tempest-s2i-content-provider: + voting: false + - test-operator-kuttl-s2i: + voting: false + dependencies: + - openstack-k8s-operators-content-provider + - tempest-s2i-content-provider + - tempest-s2i-tempest: + voting: false + dependencies: + - openstack-k8s-operators-content-provider + - tempest-s2i-content-provider