Skip to content

Commit

Permalink
Update GH runners: use juju 3.1.5 for CI (#245)
Browse files Browse the repository at this point in the history
## Issue
We need to test Juju secrets integration on CI and to test the charm
with latest Juju version which is installed with snap by default

## Solution
Configure Github runners to use Juju 3.1.5
  • Loading branch information
dmitry-ratushnyy authored Sep 13, 2023
1 parent ee973f0 commit a4b6484
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 32 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ jobs:
uses: charmed-kubernetes/actions-operator@main
with:
provider: lxd
juju-channel: 3.1/stable
bootstrap-options: "--agent-version 3.1.5"
- name: Download packed charm(s)
uses: actions/download-artifact@v3
with:
Expand Down
24 changes: 14 additions & 10 deletions tests/integration/ha_tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ async def reused_storage(ops_test: OpsTest, unit_name, removal_time) -> bool:
If member transitions to STARTUP2 from REMOVED then it is re-using the storage we
provided.
"""
cat_cmd = f"run --unit {unit_name} -- cat {MONGODB_LOG_PATH}"
cat_cmd = f"exec --unit {unit_name} -- cat {MONGODB_LOG_PATH}"
return_code, output, _ = await ops_test.juju(*cat_cmd.split())

if return_code != 0:
Expand Down Expand Up @@ -488,7 +488,7 @@ async def kill_unit_process(ops_test: OpsTest, unit_name: str, kill_code: str):
await ops_test.model.applications[app].add_unit(count=1)
await ops_test.model.wait_for_idle(apps=[app], status="active", timeout=1000)

kill_cmd = f"run --unit {unit_name} -- pkill --signal {kill_code} -f {DB_PROCESS}"
kill_cmd = f"exec --unit {unit_name} -- pkill --signal {kill_code} -f {DB_PROCESS}"
return_code, _, _ = await ops_test.juju(*kill_cmd.split())

if return_code != 0:
Expand Down Expand Up @@ -520,7 +520,7 @@ async def db_step_down(ops_test: OpsTest, old_primary_unit: str, sigterm_time: i
app = await app_name(ops_test)
for unit in ops_test.model.applications[app].units:
# verify log file exists on this machine
search_file = f"run --unit {unit.name} ls {MONGODB_LOG_PATH}"
search_file = f"exec --unit {unit.name} ls {MONGODB_LOG_PATH}"
return_code, _, _ = await ops_test.juju(*search_file.split())
if return_code == 2:
continue
Expand Down Expand Up @@ -558,7 +558,7 @@ async def all_db_processes_down(ops_test: OpsTest) -> bool:
for attempt in Retrying(stop=stop_after_attempt(60), wait=wait_fixed(3)):
with attempt:
for unit in ops_test.model.applications[app].units:
search_db_process = f"run --unit {unit.name} pgrep -x mongod"
search_db_process = f"exec --unit {unit.name} pgrep -x mongod"
_, processes, _ = await ops_test.juju(*search_db_process.split())
# splitting processes by "\n" results in one or more empty lines, hence we
# need to process these lines accordingly.
Expand Down Expand Up @@ -592,7 +592,9 @@ async def update_restart_delay(ops_test: OpsTest, unit, delay: int):
# MONGOD_SERVICE_DEFAULT_PATH since this directory has strict permissions, instead we scp it
# elsewhere and then move it to MONGOD_SERVICE_DEFAULT_PATH.
await unit.scp_to(source=TMP_SERVICE_PATH, destination="mongod.service")
mv_cmd = f"run --unit {unit.name} mv /home/ubuntu/mongod.service {MONGOD_SERVICE_DEFAULT_PATH}"
mv_cmd = (
f"exec --unit {unit.name} mv /home/ubuntu/mongod.service {MONGOD_SERVICE_DEFAULT_PATH}"
)
return_code, _, _ = await ops_test.juju(*mv_cmd.split())
if return_code != 0:
raise ProcessError(f"Command: {mv_cmd} failed on unit: {unit.name}.")
Expand All @@ -601,7 +603,7 @@ async def update_restart_delay(ops_test: OpsTest, unit, delay: int):
subprocess.call(["rm", TMP_SERVICE_PATH])

# reload the daemon for systemd otherwise changes are not saved
reload_cmd = f"run --unit {unit.name} systemctl daemon-reload"
reload_cmd = f"exec --unit {unit.name} systemctl daemon-reload"
return_code, _, _ = await ops_test.juju(*reload_cmd.split())
if return_code != 0:
raise ProcessError(f"Command: {reload_cmd} failed on unit: {unit.name}.")
Expand Down Expand Up @@ -633,7 +635,9 @@ async def update_service_logging(ops_test: OpsTest, unit, logging: bool):
# MONGOD_SERVICE_DEFAULT_PATH since this directory has strict permissions, instead we scp it
# elsewhere and then move it to MONGOD_SERVICE_DEFAULT_PATH.
await unit.scp_to(source=TMP_SERVICE_PATH, destination="mongod.service")
mv_cmd = f"run --unit {unit.name} mv /home/ubuntu/mongod.service {MONGOD_SERVICE_DEFAULT_PATH}"
mv_cmd = (
f"exec --unit {unit.name} mv /home/ubuntu/mongod.service {MONGOD_SERVICE_DEFAULT_PATH}"
)
return_code, _, _ = await ops_test.juju(*mv_cmd.split())
if return_code != 0:
raise ProcessError(f"Command: {mv_cmd} failed on unit: {unit.name}.")
Expand All @@ -642,21 +646,21 @@ async def update_service_logging(ops_test: OpsTest, unit, logging: bool):
subprocess.call(["rm", TMP_SERVICE_PATH])

# reload the daemon for systemd otherwise changes are not saved
reload_cmd = f"run --unit {unit.name} systemctl daemon-reload"
reload_cmd = f"exec --unit {unit.name} systemctl daemon-reload"
return_code, _, _ = await ops_test.juju(*reload_cmd.split())
if return_code != 0:
raise ProcessError(f"Command: {reload_cmd} failed on unit: {unit.name}.")


async def stop_mongod(ops_test: OpsTest, unit) -> None:
"""Safely stops the mongod process."""
stop_db_process = f"run --unit {unit.name} snap stop charmed-mongodb.mongod"
stop_db_process = f"exec --unit {unit.name} snap stop charmed-mongodb.mongod"
await ops_test.juju(*stop_db_process.split())


async def start_mongod(ops_test: OpsTest, unit) -> None:
"""Safely starts the mongod process."""
start_db_process = f"run --unit {unit.name} snap start charmed-mongodb.mongod"
start_db_process = f"exec --unit {unit.name} snap start charmed-mongodb.mongod"
await ops_test.juju(*start_db_process.split())


Expand Down
2 changes: 1 addition & 1 deletion tests/integration/ha_tests/test_ha.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ async def change_logging(ops_test: OpsTest):
time.sleep(15)

# remove the log file as to not clog up space on the replicas.
rm_cmd = f"run --unit {unit.name} rm {helpers.MONGODB_LOG_PATH}"
rm_cmd = f"exec --unit {unit.name} rm {helpers.MONGODB_LOG_PATH}"
await ops_test.juju(*rm_cmd.split())


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ async def check_tls(ops_test: OpsTest, unit: ops.model.Unit, enabled: bool) -> b
):
with attempt:
mongod_tls_check = await mongo_tls_command(ops_test)
check_tls_cmd = f"run --unit {unit.name} -- {mongod_tls_check}"
check_tls_cmd = f"exec --unit {unit.name} -- {mongod_tls_check}"
return_code, _, _ = await ops_test.juju(*check_tls_cmd.split())
tls_enabled = return_code == 0
if enabled != tls_enabled:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
APP_NAMES = [GRAYLOG_APP_NAME, ELASTIC_APP_NAME, DATABASE_APP_NAME]


@pytest.mark.abort_on_fail
@pytest.mark.skip("Reactive charms don't work with juju 3.1.5")
async def test_build_deploy_charms(ops_test: OpsTest):
"""Deploy both charms (application and database) to use in the tests."""
# Deploy both charms (2 units for each application to test that later they correctly
Expand Down Expand Up @@ -64,6 +64,7 @@ async def test_build_deploy_charms(ops_test: OpsTest):
)


@pytest.mark.skip("Reactive charms don't work with juju 3.1.5")
async def test_relation_data(ops_test: OpsTest) -> None:
"""Test the relation data is set correctly for this legacy relation."""
related_unit_name = ops_test.model.applications[DATABASE_APP_NAME].units[0].name
Expand Down Expand Up @@ -93,6 +94,7 @@ async def test_relation_data(ops_test: OpsTest) -> None:
assert replset == DATABASE_APP_NAME


@pytest.mark.skip("Reactive charms don't work with juju 3.1.5")
async def test_mongodb_auth_disabled(ops_test: OpsTest) -> None:
"""Test mongodb no longer uses auth after relating to a legacy relation."""
unit = ops_test.model.applications[DATABASE_APP_NAME].units[0]
Expand All @@ -102,6 +104,7 @@ async def test_mongodb_auth_disabled(ops_test: OpsTest) -> None:
), "MongoDB requires authentication after legacy relation"


@pytest.mark.skip("Reactive charms don't work with juju 3.1.5")
async def test_legacy_db_ops(ops_test: OpsTest) -> None:
"""Test graylog is able to do CRUD operations."""
try:
Expand Down Expand Up @@ -129,11 +132,12 @@ async def test_legacy_db_ops(ops_test: OpsTest) -> None:
assert "users:tokenlist" not in user_info["permissions"], "unable to perform delete operations"


@pytest.mark.skip("Reactive charms don't work with juju 3.1.5")
async def test_add_unit_joins_without_auth(ops_test: OpsTest):
"""Verify scaling mongodb with legacy relations supports no auth."""
await ops_test.model.applications[DATABASE_APP_NAME].add_unit(count=1)
await ops_test.model.wait_for_idle(
apps=[DATABASE_APP_NAME], status="active", timeout=1000, wait_for_units=3
apps=[DATABASE_APP_NAME], status="active", timeout=1000, wait_for_exact_units=3
)

# verify auth is still disabled
Expand Down Expand Up @@ -197,7 +201,7 @@ async def test_new_relation_fails_with_legacy(ops_test: OpsTest) -> None:
), "MongoDB requires disabled authentication to support legacy relations"


@pytest.mark.unstable
@pytest.mark.skip("Reactive charms don't work with juju 3.1.5")
async def test_legacy_relation_fails_with_new(ops_test: OpsTest) -> None:
"""Verify legacy relation joining results in blocked when new relations exist."""
database = await ops_test.build_charm(".")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ async def test_deploy_charms(ops_test: OpsTest, application_charm, database_char
application_name=ANOTHER_DATABASE_APP_NAME,
),
)
await ops_test.model.wait_for_idle(apps=APP_NAMES, status="active", wait_for_units=1)
await ops_test.model.wait_for_idle(apps=APP_NAMES, status="active", wait_for_at_least_units=1)


@pytest.mark.abort_on_fail
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ async def test_monitor_user(ops_test: OpsTest) -> None:
replica_set_uri = f"mongodb://monitor:{password}@{hosts}/admin?replicaSet=mongodb"

admin_mongod_cmd = f"charmed-mongodb.mongo '{replica_set_uri}' --eval 'rs.conf()'"
check_monitor_cmd = f"run --unit {unit.name} -- {admin_mongod_cmd}"
check_monitor_cmd = f"exec --unit {unit.name} -- {admin_mongod_cmd}"
return_code, _, _ = await ops_test.juju(*check_monitor_cmd.split())
assert return_code == 0, "command rs.conf() on monitor user does not work"

Expand Down
8 changes: 3 additions & 5 deletions tests/integration/tls_tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ async def check_tls(ops_test: OpsTest, unit: ops.model.Unit, enabled: bool) -> b
):
with attempt:
mongod_tls_check = await mongo_tls_command(ops_test)
check_tls_cmd = f"run --unit {unit.name} -- {mongod_tls_check}"
check_tls_cmd = f"exec --unit {unit.name} -- {mongod_tls_check}"
return_code, _, _ = await ops_test.juju(*check_tls_cmd.split())
tls_enabled = return_code == 0
if enabled != tls_enabled:
Expand All @@ -70,7 +70,7 @@ async def check_tls(ops_test: OpsTest, unit: ops.model.Unit, enabled: bool) -> b

async def time_file_created(ops_test: OpsTest, unit_name: str, path: str) -> int:
"""Returns the unix timestamp of when a file was created on a specified unit."""
time_cmd = f"run --unit {unit_name} -- ls -l --time-style=full-iso {path} "
time_cmd = f"exec --unit {unit_name} -- ls -l --time-style=full-iso {path} "
return_code, ls_output, _ = await ops_test.juju(*time_cmd.split())

if return_code != 0:
Expand All @@ -83,9 +83,7 @@ async def time_file_created(ops_test: OpsTest, unit_name: str, path: str) -> int

async def time_process_started(ops_test: OpsTest, unit_name: str, process_name: str) -> int:
"""Retrieves the time that a given process started according to systemd."""
time_cmd = (
f"run --unit {unit_name} -- systemctl show {process_name} --property=ActiveEnterTimestamp"
)
time_cmd = f"exec --unit {unit_name} -- systemctl show {process_name} --property=ActiveEnterTimestamp"
return_code, systemctl_output, _ = await ops_test.juju(*time_cmd.split())

if return_code != 0:
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/tls_tests/test_tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async def test_build_and_deploy(ops_test: OpsTest) -> None:
await ops_test.model.wait_for_idle(apps=[DATABASE_APP_NAME], status="active")

config = {"generate-self-signed-certificates": "true", "ca-common-name": "Test CA"}
await ops_test.model.deploy(TLS_CERTIFICATES_APP_NAME, channel="edge", config=config)
await ops_test.model.deploy(TLS_CERTIFICATES_APP_NAME, channel="stable", config=config)
await ops_test.model.wait_for_idle(
apps=[TLS_CERTIFICATES_APP_NAME], status="active", timeout=1000
)
Expand Down
20 changes: 11 additions & 9 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ description = Run unit tests
deps =
pytest
requests
juju==3.2.0.1
coverage[toml]
-r {tox_root}/requirements.txt
commands =
Expand All @@ -72,7 +73,7 @@ pass_env =
CI_PACKED_CHARMS
deps =
pytest
juju==2.9.44.0 # The latest python-libjuju that supports both juju 2.9 and 3.0
juju==3.2.0.1
pytest-operator
-r {tox_root}/requirements.txt
commands =
Expand All @@ -86,7 +87,7 @@ pass_env =
CI_PACKED_CHARMS
deps =
pytest
juju==2.9.44.0 # The latest python-libjuju that supports both juju 2.9 and 3.0
juju==3.2.0.1
pytest-operator
-r {tox_root}/requirements.txt
commands =
Expand All @@ -100,7 +101,8 @@ pass_env =
CI_PACKED_CHARMS
deps =
pytest
juju==2.9.44.0 # The latest python-libjuju that supports both juju 2.9 and 3.0
juju==3.2.0.1
pytest-mock
pytest-operator
-r {tox_root}/requirements.txt
commands =
Expand All @@ -114,7 +116,7 @@ pass_env =
CI_PACKED_CHARMS
deps =
pytest
juju==2.9.44.0 # The latest python-libjuju that supports both juju 2.9 and 3.0
juju==3.2.0.1
pytest-operator
-r {tox_root}/requirements.txt
commands =
Expand All @@ -128,7 +130,7 @@ pass_env =
CI_PACKED_CHARMS
deps =
pytest
juju==2.9.44.0 # The latest python-libjuju that supports both juju 2.9 and 3.0
juju==3.2.0.1
pytest-operator
-r {tox_root}/requirements.txt
commands =
Expand All @@ -147,7 +149,7 @@ pass_env =
GCP_SECRET_KEY
deps =
pytest
juju==2.9.44.0 # The latest python-libjuju that supports both juju 2.9 and 3.0
juju==3.2.0.1
pytest-operator
-r {tox_root}/requirements.txt
commands =
Expand All @@ -161,7 +163,7 @@ pass_env =
CI_PACKED_CHARMS
deps =
pytest
juju==2.9.44.0 # The latest python-libjuju that supports both juju 2.9 and 3.0
juju==3.2.0.1
pytest-operator
-r {tox_root}/requirements.txt
commands =
Expand All @@ -176,7 +178,7 @@ pass_env =
CI_PACKED_CHARMS
deps =
pytest
juju==2.9.44.0 # The latest python-libjuju that supports both juju 2.9 and 3.0
juju==3.2.0.1
pytest-operator
-r {tox_root}/requirements.txt
commands =
Expand All @@ -185,4 +187,4 @@ commands =
[testenv:cleanup_juju_models]
description = Cleanup Juju models
commands =
python {[vars]tests_path}/integration/cleanup_resources.py
python {[vars]tests_path}/integration/cleanup_resources.py

0 comments on commit a4b6484

Please sign in to comment.