ut_rpc.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #!/usr/bin/env python3
  2. """
  3. test.unit_tests_d.ut_rpc: RPC unit test for the MMGen suite
  4. """
  5. from mmgen.common import *
  6. from mmgen.exception import *
  7. from mmgen.protocol import init_proto
  8. from mmgen.rpc import rpc_init,MoneroWalletRPCClient
  9. from mmgen.daemon import CoinDaemon,MoneroWalletDaemon
  10. def cfg_file_auth_test(proto,d):
  11. qmsg(cyan(f'\n Testing authentication with credentials from {d.cfg_file}:'))
  12. d.remove_datadir() # removes cookie file to force authentication from cfg file
  13. os.makedirs(d.network_datadir)
  14. cf = os.path.join(d.datadir,d.cfg_file)
  15. with open(cf,'a') as fp:
  16. fp.write('\nrpcuser = ut_rpc\nrpcpassword = ut_rpc_passw0rd\n')
  17. d.flag.keep_cfg_file = True
  18. d.start()
  19. async def do():
  20. rpc = await rpc_init(proto)
  21. assert rpc.auth.user == 'ut_rpc', f'{rpc.auth.user}: user is not ut_rpc!'
  22. run_session(do())
  23. d.stop()
  24. def do_msg(rpc):
  25. qmsg(' Testing backend {!r}'.format( type(rpc.backend).__name__ ))
  26. class init_test:
  27. async def btc(proto,backend,daemon):
  28. rpc = await rpc_init(proto,backend,daemon)
  29. do_msg(rpc)
  30. bh = (await rpc.call('getblockchaininfo',timeout=300))['bestblockhash']
  31. await rpc.gathered_call('getblock',((bh,),(bh,1)),timeout=300)
  32. await rpc.gathered_call(None,(('getblock',(bh,)),('getblock',(bh,1))),timeout=300)
  33. async def bch(proto,backend,daemon):
  34. rpc = await rpc_init(proto,backend,daemon)
  35. do_msg(rpc)
  36. ltc = bch
  37. async def eth(proto,backend,daemon):
  38. rpc = await rpc_init(proto,backend,daemon)
  39. do_msg(rpc)
  40. await rpc.call('eth_blockNumber',timeout=300)
  41. etc = eth
  42. def run_test(network_ids,test_cf_auth=False,daemon_ids=None):
  43. def do(d):
  44. if not opt.no_daemon_stop:
  45. d.stop()
  46. if not opt.no_daemon_autostart:
  47. d.remove_datadir()
  48. d.start()
  49. for backend in g.autoset_opts['rpc_backend'].choices:
  50. test = getattr(init_test,d.proto.coin.lower())
  51. run_session(test(d.proto,backend,d),backend=backend)
  52. if not opt.no_daemon_stop:
  53. d.stop()
  54. if test_cf_auth and g.platform != 'win':
  55. cfg_file_auth_test(d.proto,d)
  56. qmsg('')
  57. for network_id in network_ids:
  58. proto = init_proto(network_id=network_id)
  59. ids = (lambda x:
  60. set(daemon_ids) & set(x) if daemon_ids else x
  61. )(CoinDaemon.coins[proto.coin].daemon_ids)
  62. for daemon_id in ids:
  63. do( CoinDaemon(proto=proto,test_suite=True,daemon_id=daemon_id) )
  64. return True
  65. class unit_tests:
  66. altcoin_deps = ('ltc','bch','geth','erigon','openethereum','parity','xmrwallet')
  67. win_skip = ('xmrwallet',) # FIXME - wallet doesn't open
  68. arm_skip = ('openethereum','parity') # no prebuilt binaries for ARM
  69. def btc(self,name,ut):
  70. return run_test(['btc','btc_tn'],test_cf_auth=True)
  71. def ltc(self,name,ut):
  72. return run_test(['ltc','ltc_tn'],test_cf_auth=True)
  73. def bch(self,name,ut):
  74. return run_test(['bch','bch_tn'],test_cf_auth=True)
  75. def geth(self,name,ut):
  76. return run_test(['eth_tn','eth_rt'],daemon_ids=['geth']) # mainnet returns EIP-155 error on empty blockchain
  77. def erigon(self,name,ut):
  78. return run_test(['eth','eth_tn','eth_rt'],daemon_ids=['erigon'])
  79. def openethereum(self,name,ut):
  80. return run_test(['eth','eth_tn','eth_rt'],daemon_ids=['openethereum'])
  81. def parity(self,name,ut):
  82. return run_test(['etc'])
  83. def xmrwallet(self,name,ut):
  84. async def run():
  85. networks = init_proto('xmr').networks
  86. daemons = [(
  87. CoinDaemon(proto=proto,test_suite=True),
  88. MoneroWalletDaemon(
  89. proto = proto,
  90. test_suite = True,
  91. wallet_dir = 'test/trash2',
  92. passwd = 'ut_rpc_passw0rd' )
  93. ) for proto in (init_proto( 'xmr', network=network ) for network in networks) ]
  94. for md,wd in daemons:
  95. if not opt.no_daemon_autostart:
  96. md.start()
  97. wd.start()
  98. c = MoneroWalletRPCClient(daemon=wd)
  99. fn = f'monero-{wd.network}-junk-wallet'
  100. qmsg(f'Creating {wd.network} wallet')
  101. await c.call(
  102. 'restore_deterministic_wallet',
  103. filename = fn,
  104. password = 'foo',
  105. seed = xmrseed().fromhex('beadface'*8,tostr=True) )
  106. qmsg(f'Opening {wd.network} wallet')
  107. await c.call( 'open_wallet', filename=fn, password='foo' )
  108. for md,wd in daemons:
  109. wd.wait = False
  110. await wd.rpc.stop_daemon()
  111. if not opt.no_daemon_stop:
  112. md.wait = False
  113. await md.rpc.stop_daemon()
  114. gmsg('OK')
  115. from mmgen.xmrseed import xmrseed
  116. import shutil
  117. shutil.rmtree('test/trash2',ignore_errors=True)
  118. os.makedirs('test/trash2')
  119. run_session(run())
  120. return True