Skip to content

Commit

Permalink
Added python script handling for unstarted nodes. GH EOSIO#6727.
Browse files Browse the repository at this point in the history
  • Loading branch information
brianjohnson5972 committed Mar 23, 2019
1 parent 97f777b commit dd4d3a4
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 13 deletions.
31 changes: 31 additions & 0 deletions tests/Cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def __init__(self, walletd=False, localCluster=True, host="localhost", port=8888
"""
self.accounts={}
self.nodes={}
self.unstartedNodes=[]
self.localCluster=localCluster
self.wallet=None
self.walletd=walletd
Expand Down Expand Up @@ -379,6 +380,9 @@ def connectGroup(group, producerNodes, bridgeNodes) :

self.nodes=nodes

if unstartedNodes > 0:
self.unstartedNodes=self.discoverUnstartedLocalNodes(unstartedNodes, totalNodes)

if onlyBios:
biosNode=Node(Cluster.__BiosHost, Cluster.__BiosPort, walletMgr=self.walletMgr)
if not biosNode.checkPulse():
Expand Down Expand Up @@ -645,6 +649,16 @@ def getNode(self, nodeId=0, exitOnError=True):
def getNodes(self):
return self.nodes

def launchUnstarted(self, numToLaunch=1, cachePopen=False):
assert(isinstance(numToLaunch, int))
assert(numToLaunch>0)
launchList=self.unstartedNodes[:numToLaunch]
del self.unstartedNodes[:numToLaunch]
for node in launchList:
# the node number is indexed off of the started nodes list
node.launchUnstarted(len(self.nodes), cachePopen=cachePopen)
self.nodes.append(node)

# Spread funds across accounts with transactions spread through cluster nodes.
# Validate transactions are synchronized on root node
def spreadFunds(self, source, accounts, amount=1):
Expand Down Expand Up @@ -1485,6 +1499,23 @@ def createAccounts(self, creator, waitForTransBlock=True, stakedDeposit=1000):

return True

def discoverUnstartedLocalNodes(self, unstartedNodes, totalNodes):
unstarted=[]
firstUnstartedNode=totalNodes-unstartedNodes
for nodeId in range(firstUnstartedNode, totalNodes):
unstarted.append(self.discoverUnstartedLocalNode(nodeId))
return unstarted

def discoverUnstartedLocalNode(self, nodeId):
startFile=Node.unstartedFile(nodeId)
with open(startFile, 'r') as file:
cmd=file.read()
Utils.Print("unstarted local node cmd: %s" % (cmd))
p=re.compile(r'^\s*(\w+)\s*=\s*([^\s](?:.*[^\s])?)\s*$')
instance=Node(self.host, port=self.port+nodeId, pid=None, cmd=cmd, walletMgr=self.walletMgr, enableMongo=self.enableMongo, mongoHost=self.mongoHost, mongoPort=self.mongoPort, mongoDb=self.mongoDb)
if Utils.Debug: Utils.Print("Unstarted Node>", instance)
return instance

def getInfos(self, silentErrors=False, exitOnError=False):
infos=[]
for node in self.nodes:
Expand Down
27 changes: 14 additions & 13 deletions tests/Node.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def eosClientArgs(self):

def __str__(self):
#return "Host: %s, Port:%d, Pid:%s, Cmd:\"%s\"" % (self.host, self.port, self.pid, self.cmd)
return "Host: %s, Port:%d" % (self.host, self.port)
return "Host: %s, Port:%d, Pid:%s" % (self.host, self.port, self.pid)

@staticmethod
def validateTransaction(trans):
Expand Down Expand Up @@ -1095,6 +1095,8 @@ def processCurlCmd(self, resource, command, payload, silentErrors=True, exitOnEr
if Utils.Debug:
end=time.perf_counter()
Utils.Print("cmd Duration: %.3f sec" % (end-start))
printReturn=json.dumps(rtn) if returnType==ReturnType.json else rtn
Utils.Print("cmd returned: %s" % (printReturn))
except subprocess.CalledProcessError as ex:
if not silentErrors:
end=time.perf_counter()
Expand Down Expand Up @@ -1241,12 +1243,12 @@ def myFunc():
self.killed=True
return True

def interruptAndVerifyExitStatus(self):
def interruptAndVerifyExitStatus(self, timeout=15):
if Utils.Debug: Utils.Print("terminating node: %s" % (self.cmd))
assert self.popenProc is not None, "node: \"%s\" does not have a popenProc, this may be because it is only set after a relaunch." % (self.cmd)
self.popenProc.send_signal(signal.SIGINT)
try:
outs, _ = self.popenProc.communicate(timeout=15)
outs, _ = self.popenProc.communicate(timeout=timeout)
assert self.popenProc.returncode == 0, "Expected terminating \"%s\" to have an exit status of 0, but got %d" % (self.cmd, self.popenProc.returncode)
except subprocess.TimeoutExpired:
Utils.errorExit("Terminate call failed on node: %s" % (self.cmd))
Expand Down Expand Up @@ -1376,18 +1378,17 @@ def isNodeAlive():
self.killed=False
return True

def launchUnstarted(self, nodeId, cachePopen=False):
@staticmethod
def unstartedFile(nodeId):
assert(isinstance(nodeId, int))
startFile=Utils.getNodeDataDir(nodeId, "start.cmd")
if not os.path.exists(startFile):
Utils.Print("Cannot launch unstarted process since %s file does not exist" % startFile)
return False

with open(startFile, 'r') as file:
cmd=file.read()
Utils.Print("launchUnstarted cmd: %s" % (cmd))
Utils.errorExit("Cannot find unstarted node since %s file does not exist" % startFile)
return startFile

self.launchCmd(cmd, nodeId, cachePopen)
return True
def launchUnstarted(self, nodeId, cachePopen=False):
Utils.Print("launchUnstarted cmd: %s" % (self.cmd))
self.launchCmd(self.cmd, nodeId, cachePopen)

def launchCmd(self, cmd, nodeId, cachePopen=False):
dataDir=Utils.getNodeDataDir(nodeId)
Expand All @@ -1401,7 +1402,7 @@ def launchCmd(self, cmd, nodeId, cachePopen=False):
if cachePopen:
self.popenProc=popen
self.pid=popen.pid
if Utils.Debug: Utils.Print("restart Node host=%s, port=%s, pid=%s, cmd=%s" % (self.host, self.port, self.pid, self.cmd))
if Utils.Debug: Utils.Print("start Node host=%s, port=%s, pid=%s, cmd=%s" % (self.host, self.port, self.pid, self.cmd))

def trackCmdTransaction(self, trans, ignoreNonTrans=False):
if trans is None:
Expand Down

0 comments on commit dd4d3a4

Please sign in to comment.