Skip to content

packages.valory.skills.abstract_round_abci.tests.test_behaviours_utils

Test the behaviours_utils.py module of the skill.

mock_yield_and_return

def mock_yield_and_return(
        return_value: Any) -> Callable[[], Generator[None, None, Any]]

Wrapper for a Dummy generator that returns a bool.

yield_and_return_bool_wrapper

def yield_and_return_bool_wrapper(
        flag_value: bool
) -> Callable[[], Generator[None, None, Optional[bool]]]

Wrapper for a Dummy generator that returns a bool.

yield_and_return_int_wrapper

def yield_and_return_int_wrapper(
    value: Optional[int]
) -> Callable[[], Generator[None, None, Optional[int]]]

Wrapper for a Dummy generator that returns an int.

AsyncBehaviourTest Objects

class AsyncBehaviourTest(AsyncBehaviour, ABC)

Concrete AsyncBehaviour class for testing purposes.

async_act_wrapper

def async_act_wrapper() -> Generator

Do async act wrapper. Forwards to 'async_act'.

async_act

def async_act() -> Generator

Do 'async_act'.

test_async_behaviour_ticks

def test_async_behaviour_ticks() -> None

Test "AsyncBehaviour", only ticks.

test_async_behaviour_wait_for_message

def test_async_behaviour_wait_for_message() -> None

Test 'wait_for_message'.

test_async_behaviour_wait_for_message_raises_timeout_exception

def test_async_behaviour_wait_for_message_raises_timeout_exception() -> None

Test 'wait_for_message' when it raises TimeoutException.

test_async_behaviour_wait_for_condition

def test_async_behaviour_wait_for_condition() -> None

Test 'wait_for_condition' method.

test_async_behaviour_wait_for_condition_with_timeout

def test_async_behaviour_wait_for_condition_with_timeout() -> None

Test 'wait_for_condition' method with timeout expired.

test_async_behaviour_sleep

def test_async_behaviour_sleep() -> None

Test 'sleep' method.

test_async_behaviour_without_yield

def test_async_behaviour_without_yield() -> None

Test AsyncBehaviour, async_act without yield/yield from.

test_async_behaviour_raise_stopiteration

def test_async_behaviour_raise_stopiteration() -> None

Test AsyncBehaviour, async_act raising 'StopIteration'.

test_async_behaviour_stop

def test_async_behaviour_stop() -> None

Test AsyncBehaviour.stop method.

RoundA Objects

class RoundA(AbstractRound)

Concrete ABCI round.

end_block

def end_block() -> Optional[Tuple[BaseSynchronizedData, Enum]]

Handle end block.

check_payload

def check_payload(payload: BaseTxPayload) -> None

Check payload.

process_payload

def process_payload(payload: BaseTxPayload) -> None

Process payload.

BehaviourATest Objects

class BehaviourATest(BaseBehaviour)

Concrete BaseBehaviour class.

async_act

def async_act() -> Generator

Do the 'async_act'.

dummy_generator_wrapper

def dummy_generator_wrapper(
        return_value: Any = None) -> Callable[[Any], Generator]

A wrapper around a dummy generator that yields nothing and returns the given return value.

TestBaseBehaviour Objects

class TestBaseBehaviour()

Tests for the 'BaseBehaviour' class.

setup_method

def setup_method() -> None

Set up the tests.

dummy_put_message

def dummy_put_message(*args: Any, **kwargs: Any) -> None

A dummy implementation of Outbox.put_message

test_behaviour_id

def test_behaviour_id() -> None

Test behaviour_id on instance.

test_send_to_ipfs

@pytest.mark.parametrize(
    "ipfs_response, expected_log",
    [
        (
            MagicMock(ipfs_hash="test",
                      performative=IpfsMessage.Performative.IPFS_HASH),
            "Successfully stored dummy_filename to IPFS with hash: test",
        ),
        (
            MagicMock(ipfs_hash="test",
                      performative=IpfsMessage.Performative.ERROR),
            f"Expected performative {IpfsMessage.Performative.IPFS_HASH} but got {IpfsMessage.Performative.ERROR}.",
        ),
    ],
)
def test_send_to_ipfs(caplog: LogCaptureFixture, ipfs_response: IpfsMessage,
                      expected_log: str) -> None

