import os from collections import defaultdict import pytest from trezorlib import MINIMUM_FIRMWARE_VERSION, btc, debuglink, device from trezorlib.tools import H_ MINIMUM_FIRMWARE_VERSION["1"] = (1, 0, 0) MINIMUM_FIRMWARE_VERSION["T"] = (2, 0, 0) try: from .emulator_wrapper import EmulatorWrapper except ImportError: pass # **** COMMON DEFINITIONS **** MNEMONIC = " ".join(["all"] * 12) PATH = [H_(44), H_(0), H_(0), 0, 0] ADDRESS = "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL" LABEL = "test" LANGUAGE = "english" STRENGTH = 128 ROOT = os.path.dirname(os.path.abspath(__file__)) + "/../../" LOCAL_BUILDS = { "core": ROOT + "core/build/unix/micropython", "legacy": ROOT + "legacy/firmware/trezor.elf", } BIN_DIR = os.path.dirname(os.path.abspath(__file__)) + "/emulators" def check_version(tag, ver_emu): if tag.startswith("v") and len(tag.split(".")) == 3: assert tag == "v" + ".".join(["%d" % i for i in ver_emu]) def check_file(gen, tag): if tag.startswith("/"): filename = tag else: filename = "%s/trezor-emu-%s-%s" % (BIN_DIR, gen, tag) if not os.path.exists(filename): raise ValueError(filename + " not found. Do not forget to build firmware.") def get_tags(): files = os.listdir(BIN_DIR) if not files: raise ValueError( "No files found. Use download_emulators.sh to download emulators." ) result = defaultdict(list) for f in sorted(files): try: _, _, gen, tag = f.split("-", maxsplit=3) result[gen].append(tag) except ValueError: pass return result ALL_TAGS = get_tags() def for_all(*args, minimum_version=(1, 0, 0)): if not args: args = ("core", "legacy") all_params = [] for gen in args: try: to_tag = LOCAL_BUILDS[gen] from_tags = ALL_TAGS[gen] + [to_tag] for from_tag in from_tags: if from_tag.startswith("v"): tag_version = tuple(int(n) for n in from_tag[1:].split(".")) if tag_version < minimum_version: continue check_file(gen, from_tag) all_params.append((gen, from_tag, to_tag)) except KeyError: pass return pytest.mark.parametrize("gen, from_tag, to_tag", all_params) @for_all() def test_upgrade_load(gen, from_tag, to_tag): def asserts(tag, client): check_version(tag, emu.client.version) assert not client.features.pin_protection assert not client.features.passphrase_protection assert client.features.initialized assert client.features.label == LABEL assert client.features.language == LANGUAGE assert btc.get_address(client, "Bitcoin", PATH) == ADDRESS with EmulatorWrapper(gen, from_tag) as emu: debuglink.load_device_by_mnemonic( emu.client, mnemonic=MNEMONIC, pin="", passphrase_protection=False, label=LABEL, language=LANGUAGE, ) device_id = emu.client.features.device_id asserts(from_tag, emu.client) storage = emu.storage() with EmulatorWrapper(gen, to_tag, storage=storage) as emu: assert device_id == emu.client.features.device_id asserts(to_tag, emu.client) @for_all("legacy") def test_upgrade_reset(gen, from_tag, to_tag): def asserts(tag, client): check_version(tag, emu.client.version) assert not client.features.pin_protection assert not client.features.passphrase_protection assert client.features.initialized assert client.features.label == LABEL assert client.features.language == LANGUAGE assert not client.features.needs_backup assert not client.features.unfinished_backup assert not client.features.no_backup with EmulatorWrapper(gen, from_tag) as emu: device.reset( emu.client, display_random=False, strength=STRENGTH, passphrase_protection=False, pin_protection=False, label=LABEL, language=LANGUAGE, ) device_id = emu.client.features.device_id asserts(from_tag, emu.client) storage = emu.storage() with EmulatorWrapper(gen, to_tag, storage=storage) as emu: assert device_id == emu.client.features.device_id asserts(to_tag, emu.client) @for_all() def test_upgrade_reset_skip_backup(gen, from_tag, to_tag): def asserts(tag, client): check_version(tag, emu.client.version) assert not client.features.pin_protection assert not client.features.passphrase_protection assert client.features.initialized assert client.features.label == LABEL assert client.features.language == LANGUAGE assert client.features.needs_backup assert not client.features.unfinished_backup assert not client.features.no_backup with EmulatorWrapper(gen, from_tag) as emu: device.reset( emu.client, display_random=False, strength=STRENGTH, passphrase_protection=False, pin_protection=False, label=LABEL, language=LANGUAGE, skip_backup=True, ) device_id = emu.client.features.device_id asserts(from_tag, emu.client) storage = emu.storage() with EmulatorWrapper(gen, to_tag, storage=storage) as emu: assert device_id == emu.client.features.device_id asserts(to_tag, emu.client) @for_all(minimum_version=(1, 7, 2)) def test_upgrade_reset_no_backup(gen, from_tag, to_tag): def asserts(tag, client): check_version(tag, emu.client.version) assert not client.features.pin_protection assert not client.features.passphrase_protection assert client.features.initialized assert client.features.label == LABEL assert client.features.language == LANGUAGE assert not client.features.needs_backup assert not client.features.unfinished_backup assert client.features.no_backup with EmulatorWrapper(gen, from_tag) as emu: device.reset( emu.client, display_random=False, strength=STRENGTH, passphrase_protection=False, pin_protection=False, label=LABEL, language=LANGUAGE, no_backup=True, ) device_id = emu.client.features.device_id asserts(from_tag, emu.client) storage = emu.storage() with EmulatorWrapper(gen, to_tag, storage=storage) as emu: assert device_id == emu.client.features.device_id asserts(to_tag, emu.client) if __name__ == "__main__": if not ALL_TAGS: print("No versions found. Remember to run download_emulators.sh") for k, v in ALL_TAGS.items(): print("Found versions for {}:".format(k), v) print() print("Use `pytest {}` to run tests".format(__file__))