diff --git a/requirements.txt b/requirements.txt index 9bdbcc0..72b481d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,21 +6,21 @@ # annotated-types==0.7.0 # via pydantic -anyio==4.4.0 +anyio==4.6.0 # via httpx -certifi==2024.7.4 +certifi==2024.8.30 # via # httpcore # httpx -cosl==0.0.34 +cosl==0.0.36 # via -r requirements.in h11==0.14.0 # via httpcore httpcore==1.0.5 # via httpx -httpx==0.27.0 +httpx==0.27.2 # via lightkube -idna==3.7 +idna==3.10 # via # anyio # httpx @@ -36,13 +36,13 @@ lightkube-models==1.31.1.8 # lightkube markupsafe==2.1.5 # via jinja2 -ops==2.16.1 +ops==2.17.0 # via # -r requirements.in # cosl -pydantic==2.8.2 +pydantic==2.9.2 # via cosl -pydantic-core==2.20.1 +pydantic-core==2.23.4 # via pydantic pyyaml==6.0.2 # via diff --git a/test-requirements.txt b/test-requirements.txt index 80c53fc..2122e87 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -10,11 +10,12 @@ bcrypt==4.2.0 # via paramiko cachetools==5.5.0 # via google-auth -certifi==2024.7.4 +certifi==2024.8.30 # via + # -c requirements.txt # kubernetes # requests -cffi==1.17.0 +cffi==1.17.1 # via # cryptography # pynacl @@ -30,32 +31,40 @@ decorator==5.1.1 # via # ipdb # ipython -executing==2.0.1 +durationpy==0.7 + # via kubernetes +executing==2.1.0 # via stack-data -google-auth==2.34.0 +google-auth==2.35.0 # via kubernetes hvac==2.3.0 # via juju -idna==3.7 - # via requests +idna==3.10 + # via + # -c requirements.txt + # requests iniconfig==2.0.0 # via pytest ipdb==0.13.13 # via pytest-operator -ipython==8.26.0 +ipython==8.27.0 # via ipdb jedi==0.19.1 # via ipython jinja2==3.1.4 - # via pytest-operator + # via + # -c requirements.txt + # pytest-operator juju==3.5.2.0 # via pytest-operator -kubernetes==30.1.0 +kubernetes==31.0.0 # via juju macaroonbakery==1.3.4 # via juju markupsafe==2.1.5 - # via jinja2 + # via + # -c requirements.txt + # jinja2 matplotlib-inline==0.1.7 # via ipython mypy-extensions==1.0.0 @@ -66,15 +75,17 @@ oauthlib==3.2.2 # via # kubernetes # requests-oauthlib -ops==2.16.1 - # via ops-scenario -ops-scenario==6.1.6 +ops==2.17.0 + # via + # -c requirements.txt + # ops-scenario +ops-scenario==7.0.5 # via -r test-requirements.in packaging==24.1 # via # juju # pytest -paramiko==3.4.1 +paramiko==3.5.0 # via juju parso==0.8.4 # via jedi @@ -82,20 +93,20 @@ pexpect==4.9.0 # via ipython pluggy==1.5.0 # via pytest -prompt-toolkit==3.0.47 +prompt-toolkit==3.0.48 # via ipython -protobuf==5.27.3 +protobuf==5.28.2 # via macaroonbakery ptyprocess==0.7.0 # via pexpect pure-eval==0.2.3 # via stack-data -pyasn1==0.6.0 +pyasn1==0.6.1 # via # juju # pyasn1-modules # rsa -pyasn1-modules==0.4.0 +pyasn1-modules==0.4.1 # via google-auth pycparser==2.22 # via cffi @@ -112,7 +123,7 @@ pyrfc3339==1.1 # via # juju # macaroonbakery -pyright==1.1.381 +pyright==1.1.382.post1 # via -r test-requirements.in pytest==8.3.3 # via @@ -123,14 +134,15 @@ pytest-asyncio==0.21.2 # via # -r test-requirements.in # pytest-operator -pytest-operator==0.36.0 +pytest-operator==0.37.0 # via -r test-requirements.in python-dateutil==2.9.0.post0 # via kubernetes -pytz==2024.1 +pytz==2024.2 # via pyrfc3339 pyyaml==6.0.2 # via + # -c requirements.txt # -r test-requirements.in # juju # kubernetes @@ -147,7 +159,7 @@ requests-oauthlib==2.0.0 # via kubernetes rsa==4.9 # via google-auth -ruff==0.6.2 +ruff==0.6.8 # via -r test-requirements.in six==1.16.0 # via @@ -165,10 +177,13 @@ traitlets==5.14.3 # ipython # matplotlib-inline typing-extensions==4.12.2 - # via typing-inspect + # via + # -c requirements.txt + # pyright + # typing-inspect typing-inspect==0.9.0 # via juju -urllib3==2.2.2 +urllib3==2.2.3 # via # kubernetes # requests @@ -176,7 +191,8 @@ wcwidth==0.2.13 # via prompt-toolkit websocket-client==1.8.0 # via + # -c requirements.txt # kubernetes # ops -websockets==13.0 +websockets==13.1 # via juju diff --git a/tests/unit/test_charm_collect_status.py b/tests/unit/test_charm_collect_status.py index 79c3008..e366838 100644 --- a/tests/unit/test_charm_collect_status.py +++ b/tests/unit/test_charm_collect_status.py @@ -20,7 +20,7 @@ def test_given_multus_not_enabled_when_collect_unit_status_then_status_is_blocke containers=[container], ) - state_out = self.ctx.run("collect_unit_status", state_in) + state_out = self.ctx.run(self.ctx.on.collect_unit_status(), state_in) assert state_out.unit_status == BlockedStatus("Multus is not installed or enabled") @@ -47,7 +47,7 @@ def test_given_invalid_config_when_collect_unit_status_then_status_is_blocked( leader=True, containers=[container], config={config_param: value} ) - state_out = self.ctx.run("collect_unit_status", state_in) + state_out = self.ctx.run(self.ctx.on.collect_unit_status(), state_in) assert state_out.unit_status == BlockedStatus( f"The following configurations are not valid: ['{config_param}']" @@ -63,7 +63,7 @@ def test_given_cant_connect_when_collect_unit_status_then_status_is_waiting( containers=[container], ) - state_out = self.ctx.run("collect_unit_status", state_in) + state_out = self.ctx.run(self.ctx.on.collect_unit_status(), state_in) assert state_out.unit_status == WaitingStatus("Waiting for workload container to be ready") @@ -78,7 +78,7 @@ def test_given_multus_not_ready_when_collect_unit_status_then_status_is_waiting( containers=[container], ) - state_out = self.ctx.run("collect_unit_status", state_in) + state_out = self.ctx.run(self.ctx.on.collect_unit_status(), state_in) assert state_out.unit_status == WaitingStatus("Waiting for Multus to be ready") @@ -93,6 +93,6 @@ def test_given_prerequisites_met_when_collect_unit_status_then_status_is_active( containers=[container], ) - state_out = self.ctx.run("collect_unit_status", state_in) + state_out = self.ctx.run(self.ctx.on.collect_unit_status(), state_in) assert state_out.unit_status == ActiveStatus() diff --git a/tests/unit/test_charm_configure.py b/tests/unit/test_charm_configure.py index 0a9368b..ea90de6 100644 --- a/tests/unit/test_charm_configure.py +++ b/tests/unit/test_charm_configure.py @@ -10,50 +10,39 @@ class TestCharmConfigure(RouterUnitTestFixtures): def test_given_prerequisites_met_when_configure_then_ip_forwarding_and_iptables_is_set( - self, caplog + self, ): self.mock_k8s_multus.multus_is_available.return_value = True self.mock_k8s_multus.is_ready.return_value = True - ip_forward_call = ("sysctl", "-w", "net.ipv4.ip_forward=1") - iptables_call = ( - "iptables-legacy", - "-t", - "nat", - "-A", - "POSTROUTING", - "-o", - "eth0", - "-j", - "MASQUERADE", - ) container = scenario.Container( name="router", can_connect=True, - exec_mock={ - ip_forward_call: scenario.ExecOutput( - return_code=0, stdout="net.ipv4.ip_forward = 1" + execs={ + scenario.Exec( + command_prefix=["iptables-legacy"], + return_code=0, + stdout="", + ), + scenario.Exec( + command_prefix=["sysctl"], + return_code=0, + stdout="net.ipv4.ip_forward = 1", ), - iptables_call: scenario.ExecOutput(return_code=0, stdout=""), }, ) state_in = scenario.State( leader=True, - containers=[container], + containers={container}, ) - self.ctx.run(container.pebble_ready_event, state_in) - - # When scenario 7 is out, we should assert that the mock exec was called - # instead of validating log content - # Reference: https://github.com/canonical/ops-scenario/issues/180 - assert "Successfully set IP forwarding" in caplog.text - assert "Successfully set ip tables" in caplog.text + self.ctx.run(self.ctx.on.pebble_ready(container=container), state_in) - def test_error_when_setting_up_ip_forwarding_when_configure_then_error_raised(self, caplog): - self.mock_k8s_multus.multus_is_available.return_value = True - self.mock_k8s_multus.is_ready.return_value = True - ip_forward_call = ("sysctl", "-w", "net.ipv4.ip_forward=1") - iptables_call = ( + assert self.ctx.exec_history[container.name][0].command == [ + "sysctl", + "-w", + "net.ipv4.ip_forward=1", + ] + assert self.ctx.exec_history[container.name][1].command == [ "iptables-legacy", "-t", "nat", @@ -63,15 +52,26 @@ def test_error_when_setting_up_ip_forwarding_when_configure_then_error_raised(se "eth0", "-j", "MASQUERADE", - ) + ] + + def test_error_when_setting_up_ip_forwarding_when_configure_then_error_raised(self, caplog): + self.mock_k8s_multus.multus_is_available.return_value = True + self.mock_k8s_multus.is_ready.return_value = True container = scenario.Container( name="router", can_connect=True, - exec_mock={ - ip_forward_call: scenario.ExecOutput( - return_code=0, stdout="", stderr="whatever error message" + execs={ + scenario.Exec( + command_prefix=["iptables-legacy"], + return_code=0, + stdout="", + ), + scenario.Exec( + command_prefix=["sysctl"], + return_code=0, + stdout="", + stderr="whatever error message", ), - iptables_call: scenario.ExecOutput(return_code=0, stdout=""), }, ) state_in = scenario.State( @@ -80,7 +80,7 @@ def test_error_when_setting_up_ip_forwarding_when_configure_then_error_raised(se ) with pytest.raises(Exception) as e: - self.ctx.run(container.pebble_ready_event, state_in) + self.ctx.run(self.ctx.on.pebble_ready(container=container), state_in) assert "Could not set IP forwarding in workload container: whatever error message" in str( e.value diff --git a/tests/unit/test_charm_remove.py b/tests/unit/test_charm_remove.py index bdc36f2..8fb2a80 100644 --- a/tests/unit/test_charm_remove.py +++ b/tests/unit/test_charm_remove.py @@ -16,6 +16,6 @@ def test_given_unit_is_leader_when_remove_then_k8s_multus_is_removed(self): ) state_in = scenario.State(leader=True, containers=[container]) - self.ctx.run("remove", state_in) + self.ctx.run(self.ctx.on.remove(), state_in) self.mock_k8s_multus.remove.assert_called_once()