class UserScenario(metaclass=ABCMeta): def __init__(self, seed, logFileName=None): if logFileName: Logger().enableFileLogging(logFileName) self._seed = seed self._client = None self._wallet = None self._looper = None @property def identifier(self): if self._wallet: return self._wallet.defaultId else: return None @property def verkey(self): if self._wallet: return self._wallet.getVerkey() else: return None @classmethod def runInstance(cls, *args, **kwargs): cls(*args, **kwargs).run() def run(self): try: self._createClientAndWallet() self._looper = Looper(debug=getConfig().LOOPER_DEBUG) try: self._startClient() self.do() finally: self._looper.shutdownSync() self._looper = None except BaseException as ex: logger.exception( "User scenario throws out exception: {}".format(ex), exc_info=ex) raise ex @abstractmethod def do(self): pass def performOperation(self, op): req = self._wallet.signOp(op) self._client.submitReqs(req) def getRequestResult(reqKey): reply, error = self._client.replyIfConsensus(*reqKey) if reply is None and error is None: raise Exception("Request has not been completed yet") else: return reply, error reply, error = self._looper.run( eventually(partial(getRequestResult, req.key), retryWait=.5, timeout=5)) assert not error, error if reply[DATA]: result = json.loads(reply[DATA]) else: result = None return result def generateNewSigner(self): assert self.identifier return SimpleSigner(identifier=self.identifier) def changeSigner(self, newSigner): assert newSigner.identifier == self.identifier self._wallet.updateSigner(self.identifier, newSigner) logger.info("Changed signer. New verkey: {}".format(self.verkey)) def _createClientAndWallet(self): signer = SimpleSigner(seed=self._seed) port = genHa()[1] ha = HA('0.0.0.0', port) self._client = Client(name=signer.identifier, ha=ha) self._wallet = Wallet(name=signer.identifier) self._wallet.addIdentifier(signer=signer) logger.info("Identifier: {}".format(self.identifier)) logger.info("Signer's verkey: {}".format(self.verkey)) def _startClient(self): self._looper.add(self._client) def ensureConnectedToAll(): connectedNodes = self._client.nodestack.connecteds connectedNodesNum = len(connectedNodes) totalNodes = len(self._client.nodeReg) logger.info("Connected {} / {} nodes".format( connectedNodesNum, totalNodes)) for node in connectedNodes: logger.info(" {}".format(node)) if connectedNodesNum == 0: raise Exception("Not connected to any") elif connectedNodesNum < totalNodes * 0.8: raise Exception("Not connected fully") else: return True self._looper.run( eventually(ensureConnectedToAll, retryWait=.5, timeout=5))
def test_hasProdable(): looper = Looper(autoStart=False) with pytest.raises(ValueError): Looper().hasProdable(Prodable(), 'prodable') looper.shutdownSync()