Skip to content

Commit ee5d2ff

Browse files
Run integration tests on arm64 (#278)
1 parent 156da2d commit ee5d2ff

File tree

8 files changed

+93
-39
lines changed

8 files changed

+93
-39
lines changed

.github/workflows/ci.yaml

+12-4
Original file line numberDiff line numberDiff line change
@@ -75,21 +75,29 @@ jobs:
7575
juju:
7676
- agent: 2.9.49 # renovate: juju-agent-pin-minor
7777
libjuju: ^2
78-
allure: false
78+
allure_on_amd64: false
7979
- agent: 3.4.3 # renovate: juju-agent-pin-minor
80-
allure: true
81-
name: Integration test charm | ${{ matrix.juju.agent }}
80+
allure_on_amd64: true
81+
architecture:
82+
- amd64
83+
include:
84+
- juju:
85+
agent: 3.4.3 # renovate: juju-agent-pin-minor
86+
allure_on_amd64: true
87+
architecture: arm64
88+
name: Integration test charm | ${{ matrix.juju.agent }} | ${{ matrix.architecture }}
8289
needs:
8390
- lint
8491
- unit-test
8592
- build
8693
uses: canonical/data-platform-workflows/.github/workflows/[email protected]
8794
with:
8895
artifact-prefix: ${{ needs.build.outputs.artifact-prefix }}
96+
architecture: ${{ matrix.architecture }}
8997
cloud: microk8s
9098
microk8s-snap-channel: 1.28-strict/stable
9199
juju-agent-version: ${{ matrix.juju.agent }}
92100
libjuju-version-constraint: ${{ matrix.juju.libjuju }}
93-
_beta_allure_report: ${{ matrix.juju.allure }}
101+
_beta_allure_report: ${{ matrix.juju.allure_on_amd64 && matrix.architecture == 'amd64' }}
94102
permissions:
95103
contents: write # Needed for Allure Report beta

tests/integration/architecture.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright 2024 Canonical Ltd.
2+
# See LICENSE file for licensing details.
3+
import subprocess
4+
5+
architecture = subprocess.run(
6+
["dpkg", "--print-architecture"], capture_output=True, check=True, encoding="utf-8"
7+
).stdout.strip()

tests/integration/helpers.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import itertools
55
import json
66
import logging
7+
import pathlib
78
import subprocess
89
import tempfile
910
from typing import Dict, List, Optional
@@ -205,13 +206,13 @@ async def write_content_to_file_in_unit(
205206
"""
206207
pod_name = unit.name.replace("/", "-")
207208

208-
with tempfile.NamedTemporaryFile(mode="w") as temp_file:
209+
with tempfile.NamedTemporaryFile(mode="w", dir=pathlib.Path.home()) as temp_file:
209210
temp_file.write(content)
210211
temp_file.flush()
211212

212213
subprocess.run(
213214
[
214-
"kubectl",
215+
"microk8s.kubectl",
215216
"cp",
216217
"-n",
217218
ops_test.model.info.name,
@@ -240,10 +241,10 @@ async def read_contents_from_file_in_unit(
240241
"""
241242
pod_name = unit.name.replace("/", "-")
242243

243-
with tempfile.NamedTemporaryFile(mode="r+") as temp_file:
244+
with tempfile.NamedTemporaryFile(mode="r+", dir=pathlib.Path.home()) as temp_file:
244245
subprocess.run(
245246
[
246-
"kubectl",
247+
"microk8s.kubectl",
247248
"cp",
248249
"-n",
249250
ops_test.model.info.name,
@@ -351,7 +352,7 @@ async def rotate_mysqlrouter_logs(ops_test: OpsTest, unit_name: str) -> None:
351352

352353
subprocess.run(
353354
[
354-
"kubectl",
355+
"microk8s.kubectl",
355356
"exec",
356357
"-n",
357358
ops_test.model.info.name,

tests/integration/markers.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@
33

44
import pytest
55

6-
from . import juju_
6+
from . import architecture, juju_
77

88
skip_if_lower_than_3_1 = pytest.mark.skipif(
99
not juju_.is_3_1_or_higher,
1010
reason="Skips juju <3.1.x as we have a dependency for self-signed-certificates",
1111
)
12+
amd64_only = pytest.mark.skipif(
13+
architecture.architecture != "amd64", reason="Requires amd64 architecture"
14+
)
15+
arm64_only = pytest.mark.skipif(
16+
architecture.architecture != "arm64", reason="Requires arm64 architecture"
17+
)

tests/integration/test_exporter.py

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import yaml
1313
from pytest_operator.plugin import OpsTest
1414

15+
from . import markers
1516
from .helpers import (
1617
APPLICATION_DEFAULT_APP_NAME,
1718
MYSQL_DEFAULT_APP_NAME,
@@ -32,6 +33,10 @@
3233

3334

3435
@pytest.mark.group(1)
36+
# TODO: remove amd64_only after these issues fixed:
37+
# https://github.com/canonical/mysql-router-k8s-operator/issues/282
38+
# https://github.com/canonical/grafana-agent-k8s-operator/issues/309
39+
@markers.amd64_only
3540
@pytest.mark.abort_on_fail
3641
async def test_exporter_endpoint(ops_test: OpsTest) -> None:
3742
"""Test that exporter endpoint is functional."""

tests/integration/test_exporter_with_tls.py

+28-16
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import yaml
1313
from pytest_operator.plugin import OpsTest
1414

15-
from . import juju_
15+
from . import architecture, juju_, markers
1616
from .helpers import (
1717
APPLICATION_DEFAULT_APP_NAME,
1818
MYSQL_DEFAULT_APP_NAME,
@@ -33,14 +33,26 @@
3333
RETRY_TIMEOUT = 3 * 60
3434

3535
if juju_.is_3_or_higher:
36-
TLS_APP_NAME = "self-signed-certificates"
37-
TLS_CONFIG = {"ca-common-name": "Test CA"}
36+
tls_app_name = "self-signed-certificates"
37+
if architecture.architecture == "arm64":
38+
tls_channel = "latest/edge"
39+
else:
40+
tls_channel = "latest/stable"
41+
tls_config = {"ca-common-name": "Test CA"}
3842
else:
39-
TLS_APP_NAME = "tls-certificates-operator"
40-
TLS_CONFIG = {"generate-self-signed-certificates": "true", "ca-common-name": "Test CA"}
43+
tls_app_name = "tls-certificates-operator"
44+
if architecture.architecture == "arm64":
45+
tls_channel = "legacy/edge"
46+
else:
47+
tls_channel = "legacy/stable"
48+
tls_config = {"generate-self-signed-certificates": "true", "ca-common-name": "Test CA"}
4149

4250

4351
@pytest.mark.group(1)
52+
# TODO: remove amd64_only after these issues fixed:
53+
# https://github.com/canonical/mysql-router-k8s-operator/issues/282
54+
# https://github.com/canonical/grafana-agent-k8s-operator/issues/309
55+
@markers.amd64_only
4456
@pytest.mark.abort_on_fail
4557
async def test_exporter_endpoint(ops_test: OpsTest) -> None:
4658
"""Test that the exporter endpoint works when related with TLS"""
@@ -125,21 +137,21 @@ async def test_exporter_endpoint(ops_test: OpsTest) -> None:
125137
"Issuer: CN = MySQL_Router_Auto_Generated_CA_Certificate" in issuer
126138
), "Expected mysqlrouter autogenerated certificate"
127139

128-
logger.info(f"Deploying {TLS_APP_NAME}")
140+
logger.info(f"Deploying {tls_app_name}")
129141
await ops_test.model.deploy(
130-
TLS_APP_NAME,
131-
application_name=TLS_APP_NAME,
132-
channel="stable",
133-
config=TLS_CONFIG,
142+
tls_app_name,
143+
application_name=tls_app_name,
144+
channel=tls_channel,
145+
config=tls_config,
134146
series="jammy",
135147
)
136148

137-
await ops_test.model.wait_for_idle([TLS_APP_NAME], status="active", timeout=SLOW_TIMEOUT)
149+
await ops_test.model.wait_for_idle([tls_app_name], status="active", timeout=SLOW_TIMEOUT)
138150

139-
logger.info(f"Relating mysqlrouter with {TLS_APP_NAME}")
151+
logger.info(f"Relating mysqlrouter with {tls_app_name}")
140152

141153
await ops_test.model.relate(
142-
f"{MYSQL_ROUTER_APP_NAME}:certificates", f"{TLS_APP_NAME}:certificates"
154+
f"{MYSQL_ROUTER_APP_NAME}:certificates", f"{tls_app_name}:certificates"
143155
)
144156

145157
unit_address = await get_unit_address(ops_test, mysql_router_app.units[0].name)
@@ -198,7 +210,7 @@ async def test_exporter_endpoint(ops_test: OpsTest) -> None:
198210
)
199211
assert (
200212
"CN = Test CA" in issuer
201-
), f"Expected mysqlrouter certificate from {TLS_APP_NAME}"
213+
), f"Expected mysqlrouter certificate from {tls_app_name}"
202214

203215
logger.info("Removing relation between mysqlrouter and grafana agent")
204216
await mysql_router_app.remove_relation(
@@ -220,9 +232,9 @@ async def test_exporter_endpoint(ops_test: OpsTest) -> None:
220232
else:
221233
assert False, "❌ can connect to metrics endpoint without relation with cos"
222234

223-
logger.info(f"Removing relation between mysqlrouter and {TLS_APP_NAME}")
235+
logger.info(f"Removing relation between mysqlrouter and {tls_app_name}")
224236
await mysql_router_app.remove_relation(
225-
f"{MYSQL_ROUTER_APP_NAME}:certificates", f"{TLS_APP_NAME}:certificates"
237+
f"{MYSQL_ROUTER_APP_NAME}:certificates", f"{tls_app_name}:certificates"
226238
)
227239

228240
for attempt in tenacity.Retrying(

tests/integration/test_node_port.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import yaml
1212
from pytest_operator.plugin import OpsTest
1313

14-
from . import markers
14+
from . import architecture, markers
1515
from .helpers import (
1616
APPLICATION_DEFAULT_APP_NAME,
1717
MYSQL_DEFAULT_APP_NAME,
@@ -35,6 +35,11 @@
3535
DATA_INTEGRATOR = "data-integrator"
3636
SLOW_TIMEOUT = 15 * 60
3737
MODEL_CONFIG = {"logging-config": "<root>=INFO;unit=DEBUG"}
38+
if architecture.architecture == "arm64":
39+
tls_channel = "latest/edge"
40+
else:
41+
tls_channel = "latest/stable"
42+
TLS_CONFIG = {"ca-common-name": "Test CA"}
3843

3944

4045
@pytest.mark.group(1)
@@ -86,7 +91,9 @@ async def test_build_and_deploy(ops_test: OpsTest):
8691
),
8792
ops_test.model.deploy(
8893
SELF_SIGNED_CERTIFICATE_NAME,
94+
channel=tls_channel,
8995
application_name=SELF_SIGNED_CERTIFICATE_NAME,
96+
config=TLS_CONFIG,
9097
series="jammy",
9198
num_units=1,
9299
),

tests/integration/test_tls.py

+20-12
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import yaml
1111
from pytest_operator.plugin import OpsTest
1212

13-
from . import juju_
13+
from . import architecture, juju_
1414
from .helpers import (
1515
APPLICATION_DEFAULT_APP_NAME,
1616
MYSQL_DEFAULT_APP_NAME,
@@ -29,11 +29,19 @@
2929
RETRY_TIMEOUT = 2 * 60
3030

3131
if juju_.is_3_or_higher:
32-
TLS_APP_NAME = "self-signed-certificates"
33-
TLS_CONFIG = {"ca-common-name": "Test CA"}
32+
tls_app_name = "self-signed-certificates"
33+
if architecture.architecture == "arm64":
34+
tls_channel = "latest/edge"
35+
else:
36+
tls_channel = "latest/stable"
37+
tls_config = {"ca-common-name": "Test CA"}
3438
else:
35-
TLS_APP_NAME = "tls-certificates-operator"
36-
TLS_CONFIG = {"generate-self-signed-certificates": "true", "ca-common-name": "Test CA"}
39+
tls_app_name = "tls-certificates-operator"
40+
if architecture.architecture == "arm64":
41+
tls_channel = "legacy/edge"
42+
else:
43+
tls_channel = "legacy/stable"
44+
tls_config = {"generate-self-signed-certificates": "true", "ca-common-name": "Test CA"}
3745

3846

3947
@pytest.mark.group(1)
@@ -71,10 +79,10 @@ async def test_build_deploy_and_relate(ops_test: OpsTest) -> None:
7179
trust=True,
7280
),
7381
ops_test.model.deploy(
74-
TLS_APP_NAME,
75-
application_name=TLS_APP_NAME,
76-
channel="stable",
77-
config=TLS_CONFIG,
82+
tls_app_name,
83+
application_name=tls_app_name,
84+
channel=tls_channel,
85+
config=tls_config,
7886
series="jammy",
7987
),
8088
ops_test.model.deploy(
@@ -121,7 +129,7 @@ async def test_connected_encryption(ops_test: OpsTest) -> None:
121129
), "Expected mysqlrouter autogenerated certificate"
122130

123131
logger.info("Relating TLS with mysqlrouter")
124-
await ops_test.model.relate(TLS_APP_NAME, MYSQL_ROUTER_APP_NAME)
132+
await ops_test.model.relate(tls_app_name, MYSQL_ROUTER_APP_NAME)
125133

126134
logger.info("Getting certificate issuer after relating with tls operator")
127135
for attempt in tenacity.Retrying(
@@ -138,11 +146,11 @@ async def test_connected_encryption(ops_test: OpsTest) -> None:
138146
)
139147
assert (
140148
"CN = Test CA" in issuer
141-
), f"Expected mysqlrouter certificate from {TLS_APP_NAME}"
149+
), f"Expected mysqlrouter certificate from {tls_app_name}"
142150

143151
logger.info("Removing relation TLS with mysqlrouter")
144152
await ops_test.model.applications[MYSQL_ROUTER_APP_NAME].remove_relation(
145-
f"{TLS_APP_NAME}:certificates", f"{MYSQL_ROUTER_APP_NAME}:certificates"
153+
f"{tls_app_name}:certificates", f"{MYSQL_ROUTER_APP_NAME}:certificates"
146154
)
147155

148156
for attempt in tenacity.Retrying(

0 commit comments

Comments
 (0)