From e1d4e407856494d6af1b08b27fd85e065c365fc4 Mon Sep 17 00:00:00 2001 From: grdddj Date: Tue, 25 Jan 2022 18:22:11 +0100 Subject: [PATCH] feat(tests): adding assert_tx_matches() to common.py --- docs/tests/device-tests.md | 6 ++++++ tests/common.py | 26 ++++++++++++++++++++++++++ tests/conftest.py | 3 +++ 3 files changed, 35 insertions(+) diff --git a/docs/tests/device-tests.md b/docs/tests/device-tests.md index 11e41a42cd..16a254aaf8 100644 --- a/docs/tests/device-tests.md +++ b/docs/tests/device-tests.md @@ -57,6 +57,12 @@ If you would like to interact with the device (i.e. press the buttons yourself), INTERACT=1 pytest tests/device_tests ``` +When testing transaction signing, there is an option to check transaction hashes on-chain using Blockbook. It is chosen by setting `CHECK_ON_CHAIN=1` environment variable before running the tests. + +```sh +CHECK_ON_CHAIN=1 pytest tests/device_tests +``` + To run the tests quicker, spawn the emulator with disabled animations using `-a` flag. ```sh diff --git a/tests/common.py b/tests/common.py index 3cb0c537b3..745d45f795 100644 --- a/tests/common.py +++ b/tests/common.py @@ -15,9 +15,12 @@ # If not, see . import json +import os +from decimal import Decimal from pathlib import Path import pytest +import requests from trezorlib import btc, tools from trezorlib.messages import ButtonRequestType as B @@ -222,3 +225,26 @@ def get_test_address(client): """Fetch a testnet address on a fixed path. Useful to make a pin/passphrase protected call, or to identify the root secret (seed+passphrase)""" return btc.get_address(client, "Testnet", TEST_ADDRESS_N) + + +def assert_tx_matches(serialized_tx: bytes, hash_link: str, tx_hex: str = None) -> None: + """Verifies if a transaction is correctly formed.""" + hash_str = hash_link.split("/")[-1] + assert tools.tx_hash(serialized_tx).hex() == hash_str + + if tx_hex: + assert serialized_tx.hex() == tx_hex + + # TODO: we could probably do better than os.environ, this was the easiest solution + # (we could create a pytest option (and use config.getoption("use-blockbook")), + # but then each test would need to have access to config via function argument) + if int(os.environ.get("CHECK_ON_CHAIN", 0)): + + def get_tx_hex(hash_link: str) -> str: + tx_data = requests.get( + hash_link, headers={"User-Agent": "BTC transactions test"} + ).json(parse_float=Decimal) + + return tx_data["hex"] + + assert serialized_tx.hex() == get_tx_hex(hash_link) diff --git a/tests/conftest.py b/tests/conftest.py index 3fc24ce098..48e3190368 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,6 +27,9 @@ from . import ui_tests from .device_handler import BackgroundDeviceHandler from .ui_tests.reporting import testreport +# So that we see details of failed asserts from this module +pytest.register_assert_rewrite("tests.common") + @pytest.fixture(scope="session") def _raw_client(request):