def test_rules_file_are_copied(self): process_commands( ['installudevrules', '--location', self.INSTALLATION_FOLDER]) # Assert files wre copied for _, _, files in walk(self.INSTALLATION_FOLDER, topdown=False): for file_name in files: src = path.join(self.SOURCE_FOLDER, file_name) tgt = path.join(self.INSTALLATION_FOLDER, file_name) self.assertTrue(filecmp.cmp(src, tgt))
def do_command(self, args): cli_args = [] for arg in args: cli_args.append(shlex.quote(arg)) if self.interface == 'cli': proc = subprocess.Popen(['hwi ' + ' '.join(cli_args)], stdout=subprocess.PIPE, shell=True) result = proc.communicate() return json.loads(result[0].decode()) elif self.interface == 'bindist': proc = subprocess.Popen(['../dist/hwi ' + ' '.join(cli_args)], stdout=subprocess.PIPE, shell=True) result = proc.communicate() return json.loads(result[0].decode()) elif self.interface == 'stdin': args = [f'"{arg}"' for arg in args] input_str = '\n'.join(args) + '\n' proc = subprocess.Popen(['hwi', '--stdin'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) result = proc.communicate(input_str.encode()) return json.loads(result[0].decode()) else: return process_commands(args)
def start(self): super().start() self.coldcard_log = open("coldcard-emulator.stdout", "a") # Start the Coldcard simulator self.coldcard_proc = subprocess.Popen( [ "python3", os.path.basename(self.simulator), "--ms" ], cwd=os.path.dirname(self.simulator), stdout=self.coldcard_log, preexec_fn=os.setsid ) # Wait for simulator to be up while True: try: enum_res = process_commands(["enumerate"]) found = False for dev in enum_res: if dev["type"] == "coldcard" and "error" not in dev: found = True break if found: break except Exception: pass time.sleep(0.5) atexit.register(self.stop)
def start(self): automation_path = os.path.abspath("data/speculos-automation.json") self.emulator_stderr = open('ledger-emulator.stderr', 'a') # Start the emulator self.emulator_proc = subprocess.Popen([ 'python3', './' + os.path.basename(self.emulator_path), '--display', 'headless', '--automation', 'file:{}'.format(automation_path), '--log-level', 'automation:DEBUG', '--log-level', 'seproxyhal:DEBUG', './apps/btc.elf' ], cwd=os.path.dirname( self.emulator_path), stderr=self.emulator_stderr, preexec_fn=os.setsid) # Wait for simulator to be up while True: try: enum_res = process_commands(['enumerate']) found = False for dev in enum_res: if dev['type'] == 'ledger' and 'error' not in dev: found = True break if found: break except Exception as e: print(str(e)) pass time.sleep(0.5)
def start(self): super().start() automation_path = os.path.abspath("data/speculos-automation.json") app_path = "./apps/nanos#btc#2.0#ce796c1b.elf" if self.legacy else "./apps/btc-test.elf" os.environ["SPECULOS_APPNAME"] = "Bitcoin Test:1.6.0" if self.legacy else "Bitcoin Test:2.0.1" self.emulator_stderr = open('ledger-emulator.stderr', 'a') # Start the emulator self.emulator_proc = subprocess.Popen( [ 'python3', './' + os.path.basename(self.emulator_path), '--display', 'headless', '--automation', 'file:{}'.format(automation_path), '--log-level', 'automation:DEBUG', '--log-level', 'seproxyhal:DEBUG', '--api-port', '0', app_path ], cwd=os.path.dirname(self.emulator_path), stderr=self.emulator_stderr, preexec_fn=os.setsid, ) # Wait for simulator to be up while True: try: enum_res = process_commands(['enumerate']) found = False for dev in enum_res: if dev['type'] == 'ledger' and 'error' not in dev: found = True break if found: break except Exception as e: print(str(e)) pass time.sleep(0.5) atexit.register(self.stop)
def coldcard_test_suite(simulator, rpc, userpass, interface): try: os.unlink('coldcard-emulator.stdout') except FileNotFoundError: pass coldcard_log = open('coldcard-emulator.stdout', 'a') # Start the Coldcard simulator coldcard_proc = subprocess.Popen(['python3', os.path.basename(simulator), '--ms'], cwd=os.path.dirname(simulator), stdout=coldcard_log, preexec_fn=os.setsid) # Wait for simulator to be up while True: try: enum_res = process_commands(['enumerate']) found = False for dev in enum_res: if dev['type'] == 'coldcard' and 'error' not in dev: found = True break if found: break except Exception: pass time.sleep(0.5) # Cleanup def cleanup_simulator(): if coldcard_proc.poll() is None: os.killpg(os.getpgid(coldcard_proc.pid), signal.SIGTERM) os.waitpid(os.getpgid(coldcard_proc.pid), 0) coldcard_log.close() atexit.register(cleanup_simulator) # Coldcard specific management command tests class TestColdcardManCommands(DeviceTestCase): def test_setup(self): result = self.do_command(self.dev_args + ['-i', 'setup']) self.assertIn('error', result) self.assertIn('code', result) self.assertEqual(result['error'], 'The Coldcard does not support software setup') self.assertEqual(result['code'], -9) def test_wipe(self): result = self.do_command(self.dev_args + ['wipe']) self.assertIn('error', result) self.assertIn('code', result) self.assertEqual(result['error'], 'The Coldcard does not support wiping via software') self.assertEqual(result['code'], -9) def test_restore(self): result = self.do_command(self.dev_args + ['-i', 'restore']) self.assertIn('error', result) self.assertIn('code', result) self.assertEqual(result['error'], 'The Coldcard does not support restoring via software') self.assertEqual(result['code'], -9) def test_backup(self): result = self.do_command(self.dev_args + ['backup']) self.assertTrue(result['success']) for filename in glob.glob("backup-*.7z"): os.remove(filename) def test_pin(self): result = self.do_command(self.dev_args + ['promptpin']) self.assertIn('error', result) self.assertIn('code', result) self.assertEqual(result['error'], 'The Coldcard does not need a PIN sent from the host') self.assertEqual(result['code'], -9) result = self.do_command(self.dev_args + ['sendpin', '1234']) self.assertIn('error', result) self.assertIn('code', result) self.assertEqual(result['error'], 'The Coldcard does not need a PIN sent from the host') self.assertEqual(result['code'], -9) class TestColdcardGetXpub(DeviceTestCase): def test_getxpub(self): result = self.do_command(self.dev_args + ['--expert', 'getxpub', 'm/44h/0h/0h/3']) self.assertEqual(result['xpub'], 'tpubDFHiBJDeNvqPWNJbzzxqDVXmJZoNn2GEtoVcFhMjXipQiorGUmps3e5ieDGbRrBPTFTh9TXEKJCwbAGW9uZnfrVPbMxxbFohuFzfT6VThty') self.assertTrue(result['testnet']) self.assertFalse(result['private']) self.assertEqual(result['depth'], 4) self.assertEqual(result['parent_fingerprint'], 'bc123c3e') self.assertEqual(result['child_num'], 3) self.assertEqual(result['chaincode'], '806b26507824f73bc331494afe122f428ef30dde80b2c1ce025d2d03aff411e7') self.assertEqual(result['pubkey'], '0368000bdff5e0b71421c37b8514de8acd4d98ba9908d183d9da56d02ca4fcfd08') dev_type = "coldcard" sim_path = "/tmp/ckcc-simulator.sock" fpr = "0f056943" xpub = "tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd" signtx_cases = [ (["legacy"], True, True, False), (["segwit"], True, True, False), (["legacy", "segwit"], True, True, False), ] # Generic device tests suite = unittest.TestSuite() suite.addTest(DeviceTestCase.parameterize(TestColdcardManCommands, rpc, userpass, dev_type, dev_type, sim_path, fpr, '', interface=interface)) suite.addTest(DeviceTestCase.parameterize(TestColdcardGetXpub, rpc, userpass, dev_type, dev_type, sim_path, fpr, xpub, interface=interface)) suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, dev_type, dev_type, sim_path, fpr, xpub, interface=interface)) suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, 'coldcard_simulator', dev_type, sim_path, fpr, xpub, interface=interface)) suite.addTest(DeviceTestCase.parameterize(TestGetDescriptors, rpc, userpass, dev_type, dev_type, sim_path, fpr, xpub, interface=interface)) suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, dev_type, dev_type, sim_path, fpr, xpub, interface=interface)) suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, dev_type, dev_type, sim_path, fpr, xpub, interface=interface)) suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, dev_type, dev_type, sim_path, fpr, xpub, interface=interface)) suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, dev_type, dev_type, sim_path, fpr, xpub, interface=interface, signtx_cases=signtx_cases)) result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(suite) cleanup_simulator() atexit.unregister(cleanup_simulator) return result.wasSuccessful()