Test send_to_ipfs

test_ipfs_store_fails

def test_ipfs_store_fails(caplog: LogCaptureFixture) -> None

Test for failure during building store_file_req.

test_do_ipfs_request

def test_do_ipfs_request() -> None

Test _do_ipfs_request

test_get_from_ipfs

@pytest.mark.parametrize(
    "ipfs_response, expected_log",
    [
        (
            MagicMock(
                files={"dummy_file_name": "test"},
                performative=IpfsMessage.Performative.FILES,
            ),
            "Retrieved 1 objects from ipfs.",
        ),
        (
            MagicMock(ipfs_hash="test",
                      performative=IpfsMessage.Performative.ERROR),
            f"Expected performative {IpfsMessage.Performative.FILES} but got {IpfsMessage.Performative.ERROR}.",
        ),
    ],
)
def test_get_from_ipfs(caplog: LogCaptureFixture, ipfs_response: IpfsMessage,
                       expected_log: str) -> None

Test get_from_ipfs

test_ipfs_get_fails

def test_ipfs_get_fails(caplog: LogCaptureFixture) -> None

Test for failure during building get_files req.

test_params_property

def test_params_property() -> None

Test the 'params' property.

test_synchronized_data_property

def test_synchronized_data_property() -> None

Test the 'synchronized_data' property.

test_check_in_round

def test_check_in_round() -> None

Test 'BaseBehaviour' initialization.

test_check_in_last_round

def test_check_in_last_round() -> None

Test 'BaseBehaviour' initialization.

test_check_round_height_has_changed

def test_check_round_height_has_changed() -> None

Test 'check_round_height_has_changed'.

test_wait_until_round_end_negative_last_round_or_matching_round

def test_wait_until_round_end_negative_last_round_or_matching_round() -> None

Test 'wait_until_round_end' method, negative case (not in matching nor last round).

test_wait_until_round_end_positive

@mock.patch.object(BaseBehaviour, "wait_for_condition")
@mock.patch.object(BaseBehaviour, "check_not_in_round", return_value=False)
@mock.patch.object(BaseBehaviour,
                   "check_not_in_last_round",
                   return_value=False)
def test_wait_until_round_end_positive(*_: Any) -> None

Test 'wait_until_round_end' method, positive case.

test_wait_from_last_timestamp

def test_wait_from_last_timestamp() -> None

Test 'wait_from_last_timestamp'.

test_wait_from_last_timestamp_negative

def test_wait_from_last_timestamp_negative() -> None

Test 'wait_from_last_timestamp'.

test_set_done

def test_set_done() -> None

Test 'set_done' method.

test_send_a2a_transaction_positive

@mock.patch.object(BaseBehaviour, "_send_transaction")
def test_send_a2a_transaction_positive(*_: Any) -> None

Test 'send_a2a_transaction' method, positive case.

test_check_sync_logs_version_mismatch_for_schema_drift

def test_check_sync_logs_version_mismatch_for_schema_drift(
        caplog: LogCaptureFixture) -> None

Schema drift triggers the distinct 'version mismatch' warning.

A KeyError/TypeError/ValueError from parsing /status indicates the response shape has drifted (e.g. Tendermint renamed a field). The widened catch must log the distinct 'version mismatch' warning, not the legacy 'not accepting transactions yet' debug message that fits the JSONDecodeError case.

test_check_sync_keeps_legacy_message_for_json_decode_error

def test_check_sync_keeps_legacy_message_for_json_decode_error(
        caplog: LogCaptureFixture) -> None

Non-JSON status response keeps the legacy debug log.

JSONDecodeError (Tendermint not started yet, returns non-JSON) keeps the legacy 'not accepting transactions yet' debug log, preserving the distinction that motivated splitting the catch.

test_async_act_wrapper_agent_sync_mode

def test_async_act_wrapper_agent_sync_mode() -> None

Test 'async_act_wrapper' in sync mode.

test_async_act_wrapper_agent_sync_mode_where_height_dont_match

@mock.patch.object(BaseBehaviour, "_get_status", _get_status_wrong_patch)
def test_async_act_wrapper_agent_sync_mode_where_height_dont_match() -> None

Test 'async_act_wrapper' in sync mode.

test_async_act_wrapper_exception

@pytest.mark.parametrize("exception_cls", [StopIteration])
def test_async_act_wrapper_exception(exception_cls: Exception) -> None

Test 'async_act_wrapper'.

test_get_request_nonce_from_dialogue

def test_get_request_nonce_from_dialogue() -> None

Test '_get_request_nonce_from_dialogue' helper method.

test_send_transaction_stop_condition

@mock.patch.object(BaseBehaviour, "_send_signing_request")
@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch.object(BaseBehaviour,
                   "_check_http_return_code_200",
                   return_value=False)
def test_send_transaction_stop_condition(*_: Any) -> None

Test '_send_transaction' method's stop_condition as provided by send_a2a_transaction.

test_send_transaction_positive_false_condition

def test_send_transaction_positive_false_condition() -> None

Test '_send_transaction', positive case (false condition)

test_send_transaction_positive

@mock.patch.object(BaseBehaviour, "_send_signing_request")
@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch.object(BaseBehaviour,
                   "_check_http_return_code_200",
                   return_value=True)
def test_send_transaction_positive(*_: Any) -> None

Test '_send_transaction', positive case.

test_send_transaction_invalid_transaction

@mock.patch.object(BaseBehaviour, "_send_signing_request")
@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch.object(BaseBehaviour,
                   "_check_http_return_code_200",
                   return_value=True)
@mock.patch.object(
    BaseBehaviour,
    "_wait_until_transaction_delivered",
    new=_wait_until_transaction_delivered_patch,
)
def test_send_transaction_invalid_transaction(*_: Any) -> None

Test '_send_transaction', positive case.

test_send_transaction_valid_transaction

@mock.patch.object(BaseBehaviour, "_send_signing_request")
@mock.patch.object(BaseBehaviour,
                   "_is_invalid_transaction",
                   return_value=False)
@mock.patch.object(BaseBehaviour, "_tx_not_found", return_value=True)
@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch.object(BaseBehaviour,
                   "_check_http_return_code_200",
                   return_value=True)
@mock.patch.object(
    BaseBehaviour,
    "_wait_until_transaction_delivered",
    new=_wait_until_transaction_delivered_patch,
)
def test_send_transaction_valid_transaction(*_: Any) -> None

Test '_send_transaction', positive case.

test_tx_not_found

def test_tx_not_found(*_: Any) -> None

Test _tx_not_found

test_is_invalid_transaction

@pytest.mark.parametrize(
    "body, expected",
    [
        (
            '{"tx_result": {"info": "LateArrivingTransaction: request \'RedeemPayload(...round_count=368...\'."}}',
            True,
        ),
        (
            '{"tx_result": {"info": "TransactionNotValidError: ..."}}',
            True,
        ),
        (
            '{"tx_result": {"info": ""}}',
            False,
        ),
    ],
)
def test_is_invalid_transaction(body: str, expected: bool) -> None

Test _is_invalid_transaction recognizes various transaction error types.

test_send_transaction_signing_error

@mock.patch.object(BaseBehaviour, "_send_signing_request")
def test_send_transaction_signing_error(*_: Any) -> None

Test '_send_transaction', signing error.

test_send_transaction_timeout_exception_submit_tx

@mock.patch.object(BaseBehaviour, "_send_signing_request")
@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
def test_send_transaction_timeout_exception_submit_tx(*_: Any) -> None

Test '_send_transaction', timeout exception.

test_send_transaction_timeout_exception_wait_until_transaction_delivered

@mock.patch.object(BaseBehaviour, "_send_signing_request")
@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch.object(BaseBehaviour,
                   "_check_http_return_code_200",
                   return_value=True)
def test_send_transaction_timeout_exception_wait_until_transaction_delivered(
        *_: Any) -> None

Test '_send_transaction', timeout exception.

test_send_transaction_transaction_not_delivered

@mock.patch.object(BaseBehaviour, "_send_signing_request")
@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch.object(BaseBehaviour,
                   "_check_http_return_code_200",
                   return_value=True)
def test_send_transaction_transaction_not_delivered(*_: Any) -> None

Test '_send_transaction', timeout exception.

test_send_transaction_wrong_ok_code

@mock.patch.object(BaseBehaviour, "_send_signing_request")
@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch.object(BaseBehaviour,
                   "_check_http_return_code_200",
                   return_value=True)
def test_send_transaction_wrong_ok_code(*_: Any) -> None

Test '_send_transaction', positive case.

test_send_transaction_wait_delivery_timeout_exception

@mock.patch.object(BaseBehaviour, "_send_signing_request")
@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch.object(
    BaseBehaviour,
    "_check_http_return_code_200",
    return_value=True,
)
@mock.patch("json.loads",
            return_value={"result": {
                "hash": "",
                "code": OK_CODE
            }})
def test_send_transaction_wait_delivery_timeout_exception(*_: Any) -> None

Test '_send_transaction', timeout exception on tx delivery.

test_send_transaction_error_status_code

@pytest.mark.parametrize("resetting", (True, False))
@pytest.mark.parametrize(
    "non_200_count",
    (
        0,
        NON_200_RETURN_CODE_DURING_RESET_THRESHOLD,
        NON_200_RETURN_CODE_DURING_RESET_THRESHOLD + 1,
    ),
)
@mock.patch.object(BaseBehaviour, "_send_signing_request")
@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch("json.loads")
def test_send_transaction_error_status_code(_: Any, __: Any, ___: Any,
                                            ____: Any, resetting: bool,
                                            non_200_count: int) -> None

Test '_send_transaction', error status code.

test_send_signing_request

@mock.patch.object(BaseBehaviour, "_get_request_nonce_from_dialogue")
@mock.patch.object(behaviour_utils, "RawMessage")
@mock.patch.object(behaviour_utils, "Terms")
def test_send_signing_request(*_: Any) -> None

Test '_send_signing_request'.

test_fuzz_send_signing_request

@given(st.binary())
def test_fuzz_send_signing_request(input_bytes: bytes) -> None

Fuzz '_send_signing_request'.

Mock context manager decorators don't work here.

Arguments:

  • input_bytes: fuzz input

test_send_transaction_signing_request

@mock.patch.object(BaseBehaviour, "_get_request_nonce_from_dialogue")
@mock.patch.object(behaviour_utils, "RawMessage")
@mock.patch.object(behaviour_utils, "Terms")
def test_send_transaction_signing_request(*_: Any) -> None

Test '_send_signing_request'.

test_send_transaction_request

@pytest.mark.parametrize(
    "chain_id, expected_kwargs",
    (
        (
            None,
            dict(
                counterparty=LEDGER_API_ADDRESS,
                performative=LedgerApiMessage.Performative.
                SEND_SIGNED_TRANSACTION,
                signed_transaction=SignedTransaction(
                    ledger_id="ethereum", body={"test_tx": "test_tx"}),
            ),
        ),
        (
            "ethereum",
            dict(
                counterparty=LEDGER_API_ADDRESS,
                performative=LedgerApiMessage.Performative.
                SEND_SIGNED_TRANSACTION,
                signed_transaction=SignedTransaction(
                    ledger_id="ethereum", body={"test_tx": "test_tx"}),
                kwargs=LedgerApiMessage.Kwargs({"chain_id": "ethereum"}),
            ),
        ),
    ),
)
def test_send_transaction_request(chain_id: Optional[str],
                                  expected_kwargs: Any) -> None

Test '_send_transaction_request'.

test_send_transaction_request_flashbots_args_are_inert

def test_send_transaction_request_flashbots_args_are_inert() -> None

Flashbots-era kwargs are accepted for downstream API compatibility but do not change the request.

The skill-level use_flashbots / target_block_numbers / raise_on_failed_simulation parameters were intentionally preserved after the upstream flashbots plugin was removed (HISTORY.md v0.21.17). Locks in that passing them produces the same plain SEND_SIGNED_TRANSACTION shape as omitting them.

test_send_transaction_receipt_request

def test_send_transaction_receipt_request() -> None

Test '_send_transaction_receipt_request'.

test_build_http_request_message

def test_build_http_request_message(*_: Any) -> None

Test '_build_http_request_message'.

test_wait_until_transaction_delivered

@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch.object(BaseBehaviour,
                   "_check_http_return_code_200",
                   return_value=True)
@mock.patch.object(BaseBehaviour, "sleep")
@mock.patch("json.loads")
def test_wait_until_transaction_delivered(*_: Any) -> None

