class ServiceTestCase(unittest.TestCase): def setUp(self): self.config = Options() def _make_service(self, options): self.config.parseOptions(options) return makeService(self.config) def test_has_receiver(self): service = self._make_service(['--local-ivo', 'ivo://comet/test', '-r', '-b', '--remote', 'dummy']) for service_name in ( "Receiver", "Broadcaster", "Remote %s:%d" % ('dummy', DEFAULT_REMOTE_PORT) ): self.assertTrue(service_name in service.namedServices) def test_no_service(self): # When we ask for no services on the command line, nothing should be # started -- but we also shouldn't raise. # Note we need to stub out the reactor's callWhenRunning() method, # because makeService schedules a reactor.stop() which will bring our # test cases crashing down. oldCallWhenRunning = reactor.callWhenRunning class MockCallWhenRunning(object): def __init__(self): self.call_count = 0 def __call__(self, *args, **kwargs): self.call_count += 1 mockCallWhenRunning = MockCallWhenRunning() try: reactor.callWhenRunning = mockCallWhenRunning service = self._make_service(['--local-ivo', 'ivo://comet/test']) finally: # Be sure to return the reactor to its initial state when done. reactor.callWhenRunning = oldCallWhenRunning # No services created. self.assertEqual(len(service.namedServices), 0) # Should have been called twice: once for logging, once to stop the # reactor. We are not actually checking the values of those calls # here, though. self.assertEqual(mockCallWhenRunning.call_count, 2) def tearDown(self): for call in reactor.getDelayedCalls(): call.cancel()
def setUp(self): self.config = Options() self.cmd_line = ["--local-ivo", DUMMY_SERVICE_IVORN]
class DefaultOptionsTestCase(unittest.TestCase): def setUp(self): self.config = Options() self.cmd_line = ["--local-ivo", DUMMY_SERVICE_IVORN] def test_faulty_cmd_line(self): self.cmd_line.append("--not-a-real-option") self.assertRaises( usage.UsageError, self.config.parseOptions, self.cmd_line ) def test_test_event_loop(self): self.assertEqual(self.config['broadcast-test-interval'], BCAST_TEST_INTERVAL) self.cmd_line.extend(["--broadcast-test-interval", "0"]) self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['broadcast-test-interval'], 0) def test_enable_receive(self): self.assertFalse(self.config['receive']) self.cmd_line.append("--receive") self.config.parseOptions(self.cmd_line) self.assertTrue(self.config['receive']) def test_enable_broadcast(self): self.assertFalse(self.config['broadcast']) self.cmd_line.append("--broadcast") self.config.parseOptions(self.cmd_line) self.assertTrue(self.config['broadcast']) def test_remotes(self): HOST0, PORT = "dummy_0", 0 HOST1 = "dummy_1" self.cmd_line.extend(["--remote", "%s:%d" % (HOST0, PORT), "--remote", HOST1]) self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['remotes']), 2) self.assertTrue((HOST0, PORT) in self.config['remotes']) self.assertTrue((HOST1, DEFAULT_REMOTE_PORT) in self.config['remotes']) def test_default_whitelist(self): self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['whitelist'], [ip_network("0.0.0.0/0")]) def test_specified_whitelist(self): net1, net2 = "1.2.3.4/32", "4.3.2.1/255.255.0.0" self.cmd_line.extend(["--whitelist", net1, "--whitelist", net2]) self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['whitelist']), 2) for net in [net1, net2]: self.assertTrue( ip_network(net, strict=False) in self.config['whitelist'] ) def test_has_print_event_plugin(self): self.cmd_line.append("--print-event") self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 1) self.assertEqual(self.config['handlers'][0].name, "print-event") def test_has_save_event_plugin(self): self.cmd_line.append("--save-event") self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 1) self.assertEqual(self.config['handlers'][0].name, "save-event") def test_save_event_plugin_takes_args(self): self.cmd_line.extend(["--save-event", "--save-event-directory=/tmp"]) self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['handlers'][0].name, "save-event") self.assertEqual(self.config['handlers'][0].directory, "/tmp") def test_args_for_disabled_plugin(self): # Should not enable the plugin self.cmd_line.append("--save-event-directory=/tmp") self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 0) def test_action_non_extant(self): action = "does-not-exist" self.cmd_line.extend(["--action", action]) self.assertRaises(usage.UsageError, self.config.parseOptions, self.cmd_line) def test_filters(self): self.cmd_line.extend(["--filter", "foo", "--filter", "bar"]) self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['filters']), 2) def test_invalid_filter(self): self.cmd_line.extend(["--filter", "not(starts-with("]) self.assertRaises(usage.UsageError, self.config.parseOptions, self.cmd_line) def test_cmd(self): self.cmd_line.extend(["--cmd", "foo", "--cmd", "bar"]) self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 2) def test_verbose_default(self): self.config.parseOptions(self.cmd_line) self.assertEqual(log.LEVEL, log.DEFAULT_LEVEL) def test_verbose_verbose(self): self.cmd_line.append('-v') self.config.parseOptions(self.cmd_line) self.assertEqual(log.LEVEL, log.Levels.DEBUG) def test_verbose_quiet(self): self.cmd_line.append('-q') self.config.parseOptions(self.cmd_line) self.assertEqual(log.LEVEL, log.Levels.WARNING) def test_verbose_contradictory(self): self.cmd_line.extend(['-q', '-v']) self.config.parseOptions(self.cmd_line) self.assertEqual(log.LEVEL, log.DEFAULT_LEVEL) def test_valid_ivorn(self): self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['local-ivo'], DUMMY_SERVICE_IVORN) def test_invalid_ivorn(self): self.cmd_line.extend(["--local-ivo", "ivo://"]) self.assertRaises(usage.UsageError, self.config.parseOptions, self.cmd_line) def test_ivorn_missing(self): self.assertRaises(usage.UsageError, self.config.parseOptions, "")
def setUp(self): config = Options() config.parseOptions(['--local-ivo', 'ivo://comet/test', '-r', '-b', '--remote', 'dummy']) self.service = makeService(config)
def setUp(self): self.config = Options()
class BrokerServiceTestCase(unittest.TestCase): def setUp(self): self.config = Options() def _make_service(self, options): self.config.parseOptions(options) return makeService(self.config) def test_has_services(self): # Demonstrate that we can create appropriate numbers of services. # A single receiver. service = self._make_service( ['--local-ivo', 'ivo://comet/test', '--receive']) self.assertEqual(len(service.services), 1) # A single broadcaster. service = self._make_service( ['--local-ivo', 'ivo://comet/test', '--broadcast']) self.assertEqual(len(service.services), 1) # A single subscriber. service = self._make_service([ '--local-ivo', 'ivo://comet/test', '--subscribe', "tcp:test:12345" ]) self.assertEqual(len(service.services), 1) # All of the above. service = self._make_service([ '--local-ivo', 'ivo://comet/test', '--receive', '--broadcast', '--subscribe', "tcp:test:12345" ]) self.assertEqual(len(service.services), 3) # Multiple instances of each service. service = self._make_service([ '--local-ivo', 'ivo://comet/test', '--receive', '--broadcast', '--receive', 'tcp:1234', '--broadcast', 'tcp:4321', '--subscribe', "tcp:test:12345", '--subscribe', "tcp:test:54321" ]) self.assertEqual(len(service.services), 6) def _check_bind_failure(self, service): # Check that starting the service raises a CannotListenError. try: self.assertRaises(CannotListenError, service.startService) finally: # Necessary to clean the reactor; this is black magic, determined # by trial and error(!). for s in service: if s._waitingForPort: s.stopService() def test_failure_to_bind_receiver(self): # Attempting to bind to the same port twice should fail. service = self._make_service([ '--local-ivo', 'ivo://comet/test', '--receive', 'tcp:1234', '--receive', 'tcp:1234' ]) self._check_bind_failure(service) def test_failure_to_bind_broadcaster(self): # Attempting to bind to the same port twice should fail. service = self._make_service([ '--local-ivo', 'ivo://comet/test', '--broadcast', 'tcp:1234', '--broadcast', 'tcp:1234' ]) self._check_bind_failure(service) def test_no_service(self): # When we ask for no services on the command line, nothing should be # started -- but we also shouldn't raise. # Note we need to stub out the reactor's callWhenRunning() method, # because makeService schedules a reactor.stop() which will bring our # test cases crashing down. oldCallWhenRunning = reactor.callWhenRunning class MockCallWhenRunning(object): def __init__(self): self.call_count = 0 def __call__(self, *args, **kwargs): self.call_count += 1 mockCallWhenRunning = MockCallWhenRunning() try: reactor.callWhenRunning = mockCallWhenRunning service = self._make_service(['--local-ivo', 'ivo://comet/test']) finally: # Be sure to return the reactor to its initial state when done. reactor.callWhenRunning = oldCallWhenRunning # No services created. self.assertEqual(len(service.namedServices), 0) # Should have been called twice: once for logging, once to stop the # reactor. We are not actually checking the values of those calls # here, though. self.assertEqual(mockCallWhenRunning.call_count, 2) def tearDown(self): for call in reactor.getDelayedCalls(): call.cancel()
def setUp(self): self.config = Options() self.cmd_line = ["--local-ivo", DUMMY_SERVICE_IVOID.decode()]
class BrokerOptionsTestCase(unittest.TestCase, OptionTestUtils): def setUp(self): self.config = Options() self.cmd_line = ["--local-ivo", DUMMY_SERVICE_IVOID.decode()] def _check_server_endpoints(self, option_name, default_port): # Check for a set of server endpoints specifed by ``--option_name``. # If not specified, we shouldn't receive at all. self.config.parseOptions(self.cmd_line) self.assertIsNone(self.config[option_name]) # If specified with no argument, use the default endpoint. self.config.parseOptions(self.cmd_line + [f"--{option_name}"]) self.assertEqual(len(self.config[option_name]), 1) self.assertEqual(self.config[option_name][0]._port, default_port) # If specified with an argument, use that. self.config.parseOptions(self.cmd_line + [f"--{option_name}", "tcp:1"]) self.assertEqual(len(self.config[option_name]), 1) self.assertEqual(self.config[option_name][0]._port, 1) # If specified without a protocol type, default to TCP. self.config.parseOptions(self.cmd_line + [f"--{option_name}", "1"]) self.assertEqual(len(self.config[option_name]), 1) self.assertEqual(self.config[option_name][0]._port, 1) # If specified with an argument AND without, do both. self.config.parseOptions( self.cmd_line + [f"--{option_name}", f"--{option_name}", "tcp:1"]) self.assertEqual(len(self.config[option_name]), 2) self.assertEqual(self.config[option_name][0]._port, default_port) self.assertEqual(self.config[option_name][1]._port, 1) # And it should work with a Unix domain socket. self.config.parseOptions(self.cmd_line + [f"--{option_name}", "unix:/test"]) self.assertEqual(len(self.config[option_name]), 1) self.assertEqual(self.config[option_name][0]._address, "/test") # But not with garbage. self._check_bad_parse(self.cmd_line + [f"--{option_name}", "bad"]) def _check_whitelist(self, option_name): # Check that ``option_name`` corresponds to a default-allow whitelist. def check_wl_contents(wl, expected_values): # Check the contents of a whitelist against a model self.assertEqual(len(wl), len(expected_values)) for net in expected_values: self.assertIn(net, wl) config_name = option_name.replace("-", "_") NET_DEFAULT, NET1, NET2 = "0.0.0.0/0", "10.0.0.0/8", "172.16.0.0/12" # By default, everything is whitelisted. self.config.parseOptions(self.cmd_line) check_wl_contents(self.config[config_name], [ip_network(NET_DEFAULT)]) # If a single argument is supplied, it replaces the default. self.config.parseOptions(self.cmd_line + [f"--{option_name}", NET1]) check_wl_contents(self.config[config_name], [ip_network(NET1)]) # If two arguments is supplied, use both self.config.parseOptions(self.cmd_line + [f"--{option_name}", NET1, NET2]) check_wl_contents( self.config[config_name], [ip_network(NET1), ip_network(NET2)]) # If --receive-whitelist is supplied twice, use only the second. self.config.parseOptions( self.cmd_line + [f"--{option_name}", NET1, f"--{option_name}", NET2]) check_wl_contents(self.config[config_name], [ip_network(NET2)]) def test_return_self(self): # parseOptions() should return `self.config` for convenience. self.assertEqual(self.config, self.config.parseOptions(self.cmd_line)) def test_local_ivoid(self): # The local IVOID should be set correctly. self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['local_ivo'], DUMMY_SERVICE_IVOID.decode()) # And a bad one rejected. self._check_bad_parse(["--local-ivo", "bad_ivo"]) def test_ivoid_required(self): # A local IVOID is not required _unless_ a broadcaster and/or a # receiver is running. # Should be fine self.config.parseOptions(self.cmd_line + ["--receive"]) self.config.parseOptions(self.cmd_line + ["--broadcast"]) self.config.parseOptions(self.cmd_line + ["--broadcast", "--receive"]) # Should fail self._check_bad_parse(["--receive"]) self._check_bad_parse(["--broadcast"]) self._check_bad_parse(["--receive", "--broadcast"]) def test_eventdb(self): # Default value should be a directory. self.assertTrue( os.path.isdir(self.config.parseOptions(self.cmd_line)['eventdb'])) # Specifying our own directory should also work. dirname = "/example" self.assertEqual( self.config.parseOptions(["--eventdb", dirname])['eventdb'], dirname) def test_receive(self): # Check that ``--receive`` properly sets up server endpoints. self._check_server_endpoints("receive", DEFAULT_SUBMIT_PORT) def test_receive_whitelist(self): # Check that we create a whitelist for receivers. self._check_whitelist("receive-whitelist") def test_broadcast(self): # Check that ``--broadcast`` properly sets up server endpoints. self._check_server_endpoints("broadcast", DEFAULT_SUBSCRIBE_PORT) def test_broadcast_test_interval(self): # Check that the default is set. self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['broadcast_test_interval'], BCAST_TEST_INTERVAL) # And can be over-ridden. self.config.parseOptions(self.cmd_line + ["--broadcast-test-interval", 0]) self.assertEqual(self.config['broadcast_test_interval'], 0) def test_broadcast_whitelist(self): # Check that we create a whitelist for broadcasters. self._check_whitelist("broadcast-whitelist") def test_subscribe(self): # By default, we subscribe to nothing. self.config.parseOptions(self.cmd_line) self.assertIsNone(self.config['subscribe']) # --subscribe always requires an egument. self._check_bad_parse(self.cmd_line + ["--subscribe"]) # Specifying a single endpoint should add that to the list of # subcribers. self.config.parseOptions( self.cmd_line + ["--subscribe", f"tcp:test:{DEFAULT_SUBSCRIBE_PORT}"]) self.assertEqual(len(self.config['subscribe']), 1) self.assertEqual(self.config['subscribe'][0]._port, DEFAULT_SUBSCRIBE_PORT) self.assertEqual(self.config['subscribe'][0]._host, "test") # If a protocol isn't specified, assume TCP. self.config.parseOptions( self.cmd_line + ["--subscribe", f"test:{DEFAULT_SUBSCRIBE_PORT}"]) self.assertEqual(len(self.config['subscribe']), 1) self.assertEqual(self.config['subscribe'][0]._port, DEFAULT_SUBSCRIBE_PORT) self.assertEqual(self.config['subscribe'][0]._host, "test") # If a port isn't specified, use the default. self.config.parseOptions(self.cmd_line + ["--subscribe", f"test"]) self.assertEqual(len(self.config['subscribe']), 1) self.assertEqual(self.config['subscribe'][0]._port, DEFAULT_SUBSCRIBE_PORT) self.assertEqual(self.config['subscribe'][0]._host, "test") # Specifying multiple endpoints to a single --subscribe option should # fail to parse. self._check_bad_parse(self.cmd_line + [ f"--subscribe", f"tcp:test:{DEFAULT_SUBSCRIBE_PORT}", f"tcp:test2:{DEFAULT_SUBSCRIBE_PORT}" ]) # Specifying multiple endpoints to with multiple --subscribe options # should succeed. self.config.parseOptions(self.cmd_line + [ f"--subscribe", f"tcp:test:{DEFAULT_SUBSCRIBE_PORT}", f"--subscribe", f"tcp:test2:{DEFAULT_SUBSCRIBE_PORT+1}" ]) self.assertEqual(len(self.config['subscribe']), 2) self.assertEqual(self.config['subscribe'][0]._port, DEFAULT_SUBSCRIBE_PORT) self.assertEqual(self.config['subscribe'][0]._host, "test") self.assertEqual(self.config['subscribe'][1]._port, DEFAULT_SUBSCRIBE_PORT + 1) self.assertEqual(self.config['subscribe'][1]._host, "test2") def test_filter(self): # By default, no filters are specified. self.config.parseOptions(self.cmd_line) self.assertIsNone(self.config['filters']) # A single valid XPath expression should be accepted as a filter. self.config.parseOptions(self.cmd_line + ["--filter", "foo"]) self.assertEqual(len(self.config['filters']), 1) self.assertEqual(self.config['filters'][0], "foo") # Multiple valid XPath expressions should be accepted. self.config.parseOptions(self.cmd_line + ["--filter", "foo", "--filter", "bar"]) self.assertEqual(len(self.config['filters']), 2) self.assertIn("foo", self.config['filters']) self.assertIn("bar", self.config['filters']) # But each ``--filter`` option only takes one argument. self._check_bad_parse(self.cmd_line + ["--filter", "foo", "bar"]) # An invalid filter should be rejected. self._check_bad_parse(self.cmd_line + ["--filter", "\/\/\/\/"]) def test_cmd(self): # By default, no handlers are specified. self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 0) # A single cmd results in a single handler. self.config.parseOptions(self.cmd_line + ["--cmd", "foo"]) self.assertEqual(len(self.config['handlers']), 1) self.assertEqual(self.config['handlers'][0].cmd, "foo") # Multiple cmds may be specified self.config.parseOptions(self.cmd_line + ["--cmd", "foo", "--cmd", "bar"]) self.assertEqual(len(self.config['handlers']), 2) self.assertEqual(self.config['handlers'][0].cmd, "foo") self.assertEqual(self.config['handlers'][1].cmd, "bar") # But each ``--cmd`` option only takes one argument. self._check_bad_parse(self.cmd_line + ["--cmd", "foo", "bar"]) def test_has_print_event_plugin(self): self.config.parseOptions(self.cmd_line + ["--print-event"]) self.assertEqual(len(self.config['handlers']), 1) self.assertEqual(self.config['handlers'][0].name, "print-event") def test_has_save_event_plugin(self): self.config.parseOptions(self.cmd_line + ["--save-event"]) self.assertEqual(len(self.config['handlers']), 1) self.assertEqual(self.config['handlers'][0].name, "save-event") def test_save_event_plugin_takes_args(self): ["--save-event", "--save-event-directory=/tmp"] self.config.parseOptions( self.cmd_line + ["--save-event", "--save-event-directory=/tmp"]) self.assertEqual(self.config['handlers'][0].name, "save-event") self.assertEqual(self.config['handlers'][0].directory, "/tmp") def test_args_for_disabled_plugin(self): # Should not enable the plugin self.cmd_line.append("--save-event-directory=/tmp") self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 0)
def setUp(self): self.config = Options() # Note that parsing from the command line always results in a str, # regardless of whether we're running Python 2. self.cmd_line = ["--local-ivo", DUMMY_SERVICE_IVOID.decode()]
class DefaultOptionsTestCase(unittest.TestCase): def setUp(self): self.config = Options() # Note that parsing from the command line always results in a str, # regardless of whether we're running Python 2. self.cmd_line = ["--local-ivo", DUMMY_SERVICE_IVOID.decode()] def test_faulty_cmd_line(self): self.cmd_line.append("--not-a-real-option") self.assertRaises( usage.UsageError, self.config.parseOptions, self.cmd_line ) def test_test_event_loop(self): self.assertEqual(self.config['broadcast-test-interval'], BCAST_TEST_INTERVAL) self.cmd_line.extend(["--broadcast-test-interval", "0"]) self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['broadcast-test-interval'], 0) def test_enable_receive(self): self.assertFalse(self.config['receive']) self.cmd_line.append("--receive") self.config.parseOptions(self.cmd_line) self.assertTrue(self.config['receive']) def test_enable_broadcast(self): self.assertFalse(self.config['broadcast']) self.cmd_line.append("--broadcast") self.config.parseOptions(self.cmd_line) self.assertTrue(self.config['broadcast']) def test_remotes(self): HOST0, PORT = "dummy_0", 0 HOST1 = "dummy_1" self.cmd_line.extend(["--remote", "%s:%d" % (HOST0, PORT), "--remote", HOST1]) self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['remotes']), 2) self.assertTrue((HOST0, PORT) in self.config['remotes']) self.assertTrue((HOST1, DEFAULT_REMOTE_PORT) in self.config['remotes']) def _test_empty_whitelist(self, whitelist_name): self.config.parseOptions(self.cmd_line) self.assertEqual(self.config[whitelist_name], [ip_network("0.0.0.0/0")]) def test_default_broadcast_whitelist(self): self._test_empty_whitelist('subscriber-whitelist') def test_default_submission_whitelist(self): self._test_empty_whitelist('author-whitelist') def _test_populated_whitelist(self, whitelist_name): net1, net2 = "1.2.3.4/32", "4.3.2.1/255.255.0.0" cmd_line_flag = "--%s" % (whitelist_name,) self.cmd_line.extend([cmd_line_flag, net1, cmd_line_flag, net2]) self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config[whitelist_name]), 2) for net in [net1, net2]: self.assertTrue( ip_network(net, strict=False) in self.config[whitelist_name] ) def test_populated_broadcast_whitelist(self): self._test_populated_whitelist('subscriber-whitelist') def test_populated_submission_whitelist(self): self._test_populated_whitelist('author-whitelist') def test_has_print_event_plugin(self): self.cmd_line.append("--print-event") self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 1) self.assertEqual(self.config['handlers'][0].name, "print-event") def test_has_save_event_plugin(self): self.cmd_line.append("--save-event") self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 1) self.assertEqual(self.config['handlers'][0].name, "save-event") def test_save_event_plugin_takes_args(self): self.cmd_line.extend(["--save-event", "--save-event-directory=/tmp"]) self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['handlers'][0].name, "save-event") self.assertEqual(self.config['handlers'][0].directory, "/tmp") def test_args_for_disabled_plugin(self): # Should not enable the plugin self.cmd_line.append("--save-event-directory=/tmp") self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 0) def test_action_non_extant(self): action = "does-not-exist" self.cmd_line.extend(["--action", action]) self.assertRaises(usage.UsageError, self.config.parseOptions, self.cmd_line) def test_filters(self): self.cmd_line.extend(["--filter", "foo", "--filter", "bar"]) self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['filters']), 2) def test_invalid_filter(self): self.cmd_line.extend(["--filter", "not(starts-with("]) self.assertRaises(usage.UsageError, self.config.parseOptions, self.cmd_line) def test_cmd(self): self.cmd_line.extend(["--cmd", "foo", "--cmd", "bar"]) self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 2) def test_verbose_default(self): self.config.parseOptions(self.cmd_line) self.assertEqual(log.LEVEL, log.DEFAULT_LEVEL) def test_verbose_verbose(self): self.cmd_line.append('-v') self.config.parseOptions(self.cmd_line) self.assertEqual(log.LEVEL, log.Levels.DEBUG) def test_verbose_quiet(self): self.cmd_line.append('-q') self.config.parseOptions(self.cmd_line) self.assertEqual(log.LEVEL, log.Levels.WARNING) def test_verbose_contradictory(self): self.cmd_line.extend(['-q', '-v']) self.config.parseOptions(self.cmd_line) self.assertEqual(log.LEVEL, log.DEFAULT_LEVEL) def test_valid_ivoid(self): self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['local-ivo'], DUMMY_SERVICE_IVOID.decode()) def test_invalid_ivoid(self): self.cmd_line.extend(["--local-ivo", "ivo://"]) self.assertRaises(usage.UsageError, self.config.parseOptions, self.cmd_line) def test_ivoid_missing(self): # It's fine not to provide an IVOID on the command line as of the VTP2 # spec, as long as we're only operating as a subscriber. self.config.parseOptions("") # But it's required if we act as broadcaster or receiver. self.assertRaises(usage.UsageError, self.config.parseOptions, "-b") self.assertRaises(usage.UsageError, self.config.parseOptions, "-r")
class BrokerServiceTestCase(unittest.TestCase): def setUp(self): self.config = Options() def _make_service(self, options): self.config.parseOptions(options) return makeService(self.config) def test_has_services(self): # Demonstrate that we can create appropriate numbers of services. # A single receiver. service = self._make_service(['--local-ivo', 'ivo://comet/test', '--receive']) self.assertEqual(len(service.services), 1) # A single broadcaster. service = self._make_service(['--local-ivo', 'ivo://comet/test', '--broadcast']) self.assertEqual(len(service.services), 1) # A single subscriber. service = self._make_service(['--local-ivo', 'ivo://comet/test', '--subscribe', "tcp:test:12345"]) self.assertEqual(len(service.services), 1) # All of the above. service = self._make_service(['--local-ivo', 'ivo://comet/test', '--receive', '--broadcast', '--subscribe', "tcp:test:12345"]) self.assertEqual(len(service.services), 3) # Multiple instances of each service. service = self._make_service(['--local-ivo', 'ivo://comet/test', '--receive', '--broadcast', '--receive', 'tcp:1234', '--broadcast', 'tcp:4321', '--subscribe', "tcp:test:12345", '--subscribe', "tcp:test:54321"]) self.assertEqual(len(service.services), 6) def _check_bind_failure(self, service): # Check that starting the service raises a CannotListenError. try: self.assertRaises(CannotListenError, service.startService) finally: # Necessary to clean the reactor; this is black magic, determined # by trial and error(!). for s in service: if s._waitingForPort: s.stopService() def test_failure_to_bind_receiver(self): # Attempting to bind to the same port twice should fail. service = self._make_service(['--local-ivo', 'ivo://comet/test', '--receive', 'tcp:1234', '--receive', 'tcp:1234']) self._check_bind_failure(service) def test_failure_to_bind_broadcaster(self): # Attempting to bind to the same port twice should fail. service = self._make_service(['--local-ivo', 'ivo://comet/test', '--broadcast', 'tcp:1234', '--broadcast', 'tcp:1234']) self._check_bind_failure(service) def test_no_service(self): # When we ask for no services on the command line, nothing should be # started -- but we also shouldn't raise. # Note we need to stub out the reactor's callWhenRunning() method, # because makeService schedules a reactor.stop() which will bring our # test cases crashing down. oldCallWhenRunning = reactor.callWhenRunning class MockCallWhenRunning(object): def __init__(self): self.call_count = 0 def __call__(self, *args, **kwargs): self.call_count += 1 mockCallWhenRunning = MockCallWhenRunning() try: reactor.callWhenRunning = mockCallWhenRunning service = self._make_service(['--local-ivo', 'ivo://comet/test']) finally: # Be sure to return the reactor to its initial state when done. reactor.callWhenRunning = oldCallWhenRunning # No services created. self.assertEqual(len(service.namedServices), 0) # Should have been called twice: once for logging, once to stop the # reactor. We are not actually checking the values of those calls # here, though. self.assertEqual(mockCallWhenRunning.call_count, 2) def tearDown(self): for call in reactor.getDelayedCalls(): call.cancel()
class BrokerOptionsTestCase(unittest.TestCase, OptionTestUtils): def setUp(self): self.config = Options() self.cmd_line = ["--local-ivo", DUMMY_SERVICE_IVOID.decode()] def _check_server_endpoints(self, option_name, default_port): # Check for a set of server endpoints specifed by ``--option_name``. # If not specified, we shouldn't receive at all. self.config.parseOptions(self.cmd_line) self.assertIsNone(self.config[option_name]) # If specified with no argument, use the default endpoint. self.config.parseOptions(self.cmd_line + [f"--{option_name}"]) self.assertEqual(len(self.config[option_name]), 1) self.assertEqual(self.config[option_name][0]._port, default_port) # If specified with an argument, use that. self.config.parseOptions(self.cmd_line + [f"--{option_name}", "tcp:1"]) self.assertEqual(len(self.config[option_name]), 1) self.assertEqual(self.config[option_name][0]._port, 1) # If specified without a protocol type, default to TCP. self.config.parseOptions(self.cmd_line + [f"--{option_name}", "1"]) self.assertEqual(len(self.config[option_name]), 1) self.assertEqual(self.config[option_name][0]._port, 1) # If specified with an argument AND without, do both. self.config.parseOptions(self.cmd_line + [f"--{option_name}", f"--{option_name}", "tcp:1"]) self.assertEqual(len(self.config[option_name]), 2) self.assertEqual(self.config[option_name][0]._port, default_port) self.assertEqual(self.config[option_name][1]._port, 1) # And it should work with a Unix domain socket. self.config.parseOptions(self.cmd_line + [f"--{option_name}", "unix:/test"]) self.assertEqual(len(self.config[option_name]), 1) self.assertEqual(self.config[option_name][0]._address, "/test") # But not with garbage. self._check_bad_parse(self.cmd_line + [f"--{option_name}", "bad"]) def _check_whitelist(self, option_name): # Check that ``option_name`` corresponds to a default-allow whitelist. def check_wl_contents(wl, expected_values): # Check the contents of a whitelist against a model self.assertEqual(len(wl), len(expected_values)) for net in expected_values: self.assertIn(net, wl) config_name = option_name.replace("-", "_") NET_DEFAULT, NET1, NET2 = "0.0.0.0/0", "10.0.0.0/8", "172.16.0.0/12" # By default, everything is whitelisted. self.config.parseOptions(self.cmd_line) check_wl_contents(self.config[config_name], [ip_network(NET_DEFAULT)]) # If a single argument is supplied, it replaces the default. self.config.parseOptions(self.cmd_line + [f"--{option_name}", NET1]) check_wl_contents(self.config[config_name], [ip_network(NET1)]) # If two arguments is supplied, use both self.config.parseOptions(self.cmd_line + [f"--{option_name}", NET1, NET2]) check_wl_contents(self.config[config_name], [ip_network(NET1), ip_network(NET2)]) # If --receive-whitelist is supplied twice, use only the second. self.config.parseOptions(self.cmd_line + [f"--{option_name}", NET1, f"--{option_name}", NET2]) check_wl_contents(self.config[config_name], [ip_network(NET2)]) def test_return_self(self): # parseOptions() should return `self.config` for convenience. self.assertEqual(self.config, self.config.parseOptions(self.cmd_line)) def test_local_ivoid(self): # The local IVOID should be set correctly. self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['local_ivo'], DUMMY_SERVICE_IVOID.decode()) # And a bad one rejected. self._check_bad_parse(["--local-ivo", "bad_ivo"]) def test_ivoid_required(self): # A local IVOID is not required _unless_ a broadcaster and/or a # receiver is running. # Should be fine self.config.parseOptions(self.cmd_line + ["--receive"]) self.config.parseOptions(self.cmd_line + ["--broadcast"]) self.config.parseOptions(self.cmd_line + ["--broadcast", "--receive"]) # Should fail self._check_bad_parse(["--receive"]) self._check_bad_parse(["--broadcast"]) self._check_bad_parse(["--receive", "--broadcast"]) def test_eventdb(self): # Default value should be a directory. self.assertTrue(os.path.isdir(self.config.parseOptions(self.cmd_line) ['eventdb'])) # Specifying our own directory should also work. dirname = "/example" self.assertEqual(self.config.parseOptions(["--eventdb", dirname])['eventdb'], dirname) def test_receive(self): # Check that ``--receive`` properly sets up server endpoints. self._check_server_endpoints("receive", DEFAULT_SUBMIT_PORT) def test_receive_whitelist(self): # Check that we create a whitelist for receivers. self._check_whitelist("receive-whitelist") def test_broadcast(self): # Check that ``--broadcast`` properly sets up server endpoints. self._check_server_endpoints("broadcast", DEFAULT_SUBSCRIBE_PORT) def test_broadcast_test_interval(self): # Check that the default is set. self.config.parseOptions(self.cmd_line) self.assertEqual(self.config['broadcast_test_interval'], BCAST_TEST_INTERVAL) # And can be over-ridden. self.config.parseOptions(self.cmd_line + ["--broadcast-test-interval", 0]) self.assertEqual(self.config['broadcast_test_interval'], 0) def test_broadcast_whitelist(self): # Check that we create a whitelist for broadcasters. self._check_whitelist("broadcast-whitelist") def test_subscribe(self): # By default, we subscribe to nothing. self.config.parseOptions(self.cmd_line) self.assertIsNone(self.config['subscribe']) # --subscribe always requires an egument. self._check_bad_parse(self.cmd_line + ["--subscribe"]) # Specifying a single endpoint should add that to the list of # subcribers. self.config.parseOptions(self.cmd_line + ["--subscribe", f"tcp:test:{DEFAULT_SUBSCRIBE_PORT}"]) self.assertEqual(len(self.config['subscribe']), 1) self.assertEqual(self.config['subscribe'][0]._port, DEFAULT_SUBSCRIBE_PORT) self.assertEqual(self.config['subscribe'][0]._host, "test") # If a protocol isn't specified, assume TCP. self.config.parseOptions(self.cmd_line + ["--subscribe", f"test:{DEFAULT_SUBSCRIBE_PORT}"]) self.assertEqual(len(self.config['subscribe']), 1) self.assertEqual(self.config['subscribe'][0]._port, DEFAULT_SUBSCRIBE_PORT) self.assertEqual(self.config['subscribe'][0]._host, "test") # If a port isn't specified, use the default. self.config.parseOptions(self.cmd_line + ["--subscribe", f"test"]) self.assertEqual(len(self.config['subscribe']), 1) self.assertEqual(self.config['subscribe'][0]._port, DEFAULT_SUBSCRIBE_PORT) self.assertEqual(self.config['subscribe'][0]._host, "test") # Specifying multiple endpoints to a single --subscribe option should # fail to parse. self._check_bad_parse(self.cmd_line + [f"--subscribe", f"tcp:test:{DEFAULT_SUBSCRIBE_PORT}", f"tcp:test2:{DEFAULT_SUBSCRIBE_PORT}"]) # Specifying multiple endpoints to with multiple --subscribe options # should succeed. self.config.parseOptions(self.cmd_line + [f"--subscribe", f"tcp:test:{DEFAULT_SUBSCRIBE_PORT}", f"--subscribe", f"tcp:test2:{DEFAULT_SUBSCRIBE_PORT+1}"]) self.assertEqual(len(self.config['subscribe']), 2) self.assertEqual(self.config['subscribe'][0]._port, DEFAULT_SUBSCRIBE_PORT) self.assertEqual(self.config['subscribe'][0]._host, "test") self.assertEqual(self.config['subscribe'][1]._port, DEFAULT_SUBSCRIBE_PORT + 1) self.assertEqual(self.config['subscribe'][1]._host, "test2") def test_filter(self): # By default, no filters are specified. self.config.parseOptions(self.cmd_line) self.assertIsNone(self.config['filters']) # A single valid XPath expression should be accepted as a filter. self.config.parseOptions(self.cmd_line + ["--filter", "foo"]) self.assertEqual(len(self.config['filters']), 1) self.assertEqual(self.config['filters'][0], "foo") # Multiple valid XPath expressions should be accepted. self.config.parseOptions(self.cmd_line + ["--filter", "foo", "--filter", "bar"]) self.assertEqual(len(self.config['filters']), 2) self.assertIn("foo", self.config['filters']) self.assertIn("bar", self.config['filters']) # But each ``--filter`` option only takes one argument. self._check_bad_parse(self.cmd_line + ["--filter", "foo", "bar"]) # An invalid filter should be rejected. self._check_bad_parse(self.cmd_line + ["--filter", "\/\/\/\/"]) def test_cmd(self): # By default, no handlers are specified. self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 0) # A single cmd results in a single handler. self.config.parseOptions(self.cmd_line + ["--cmd", "foo"]) self.assertEqual(len(self.config['handlers']), 1) self.assertEqual(self.config['handlers'][0].cmd, "foo") # Multiple cmds may be specified self.config.parseOptions(self.cmd_line + ["--cmd", "foo", "--cmd", "bar"]) self.assertEqual(len(self.config['handlers']), 2) self.assertEqual(self.config['handlers'][0].cmd, "foo") self.assertEqual(self.config['handlers'][1].cmd, "bar") # But each ``--cmd`` option only takes one argument. self._check_bad_parse(self.cmd_line + ["--cmd", "foo", "bar"]) def test_has_print_event_plugin(self): self.config.parseOptions(self.cmd_line + ["--print-event"]) self.assertEqual(len(self.config['handlers']), 1) self.assertEqual(self.config['handlers'][0].name, "print-event") def test_has_save_event_plugin(self): self.config.parseOptions(self.cmd_line + ["--save-event"]) self.assertEqual(len(self.config['handlers']), 1) self.assertEqual(self.config['handlers'][0].name, "save-event") def test_save_event_plugin_takes_args(self): ["--save-event", "--save-event-directory=/tmp"] self.config.parseOptions(self.cmd_line + ["--save-event", "--save-event-directory=/tmp"]) self.assertEqual(self.config['handlers'][0].name, "save-event") self.assertEqual(self.config['handlers'][0].directory, "/tmp") def test_args_for_disabled_plugin(self): # Should not enable the plugin self.cmd_line.append("--save-event-directory=/tmp") self.config.parseOptions(self.cmd_line) self.assertEqual(len(self.config['handlers']), 0)