From 9484803b7175c04df2a4a495fd34df1698e4d0df Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Fri, 3 May 2019 21:15:06 -0400 Subject: [PATCH 1/4] Update Trezor T support --- README.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 4acdc1e..b4198f6 100644 --- a/README.md +++ b/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 From 6952edd879a57247c3e1b6d74f235253eabb6f42 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Wed, 22 May 2019 13:49:05 -0400 Subject: [PATCH 2/4] Introduce full_type in tests for distinguishing between device models --- test/test_coldcard.py | 12 ++++++------ test/test_device.py | 35 ++++++++++++++++++----------------- test/test_digitalbitbox.py | 11 ++++++----- test/test_keepkey.py | 11 ++++++----- test/test_ledger.py | 12 ++++++------ test/test_trezor.py | 11 ++++++----- 6 files changed, 48 insertions(+), 44 deletions(-) diff --git a/test/test_coldcard.py b/test/test_coldcard.py index 6998bc6..688ff06 100755 --- a/test/test_coldcard.py +++ b/test/test_coldcard.py @@ -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__': diff --git a/test/test_device.py b/test/test_device.py index d432b38..eb9d8bd 100644 --- a/test/test_device.py +++ b/test/test_device.py @@ -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): diff --git a/test/test_digitalbitbox.py b/test/test_digitalbitbox.py index 419aa02..faf7d93 100755 --- a/test/test_digitalbitbox.py +++ b/test/test_digitalbitbox.py @@ -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__': diff --git a/test/test_keepkey.py b/test/test_keepkey.py index ef0ff4c..ab94ca9 100755 --- a/test/test_keepkey.py +++ b/test/test_keepkey.py @@ -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 diff --git a/test/test_ledger.py b/test/test_ledger.py index a375ef6..40a8e0d 100755 --- a/test/test_ledger.py +++ b/test/test_ledger.py @@ -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__': diff --git a/test/test_trezor.py b/test/test_trezor.py index 9e3f1fb..ef9042d 100755 --- a/test/test_trezor.py +++ b/test/test_trezor.py @@ -283,6 +283,7 @@ def trezor_test_suite(emulator, rpc, userpass, interface): # Device info for tests type = 'trezor' + full_type = 'trezor_1' path = 'udp:127.0.0.1:21324' fingerprint = '95d8f670' master_xpub = 'xpub6D1weXBcFAo8CqBbpP4TbH5sxQH8ZkqC5pDEvJ95rNNBZC9zrKmZP2fXMuve7ZRBe18pWQQsGg68jkq24mZchHwYENd8cCiSb71u3KD4AFH' @@ -290,11 +291,11 @@ def trezor_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(TrezorTestCase.parameterize(TestTrezorGetxpub, emulator=dev_emulator, interface=interface)) suite.addTest(TrezorTestCase.parameterize(TestTrezorManCommands, emulator=dev_emulator, interface=interface)) return suite From ef816628e14619eb245dd3336b0e3db50eabf807 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Wed, 22 May 2019 13:49:29 -0400 Subject: [PATCH 3/4] Switch to Trezor monorepo --- test/run_tests.py | 2 +- test/setup_environment.sh | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/test/run_tests.py b/test/run_tests.py index 635a9ba..62e2608 100755 --- a/test/run_tests.py +++ b/test/run_tests.py @@ -19,7 +19,7 @@ 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') 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') diff --git a/test/setup_environment.sh b/test/setup_environment.sh index 33ace75..8ad3acf 100755 --- a/test/setup_environment.sh +++ b/test/setup_environment.sh @@ -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 @@ -41,7 +42,7 @@ fi pipenv run script/cibuild # Delete any emulator.img file find . -name "emulator.img" -exec rm {} \; -cd .. +cd ../.. # Clone coldcard firmware if it doesn't exist, or update it if it does coldcard_setup_needed=false From 84315dd5def865c929b44ab2ce53e0a132031077 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Wed, 22 May 2019 13:50:07 -0400 Subject: [PATCH 4/4] Build and test with Trezor T emulator --- test/run_tests.py | 7 ++++++- test/setup_environment.sh | 11 +++++++++++ test/test_trezor.py | 27 +++++++++++++++++---------- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/test/run_tests.py b/test/run_tests.py index 62e2608..9470608 100755 --- a/test/run_tests.py +++ b/test/run_tests.py @@ -20,6 +20,9 @@ parser = argparse.ArgumentParser(description='Setup the testing environment and 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-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: diff --git a/test/setup_environment.sh b/test/setup_environment.sh index 8ad3acf..3b3045b 100755 --- a/test/setup_environment.sh +++ b/test/setup_environment.sh @@ -42,6 +42,17 @@ fi pipenv run script/cibuild # Delete any emulator.img file 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 diff --git a/test/test_trezor.py b/test/test_trezor.py index ef9042d..f84724f 100755 --- a/test/test_trezor.py +++ b/test/test_trezor.py @@ -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,18 +278,22 @@ 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') # Device info for tests type = 'trezor' - full_type = 'trezor_1' path = 'udp:127.0.0.1:21324' fingerprint = '95d8f670' 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, full_type, path, fingerprint, master_xpub, emulator=dev_emulator, interface=interface)) @@ -296,8 +301,9 @@ def trezor_test_suite(emulator, rpc, userpass, 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(TrezorTestCase.parameterize(TestTrezorGetxpub, emulator=dev_emulator, interface=interface)) - suite.addTest(TrezorTestCase.parameterize(TestTrezorManCommands, 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__': @@ -305,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)