Test '_wait_until_transaction_delivered' method.

test_wait_until_transaction_delivered_failed

@mock.patch.object(Transaction, "encode", return_value=MagicMock())
@mock.patch.object(
    BaseBehaviour,
    "_build_http_request_message",
    return_value=(MagicMock(), MagicMock()),
)
@mock.patch.object(BaseBehaviour,
                   "_check_http_return_code_200",
                   return_value=True)
@mock.patch.object(BaseBehaviour, "sleep")
@mock.patch("json.loads")
def test_wait_until_transaction_delivered_failed(*_: Any) -> None

Test '_wait_until_transaction_delivered' method.

test_wait_until_transaction_delivered_raises_timeout

def test_wait_until_transaction_delivered_raises_timeout(*_: Any) -> None

Test '_wait_until_transaction_delivered' method.

Uses a negative timeout to guarantee the deadline is already expired, avoiding timer-resolution issues on Windows (see 1477).

test_get_default_terms

@mock.patch.object(behaviour_utils, "Terms")
def test_get_default_terms(*_: Any) -> None

Test '_get_default_terms'.

test_send_raw_transaction

@mock.patch.object(BaseBehaviour, "_send_transaction_signing_request")
@mock.patch.object(BaseBehaviour, "_send_transaction_request")
@mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request")
@mock.patch.object(behaviour_utils, "Terms")
@pytest.mark.parametrize(
    "ledger_message, expected_hash, expected_response_status",
    (
        (
            LedgerApiMessage(
                cast(
                    LedgerApiMessage.Performative,
                    LedgerApiMessage.Performative.TRANSACTION_DIGEST,
                ),
                ("", ""),
                transaction_digest=TransactionDigest("ledger_id", body="test"),
            ),
            "test",
            RPCResponseStatus.SUCCESS,
        ),
        (
            LedgerApiMessage(
                cast(
                    LedgerApiMessage.Performative,
                    LedgerApiMessage.Performative.TRANSACTION_DIGESTS,
                ),
                ("", ""),
                # Only the first hash will be considered
                # because we do not support sending multiple messages and receiving multiple tx hashes yet
                transaction_digests=TransactionDigests(
                    "ledger_id",
                    transaction_digests=["test", "will_not_be_considered"],
                ),
            ),
            "test",
            RPCResponseStatus.SUCCESS,
        ),
    ),
)
def test_send_raw_transaction(
        _send_transaction_signing_request: Any, _send_transaction_request: Any,
        _send_transaction_receipt_request: Any, _terms: Any,
        ledger_message: LedgerApiMessage, expected_hash: str,
        expected_response_status: RPCResponseStatus) -> None

Test 'send_raw_transaction'.

test_send_raw_transaction_with_wrong_signing_performative

@mock.patch.object(BaseBehaviour, "_send_transaction_signing_request")
@mock.patch.object(BaseBehaviour, "_send_transaction_request")
@mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request")
@mock.patch.object(behaviour_utils, "Terms")
def test_send_raw_transaction_with_wrong_signing_performative(*_: Any) -> None

Test 'send_raw_transaction'.

test_send_raw_transaction_errors

@pytest.mark.parametrize(
    "message, expected_rpc_status",
    (
        ("Simulation failed for bundle", RPCResponseStatus.SIMULATION_FAILED),
        ("replacement transaction underpriced", RPCResponseStatus.UNDERPRICED),
        ("nonce too low", RPCResponseStatus.INCORRECT_NONCE),
        ("insufficient funds", RPCResponseStatus.INSUFFICIENT_FUNDS),
        ("already known", RPCResponseStatus.ALREADY_KNOWN),
        ("test", RPCResponseStatus.UNCLASSIFIED_ERROR),
    ),
)
@mock.patch.object(BaseBehaviour, "_send_transaction_signing_request")
@mock.patch.object(BaseBehaviour, "_send_transaction_request")
@mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request")
@mock.patch.object(behaviour_utils, "Terms")
def test_send_raw_transaction_errors(
        _: Any, __: Any, ___: Any, ____: Any, message: str,
        expected_rpc_status: RPCResponseStatus) -> None

Test 'send_raw_transaction'.

test_send_raw_transaction_hashes_mismatch

