def test_pubsub_1_1_1(self): """ Tests pub/sub 1-1 (one sub one pub) with one message """ def config_sub(composer: Composer): from unittest.mock import MagicMock composer.manager.router = MagicMock() return composer def assert_sub(composer: Composer): from cilantro.messages.reactor.reactor_command import ReactorCommand from cilantro.protocol.states.decorators import StateInput cb = ReactorCommand.create_callback(callback=StateInput.INPUT, envelope=env) composer.manager.router.route_callback.assert_called_with(cb) env = random_envelope() sub = MPComposer(config_fn=config_sub, assert_fn=assert_sub, name='[MN1] SUB', sk=sk1) pub = MPComposer(name='[Delegate1] PUB', sk=sk2) pub_ip = pub.ip sub.add_sub(vk=vk2, filter=FILTER) pub.add_pub(ip=pub_ip) time.sleep(5.0) pub.send_pub_env(filter=FILTER, envelope=env) self.start()
def test_pubsub_1_1_1(self): """ Tests pub/sub 1-1 (one sub one pub) with one message """ def configure(composer: Composer): composer.interface.router = MagicMock() return composer def run_assertions(composer: Composer): callback = ReactorCommand.create_callback( callback=StateInput.INPUT, envelope=env) composer.interface.router.route_callback.assert_called_once_with( callback) env = random_envelope() sub = MPComposer(config_fn=configure, assert_fn=run_assertions, name='** SUB', sk=sk1) pub = MPComposer(name='++ PUB', sk=sk2) sub.add_sub(url=URL, filter=FILTER) pub.add_pub(url=URL) time.sleep(0.2) pub.send_pub_env(filter=FILTER, envelope=env) self.start()
def test_req_reply_1_1_1_timeout(self): """ Tests request/reply 1_1_1 with a timeout and a late reply """ def config_router(composer: Composer): def reply(*args, **kwargs): # do i need the *args **kwargs ?? time.sleep(timeout_duration * 1.5) composer.send_reply(message=reply_msg, request_envelope=request_env) composer.interface.router = MagicMock() composer.interface.router.route_callback.side_effect = reply return composer def config_dealer(composer: Composer): composer.interface.router = MagicMock() return composer def assert_dealer(composer: Composer): cb = ReactorCommand.create_callback(callback=StateInput.TIMEOUT, envelope=request_env) composer.interface.router.route_callback.assert_any_call(cb) def assert_router(composer: Composer): cb = ReactorCommand.create_callback(callback=StateInput.REQUEST, envelope=request_env, header=dealer_id) composer.interface.router.route_callback.assert_called_once_with( cb) timeout_duration = 0.5 dealer_id = vk1 dealer_sk = sk1 router_sk = sk2 router_url = URLS[1] request_env = random_envelope(sk=dealer_sk) reply_msg = random_msg() dealer = MPComposer(name='DEALER', sk=sk1, config_fn=config_dealer, assert_fn=assert_dealer) router = MPComposer(config_fn=config_router, assert_fn=assert_router, name='ROUTER', sk=router_sk) dealer.add_dealer(url=router_url) router.add_router(url=router_url) time.sleep(0.2) dealer.send_request_env(url=router_url, envelope=request_env, timeout=timeout_duration) self.start()
def run_mgmt(): from cilantro.logger import get_logger from cilantro.utils.test import MPComposer log = get_logger(__name__) sk = masternodes[0]['sk'] vk = wallet.get_vk(sk) s, v = wallet.new() mpc = MPComposer(name='mgmt', sk=s) mpc.add_sub(filter='a', vk=vk)
def run_mgmt(): from cilantro.logger import get_logger from cilantro import Constants from cilantro.db import DB, DB_NAME from cilantro.utils.test import MPComposer from cilantro.protocol.wallets import ED25519Wallet import os, time, asyncio log = get_logger(__name__) sk = Constants.Testnet.Masternodes[0]['sk'] vk = Constants.Protocol.Wallets.get_vk(sk) s,v = ED25519Wallet.new() mpc = MPComposer(name='mgmt', sk=s) mpc.add_sub(filter='a', vk=vk)
def publisher(): SLEEP_TIME = 1 MAX_TIME = 10 from cilantro.logger import get_logger, overwrite_logger_level from cilantro.utils.test import MPComposer from cilantro.messages.transaction.standard import StandardTransactionBuilder import time, os log = get_logger("Publisher") sub_info = delegates[1] sub_info['ip'] = os.getenv('HOST_IP') d_info = delegates[0] d_info['ip'] = os.getenv('HOST_IP') pub = MPComposer(sk=d_info['sk']) # Publish on this node's own IP pub.add_pub(os.getenv('HOST_IP')) log.critical( "Starting experiment, sending messages every {} seconds for a total of {} seconds" .format(SLEEP_TIME, MAX_TIME)) elapsed_time = 0 while elapsed_time < MAX_TIME: log.info("Sending pub") msg = StandardTransactionBuilder.random_tx() pub.send_pub_msg(filter='0', message=msg) time.sleep(SLEEP_TIME) elapsed_time += SLEEP_TIME pub.teardown() log.critical("Done with experiment!")
def run_mgmt(): from cilantro.logger import get_logger from cilantro import Constants from cilantro.db import DB, DB_NAME from cilantro.utils.test import MPComposer from cilantro.protocol.wallets import ED25519Wallet import os, time, asyncio log = get_logger("MANAGEMENT NODE") sk = Constants.Testnet.Masternode.Sk vk = Constants.Protocol.Wallets.get_vk(sk) s, v = ED25519Wallet.new() mpc = MPComposer(name='mgmt', sk=s) log.critical("trying to look at vk: {}".format(vk)) mpc.add_sub(filter='a', url='tcp://{}:33333'.format(vk))
def test_pubsub_1_1_2_mult_filters(self): """ Tests pub/sub 1-1 (one sub one pub) with 2 message each on a different filter """ def configure(composer: Composer): from unittest.mock import MagicMock composer.manager.router = MagicMock() return composer def run_assertions(composer: Composer): from cilantro.messages.reactor.reactor_command import ReactorCommand from cilantro.protocol.states.decorators import StateInput from unittest.mock import call cb1 = ReactorCommand.create_callback(callback=StateInput.INPUT, envelope=env1) cb2 = ReactorCommand.create_callback(callback=StateInput.INPUT, envelope=env2) composer.manager.router.route_callback.assert_has_calls( [call(cb1), call(cb2)], any_order=True) env1 = random_envelope() env2 = random_envelope() filter1 = FILTERS[0] filter2 = FILTERS[1] sub = MPComposer(config_fn=configure, assert_fn=run_assertions, name='SUB', sk=sk1) pub = MPComposer(name='PUB', sk=sk2) sub.add_sub(vk=vk2, filter=filter2) sub.add_sub(vk=vk2, filter=filter1) pub.add_pub(ip=pub.ip) time.sleep( 5.0) # allow time for VK lookups before we start sending things # Send 2 envelopes on 2 different filters pub.send_pub_env(filter=filter1, envelope=env1) pub.send_pub_env(filter=filter2, envelope=env2) self.start()
def publisher(): from cilantro.logger import get_logger from cilantro.utils.test import MPComposer from cilantro.messages.transaction.standard import StandardTransactionBuilder import time, os, sys log = get_logger("Publisher") sub_info = delegates[1] sub_info['ip'] = os.getenv('HOST_IP') d_info = delegates[0] d_info['ip'] = os.getenv('HOST_IP') pub = MPComposer(sk=d_info['sk']) # Publish on this node's own IP pub.add_pub(os.getenv('HOST_IP')) for i in range(100): log.critical("Sending pub") msg = StandardTransactionBuilder.random_tx() time.sleep(0.1) pub.send_pub_msg(filter='0', message=msg) log.critical("Pub Done") sys.exit(0) exit
def subscriber(): from cilantro.logger import get_logger from cilantro.utils.test import MPComposer import time, os, sys log = get_logger("Sub") d_info = delegates[1] d_info['ip'] = os.getenv('HOST_IP') pub_info = delegates[0] pub_info['ip'] = os.getenv('HOST_IP') sub = MPComposer(sk=d_info['sk']) sub.add_sub(filter='0', vk=pub_info['vk']) log.critical("Sub sleeping") time.sleep(26) log.critical("Sub done. Exiting.") sys.exit(0) exit
def test_pubsub_1_1_2_mult_filters(self): """ Tests pub/sub 1-1 (one sub one pub) with 2 message each on a different filter """ def configure(composer: Composer): composer.interface.router = MagicMock() return composer def run_assertions(composer: Composer): cb1 = ReactorCommand.create_callback(callback=StateInput.INPUT, envelope=env1) cb2 = ReactorCommand.create_callback(callback=StateInput.INPUT, envelope=env2) composer.interface.router.route_callback.assert_has_calls( [call(cb1), call(cb2)], any_order=True) env1 = random_envelope() env2 = random_envelope() filter1 = FILTERS[0] filter2 = FILTERS[1] sub = MPComposer(config_fn=configure, assert_fn=run_assertions, name='** SUB', sk=sk1) pub = MPComposer(name='++ PUB', sk=sk2) sub.add_sub(url=URL, filter=filter2) sub.add_sub(url=URL, filter=filter1) pub.add_pub(url=URL) time.sleep(0.2) pub.send_pub_env(filter=filter1, envelope=env1) pub.send_pub_env(filter=filter2, envelope=env2) self.start()
def publisher(): SLEEP_TIME = 0.05 MAX_TIME = 10 from cilantro.logger import get_logger, overwrite_logger_level from cilantro.utils.test import MPComposer from cilantro.messages.transaction.contract import ContractTransactionBuilder from cilantro.constants.testnet import TESTNET_DELEGATES import time, os log = get_logger("Publisher") sub_info = TESTNET_DELEGATES[1] sub_info['ip'] = os.getenv('HOST_IP') d_info = TESTNET_DELEGATES[0] d_info['ip'] = os.getenv('HOST_IP') pub = MPComposer(sk=d_info['sk']) # Publish on this node's own IP pub.add_pub(os.getenv('HOST_IP')) log.important( "Starting experiment, sending messages every {} seconds for a total of {} seconds" .format(SLEEP_TIME, MAX_TIME)) elapsed_time = 0 while elapsed_time < MAX_TIME: log.notice("Sending pub") msg = ContractTransactionBuilder.random_currency_tx() pub.send_pub_msg(filter='0', message=msg) time.sleep(SLEEP_TIME) elapsed_time += SLEEP_TIME pub.teardown() log.important("Done with experiment!")
def subscriber(): SLEEP_TIME = 1 MAX_TIME = 10 from cilantro.logger import get_logger, overwrite_logger_level from cilantro.utils.test import MPComposer import time, os log = get_logger("Subscriber") d_info = delegates[1] d_info['ip'] = os.getenv('HOST_IP') pub_info = delegates[0] pub_info['ip'] = os.getenv('HOST_IP') sub = MPComposer(sk=d_info['sk']) sub.add_sub(filter='0', vk=pub_info['vk']) log.critical( "Starting Subscriber, and exiting after {} seconds".format(SLEEP_TIME)) time.sleep(MAX_TIME) sub.teardown() log.critical("Done with experiment!")
def subscriber(): MAX_TIME = 90 from cilantro.logger import get_logger, overwrite_logger_level from cilantro.utils.test import MPComposer from cilantro.constants.testnet import TESTNET_DELEGATES import time, os log = get_logger("Subscriber") d_info = TESTNET_DELEGATES[1] d_info['ip'] = os.getenv('HOST_IP') pub_info = TESTNET_DELEGATES[0] pub_info['ip'] = os.getenv('HOST_IP') sub = MPComposer(sk=d_info['sk']) sub.add_sub(filter='0', vk=pub_info['vk']) log.important2( "Starting Subscriber, and exiting after {} seconds".format(MAX_TIME)) time.sleep(MAX_TIME) sub.teardown() log.important2("Done with experiment!")
def test_pubsub_n_1_n_removesub(self): """ Tests pub/sub n-1, with a sub removing a publisher after its first message """ def configure(composer: Composer): from unittest.mock import MagicMock composer.manager.router.route_callback = MagicMock() return composer def assert_sub(composer: Composer): from cilantro.messages.reactor.reactor_command import ReactorCommand from cilantro.protocol.states.decorators import StateInput from unittest.mock import call callback1 = ReactorCommand.create_callback( callback=StateInput.INPUT, envelope=env1) callback2 = ReactorCommand.create_callback( callback=StateInput.INPUT, envelope=env2) calls = [call(callback1), call(callback2)] call_args = composer.manager.router.route_callback.call_args_list composer.manager.router.route_callback.assert_has_calls( calls, any_order=True) env1 = random_envelope() env2 = random_envelope() env3 = random_envelope() sub = MPComposer(config_fn=configure, assert_fn=assert_sub, name='SUB [MN1]', sk=sk1) pub1 = MPComposer(name='PUB 1 [Delegate1]', sk=sk2) pub2 = MPComposer(name='PUB 2 [Delegate2]', sk=sk3) sub.add_sub(vk=vk2, filter=FILTER) # sub to pub1 sub.add_sub(vk=vk3, filter=FILTER) # sub to pub2 pub1.add_pub(ip=pub1.ip) # Pub on its own URL pub2.add_pub(ip=pub2.ip) # Pub on its own URL time.sleep(5.0) pub1.send_pub_env(filter=FILTER, envelope=env1) pub2.send_pub_env(filter=FILTER, envelope=env2) time.sleep(1.0) # allow messages to go through sub.remove_sub(vk=vk3) # unsub to pub2 time.sleep(1.0) # allow remove_sub_url command to go through pub2.send_pub_env( filter=FILTER, envelope=env3 ) # this should not be recv by sub, as he removed this guy's url time.sleep( 5.0 ) # allow messages to go through before we start checking assertions self.start()
def test_pubsub_n_1_n_removesub(self): """ Tests pub/sub n-1, with a sub removing a publisher after its first message """ def configure(composer: Composer): composer.interface.router.route_callback = MagicMock() return composer def assert_sub(composer: Composer): callback1 = ReactorCommand.create_callback( callback=StateInput.INPUT, envelope=env1) callback2 = ReactorCommand.create_callback( callback=StateInput.INPUT, envelope=env2) calls = [call(callback1), call(callback2)] # i = 10 / 0 call_args = composer.interface.router.route_callback.call_args_list assert len(call_args) == 2, "route_callback should be called exactly twice, not {} times with {}"\ .format(len(call_args), call_args) composer.interface.router.route_callback.assert_has_calls( calls, any_order=True) env1 = random_envelope() env2 = random_envelope() env3 = random_envelope() sub = MPComposer(config_fn=configure, assert_fn=assert_sub, name='** SUB', sk=sk1) pub1 = MPComposer(name='++ PUB 1', sk=sk2) pub2 = MPComposer(name='++ PUB 2', sk=sk3) sub.add_sub(url=URLS[0], filter=FILTER) # sub to pub1 sub.add_sub(url=URLS[1], filter=FILTER) # sub to pub2 pub1.add_pub(url=URLS[0]) pub2.add_pub(url=URLS[1]) time.sleep(0.2) pub1.send_pub_env(filter=FILTER, envelope=env1) pub2.send_pub_env(filter=FILTER, envelope=env2) time.sleep(0.1) # allow messages to go through sub.remove_sub_url(url=URLS[1]) # unsub to pub2 time.sleep(0.1) # allow remove_sub_url command to go through pub2.send_pub_env( filter=FILTER, envelope=env3 ) # this should not be recv by sub, as he removed this guy's url time.sleep( 0.2 ) # allow messages to go through before we start checking assertions self.start()
def test_req_reply_1_1_1(self): """ Tests request/reply 1_1_1 """ def config_router(composer: Composer): def reply(*args, **kwargs): # do i need the *args **kwargs ?? composer.send_reply(message=reply_msg, request_envelope=request_env) composer.interface.router = MagicMock() composer.interface.router.route_callback.side_effect = reply return composer def config_dealer(composer: Composer): composer.interface.router = MagicMock() return composer def assert_dealer(composer: Composer): args = composer.interface.router.route_callback.call_args_list assert len( args ) == 1, "dealer's route_callback should of only been called once (with the reply env)" call = args[0] callback_cmd = call[0][0] assert isinstance( callback_cmd, ReactorCommand ), "arg of route_callback should be a ReactorCommand" assert callback_cmd.envelope.message == reply_msg, "Callback's envelope's message should be the reply_msg" def assert_router(composer: Composer): cb = ReactorCommand.create_callback(callback=StateInput.REQUEST, envelope=request_env, header=dealer_id) composer.interface.router.route_callback.assert_called_once_with( cb) dealer_id = vk1 dealer_sk = sk1 router_sk = sk2 router_url = URLS[1] request_env = random_envelope(sk=dealer_sk) reply_msg = random_msg() dealer = MPComposer(name='DEALER', sk=sk1, config_fn=config_dealer, assert_fn=assert_dealer) router = MPComposer(config_fn=config_router, assert_fn=assert_router, name='ROUTER', sk=router_sk) dealer.add_dealer(url=router_url) router.add_router(url=router_url) time.sleep(0.2) dealer.send_request_env(url=router_url, envelope=request_env) self.start()
def test_req_reply_1_1_1(self): """ Tests request/reply 1_1_1 """ def config_router(composer: Composer): from unittest.mock import MagicMock def reply(*args, **kwargs): # do i need the *args **kwargs ?? composer.send_reply(message=reply_msg, request_envelope=request_env) composer.manager.router = MagicMock() composer.manager.router.route_callback.side_effect = reply return composer def config_dealer(composer: Composer): from unittest.mock import MagicMock composer.manager.router = MagicMock() return composer def assert_dealer(composer: Composer): from cilantro.messages.reactor.reactor_command import ReactorCommand args = composer.manager.router.route_callback.call_args_list # assert len(args) == 1, "dealer's route_callback should of only been called once (with the reply env)" reply_callback_found = False for call in args: callback_cmd = call[0][0] assert isinstance( callback_cmd, ReactorCommand ), "arg of route_callback should be a ReactorCommand" if callback_cmd.envelope and callback_cmd.envelope.message == reply_msg: reply_callback_found = True break # assert callback_cmd.envelope.message == reply_msg, "Callback's envelope's message should be the reply_msg" assert reply_callback_found, "Reply callback {} not found in call args {}".format( reply_msg, args) def assert_router(composer: Composer): from cilantro.protocol.states.decorators import StateInput from cilantro.messages.reactor.reactor_command import ReactorCommand cb = ReactorCommand.create_callback(callback=StateInput.REQUEST, envelope=request_env, header=dealer_id) composer.manager.router.route_callback.assert_called_with(cb) dealer_id = vk1 dealer_sk = sk1 router_sk = sk2 router_vk = vk2 request_env = random_envelope(sk=dealer_sk) reply_msg = random_msg() dealer = MPComposer(name='DEALER', sk=sk1, config_fn=config_dealer, assert_fn=assert_dealer) router = MPComposer(config_fn=config_router, assert_fn=assert_router, name='ROUTER', sk=router_sk) dealer.add_dealer(vk=router_vk) router.add_router(vk=router_vk) time.sleep(5.0) dealer.send_request_env(vk=router_vk, envelope=request_env) self.start()
def test_pubsub_1_1_1_with_unauth_sub(self): """ Tests pub/sub 1-1 (one sub one pub) with one message, and one unauthorized veriying key """ def config_sub(composer: Composer): from unittest.mock import MagicMock composer.manager.router = MagicMock() return composer def assert_good_sub(composer: Composer): from cilantro.messages.reactor.reactor_command import ReactorCommand from cilantro.protocol.states.decorators import StateInput cb = ReactorCommand.create_callback(callback=StateInput.INPUT, envelope=env) composer.manager.router.route_callback.assert_called_with(cb) def assert_bad_sub(composer: Composer): from cilantro.messages.reactor.reactor_command import ReactorCommand from cilantro.protocol.states.decorators import StateInput from unittest.mock import call cb = call( ReactorCommand.create_callback(callback=StateInput.INPUT, envelope=env)) assert cb not in composer.manager.router.route_callback.call_args_list env = random_envelope() evil_env = random_envelope() sub = MPComposer(config_fn=config_sub, assert_fn=assert_good_sub, name='** [MN1] SUB', sk=sk1) pub = MPComposer(name='++ [Delegate1] PUB', sk=sk2) no_auth_sub = MPComposer(name='++ [Mr. Evil] SUB', config_fn=config_sub, assert_fn=assert_bad_sub, sk=sk_sketch) sub.add_sub(vk=vk2, filter=FILTER) no_auth_sub.add_sub(vk=vk2, filter=FILTER) pub.add_pub(ip=pub.ip) time.sleep(3.0) # allow add pub/add sub to go through pub.send_pub_env(filter=FILTER, envelope=env) time.sleep(3.0) # allow PUB envelopes to go through self.start()
def test_pubsub_n_1_n(self): """ Tests pub/sub with 2 pubs, 1 sub, and multiple messages and the same filter """ def config_sub(composer: Composer): from unittest.mock import MagicMock composer.manager.router = MagicMock() return composer def assert_sub(composer: Composer): from cilantro.messages.reactor.reactor_command import ReactorCommand from cilantro.protocol.states.decorators import StateInput from unittest.mock import call expected_calls = [] for env in envs: callback = ReactorCommand.create_callback( callback=StateInput.INPUT, envelope=env) expected_calls.append(call(callback)) call_args = composer.manager.router.route_callback.call_args_list composer.manager.router.route_callback.assert_has_calls( expected_calls, any_order=True) envs = [random_envelope() for _ in range(4)] sub = MPComposer(config_fn=config_sub, assert_fn=assert_sub, name='[MN1] SUB', sk=sk1) pub1 = MPComposer(name='[Delegate1] PUB1', sk=sk2) pub2 = MPComposer(name='[Delegate2] PUB2', sk=sk3) sub.add_sub(vk=vk2, filter=FILTER) sub.add_sub(vk=vk3, filter=FILTER) pub1.add_pub(ip=pub1.ip) pub2.add_pub(ip=pub2.ip) time.sleep(5.0) pub1.send_pub_env(filter=FILTER, envelope=envs[0]) pub1.send_pub_env(filter=FILTER, envelope=envs[1]) pub2.send_pub_env(filter=FILTER, envelope=envs[2]) pub2.send_pub_env(filter=FILTER, envelope=envs[3]) self.start()
def test_pubsub_1_1_1_with_unauth_pub(self): """ Tests pub/sub 1-1 (one sub one pub) with one message, and one unauthorized veriying key """ def config_sub(composer: Composer): from unittest.mock import MagicMock composer.manager.router = MagicMock() return composer def assert_sub(composer: Composer): from cilantro.messages.reactor.reactor_command import ReactorCommand from cilantro.protocol.states.decorators import StateInput from unittest.mock import call # cb = ReactorCommand.create_callback(callback=StateInput.INPUT, envelope=env) # composer.interface.router.route_callback.assert_called_once_with(cb) expected_cb = call( ReactorCommand.create_callback(callback=StateInput.INPUT, envelope=env)) unexpected_cb = call( ReactorCommand.create_callback( callback=StateInput.LOOKUP_FAILED, envelope=evil_env)) call_args = composer.manager.router.route_callback.call_args_list # # DEBUG STUFF # from cilantro.logger.base import get_logger # l = get_logger("assert sub") # l.debug('EXPECTED') # l.critical(expected_cb) # l.debug('UNEXPECTED') # l.critical(unexpected_cb) # l.important2("got dat call args: {}".format(call_args)) # # END DEBUG STUFF # composer.interface.router.route_callback.assert_has_calls([expected_cb], any_order=True) assert expected_cb in call_args, "Expected callback {} to be in call_args {}".format( expected_cb, call_args) assert unexpected_cb not in call_args, "Did not expect callback {} to be in call_args {}".format( unexpected_cb, call_args) # assert len(call_args) == 2, "route_callback should be called exactly twice, not {} times with {}"\ # .format(len(call_args), call_args) # composer.interface.router.route_callback.assert_has_calls(calls, any_order=True) env = random_envelope() evil_env = random_envelope() sub = MPComposer(config_fn=config_sub, assert_fn=assert_sub, name='** [MN1] SUB', sk=sk1) pub = MPComposer(name='++ [Delegate1] PUB', sk=sk2) no_auth_pub = MPComposer(name='++ [Mr. Evil] PUB', sk=sk_sketch) sub.add_sub(vk=vk2, filter=FILTER) sub.add_sub(vk=vk_sketch, filter=FILTER) pub.add_pub(ip=pub.ip) no_auth_pub.add_pub(ip=no_auth_pub.ip) time.sleep(3.0) pub.send_pub_env(filter=FILTER, envelope=env) no_auth_pub.send_pub_env(filter=FILTER, envelope=evil_env) time.sleep(3.0) # allow PUB envelopes to go through self.start()