-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DPE-5372] Add safeguard hooks for upgrades (#327)
- Loading branch information
Showing
4 changed files
with
148 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Copyright 2024 Canonical Ltd. | ||
# See LICENSE file for licensing details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#!/usr/bin/env python3 | ||
# Copyright 2024 Canonical Ltd. | ||
# See LICENSE file for licensing details. | ||
|
||
import pytest | ||
from pytest_operator.plugin import OpsTest | ||
|
||
from ..ha_tests.helpers import find_unit | ||
from ..helpers import ( | ||
APP_NAME, | ||
check_or_scale_app, | ||
get_app_name, | ||
get_password, | ||
set_password, | ||
) | ||
|
||
|
||
@pytest.mark.skip("Missing upgrade code for now") | ||
@pytest.mark.group(1) | ||
@pytest.mark.abort_on_fail | ||
async def test_build_and_deploy(ops_test: OpsTest): | ||
app_name = await get_app_name(ops_test) | ||
|
||
if app_name: | ||
await check_or_scale_app(ops_test, app_name, required_units=3) | ||
return | ||
|
||
app_name = APP_NAME | ||
|
||
await ops_test.model.deploy( | ||
app_name, | ||
application_name=app_name, | ||
num_units=3, | ||
series="jammy", | ||
channel="6/edge", | ||
) | ||
await ops_test.model.wait_for_idle( | ||
apps=[app_name], status="active", timeout=1000, idle_period=120 | ||
) | ||
|
||
|
||
@pytest.mark.skip("Missing upgrade code for now") | ||
@pytest.mark.group(1) | ||
@pytest.mark.abort_on_fail | ||
async def test_upgrade_password_change_fail(ops_test: OpsTest): | ||
app_name = await get_app_name(ops_test) | ||
leader_id = await find_unit(ops_test, leader=True, app_name=app_name) | ||
|
||
current_password = await get_password(ops_test, leader_id, app_name=app_name) | ||
new_charm = await ops_test.build_charm(".") | ||
await ops_test.model.applications[app_name].refresh(path=new_charm) | ||
results = await set_password(ops_test, leader_id, password="0xdeadbeef", app_name=app_name) | ||
|
||
assert results == "Cannot set passwords while an upgrade is in progress." | ||
|
||
after_action_password = await get_password(ops_test, leader_id, app_name=app_name) | ||
|
||
assert current_password == after_action_password |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# Copyright 2024 Canonical Ltd. | ||
# See LICENSE file for licensing details. | ||
import unittest | ||
from unittest.mock import Mock, PropertyMock, patch | ||
|
||
from ops.model import ActiveStatus, Relation | ||
from ops.testing import ActionFailed, Harness | ||
from parameterized import parameterized | ||
|
||
from charm import MongoDBCharm | ||
from config import Config | ||
|
||
from .helpers import patch_network_get | ||
|
||
|
||
class TestUpgrades(unittest.TestCase): | ||
@patch_network_get(private_address="1.1.1.1") | ||
def setUp(self, *unused): | ||
self.harness = Harness(MongoDBCharm) | ||
self.addCleanup(self.harness.cleanup) | ||
mongo_resource = { | ||
"registrypath": "mongo:4.4", | ||
} | ||
self.harness.add_oci_resource("mongodb-image", mongo_resource) | ||
self.harness.begin() | ||
self.harness.set_leader(True) | ||
self.peer_rel_id = self.harness.add_relation("database-peers", "mongodb-peers") | ||
|
||
@patch("ops.framework.EventBase.defer") | ||
@patch("charm.MongoDBCharm.upgrade_in_progress", new_callable=PropertyMock) | ||
def test_on_config_changed_during_upgrade_fails(self, mock_upgrade, defer): | ||
def is_role_changed_mock(*args): | ||
return True | ||
|
||
self.harness.charm.is_role_changed = is_role_changed_mock | ||
|
||
mock_upgrade.return_value = True | ||
self.harness.charm.on.config_changed.emit() | ||
|
||
defer.assert_called() | ||
|
||
@parameterized.expand([("relation_joined"), ("relation_changed")]) | ||
@patch("charm.MongoDBCharm._connect_pbm_agent") | ||
@patch("charm.MongoDBCharm._connect_mongodb_exporter") | ||
@patch("ops.framework.EventBase.defer") | ||
@patch("charm.MongoDBCharm.upgrade_in_progress", new_callable=PropertyMock) | ||
def test_on_relation_handler(self, handler, mock_upgrade, defer, *unused): | ||
relation: Relation = self.harness.charm.model.get_relation("database-peers") | ||
mock_upgrade.return_value = True | ||
getattr(self.harness.charm.on[Config.Relations.PEERS], handler).emit(relation) | ||
defer.assert_called() | ||
|
||
@patch("charm.MongoDBCharm.upgrade_in_progress", new_callable=PropertyMock) | ||
def test_pass_pre_set_password_check_fails(self, mock_upgrade): | ||
def mock_shard_role(*args): | ||
return args != ("shard",) | ||
|
||
mock_pbm_status = Mock(return_value=ActiveStatus()) | ||
self.harness.charm.is_role = mock_shard_role | ||
mock_upgrade.return_value = True | ||
self.harness.charm.backups.get_pbm_status = mock_pbm_status | ||
|
||
with self.assertRaises(ActionFailed) as action_failed: | ||
self.harness.run_action("set-password") | ||
|
||
assert ( | ||
action_failed.exception.message | ||
== "Cannot set passwords while an upgrade is in progress." | ||
) |