Skip to content

Commit

Permalink
Add tests for ConfigManagingActor
Browse files Browse the repository at this point in the history
Signed-off-by: Elzbieta Kotulska <[email protected]>
  • Loading branch information
ela-kotulska-frequenz committed Nov 27, 2024
1 parent c3e3c06 commit ceef54b
Showing 1 changed file with 90 additions and 0 deletions.
90 changes: 90 additions & 0 deletions tests/config/test_config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import pytest
from frequenz.channels import Broadcast
from frequenz.channels.file_watcher import Event, EventType
from pytest_mock import MockerFixture

from frequenz.sdk.config import ConfigManagingActor
from frequenz.sdk.config._config_managing import _recursive_update
Expand Down Expand Up @@ -265,6 +267,94 @@ async def test_update_multiple_files(self, config_file: pathlib.Path) -> None:
"dict_str_int": {"a": 1, "b": 2, "c": 4},
}

async def test_actor_works_if_not_all_config_files_exist(
self, config_file: pathlib.Path
) -> None:
"""Test ConfigManagingActor works if not all config files exist."""
config_channel: Broadcast[Mapping[str, Any]] = Broadcast(
name="Config Channel", resend_latest=True
)
config_receiver = config_channel.new_receiver()

# This file does not exist
config_file2 = config_file.parent / "config2.toml"

async with ConfigManagingActor(
[config_file, config_file2],
config_channel.new_sender(),
force_polling=False,
):
config = await config_receiver.receive()
assert config is not None
assert config.get("var2") is None

number = 5
config_file.write_text(create_content(number=number))

config = await config_receiver.receive()
assert config is not None
assert config.get("var2") == str(number)

# Create second config file that overrides the value from the first one
number = 42
config_file2.write_text(create_content(number=number))

config = await config_receiver.receive()
assert config is not None
assert config.get("var2") == str(number)

async def test_actor_does_not_crash_if_file_is_deleted(
self, config_file: pathlib.Path, mocker: MockerFixture
) -> None:
"""Test ConfigManagingActor does not crash if a file is deleted."""
config_channel: Broadcast[Mapping[str, Any]] = Broadcast(
name="Config Channel", resend_latest=True
)
config_receiver = config_channel.new_receiver()

number = 5
config_file2 = config_file.parent / "config2.toml"
config_file2.write_text(create_content(number=number))

# Not config file but existing in the same directory
any_file = config_file.parent / "any_file.txt"
any_file.write_text("content")

async with ConfigManagingActor(
[config_file, config_file2],
config_channel.new_sender(),
force_polling=False,
) as actor:
send_config_spy = mocker.spy(actor, "send_config")

config = await config_receiver.receive()
assert config is not None
assert config.get("var2") == str(number)
send_config_spy.assert_called_once()
send_config_spy.reset_mock()

# Remove file and send DELETE events
any_file.unlink()
config_file2.unlink()
number = 101
config_file.write_text(create_content(number=number))
mocker.patch.object(
actor._file_watcher,
"__anext__",
side_effect=[
Event(EventType.DELETE, any_file),
Event(EventType.DELETE, config_file2),
Event(EventType.MODIFY, config_file),
],
)

config = await config_receiver.receive()
assert config is not None
assert config.get("var2") == str(number)
# Config should be updated only once on MODIFY event
# DELETE events are ignored
send_config_spy.assert_called_once()


@dataclass(frozen=True, kw_only=True)
class RecursiveUpdateTestCase:
Expand Down

0 comments on commit ceef54b

Please sign in to comment.