def setUp(self): super(ComponentConnectorTest, self).setUp() self.reactor = FakeReactor() # XXX this should be dropped once the FakeReactor doesn't use the # real reactor anymore under the hood. self.reactor._reactor = Clock() self.config = Configuration() self.config.data_path = self.makeDir() self.makeDir(path=self.config.sockets_path) self.connector = TestComponentConnector(self.reactor, self.config)
def setUp(self): super(PackageTaskHandlerTest, self).setUp() self.config = PackageTaskHandlerConfiguration() self.store = PackageStore(self.makeFile()) self.reactor = FakeReactor() self.handler = PackageTaskHandler(self.store, self.facade, self.remote, self.config, self.reactor)
def set_up(self, test_case): super(BrokerClientHelper, self).set_up(test_case) # The client needs its own reactor to avoid infinite loops # when the broker broadcasts and event test_case.client_reactor = FakeReactor() test_case.client = BrokerClient(test_case.client_reactor) test_case.client.broker = test_case.remote
def set_up(self, test_case): super(ManagerHelper, self).set_up(test_case) test_case.config = ManagerConfiguration() test_case.config.load(["-c", test_case.config_filename]) test_case.reactor = FakeReactor() test_case.manager = Manager(test_case.reactor, test_case.config) test_case.manager.broker = test_case.remote
def setUp(self): super(LandscapeServiceTest, self).setUp() self.config = Configuration() self.config.data_path = self.makeDir() self.makeDir(path=self.config.sockets_path) self.reactor = FakeReactor() signal.signal(signal.SIGUSR1, signal.SIG_DFL)
def set_up(self, test_case): super(BrokerServiceHelper, self).set_up(test_case) test_case.broker_service.startService() # Use different reactor to simulate separate processes self._connector = RemoteBrokerConnector( FakeReactor(), test_case.broker_service.config) deferred = self._connector.connect() test_case.remote = test_case.successResultOf(deferred)
def set_up(self, test_case): super(BrokerClientHelper, self).set_up(test_case) # The client needs its own reactor to avoid infinite loops # when the broker broadcasts and event test_case.client_reactor = FakeReactor() config = BrokerConfiguration() config.stagger_launch = 0 # let's keep tests deterministic test_case.client = BrokerClient(test_case.client_reactor, config) test_case.client.broker = test_case.remote
def set_up(self, test_case): super(MonitorHelper, self).set_up(test_case) persist = Persist() persist_filename = test_case.makePersistFile() test_case.config = MonitorConfiguration() test_case.config.load(["-c", test_case.config_filename]) test_case.reactor = FakeReactor() test_case.monitor = Monitor(test_case.reactor, test_case.config, persist, persist_filename) test_case.monitor.broker = test_case.remote test_case.mstore = test_case.broker_service.message_store
def setUp(self): super(ComponentPublisherTest, self).setUp() reactor = FakeReactor() config = Configuration() config.data_path = self.makeDir() self.makeDir(path=config.sockets_path) self.component = TestComponent() self.publisher = ComponentPublisher(self.component, reactor, config) self.publisher.start() self.connector = TestComponentConnector(reactor, config) connected = self.connector.connect() connected.addCallback(lambda remote: setattr(self, "remote", remote)) return connected
def set_up(self, test_case): super(ExchangeHelper, self).set_up(test_case) test_case.persist_filename = test_case.makePersistFile() test_case.persist = Persist(filename=test_case.persist_filename) test_case.mstore = get_default_message_store( test_case.persist, test_case.config.message_store_path) test_case.identity = Identity(test_case.config, test_case.persist) test_case.transport = FakeTransport(None, test_case.config.url, test_case.config.ssl_public_key) test_case.reactor = FakeReactor() test_case.exchange_store = ExchangeStore( test_case.config.exchange_store_path) test_case.exchanger = MessageExchange( test_case.reactor, test_case.mstore, test_case.transport, test_case.identity, test_case.exchange_store, test_case.config)
def test_wb_is_lazy(self): """ The L{LazyRemoteBroker} class doesn't initialize the actual remote broker until one of its attributes gets actually accessed. """ reactor = FakeReactor() connector = RemoteBrokerConnector(reactor, self.broker_service.config) self.broker = LazyRemoteBroker(connector) self.assertIs(self.broker._remote, None) def close_connection(result): self.assertTrue(result) connector.disconnect() result = self.broker.ping() return result.addCallback(close_connection)
def test_errors_are_printed_and_exit_program(self, init_logging_mock): class MyException(Exception): pass self.log_helper.ignore_errors(MyException) class HandlerMock(PackageTaskHandler): def run(self): return fail(MyException("Hey error")) # Ok now for some real stuff def assert_log(ignored): self.assertIn("MyException", self.logfile.getvalue()) init_logging_mock.assert_called_once_with(ANY, "handler-mock") result = run_task_handler(HandlerMock, ["-c", self.config_filename], reactor=FakeReactor()) return result.addCallback(assert_log)
def test_start_stop(self): """ The L{BrokerService.startService} method makes the process start listening to the broker socket, and starts the L{Exchanger} and the L{Pinger} as well. """ self.service.exchanger.start = Mock() self.service.pinger.start = Mock() self.service.exchanger.stop = Mock() self.service.startService() reactor = FakeReactor() connector = RemoteBrokerConnector(reactor, self.config) connected = connector.connect() connected.addCallback(lambda remote: remote.get_server_uuid()) connected.addCallback(lambda x: connector.disconnect()) connected.addCallback(lambda x: self.service.stopService()) self.service.exchanger.start.assert_called_with() self.service.pinger.start.assert_called_with() self.service.exchanger.stop.assert_called_with()
def get_reactor(self): return FakeReactor()
class ComponentConnectorTest(LandscapeTest): def setUp(self): super(ComponentConnectorTest, self).setUp() self.reactor = FakeReactor() # XXX this should be dropped once the FakeReactor doesn't use the # real reactor anymore under the hood. self.reactor._reactor = Clock() self.config = Configuration() self.config.data_path = self.makeDir() self.makeDir(path=self.config.sockets_path) self.connector = TestComponentConnector(self.reactor, self.config) def test_connect_with_max_retries(self): """ If C{max_retries} is passed to L{RemoteObjectConnector.connect}, then it will give up trying to connect after that amount of times. """ self.log_helper.ignore_errors("Error while connecting to test") deferred = self.connector.connect(max_retries=2) self.assertNoResult(deferred) return self.failureResultOf(deferred).trap(ConnectError) def test_connect_logs_errors(self): """ Connection errors are logged. """ self.log_helper.ignore_errors("Error while connecting to test") def assert_log(ignored): self.assertIn("Error while connecting to test", self.logfile.getvalue()) result = self.connector.connect(max_retries=0) self.assertFailure(result, ConnectError) return result.addCallback(assert_log) def test_connect_with_quiet(self): """ If the C{quiet} option is passed, no errors will be logged. """ result = self.connector.connect(max_retries=0, quiet=True) return self.assertFailure(result, ConnectError) def test_reconnect_fires_event(self): """ An event is fired whenever the connection is established again after it has been lost. """ reconnects = [] self.reactor.call_on("test-reconnect", lambda: reconnects.append(True)) component = TestComponent() publisher = ComponentPublisher(component, self.reactor, self.config) publisher.start() deferred = self.connector.connect() self.successResultOf(deferred) self.connector._connector.disconnect() # Simulate a disconnection self.assertEqual([], reconnects) self.reactor._reactor.advance(10) self.assertEqual([True], reconnects) def test_connect_with_factor(self): """ If C{factor} is passed to the L{ComponentConnector.connect} method, then the associated protocol factory will be set to that value. """ component = TestComponent() publisher = ComponentPublisher(component, self.reactor, self.config) publisher.start() deferred = self.connector.connect(factor=1.0) remote = self.successResultOf(deferred) self.assertEqual(1.0, remote._factory.factor) def test_disconnect(self): """ It is possible to call L{ComponentConnector.disconnect} multiple times, even if the connection has been already closed. """ component = TestComponent() publisher = ComponentPublisher(component, self.reactor, self.config) publisher.start() self.connector.connect() self.connector.disconnect() self.connector.disconnect() def test_disconnect_without_connect(self): """ It is possible to call L{ComponentConnector.disconnect} even if the connection was never established. In that case the method is effectively a no-op. """ self.connector.disconnect() @mock.patch("twisted.python.lockfile.kill") def test_stale_locks_with_dead_pid(self, mock_kill): """Publisher starts with stale lock.""" mock_kill.side_effect = [OSError(errno.ESRCH, "No such process")] sock_path = os.path.join(self.config.sockets_path, u"test.sock") lock_path = u"{}.lock".format(sock_path) # fake a PID which does not exist os.symlink("-1", lock_path) component = TestComponent() # Test the actual Unix reactor implementation. Fakes won't do. reactor = LandscapeReactor() publisher = ComponentPublisher(component, reactor, self.config) # Shouldn't raise the exception. publisher.start() # ensure stale lock was replaced self.assertNotEqual("-1", os.readlink(lock_path)) mock_kill.assert_called_with(-1, 0) publisher.stop() reactor._cleanup() @mock.patch("twisted.python.lockfile.kill") def test_stale_locks_recycled_pid(self, mock_kill): """Publisher starts with stale lock pointing to recycled process.""" mock_kill.side_effect = [ OSError(errno.EPERM, "Operation not permitted") ] sock_path = os.path.join(self.config.sockets_path, u"test.sock") lock_path = u"{}.lock".format(sock_path) # fake a PID recycled by a known process which isn't landscape (init) os.symlink("1", lock_path) component = TestComponent() # Test the actual Unix reactor implementation. Fakes won't do. reactor = LandscapeReactor() publisher = ComponentPublisher(component, reactor, self.config) # Shouldn't raise the exception. publisher.start() # ensure stale lock was replaced self.assertNotEqual("1", os.readlink(lock_path)) mock_kill.assert_not_called() self.assertFalse(publisher._port.lockFile.clean) publisher.stop() reactor._cleanup() @mock.patch("twisted.python.lockfile.kill") def test_with_valid_lock(self, mock_kill): """Publisher raises lock error if a valid lock is held.""" sock_path = os.path.join(self.config.sockets_path, u"test.sock") lock_path = u"{}.lock".format(sock_path) # fake a landscape process app = self.makeFile(textwrap.dedent("""\ #!/usr/bin/python3 import time time.sleep(10) """), basename="landscape-manager") os.chmod(app, 0o755) call = subprocess.Popen([app]) self.addCleanup(call.terminate) os.symlink(str(call.pid), lock_path) component = TestComponent() # Test the actual Unix reactor implementation. Fakes won't do. reactor = LandscapeReactor() publisher = ComponentPublisher(component, reactor, self.config) with self.assertRaises(CannotListenError): publisher.start() # ensure lock was not replaced self.assertEqual(str(call.pid), os.readlink(lock_path)) mock_kill.assert_called_with(call.pid, 0) reactor._cleanup()
def setUp(self): super(PingClientTest, self).setUp() self.reactor = FakeReactor()
class ComponentConnectorTest(LandscapeTest): def setUp(self): super(ComponentConnectorTest, self).setUp() self.reactor = FakeReactor() # XXX this should be dropped once the FakeReactor doesn't use the # real reactor anymore under the hood. self.reactor._reactor = Clock() self.config = Configuration() self.config.data_path = self.makeDir() self.makeDir(path=self.config.sockets_path) self.connector = TestComponentConnector(self.reactor, self.config) def test_connect_with_max_retries(self): """ If C{max_retries} is passed to L{RemoteObjectConnector.connect}, then it will give up trying to connect after that amount of times. """ self.log_helper.ignore_errors("Error while connecting to test") deferred = self.connector.connect(max_retries=2) self.assertNoResult(deferred) return self.failureResultOf(deferred).trap(ConnectError) def test_connect_logs_errors(self): """ Connection errors are logged. """ self.log_helper.ignore_errors("Error while connecting to test") def assert_log(ignored): self.assertIn("Error while connecting to test", self.logfile.getvalue()) result = self.connector.connect(max_retries=0) self.assertFailure(result, ConnectError) return result.addCallback(assert_log) def test_connect_with_quiet(self): """ If the C{quiet} option is passed, no errors will be logged. """ result = self.connector.connect(max_retries=0, quiet=True) return self.assertFailure(result, ConnectError) def test_reconnect_fires_event(self): """ An event is fired whenever the connection is established again after it has been lost. """ reconnects = [] self.reactor.call_on("test-reconnect", lambda: reconnects.append(True)) component = TestComponent() publisher = ComponentPublisher(component, self.reactor, self.config) publisher.start() deferred = self.connector.connect() self.successResultOf(deferred) self.connector._connector.disconnect() # Simulate a disconnection self.assertEqual([], reconnects) self.reactor._reactor.advance(10) self.assertEqual([True], reconnects) def test_connect_with_factor(self): """ If C{factor} is passed to the L{ComponentConnector.connect} method, then the associated protocol factory will be set to that value. """ component = TestComponent() publisher = ComponentPublisher(component, self.reactor, self.config) publisher.start() deferred = self.connector.connect(factor=1.0) remote = self.successResultOf(deferred) self.assertEqual(1.0, remote._factory.factor) def test_disconnect(self): """ It is possible to call L{ComponentConnector.disconnect} multiple times, even if the connection has been already closed. """ component = TestComponent() publisher = ComponentPublisher(component, self.reactor, self.config) publisher.start() self.connector.connect() self.connector.disconnect() self.connector.disconnect() def test_disconnect_without_connect(self): """ It is possible to call L{ComponentConnector.disconnect} even if the connection was never established. In that case the method is effectively a no-op. """ self.connector.disconnect()