Home | History | Annotate | Download | only in network_DhcpRenew
      1 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import logging
      6 import time
      7 
      8 from autotest_lib.client.common_lib import error
      9 from autotest_lib.client.cros import dhcp_handling_rule
     10 from autotest_lib.client.cros import dhcp_packet
     11 from autotest_lib.client.cros import dhcp_test_base
     12 
     13 # dhcpcd has a 20 second minimal accepted lease time
     14 LEASE_TIME_SECONDS = 20
     15 # dhcpcd should request a renewal after this many seconds.
     16 LEASE_T1_TIME = 10
     17 # dhcpcd will broadcast a REQUEST after this many seconds.
     18 LEASE_T2_TIME = 15
     19 # We had better have lost the lease 25 seconds after we gained it.
     20 DHCP_RENEWAL_TIMEOUT_SECONDS = 25
     21 # We'll fill in the subnet and give this address to the client.
     22 INTENDED_IP_SUFFIX = "0.0.0.101"
     23 # How far off the expected deadlines we'll accept the T1/T2 packets.
     24 RENEWAL_TIME_DELTA_SECONDS = 2.0
     25 # Time by which we are sure shill will give up on the DHCP client.
     26 DHCP_ATTEMPT_TIMEOUT_SECONDS = 40
     27 
     28 class network_DhcpRenew(dhcp_test_base.DhcpTestBase):
     29     """Tests DHCP renewal process in the connection manager."""
     30     def test_body(self):
     31         subnet_mask = self.ethernet_pair.interface_subnet_mask
     32         intended_ip = dhcp_test_base.DhcpTestBase.rewrite_ip_suffix(
     33                 subnet_mask,
     34                 self.server_ip,
     35                 INTENDED_IP_SUFFIX)
     36         # Two real name servers, and a bogus one to be unpredictable.
     37         dns_servers = ["8.8.8.8", "8.8.4.4", "192.168.87.88"]
     38         domain_name = "corp.google.com"
     39         dns_search_list = [
     40                 "corgie.google.com",
     41                 "lies.google.com",
     42                 "that.is.a.tasty.burger.google.com",
     43                 ]
     44         # This is the pool of information the server will give out to the client
     45         # upon request.
     46         dhcp_options = {
     47                 dhcp_packet.OPTION_SERVER_ID : self.server_ip,
     48                 dhcp_packet.OPTION_SUBNET_MASK : subnet_mask,
     49                 dhcp_packet.OPTION_IP_LEASE_TIME : LEASE_TIME_SECONDS,
     50                 dhcp_packet.OPTION_REQUESTED_IP : intended_ip,
     51                 dhcp_packet.OPTION_DNS_SERVERS : dns_servers,
     52                 dhcp_packet.OPTION_DOMAIN_NAME : domain_name,
     53                 dhcp_packet.OPTION_DNS_DOMAIN_SEARCH_LIST : dns_search_list,
     54                 dhcp_packet.OPTION_RENEWAL_T1_TIME_VALUE : LEASE_T1_TIME,
     55                 dhcp_packet.OPTION_REBINDING_T2_TIME_VALUE : LEASE_T2_TIME,
     56                 }
     57         self.negotiate_and_check_lease(dhcp_options)
     58         # This is very imprecise, since there is some built in delay in
     59         # negotiate_new_lease() for settings propagations, but we're not
     60         # interested in microsecond timings anyway.
     61         lease_start_time = time.time()
     62         t1_deadline = lease_start_time + LEASE_T1_TIME
     63         t2_deadline = lease_start_time + LEASE_T2_TIME
     64         # Ignore the T1 deadline packet.
     65         t1_handler = dhcp_handling_rule.DhcpHandlingRule_RespondToRequest(
     66                 intended_ip,
     67                 self.server_ip,
     68                 dhcp_options,
     69                 {},
     70                 should_respond=False)
     71         t1_handler.target_time_seconds = t1_deadline
     72         t1_handler.allowable_time_delta_seconds = RENEWAL_TIME_DELTA_SECONDS
     73         t2_handler = dhcp_handling_rule.DhcpHandlingRule_RespondToPostT2Request(
     74                 intended_ip,
     75                 self.server_ip,
     76                 dhcp_options,
     77                 {},
     78                 should_respond=False)
     79         t2_handler.target_time_seconds = t2_deadline
     80         t2_handler.allowable_time_delta_seconds = RENEWAL_TIME_DELTA_SECONDS
     81         discovery_handler = \
     82                 dhcp_handling_rule.DhcpHandlingRule_RespondToDiscovery(
     83                         intended_ip,
     84                         self.server_ip,
     85                         dhcp_options,
     86                         {},
     87                         should_respond=False)
     88         rules = [t1_handler, t2_handler, discovery_handler]
     89         rules[-1].is_final_handler = True
     90         self.server.start_test(rules, DHCP_RENEWAL_TIMEOUT_SECONDS)
     91         self.server.wait_for_test_to_finish()
     92         if not self.server.last_test_passed:
     93             raise error.TestFail("Test server didn't get all the messages it "
     94                                  "was told to expect for renewal.")
     95 
     96         # The service should leave the connected state after shill attempts
     97         # one last DHCP attempt from scratch.  We may miss the transition to the
     98         # "idle" state since the system immediately attempts to re-connect, so
     99         # we also test for the "configuration" state.
    100         service = self.find_ethernet_service(
    101                 self.ethernet_pair.peer_interface_name)
    102         (successful, state, duration) = self.shill_proxy.wait_for_property_in(
    103                 service,
    104                 self.shill_proxy.SERVICE_PROPERTY_STATE,
    105                 ('failure', 'idle', 'configuration'),
    106                 DHCP_ATTEMPT_TIMEOUT_SECONDS)
    107         if not successful:
    108             raise error.TestFail('Service failed to go idle in %ds (state %s)' %
    109                                  (duration, state))
    110         logging.info('In state "%s" after %d seconds', state, duration)
    111