@mock.patch.object(BaseBehaviour, "_send_transaction_signing_request")
@mock.patch.object(BaseBehaviour, "_send_transaction_request")
@mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request")
@mock.patch.object(behaviour_utils, "Terms")
def test_send_raw_transaction_hashes_mismatch(*_: Any) -> None

Test 'send_raw_transaction' when signature and tx responses' hashes mismatch.

test_get_transaction_receipt

def test_get_transaction_receipt(caplog: LogCaptureFixture) -> None

Test get_transaction_receipt.

test_get_transaction_receipt_error

def test_get_transaction_receipt_error(caplog: LogCaptureFixture) -> None

Test get_transaction_receipt with error performative.

test_get_contract_api_response

@pytest.mark.parametrize("contract_address", [None, "contract_address"])
def test_get_contract_api_response(contract_address: Optional[str]) -> None

Test 'get_contract_api_response'.

test_get_status

@mock.patch.object(BaseBehaviour,
                   "_build_http_request_message",
                   return_value=(None, None))
def test_get_status(_: mock.Mock) -> None

Test '_get_status'.

test_get_netinfo

def test_get_netinfo() -> None

Test _get_netinfo method

test_num_active_peers

@pytest.mark.parametrize(
    ("num_peers", "expected_num_peers", "netinfo_status_code"),
    [
        ("0", 1, 200),
        ("0", None, 500),
        ("0", None, None),
        (None, None, 200),
    ],
)
def test_num_active_peers(num_peers: Optional[str],
                          expected_num_peers: Optional[int],
                          netinfo_status_code: Optional[int]) -> None

Test num_active_peers.

test_default_callback_request_stopped

def test_default_callback_request_stopped() -> None

Test 'default_callback_request' when stopped.

test_default_callback_late_arriving_message

def test_default_callback_late_arriving_message(*_: Any) -> None

Test 'default_callback_request' when a message arrives late.

test_default_callback_request_waiting_message

def test_default_callback_request_waiting_message(*_: Any) -> None

Test 'default_callback_request' when waiting message.

test_default_callback_request_else

def test_default_callback_request_else(*_: Any) -> None

Test 'default_callback_request' else branch.

test_stop

def test_stop() -> None

Test the stop method.

test_acn_request_from_pending

@pytest.mark.parametrize(
    "performative",
    (
        TendermintMessage.Performative.GET_GENESIS_INFO,
        TendermintMessage.Performative.GET_RECOVERY_PARAMS,
    ),
)
@pytest.mark.parametrize(
    "address_to_acn_deliverable, n_pending",
    (
        ({}, 0),
        ({
            i: None
            for i in range(3)
        }, 3),
        ({
            0: "test",
            1: None,
            2: None
        }, 2),
        ({
            i: "test"
            for i in range(3)
        }, 0),
    ),
)
def test_acn_request_from_pending(performative: TendermintMessage.Performative,
                                  address_to_acn_deliverable: Dict[str, Any],
                                  n_pending: int) -> None

Test the _acn_request_from_pending method.

test_perform_acn_request

@pytest.mark.parametrize(
    "performative",
    (
        TendermintMessage.Performative.GET_GENESIS_INFO,
        TendermintMessage.Performative.GET_RECOVERY_PARAMS,
    ),
)
@pytest.mark.parametrize(
    "address_to_acn_deliverable_per_attempt, expected_result",
    (
        (
            tuple({"address": None} for _ in range(10)),
            None,
        ),  # an example in which no agent responds
        (
            (
                {
                    f"address{i}": None
                    for i in range(3)
                },
                {
                    "address1": None,
                    "address2": "test",
                    "address3": None
                },
            ) + tuple({
                "address1": None,
                "address2": "test",
                "address3": "malicious"
            } for _ in range(8)),
            None,
        ),  # an example in which no majority is reached
        (
            tuple({f"address{i}": None
                   for i in range(3)} for _ in range(3)) + ({
                       "address1": "test",
                       "address2": "test",
                       "address3": None
                   }, ),
            "test",
        ),  # an example in which majority is reached during the 4th ACN attempt
    ),
)
def test_perform_acn_request(performative: TendermintMessage.Performative,
                             address_to_acn_deliverable_per_attempt: Tuple[
                                 Dict[str, Any], ...],
                             expected_result: Any) -> None

