Skip to content

Commit

Permalink
test: more backup and basic tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Gu1nness committed Nov 25, 2024
1 parent 6bb366e commit 0ef8f75
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 4 deletions.
2 changes: 1 addition & 1 deletion single_kernel_mongo/core/vm_workload.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def delete(self, path: Path) -> None:
path.unlink()

@override
def copy_to_unit(self, src: Path, destination: Path) -> None:
def copy_to_unit(self, src: Path, destination: Path) -> None: # pragma: nocover
copyfile(src, destination)

@override
Expand Down
4 changes: 2 additions & 2 deletions single_kernel_mongo/managers/backups.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def get_status(self) -> StatusBase | None:
logger.error(f"Failed to get pbm status: {e}")
return BlockedStatus("PBM error")

def resync_config_options(self):
def resync_config_options(self): # pragma: nocover
"""Attempts to resync config options and sets status in case of failure."""
self.workload.start()

Expand Down Expand Up @@ -382,7 +382,7 @@ def can_restore(self, backup_id: str, remapping_pattern: str) -> None:
case BlockedStatus():
raise InvalidPBMStatusError(pbm_status.message)
case _:
return
pass

if not backup_id:
raise InvalidArgumentForActionError("Missing backup-id to restore.")
Expand Down
136 changes: 136 additions & 0 deletions tests/unit/test_backup_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from single_kernel_mongo.events.backups import INVALID_S3_INTEGRATION_STATUS
from single_kernel_mongo.exceptions import (
BackupError,
InvalidArgumentForActionError,
InvalidPBMStatusError,
ListBackupError,
ResyncError,
WorkloadExecError,
Expand Down Expand Up @@ -265,3 +267,137 @@ def test_restore_backup_success(harness: Harness[MongoTestCharm], mocker) -> Non
["deadbeef", "--replset-remapping", "test-mongodb=test-mongodb"],
environment=backup_manager.environment,
)


def test_get_backup_error_status(harness: Harness[MongoTestCharm], mocker) -> None:
backup_manager = harness.charm.operator.backup_manager
harness.set_leader(True)
harness.charm.operator.state.app_peer_data.role = MongoDBRoles.REPLICATION.value
mocker.patch("single_kernel_mongo.core.vm_workload.VMWorkload.active", return_value=True)
relation_id = harness.add_relation(
ExternalRequirerRelations.S3_CREDENTIALS.value, "s3-integrator"
)
harness.add_relation_unit(relation_id, "s3-integrator/0")
mock = mocker.patch(
"single_kernel_mongo.managers.backups.BackupManager.pbm_status",
new_callable=mocker.PropertyMock,
)
with open("tests/unit/data/list_backups.json") as fd:
pbm_status = fd.read()

mock.return_value = pbm_status

error = backup_manager.get_backup_error_status("2024-11-25T-15:30:05Z")
assert error == "not found"


@pytest.mark.parametrize(
("pbm_status", "pattern"),
(
(MaintenanceStatus(""), "Please wait for current.*"),
(WaitingStatus(""), "Sync-ing configurations needs more time.*"),
(BlockedStatus("error"), "error"),
),
)
def test_can_restore_fail_status(
harness: Harness[MongoTestCharm], mocker, pbm_status, pattern
) -> None:
backup_manager = harness.charm.operator.backup_manager
harness.set_leader(True)
harness.charm.operator.state.app_peer_data.role = MongoDBRoles.REPLICATION.value
mocker.patch("single_kernel_mongo.core.vm_workload.VMWorkload.active", return_value=True)
relation_id = harness.add_relation(
ExternalRequirerRelations.S3_CREDENTIALS.value, "s3-integrator"
)
harness.add_relation_unit(relation_id, "s3-integrator/0")
mock = mocker.patch(
"single_kernel_mongo.managers.backups.BackupManager.get_status",
)

mock.return_value = pbm_status
with pytest.raises(InvalidPBMStatusError) as e:
backup_manager.can_restore("backup", "remapping_pattern")
assert e.match(pattern)


@pytest.mark.parametrize(
("backup_id", "remap_pattern", "pattern"),
(("", "", "Missing backup-id.*"), ("2024", "", ".*'remap-pattern'.*")),
)
def test_can_restore_fail_params(
harness: Harness[MongoTestCharm], mocker, backup_id, remap_pattern, pattern
) -> None:
backup_manager = harness.charm.operator.backup_manager
harness.set_leader(True)
harness.charm.operator.state.app_peer_data.role = MongoDBRoles.REPLICATION.value
mocker.patch("single_kernel_mongo.core.vm_workload.VMWorkload.active", return_value=True)
relation_id = harness.add_relation(
ExternalRequirerRelations.S3_CREDENTIALS.value, "s3-integrator"
)
harness.add_relation_unit(relation_id, "s3-integrator/0")
mocker.patch(
"single_kernel_mongo.managers.backups.BackupManager.get_status", return_value=ActiveStatus()
)
mocker.patch(
"single_kernel_mongo.managers.backups.BackupManager._needs_provided_remap_arguments",
return_value=True,
)
with pytest.raises(InvalidArgumentForActionError) as e:
backup_manager.can_restore(backup_id, remap_pattern)

assert e.match(pattern)


@pytest.mark.parametrize(
("pbm_status", "pattern"),
(
(MaintenanceStatus(""), "Can only create one backup.*"),
(WaitingStatus(""), "Sync-ing configurations needs more time.*"),
(BlockedStatus("error"), "error"),
),
)
def test_can_backup_fail(harness: Harness[MongoTestCharm], mocker, pbm_status, pattern) -> None:
backup_manager = harness.charm.operator.backup_manager
harness.set_leader(True)
harness.charm.operator.state.app_peer_data.role = MongoDBRoles.REPLICATION.value
mocker.patch("single_kernel_mongo.core.vm_workload.VMWorkload.active", return_value=True)
relation_id = harness.add_relation(
ExternalRequirerRelations.S3_CREDENTIALS.value, "s3-integrator"
)
harness.add_relation_unit(relation_id, "s3-integrator/0")
mock = mocker.patch(
"single_kernel_mongo.managers.backups.BackupManager.get_status",
)

mock.return_value = pbm_status
with pytest.raises(InvalidPBMStatusError) as e:
backup_manager.can_backup()
assert e.match(pattern)


@pytest.mark.parametrize(
("pbm_status", "pattern"),
(
(WaitingStatus(""), "Sync-ing configurations needs more time.*"),
(BlockedStatus("error"), "error"),
),
)
def test_can_list_backup_fail(
harness: Harness[MongoTestCharm], mocker, pbm_status, pattern
) -> None:
backup_manager = harness.charm.operator.backup_manager
harness.set_leader(True)
harness.charm.operator.state.app_peer_data.role = MongoDBRoles.REPLICATION.value
mocker.patch("single_kernel_mongo.core.vm_workload.VMWorkload.active", return_value=True)
relation_id = harness.add_relation(
ExternalRequirerRelations.S3_CREDENTIALS.value, "s3-integrator"
)
harness.add_relation_unit(relation_id, "s3-integrator/0")
mock = mocker.patch(
"single_kernel_mongo.managers.backups.BackupManager.get_status",
)

mock.return_value = pbm_status
with pytest.raises(InvalidPBMStatusError) as e:
backup_manager.can_list_backup()
assert e.match(pattern)
1 change: 1 addition & 0 deletions tests/unit/test_mongodb_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ def test_mongo_paths(role: Role):
assert paths.int_pem_file.parent == Path(role.paths["CONF"])
assert paths.int_ca_file.parent == Path(role.paths["CONF"])
assert paths.socket_path.parent == Path(role.paths["VAR"])
assert paths.common_path == Path(role.paths["VAR"]).parent

assert all(path.parent == Path(role.paths["CONF"]) for path in paths.tls_files)
25 changes: 24 additions & 1 deletion tests/unit/test_mongodb_workload.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,34 @@ def mock_snap(*args, **kwargs):
assert workload.install()


def test_read_file():
def test_read_file_fail():
workload = VMMongoDBWorkload(container=None)
assert workload.read(Path("/nonexistent")) == []


def test_read_file_succeed(tmp_path):
tmp_file = tmp_path / "test_file.txt"
tmp_file.write_text("need\ndead\ncafe\n")

workload = VMMongoDBWorkload(container=None)
assert workload.read(tmp_file) == ["need", "dead", "cafe"]


def test_delete_fail():
workload = VMMongoDBWorkload(container=None)
assert workload.delete(Path("/nonexistent")) is None


def test_delete_success(tmp_path):
tmp_file = tmp_path / "test_file.txt"
tmp_file.write_text("need\ndead\ncafe\n")

workload = VMMongoDBWorkload(container=None)
workload.delete(tmp_file)

assert not tmp_file.is_file()


@pytest.mark.parametrize("command", [("start"), ("stop"), ("restart")])
def test_command_success(monkeypatch, command):
def mock_snap(*args, **kwargs):
Expand Down

0 comments on commit 0ef8f75

Please sign in to comment.