def test_sow_since(self): """Tests sow since handling.""" # Access to protected member: _sow # # pylint: disable=W0212 pubsub = websocket.DirWatchPubSub(self.root) handler = mock.Mock() impl = mock.Mock() impl.sow_db = None impl.on_event.return_value = {'echo': 1} open(os.path.join(self.root, 'xxx'), 'w+').close() modified = int(os.stat(os.path.join(self.root, 'xxx')).st_mtime) pubsub._sow(self.root, '*', 0, handler, impl) handler.write_message.assert_called_with({ 'echo': 1, 'when': modified }, ) handler.write_message.reset_mock() pubsub._sow(self.root, '*', time.time() + 1, handler, impl) self.assertFalse(handler.write_message.called) handler.write_message.reset_mock() pubsub._sow(self.root, '*', time.time() - 1, handler, impl) handler.write_message.assert_called_with({ 'echo': 1, 'when': modified }, ) handler.write_message.reset_mock()
def test_permanent_watches(self, watcher_cls_mock, isdir_mock, glob_mock): """Tests permanent watches.""" # Access to protected member: _gc # # pylint: disable=W0212 # Add permanent watches watcher_mock = mock.Mock() watcher_cls_mock.return_value = watcher_mock glob_mock.return_value = ['/root/test/foo', '/root/test/bar'] isdir_mock.side_effect = [True, False] pubsub = websocket.DirWatchPubSub('/root', watches=['/test/*']) glob_mock.assert_called_once_with('/root/test/*') watcher_mock.add_dir.assert_called_once_with('/root/test/foo') # Register on permanent watch should not add dir again ws_handler_mock = mock.Mock() impl_mock = mock.Mock() isdir_mock.side_effect = [True, False] pubsub.register('/test/*', '*', ws_handler_mock, impl_mock, None) self.assertEqual(watcher_mock.add_dir.call_count, 1) # No new calls. self.assertIn('/root/test/foo', pubsub.handlers) # Do not GC permanent watches ws_handler_mock.active.return_value = False pubsub._gc() self.assertEqual(watcher_mock.remove_dir.call_count, 0)
def test_sow_since(self): """Tests sow since handling.""" # Access to protected member: _sow # # pylint: disable=W0212 pubsub = websocket.DirWatchPubSub(self.root) handler = mock.Mock() impl = mock.Mock() impl.sow = None impl.on_event.side_effect = [ { 'echo': 1 }, { 'echo': 2 }, ] io.open(os.path.join(self.root, 'xxx'), 'w').close() modified = os.stat(os.path.join(self.root, 'xxx')).st_mtime pubsub._sow('/', '*', 0, handler, impl) handler.send_msg.assert_called_with({'echo': 1, 'when': modified}, ) handler.send_msg.reset_mock() pubsub._sow('/', '*', time.time() + 1, handler, impl) self.assertFalse(handler.send_msg.called) handler.send_msg.reset_mock() pubsub._sow('/', '*', time.time() - 1, handler, impl) handler.send_msg.assert_called_with({'echo': 2, 'when': modified}, ) handler.send_msg.reset_mock()
def test_pubsub(self): """Tests subscription.""" pubsub = websocket.DirWatchPubSub(self.root) handler1 = DummyHandler() handler2 = DummyHandler() open(os.path.join(self.root, 'xxx'), 'w+').close() open(os.path.join(self.root, 'aaa'), 'w+').close() ws1 = mock.Mock() ws2 = mock.Mock() ws1.active.return_value = True ws2.active.return_value = True pubsub.register('/', '*', ws1, handler1, True) pubsub.register('/', 'a*', ws2, handler2, True) self.assertEqual(2, len(pubsub.handlers[self.root])) self.assertIn(('/aaa', None, ''), handler1.events) self.assertIn(('/xxx', None, ''), handler1.events) self.assertEqual([('/aaa', None, '')], handler2.events) with open(os.path.join(self.root, 'abc'), 'w+') as f: f.write('x') with open(os.path.join(self.root, '.abc'), 'w+') as f: f.write('x') pubsub.run(once=True) self.assertIn(('/abc', 'c', 'x'), handler1.events) self.assertIn(('/abc', 'm', 'x'), handler1.events) self.assertIn(('/abc', 'c', 'x'), handler2.events) self.assertIn(('/abc', 'm', 'x'), handler2.events) self.assertNotIn(('/.abc', 'c', 'x'), handler1.events) self.assertNotIn(('/.abc', 'c', 'x'), handler2.events) # Simulate connection close. ws1.active.return_value = False pubsub.run(once=True) self.assertEqual(1, len(pubsub.handlers[self.root])) pubsub.register('/new_dir', 'bbb', ws2, handler2, True) self.assertTrue(os.path.exists(os.path.join(self.root, 'new_dir')))
def websocket(fs_root, modules, port): """Treadmill Websocket""" _LOGGER.debug('port: %s', port) modified = os.path.join(fs_root, '.modified') while not os.path.exists(modified): _LOGGER.info('zk2fs mirror does not exist, waiting.') time.sleep(1) pubsub = ws.DirWatchPubSub(fs_root) for topic, impl in api.init(modules): pubsub.impl[topic] = impl pubsub.run_detached() application = tornado.web.Application([(r'/', pubsub.ws)]) http_server = tornado.httpserver.HTTPServer(application) http_server.listen(port) tornado.ioloop.IOLoop.instance().start()
def websocket(fs_root, modules, port): """Treadmill Websocket""" _LOGGER.debug('port: %s', port) # keep sleeping until zksync ready zksync_utils.wait_for_ready(fs_root) impl, watches = {}, [] for topic, topic_impl, topic_watches in api.init(modules): impl[topic] = topic_impl watches.extend(topic_watches) pubsub = ws.DirWatchPubSub(fs_root, impl, watches) pubsub.run_detached() application = tornado.web.Application([(r'/', pubsub.ws)]) http_server = tornado.httpserver.HTTPServer(application) http_server.listen(port) tornado.ioloop.IOLoop.instance().start()
def setUp(self): """Setup test""" self.root = tempfile.mkdtemp() self.pubsub = websocket.DirWatchPubSub(self.root) AsyncHTTPTestCase.setUp(self)
def test_sow_fs_and_db(self): """Tests sow from filesystem and database.""" # Access to protected member: _sow # # pylint: disable=W0212 pubsub = websocket.DirWatchPubSub(self.root) handler = mock.Mock() impl = mock.Mock() sow_dir = os.path.join(self.root, '.sow', 'trace') fs.mkdir_safe(sow_dir) with tempfile.NamedTemporaryFile(dir=sow_dir, delete=False, prefix='trace.db-') as temp: pass impl.sow = sow_dir impl.sow_table = 'trace' conn = sqlite3.connect(temp.name) conn.execute(""" CREATE TABLE trace ( path text, timestamp integer, data text, directory text, name text ) """) conn.executemany( """ INSERT INTO trace ( path, timestamp, directory, name ) VALUES(?, ?, ?, ?) """, [('/aaa', 3, '/', 'aaa'), ('/bbb', 2, '/', 'bbb'), ('/ccc', 1, '/', 'ccc')]) conn.commit() conn.close() impl.on_event.side_effect = [ { 'echo': 1 }, { 'echo': 2 }, { 'echo': 3 }, { 'echo': 4 }, ] io.open(os.path.join(self.root, 'xxx'), 'w').close() modified = os.stat(os.path.join(self.root, 'xxx')).st_mtime pubsub._sow('/', '*', 0, handler, impl) impl.on_event.assert_has_calls([ mock.call('/ccc', None, None), mock.call('/bbb', None, None), mock.call('/aaa', None, None), mock.call('/xxx', None, ''), ]) handler.send_msg.assert_has_calls([ mock.call({ 'when': 1, 'echo': 1 }), mock.call().add_done_callback(mock.ANY), mock.call({ 'when': 2, 'echo': 2 }), mock.call().add_done_callback(mock.ANY), mock.call({ 'when': 3, 'echo': 3 }), mock.call().add_done_callback(mock.ANY), mock.call({ 'when': modified, 'echo': 4 }), ]) # Create empty sow database, this will simulate db removing database # while constructing sow. # with tempfile.NamedTemporaryFile(dir=sow_dir, delete=False, prefix='trace.db-') as temp: pass pubsub._sow('/', '*', 0, handler, impl) impl.on_event.assert_has_calls([ mock.call('/ccc', None, None), mock.call('/bbb', None, None), mock.call('/aaa', None, None), mock.call('/xxx', None, ''), ]) handler.send_msg.assert_has_calls([ mock.call({ 'when': 1, 'echo': 1 }), mock.call().add_done_callback(mock.ANY), mock.call({ 'when': 2, 'echo': 2 }), mock.call().add_done_callback(mock.ANY), mock.call({ 'when': 3, 'echo': 3 }), mock.call().add_done_callback(mock.ANY), mock.call({ 'when': modified, 'echo': 4 }), ])
def test_sow_fs_and_db(self): """Tests sow from filesystem and database.""" # Access to protected member: _sow # # pylint: disable=W0212 pubsub = websocket.DirWatchPubSub(self.root) handler = mock.Mock() impl = mock.Mock() impl.sow_db = '.tasks-sow.db' impl.on_event.side_effect = [ { 'echo': 1 }, { 'echo': 2 }, { 'echo': 3 }, { 'echo': 4 }, ] open(os.path.join(self.root, 'xxx'), 'w+').close() modified = int(os.stat(os.path.join(self.root, 'xxx')).st_mtime) conn_mock = mock.Mock() cur_mock = mock.Mock() sqlite3.connect.return_value = conn_mock conn_mock.cursor.return_value = cur_mock cur_mock.fetchall.return_value = [ ('/aaa', 1, ''), ('/bbb', 2, ''), ('/ccc', 3, ''), ] pubsub._sow(self.root, '*', 0, handler, impl) impl.on_event.assert_has_calls([ mock.call('/aaa', None, ''), mock.call('/bbb', None, ''), mock.call('/ccc', None, ''), mock.call('/xxx', None, ''), ]) handler.write_message.assert_has_calls([ mock.call({ 'when': 1, 'echo': 1 }), mock.call({ 'when': 2, 'echo': 2 }), mock.call({ 'when': 3, 'echo': 3 }), mock.call({ 'when': modified, 'echo': 4 }), ])
def test_sow_fs_and_db(self): """Tests sow from filesystem and database.""" # Access to protected member: _sow # # pylint: disable=W0212 pubsub = websocket.DirWatchPubSub(self.root) handler = mock.Mock() impl = mock.Mock() sow_dir = os.path.join(self.root, '.sow', 'trace') fs.mkdir_safe(sow_dir) with tempfile.NamedTemporaryFile(dir=sow_dir, delete=False, prefix='trace.db-') as temp: pass impl.sow = sow_dir impl.sow_table = 'trace' conn = sqlite3.connect(temp.name) conn.execute('CREATE TABLE trace (' ' path TEXT,' ' timestamp INTEGER,' ' data TEXT,' ' source TEXT)') conn.executemany('INSERT INTO trace (path, timestamp) values(?, ?)', [('/aaa', 3), ('/bbb', 2), ('/ccc', 1)]) conn.commit() conn.close() impl.on_event.side_effect = [ { 'echo': 1 }, { 'echo': 2 }, { 'echo': 3 }, { 'echo': 4 }, ] open(os.path.join(self.root, 'xxx'), 'w+').close() modified = int(os.stat(os.path.join(self.root, 'xxx')).st_mtime) pubsub._sow('/', '*', 0, handler, impl) impl.on_event.assert_has_calls([ mock.call('/ccc', None, None), mock.call('/bbb', None, None), mock.call('/aaa', None, None), mock.call('/xxx', None, ''), ]) handler.write_message.assert_has_calls([ mock.call({ 'when': 1, 'echo': 1 }), mock.call({ 'when': 2, 'echo': 2 }), mock.call({ 'when': 3, 'echo': 3 }), mock.call({ 'when': modified, 'echo': 4 }), ])