TestDaemon: support ETH; test.py: start/stop parity automatically
This commit is contained in:
parent
69890d831b
commit
ebe21cf8d8
2 changed files with 60 additions and 47 deletions
|
|
@ -20,6 +20,7 @@
|
|||
test_daemon.py: Daemon control classes for MMGen test suite and regtest mode
|
||||
"""
|
||||
|
||||
import shutil
|
||||
from subprocess import run,PIPE
|
||||
from collections import namedtuple
|
||||
from mmgen.exception import *
|
||||
|
|
@ -30,7 +31,7 @@ class TestDaemon(MMGenObject):
|
|||
|
||||
subclasses_must_implement = ('state','stop_cmd')
|
||||
|
||||
network_ids = ('btc','btc_tn','bch','bch_tn','ltc','ltc_tn','xmr')
|
||||
network_ids = ('btc','btc_tn','bch','bch_tn','ltc','ltc_tn','xmr','eth','etc')
|
||||
|
||||
cd = namedtuple('coin_data',['coin','coind_exec','cli_exec','conf_file','dfl_rpc','dfl_rpc_tn'])
|
||||
coins = {
|
||||
|
|
@ -52,6 +53,7 @@ class TestDaemon(MMGenObject):
|
|||
coind_args = []
|
||||
cli_args = []
|
||||
shared_args = []
|
||||
coind_cmd = []
|
||||
|
||||
coin_specific_coind_args = []
|
||||
coin_specific_cli_args = []
|
||||
|
|
@ -81,6 +83,7 @@ class TestDaemon(MMGenObject):
|
|||
|
||||
me = MMGenObject.__new__(
|
||||
MoneroTestDaemon if coinsym == 'xmr'
|
||||
else EthereumTestDaemon if coinsym in ('eth','etc')
|
||||
else BitcoinTestDaemon )
|
||||
|
||||
me.network_id = network_id
|
||||
|
|
@ -158,7 +161,8 @@ class TestDaemon(MMGenObject):
|
|||
+ self.coin_specific_coind_args
|
||||
+ self.coin_specific_shared_args
|
||||
+ self.usr_coind_args
|
||||
+ self.usr_shared_args)
|
||||
+ self.usr_shared_args
|
||||
+ self.coind_cmd )
|
||||
|
||||
def cli_cmd(self,*cmds):
|
||||
return ([self.cli_exec]
|
||||
|
|
@ -193,6 +197,10 @@ class TestDaemon(MMGenObject):
|
|||
os.makedirs(self.datadir,exist_ok=True)
|
||||
if self.conf_file:
|
||||
open('{}/{}'.format(self.datadir,self.conf_file),'w').write(self.cfg_file_hdr)
|
||||
if self.use_pidfile and os.path.exists(self.pidfile):
|
||||
# Parity just overwrites the data in an existing pidfile, leading to
|
||||
# interesting consequences.
|
||||
os.unlink(self.pidfile)
|
||||
ret = self.do_start(silent=silent)
|
||||
if self.wait:
|
||||
self.wait_for_state('ready')
|
||||
|
|
@ -305,4 +313,50 @@ class MoneroTestDaemon(TestDaemon):
|
|||
def stop_cmd(self):
|
||||
return [self.coind_exec] + self.shared_args + ['exit']
|
||||
|
||||
class EthereumTestDaemon(TestDaemon):
|
||||
|
||||
def subclass_init(self):
|
||||
# defaults:
|
||||
# linux: $HOME/.local/share/io.parity.ethereum/chains/DevelopmentChain
|
||||
# win: $LOCALAPPDATA/Parity/Ethereum/chains/DevelopmentChain
|
||||
self.chaindir = os.path.join(self.datadir,'devchain')
|
||||
shutil.rmtree(self.chaindir,ignore_errors=True)
|
||||
|
||||
@property
|
||||
def coind_cmd(self):
|
||||
return ['daemon',self.pidfile] if self.platform == 'linux' else []
|
||||
|
||||
@property
|
||||
def coind_args(self):
|
||||
return ['--ports-shift={}'.format(self.port_shift),
|
||||
'--base-path={}'.format(self.chaindir),
|
||||
'--config=dev',
|
||||
'--log-file={}'.format(os.path.join(self.datadir,'parity.log')) ]
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
from mmgen.rpc import EthereumRPCConnection
|
||||
try:
|
||||
conn = EthereumRPCConnection('localhost',self.rpc_port,socket_timeout=0.2)
|
||||
except:
|
||||
return 'stopped'
|
||||
|
||||
ret = conn.eth_chainId(on_fail='return')
|
||||
|
||||
return ('stopped','ready')[ret == '0x11']
|
||||
|
||||
@property
|
||||
def stop_cmd(self):
|
||||
return ['kill','-Wf',self.pid] if g.platform == 'win' else ['kill',self.pid]
|
||||
|
||||
@property
|
||||
def pid(self): # TODO: distinguish between ETH and ETC
|
||||
if g.platform == 'win':
|
||||
cp = self.run_cmd(['ps','-Wl'],silent=True,check=False)
|
||||
for line in cp.stdout.decode().splitlines():
|
||||
if 'parity.exe' in line:
|
||||
return line.split()[3] # use Windows, not Cygwin, PID
|
||||
else:
|
||||
return super().pid
|
||||
|
||||
TestDaemon.check_implement()
|
||||
|
|
|
|||
|
|
@ -302,43 +302,11 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
|
|||
|
||||
def setup(self):
|
||||
self.spawn('',msg_only=True)
|
||||
os.environ['MMGEN_BOGUS_WALLET_DATA'] = ''
|
||||
opts = ['--ports-shift=4','--config=dev']
|
||||
lf_arg = '--log-file=' + joinpath(self.tr.data_dir,'parity.log')
|
||||
if g.platform == 'win':
|
||||
dc_dir = joinpath(os.environ['LOCALAPPDATA'],'Parity','Ethereum','chains','DevelopmentChain')
|
||||
shutil.rmtree(dc_dir,ignore_errors=True)
|
||||
m1 = 'Please copy precompiled contract data to {d}/mm1 and {d}/mm2\n'.format(d=self.tmpdir)
|
||||
m2 = 'Then start parity on another terminal as follows:\n'
|
||||
m3 = ['parity',lf_arg] + opts
|
||||
m4 = '\nPress ENTER to continue: '
|
||||
my_raw_input(m1 + m2 + ' '.join(m3) + m4)
|
||||
elif run(['which','parity'],stdout=DEVNULL).returncode == 0:
|
||||
ss = 'parity.*--log-file=test/data_dir.*/parity.log' # allow for UTF8_DEBUG
|
||||
try:
|
||||
pid = run(['pgrep','-af',ss],stdout=PIPE).stdout.split()[0]
|
||||
os.kill(int(pid),9)
|
||||
except: pass
|
||||
# '--base-path' doesn't work together with daemon mode, so we have to clobber the main dev chain
|
||||
dc_dir = joinpath(os.environ['HOME'],'.local/share/io.parity.ethereum/chains/DevelopmentChain')
|
||||
shutil.rmtree(dc_dir,ignore_errors=True)
|
||||
bdir = joinpath(self.tr.data_dir,'parity')
|
||||
try: os.mkdir(bdir)
|
||||
except: pass
|
||||
redir = None if opt.exact_output else PIPE
|
||||
pidfile = joinpath(self.tmpdir,parity_pid_fn)
|
||||
run(['parity',lf_arg] + opts + ['daemon',pidfile],stderr=redir,stdout=redir,check=True)
|
||||
time.sleep(3) # race condition
|
||||
pid = self.read_from_tmpfile(parity_pid_fn)
|
||||
elif run('netstat -tnl | grep -q 127.0.0.1:8549',shell=True).returncode == 0:
|
||||
m1 = 'No parity executable found on system, but port 8549 is active!'
|
||||
m2 = 'Before continuing, you should probably run the command'
|
||||
m3 = 'test/test.py -X setup ethdev'
|
||||
m4 = 'on the remote host.'
|
||||
sys.stderr.write('{}\n{}\n{} {}\n'.format(m1,m2,cyan(m3),m4))
|
||||
confirm_continue()
|
||||
else:
|
||||
die(1,'No parity executable found!')
|
||||
m2 = '\nPress ENTER to continue: '
|
||||
my_raw_input(m1+m2)
|
||||
start_test_daemons(g.coin)
|
||||
return 'ok'
|
||||
|
||||
def wallet_upgrade(self,src_file):
|
||||
|
|
@ -950,14 +918,5 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
|
|||
|
||||
def stop(self):
|
||||
self.spawn('',msg_only=True)
|
||||
if g.platform == 'win':
|
||||
my_raw_input('Please stop parity and Press ENTER to continue: ')
|
||||
elif run(['which','parity'],stdout=DEVNULL).returncode == 0:
|
||||
pid = self.read_from_tmpfile(parity_pid_fn)
|
||||
if opt.no_daemon_stop:
|
||||
msg_r('(leaving daemon running by user request)')
|
||||
else:
|
||||
run(['kill',pid],check=True)
|
||||
else:
|
||||
imsg('No parity executable found on system. Ignoring')
|
||||
stop_test_daemons(g.coin)
|
||||
return 'ok'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue