canonical / ops-scenario

State-transition testing SDK for Operator Framework Juju charms.
Apache License 2.0
10 stars 7 forks source link

Support for asserting that an `exec_mock` was called #180

Open gruyaume opened 2 weeks ago

gruyaume commented 2 weeks ago

Description

I am using scenario's exec_mock and I can't figure out how to check that my mock was called. Reading the documentation it is not clear whether this is possible.

class TestCharmConfigure(RouterUnitTestFixtures):
    def test_given_can_connect_when_configure_then_ip_forwarding_is_set(
        self,
    ):
        ip_forward_call = ("sysctl", "-w", "net.ipv4.ip_forward=1")
        container = scenario.Container(
            name="router",
            can_connect=True,
            exec_mock={
                ip_forward_call: scenario.ExecOutput(
                    return_code=0, stdout="net.ipv4.ip_forward = 1"
                ),
            },
        )
        state_in = scenario.State(
            leader=True,
            containers=[container],
        )

        state_out = self.ctx.run(container.pebble_ready_event, state_in)

        state_out.containers[0].exec_mock[ip_forward_call].assert_called()

Logs

AttributeError: 'ExecOutput' object has no attribute 'assert_called'

Reference

tonyandrewmeyer commented 2 weeks ago

I don't think this is possible in 6.x (without using a regular unittest/pytest mock).

However, you can do this in (very soon to be released) 7.0:

class TestCharmConfigure(RouterUnitTestFixtures):
    def test_given_can_connect_when_configure_then_ip_forwarding_is_set(
        self,
    ):
        ip_forward_call = ("sysctl", "-w", "net.ipv4.ip_forward=1")
        container = scenario.Container(
            name="router",
            can_connect=True,
            execs={
                scenario.Exec(
                    ip_forward_call, return_code=0, stdout="net.ipv4.ip_forward = 1"
                ),
            },
        )
        state_in = scenario.State(
            leader=True,
            containers={container},
        )

        state_out = self.ctx.run(self.ctx.on.pebble_ready(container), state_in)

        assert self.ctx.exec_history[container.name][0].command == ip_forward_call