Ejemplo n.º 1
0
 def test__deferDHCPRequests(self):
     clock = Clock()
     monitor = DHCPRequestMonitor('lo', clock)
     mock_addErrback = mock.MagicMock()
     mock_deferredListResult = mock.MagicMock()
     mock_deferLater = self.patch(detect_module, 'deferLater')
     mock_deferLater.return_value = mock.MagicMock()
     mock_deferLater.return_value.addErrback = mock_addErrback
     mock_DeferredList = self.patch(detect_module, 'DeferredList')
     mock_DeferredList.return_value = mock_deferredListResult
     mock_deferredListResult.addErrback = mock_addErrback
     expected_calls = [
         call(
             clock, seconds + 0.1, send_dhcp_request_packet,
             DHCPDiscoverPacket(transaction_id=monitor.transaction_id,
                                seconds=seconds), 'lo')
         for seconds in DHCP_REQUEST_TIMING
     ]
     monitor.deferDHCPRequests()
     self.assertThat(mock_deferLater, MockCallsMatch(*expected_calls))
     self.assertThat(
         mock_DeferredList,
         MockCallsMatch(
             call(monitor.deferredDHCPRequests,
                  fireOnOneErrback=True,
                  consumeErrors=True)))
     # Expect addErrback to be called both on each individual Deferred, plus
     # one more time on the DeferredList.
     expected_errback_calls = [
         call(monitor.deferredDHCPRequestErrback)
         for _ in range(len(DHCP_REQUEST_TIMING) + 1)
     ]
     self.assertThat(mock_addErrback,
                     MockCallsMatch(*expected_errback_calls))
Ejemplo n.º 2
0
 def test__deferredDHCPRequestErrback_logs_known_exceptions(self):
     logger = self.useFixture(TwistedLoggerFixture())
     monitor = DHCPRequestMonitor("lo")
     error = factory.make_string()
     monitor.deferredDHCPRequestErrback(
         make_Failure(DHCPProbeException, error))
     self.assertThat(logger.output,
                     DocTestMatches("DHCP probe failed. %s" % error))
Ejemplo n.º 3
0
 def test__deferredDHCPRequestErrback_logs_unknown_exceptions(self):
     logger = self.useFixture(TwistedLoggerFixture())
     monitor = DHCPRequestMonitor('lo')
     error = factory.make_string()
     monitor.deferredDHCPRequestErrback(make_Failure(IOError, error))
     self.assertThat(
         logger.output,
         DocTestMatches("...unknown error...Traceback...%s" % error))
Ejemplo n.º 4
0
 def test__run_skips_logging_if_no_servers_found(self):
     logger = self.useFixture(TwistedLoggerFixture())
     monitor = DHCPRequestMonitor("lo")
     mock_send_and_await = self.patch(monitor,
                                      "send_requests_and_await_replies")
     mock_send_and_await.return_value = {}
     yield monitor.run()
     self.assertThat(mock_send_and_await, MockCallsMatch(call()))
     self.assertThat(logger.output, DocTestMatches(""))
Ejemplo n.º 5
0
    def test__cancelAll(self):
        self.errbacks_called = 0

        def mock_errback(result: Failure):
            self.assertTrue(result.check(CancelledError))
            self.errbacks_called += 1

        a = deferLater(reactor, 6, lambda: "a")
        b = deferLater(reactor, 6, lambda: "b")
        a.addBoth(mock_errback)
        b.addBoth(mock_errback)
        deferreds = [a, b]
        DHCPRequestMonitor.cancelAll(deferreds)
        deferredList = DeferredList(deferreds)
        yield deferredList
        self.assertThat(self.errbacks_called, Equals(2))
Ejemplo n.º 6
0
    def test__deferredDHCPRequestErrback_cancels_all_on_FirstError(self):
        mock_cancelAll = self.patch(DHCPRequestMonitor, 'cancelAll')

        def raise_ioerror():
            raise IOError()

        a = deferLater(reactor, 0.0, raise_ioerror)
        b = deferLater(reactor, 6, lambda: 'b')
        monitor = DHCPRequestMonitor('lo')
        monitor.deferredDHCPRequests = [a, b]
        deferredList = DeferredList(monitor.deferredDHCPRequests,
                                    consumeErrors=True,
                                    fireOnOneErrback=True)
        deferredList.addErrback(monitor.deferredDHCPRequestErrback)
        yield deferredList
        # Still have one call left in the reactor, since we mocked cancelAll().
        b.cancel()
        self.assertThat(mock_cancelAll, MockCallsMatch(call([a, b])))
