Testing subpackage
This subpackage contains modules for test mocking in the SKA SatLMC tests.
- class MockCallable(return_value=None, called_timeout=5.0, not_called_timeout=1.0)
This class implements a mock callable.
It is useful for when you want to assert that a callable is called, but the callback is called asynchronously, so that you might have to wait a short time for the call to occur.
If you use a regular mock for the callback, your tests will end up littered with sleeps:
antenna_apiu_proxy.start_communicating() communication_state_changed_callback.assert_called_once_with( CommunicationStatus.NOT_ESTABLISHED ) time.sleep(0.1) communication_state_changed_callback.assert_called_once_with( CommunicationStatus.ESTABLISHED )
These sleeps waste time, slow down the tests, and they are difficult to tune: maybe you only need to sleep 0.1 seconds on your development machine, but what if the CI pipeline deploys the tests to an environment that needs 0.2 seconds for this?
This class solves that by putting each call to the callback onto a queue. Then, each time we assert that a callback was called, we get a call from the queue, waiting if necessary for the call to arrive, but with a timeout:
antenna_apiu_proxy.start_communicating() communication_state_changed_callback.assert_next_call( CommunicationStatus.NOT_ESTABLISHED ) communication_state_changed_callback.assert_next_call( CommunicationStatus.ESTABLISHED )
- __init__(return_value=None, called_timeout=5.0, not_called_timeout=1.0)
Initialise a new instance.
- Parameters:
called_timeout (
float
) – how long to wait for a call to occur when we are expecting one. It makes sense to wait a long time for the expected call, as it will generally arrive much much sooner anyhow, and failure for the call to arrive in time will cause the assertion to fail. The default is 5 seconds.not_called_timeout (
float
) – how long to wait for a callback when we are not expecting one. Since we need to wait the full timeout period in order to determine that a callback has not arrived, asserting that a call has not been made can severely slow down your tests. By keeping this timeout quite short, we can speed up our tests, at the risk of prematurely passing an assertion. The default is 0.5
- assert_last_call(*args, **kwargs)
Assert the arguments of the last call to this mock callback.
The “last” call is the last call before an attempt to get the next event times out.
This is useful for situations where we know a device may call a callback several time, and we don’t care too much about the exact order of calls, but we do know what the final call should be.
- Parameters:
- Raises:
AssertionError – if the callback has not been called.
- Return type:
- assert_next_call(*args, **kwargs)
Assert the arguments of the next call to this mock callback.
If the call has not been made, this method will wait up to the specified timeout for a call to arrive.
- Parameters:
- Raises:
AssertionError – if the callback has not been called.
- Return type:
- assert_not_called(timeout=None)
Assert that the callback still has not been called after the timeout period.
This is a slow method because it has to wait the full timeout period in order to determine that the call is not coming. An optional timeout parameter is provided for the situation where you are happy for the assertion to pass after a shorter wait time.
- calls_in_queue(expected_arguments_list)
Docstring.
- get_next_call()
Return the arguments of the next call to this mock callback.
This is useful for situations where you do not know exactly what the arguments of the next call will be, so you cannot use the
assert_next_call()
method. Instead you want to assert some specific properties on the arguments:(args, kwargs) = mock_callback.get_next_call() event_data = args[0].attr_value assert event_data.name == "healthState" assert event_data.value == HealthState.UNKNOWN assert event_data.quality == tango.AttrQuality.ATTR_VALID
If the call has not been made, this method will wait up to the specified timeout for a call to arrive.
- get_whole_queue()
Return the arguments of all calls to this mock callback currently in the queue.
This is useful for situations where you do not know exactly what order the calls will happen but you do know what the arguments will be. Instead you want to assert that your call is somewhere in the queue.
If the call has not been made, this method will wait up to the specified timeout for a call to arrive.
- class MockChangeEventCallback(event_name, called_timeout=5.0, not_called_timeout=0.5, filter_for_change=False)
This class implements a mock change event callback.
It is a special case of a
MockCallable
where the callable expects to be called with event_name, event_value and event_quality arguments (which is howska_sat_lmc.device_proxy.SatDeviceProxy
calls its change event callbacks).- __init__(event_name, called_timeout=5.0, not_called_timeout=0.5, filter_for_change=False)
Initialise a new instance.
- Parameters:
event_name (
str
) – the name of the event for which this callable is a callbackcalled_timeout (
float
) – how long to wait for a call to occur when we are expecting one. It makes sense to wait a long time for the expected call, as it will generally arrive much much sooner anyhow, and failure for the call to arrive in time will cause the assertion to fail. The default is 5 seconds.not_called_timeout (
float
) – how long to wait for a callback when we are not expecting one. Since we need to wait the full timeout period in order to determine that a callback has not arrived, asserting that a call has not been made can severely slow down your tests. By keeping this timeout quite short, we can speed up our tests, at the risk of prematurely passing an assertion. The default is 0.5filter_for_change (
bool
) – filtered?
- assert_last_change_event(value, _do_assert=True, quality=tango.AttrQuality.ATTR_VALID)
Assert the arguments of the last call to this mock callback.
The “last” call is the last call before an attempt to get the next event times out.
This is useful for situations where we know a device may fire several events, and we don’t know or care about the exact order of events, but we do know what the final event should be. For example, when we tell MccsController to turn on, it has to turn many devices on, which have to turn many devices on, etc. With so m
- Parameters:
value (
Any
) – the asserted value of the change eventquality (
AttrQuality
) – the asserted quality of the change event. This is optional, with a default of ATTR_VALID._do_assert (
bool
) – option to not perform an assert (useful for debugging).
- Raises:
AssertionError – if the callback has not been called.
- Return type:
- assert_next_change_event(value, quality=tango.AttrQuality.ATTR_VALID)
Assert the arguments of the next call to this mock callback.
If the call has not been made, this method will wait up to the specified timeout for a call to arrive.
- Parameters:
value (
Any
) – the asserted value of the change eventquality (
AttrQuality
) – the asserted quality of the change event. This is optional, with a default of ATTR_VALID.
- Raises:
AssertionError – if the callback has not been called.
- Return type:
- assert_not_called()
Assert if not called.
- Raises:
AssertionError – change event callback
- Return type:
- get_next_change_event()
Return the attribute value in the next call to this mock change event callback.
This is useful for situations where you do not know exactly what the value will be, so you cannot use the
assert_next_change_event()
method. Instead you want to assert some specific properties on the arguments.- Raises:
AssertionError – if the callback has not been called
- Return type:
- Returns:
an (args, kwargs) tuple
- class MockDeviceBuilder(from_factory=<class 'unittest.mock.Mock'>)
This module implements a mock builder for tango devices.
- __init__(from_factory=<class 'unittest.mock.Mock'>)
Create a new instance.
- add_attribute(name, value)
Tell this builder to build mocks with a given attribute.
TODO: distinguish between read-only and read-write attributes
- add_command(name, return_value)
Tell this builder to build mocks with a specified command.
And that the command returns the provided value.
- add_result_command(name, result_code, status='Mock information-only message')
Tell this builder to build mocks with a specified command.
And that the command returns (ResultCode, [message, message_uid]) or (ResultCode, message) tuples as required.
- Parameters:
name (
str
) – the name of the commandresult_code (
ResultCode
) – code indicating the status of the commandstatus (
str
) – an information-only message for the command to return
- Return type:
- Mock callables
MockCallable
MockCallableDeque
MockCallableDeque.__init__()
MockCallableDeque.assert_all_in_deque()
MockCallableDeque.assert_in_deque()
MockCallableDeque.assert_next_call_with_keys()
MockCallableDeque.assert_next_calls_with_keys()
MockCallableDeque.assert_not_called_with_keys()
MockCallableDeque.assert_ordered_in_deque()
MockCallableDeque.get_next_call_with_keys()
MockChangeEventCallback
- Mock devices