Merge #183: Officially support Trezor T and tests for it
84315ddBuild and test with Trezor T emulator (Andrew Chow)ef81662Switch to Trezor monorepo (Andrew Chow)6952eddIntroduce full_type in tests for distinguishing between device models (Andrew Chow)9484803Update Trezor T support (Andrew Chow) Pull request description: Fills out the table in the README with the rest of the Trezor T support. Changes the Trezor emulator stuff to use their new monorepo. Also adds Trezor T tests. Built on #157 ACKs for commit 84315d: Tree-SHA512: f4f19574d4f7b177dc98e5770017c7801fec35f481d1b50cc5ec8bf95ce483327c47626d824cea372c28ebd807c19adb412aec58d0a016643ab5366bb0eb528e
This commit is contained in:
commit
9b722055c4
32
README.md
32
README.md
@ -69,23 +69,23 @@ Please also see [docs](docs/) for additional information about each device.
|
||||
| Support Planned | Yes | Yes | Yes | Yes | Yes | Yes |
|
||||
| Implemented | Yes | Yes | Yes | Yes | Yes | Yes |
|
||||
| xpub retrieval | Yes | Yes | Yes | Yes | Yes | Yes |
|
||||
| Message Signing | Yes | Yes | ? | Yes | Yes | Yes |
|
||||
| Device Setup | N/A | Yes | ? | Yes | Yes | N/A |
|
||||
| Device Wipe | N/A | Yes | ? | Yes | Yes | N/A |
|
||||
| Device Recovery | N/A | Yes | ? | N/A | Yes | N/A |
|
||||
| Device Backup | N/A | N/A | ? | Yes | N/A | Yes |
|
||||
| P2PKH Inputs | Yes | Yes | ? | Yes | Yes | Yes |
|
||||
| P2SH-P2WPKH Inputs | Yes | Yes | ? | Yes | Yes | Yes |
|
||||
| Message Signing | Yes | Yes | Yes | Yes | Yes | Yes |
|
||||
| Device Setup | N/A | Yes | Yes | Yes | Yes | N/A |
|
||||
| Device Wipe | N/A | Yes | Yes | Yes | Yes | N/A |
|
||||
| Device Recovery | N/A | Yes | Yes | N/A | Yes | N/A |
|
||||
| Device Backup | N/A | N/A | N/A | Yes | N/A | Yes |
|
||||
| P2PKH Inputs | Yes | Yes | Yes | Yes | Yes | Yes |
|
||||
| P2SH-P2WPKH Inputs | Yes | Yes | Yes | Yes | Yes | Yes |
|
||||
| P2WPKH Inputs | Yes | Yes | Yes | Yes | Yes | Yes |
|
||||
| P2SH Multisig Inputs | Yes | Yes | ? | Yes | Yes | N/A |
|
||||
| P2SH-P2WSH Multisig Inputs | Yes | No | ? | Yes | No | N/A |
|
||||
| P2WSH Multisig Inputs | Yes | No | ? | Yes | Yes | N/A |
|
||||
| Bare Multisig Inputs | Yes | N/A | ? | Yes | N/A | N/A |
|
||||
| Aribtrary scriptPubKey Inputs | Yes | N/A | ? | Yes | N/A | N/A |
|
||||
| Aribtrary redeemScript Inputs | Yes | N/A | ? | Yes | N/A | N/A |
|
||||
| Arbitrary witnessScript Inputs | Yes | N/A | ? | Yes | N/A | N/A |
|
||||
| Non-wallet inputs | Yes | Yes | ? | Yes | Yes | Yes |
|
||||
| Mixed Segwit and Non-Segwit Inputs | N/A | Yes | ? | Yes | Yes | Yes |
|
||||
| P2SH Multisig Inputs | Yes | Yes | Yes | Yes | Yes | N/A |
|
||||
| P2SH-P2WSH Multisig Inputs | Yes | Yes | Yes | Yes | No | N/A |
|
||||
| P2WSH Multisig Inputs | Yes | Yes | Yes | Yes | Yes | N/A |
|
||||
| Bare Multisig Inputs | Yes | N/A | N/A | Yes | N/A | N/A |
|
||||
| Aribtrary scriptPubKey Inputs | Yes | N/A | N/A | Yes | N/A | N/A |
|
||||
| Aribtrary redeemScript Inputs | Yes | N/A | N/A | Yes | N/A | N/A |
|
||||
| Arbitrary witnessScript Inputs | Yes | N/A | N/A | Yes | N/A | N/A |
|
||||
| Non-wallet inputs | Yes | Yes | Yes | Yes | Yes | Yes |
|
||||
| Mixed Segwit and Non-Segwit Inputs | N/A | Yes | N/A | Yes | Yes | Yes |
|
||||
| Display on device screen | Yes | Yes | Yes | N/A | Yes | Yes |
|
||||
|
||||
## Using with Bitcoin Core
|
||||
|
||||
@ -19,7 +19,10 @@ from test_udevrules import TestUdevRulesInstaller
|
||||
parser = argparse.ArgumentParser(description='Setup the testing environment and run automated tests')
|
||||
trezor_group = parser.add_mutually_exclusive_group()
|
||||
trezor_group.add_argument('--no_trezor', help='Do not run Trezor test with emulator', action='store_true')
|
||||
trezor_group.add_argument('--trezor', help='Path to Trezor emulator.', default='work/trezor-mcu/firmware/trezor.elf')
|
||||
trezor_group.add_argument('--trezor', help='Path to Trezor emulator.', default='work/trezor-firmware/legacy/firmware/trezor.elf')
|
||||
trezor_t_group = parser.add_mutually_exclusive_group()
|
||||
trezor_t_group.add_argument('--no_trezor_t', help='Do not run Trezor T test with emulator', action='store_true')
|
||||
trezor_t_group.add_argument('--trezor_t', help='Path to Trezor T emulator.', default='work/trezor-firmware/core/emu.sh')
|
||||
coldcard_group = parser.add_mutually_exclusive_group()
|
||||
coldcard_group.add_argument('--no_coldcard', help='Do not run Coldcard test with simulator', action='store_true')
|
||||
coldcard_group.add_argument('--coldcard', help='Path to Coldcard simulator.', default='work/firmware/unix/headless.py')
|
||||
@ -45,7 +48,7 @@ if sys.platform.startswith("linux"):
|
||||
suite.addTests(unittest.defaultTestLoader.loadTestsFromTestCase(TestUdevRulesInstaller))
|
||||
|
||||
|
||||
if not args.no_trezor or not args.no_coldcard or args.ledger or not args.no_bitbox or not args.no_keepkey:
|
||||
if not args.no_trezor or not args.no_coldcard or args.ledger or not args.no_bitbox or not args.no_keepkey or not args.no_trezor_t:
|
||||
# Start bitcoind
|
||||
rpc, userpass = start_bitcoind(args.bitcoind)
|
||||
|
||||
@ -55,6 +58,8 @@ if not args.no_coldcard:
|
||||
suite.addTest(coldcard_test_suite(args.coldcard, rpc, userpass, args.interface))
|
||||
if not args.no_trezor:
|
||||
suite.addTest(trezor_test_suite(args.trezor, rpc, userpass, args.interface))
|
||||
if not args.no_trezor_t:
|
||||
suite.addTest(trezor_test_suite(args.trezor_t, rpc, userpass, args.interface, True))
|
||||
if not args.no_keepkey:
|
||||
suite.addTest(keepkey_test_suite(args.keepkey, rpc, userpass, args.interface))
|
||||
if args.ledger:
|
||||
|
||||
@ -9,12 +9,12 @@ cd work
|
||||
|
||||
# Clone trezor-mcu if it doesn't exist, or update it if it does
|
||||
trezor_setup_needed=false
|
||||
if [ ! -d "trezor-mcu" ]; then
|
||||
git clone --recursive https://github.com/trezor/trezor-mcu.git
|
||||
cd trezor-mcu
|
||||
if [ ! -d "trezor-firmware" ]; then
|
||||
git clone --recursive https://github.com/trezor/trezor-firmware.git
|
||||
cd trezor-firmware
|
||||
trezor_setup_needed=true
|
||||
else
|
||||
cd trezor-mcu
|
||||
cd trezor-firmware
|
||||
git fetch
|
||||
|
||||
# Determine if we need to pull. From https://stackoverflow.com/a/3278427
|
||||
@ -31,8 +31,9 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build emulator. This is pretty fast, so rebuilding every time is ok
|
||||
# Build trezor one emulator. This is pretty fast, so rebuilding every time is ok
|
||||
# But there should be some caching that makes this faster
|
||||
cd legacy
|
||||
export EMULATOR=1 TREZOR_TRANSPORT_V1=1 DEBUG_LINK=1 HEADLESS=1
|
||||
if [ "$trezor_setup_needed" == true ] ; then
|
||||
script/setup
|
||||
@ -43,6 +44,17 @@ pipenv run script/cibuild
|
||||
find . -name "emulator.img" -exec rm {} \;
|
||||
cd ..
|
||||
|
||||
# Build trezor t emulator. This is pretty fast, so rebuilding every time is ok
|
||||
# But there should be some caching that makes this faster
|
||||
cd core
|
||||
if [ "$trezor_setup_needed" == true ] ; then
|
||||
make vendor
|
||||
fi
|
||||
make build_unix
|
||||
# Delete any emulator.img file
|
||||
rm /var/tmp/trezor.flash
|
||||
cd ../..
|
||||
|
||||
# Clone coldcard firmware if it doesn't exist, or update it if it does
|
||||
coldcard_setup_needed=false
|
||||
if [ ! -d "firmware" ]; then
|
||||
|
||||
@ -75,12 +75,12 @@ def coldcard_test_suite(simulator, rpc, userpass, interface):
|
||||
|
||||
# Generic device tests
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(DeviceTestCase.parameterize(TestColdcardManCommands, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', '', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestColdcardManCommands, rpc, userpass, 'coldcard', 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', '', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, 'coldcard', 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, 'coldcard', 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, 'coldcard', 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, 'coldcard', 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, 'coldcard', 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd', interface=interface))
|
||||
return suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -52,11 +52,12 @@ def start_bitcoind(bitcoind_path):
|
||||
return (rpc, userpass)
|
||||
|
||||
class DeviceTestCase(unittest.TestCase):
|
||||
def __init__(self, rpc, rpc_userpass, type, path, fingerprint, master_xpub, password = '', emulator=None, interface='library', methodName='runTest'):
|
||||
def __init__(self, rpc, rpc_userpass, type, full_type, path, fingerprint, master_xpub, password = '', emulator=None, interface='library', methodName='runTest'):
|
||||
super(DeviceTestCase, self).__init__(methodName)
|
||||
self.rpc = rpc
|
||||
self.rpc_userpass = rpc_userpass
|
||||
self.type = type
|
||||
self.full_type = full_type
|
||||
self.path = path
|
||||
self.fingerprint = fingerprint
|
||||
self.master_xpub = master_xpub
|
||||
@ -71,12 +72,12 @@ class DeviceTestCase(unittest.TestCase):
|
||||
self.interface = interface
|
||||
|
||||
@staticmethod
|
||||
def parameterize(testclass, rpc, rpc_userpass, type, path, fingerprint, master_xpub, password = '', interface='library', emulator=None):
|
||||
def parameterize(testclass, rpc, rpc_userpass, type, full_type, path, fingerprint, master_xpub, password = '', interface='library', emulator=None):
|
||||
testloader = unittest.TestLoader()
|
||||
testnames = testloader.getTestCaseNames(testclass)
|
||||
suite = unittest.TestSuite()
|
||||
for name in testnames:
|
||||
suite.addTest(testclass(rpc, rpc_userpass, type, path, fingerprint, master_xpub, password, emulator, interface, name))
|
||||
suite.addTest(testclass(rpc, rpc_userpass, type, full_type, path, fingerprint, master_xpub, password, emulator, interface, name))
|
||||
return suite
|
||||
|
||||
def do_command(self, args):
|
||||
@ -105,10 +106,10 @@ class DeviceTestCase(unittest.TestCase):
|
||||
return []
|
||||
|
||||
def __str__(self):
|
||||
return '{}: {}'.format(self.type, super().__str__())
|
||||
return '{}: {}'.format(self.full_type, super().__str__())
|
||||
|
||||
def __repr__(self):
|
||||
return '{}: {}'.format(self.type, super().__repr__())
|
||||
return '{}: {}'.format(self.full_type, super().__repr__())
|
||||
|
||||
class TestDeviceConnect(DeviceTestCase):
|
||||
def setUp(self):
|
||||
@ -158,9 +159,9 @@ class TestDeviceConnect(DeviceTestCase):
|
||||
class TestGetKeypool(DeviceTestCase):
|
||||
def setUp(self):
|
||||
self.rpc = AuthServiceProxy('http://{}@127.0.0.1:18443'.format(self.rpc_userpass))
|
||||
if '{}_test'.format(self.type) not in self.rpc.listwallets():
|
||||
self.rpc.createwallet('{}_test'.format(self.type), True)
|
||||
self.wrpc = AuthServiceProxy('http://{}@127.0.0.1:18443/wallet/{}_test'.format(self.rpc_userpass, self.type))
|
||||
if '{}_test'.format(self.full_type) not in self.rpc.listwallets():
|
||||
self.rpc.createwallet('{}_test'.format(self.full_type), True)
|
||||
self.wrpc = AuthServiceProxy('http://{}@127.0.0.1:18443/wallet/{}_test'.format(self.rpc_userpass, self.full_type))
|
||||
self.wpk_rpc = AuthServiceProxy('http://{}@127.0.0.1:18443/wallet/'.format(self.rpc_userpass))
|
||||
if '--testnet' not in self.dev_args:
|
||||
self.dev_args.append('--testnet')
|
||||
@ -265,9 +266,9 @@ class TestGetKeypool(DeviceTestCase):
|
||||
class TestSignTx(DeviceTestCase):
|
||||
def setUp(self):
|
||||
self.rpc = AuthServiceProxy('http://{}@127.0.0.1:18443'.format(self.rpc_userpass))
|
||||
if '{}_test'.format(self.type) not in self.rpc.listwallets():
|
||||
self.rpc.createwallet('{}_test'.format(self.type), True)
|
||||
self.wrpc = AuthServiceProxy('http://{}@127.0.0.1:18443/wallet/{}_test'.format(self.rpc_userpass, self.type))
|
||||
if '{}_test'.format(self.full_type) not in self.rpc.listwallets():
|
||||
self.rpc.createwallet('{}_test'.format(self.full_type), True)
|
||||
self.wrpc = AuthServiceProxy('http://{}@127.0.0.1:18443/wallet/{}_test'.format(self.rpc_userpass, self.full_type))
|
||||
self.wpk_rpc = AuthServiceProxy('http://{}@127.0.0.1:18443/wallet/'.format(self.rpc_userpass))
|
||||
if '--testnet' not in self.dev_args:
|
||||
self.dev_args.append('--testnet')
|
||||
@ -409,13 +410,13 @@ class TestSignTx(DeviceTestCase):
|
||||
|
||||
# Test wrapper to avoid mixed-inputs signing for Ledger
|
||||
def test_signtx(self):
|
||||
supports_mixed = {'coldcard', 'trezor', 'digitalbitbox', 'keepkey'}
|
||||
supports_multisig = {'ledger', 'trezor', 'digitalbitbox', 'keepkey'}
|
||||
if self.type not in supports_mixed:
|
||||
self._test_signtx("legacy", self.type in supports_multisig)
|
||||
self._test_signtx("segwit", self.type in supports_multisig)
|
||||
supports_mixed = {'coldcard', 'trezor_1', 'digitalbitbox', 'keepkey'}
|
||||
supports_multisig = {'ledger', 'trezor_1', 'digitalbitbox', 'keepkey'}
|
||||
if self.full_type not in supports_mixed:
|
||||
self._test_signtx("legacy", self.full_type in supports_multisig)
|
||||
self._test_signtx("segwit", self.full_type in supports_multisig)
|
||||
else:
|
||||
self._test_signtx("all", self.type in supports_multisig)
|
||||
self._test_signtx("all", self.full_type in supports_multisig)
|
||||
|
||||
# Make a huge transaction which might cause some problems with different interfaces
|
||||
def test_big_tx(self):
|
||||
|
||||
@ -37,6 +37,7 @@ def digitalbitbox_test_suite(rpc, userpass, simulator, interface):
|
||||
|
||||
# params
|
||||
type = 'digitalbitbox'
|
||||
full_type = 'digitalbitbox'
|
||||
path = 'udp:127.0.0.1:35345'
|
||||
fingerprint = 'a31b978a'
|
||||
master_xpub = 'xpub6BsWJiRvbzQJg3J6tgUKmHWYbHJSj41EjAAje6LuDwnYLqLiNSWK4N7rCXwiUmNJTBrKL8AEH3LBzhJdgdxoy4T9aMPLCWAa6eWKGCFjQhq'
|
||||
@ -126,11 +127,11 @@ def digitalbitbox_test_suite(rpc, userpass, simulator, interface):
|
||||
|
||||
# Generic Device tests
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDBBManCommands, rpc, userpass, type, path, fingerprint, master_xpub, '0000', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, type, path, fingerprint, master_xpub, '0000', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, type, path, fingerprint, master_xpub, '0000', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, type, path, fingerprint, master_xpub, '0000', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, type, path, fingerprint, master_xpub, '0000', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDBBManCommands, rpc, userpass, type, full_type, path, fingerprint, master_xpub, '0000', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, type, full_type, path, fingerprint, master_xpub, '0000', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, type, full_type, path, fingerprint, master_xpub, '0000', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, type, full_type, path, fingerprint, master_xpub, '0000', interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, type, full_type, path, fingerprint, master_xpub, '0000', interface=interface))
|
||||
return suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -284,6 +284,7 @@ def keepkey_test_suite(emulator, rpc, userpass, interface):
|
||||
|
||||
# Device info for tests
|
||||
type = 'keepkey'
|
||||
full_type = 'keepkey'
|
||||
path = 'udp:127.0.0.1:21324'
|
||||
fingerprint = '95d8f670'
|
||||
master_xpub = 'xpub6D1weXBcFAo8CqBbpP4TbH5sxQH8ZkqC5pDEvJ95rNNBZC9zrKmZP2fXMuve7ZRBe18pWQQsGg68jkq24mZchHwYENd8cCiSb71u3KD4AFH'
|
||||
@ -291,11 +292,11 @@ def keepkey_test_suite(emulator, rpc, userpass, interface):
|
||||
|
||||
# Generic Device tests
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, type, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, type, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, type, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, type, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, type, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(KeepkeyTestCase.parameterize(TestKeepkeyGetxpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(KeepkeyTestCase.parameterize(TestKeepkeyManCommands, emulator=dev_emulator, interface=interface))
|
||||
return suite
|
||||
|
||||
@ -73,12 +73,12 @@ def ledger_test_suite(rpc, userpass, interface):
|
||||
|
||||
# Generic Device tests
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(DeviceTestCase.parameterize(TestLedgerDisabledCommands, rpc, userpass, 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestLedgerDisabledCommands, rpc, userpass, 'ledger', 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, 'ledger', 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, 'ledger', 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, 'ledger', 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, 'ledger', 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, 'ledger', 'ledger', path, fingerprint, master_xpub, interface=interface))
|
||||
return suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -5,6 +5,7 @@ import atexit
|
||||
import json
|
||||
import os
|
||||
import shlex
|
||||
import signal
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
@ -36,7 +37,7 @@ class TrezorEmulator(DeviceEmulator):
|
||||
|
||||
def start(self):
|
||||
# Start the Trezor emulator
|
||||
self.emulator_proc = subprocess.Popen(['./' + os.path.basename(self.emulator_path)], cwd=os.path.dirname(self.emulator_path))
|
||||
self.emulator_proc = subprocess.Popen(['./' + os.path.basename(self.emulator_path)], cwd=os.path.dirname(self.emulator_path), stdout=subprocess.DEVNULL, env={'SDL_VIDEODRIVER': 'dummy', 'PYOPT': '0'}, shell=True, preexec_fn=os.setsid)
|
||||
# Wait for emulator to be up
|
||||
# From https://github.com/trezor/trezor-mcu/blob/master/script/wait_for_emulator.py
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
@ -64,8 +65,8 @@ class TrezorEmulator(DeviceEmulator):
|
||||
return client
|
||||
|
||||
def stop(self):
|
||||
self.emulator_proc.kill()
|
||||
self.emulator_proc.wait()
|
||||
os.killpg(os.getpgid(self.emulator_proc.pid), signal.SIGINT)
|
||||
os.waitpid(self.emulator_proc.pid, 0)
|
||||
|
||||
class TrezorTestCase(unittest.TestCase):
|
||||
def __init__(self, emulator, interface='library', methodName='runTest'):
|
||||
@ -103,10 +104,10 @@ class TrezorTestCase(unittest.TestCase):
|
||||
return process_commands(args)
|
||||
|
||||
def __str__(self):
|
||||
return 'trezor: {}'.format(super().__str__())
|
||||
return 'trezor 1: {}'.format(super().__str__())
|
||||
|
||||
def __repr__(self):
|
||||
return 'trezor: {}'.format(super().__repr__())
|
||||
return 'trezor 1: {}'.format(super().__repr__())
|
||||
|
||||
# Trezor specific getxpub test because this requires device specific thing to set xprvs
|
||||
class TestTrezorGetxpub(TrezorTestCase):
|
||||
@ -277,7 +278,7 @@ class TestTrezorManCommands(TrezorTestCase):
|
||||
self.assertFalse(dev['needs_passphrase_sent'])
|
||||
self.assertNotEqual(dev['fingerprint'], fpr)
|
||||
|
||||
def trezor_test_suite(emulator, rpc, userpass, interface):
|
||||
def trezor_test_suite(emulator, rpc, userpass, interface, model_t=False):
|
||||
# Redirect stderr to /dev/null as it's super spammy
|
||||
sys.stderr = open(os.devnull, 'w')
|
||||
|
||||
@ -288,15 +289,21 @@ def trezor_test_suite(emulator, rpc, userpass, interface):
|
||||
master_xpub = 'xpub6D1weXBcFAo8CqBbpP4TbH5sxQH8ZkqC5pDEvJ95rNNBZC9zrKmZP2fXMuve7ZRBe18pWQQsGg68jkq24mZchHwYENd8cCiSb71u3KD4AFH'
|
||||
dev_emulator = TrezorEmulator(emulator)
|
||||
|
||||
if model_t:
|
||||
full_type = 'trezor_t'
|
||||
else:
|
||||
full_type = 'trezor_1'
|
||||
|
||||
# Generic Device tests
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(TrezorTestCase.parameterize(TestTrezorGetxpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(TrezorTestCase.parameterize(TestTrezorManCommands, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, type, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, type, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, type, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, type, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, type, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface))
|
||||
if not model_t:
|
||||
suite.addTest(TrezorTestCase.parameterize(TestTrezorGetxpub, emulator=dev_emulator, interface=interface))
|
||||
suite.addTest(TrezorTestCase.parameterize(TestTrezorManCommands, emulator=dev_emulator, interface=interface))
|
||||
return suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
@ -304,10 +311,11 @@ if __name__ == '__main__':
|
||||
parser.add_argument('emulator', help='Path to the Trezor emulator')
|
||||
parser.add_argument('bitcoind', help='Path to bitcoind binary')
|
||||
parser.add_argument('--interface', help='Which interface to send commands over', choices=['library', 'cli', 'bindist'], default='library')
|
||||
parser.add_argument('--model_t', help='The emulator is for the Trezor T', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
# Start bitcoind
|
||||
rpc, userpass = start_bitcoind(args.bitcoind)
|
||||
|
||||
suite = trezor_test_suite(args.emulator, rpc, userpass, args.interface)
|
||||
suite = trezor_test_suite(args.emulator, rpc, userpass, args.interface, args.model_t)
|
||||
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(suite)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user