Add keepkey automated test

This commit is contained in:
Andrew Chow 2019-01-10 19:09:14 -05:00
parent b7f5288bab
commit a3f31aae60
3 changed files with 115 additions and 3 deletions

View File

@ -12,6 +12,7 @@ from test_psbt import TestPSBT
from test_trezor import trezor_test_suite
from test_ledger import ledger_test_suite
from test_digitalbitbox import digitalbitbox_test_suite
from test_keepkey import keepkey_test_suite
parser = argparse.ArgumentParser(description='Setup the testing environment and run automated tests')
trezor_group = parser.add_mutually_exclusive_group()
@ -22,6 +23,9 @@ coldcard_group.add_argument('--no_coldcard', help='Do not run Coldcard test with
coldcard_group.add_argument('--coldcard', help='Path to Coldcard simulator.', default='work/firmware/unix/headless.py')
ledger_group = parser.add_mutually_exclusive_group()
ledger_group.add_argument('--ledger', help='Run physical Ledger Nano S/X tests.', action='store_true')
keepkey_group = parser.add_mutually_exclusive_group()
keepkey_group.add_argument('--no_keepkey', help='Do not run Keepkey test with emulator', action='store_true')
keepkey_group.add_argument('--keepkey', help='Path to Keepkey emulator.', default='work/keepkey-firmware/bin/kkemu')
parser.add_argument('--digitalbitbox', help='Run physical Digital Bitbox tests.', action='store_true')
parser.add_argument('--bitcoind', help='Path to bitcoind.', default='work/bitcoin/src/bitcoind')
@ -48,5 +52,7 @@ if args.digitalbitbox:
suite.addTest(digitalbitbox_test_suite(rpc, userpass, args.password))
else:
print('Cannot run Digital Bitbox test without --password set')
result = unittest.TextTestRunner().run(suite)
if not args.no_keepkey:
suite.addTest(keepkey_test_suite(args.keepkey, rpc, userpass))
result = unittest.TextTestRunner(stream=sys.stdout).run(suite)
sys.exit(not result.wasSuccessful())

View File

@ -333,8 +333,8 @@ class TestSignTx(DeviceTestCase):
# Test wrapper to avoid mixed-inputs signing for Ledger
def test_signtx(self):
supports_mixed = {'coldcard', 'trezor', 'digitalbitbox'}
supports_multisig = {'ledger', 'trezor', 'digitalbitbox'}
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)

106
test/test_keepkey.py Executable file
View File

@ -0,0 +1,106 @@
#! /usr/bin/env python3
import argparse
import atexit
import json
import logging
import os
import socket
import subprocess
import sys
import time
import unittest
from keepkeylib.transport_udp import UDPTransport
from keepkeylib.client import KeepKeyDebugClient
from test_device import DeviceTestCase, start_bitcoind, TestDeviceConnect, TestDisplayAddress, TestGetKeypool, TestSignTx
from hwilib.commands import process_commands
emulator_proc = None
def start_emulator():
# Start the Keepkey emulator
emulator_proc = subprocess.Popen([emulator])
# 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)
sock.connect(('127.0.0.1', 21324))
sock.settimeout(0)
while True:
try:
sock.sendall(b"PINGPING")
r = sock.recv(8)
if r == b"PONGPONG":
break
except Exception:
time.sleep(0.05)
# Setup the emulator
sim_dev = UDPTransport('127.0.0.1:21324')
sim_dev.buffer = b'' # HACK to work around a bug in the keepkey library
sim_dev_debug = UDPTransport('127.0.0.1:21325')
sim_dev_debug.buffer = b'' # HACK to work around a bug in the keepkey library
client = KeepKeyDebugClient(sim_dev)
client.set_debuglink(sim_dev_debug)
client.wipe_device()
client.load_device_by_mnemonic(mnemonic='alcohol woman abuse must during monitor noble actual mixed trade anger aisle', pin='', passphrase_protection=False, label='test', language='english') # From Trezor device tests
return client
def stop_emulator():
if emulator_proc:
emulator_proc.kill()
# Keepkey specific getxpub test because this requires device specific thing to set xprvs
class TestKeepkeyGetxpub(unittest.TestCase):
def setUp(self):
self.client = start_emulator()
def test_getxpub(self):
with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/bip32_vectors.json'), encoding='utf-8') as f:
vectors = json.load(f)
for vec in vectors:
with self.subTest(vector=vec):
# Setup with xprv
self.client.wipe_device()
self.client.load_device_by_xprv(xprv=vec['xprv'], pin='', passphrase_protection=False, label='test', language='english')
# Test getmasterxpub
gmxp_res = process_commands(['-t', 'keepkey', '-d', 'udp:127.0.0.1:21324', 'getmasterxpub'])
self.assertEqual(gmxp_res['xpub'], vec['master_xpub'])
# Test the path derivs
for path_vec in vec['vectors']:
gxp_res = process_commands(['-t', 'keepkey', '-d', 'udp:127.0.0.1:21324', 'getxpub', path_vec['path']])
self.assertEqual(gxp_res['xpub'], path_vec['xpub'])
def keepkey_test_suite(emulator, rpc, userpass):
# Redirect stderr to /dev/null as it's super spammy
sys.stderr = open(os.devnull, 'w')
# Device info for tests
type = 'keepkey'
path = 'udp:127.0.0.1:21324'
fingerprint = '95d8f670'
master_xpub = 'xpub6D1weXBcFAo8CqBbpP4TbH5sxQH8ZkqC5pDEvJ95rNNBZC9zrKmZP2fXMuve7ZRBe18pWQQsGg68jkq24mZchHwYENd8cCiSb71u3KD4AFH'
# Generic Device tests
suite = unittest.TestSuite()
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, type, path, fingerprint, master_xpub))
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, type, path, fingerprint, master_xpub))
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, type, path, fingerprint, master_xpub))
suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, type, path, fingerprint, master_xpub))
suite.addTest(TestKeepkeyGetxpub())
return suite
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Test Keepkey implementation')
parser.add_argument('emulator', help='Path to the Keepkey emulator')
parser.add_argument('bitcoind', help='Path to bitcoind binary')
args = parser.parse_args()
# Start bitcoind
rpc, userpass = start_bitcoind(args.bitcoind)
suite = keepkey_test_suite(args.emulator, rpc, userpass)
unittest.TextTestRunner(stream=sys.stdout).run(suite)