Ejemplo n.º 7
0
 def test__run_logs_result_and_makes_properties_available(self):
     logger = self.useFixture(TwistedLoggerFixture())
     monitor = DHCPRequestMonitor('lo')
     mock_send_and_await = self.patch(monitor,
                                      'send_requests_and_await_replies')
     mock_send_and_await.return_value = {
         DHCPServer('127.0.0.1', '127.0.0.1'),
         DHCPServer('127.1.1.1', '127.2.2.2'),
     }
     yield monitor.run()
     self.assertThat(mock_send_and_await, MockCallsMatch(call()))
     self.assertThat(
         logger.output,
         DocTestMatches(
             "External DHCP server(s) discovered on interface 'lo': 127.0.0.1, "
             "127.1.1.1 (via 127.2.2.2)"))
     self.assertThat(monitor.dhcp_servers,
                     Equals({"127.0.0.1", "127.1.1.1"}))
     self.assertThat(monitor.dhcp_addresses,
                     Equals({"127.0.0.1", "127.2.2.2"}))
Ejemplo n.º 8
0
 def test__deferredDHCPRequestErrback_ignores_cancelled(self):
     logger = self.useFixture(TwistedLoggerFixture())
     monitor = DHCPRequestMonitor("lo")
     error = factory.make_string()
     monitor.deferredDHCPRequestErrback(make_Failure(CancelledError, error))
     self.assertThat(logger.output, DocTestMatches(""))
Ejemplo n.º 9
0
 def test__send_requests_and_await_replies(self):
     # This test is a bit large because it covers the entire functionality
     # of the `send_requests_and_await_replies()` method. (It could be
     # split apart into multiple tests, but the large amount of setup work
     # and interdependencies makes that a maintenance burden.)
     mock_socket = patch_socket(self)
     mock_socket.bind = mock.MagicMock()
     mock_socket.recvfrom = mock.MagicMock()
     mock_socket.setsockopt = mock.MagicMock()
     mock_socket.settimeout = mock.MagicMock()
     # Pretend we were successful at deferring the DHCP requests.
     self.patch_autospec(detect_module, "blockingCallFromThread")
     # This method normally blocks for ~10 seconds, so take control of the
     # monotonic clock and make sure the last call to `recvfrom()` happens
     # just as we hit the reply timeout.
     mock_time_monotonic = self.patch(detect_module.time.monotonic)
     mock_time_monotonic.side_effect = (
         # Start time (before loop starts).
         10,
         # First reply (truncated packet).
         11,
         # Second reply (not a match to our transaction).
         12,
         # Third reply (Matching reply with server identifier option).
         13,
         # First socket timeout (need to make sure the loop continues).
         14,
         # Second socket timeout (hey, we're done!).
         10 + detect_module.REPLY_TIMEOUT,
     )
     mock_xid = factory.make_bytes(4)
     valid_dhcp_reply = factory.make_dhcp_packet(
         transaction_id=mock_xid,
         include_server_identifier=True,
         server_ip="127.1.1.1",
     )
     mock_get_xid = self.patch(detect_module.make_dhcp_transaction_id)
     mock_get_xid.return_value = mock_xid
     # Valid DHCP packet, but not a match because it doesn't have a
     # Server Identifier option.
     valid_non_match = DHCPDiscoverPacket(mac="01:02:03:04:05:06",
                                          transaction_id=mock_xid).packet
     mock_socket.recvfrom.side_effect = (
         # Truncated packet, to test logging.
         (b"", ("127.0.0.1", BOOTP_SERVER_PORT)),
         (valid_non_match, ("127.0.0.2", BOOTP_SERVER_PORT)),
         (valid_dhcp_reply, ("127.0.0.3", BOOTP_SERVER_PORT)),
         socket.timeout,
         socket.timeout,
     )
     logger = self.useFixture(TwistedLoggerFixture())
     monitor = DHCPRequestMonitor("lo", Clock())
     result = monitor.send_requests_and_await_replies()
     self.assertThat(
         mock_socket.setsockopt,
         MockCallsMatch(
             call(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1),
             call(socket.SOL_SOCKET, socket.SO_BROADCAST, 1),
         ),
     )
     self.assertThat(mock_socket.bind, MockCallsMatch(call(("", 68))))
     self.assertThat(
         mock_socket.settimeout,
         MockCallsMatch(call(detect_module.SOCKET_TIMEOUT)),
     )
     self.assertThat(
         mock_socket.recvfrom,
         MockCallsMatch(call(2048), call(2048), call(2048), call(2048),
                        call(2048)),
     )
     # One of the response packets was truncated.
     self.assertThat(
         logger.output,
         DocTestMatches("Invalid DHCP response...Truncated..."),
     )
     self.assertThat(result, HasLength(1))
     # Ensure we record the fact that the reply packet came from a different
     # IP address than the server claimed to be.
     self.assertThat(result, Contains(DHCPServer("127.1.1.1", "127.0.0.3")))