diff --git a/ait/server/handlers/example_handler.py b/ait/server/handlers/example_handler.py new file mode 100644 index 00000000..aba0e491 --- /dev/null +++ b/ait/server/handlers/example_handler.py @@ -0,0 +1,11 @@ +from ait.core import log, tlm +from ait.server.handler import Handler + + +class ExampleHandler(Handler): + + def __init__(self, input_type=None, output_type=None, **kwargs): + super(ExampleHandler, self).__init__(input_type, output_type) + + def handle(self, input_data): + pass diff --git a/ait/server/test/test_broker.py b/ait/server/test/test_server.py similarity index 51% rename from ait/server/test/test_broker.py rename to ait/server/test/test_server.py index f8826dd6..5c2f82fd 100644 --- a/ait/server/test/test_broker.py +++ b/ait/server/test/test_server.py @@ -1,26 +1,24 @@ import ait from ait.core import cfg import ait.server -from ait.server.broker import AitBroker -from ait.server.stream import Stream from ait.server.handlers import * -from ait.server.plugins import * +from ait.server.server import AitServer import nose from nose.tools import * import mock @mock.patch.object(ait.core.log, 'warn') -@mock.patch.object(ait.server.broker.AitBroker, 'create_stream') +@mock.patch('ait.server.broker.AitBroker') +@mock.patch.object(ait.server.server.AitServer, '__init__', return_value=None) +@mock.patch.object(ait.server.server.AitServer, 'create_stream') class TestStreamConfigParsing(object): test_yaml_file = '/tmp/test.yaml' - def setUp(self): - ait.broker.inbound_streams = [ ] - ait.broker.outbound_streams = [ ] - def test_no_inbound_streams(self, create_stream_mock, + server_init_mock, + broker_class_mock, log_warn_mock): """ Tests that broker started with no inbound streams specified and that warning is logged """ @@ -38,17 +36,20 @@ def test_no_inbound_streams(self, """ rewrite_and_reload_config(self.test_yaml_file, yaml) - ait.broker.load_streams() + server = AitServer() + server.load_streams() # assert warning is logged log_warn_mock.assert_called_with( 'No valid inbound telemetry stream configurations found. ' 'No telemetry will be received (or displayed).') # assert outbound stream is added successfully - assert len(ait.broker.outbound_streams) == 1 + assert len(server.outbound_streams) == 1 def test_no_outbound_streams(self, create_stream_mock, + server_init_mock, + broker_class_mock, log_warn_mock): """ Tests that broker started with no outbound streams specified and that warning is logged """ @@ -66,96 +67,123 @@ def test_no_outbound_streams(self, """ rewrite_and_reload_config(self.test_yaml_file, yaml) - ait.broker.load_streams() + server = AitServer() + server.load_streams() # assert warning is logged log_warn_mock.assert_called_with( 'No valid outbound telemetry stream configurations found. ' 'No telemetry will be published.') # assert inbound stream is added successfully - assert len(ait.broker.inbound_streams) == 1 + assert len(server.inbound_streams) == 1 +@mock.patch('ait.server.broker.AitBroker') +@mock.patch.object(ait.server.server.AitServer, '__init__', return_value=None) class TestStreamCreation(object): - def test_no_stream_type(self): + def test_no_stream_type(self, + server_init_mock, + broker_class_mock): """ Tests that a ValueError is raised when creating a stream with stream_type of None """ + server = AitServer() with assert_raises_regexp(ValueError, 'Stream type must be \'inbound\' or \'outbound\'.'): - ait.broker.create_stream('some_config', 'some_path', None) + server.create_stream('some_config', None) - def test_bad_stream_type(self): + def test_bad_stream_type(self, + server_init_mock, + broker_class_mock): """ Tests that a ValueError is raised when creating a stream with a stream_type not equal to either 'inbound' or 'outboud' """ + server = AitServer() with assert_raises_regexp(ValueError, 'Stream type must be \'inbound\' or \'outbound\'.'): - ait.broker.create_stream('some_config', 'some_path', 'some_type') + server.create_stream('some_config', 'some_type') - def test_no_stream_config(self): + def test_no_stream_config(self, + server_init_mock, + broker_class_mock): """ Tests that a ValueError is raised when creating a stream with a config of None """ + server = AitServer() with assert_raises_regexp(ValueError, - 'The parameter %s is missing from config.yaml' - % 'some_path'): - ait.broker.create_stream(None, 'some_path', 'inbound') + 'No stream config to create stream from.'): + server.create_stream(None, 'inbound') - def test_no_stream_name(self): + def test_no_stream_name(self, + server_init_mock, + broker_class_mock): """ Tests that a ValueError is raised when creating a stream with no name specified in the config """ config = {'input': 'some_stream', 'handlers': ['some-handler']} - - with assert_raises_regexp(ValueError, + server = AitServer() + with assert_raises_regexp(cfg.AitConfigMissing, 'The parameter %s is missing from config.yaml' - % 'some_path.name'): - ait.broker.create_stream(config, 'some_path', 'inbound') + % 'inbound stream name'): + server.create_stream(config, 'inbound') - def test_duplicate_stream_name(self): + def test_duplicate_stream_name(self, + server_init_mock, + broker_class_mock): """ Tests that a ValueError is raised when creating a stream with a name that already belongs to another stream or plugin """ + server = AitServer() + config = {'input': 'some_stream', 'name': 'myname', 'handlers': ['some-handler']} # Testing existing name in plugins - ait.broker.plugins = [FakeStream(name='myname')] + server.plugins = [FakeStream(name='myname')] with assert_raises_regexp(ValueError, 'Stream name already exists. Please rename.'): - ait.broker.create_stream(config, 'some_path', 'outbound') + server.create_stream(config, 'outbound') # Testing existing name in inbound_streams - ait.broker.plugins = [ ] - ait.broker.inbound_streams = [FakeStream(name='myname')] + server.plugins = [ ] + server.inbound_streams = [FakeStream(name='myname')] with assert_raises_regexp(ValueError, 'Stream name already exists. Please rename.'): - ait.broker.create_stream(config, 'some_path', 'inbound') + server.create_stream(config, 'inbound') # Testing existing name in outbound_streams - ait.broker.inbound_streams = [ ] - ait.broker.outbound_streams = [FakeStream(name='myname')] + server.inbound_streams = [ ] + server.outbound_streams = [FakeStream(name='myname')] with assert_raises_regexp(ValueError, 'Stream name already exists. Please rename.'): - ait.broker.create_stream(config, 'some_path', 'inbound') + server.create_stream(config, 'inbound') - def test_no_stream_input(self): + def test_no_stream_input(self, + server_init_mock, + broker_class_mock): """ Tests that a ValueError is raised when creating a stream with no input specified in the config """ + server = AitServer() + config = {'name': 'some_stream', 'handlers': ['some-handler']} - with assert_raises_regexp(ValueError, + with assert_raises_regexp(cfg.AitConfigMissing, 'The parameter %s is missing from config.yaml' - % 'some_path.input'): - ait.broker.create_stream(config, 'some_path', 'inbound') - - @mock.patch.object(ait.server.broker.AitBroker, 'create_handler') - def test_successful_stream_creation(self, create_handler_mock): + % 'inbound stream input'): + server.create_stream(config, 'inbound') + + @mock.patch.object(ait.server.server.AitServer, 'create_handler') + def test_successful_stream_creation(self, + create_handler_mock, + server_init_mock, + broker_class_mock): """ Tests that streams are successfully created both with or without handlers """ # Testing stream creating with handlers + server = AitServer() + server.broker = ait.server.broker.AitBroker() + config = {'name': 'some_stream', 'input': 'some_input', 'handlers': ['some-handler']} - created_stream = ait.broker.create_stream(config, 'some_path', 'inbound') - assert type(created_stream) == Stream + created_stream = server.create_stream(config, 'inbound') + assert type(created_stream) == ait.server.stream.ZMQInputStream assert created_stream.name == 'some_stream' assert created_stream.input_ == 'some_input' assert type(created_stream.handlers) == list @@ -163,58 +191,77 @@ def test_successful_stream_creation(self, create_handler_mock): # Testing stream creation without handlers config = cfg.AitConfig(config={'name': 'some_stream', 'input': 'some_input'}) - created_stream = ait.broker.create_stream(config, 'some_path', 'inbound') - assert type(created_stream) == Stream + created_stream = server.create_stream(config, 'inbound') + assert type(created_stream) == ait.server.stream.ZMQInputStream assert created_stream.name == 'some_stream' assert created_stream.input_ == 'some_input' assert type(created_stream.handlers) == list +@mock.patch('ait.server.broker.AitBroker') +@mock.patch.object(ait.server.server.AitServer, '__init__', return_value=None) class TestHandlerCreation(object): - def test_no_handler_config(self): + def test_no_handler_config(self, + server_init_mock, + broker_mock): """ Tests that a ValueError is raised when creating a handler with a config of None """ + server = AitServer() with assert_raises_regexp(ValueError, - 'The parameter %s is missing from config.yaml' - % 'some_path'): - ait.broker.create_handler(None, 'some_path') - - def test_handler_creation_with_no_configs(self): - """ Tests handler is successfully created when it has not configs """ - config = 'tm_trans_frame_decode_handler' - handler = ait.broker.create_handler(config, 'some_path') - assert type(handler) == tm_trans_frame_decode_handler.TmTransFrameDecodeHandler + 'No handler config to create handler from.'): + server.create_handler(None) + + def test_handler_creation_with_no_configs(self, + server_init_mock, + broker_mock): + """ Tests handler is successfully created when it has no configs """ + server = AitServer() + + config = {'name': 'ait.server.handlers.example_handler'} + handler = server.create_handler(config) + assert type(handler) == ait.server.handlers.example_handler.ExampleHandler assert handler.input_type is None assert handler.output_type is None - def test_handler_creation_with_configs(self): + def test_handler_creation_with_configs(self, + server_init_mock, + broker_mock): """ Tests handler is successfully created when it has configs """ - config = {'ccsds_packet_handler': {'input_type': 'int', 'output_type': 'int'}} - handler = ait.broker.create_handler(config, 'some_path') - assert type(handler) == ccsds_packet_handler.CcsdsPacketHandler + server = AitServer() + + config = {'name': 'ait.server.handlers.example_handler', 'input_type': 'int', 'output_type': 'int'} + handler = server.create_handler(config) + assert type(handler) == ait.server.handlers.example_handler.ExampleHandler assert handler.input_type == 'int' assert handler.output_type == 'int' - def test_handler_that_doesnt_exist(self): + def test_handler_that_doesnt_exist(self, + server_init_mock, + broker_mock): """ Tests that exception thrown if handler doesn't exist """ - config = 'some_nonexistant_handler' - with assert_raises_regexp(ImportError, 'No module named %s' % config): - ait.broker.create_handler(config, 'some_path') + server = AitServer() + + config = {'name': 'some_nonexistant_handler'} + with assert_raises_regexp(ImportError, 'No module named %s' % config['name']): + server.create_handler(config) @mock.patch.object(ait.core.log, 'warn') @mock.patch.object(ait.core.log, 'error') +@mock.patch('ait.server.broker.AitBroker') +@mock.patch.object(ait.server.server.AitServer, '__init__', return_value=None) class TestPluginConfigParsing(object): test_yaml_file = '/tmp/test.yaml' - def setUp(self): - ait.broker.plugins = [ ] - def test_no_plugins_listed(self, + server_init_mock, + broker_mock, log_error_mock, log_warn_mock): """ Tests that warning logged if no plugins configured """ + server = AitServer() + yaml = """ default: server: @@ -222,54 +269,75 @@ def test_no_plugins_listed(self, """ rewrite_and_reload_config(self.test_yaml_file, yaml) - ait.broker.load_plugins() + server.load_plugins() log_warn_mock.assert_called_with( - 'No valid plugin configurations found. No plugins will be added.') + 'No plugins specified in config.') +@mock.patch('ait.server.broker.AitBroker') +@mock.patch.object(ait.server.server.AitServer, '__init__', return_value=None) class TestPluginCreation(object): - def test_plugin_with_no_config(self): + def test_plugin_with_no_config(self, + server_init_mock, + broker_mock): """ Tests that error raised if plugin not configured """ + server = AitServer() + config = None with assert_raises_regexp(ValueError, - 'The parameter %s is missing from config.yaml' - % 'some_path'): - ait.broker.create_plugin(config, 'some_path') + 'No plugin config to create plugin from.'): + server.create_plugin(config) - def test_plugin_missing_name(self): + def test_plugin_missing_name(self, + server_init_mock, + broker_mock): """ Tests that error raised if plugin has no name """ + server = AitServer() + config = {'inputs': 'some_inputs'} - with assert_raises_regexp(ValueError, - 'The parameter %s is missing from config.yaml' - % 'some_path.name'): - ait.broker.create_plugin(config, 'some_path') + with assert_raises_regexp(cfg.AitConfigMissing, + 'The parameter plugin name is missing from config.yaml'): + server.create_plugin(config) @mock.patch.object(ait.core.log, 'warn') - def test_plugin_missing_inputs(self, log_warn_mock): + def test_plugin_missing_inputs(self, + log_warn_mock, + server_init_mock, + broker_mock): """ Tests that warning logged if plugin has no inputs and plugin created anyways """ - config = {'name': 'ait_gui_plugin'} - ait.broker.create_plugin(config, 'some_path') + server = AitServer() + server.broker = ait.server.broker.AitBroker() + + config = {'name': 'ait.server.plugins.example_plugin'} + server.create_plugin(config) - log_warn_mock.assert_called_with('The parameter some_path.inputs is missing' - ' from config.yaml (/tmp/test.yaml).') + log_warn_mock.assert_called_with('No plugin inputs specified for ait.server.plugins.example_plugin') - def test_plugin_name_already_in_use(self): + def test_plugin_name_already_in_use(self, + server_init_mock, + broker_mock): """ Tests that error raised if name already in use """ - ait.broker.plugins = [ait_gui_plugin.AitGuiPlugin(None)] - config = {'name': 'ait_gui_plugin', 'inputs': 'some_inputs'} + server = AitServer() + + server.plugins = [FakeStream(name='ExamplePlugin')] + config = {'name': 'example_plugin', 'inputs': 'some_inputs'} with assert_raises_regexp(ValueError, 'Plugin name already exists. Please rename.'): - ait.broker.create_plugin(config, 'some_path') + server.create_plugin(config) - def test_plugin_doesnt_exist(self): + def test_plugin_doesnt_exist(self, + server_init_mock, + broker_mock): """ Tests that error raised if plugin doesn't exist """ + server = AitServer() + config = {'name': 'some_nonexistant_plugin', 'inputs': 'some_inputs'} with assert_raises_regexp(ImportError, 'No module named some_nonexistant_plugin'): - ait.broker.create_plugin(config, 'some_path') + server.create_plugin(config) def rewrite_and_reload_config(filename, yaml):