def setUp(self): self.context = Context() self.ears = Queue() self.fan = Queue() self.space = SparkSpace(context=self.context, ears=self.ears, fan=self.fan)
def test_concurrency(self): def worker(id, context): for i in range(4): r = random.random() time.sleep(r) value = context.increment('gauge') logging.info('worker %d:counter=%d' % (id, value)) logging.info('worker %d:done' % id) logging.info('Creating a counter') self.counter = Context() logging.info('Launching incrementing workers') workers = [] for i in range(4): p = Process(target=worker, args=( i, self.counter, )) p.start() workers.append(p) logging.info('Waiting for worker threads') for p in workers: p.join() logging.info('Counter: %d' % self.counter.get('gauge')) self.assertEqual(self.counter.get('gauge'), 16)
def test_notify(self): r = Notifier(Context()) self.assertEqual(r.route, '/notify') self.assertTrue(r.queue is not None) self.assertEqual(r.notification, None) with self.assertRaises(Exception): r.get() queue = Queue() r = Notifier(Context(), queue=queue, route='/test') self.assertEqual(r.queue, queue) self.assertEqual(r.notification, None) self.assertEqual(r.get(), 'OK') self.assertEqual(queue.get(), '/test') queue = Queue() r = Notifier(Context(), queue=queue, notification='signal') self.assertEqual(r.queue, queue) self.assertEqual(r.notification, 'signal') self.assertEqual(r.get(), 'OK') self.assertEqual(queue.get(), 'signal') self.assertEqual(r.post(), 'OK') self.assertEqual(queue.get(), 'signal') self.assertEqual(r.put(), 'OK') self.assertEqual(queue.get(), 'signal') self.assertEqual(r.delete(), 'OK') self.assertEqual(queue.get(), 'signal')
def test_wrapper(self): r = Wrapper(Context()) with self.assertRaises(AttributeError): r.get() with self.assertRaises(AttributeError): r.post() with self.assertRaises(AttributeError): r.put() with self.assertRaises(AttributeError): r.delete() def hook(): return 'hello' def hook_patched(): return 'world' r = Wrapper(callable=hook, route='/wrapped') self.assertEqual(r.route, '/wrapped') self.assertTrue(r.callable is not None) self.assertEqual(r.get(), 'hello') self.assertEqual(r.post(), 'hello') self.assertEqual(r.put(), 'hello') self.assertEqual(r.delete(), 'hello') r.callable = hook_patched self.assertEqual(r.get(), 'world') self.assertEqual(r.post(), 'world') self.assertEqual(r.put(), 'world') self.assertEqual(r.delete(), 'world') context = Context() class Callable(object): def __init__(self, context): self.context = context def hook(self, **kwargs): self.context.set('signal', 'wrapped!') return 'OK' callable = Callable(context) r = Wrapper(context=context, callable=callable.hook, route='/wrapped') self.assertEqual(r.route, '/wrapped') self.assertEqual(r.callable, callable.hook) self.assertEqual(context.get('signal'), None) self.assertEqual(r.get(), 'OK') self.assertEqual(r.post(), 'OK') self.assertEqual(r.put(), 'OK') self.assertEqual(r.delete(), 'OK') self.assertEqual(context.get('signal'), 'wrapped!')
def test_text(self): r = Text(Context()) self.assertEqual(r.route, '/') self.assertEqual(r.page, None) self.assertEqual(r.get(), 'OK') r = Text(Context(), route='/hello', page='Hello world') self.assertEqual(r.route, '/hello') self.assertEqual(r.page, 'Hello world') self.assertEqual(r.get(), 'Hello world')
def test_init(self): settings = { 'bot': { 'name': 'testy', 'version': '17.4.1' }, } self.context = Context(settings) self.assertEqual(self.context.get('bot.name'), 'testy') self.assertEqual(self.context.get('bot.version'), '17.4.1')
def setUp(self): self.context = Context() self.engine = Engine(context=self.context, ears=Queue(), mouth=Queue()) self.engine.bus = Bus(self.context) self.engine.bus.check() self.engine.publisher = self.engine.bus.publish() self.space = LocalSpace(context=self.context, ears=self.engine.ears) self.store = MemoryStore(context=self.context) self.bot = ShellBot(engine=self.engine, space=self.space, store=self.store) self.channel = Channel({'id': '*id', 'title': '*title'})
def test_configuration(self): logging.info('*** Configuration test ***') settings = { 'server': { 'binding': '1.2.3.4', 'port': 8888, 'debug': True, }, } server = Server(context=my_context) self.assertEqual(server.context.get('server.binding'), None) self.assertEqual(server.context.get('server.port'), None) self.assertEqual(server.context.get('server.debug'), None) server.configure(settings) self.assertEqual(server.context.get('server.binding'), '1.2.3.4') self.assertEqual(server.context.get('server.port'), 8888) self.assertEqual(server.context.get('server.debug'), True) context = Context(settings) server = Server(context=context) self.assertEqual(server.context.get('server.binding'), '1.2.3.4') self.assertEqual(server.context.get('server.port'), 8888) self.assertEqual(server.context.get('server.debug'), True)
def test_init(self): logging.info('*** init ***') settings = { 'localized': { 'hello world': "What'up, Doc?", 'another string': 'Bye!', }, 'space': { 'title': 'space name', 'participants': ['*****@*****.**'], }, 'server': { 'url': 'http://to.no.where', 'hook': '/hook', 'binding': '0.0.0.0', 'port': 8080, }, } context = Context(settings) my_localization = Localization(context) self.assertEqual(my_localization.context, context) self.assertEqual(my_localization._('hello world'), "What'up, Doc?") self.assertEqual(my_localization._('not localized'), 'not localized') self.assertEqual(my_localization.actual_strings, { 'hello world': "What'up, Doc?", 'not localized': 'not localized' })
def test_load_commands_via_configure(self): logging.info('***** load_commands via configure') settings = { 'shell': {'commands': ['shellbot.commands.help', 'shellbot.commands.noop']}, 'localized': { 'help': 'aide', }, } context=Context(settings) l10n.set_context(context) shell = Shell(engine=self.engine) shell.configure(settings) self.assertEqual( shell.commands, ['*default', '*empty', '*upload', 'aide', 'echo', 'pass', 'sleep', 'version']) l10n.set_context(self.engine.context)
def test_configuration_2(self): logging.info('*** configure 2 ***') settings = { 'bot': { 'on_enter': 'Hello!', 'on_exit': 'Bye!', }, 'space': { 'title': 'Support channel', }, 'server': { 'url': 'http://to.nowhere/', 'trigger': '/trigger', 'hook': '/hook', 'binding': '0.0.0.0', 'port': 8080, }, } clear_env('CHANNEL_DEFAULT_PARTICIPANTS') context = Context(settings) engine = Engine(context=context, configure=True) self.assertEqual(engine.get('bot.on_enter'), 'Hello!') self.assertEqual(engine.get('bot.on_exit'), 'Bye!') self.assertEqual(engine.get('space.title'), 'Support channel') self.assertEqual(engine.get('space.participants'), None) self.assertEqual(engine.get('server.url'), 'http://to.nowhere/') self.assertEqual(engine.get('server.hook'), '/hook') self.assertEqual(engine.get('server.trigger'), '/trigger') self.assertEqual(engine.get('server.binding'), None) self.assertEqual(engine.get('server.port'), 8080)
def setUp(self): self.context = Context(settings=my_settings) self.engine = Engine(context=self.context, mouth=Queue()) self.engine.factory = TodoFactory(self.engine.get('todos.items', [])) self.engine.bus = Bus(self.context) self.engine.bus.check() self.engine.publisher = self.engine.bus.publish() self.bot = self.engine.get_bot()
def setUp(self): self.context = Context() self.engine = Engine(context=self.context, mouth=Queue()) self.space = LocalSpace(context=self.context, ears=self.engine.ears) self.store = MemoryStore(context=self.context) self.machine = MyMachine() self.bot = MyBot(engine=self.engine) self.bot.machine = None
def test_from_base(self): w = ['world'] q = Queue() r = Route(Context(), arg_1='hello', arg_2=w, arg_3=q, route='/ping') self.assertEqual(r.arg_1, 'hello') self.assertEqual(r.arg_2, w) self.assertEqual(r.arg_3, q) self.assertEqual(r.route, '/ping')
def test__filter(self): self.assertEqual(Context._filter(None), None) self.assertEqual(Context._filter(''), '') self.assertEqual(Context._filter('ZLOGQ0OVGlZWU1NmYtyY'), 'ZLOGQ0OVGlZWU1NmYtyY') if os.environ.get('PATH') is not None: self.assertTrue(Context._filter('$PATH') != '$PATH') Context._filter('$TOTALLY*UNKNOWN*HERE') # warning in log
def test_base(self): settings = { u'hello': u'world', } context = Context(settings) r = Route(context) self.assertEqual(r.context.get('hello'), u'world') self.assertEqual(r.route, None) with self.assertRaises(NotImplementedError): r.get() with self.assertRaises(NotImplementedError): r.post() with self.assertRaises(NotImplementedError): r.put() with self.assertRaises(NotImplementedError): r.delete()
class EngineTests(unittest.TestCase): def setUp(self): self.context = Context() self.engine = Engine(context=self.context, mouth=Queue()) self.space = LocalSpace(context=self.context) self.engine.space = self.space def tearDown(self): del self.space del self.engine del self.context collected = gc.collect() if collected: logging.info("Garbage collector: collected %d objects." % (collected)) def test_init(self): logging.info('*** init ***') engine = Engine(context=self.context) self.assertEqual(engine.context, self.context) self.assertTrue(engine.mouth is None) self.assertTrue(engine.speaker is not None) self.assertTrue(engine.ears is None) self.assertTrue(engine.listener is not None) self.assertTrue(engine.fan is None) self.assertTrue(engine.observer is not None) self.assertTrue(engine.registered is not None) self.assertEqual(engine.bots, {}) self.assertFalse(engine.space is None) self.assertTrue(engine.server is None) self.assertTrue(engine.shell is not None) self.assertEqual(engine.driver, ShellBot) self.assertEqual(engine.machine_factory, None) self.assertEqual(engine.updater_factory, None) del engine engine = Engine(context=self.context, type='local', mouth='m', ears='e', fan='f') self.assertEqual(engine.context, self.context) self.assertEqual(engine.mouth, 'm') self.assertTrue(engine.speaker is not None) self.assertEqual(engine.ears, 'e') self.assertTrue(engine.listener is not None) self.assertEqual(engine.fan, 'f') self.assertTrue(engine.observer is not None) self.assertTrue(engine.registered is not None) self.assertEqual(engine.bots, {}) self.assertTrue(engine.space is not None) self.assertTrue(engine.server is None) self.assertTrue(engine.shell is not None) self.assertEqual(engine.driver, ShellBot) self.assertEqual(engine.machine_factory, None) self.assertEqual(engine.updater_factory, None) del engine engine = Engine(context=self.context, space=self.space, mouth='m', ears='e', fan='f') self.assertEqual(engine.context, self.context) self.assertEqual(engine.mouth, 'm') self.assertTrue(engine.speaker is not None) self.assertEqual(engine.ears, 'e') self.assertTrue(engine.listener is not None) self.assertEqual(engine.fan, 'f') self.assertTrue(engine.observer is not None) self.assertTrue(engine.registered is not None) self.assertEqual(engine.bots, {}) self.assertEqual(engine.space, self.space) self.assertTrue(engine.server is None) self.assertTrue(engine.shell is not None) self.assertEqual(engine.driver, ShellBot) self.assertEqual(engine.machine_factory, None) self.assertEqual(engine.updater_factory, None) del engine engine = Engine( context=self.context, driver=FakeBot, machine_factory=MachineFactory, updater_factory=MyUpdaterFactory, ) self.assertEqual(engine.context, self.context) self.assertEqual(engine.mouth, None) self.assertTrue(engine.speaker is not None) self.assertEqual(engine.ears, None) self.assertTrue(engine.listener is not None) self.assertTrue(engine.fan is None) self.assertTrue(engine.observer is not None) self.assertTrue(engine.registered is not None) self.assertEqual(engine.bots, {}) self.assertTrue(engine.space is not None) self.assertTrue(engine.server is None) self.assertTrue(engine.shell is not None) self.assertEqual(engine.driver, FakeBot) self.assertEqual(engine.machine_factory, MachineFactory) self.assertEqual(engine.updater_factory, MyUpdaterFactory) self.context.apply({ 'bot': { 'name': 'testy', 'version': '17.4.1' }, }) engine = Engine(context=self.context) self.assertEqual(engine.name, 'testy') self.assertEqual(engine.version, '17.4.1') del engine def test_configure(self): logging.info('*** configure ***') self.engine.configure({}) self.assertEqual(self.engine.space.ears, self.engine.ears) self.assertTrue(self.engine.list_factory is not None) self.engine.context.clear() settings = { 'bot': { 'on_enter': 'Hello!', 'on_exit': 'Bye!', }, 'localized': { 'hello world': "What'up, Doc?", 'another string': 'Bye!', }, 'space': { 'title': 'space name', 'participants': ['*****@*****.**'], }, 'server': { 'url': 'http://to.no.where', 'hook': '/hook', 'binding': '0.0.0.0', 'port': 8080, }, } self.engine.configure(settings) self.assertEqual(self.engine.get('bot.on_enter'), 'Hello!') self.assertEqual(self.engine.get('bot.on_exit'), 'Bye!') self.assertEqual(self.engine.get('space.title'), 'space name') self.assertEqual(self.engine.get('space.participants'), ['*****@*****.**']) self.assertEqual(self.engine.get('server.url'), 'http://to.no.where') self.assertEqual(self.engine.get('server.hook'), '/hook') self.assertEqual(_('hello world'), "What'up, Doc?") self.assertEqual(_('not localized'), 'not localized') self.engine.context.clear() self.engine.configure_from_path( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_settings', 'regular.yaml')) self.assertEqual(self.engine.get('bot.on_enter'), 'How can I help you?') self.assertEqual(self.engine.get('bot.on_exit'), 'Bye for now') self.assertEqual(self.engine.get('space.title'), 'Support channel') self.assertEqual(self.engine.get('space.participants'), ['*****@*****.**', '*****@*****.**']) self.assertEqual(self.engine.get('server.url'), None) self.assertEqual(self.engine.get('server.hook'), None) self.assertEqual(self.engine.get('server.binding'), None) self.assertEqual(self.engine.get('server.port'), None) items = [x for x in self.engine.list_factory.get_list('SupportTeam')] self.assertEqual(items, ['*****@*****.**', '*****@*****.**']) items = [x for x in self.engine.list_factory.get_list('*unknown*list')] self.assertEqual(items, []) names = self.engine.list_factory.list_commands() self.assertEqual(sorted(names), ['SupportTeam']) def test_configuration_2(self): logging.info('*** configure 2 ***') settings = { 'bot': { 'on_enter': 'Hello!', 'on_exit': 'Bye!', }, 'space': { 'title': 'Support channel', }, 'server': { 'url': 'http://to.nowhere/', 'trigger': '/trigger', 'hook': '/hook', 'binding': '0.0.0.0', 'port': 8080, }, } clear_env('CHANNEL_DEFAULT_PARTICIPANTS') context = Context(settings) engine = Engine(context=context, configure=True) self.assertEqual(engine.get('bot.on_enter'), 'Hello!') self.assertEqual(engine.get('bot.on_exit'), 'Bye!') self.assertEqual(engine.get('space.title'), 'Support channel') self.assertEqual(engine.get('space.participants'), None) self.assertEqual(engine.get('server.url'), 'http://to.nowhere/') self.assertEqual(engine.get('server.hook'), '/hook') self.assertEqual(engine.get('server.trigger'), '/trigger') self.assertEqual(engine.get('server.binding'), None) self.assertEqual(engine.get('server.port'), 8080) def test_configure_default(self): logging.info('*** configure with default values ***') clear_env("BOT_BANNER_TEXT") clear_env("BOT_BANNER_CONTENT") clear_env("BOT_BANNER_FILE") clear_env("BOT_ON_ENTER") clear_env("BOT_ON_EXIT") clear_env("CHAT_ROOM_TITLE") clear_env("CHANNEL_DEFAULT_PARTICIPANTS") clear_env("CISCO_SPARK_BOT_TOKEN") clear_env("SERVER_URL") self.engine.configure() # logging.debug(self.engine.context.values) self.assertEqual(self.engine.get('bot.banner.text'), None) self.assertEqual(self.engine.get('bot.banner.content'), None) self.assertEqual(self.engine.get('bot.banner.file'), None) self.assertEqual(self.engine.get('bot.on_enter'), None) self.assertEqual(self.engine.get('bot.on_exit'), None) self.assertEqual(self.engine.get('space.title'), 'Collaboration space') self.assertEqual(self.engine.get('space.participants'), None) self.assertEqual(self.engine.get('space.unknown'), None) self.assertEqual(self.engine.get('server.url'), '$SERVER_URL') self.assertEqual(self.engine.get('server.hook'), '/hook') self.assertEqual(self.engine.get('server.binding'), None) self.assertEqual(self.engine.get('server.port'), 8080) self.assertEqual(self.engine.space.ears, self.engine.ears) self.assertTrue(self.engine.bus is not None) self.assertTrue(self.engine.publisher is not None) def test_configure_environment(self): logging.info('*** configure from the environment ***') os.environ["BOT_BANNER_TEXT"] = 'some text' os.environ["BOT_BANNER_CONTENT"] = 'some content' os.environ["BOT_BANNER_FILE"] = 'some link' os.environ["BOT_ON_ENTER"] = 'Hello!' os.environ["BOT_ON_EXIT"] = 'Bye!' os.environ["CHAT_ROOM_TITLE"] = 'Support channel' os.environ["CHANNEL_DEFAULT_PARTICIPANTS"] = '*****@*****.**' os.environ["CISCO_SPARK_BOT_TOKEN"] = '*token' os.environ["SERVER_URL"] = 'http://to.nowhere/' self.engine.configure() # logging.debug(self.engine.context.values) self.assertEqual(self.engine.get('bot.banner.text'), 'some text') self.assertEqual(self.engine.get('bot.banner.content'), 'some content') self.assertEqual(self.engine.get('bot.banner.file'), 'some link') self.assertEqual(self.engine.get('bot.on_enter'), 'Hello!') self.assertEqual(self.engine.get('bot.on_exit'), 'Bye!') self.assertEqual(self.engine.get('space.title'), 'Support channel') self.assertEqual(self.engine.get('space.participants'), '*****@*****.**') self.assertEqual(self.engine.get('space.unknown'), None) self.assertEqual(self.engine.get('server.url'), '$SERVER_URL') self.assertEqual(self.engine.get('server.hook'), '/hook') self.assertEqual(self.engine.get('server.binding'), None) self.assertEqual(self.engine.get('server.port'), 8080) def test_get(self): logging.info('*** get ***') os.environ["BOT_ON_ENTER"] = 'Hello!' os.environ["BOT_ON_EXIT"] = 'Bye!' os.environ["CHAT_ROOM_TITLE"] = 'Support channel' os.environ["CHANNEL_DEFAULT_PARTICIPANTS"] = '*****@*****.**' os.environ["CISCO_SPARK_BOT_TOKEN"] = '*token' os.environ["SERVER_URL"] = 'http://to.nowhere/' settings = { 'bot': { 'on_enter': 'Hello!', 'on_exit': 'Bye!', }, 'space': { 'title': '$CHAT_ROOM_TITLE', }, 'server': { 'url': '$SERVER_URL', 'hook': '/hook', 'binding': '0.0.0.0', 'port': 8080, }, } self.engine.configure(settings=settings) self.assertEqual(self.engine.get('bot.on_enter'), 'Hello!') self.assertEqual(self.engine.get('bot.on_exit'), 'Bye!') self.assertEqual(self.engine.get('space.title'), 'Support channel') self.assertEqual(self.engine.get('space.participants'), '*****@*****.**') self.assertEqual(self.engine.get('space.unknown'), None) self.assertEqual(self.engine.get('server.url'), 'http://to.nowhere/') self.assertEqual(self.engine.get('server.hook'), '/hook') self.assertEqual(self.engine.get('server.binding'), None) self.assertEqual(self.engine.get('server.port'), 8080) def test_set(self): logging.info('*** set ***') self.engine.set('hello', 'world') self.assertEqual(self.engine.get('hello'), 'world') self.assertEqual(self.engine.get(u'hello'), 'world') self.engine.set('hello', u'wôrld') self.assertEqual(self.engine.get('hello'), u'wôrld') self.engine.set(u'hello', u'wôrld') self.assertEqual(self.engine.get(u'hello'), u'wôrld') def test_name(self): logging.info('*** name ***') self.assertEqual(self.engine.name, 'Shelly') def test_version(self): logging.info('*** version ***') self.assertEqual(self.engine.version, '*unknown*') def test_register(self): logging.info('*** register ***') with self.assertRaises(AttributeError): self.engine.register('*unknown*event', lambda: 'ok') with self.assertRaises(AttributeError): self.engine.register('bond', lambda: 'ok') with self.assertRaises(AttributeError): self.engine.register('dispose', lambda: 'ok') counter = MyCounter('counter #1') with self.assertRaises(AssertionError): self.engine.register(None, counter) with self.assertRaises(AssertionError): self.engine.register('', counter) with self.assertRaises(AssertionError): self.engine.register(1.2, counter) self.engine.register('bond', counter) self.engine.register('dispose', counter) with self.assertRaises(AttributeError): self.engine.register('start', counter) with self.assertRaises(AttributeError): self.engine.register('stop', counter) with self.assertRaises(AttributeError): self.engine.register('*unknown*event', counter) self.engine.register('bond', MyCounter('counter #2')) class AllEvents(object): def on_bond(self, bot): pass def on_dispose(self): pass def on_start(self): pass def on_stop(self): pass def on_message(self): pass def on_join(self): pass def on_leave(self): pass def on_enter(self): pass def on_exit(self): pass def on_inbound(self): pass def on_some_custom_event(self): pass all_events = AllEvents() self.engine.register('bond', all_events) self.engine.register('dispose', all_events) self.engine.register('start', all_events) self.engine.register('stop', all_events) self.engine.register('message', all_events) self.engine.register('join', all_events) self.engine.register('leave', all_events) self.engine.register('enter', all_events) self.engine.register('exit', all_events) self.engine.register('inbound', all_events) self.engine.register('some_custom_event', all_events) self.assertEqual(len(self.engine.registered['bond']), 3) self.assertEqual(len(self.engine.registered['dispose']), 2) self.assertEqual(len(self.engine.registered['start']), 1) self.assertEqual(len(self.engine.registered['stop']), 1) self.assertEqual(len(self.engine.registered['message']), 1) self.assertEqual(len(self.engine.registered['join']), 1) self.assertEqual(len(self.engine.registered['leave']), 1) self.assertEqual(len(self.engine.registered['enter']), 1) self.assertEqual(len(self.engine.registered['exit']), 1) self.assertEqual(len(self.engine.registered['inbound']), 1) self.assertEqual(len(self.engine.registered['some_custom_event']), 1) def test_dispatch(self): logging.info('*** dispatch ***') counter = MyCounter('counter #1') self.engine.register('bond', counter) self.engine.register('dispose', counter) self.engine.register('bond', MyCounter('counter #2')) self.engine.register('dispose', MyCounter('counter #3')) class AllEvents(object): def __init__(self): self.events = [] def on_bond(self, bot): self.events.append('bond') def on_dispose(self): self.events.append('dispose') def on_start(self): self.events.append('start') def on_stop(self): self.events.append('stop') def on_message(self, received): assert received == '*void' self.events.append('message') def on_join(self, received): assert received == '*void' self.events.append('join') def on_leave(self, received): assert received == '*void' self.events.append('leave') def on_enter(self, received): assert received == '*void' self.events.append('enter') def on_exit(self, received): assert received == '*void' self.events.append('exit') def on_inbound(self, received): assert received == '*void' self.events.append('inbound') def on_some_custom_event(self, data): assert data == '*data' self.events.append('some_custom_event') all_events = AllEvents() self.engine.register('bond', all_events) self.engine.register('dispose', all_events) self.engine.register('start', all_events) self.engine.register('stop', all_events) self.engine.register('message', all_events) self.engine.register('join', all_events) self.engine.register('leave', all_events) self.engine.register('enter', all_events) self.engine.register('exit', all_events) self.engine.register('inbound', all_events) self.engine.register('some_custom_event', all_events) self.engine.dispatch('bond', bot='*dummy') self.engine.dispatch('dispose') self.engine.dispatch('start') self.engine.dispatch('stop') self.engine.dispatch('message', received='*void') self.engine.dispatch('join', received='*void') self.engine.dispatch('leave', received='*void') self.engine.dispatch('enter', received='*void') self.engine.dispatch('exit', received='*void') self.engine.dispatch('inbound', received='*void') self.engine.dispatch('some_custom_event', data='*data') with self.assertRaises(AssertionError): self.engine.dispatch('*unknown*event') self.assertEqual(counter.count, 2) self.assertEqual(all_events.events, [ 'bond', 'dispose', 'start', 'stop', 'message', 'join', 'leave', 'enter', 'exit', 'inbound', 'some_custom_event' ]) def test_load_commands(self): logging.info('*** load_commands ***') with mock.patch.object(self.engine.shell, 'load_commands', return_value=None) as mocked: self.engine.load_commands(['a', 'b', 'c', 'd']) mocked.assert_called_with(['a', 'b', 'c', 'd']) def test_load_command(self): logging.info('*** load_command ***') with mock.patch.object(self.engine.shell, 'load_command', return_value=None) as mocked: self.engine.load_command('a') mocked.assert_called_with('a') def test_hook(self): logging.info('*** hook ***') self.context.set('server.url', 'http://here.you.go:123') server = mock.Mock() with mock.patch.object(self.engine.space, 'register', return_value=None) as mocked: self.engine.hook(server=server) self.assertFalse(mocked.called) self.context.set('server.binding', '0.0.0.0') self.engine.hook(server=server) mocked.assert_called_with(hook_url='http://here.you.go:123/hook') def test_get_hook(self): logging.info('*** get_hook ***') self.context.set('server.url', 'http://here.you.go:123') self.assertEqual(self.engine.get_hook(), self.engine.space.webhook) def test_run(self): logging.info('*** run ***') engine = Engine(context=self.context) engine.space = LocalSpace(context=self.context) engine.start = mock.Mock() engine.space.run = mock.Mock() engine.run() self.assertTrue(engine.start.called) self.assertTrue(engine.space.run.called) class MyServer(object): def __init__(self, engine): self.engine = engine def add_route(self, route, **kwargs): pass def run(self): self.engine.set("has_been_ran", True) server = MyServer(engine=engine) engine.run(server=server) self.assertTrue(engine.get("has_been_ran")) def test_start(self): logging.info('*** start ***') engine = Engine(context=self.context) engine.space = LocalSpace(context=self.context) engine.start_processes = mock.Mock() engine.on_start = mock.Mock() engine.start() self.assertTrue(engine.ears is not None) self.assertTrue(engine.mouth is not None) self.assertTrue(engine.start_processes.called) self.assertTrue(engine.on_start.called) def test_static(self): logging.info('*** static test ***') self.engine.configure() self.context.set('bus.address', 'tcp://127.0.0.1:6666') self.engine.listener.DEFER_DURATION = 0.0 self.engine.publisher.DEFER_DURATION = 0.0 self.engine.start() self.engine.stop() self.assertEqual(self.engine.get('listener.counter', 0), 0) self.assertEqual(self.engine.get('speaker.counter', 0), 0) def test_bond(self): logging.info("*** bond") self.space.delete = mock.Mock() channel = self.engine.bond(title=None) self.assertEqual(channel.id, '*local') self.assertEqual(channel.title, 'Collaboration space') channel = self.engine.bond(title='') self.assertEqual(channel.id, '*local') self.assertEqual(channel.title, 'Collaboration space') channel = self.engine.bond(title='hello world') self.assertEqual(channel.id, '*local') self.assertEqual(channel.title, 'hello world') self.assertFalse(self.space.delete.called) channel = self.engine.bond(reset=True) self.assertTrue(self.space.delete.called) self.space.add_participants = mock.Mock() self.engine.dispatch = mock.Mock() with mock.patch.object(self.space, 'get_by_title', return_value=None) as mocked: self.engine.bond( title='my title', participants=['c', 'd'], ) mocked.assert_called_with(title='my title') self.space.add_participants.assert_called_with(id='*local', persons=['c', 'd']) self.space.configure( settings={ 'space': { 'title': 'Another title', 'participants': ['*****@*****.**', '*****@*****.**'], } }) with mock.patch.object(self.space, 'get_by_title', return_value=None) as mocked: self.engine.bond() mocked.assert_called_with(title='Another title') self.space.add_participants.assert_called_with( id='*local', persons=['*****@*****.**', '*****@*****.**']) def test_enumerate_bots(self): logging.info('*** enumerate_bots ***') self.engine.bots = { '123': FakeBot(self.engine, '123'), '456': FakeBot(self.engine, '456'), '789': FakeBot(self.engine, '789'), } for bot in self.engine.enumerate_bots(): self.assertTrue(bot.id in ['123', '456', '789']) def test_get_bot(self): logging.info('*** get_bot ***') self.engine.bots = { '123': FakeBot(self.engine, '123'), '456': FakeBot(self.engine, '456'), '789': FakeBot(self.engine, '789'), } bot = self.engine.get_bot('123') self.assertEqual(bot.id, '123') self.assertEqual(bot, self.engine.bots['123']) bot = self.engine.get_bot('456') self.assertEqual(bot.id, '456') self.assertEqual(bot, self.engine.bots['456']) bot = self.engine.get_bot('789') self.assertEqual(bot.id, '789') self.assertEqual(bot, self.engine.bots['789']) with mock.patch.object(self.engine, 'build_bot', return_value=FakeBot(self.engine, '*bot')) as mocked: bot = self.engine.get_bot() self.assertEqual(bot.id, '*bot') self.assertTrue('*bot' in self.engine.bots.keys()) def test_build_bot(self): logging.info('*** build_bot ***') self.engine.context.apply(self.engine.DEFAULT_SETTINGS) self.engine.bots = {} bot = self.engine.build_bot('123', FakeBot) self.assertEqual(bot.id, '123') bot.store.remember('a', 'b') self.assertEqual(bot.store.recall('a'), 'b') bot = self.engine.build_bot('456', FakeBot) self.assertEqual(bot.id, '456') bot.store.remember('c', 'd') self.assertEqual(bot.store.recall('a'), None) self.assertEqual(bot.store.recall('c'), 'd') bot = self.engine.build_bot('789', FakeBot) self.assertEqual(bot.id, '789') bot.store.remember('e', 'f') self.assertEqual(bot.store.recall('a'), None) self.assertEqual(bot.store.recall('c'), None) self.assertEqual(bot.store.recall('e'), 'f') def test_on_build(self): logging.info('*** on_build ***') bot = ShellBot(engine=self.engine) self.engine.on_build(bot) def test_build_store(self): logging.info('*** build_store ***') store_1 = self.engine.build_store('123') store_1.append('names', 'Alice') store_1.append('names', 'Bob') self.assertEqual(store_1.recall('names'), ['Alice', 'Bob']) store_2 = self.engine.build_store('456') store_2.append('names', 'Chloe') store_2.append('names', 'David') self.assertEqual(store_2.recall('names'), ['Chloe', 'David']) self.assertEqual(store_1.recall('names'), ['Alice', 'Bob']) store_2.forget() self.assertEqual(store_1.recall('names'), ['Alice', 'Bob']) self.assertEqual(store_2.recall('names'), None) def test_initialize_store(self): logging.info('*** initialize_store ***') settings = {'bot.store': {'planets': ['Uranus', 'Mercury']}} self.engine.context.apply(settings) print(self.engine.get('bot.store')) bot = self.engine.build_bot('123', FakeBot) self.assertEqual(bot.store.recall('planets'), ['Uranus', 'Mercury']) def test_build_machine(self): logging.info('*** build_machine ***') bot = ShellBot(engine=self.engine) machine = self.engine.build_machine(bot) previous = self.engine.machine_factory self.engine.machine_factory = MachineFactory( module='shellbot.machines.base', name='Machine') machine = self.engine.build_machine(bot) self.engine.machine_factory = previous def test_build_updater(self): logging.info('*** build_updater ***') updater = self.engine.build_updater('*id') self.assertEqual(updater, None) self.engine.updater_factory = MyUpdaterFactory() updater = self.engine.build_updater('*id') self.assertEqual(updater.id, '*id')
is_direct = False class MyBot(object): channel = MyChannel() id = '123' def __init__(self, engine): self.engine = engine def say(self, text, content=None, file=None): self.engine.mouth.put(Vibes(text, content, file)) my_context = Context() my_ears = Queue() my_mouth = Queue() my_space = Space(my_context) my_space.post_message = MagicMock() class CompositeTests(unittest.TestCase): def setUp(self): self.engine = MyEngine(context=my_context, ears=my_ears, mouth=my_mouth, space=my_space) self.engine.set( 'bot.id', "Y2lzY29zcGFyazovL3VzL1BFT1BMRS83YWYyZjcyYy0xZDk1LTQxZjAtYTcxNi00MjlmZmNmYmM0ZDg"
def __init__(self, context=None): self.context = context if context else Context() self.lists = {}
#!/usr/bin/env python # -*- coding: utf-8 -*- import json import logging import sys import time from shellbot import Context from shellbot.bus import Bus, Subscriber, Publisher Context.set_logger() # this should be ran manually for test purpose # you can run multiple instances of this program and see message replication # done by ZeroMQ bus = Bus(context=Context()) bus.check() subscriber = bus.subscribe(['topic_A', 'topic_B']) logging.info("Waiting for messages (non-blocking mode)") while True: time.sleep(0.01) message = subscriber.get() if message: logging.info("- receiving: {}".format(message)) if isinstance(message, dict): logging.info("- visible keys: {}".format(message.keys()))
class BotTests(unittest.TestCase): def setUp(self): self.context = Context() self.engine = Engine(context=self.context, ears=Queue(), mouth=Queue()) self.engine.bus = Bus(self.context) self.engine.bus.check() self.engine.publisher = self.engine.bus.publish() self.space = LocalSpace(context=self.context, ears=self.engine.ears) self.store = MemoryStore(context=self.context) self.bot = ShellBot(engine=self.engine, space=self.space, store=self.store) self.channel = Channel({'id': '*id', 'title': '*title'}) def tearDown(self): del self.channel del self.bot del self.store del self.space del self.engine.publisher del self.engine.bus del self.engine del self.context collected = gc.collect() if collected: logging.info("Garbage collector: collected %d objects." % (collected)) def test_init(self): logging.info('*** init ***') bot = ShellBot(engine=self.engine) self.assertEqual(bot.engine, self.engine) self.assertTrue(bot.space is not None) self.assertTrue(bot.channel is None) self.assertFalse(bot.store is None) self.assertFalse(bot.fan is None) self.assertTrue(bot.machine is None) bot = ShellBot(engine=self.engine, space=self.space, store=self.store, fan='f') self.assertEqual(bot.engine, self.engine) self.assertEqual(bot.space, self.space) self.assertEqual(bot.store, self.store) self.assertEqual(bot.fan, 'f') def test_on_init(self): logging.info('*** on_init ***') bot = ShellBot(engine=self.engine, fan='f') bot.on_init() def test_is_ready(self): logging.info("*** is_ready") self.bot.channel = None self.assertFalse(self.bot.is_ready) self.bot.channel = self.channel self.assertTrue(self.bot.is_ready) def test_id(self): logging.info("*** id") self.bot.channel = None self.assertEqual(self.bot.id, None) self.bot.channel = self.channel self.assertEqual(self.bot.id, '*id') def test_title(self): logging.info("*** title") self.bot.channel = None self.assertEqual(self.bot.title, None) self.bot.channel = self.channel self.assertEqual(self.bot.title, '*title') def test_reset(self): logging.info("*** reset") self.bot.channel = self.channel self.bot.reset() self.assertEqual(self.bot.channel, None) def test_on_reset(self): logging.info("*** on_reset") self.bot.on_reset() def test_bond(self): logging.info("*** bond") self.bot.channel = self.channel self.bot.bond() def test_on_bond(self): logging.info("*** on_bond") self.bot.on_bond() def test_on_enter(self): logging.info("*** on_enter") self.bot.on_enter() def test_dispose(self): logging.info("*** dispose") self.engine.dispatch = mock.Mock() self.space.delete = mock.Mock() self.bot.dispose() self.assertFalse(self.engine.dispatch.called) self.assertFalse(self.space.delete.called) self.bot.channel = self.channel self.bot.dispose() self.assertTrue(self.engine.dispatch.called) self.assertTrue(self.space.delete.called) self.assertEqual(self.bot.channel, None) def test_on_exit(self): logging.info("*** on_exit") self.bot.on_exit() def test_add_participants(self): logging.info('*** add_participants ***') self.bot.channel = self.channel with mock.patch.object(self.bot.space, 'add_participants', return_value=None) as mocked: self.bot.add_participants(['a', 'b', 'c', 'd']) mocked.assert_called_with(id='*id', persons=['a', 'b', 'c', 'd']) def test_add_participant(self): logging.info('*** add_participant ***') self.bot.channel = self.channel with mock.patch.object(self.bot.space, 'add_participant', return_value=None) as mocked: self.bot.add_participant('*****@*****.**') mocked.assert_called_with(id='*id', is_moderator=False, person='*****@*****.**') def test_remove_participants(self): logging.info('*** remove_participants ***') self.bot.channel = self.channel with mock.patch.object(self.bot.space, 'remove_participants', return_value=None) as mocked: self.bot.remove_participants(['a', 'b', 'c', 'd']) mocked.assert_called_with(id='*id', persons=['a', 'b', 'c', 'd']) def test_remove_participant(self): logging.info('*** remove_participant ***') self.bot.channel = self.channel with mock.patch.object(self.bot.space, 'remove_participant', return_value=None) as mocked: self.bot.remove_participant('*****@*****.**') mocked.assert_called_with(id='*id', person='*****@*****.**') def test_say(self): logging.info('*** say ***') self.bot.say('*not*said*because*not*ready') self.bot.channel = self.channel self.bot.say('') self.bot.say(None) with mock.patch.object(self.engine.mouth, 'put', return_value=None) as mocked: self.bot.say('test') self.bot.say('test', content='test') self.bot.say('test', file='test.yaml') self.bot.say('test', person='*****@*****.**') self.bot.say('test', content='test', person='*****@*****.**') self.bot.say('test', file='test.yaml', person='*****@*****.**') message_0 = None self.bot.say(message_0) with self.assertRaises(Exception): self.engine.mouth.get_nowait() message_0 = '' self.bot.say(message_0) with self.assertRaises(Exception): self.engine.mouth.get_nowait() message_1 = 'hello' self.bot.say(message_1) item = self.engine.mouth.get() self.assertEqual(item.text, message_1) self.assertEqual(item.channel_id, self.bot.id) self.assertEqual(item.person, None) self.bot.say(message_1, person='*****@*****.**') item = self.engine.mouth.get() self.assertEqual(item.text, message_1) self.assertEqual(item.channel_id, None) self.assertEqual(item.person, '*****@*****.**') message_2 = 'world' self.bot.say(message_2) self.assertEqual(self.engine.mouth.get().text, message_2) message_3 = 'hello' content_3 = 'world' self.bot.say(message_3, content=content_3) item = self.engine.mouth.get() self.assertEqual(item.text, message_3) self.assertEqual(item.content, content_3) self.assertEqual(item.file, None) message_4 = "What'sup Doc?" file_4 = 'http://some.server/some/file' self.bot.say(message_4, file=file_4) item = self.engine.mouth.get() self.assertEqual(item.text, message_4) self.assertEqual(item.content, None) self.assertEqual(item.file, file_4) message_5 = 'hello' content_5 = 'world' file_5 = 'http://some.server/some/file' self.bot.say(message_5, content=content_5, file=file_5) item = self.engine.mouth.get() self.assertEqual(item.text, message_5) self.assertEqual(item.content, content_5) self.assertEqual(item.file, file_5) content_6 = 'life is *good*' file_6 = 'http://some.server/some/file' self.bot.say(content=content_6, file=file_6) item = self.engine.mouth.get() self.assertEqual(item.text, None) self.assertEqual(item.content, content_6) self.assertEqual(item.file, file_6) content_7 = 'life is _very_ *good*' self.bot.say(content=content_7) item = self.engine.mouth.get() self.assertEqual(item.text, None) self.assertEqual(item.content, content_7) self.assertEqual(item.file, None) def test_say_banner(self): logging.info("*** say_banner") self.bot.channel = self.channel # banner settings have not been defined at all self.context.set('bot.banner.text', None) self.context.set('bot.banner.content', None) self.context.set('bot.banner.file', None) self.bot.say_banner() with self.assertRaises(Exception): self.engine.mouth.get_nowait() # banner settings are empty strings self.context.set('bot.banner.text', '') self.context.set('bot.banner.content', '') self.context.set('bot.banner.file', '') self.bot.say_banner() with self.assertRaises(Exception): self.engine.mouth.get_nowait() # plain banner with text, rich content, and some document upload self.context.set('bot.banner.text', u"Type '@{} help' for more information") self.context.set('bot.banner.content', u"Type ``@{} help`` for more information") self.context.set('bot.banner.file', "http://on.line.doc/guide.pdf") self.bot.say_banner() item = self.engine.mouth.get() self.assertEqual(item.text, "Type '@Shelly help' for more information") self.assertEqual(item.content, 'Type ``@Shelly help`` for more information') self.assertEqual(item.file, 'http://on.line.doc/guide.pdf') with self.assertRaises(Exception): self.engine.mouth.get_nowait() def test_remember(self): logging.info('***** remember') self.assertEqual(self.bot.recall('sca.lar'), None) self.bot.remember('sca.lar', 'test') self.assertEqual(self.bot.recall('sca.lar'), 'test') self.assertEqual(self.bot.recall('list'), None) self.bot.remember('list', ['hello', 'world']) self.assertEqual(self.bot.recall('list'), ['hello', 'world']) self.assertEqual(self.bot.recall('dict'), None) self.bot.remember('dict', {'hello': 'world'}) self.assertEqual(self.bot.recall('dict'), {'hello': 'world'}) def test_recall(self): logging.info('***** recall') # undefined key self.assertEqual(self.bot.recall('hello'), None) # undefined key with default value whatever = 'whatever' self.assertEqual(self.bot.recall('hello', whatever), whatever) # set the key self.bot.remember('hello', 'world') self.assertEqual(self.bot.recall('hello'), 'world') # default value is meaningless when key has been set self.assertEqual(self.bot.recall('hello', 'whatever'), 'world') # except when set to None self.bot.remember('special', None) self.assertEqual(self.bot.recall('special', []), []) def test_forget(self): logging.info('***** forget') # set the key and then forget it self.bot.remember('hello', 'world') self.assertEqual(self.bot.recall('hello'), 'world') self.bot.forget('hello') self.assertEqual(self.bot.recall('hello'), None) # set multiple keys and then forget all of them self.bot.remember('hello', 'world') self.bot.remember('bunny', "What'up, Doc?") self.assertEqual(self.bot.recall('hello'), 'world') self.assertEqual(self.bot.recall('bunny'), "What'up, Doc?") self.bot.forget() self.assertEqual(self.bot.recall('hello'), None) self.assertEqual(self.bot.recall('bunny'), None) def test_append(self): logging.info('***** append') self.bot.append('famous', 'hello, world') self.bot.append('famous', "What'up, Doc?") self.assertEqual(self.bot.recall('famous'), ['hello, world', "What'up, Doc?"]) def test_update(self): logging.info('***** update') self.bot.update('input', 'PO#', '1234A') self.bot.update('input', 'description', 'part does not fit') self.assertEqual(self.bot.recall('input'), { u'PO#': u'1234A', u'description': u'part does not fit' })
def setUp(self): self.context = Context()
def setUp(self): self.context = Context() self.db_name = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'local', 'store.db')
def test_init_filter(self): self.context = Context(filter=lambda x, y: x + '...') self.context.apply({'my.var': 'my value'}) self.context.check('my.var', filter=True) self.assertEqual(self.context.get('my.var'), 'my value...')
class SpaceTests(unittest.TestCase): def setUp(self): self.context = Context() self.space = Space(context=self.context) def tearDown(self): del self.space del self.context collected = gc.collect() if collected: logging.info("Garbage collector: collected %d objects." % (collected)) def test_init(self): logging.info("*** init") logging.debug("- default init") self.assertEqual(self.space.ears, None) self.assertEqual(self.space.fan, None) logging.debug("- unknown parameter") space = Space(context=self.context, weird='w') with self.assertRaises(AttributeError): self.assertEqual(space.weird, 'w') logging.debug("- extended parameters") class ExSpace(Space): def on_init(self, ex_token=None, **kwargs): self.token = ex_token space = ExSpace(context=self.context, ears='e', fan='f', ex_token='*token', ex_unknown='*weird') self.assertEqual(space.ears, 'e') self.assertEqual(space.fan, 'f') self.assertEqual(space.token, '*token') with self.assertRaises(AttributeError): self.assertTrue(space.unknown is not None) with self.assertRaises(AttributeError): self.assertTrue(space.ex_unknown is not None) logging.debug("- initialised via configuration") space = LocalSpace(context=self.context) space.configure({ 'space': { 'title': 'Another title', 'participants': ['*****@*****.**', '*****@*****.**'], } }) self.assertEqual(space.configured_title(), 'Another title') def test_on_start(self): logging.info("*** on_start") self.space.on_start() def test_on_stop(self): logging.info("*** on_stop") self.space.on_stop() def test_configure(self): logging.info("*** configure") class ExSpace(Space): def check(self): self.context.check('space.title', is_mandatory=True) settings = {'space.key': 'my value'} space = ExSpace(context=self.context) with self.assertRaises(KeyError): space.configure(settings=settings) self.assertEqual(space.context.get('space.title'), None) self.assertEqual(space.context.get('space.key'), 'my value') def test_configured_title(self): logging.info("*** configured_title") space = Space(context=self.context) self.assertEqual(space.configured_title(), space.DEFAULT_SPACE_TITLE) settings = {'space.title': 'my channel'} space.configure(settings=settings) self.assertEqual(self.context.get('space.title'), 'my channel') self.assertEqual(space.context.get('space.title'), 'my channel') self.assertEqual(space.configured_title(), 'my channel') def test_connect(self): logging.info("*** connect") self.space.connect() def test_list_group_channels(self): logging.info("*** list_group_channels") with self.assertRaises(NotImplementedError): channels = self.space.list_group_channels() def test_create(self): logging.info("*** create") with self.assertRaises(NotImplementedError): channel = self.space.create(title='*title') def test_get_by_title(self): logging.info("*** get_by_title") with self.assertRaises(AssertionError): self.space.get_by_title(None) with self.assertRaises(AssertionError): self.space.get_by_title('') self.assertEqual(self.space.get_by_title(title='*unknown'), None) def test_get_by_id(self): logging.info("*** get_by_id") with self.assertRaises(AssertionError): self.space.get_by_id(None) with self.assertRaises(AssertionError): self.space.get_by_id('') self.assertEqual(self.space.get_by_id(id='*unknown'), None) def test_get_by_person(self): logging.info("*** get_by_person") with self.assertRaises(AssertionError): self.space.get_by_person(None) with self.assertRaises(AssertionError): self.space.get_by_person('') self.assertEqual(self.space.get_by_person('*unknown'), None) def test_update(self): logging.info("*** update") with self.assertRaises(NotImplementedError): self.space.update(channel=FakeChannel()) def test_delete(self): logging.info("*** delete") with self.assertRaises(NotImplementedError): self.space.delete(id='*id') def test_list_participants(self): logging.info("*** list_participants") with self.assertRaises(NotImplementedError): self.space.list_participants(id='*id') def test_add_participants(self): logging.info("*** add_participants") with mock.patch.object(self.space, 'add_participant') as mocked: self.space.add_participants(id='*id', persons=[]) self.assertFalse(mocked.called) class MySpace(Space): def on_init(self): self._persons = [] def add_participant(self, id, person): self._persons.append(person) space = MySpace(context=self.context) space.add_participants(id='*id', persons=['*****@*****.**', '*****@*****.**']) self.assertEqual(space._persons, ['*****@*****.**', '*****@*****.**']) def test_add_participant(self): logging.info("*** add_participant") with self.assertRaises(NotImplementedError): self.space.add_participant(id='*id', person='*****@*****.**') def test_remove_participants(self): logging.info("*** remove_participants") with mock.patch.object(self.space, 'remove_participant') as mocked: self.space.remove_participants(id='*id', persons=[]) self.assertFalse(mocked.called) class MySpace(Space): def on_init(self): self._persons = ['*****@*****.**', '*****@*****.**'] def remove_participant(self, id, person): self._persons.remove(person) space = MySpace(context=self.context) space.remove_participants(id='*id', persons=['*****@*****.**', '*****@*****.**']) self.assertEqual(space._persons, []) def test_remove_participant(self): logging.info("*** remove_participant") with self.assertRaises(NotImplementedError): self.space.remove_participant(id='*id', person='*****@*****.**') def test_walk_messages(self): logging.info("*** walk_messages") with self.assertRaises(NotImplementedError): message = next(self.space.walk_messages(id='*id')) def test_post_message(self): logging.info("*** post_message") with self.assertRaises(AssertionError): # missing id and person self.space.post_message(text="What's up, Doc?") with self.assertRaises(AssertionError): # too much: id and person self.space.post_message(id='1', person='2', text="What's up, Doc?") with self.assertRaises(NotImplementedError): self.space.post_message(id='*id', text="What's up, Doc?") with self.assertRaises(NotImplementedError): self.space.post_message(person='*****@*****.**', text="What's up, Doc?") def test_webhook(self): logging.info("*** webhook") with self.assertRaises(NotImplementedError): self.space.webhook() def test_register(self): logging.info("*** register") with self.assertRaises(NotImplementedError): self.space.register(hook_url='http://no.where/') def test_deregister(self): logging.info("*** deregister") self.space.deregister() def test_start(self): logging.info("*** start") space = Space(context=self.context) space.register = mock.Mock() space.pull = mock.Mock() space.start(hook_url='http:/who.knows/') space.register.assert_called_with(hook_url='http:/who.knows/') self.assertFalse(space.pull.called) class ExSpace(Space): def on_reset(self): self._bot_id = None def on_start(self): self._bot_id = 123 space = ExSpace(context=self.context) space.register = mock.Mock() space.pull = mock.Mock() space.PULL_INTERVAL = 0.01 space.start() time.sleep(0.1) while space._bot_id is None: time.sleep(0.1) while self.context.get('puller.counter', 0) < 4: time.sleep(0.1) self.context.set('general.switch', 'off') self.assertFalse(space.register.called) self.assertEqual(space._bot_id, 123) self.assertTrue(self.context.get('puller.counter') > 3) def test_run(self): logging.info("*** run") space = Space(context=self.context) space.pull = mock.Mock(side_effect=Exception('TEST')) space.run() self.assertEqual(self.context.get('puller.counter'), 0) space = Space(context=self.context) space.pull = mock.Mock(side_effect=KeyboardInterrupt('ctl-C')) space.run() self.assertEqual(self.context.get('puller.counter'), 0) def test_pull(self): logging.info("*** pull") with self.assertRaises(NotImplementedError): self.space.pull()
class ContextTests(unittest.TestCase): def setUp(self): self.context = Context() def tearDown(self): del self.context collected = gc.collect() if collected: logging.info("Garbage collector: collected %d objects." % (collected)) def test_init(self): settings = { 'bot': { 'name': 'testy', 'version': '17.4.1' }, } self.context = Context(settings) self.assertEqual(self.context.get('bot.name'), 'testy') self.assertEqual(self.context.get('bot.version'), '17.4.1') def test_init_filter(self): self.context = Context(filter=lambda x, y: x + '...') self.context.apply({'my.var': 'my value'}) self.context.check('my.var', filter=True) self.assertEqual(self.context.get('my.var'), 'my value...') def test_apply(self): self.assertEqual(self.context.get('port'), None) settings = { 'spark': { 'CISCO_SPARK_BTTN_BOT': 'who_knows' }, 'spark.room': 'title', 'DEBUG': True, 'server': { 'port': 80, 'url': 'http://www.acme.com/' }, 'bot.store': { 'planets': ['Uranus', 'Mercury'] }, } self.context.apply(settings) self.assertEqual(self.context.get('DEBUG'), True) self.assertEqual(self.context.get('spark.CISCO_SPARK_BTTN_BOT'), 'who_knows') self.assertEqual(self.context.get('spark.room'), 'title') self.assertEqual(self.context.get('server.port'), 80) self.assertEqual(self.context.get('server.url'), 'http://www.acme.com/') self.assertEqual(self.context.get('bot.store.planets'), ['Uranus', 'Mercury']) self.assertEqual(self.context.get('bot.store'), {'planets': ['Uranus', 'Mercury']}) def test_clear(self): self.assertEqual(self.context.get('port'), None) settings = { 'spark': { 'CISCO_SPARK_BTTN_BOT': 'who_knows' }, 'spark.room': 'title', 'DEBUG': True, 'server': { 'port': 80, 'url': 'http://www.acme.com/' }, } self.context.apply(settings) self.assertEqual(self.context.get('DEBUG'), True) self.assertEqual(self.context.get('spark.CISCO_SPARK_BTTN_BOT'), 'who_knows') self.assertEqual(self.context.get('spark.room'), 'title') self.assertEqual(self.context.get('server.port'), 80) self.assertEqual(self.context.get('server.url'), 'http://www.acme.com/') self.context.clear() self.assertEqual(self.context.get('DEBUG'), None) self.assertEqual(self.context.get('spark.CISCO_SPARK_BTTN_BOT'), None) self.assertEqual(self.context.get('spark.room'), None) self.assertEqual(self.context.get('server.port'), None) self.assertEqual(self.context.get('server.url'), None) def test_is_empty(self): self.assertTrue(self.context.is_empty) # set a key self.context.set('hello', 'world') self.assertEqual(self.context.get('hello'), 'world') self.assertFalse(self.context.is_empty) self.context.clear() self.assertTrue(self.context.is_empty) settings = { 'spark': { 'CISCO_SPARK_BTTN_BOT': 'who_knows' }, 'spark.room': 'title', 'DEBUG': True, 'server': { 'port': 80, 'url': 'http://www.acme.com/' }, } self.context.apply(settings) self.assertFalse(self.context.is_empty) def test_check(self): self.assertEqual(self.context.get('spark.room'), None) settings = { 'spark': { 'room': 'My preferred channel', 'participants': ['*****@*****.**', '*****@*****.**'], 'team': 'Anchor team', 'token': 'hkNWEtMJNkODk3ZDZLOGQ0OVGlZWU1NmYtyY', 'weird_token': '$MY_FUZZY_SPARK_TOKEN', 'fuzzy_token': '$MY_FUZZY_SPARK_TOKEN', 'webhook': "http://73a1e282.ngrok.io", } } self.context.apply(settings) self.context.check('spark.room', is_mandatory=True) self.assertEqual(self.context.get('spark.room'), 'My preferred channel') self.context.check('spark.team') self.assertEqual(self.context.get('spark.team'), 'Anchor team') self.context.check('spark.*not*present') # will be set to None self.assertEqual(self.context.get('spark.*not*present'), None) self.context.check('spark.absent_list', default=[]) self.assertEqual(self.context.get('spark.absent_list'), []) self.context.check('spark.absent_dict', default={}) self.assertEqual(self.context.get('spark.absent_dict'), {}) self.context.check('spark.absent_text', default='*born') self.assertEqual(self.context.get('spark.absent_text'), '*born') # is_mandatory is useless if default is set self.context.check('spark.*not*present', default='*born', is_mandatory=True) self.assertEqual(self.context.get('spark.*not*present'), '*born') # missing key self.assertEqual(self.context.get('spark.*unknown*key*'), None) # we need the missing key with self.assertRaises(KeyError): self.context.check('spark.*unknown*key*', is_mandatory=True) # validate implies is_mandatory with self.assertRaises(KeyError): self.context.check('spark.*unknown*key*', validate=lambda line: True) # exception when is_mandatory is explicit with self.assertRaises(KeyError): self.context.check('spark.*unknown*key*', is_mandatory=True, filter=True) # yet filter does not imply is_mandatory by itself self.context.check('spark.*unknown*key*', filter=True) # warning in log # a web link has been set self.assertEqual(self.context.get('spark.webhook'), "http://73a1e282.ngrok.io") # validate http self.context.check('spark.webhook', validate=lambda line: line.startswith('http')) # validate https with self.assertRaises(ValueError): self.context.check('spark.webhook', validate=lambda line: line.startswith('https')) # a token has been set self.assertEqual(self.context.get('spark.token'), 'hkNWEtMJNkODk3ZDZLOGQ0OVGlZWU1NmYtyY') # validate length of token with self.assertRaises(ValueError): self.context.check('spark.token', validate=lambda line: len(line) == 32) # we rely on the environment for this key self.assertEqual(self.context.get('spark.weird_token'), '$MY_FUZZY_SPARK_TOKEN') # no change to the value self.context.check('spark.weird_token') # lookup the environment and change the value to None self.context.check('spark.weird_token', filter=True) # warning in log self.assertEqual(self.context.get('spark.weird_token'), None) # ensure the environment is clean def clear_env(name): try: os.environ.pop(name) except: pass clear_env('MY_FUZZY_SPARK_TOKEN') # a value based on the environment self.context.set('spark.fuzzy_token', '$MY_FUZZY_SPARK_TOKEN') self.context.check('spark.fuzzy_token') self.assertEqual(self.context.get('spark.fuzzy_token'), '$MY_FUZZY_SPARK_TOKEN') # default has no effect, mandatory is ok self.context.set('spark.fuzzy_token', '$MY_FUZZY_SPARK_TOKEN') self.context.check('spark.fuzzy_token', default='hello there') self.context.check('spark.fuzzy_token', is_mandatory=True) self.assertEqual(self.context.get('spark.fuzzy_token'), '$MY_FUZZY_SPARK_TOKEN') # default value is used if key is absent from the environment self.context.set('spark.fuzzy_token', '$MY_FUZZY_SPARK_TOKEN') self.context.check('spark.fuzzy_token', default='hello there', filter=True) self.assertEqual(self.context.get('spark.fuzzy_token'), 'hello there') # is_mandatory is useless in that case self.context.set('spark.fuzzy_token', '$MY_FUZZY_SPARK_TOKEN') self.context.check('spark.fuzzy_token', is_mandatory=True, filter=True) self.assertEqual(self.context.get('spark.fuzzy_token'), None) # set the value to '' self.context.set('spark.fuzzy_token', '$MY_FUZZY_SPARK_TOKEN') os.environ['MY_FUZZY_SPARK_TOKEN'] = '' self.context.check('spark.fuzzy_token', filter=True) self.assertEqual(self.context.get('spark.fuzzy_token'), '') # set the value to '' -- default value is useless in that case self.context.set('spark.fuzzy_token', '$MY_FUZZY_SPARK_TOKEN') os.environ['MY_FUZZY_SPARK_TOKEN'] = '' self.context.check('spark.fuzzy_token', default='ok?', filter=True) self.assertEqual(self.context.get('spark.fuzzy_token'), '') # set the value to 'hello' self.context.set('spark.fuzzy_token', '$MY_FUZZY_SPARK_TOKEN') os.environ['MY_FUZZY_SPARK_TOKEN'] = 'hello' self.context.check('spark.fuzzy_token', filter=True) self.assertEqual(self.context.get('spark.fuzzy_token'), 'hello') # set the value to 'hello' -- default value is useless in that case self.context.set('spark.fuzzy_token', '$MY_FUZZY_SPARK_TOKEN') os.environ['MY_FUZZY_SPARK_TOKEN'] = 'hello again' self.context.check('spark.fuzzy_token', default='ok?', filter=True) self.assertEqual(self.context.get('spark.fuzzy_token'), 'hello again') # pass the variable name as default value self.context.set('spark.fuzzy_token', None) os.environ['MY_FUZZY_SPARK_TOKEN'] = 'hello' self.context.check('spark.fuzzy_token', default='$MY_FUZZY_SPARK_TOKEN', filter=True) self.assertEqual(self.context.get('spark.fuzzy_token'), 'hello') # pass the variable name as default value -- no effect self.context.set('spark.fuzzy_token', '$MY_FUZZY_SPARK_TOKEN') os.environ['MY_FUZZY_SPARK_TOKEN'] = 'hello' self.context.check('spark.fuzzy_token', default='$MY_FUZZY_SPARK_TOKEN', filter=True) self.assertEqual(self.context.get('spark.fuzzy_token'), 'hello') # pass as default the name of an empty variable -- tricky case self.context.set('spark.fuzzy_token', '$MY_FUZZY_SPARK_TOKEN') clear_env('MY_FUZZY_SPARK_TOKEN') self.context.check('spark.fuzzy_token', default='$MY_FUZZY_SPARK_TOKEN', filter=True) self.assertEqual(self.context.get('spark.fuzzy_token'), None) def test__filter(self): self.assertEqual(Context._filter(None), None) self.assertEqual(Context._filter(''), '') self.assertEqual(Context._filter('ZLOGQ0OVGlZWU1NmYtyY'), 'ZLOGQ0OVGlZWU1NmYtyY') if os.environ.get('PATH') is not None: self.assertTrue(Context._filter('$PATH') != '$PATH') Context._filter('$TOTALLY*UNKNOWN*HERE') # warning in log def test_has(self): self.context.apply({ 'spark': { 'room': 'My preferred channel', 'participants': ['*****@*****.**', '*****@*****.**'], 'team': 'Anchor team', 'token': 'hkNWEtMJNkODk3ZDZLOGQ0OVGlZWU1NmYtyY', 'fuzzy_token': '$MY_FUZZY_SPARK_TOKEN', 'webhook': "http://73a1e282.ngrok.io", } }) # undefined prefix self.assertFalse(self.context.has('hello')) # top-level prefix self.assertTrue(self.context.has('spark')) # 2-level prefix self.assertTrue(self.context.has('spark.team')) # undefined 2-level prefix self.assertFalse(self.context.has('.token')) def test_getter(self): # undefined key self.assertEqual(self.context.get('hello'), None) # undefined key with default value whatever = 'whatever' self.assertEqual(self.context.get('hello', whatever), whatever) # set a key self.context.set('hello', 'world') self.assertEqual(self.context.get('hello'), 'world') # default value is meaningless when key has been set self.assertEqual(self.context.get('hello', 'whatever'), 'world') # except when set to None self.context.set('special', None) self.assertEqual(self.context.get('special', []), []) def test_unicode(self): self.context.set('hello', 'world') self.assertEqual(self.context.get('hello'), 'world') self.assertEqual(self.context.get(u'hello'), 'world') self.context.set('hello', u'wôrld') self.assertEqual(self.context.get('hello'), u'wôrld') self.context.set(u'hello', u'wôrld') self.assertEqual(self.context.get(u'hello'), u'wôrld') def test_increment(self): self.assertEqual(self.context.get('gauge'), None) value = self.context.increment('gauge') self.assertEqual(value, 1) self.context.set('gauge', 'world') self.assertEqual(self.context.get('gauge'), 'world') value = self.context.increment('gauge') self.assertEqual(value, 1) def test_decrement(self): self.assertEqual(self.context.get('gauge'), None) value = self.context.decrement('gauge') self.assertEqual(value, -1) self.context.set('gauge', 'world') self.assertEqual(self.context.get('gauge'), 'world') value = self.context.decrement('gauge') self.assertEqual(value, -1) def test_gauge(self): # undefined key self.assertEqual(self.context.get('gauge'), None) # see if type mismatch would create an error self.context.set('gauge', 'world') self.assertEqual(self.context.get('gauge'), 'world') # increment and decrement the counter value = self.context.increment('gauge') self.assertEqual(value, 1) self.assertEqual(self.context.get('gauge'), 1) self.assertEqual(self.context.decrement('gauge', 2), -1) self.assertEqual(self.context.increment('gauge', 4), 3) self.assertEqual(self.context.decrement('gauge', 10), -7) self.assertEqual(self.context.increment('gauge', 27), 20) self.assertEqual(self.context.get('gauge'), 20) # default value is meaningless when key has been set self.assertEqual(self.context.get('gauge', 'world'), 20) # reset the gauge self.context.set('gauge', 123) self.assertEqual(self.context.get('gauge'), 123) def test_concurrency(self): def worker(id, context): for i in range(4): r = random.random() time.sleep(r) value = context.increment('gauge') logging.info('worker %d:counter=%d' % (id, value)) logging.info('worker %d:done' % id) logging.info('Creating a counter') self.counter = Context() logging.info('Launching incrementing workers') workers = [] for i in range(4): p = Process(target=worker, args=( i, self.counter, )) p.start() workers.append(p) logging.info('Waiting for worker threads') for p in workers: p.join() logging.info('Counter: %d' % self.counter.get('gauge')) self.assertEqual(self.counter.get('gauge'), 16)
def setUp(self): self.context = Context() self.space = Space(context=self.context)
class ListFactoryTests(unittest.TestCase): def setUp(self): self.context = Context() def tearDown(self): del self.context collected = gc.collect() if collected: logging.info("Garbage collector: collected %d objects." % (collected)) def test_init(self): logging.info("***** init") factory = ListFactory(context='a') self.assertEqual(factory.context, 'a') self.assertEqual(factory.lists, {}) factory = ListFactory(context=self.context) self.assertEqual(factory.context, self.context) self.assertEqual(factory.lists, {}) def test_configure(self): logging.info("***** configure") settings = yaml.load(my_yaml) self.context.apply(settings) factory = ListFactory(context=self.context) factory.configure() self.assertEqual(sorted(factory.lists.keys()), ['supportteam', 'the famous four']) settings = yaml.load(dict_instead_of_list_yaml) self.context.clear() self.context.apply(settings) factory = ListFactory(context=self.context) factory.configure() self.assertEqual(len(factory.lists.keys()), 0) settings = yaml.load(list_instead_of_dict_yaml) self.context.clear() self.context.apply(settings) factory = ListFactory(context=self.context) factory.configure() self.assertEqual(len(factory.lists.keys()), 0) settings = yaml.load(missing_names_yaml) self.context.clear() self.context.apply(settings) factory = ListFactory(context=self.context) factory.configure() self.assertEqual(len(factory.lists.keys()), 0) def test_build_list(self): logging.info("***** build_list") factory = ListFactory(self.context) with self.assertRaises(AssertionError): list = factory.build_list(None) with self.assertRaises(AssertionError): list = factory.build_list('*weird') list = factory.build_list({}) self.assertEqual(list.items, []) self.assertEqual(list.as_command, False) list = factory.build_list({ 'items': ['*****@*****.**', '*****@*****.**'], 'as_command': True }) self.assertEqual(list.items, ['*****@*****.**', '*****@*****.**']) self.assertEqual(list.as_command, True) def test_get_list(self): logging.info("***** get_list") factory = ListFactory(self.context) settings = yaml.load(my_yaml) self.context.apply(settings) factory = ListFactory(context=self.context) factory.configure() list = factory.get_list("*unknown") self.assertEqual(list, []) list = factory.get_list("The Famous Four") self.assertEqual(list.items, [ '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**' ]) list = factory.get_list("the famous four") self.assertEqual(list.items, [ '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**' ]) list = factory.get_list("SupportTeam") self.assertEqual(list.items, ['*****@*****.**', '*****@*****.**']) list = factory.get_list("supportteam") self.assertEqual(list.items, ['*****@*****.**', '*****@*****.**']) def test_list_commands(self): logging.info("***** list_commands") factory = ListFactory(self.context) settings = yaml.load(my_yaml) self.context.apply(settings) factory = ListFactory(context=self.context) factory.configure() names = [x for x in factory.list_commands()] self.assertEqual(sorted(names), ['SupportTeam']) def test_apply_to_list(self): logging.info("***** aply_to_list") factory = ListFactory(self.context) settings = yaml.load(my_yaml) self.context.apply(settings) factory = ListFactory(context=self.context) factory.configure() class Counter(object): value = 0 def consume(self, item): logging.debug(u"- {}".format(item)) self.value += 1 my_counter = Counter() factory.apply_to_list(name='SupportTeam', apply=lambda x: my_counter.consume(x)) self.assertEqual(my_counter.value, 2) factory.apply_to_list(name='supportteam', apply=lambda x: my_counter.consume(x)) self.assertEqual(my_counter.value, 4)
outbound = u.format(inbound) self.assertEqual(outbound, inbound) inbound = Message({'text': 'hello world'}) outbound = u.format(inbound) self.assertEqual(json.loads(outbound), { "text": "hello world", "type": "message" }) inbound = Message({'personEmail': '*****@*****.**'}) outbound = u.format(inbound) self.assertEqual(json.loads(outbound), { "type": "message", "personEmail": "*****@*****.**" }) inbound = Message({'text': 'hello world', 'personEmail': '*****@*****.**'}) outbound = u.format(inbound) self.assertEqual(json.loads(outbound), { "text": "hello world", "type": "message", "personEmail": "*****@*****.**" }) if __name__ == '__main__': Context.set_logger() sys.exit(unittest.main())
def setUp(self): self.context = Context() self.engine = Engine(context=self.context, mouth=Queue()) self.space = LocalSpace(context=self.context) self.engine.space = self.space