test(core): simplify unittests' context handling
What changed, and why it matters
This commit is a test-code cleanup only. It moves repeated setup and teardown code for unit tests into a shared helper class, TestCaseWithContext. There are no changes to the actual firmware, wallet logic, cryptography, or any code that runs on a real Trezor device. It cannot affect user funds, device security, or real-world attacks.
No security action needed. This is a routine test refactoring. Reviewers may optionally verify that the new helper class preserves the same context setup behavior for both THP and non-THP test configurations.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff refactors Trezor Core unit tests by introducing TestCaseWithContext in core/tests/common.py. This helper class centralizes context creation for both THP (Trezor Host Protocol) and legacy codec-based tests, and clears the global CURRENT_CONTEXT after tests. Existing test classes are updated to inherit from it, removing duplicated setUpClass/tearDownClass methods. thp_common.prepare_context() is renamed to create_context() and now returns a SessionContext instead of mutating global state directly. No production code, protocol handling, or security-sensitive logic is modified.
Changed components
core/tests/common.pycore/tests/test_apps.bitcoin.approver.pycore/tests/test_apps.bitcoin.authorization.pycore/tests/test_apps.bitcoin.keychain.pycore/tests/test_apps.common.keychain.pycore/tests/test_apps.ethereum.keychain.pycore/tests/test_storage.cache.pycore/tests/test_trezor.wire.thp.channel.pycore/tests/thp_common.pyInspect captured patch +27 / −94
diff --git a/core/tests/common.py b/core/tests/common.py
index 8b0494e3..cbb67e85 100644
--- a/core/tests/common.py
+++ b/core/tests/common.py
@@ -3,6 +3,7 @@ from typing import Any, Awaitable
from ubinascii import hexlify, unhexlify # noqa: F401
from trezor import utils # noqa: F401
+from trezor.wire import context
from apps.common.paths import HARDENED
@@ -26,3 +27,18 @@ def await_result(task: Awaitable) -> Any:
value = await_result(result)
else:
value = None
+
+
+class TestCaseWithContext(unittest.TestCase):
+ def setUpClass(self):
+ if utils.USE_THP:
+ from thp_common import create_context
+
+ context.CURRENT_CONTEXT = create_context()
+ else:
+ from trezor.wire.codec.codec_context import CodecContext
+
+ context.CURRENT_CONTEXT = CodecContext(None, bytearray(64))
+
+ def tearDownClass(self):
+ context.CURRENT_CONTEXT = None
diff --git a/core/tests/test_apps.bitcoin.approver.py b/core/tests/test_apps.bitcoin.approver.py
index 0158cb33..1a200a9d 100644
--- a/core/tests/test_apps.bitcoin.approver.py
+++ b/core/tests/test_apps.bitcoin.approver.py
@@ -21,26 +21,8 @@ from apps.bitcoin.sign_tx.bitcoin import Bitcoin
from apps.bitcoin.sign_tx.tx_info import TxInfo
from apps.common import coins
-if utils.USE_THP:
- import thp_common
-else:
- import storage.cache_codec
- from trezor.wire.codec.codec_context import CodecContext
-
-class TestApprover(unittest.TestCase):
- if utils.USE_THP:
-
- def setUpClass(self):
- thp_common.prepare_context()
-
- else:
-
- def setUpClass(self):
- context.CURRENT_CONTEXT = CodecContext(None, bytearray(64))
-
- def tearDownClass(self):
- context.CURRENT_CONTEXT = None
+class TestApprover(TestCaseWithContext):
def setUp(self):
self.coin = coins.by_name("Bitcoin")
diff --git a/core/tests/test_apps.bitcoin.authorization.py b/core/tests/test_apps.bitcoin.authorization.py
index e07b8622..080b94f6 100644
--- a/core/tests/test_apps.bitcoin.authorization.py
+++ b/core/tests/test_apps.bitcoin.authorization.py
@@ -18,23 +18,10 @@ else:
from trezor.wire.codec.codec_context import CodecContext
-class TestAuthorization(unittest.TestCase):
+class TestAuthorization(TestCaseWithContext):
coin = coins.by_name("Bitcoin")
- if utils.USE_THP:
-
- def setUpClass(self):
- thp_common.prepare_context()
-
- else:
-
- def setUpClass(self):
- context.CURRENT_CONTEXT = CodecContext(None, bytearray(64))
-
- def tearDownClass(self):
- context.CURRENT_CONTEXT = None
-
def setUp(self):
self.msg_auth = AuthorizeCoinJoin(
coordinator="www.example.com",
diff --git a/core/tests/test_apps.bitcoin.keychain.py b/core/tests/test_apps.bitcoin.keychain.py
index fe59c639..eee605c0 100644
--- a/core/tests/test_apps.bitcoin.keychain.py
+++ b/core/tests/test_apps.bitcoin.keychain.py
@@ -15,30 +15,21 @@ else:
from storage import cache_codec
-class TestBitcoinKeychain(unittest.TestCase):
+class TestBitcoinKeychain(TestCaseWithContext):
if utils.USE_THP:
- def setUpClass(self):
- thp_common.prepare_context()
-
def setUp(self):
seed = bip39.seed(" ".join(["all"] * 12), "")
context.cache_set(cache_common.APP_COMMON_SEED, seed)
else:
- def setUpClass(self):
- context.CURRENT_CONTEXT = CodecContext(None, bytearray(64))
-
def setUp(self):
cache_codec.start_session()
seed = bip39.seed(" ".join(["all"] * 12), "")
cache_codec.get_active_session().set(cache_common.APP_COMMON_SEED, seed)
- def tearDownClass(self):
- context.CURRENT_CONTEXT = None
-
def test_bitcoin(self):
coin = _get_coin_by_name("Bitcoin")
keychain = await_result(_get_keychain_for_coin(coin))
@@ -113,29 +104,20 @@ class TestBitcoinKeychain(unittest.TestCase):
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
-class TestAltcoinKeychains(unittest.TestCase):
+class TestAltcoinKeychains(TestCaseWithContext):
if utils.USE_THP:
- def setUpClass(self):
- thp_common.prepare_context()
-
def setUp(self):
seed = bip39.seed(" ".join(["all"] * 12), "")
context.cache_set(cache_common.APP_COMMON_SEED, seed)
else:
- def setUpClass(self):
- context.CURRENT_CONTEXT = CodecContext(None, bytearray(64))
-
def setUp(self):
cache_codec.start_session()
seed = bip39.seed(" ".join(["all"] * 12), "")
cache_codec.get_active_session().set(cache_common.APP_COMMON_SEED, seed)
- def tearDownClass(self):
- context.CURRENT_CONTEXT = None
-
def test_bcash(self):
coin = _get_coin_by_name("Bcash")
keychain = await_result(_get_keychain_for_coin(coin))
diff --git a/core/tests/test_apps.common.keychain.py b/core/tests/test_apps.common.keychain.py
index 570e4277..e0e8d7fb 100644
--- a/core/tests/test_apps.common.keychain.py
+++ b/core/tests/test_apps.common.keychain.py
@@ -19,24 +19,13 @@ if not utils.USE_THP:
from storage import cache_codec
-class TestKeychain(unittest.TestCase):
+class TestKeychain(TestCaseWithContext):
- if utils.USE_THP:
-
- def setUpClass(self):
- thp_common.prepare_context()
-
- else:
-
- def setUpClass(self):
- context.CURRENT_CONTEXT = CodecContext(None, bytearray(64))
+ if not utils.USE_THP:
def setUp(self):
cache_codec.start_session()
- def tearDownClass(self):
- context.CURRENT_CONTEXT = None
-
def tearDown(self):
cache.clear_all()
diff --git a/core/tests/test_apps.ethereum.keychain.py b/core/tests/test_apps.ethereum.keychain.py
index 9e60f933..fd7c06d4 100644
--- a/core/tests/test_apps.ethereum.keychain.py
+++ b/core/tests/test_apps.ethereum.keychain.py
@@ -42,7 +42,7 @@ if not utils.BITCOIN_ONLY:
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
-class TestEthereumKeychain(unittest.TestCase):
+class TestEthereumKeychain(TestCaseWithContext):
def _check_keychain(self, keychain, slip44_id):
# valid address should succeed
valid_addresses = (
@@ -82,26 +82,17 @@ class TestEthereumKeychain(unittest.TestCase):
if utils.USE_THP:
- def setUpClass(self):
- thp_common.prepare_context()
-
def setUp(self):
seed = bip39.seed(" ".join(["all"] * 12), "")
context.cache_set(cache_common.APP_COMMON_SEED, seed)
else:
- def setUpClass(self):
- context.CURRENT_CONTEXT = CodecContext(None, bytearray(64))
-
def setUp(self):
cache_codec.start_session()
seed = bip39.seed(" ".join(["all"] * 12), "")
cache_codec.get_active_session().set(cache_common.APP_COMMON_SEED, seed)
- def tearDownClass(self):
- context.CURRENT_CONTEXT = None
-
def from_address_n(self, address_n):
slip44 = _slip44_from_address_n(address_n)
network = make_eth_network(slip44=slip44)
diff --git a/core/tests/test_storage.cache.py b/core/tests/test_storage.cache.py
index ee7892d0..8047ae2b 100644
--- a/core/tests/test_storage.cache.py
+++ b/core/tests/test_storage.cache.py
@@ -33,7 +33,7 @@ else:
return cache_codec.get_active_session()
-class TestStorageCache(unittest.TestCase):
+class TestStorageCache(TestCaseWithContext):
if utils.USE_THP:
@@ -347,17 +347,6 @@ class TestStorageCache(unittest.TestCase):
else:
- def setUpClass(self):
- from trezor.wire import context
- from trezor.wire.codec.codec_context import CodecContext
-
- context.CURRENT_CONTEXT = CodecContext(None, bytearray(64))
-
- def tearDownClass(self):
- from trezor.wire import context
-
- context.CURRENT_CONTEXT = None
-
def setUp(self):
cache.clear_all()
diff --git a/core/tests/test_trezor.wire.thp.channel.py b/core/tests/test_trezor.wire.thp.channel.py
index 5315e930..2bd631b9 100644
--- a/core/tests/test_trezor.wire.thp.channel.py
+++ b/core/tests/test_trezor.wire.thp.channel.py
@@ -42,10 +42,7 @@ if utils.USE_THP:
@unittest.skipUnless(utils.USE_THP, "only needed for THP")
-class TestTrezorHostProtocolChannel(unittest.TestCase):
- def setUp(self):
- thp_common.prepare_context()
-
+class TestTrezorHostProtocolChannel(TestCaseWithContext):
def test_reassembler_get_buffer(self):
"""
Test request of a reassembly buffer (various sizes).
diff --git a/core/tests/thp_common.py b/core/tests/thp_common.py
index a54665b4..fb244791 100644
--- a/core/tests/thp_common.py
+++ b/core/tests/thp_common.py
@@ -20,13 +20,13 @@ if utils.USE_THP:
from trezor import protobuf
from trezor.wire import WireInterface
- def prepare_context() -> None:
+ def create_context() -> SessionContext:
mock_iface = MockHID()
channel = get_new_channel(mock_iface)
session_cache = cache_thp.create_or_replace_session(
channel.channel_cache, session_id=b"\x01"
)
- context.CURRENT_CONTEXT = SessionContext(channel, session_cache)
+ return SessionContext(channel, session_cache)
def get_new_channel(iface: WireInterface) -> Channel:
channel_cache = create_new_channel(iface)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.