diff --git a/.github/workflows/integration_test.yaml b/.github/workflows/integration_test.yaml index 67f554f3..84d2206e 100644 --- a/.github/workflows/integration_test.yaml +++ b/.github/workflows/integration_test.yaml @@ -42,7 +42,9 @@ jobs: _, runner, task, variant = job.split(":") # Example: "test_charm.py" task = task.removeprefix("tests/spread/") - if runner.endswith("-arm"): + if "s390x" in runner: + architecture = "s390x" + elif runner.endswith("-arm"): architecture = "arm64" else: architecture = "amd64" @@ -86,8 +88,9 @@ jobs: runs-on: ${{ matrix.job.runner }} timeout-minutes: 217 # Sum of steps `timeout-minutes` + 5 steps: - - name: Free up disk space + - name: (GitHub hosted) Free up disk space timeout-minutes: 1 + if: ${{ !contains(matrix.job.runner, 'self-hosted') }} run: | printf '\nDisk usage before cleanup\n' df --human-readable @@ -95,6 +98,10 @@ jobs: rm -r /opt/hostedtoolcache/ printf '\nDisk usage after cleanup\n' df --human-readable + - name: (IS hosted) Disk usage + timeout-minutes: 1 + if: ${{ contains(matrix.job.runner, 'self-hosted') }} + run: df --human-readable - name: Checkout timeout-minutes: 3 uses: actions/checkout@v4 diff --git a/spread.yaml b/spread.yaml index 81fe5689..23e89701 100644 --- a/spread.yaml +++ b/spread.yaml @@ -97,6 +97,16 @@ backends: username: runner variants: - -juju29_ubuntu22 + - self-hosted-linux-s390x-noble-edge: + username: ubuntu + environment: + # Several python packages (e.g. cryptography, bcrypt) do not have s390x builds on PyPI, + # so they must be built from source. pkg-config & rust toolchain needed + # (These packages are being built when installing poetry or integration test Python + # dependencies) + CONCIERGE_EXTRA_DEBS: pipx,pkg-config,rustup + variants: + - -juju29_ubuntu22 suites: tests/spread/: @@ -114,10 +124,18 @@ prepare: | snap refresh --hold chown -R root:root "$SPREAD_PATH" cd "$SPREAD_PATH" - snap install --classic concierge + # Install via snap after https://github.com/canonical/concierge/pull/81 released + go install github.com/canonical/concierge@latest + + # Install charmcraft & pipx on lxd-vm backend and install pipx on IS-hosted runners + ~/go/bin/concierge prepare --trace - # Install charmcraft & pipx (on lxd-vm backend) - concierge prepare --trace + if [[ $SPREAD_SYSTEM == *"s390x"* ]] + then + rustup set profile minimal + # TODO add renovate comment for rust version + rustup default 1.88.0 + fi pipx install tox poetry prepare-each: | @@ -129,7 +147,7 @@ prepare-each: | poetry add --lock --group integration juju@^2 fi # `concierge prepare` needs to be run for each spread job in case Juju version changed - concierge prepare --trace + ~/go/bin/concierge prepare --trace # Unable to set constraint on all models because of Juju bug: # https://bugs.launchpad.net/juju/+bug/2065050 diff --git a/tests/integration/markers.py b/tests/integration/markers.py index 2b73cb73..de8b361f 100644 --- a/tests/integration/markers.py +++ b/tests/integration/markers.py @@ -11,3 +11,6 @@ arm64_only = pytest.mark.skipif( architecture.architecture != "arm64", reason="Requires arm64 architecture" ) +s390x_only = pytest.mark.skipif( + architecture.architecture != "s390x", reason="Requires s390x architecture" +) diff --git a/tests/integration/test_architecture.py b/tests/integration/test_architecture.py index 9440c7af..d9a2944e 100644 --- a/tests/integration/test_architecture.py +++ b/tests/integration/test_architecture.py @@ -81,4 +81,34 @@ async def test_amd_charm_on_arm_host(ops_test: OpsTest, charm, series) -> None: ) -# TODO: add s390x test +@markers.s390x_only +async def test_amd_charm_on_s390x_host(ops_test: OpsTest, charm, series) -> None: + """Tries deploying an amd64 charm on s390x host.""" + charm = charm.replace("s390x", "amd64") + + await asyncio.gather( + ops_test.model.deploy( + charm, + application_name=MYSQL_ROUTER_APP_NAME, + num_units=0, + series=series, + ), + ops_test.model.deploy( + MYSQL_TEST_APP_NAME, + application_name=MYSQL_TEST_APP_NAME, + num_units=1, + channel="latest/edge", + series=series, + ), + ) + + await ops_test.model.relate( + f"{MYSQL_ROUTER_APP_NAME}:database", + f"{MYSQL_TEST_APP_NAME}:database", + ) + + await ops_test.model.wait_for_idle( + apps=[MYSQL_ROUTER_APP_NAME], + status="error", + raise_on_error=False, + ) diff --git a/tests/integration/test_data_integrator.py b/tests/integration/test_data_integrator.py index 96ed3023..bd92beb7 100644 --- a/tests/integration/test_data_integrator.py +++ b/tests/integration/test_data_integrator.py @@ -29,7 +29,7 @@ if juju_.is_3_or_higher: tls_app_name = "self-signed-certificates" - tls_channel = "latest/edge" if architecture.architecture == "arm64" else "latest/stable" + tls_channel = "1/edge" if architecture.architecture == "s390x" else "latest/stable" tls_config = {"ca-common-name": "Test CA"} else: tls_app_name = "tls-certificates-operator" @@ -64,7 +64,7 @@ async def test_external_connectivity_with_data_integrator( ops_test.model.deploy( DATA_INTEGRATOR_APP_NAME, application_name=DATA_INTEGRATOR_APP_NAME, - channel="latest/stable", + channel="latest/edge", # Use edge for s390x series=series, config=data_integrator_config, ), diff --git a/tests/integration/test_exporter_with_tls.py b/tests/integration/test_exporter_with_tls.py index 69dbf94e..fd27d4f2 100644 --- a/tests/integration/test_exporter_with_tls.py +++ b/tests/integration/test_exporter_with_tls.py @@ -29,7 +29,7 @@ if juju_.is_3_or_higher: tls_app_name = "self-signed-certificates" - tls_channel = "latest/edge" if architecture.architecture == "arm64" else "latest/stable" + tls_channel = "1/edge" if architecture.architecture == "s390x" else "latest/stable" tls_config = {"ca-common-name": "Test CA"} else: tls_app_name = "tls-certificates-operator" @@ -138,7 +138,6 @@ async def test_exporter_endpoint(ops_test: OpsTest, charm, series) -> None: application_name=tls_app_name, channel=tls_channel, config=tls_config, - series="jammy", ) await ops_test.model.wait_for_idle([tls_app_name], status="active", timeout=SLOW_TIMEOUT) diff --git a/tests/integration/test_hacluster.py b/tests/integration/test_hacluster.py index 04f82872..dc3e6ecc 100644 --- a/tests/integration/test_hacluster.py +++ b/tests/integration/test_hacluster.py @@ -35,7 +35,7 @@ if juju_.is_3_or_higher: tls_app_name = "self-signed-certificates" - tls_channel = "latest/edge" if architecture.architecture == "arm64" else "latest/stable" + tls_channel = "1/edge" if architecture.architecture == "s390x" else "latest/stable" tls_config = {"ca-common-name": "Test CA"} else: tls_app_name = "tls-certificates-operator" @@ -111,7 +111,7 @@ async def test_external_connectivity_vip_with_hacluster(ops_test: OpsTest, charm ops_test.model.deploy( DATA_INTEGRATOR_APP_NAME, application_name=DATA_INTEGRATOR_APP_NAME, - channel="latest/stable", + channel="latest/edge", # Use edge for s390x series=series, config={"database-name": TEST_DATABASE}, num_units=4, diff --git a/tests/integration/test_tls.py b/tests/integration/test_tls.py index ea7cdd51..1ec8510b 100644 --- a/tests/integration/test_tls.py +++ b/tests/integration/test_tls.py @@ -26,7 +26,7 @@ if juju_.is_3_or_higher: tls_app_name = "self-signed-certificates" - tls_channel = "latest/edge" if architecture.architecture == "arm64" else "latest/stable" + tls_channel = "1/edge" if architecture.architecture == "s390x" else "latest/stable" tls_config = {"ca-common-name": "Test CA"} else: tls_app_name = "tls-certificates-operator" @@ -61,7 +61,6 @@ async def test_build_deploy_and_relate(ops_test: OpsTest, charm, series) -> None application_name=tls_app_name, channel=tls_channel, config=tls_config, - series="jammy", ), ops_test.model.deploy( TEST_APP_NAME, diff --git a/tests/integration/test_upgrade.py b/tests/integration/test_upgrade.py index 53a57ec0..c54db9d3 100644 --- a/tests/integration/test_upgrade.py +++ b/tests/integration/test_upgrade.py @@ -214,9 +214,10 @@ def create_valid_upgrade_charm(charm_file: typing.Union[str, pathlib.Path]) -> N # charm needs to refresh snap to be able to avoid no-op when upgrading. # set an old revision of the snap - versions["snap"]["revisions"]["x86_64"] = "121" - versions["snap"]["revisions"]["aarch64"] = "122" - versions["workload"] = "8.0.39" + versions["snap"]["revisions"]["x86_64"] = "148" + versions["snap"]["revisions"]["aarch64"] = "150" + versions["snap"]["revisions"]["s390x"] = "149" + versions["workload"] = "8.0.42" with zipfile.ZipFile(charm_file, mode="a") as charm_zip: charm_zip.writestr("refresh_versions.toml", tomli_w.dumps(versions)) diff --git a/tests/spread/test_architecture.py/task.yaml b/tests/spread/test_architecture.py/task.yaml deleted file mode 100644 index cad86336..00000000 --- a/tests/spread/test_architecture.py/task.yaml +++ /dev/null @@ -1,9 +0,0 @@ -summary: test_architecture.py -environment: - TEST_MODULE: test_architecture.py -execute: | - tox run -e integration -- "tests/integration/$TEST_MODULE" --model testing --alluredir="$SPREAD_TASK/allure-results" -artifacts: - - allure-results -backends: - - -lxd-vm # This task requires charm built on different architecture from host diff --git a/tests/spread/test_data_integrator.py/task.yaml b/tests/spread/test_data_integrator.py/task.yaml deleted file mode 100644 index 9d5bc3a5..00000000 --- a/tests/spread/test_data_integrator.py/task.yaml +++ /dev/null @@ -1,7 +0,0 @@ -summary: test_data_integrator.py -environment: - TEST_MODULE: test_data_integrator.py -execute: | - tox run -e integration -- "tests/integration/$TEST_MODULE" --model testing --alluredir="$SPREAD_TASK/allure-results" -artifacts: - - allure-results diff --git a/tests/spread/test_database.py/task.yaml b/tests/spread/test_database.py/task.yaml deleted file mode 100644 index ab87406f..00000000 --- a/tests/spread/test_database.py/task.yaml +++ /dev/null @@ -1,7 +0,0 @@ -summary: test_database.py -environment: - TEST_MODULE: test_database.py -execute: | - tox run -e integration -- "tests/integration/$TEST_MODULE" --model testing --alluredir="$SPREAD_TASK/allure-results" -artifacts: - - allure-results diff --git a/tests/spread/test_exporter.py/task.yaml b/tests/spread/test_exporter.py/task.yaml deleted file mode 100644 index 647ca870..00000000 --- a/tests/spread/test_exporter.py/task.yaml +++ /dev/null @@ -1,7 +0,0 @@ -summary: test_exporter.py -environment: - TEST_MODULE: test_exporter.py -execute: | - tox run -e integration -- "tests/integration/$TEST_MODULE" --model testing --alluredir="$SPREAD_TASK/allure-results" -artifacts: - - allure-results diff --git a/tests/spread/test_exporter_with_tls.py/task.yaml b/tests/spread/test_exporter_with_tls.py/task.yaml deleted file mode 100644 index 5974f89f..00000000 --- a/tests/spread/test_exporter_with_tls.py/task.yaml +++ /dev/null @@ -1,7 +0,0 @@ -summary: test_exporter_with_tls.py -environment: - TEST_MODULE: test_exporter_with_tls.py -execute: | - tox run -e integration -- "tests/integration/$TEST_MODULE" --model testing --alluredir="$SPREAD_TASK/allure-results" -artifacts: - - allure-results diff --git a/tests/spread/test_log_rotation.py/task.yaml b/tests/spread/test_log_rotation.py/task.yaml deleted file mode 100644 index 8e890011..00000000 --- a/tests/spread/test_log_rotation.py/task.yaml +++ /dev/null @@ -1,7 +0,0 @@ -summary: test_log_rotation.py -environment: - TEST_MODULE: test_log_rotation.py -execute: | - tox run -e integration -- "tests/integration/$TEST_MODULE" --model testing --alluredir="$SPREAD_TASK/allure-results" -artifacts: - - allure-results diff --git a/tests/spread/test_subordinate_charms.py/task.yaml b/tests/spread/test_subordinate_charms.py/task.yaml deleted file mode 100644 index 3b281deb..00000000 --- a/tests/spread/test_subordinate_charms.py/task.yaml +++ /dev/null @@ -1,9 +0,0 @@ -summary: test_subordinate_charms.py -environment: - TEST_MODULE: test_subordinate_charms.py -execute: | - tox run -e integration -- "tests/integration/$TEST_MODULE" --model testing --alluredir="$SPREAD_TASK/allure-results" -artifacts: - - allure-results -backends: - - -lxd-vm # Requires CI secrets diff --git a/tests/spread/test_upgrade.py/task.yaml b/tests/spread/test_upgrade.py/task.yaml deleted file mode 100644 index a53e8a4e..00000000 --- a/tests/spread/test_upgrade.py/task.yaml +++ /dev/null @@ -1,7 +0,0 @@ -summary: test_upgrade.py -environment: - TEST_MODULE: test_upgrade.py -execute: | - tox run -e integration -- "tests/integration/$TEST_MODULE" --model testing --alluredir="$SPREAD_TASK/allure-results" -artifacts: - - allure-results