def test_unstash_appends_to_right(): q = deque([1, 2, 3]) s = Stasher(q, "my-stasher") s.delay(delay_all) s.process() assert len(q) == 0 s.force_unstash() assert q == deque([1, 2, 3])
class TestStack(BaseStackClass): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.stasher = Stasher(self.rxMsgs, "TestStack~" + self.name) self.delay = self.stasher.delay # def _serviceStack(self, age): # super()._serviceStack(age) # self.stasher.process(age) async def _serviceStack(self, age): await super()._serviceStack(age) self.stasher.process(age) def resetDelays(self): self.stasher.resetDelays() def force_process_delayeds(self, *names): return self.stasher.force_unstash(*names)
class TestNodeCore(StackedTester): def __init__(self, *args, **kwargs): self.nodeMsgRouter.routes[TestMsg] = self.eatTestMsg self.nodeIbStasher = Stasher(self.nodeInBox, "nodeInBoxStasher~" + self.name) self.clientIbStasher = Stasher(self.clientInBox, "clientInBoxStasher~" + self.name) self.actionQueueStasher = Stasher(self.actionQueue, "actionQueueStasher~" + self.name) # alter whitelist to allow TestMsg type through without sig self.authnWhitelist = self.authnWhitelist + (TestMsg, ) # Nodes that wont be blacklisted by this node if the suspicion code # is among the set of suspicion codes mapped to its name. If the set of # suspicion codes is empty then the node would not be blacklisted for # any suspicion code self.whitelistedNodes = {} # type: Dict[str, Set[int]] # Clients that wont be blacklisted by this node if the suspicion code # is among the set of suspicion codes mapped to its name. If the set of # suspicion codes is empty then the client would not be blacklisted for # suspicion code self.whitelistedClients = {} # type: Dict[str, Set[int]] # Reinitialize the monitor d, l, o = self.monitor.Delta, self.monitor.Lambda, self.monitor.Omega notifierEventTriggeringConfig = self.monitor.notifierEventTriggeringConfig self.instances = Instances() self.nodeInfo = {'data': {}} pluginPaths = kwargs.get('pluginPaths', []) self.monitor = TestMonitor( self.name, d, l, o, self.instances, MockedNodeStack(), MockedBlacklister(), nodeInfo=self.nodeInfo, notifierEventTriggeringConfig=notifierEventTriggeringConfig, pluginPaths=pluginPaths) for i in range(len(self.replicas)): self.monitor.addInstance() self.replicas._monitor = self.monitor self.replicas.register_monitor_handler() def create_replicas(self, config=None): return TestReplicas(self, self.monitor, config) async def processNodeInBox(self): self.nodeIbStasher.process() await super().processNodeInBox() async def processClientInBox(self): self.clientIbStasher.process() await super().processClientInBox() def _serviceActions(self): self.actionQueueStasher.process() return super()._serviceActions() def createReplica(self, instNo: int, isMaster: bool, config=None): return TestReplica(self, instNo, isMaster, config) def newPrimaryDecider(self): pdCls = self.primaryDecider if self.primaryDecider else \ TestPrimarySelector return pdCls(self) def newViewChanger(self): vchCls = self.view_changer if self.view_changer is not None else \ TestViewChanger return vchCls(self) def delaySelfNomination(self, delay: Seconds): if isinstance(self.primaryDecider, PrimaryElector): logger.debug("{} delaying start election".format(self)) delayerElection = partial(delayers.delayerMethod, TestPrimaryElector.startElection) self.elector.actionQueueStasher.delay(delayerElection(delay)) elif isinstance(self.primaryDecider, PrimarySelector): raise RuntimeError('Does not support nomination since primary is ' 'selected deterministically') else: raise RuntimeError('Unknown primary decider encountered {}'.format( self.primaryDecider)) def delayCheckPerformance(self, delay: Seconds): logger.debug("{} delaying check performance".format(self)) delayerCheckPerf = partial(delayers.delayerMethod, TestNode.checkPerformance) self.actionQueueStasher.delay(delayerCheckPerf(delay)) def resetDelays(self, *names): logger.debug("{} resetting delays".format(self)) self.nodestack.resetDelays() self.nodeIbStasher.resetDelays(*names) for r in self.replicas: r.outBoxTestStasher.resetDelays() def resetDelaysClient(self): logger.debug("{} resetting delays for client".format(self)) self.nodestack.resetDelays() self.clientstack.resetDelays() self.clientIbStasher.resetDelays() def force_process_delayeds(self, *names): c = self.nodestack.force_process_delayeds(*names) c += self.nodeIbStasher.force_unstash(*names) for r in self.replicas: c += r.outBoxTestStasher.force_unstash(*names) logger.debug("{} forced processing of delayed messages, " "{} processed in total".format(self, c)) return c def force_process_delayeds_for_client(self): c = self.clientstack.force_process_delayeds() c += self.clientIbStasher.force_unstash() logger.debug("{} forced processing of delayed messages for clients, " "{} processed in total".format(self, c)) return c def reset_delays_and_process_delayeds(self, *names): self.resetDelays(*names) self.force_process_delayeds(*names) def reset_delays_and_process_delayeds_for_clients(self): self.resetDelaysClient() self.force_process_delayeds_for_client() def whitelistNode(self, nodeName: str, *codes: int): if nodeName not in self.whitelistedClients: self.whitelistedClients[nodeName] = set() self.whitelistedClients[nodeName].update(codes) logger.debug("{} whitelisting {} for codes {}".format( self, nodeName, codes)) def blacklistNode(self, nodeName: str, reason: str = None, code: int = None): if nodeName in self.whitelistedClients: # If node whitelisted for all codes if len(self.whitelistedClients[nodeName]) == 0: return # If no code is provided or node is whitelisted for that code elif code is None or code in self.whitelistedClients[nodeName]: return super().blacklistNode(nodeName, reason, code) def whitelistClient(self, clientName: str, *codes: int): if clientName not in self.whitelistedClients: self.whitelistedClients[clientName] = set() self.whitelistedClients[clientName].update(codes) logger.debug("{} whitelisting {} for codes {}".format( self, clientName, codes)) def blacklistClient(self, clientName: str, reason: str = None, code: int = None): if clientName in self.whitelistedClients: # If node whitelisted for all codes if len(self.whitelistedClients[clientName]) == 0: return # If no code is provided or node is whitelisted for that code elif code is None or code in self.whitelistedClients[clientName]: return super().blacklistClient(clientName, reason, code) def validateNodeMsg(self, wrappedMsg): node_message_factory.set_message_class(TestMsg) return super().validateNodeMsg(wrappedMsg) async def eatTestMsg(self, msg, frm): logger.debug("{0} received Test message: {1} from {2}".format( self.nodestack.name, msg, frm)) def service_replicas_outbox(self, *args, **kwargs) -> int: for r in self.replicas: # type: TestReplica r.outBoxTestStasher.process() return super().service_replicas_outbox(*args, **kwargs) def ensureKeysAreSetup(self): pass def getDomainReqHandler(self): return TestDomainRequestHandler(self.domainLedger, self.states[DOMAIN_LEDGER_ID], self.config, self.reqProcessors, self.bls_bft.bls_store, self.getStateTsDbStorage()) def init_core_authenticator(self): state = self.getState(DOMAIN_LEDGER_ID) return TestCoreAuthnr(state=state) def processRequest(self, request, frm): if request.operation[TXN_TYPE] == 'get_buy': self.send_ack_to_client(request.key, frm) identifier = request.identifier req_id = request.reqId req_handler = self.get_req_handler(DOMAIN_LEDGER_ID) buy_key = req_handler.prepare_buy_key(identifier, req_id) result = req_handler.state.get(buy_key) res = { f.IDENTIFIER.nm: identifier, f.REQ_ID.nm: req_id, "buy": result } self.transmitToClient(Reply(res), frm) else: super().processRequest(request, frm)
class TestNodeCore(StackedTester): def __init__(self, *args, **kwargs): self.nodeMsgRouter.routes[TestMsg] = self.eatTestMsg self.nodeIbStasher = Stasher(self.nodeInBox, "nodeInBoxStasher~" + self.name) self.clientIbStasher = Stasher(self.clientInBox, "clientInBoxStasher~" + self.name) self.actionQueueStasher = Stasher(self.actionQueue, "actionQueueStasher~" + self.name) # alter whitelist to allow TestMsg type through without sig self.authnWhitelist = self.authnWhitelist + (TestMsg, ) # Nodes that wont be blacklisted by this node if the suspicion code # is among the set of suspicion codes mapped to its name. If the set of # suspicion codes is empty then the node would not be blacklisted for # any suspicion code self.whitelistedNodes = {} # type: Dict[str, Set[int]] # Clients that wont be blacklisted by this node if the suspicion code # is among the set of suspicion codes mapped to its name. If the set of # suspicion codes is empty then the client would not be blacklisted for # suspicion code self.whitelistedClients = {} # type: Dict[str, Set[int]] # Reinitialize the monitor d, l, o = self.monitor.Delta, self.monitor.Lambda, self.monitor.Omega notifierEventTriggeringConfig = self.monitor.notifierEventTriggeringConfig self.instances = Instances() self.nodeInfo = {'data': {}} pluginPaths = kwargs.get('pluginPaths', []) self.monitor = TestMonitor( self.name, d, l, o, self.instances, MockedNodeStack(), MockedBlacklister(), nodeInfo=self.nodeInfo, notifierEventTriggeringConfig=notifierEventTriggeringConfig, pluginPaths=pluginPaths) for i in self.replicas.keys(): self.monitor.addInstance(i) self.replicas._monitor = self.monitor self.replicas.register_monitor_handler() def create_replicas(self, config=None): return TestReplicas(self, self.monitor, config, self.metrics) async def processNodeInBox(self): self.nodeIbStasher.process() await super().processNodeInBox() async def processClientInBox(self): self.clientIbStasher.process() await super().processClientInBox() def _serviceActions(self): self.actionQueueStasher.process() return super()._serviceActions() def newViewChanger(self): view_changer = self.view_changer if self.view_changer is not None \ else create_view_changer(self, TestViewChanger) # TODO: This is a hack for tests compatibility, do something better view_changer.node = self return view_changer def delayCheckPerformance(self, delay: Seconds): logger.debug("{} delaying check performance".format(self)) delayerCheckPerf = partial(delayers.delayerMethod, TestNode.checkPerformance) self.actionQueueStasher.delay(delayerCheckPerf(delay)) def resetDelays(self, *names): logger.debug("{} resetting delays".format(self)) self.nodestack.resetDelays() self.nodeIbStasher.resetDelays(*names) for r in self.replicas.values(): r.outBoxTestStasher.resetDelays() def resetDelaysClient(self): logger.debug("{} resetting delays for client".format(self)) self.nodestack.resetDelays() self.clientstack.resetDelays() self.clientIbStasher.resetDelays() def force_process_delayeds(self, *names): c = self.nodestack.force_process_delayeds(*names) c += self.nodeIbStasher.force_unstash(*names) for r in self.replicas.values(): c += r.outBoxTestStasher.force_unstash(*names) logger.debug("{} forced processing of delayed messages, " "{} processed in total".format(self, c)) return c def force_process_delayeds_for_client(self): c = self.clientstack.force_process_delayeds() c += self.clientIbStasher.force_unstash() logger.debug("{} forced processing of delayed messages for clients, " "{} processed in total".format(self, c)) return c def reset_delays_and_process_delayeds(self, *names): self.resetDelays(*names) self.force_process_delayeds(*names) def reset_delays_and_process_delayeds_for_clients(self): self.resetDelaysClient() self.force_process_delayeds_for_client() def whitelistNode(self, nodeName: str, *codes: int): if nodeName not in self.whitelistedClients: self.whitelistedClients[nodeName] = set() self.whitelistedClients[nodeName].update(codes) logger.debug("{} whitelisting {} for codes {}".format( self, nodeName, codes)) def blacklistNode(self, nodeName: str, reason: str = None, code: int = None): if nodeName in self.whitelistedClients: # If node whitelisted for all codes if len(self.whitelistedClients[nodeName]) == 0: return # If no code is provided or node is whitelisted for that code elif code is None or code in self.whitelistedClients[nodeName]: return super().blacklistNode(nodeName, reason, code) def whitelistClient(self, clientName: str, *codes: int): if clientName not in self.whitelistedClients: self.whitelistedClients[clientName] = set() self.whitelistedClients[clientName].update(codes) logger.debug("{} whitelisting {} for codes {}".format( self, clientName, codes)) def blacklistClient(self, clientName: str, reason: str = None, code: int = None): if clientName in self.whitelistedClients: # If node whitelisted for all codes if len(self.whitelistedClients[clientName]) == 0: return # If no code is provided or node is whitelisted for that code elif code is None or code in self.whitelistedClients[clientName]: return super().blacklistClient(clientName, reason, code) def validateNodeMsg(self, wrappedMsg): node_message_factory.set_message_class(TestMsg) return super().validateNodeMsg(wrappedMsg) async def eatTestMsg(self, msg, frm): logger.debug("{0} received Test message: {1} from {2}".format( self.nodestack.name, msg, frm)) def service_replicas_outbox(self, *args, **kwargs) -> int: for r in self.replicas.values(): # type: TestReplica r.outBoxTestStasher.process() return super().service_replicas_outbox(*args, **kwargs) def ensureKeysAreSetup(self): pass def init_core_authenticator(self): state = self.getState(DOMAIN_LEDGER_ID) return TestCoreAuthnr(self.write_manager.txn_types, self.read_manager.txn_types, self.action_manager.txn_types, state=state) def processRequest(self, request, frm): if request.operation[TXN_TYPE] == GET_BUY: self.send_ack_to_client(request.key, frm) identifier = request.identifier req_id = request.reqId result = self.read_manager.get_result(request) res = { f.IDENTIFIER.nm: identifier, f.REQ_ID.nm: req_id, "buy": result } self.transmitToClient(Reply(res), frm) else: super().processRequest(request, frm)
class TestNodeCore(StackedTester): def __init__(self, *args, **kwargs): self.nodeMsgRouter.routes[TestMsg] = self.eatTestMsg self.nodeIbStasher = Stasher(self.nodeInBox, "nodeInBoxStasher~" + self.name) self.clientIbStasher = Stasher(self.clientInBox, "clientInBoxStasher~" + self.name) self.actionQueueStasher = Stasher(self.actionQueue, "actionQueueStasher~" + self.name) # alter whitelist to allow TestMsg type through without sig self.authnWhitelist = self.authnWhitelist + (TestMsg,) # Nodes that wont be blacklisted by this node if the suspicion code # is among the set of suspicion codes mapped to its name. If the set of # suspicion codes is empty then the node would not be blacklisted for # any suspicion code self.whitelistedNodes = {} # type: Dict[str, Set[int]] # Clients that wont be blacklisted by this node if the suspicion code # is among the set of suspicion codes mapped to its name. If the set of # suspicion codes is empty then the client would not be blacklisted for # suspicion code self.whitelistedClients = {} # type: Dict[str, Set[int]] # Reinitialize the monitor d, l, o = self.monitor.Delta, self.monitor.Lambda, self.monitor.Omega notifierEventTriggeringConfig = self.monitor.notifierEventTriggeringConfig self.instances = Instances() self.nodeInfo = { 'data': {} } pluginPaths = kwargs.get('pluginPaths', []) self.monitor = TestMonitor( self.name, d, l, o, self.instances, MockedNodeStack(), MockedBlacklister(), nodeInfo=self.nodeInfo, notifierEventTriggeringConfig=notifierEventTriggeringConfig, pluginPaths=pluginPaths) for i in self.replicas.keys(): self.monitor.addInstance(i) self.replicas._monitor = self.monitor self.replicas.register_monitor_handler() def create_replicas(self, config=None): return TestReplicas(self, self.monitor, config, self.metrics) async def processNodeInBox(self): self.nodeIbStasher.process() await super().processNodeInBox() async def processClientInBox(self): self.clientIbStasher.process() await super().processClientInBox() def _serviceActions(self): self.actionQueueStasher.process() return super()._serviceActions() def newPrimaryDecider(self): pdCls = self.primaryDecider if self.primaryDecider else \ TestPrimarySelector return pdCls(self) def newViewChanger(self): vchCls = self.view_changer if self.view_changer is not None else \ TestViewChanger return vchCls(self) def delaySelfNomination(self, delay: Seconds): if isinstance(self.primaryDecider, PrimaryElector): logger.debug("{} delaying start election".format(self)) delayerElection = partial(delayers.delayerMethod, TestPrimaryElector.startElection) self.elector.actionQueueStasher.delay(delayerElection(delay)) elif isinstance(self.primaryDecider, PrimarySelector): raise RuntimeError('Does not support nomination since primary is ' 'selected deterministically') else: raise RuntimeError('Unknown primary decider encountered {}'. format(self.primaryDecider)) def delayCheckPerformance(self, delay: Seconds): logger.debug("{} delaying check performance".format(self)) delayerCheckPerf = partial(delayers.delayerMethod, TestNode.checkPerformance) self.actionQueueStasher.delay(delayerCheckPerf(delay)) def resetDelays(self, *names): logger.debug("{} resetting delays".format(self)) self.nodestack.resetDelays() self.nodeIbStasher.resetDelays(*names) for r in self.replicas.values(): r.outBoxTestStasher.resetDelays() def resetDelaysClient(self): logger.debug("{} resetting delays for client".format(self)) self.nodestack.resetDelays() self.clientstack.resetDelays() self.clientIbStasher.resetDelays() def force_process_delayeds(self, *names): c = self.nodestack.force_process_delayeds(*names) c += self.nodeIbStasher.force_unstash(*names) for r in self.replicas.values(): c += r.outBoxTestStasher.force_unstash(*names) logger.debug("{} forced processing of delayed messages, " "{} processed in total".format(self, c)) return c def force_process_delayeds_for_client(self): c = self.clientstack.force_process_delayeds() c += self.clientIbStasher.force_unstash() logger.debug("{} forced processing of delayed messages for clients, " "{} processed in total".format(self, c)) return c def reset_delays_and_process_delayeds(self, *names): self.resetDelays(*names) self.force_process_delayeds(*names) def reset_delays_and_process_delayeds_for_clients(self): self.resetDelaysClient() self.force_process_delayeds_for_client() def whitelistNode(self, nodeName: str, *codes: int): if nodeName not in self.whitelistedClients: self.whitelistedClients[nodeName] = set() self.whitelistedClients[nodeName].update(codes) logger.debug("{} whitelisting {} for codes {}" .format(self, nodeName, codes)) def blacklistNode(self, nodeName: str, reason: str = None, code: int = None): if nodeName in self.whitelistedClients: # If node whitelisted for all codes if len(self.whitelistedClients[nodeName]) == 0: return # If no code is provided or node is whitelisted for that code elif code is None or code in self.whitelistedClients[nodeName]: return super().blacklistNode(nodeName, reason, code) def whitelistClient(self, clientName: str, *codes: int): if clientName not in self.whitelistedClients: self.whitelistedClients[clientName] = set() self.whitelistedClients[clientName].update(codes) logger.debug("{} whitelisting {} for codes {}" .format(self, clientName, codes)) def blacklistClient(self, clientName: str, reason: str = None, code: int = None): if clientName in self.whitelistedClients: # If node whitelisted for all codes if len(self.whitelistedClients[clientName]) == 0: return # If no code is provided or node is whitelisted for that code elif code is None or code in self.whitelistedClients[clientName]: return super().blacklistClient(clientName, reason, code) def validateNodeMsg(self, wrappedMsg): node_message_factory.set_message_class(TestMsg) return super().validateNodeMsg(wrappedMsg) async def eatTestMsg(self, msg, frm): logger.debug("{0} received Test message: {1} from {2}". format(self.nodestack.name, msg, frm)) def service_replicas_outbox(self, *args, **kwargs) -> int: for r in self.replicas.values(): # type: TestReplica r.outBoxTestStasher.process() return super().service_replicas_outbox(*args, **kwargs) def ensureKeysAreSetup(self): pass def init_domain_req_handler(self): return TestDomainRequestHandler(self.domainLedger, self.states[DOMAIN_LEDGER_ID], self.config, self.reqProcessors, self.bls_bft.bls_store, self.getStateTsDbStorage()) def init_core_authenticator(self): state = self.getState(DOMAIN_LEDGER_ID) return TestCoreAuthnr(state=state) def processRequest(self, request, frm): if request.operation[TXN_TYPE] == 'get_buy': self.send_ack_to_client(request.key, frm) identifier = request.identifier req_id = request.reqId req_handler = self.get_req_handler(DOMAIN_LEDGER_ID) buy_key = req_handler.prepare_buy_key(identifier, req_id) result = req_handler.state.get(buy_key) res = { f.IDENTIFIER.nm: identifier, f.REQ_ID.nm: req_id, "buy": result } self.transmitToClient(Reply(res), frm) else: super().processRequest(request, frm)