Test the _perform_acn_request method.

test_request_recovery_params

@pytest.mark.parametrize("expected_result", (True, False))
def test_request_recovery_params(expected_result: bool) -> None

Test request_recovery_params.

test_start_reset

def test_start_reset() -> None

Test the _start_reset method.

test_end_reset

def test_end_reset() -> None

Test the _end_reset method.

test_is_timeout_expired

@pytest.mark.parametrize(
    "check_started, is_healthy, timeout, expiration_expected",
    (
        (None, True, 0, False),
        (None, False, 0, False),
        (datetime(1, 1, 1), True, 0, False),
        (datetime.now(), False, 3000, False),
        (datetime(1, 1, 1), False, 0, True),
    ),
)
def test_is_timeout_expired(check_started: Optional[datetime],
                            is_healthy: bool, timeout: float,
                            expiration_expected: bool) -> None

Test the _is_timeout_expired method.

test_get_reset_params

@pytest.mark.parametrize("default", (True, False))
@given(
    st.datetimes(
        min_value=MIN_DATETIME_WINDOWS,
        max_value=MAX_DATETIME_WINDOWS,
    ),
    st.integers(),
    st.integers(),
    st.integers(),
)
def test_get_reset_params(default: bool, timestamp: datetime, height: int,
                          interval: int, period: int) -> None

Test _get_reset_params method.

test_get_reset_params_before_first_transition

def test_get_reset_params_before_first_transition(
        caplog: LogCaptureFixture) -> None

Test _get_reset_params falls back to default params before the first round transition.

test_reset_tendermint_with_wait_timeout_expired

@mock.patch.object(BaseBehaviour, "_start_reset")
@mock.patch.object(BaseBehaviour, "_is_timeout_expired")
def test_reset_tendermint_with_wait_timeout_expired(*_: mock.Mock) -> None

Test tendermint reset.

test_reset_tendermint_with_wait

@mock.patch.object(BaseBehaviour, "_start_reset")
@mock.patch.object(BaseBehaviour,
                   "_build_http_request_message",
                   return_value=(None, None))
@pytest.mark.parametrize(
    "reset_response, status_response, local_height, on_startup, n_iter, expecting_success",
    (
        (
            {
                "message": "Tendermint reset was successful.",
                "status": True
            },
            {
                "result": {
                    "sync_info": {
                        "latest_block_height": 1
                    }
                }
            },
            1,
            False,
            3,
            True,
        ),
        (
            {
                "message": "Tendermint reset was successful.",
                "status": True
            },
            {
                "result": {
                    "sync_info": {
                        "latest_block_height": 1
                    }
                }
            },
            1,
            True,
            2,
            True,
        ),
        (
            {
                "message": "Tendermint reset was successful.",
                "status": True,
                "is_replay": True,
            },
            {
                "result": {
                    "sync_info": {
                        "latest_block_height": 1
                    }
                }
            },
            1,
            False,
            3,
            True,
        ),
        (
            {
                "message": "Tendermint reset was successful.",
                "status": True
            },
            {
                "result": {
                    "sync_info": {
                        "latest_block_height": 1
                    }
                }
            },
            3,
            False,
            3,
            False,
        ),
        (
            {
                "message": "Error resetting tendermint.",
                "status": False
            },
            {},
            0,
            False,
            2,
            False,
        ),
        ("wrong_response", {}, 0, False, 2, False),
        (
            {
                "message": "Reset Successful.",
                "status": True
            },
            "not_accepting_txs_yet",
            0,
            False,
            3,
            False,
        ),
    ),
)
def test_reset_tendermint_with_wait(build_http_request_message_mock: mock.Mock,
                                    _start_reset: mock.Mock,
                                    reset_response: Union[Dict[str,
                                                               Union[bool,
                                                                     str]],
                                                          str],
                                    status_response: Union[Dict[str,
                                                                Union[int,
                                                                      str]],
                                                           str],
                                    local_height: int, on_startup: bool,
                                    n_iter: int,
                                    expecting_success: bool) -> None

Test tendermint reset.

test_fuzz_submit_tx

@given(st.binary())
def test_fuzz_submit_tx(input_bytes: bytes) -> None

Fuzz '_submit_tx'.

Mock context manager decorators don't work here.

Arguments:

  • input_bytes: fuzz input

test_degenerate_behaviour_async_act

def test_degenerate_behaviour_async_act() -> None

Test DegenerateBehaviour.async_act.

test_make_degenerate_behaviour

def test_make_degenerate_behaviour() -> None

Test 'make_degenerate_behaviour'.

TestTmManager Objects

class TestTmManager()

Class to test the TmManager behaviour.

setup_method

def setup_method() -> None

Set up the tests.

test_async_act

def test_async_act() -> None

Test the async_act method of the TmManager.

test_handle_unhealthy_tm

@given(latest_block_height=st.integers(min_value=0))
@pytest.mark.parametrize(
    "acn_communication_success",
    (
        True,
        False,
    ),
)
@pytest.mark.parametrize(
    "gentle_reset_attempted",
    (
        True,
        False,
    ),
)
@pytest.mark.parametrize(
    ("tm_reset_success", "num_active_peers"),
    [
        (True, 4),
        (False, 4),
        (True, 2),
        (False, None),
    ],
)
def test_handle_unhealthy_tm(latest_block_height: int,
                             acn_communication_success: bool,
                             gentle_reset_attempted: bool,
                             tm_reset_success: bool,
                             num_active_peers: Optional[int]) -> None

Test _handle_unhealthy_tm.

test_handle_unhealthy_tm_logging

@pytest.mark.parametrize(
    "n_repetitions",
    (
        1,
        2,
        1000,
    ),
)
def test_handle_unhealthy_tm_logging(n_repetitions: int) -> None

Verify if unintended logging repetition occurs during the execution of _handle_unhealthy_tm.

test_get_reset_params

@pytest.mark.parametrize(
    "expected_reset_params",
    (
        {
            "genesis_time": "genesis-time",
            "initial_height": "1"
        },
        None,
    ),
)
def test_get_reset_params(
        expected_reset_params: Optional[Dict[str, str]]) -> None

Test that reset params returns the correct params.

test_sleep_after_hard_reset

def test_sleep_after_hard_reset() -> None

Check that hard_reset_sleep returns the expected amount of time.

test_try_fix

@pytest.mark.parametrize(
    ("state", "notified", "message", "num_iter"),
    [
        (AsyncBehaviour.AsyncState.READY, False, None, 1),
        (AsyncBehaviour.AsyncState.WAITING_MESSAGE, True, Message(), 2),
        (AsyncBehaviour.AsyncState.WAITING_MESSAGE, True, Message(), 1),
    ],
)
def test_try_fix(state: AsyncBehaviour.AsyncState, notified: bool,
                 message: Optional[Message], num_iter: int) -> None

Tests try_fix.

test_get_callback_request

@pytest.mark.parametrize(
    "state",
    [
        AsyncBehaviour.AsyncState.WAITING_MESSAGE,
        AsyncBehaviour.AsyncState.READY,
    ],
)
def test_get_callback_request(state: AsyncBehaviour.AsyncState) -> None

Tests get_callback_request.

test_is_acting

def test_is_acting() -> None

Test is_acting.

test_meta_base_behaviour_when_instance_not_subclass_of_base_behaviour

def test_meta_base_behaviour_when_instance_not_subclass_of_base_behaviour(
) -> None

Test instantiation of meta class when instance not a subclass of BaseBehaviour.

test_base_behaviour_instantiation_without_attributes_raises_error

def test_base_behaviour_instantiation_without_attributes_raises_error(
) -> None

Test that definition of concrete subclass of BaseBehaviour without attributes raises error.

TestIPFSBehaviour Objects

class TestIPFSBehaviour()

Test IPFSBehaviour tests.

setup_method

def setup_method() -> None

Sets up the tests.

test_build_ipfs_message

def test_build_ipfs_message() -> None

Tests _build_ipfs_message.

test_build_ipfs_store_file_req

def test_build_ipfs_store_file_req() -> None

Tests _build_ipfs_store_file_req.

test_build_ipfs_get_file_req

def test_build_ipfs_get_file_req() -> None

Tests _build_ipfs_get_file_req.

test_deserialize_ipfs_objects

def test_deserialize_ipfs_objects() -> None

Tests _deserialize_ipfs_objects