[autotest] Use fping for moblab DUT discovery.

arp or ip n commands seem to be unreliable at times, showing
phantom IP's when using cisco managed router in the lab but showing
IP addresses as DELAY rather than REACHABLE in the VM.

Switch to a new strategy, just ping the devices and include devices
that have a 0% ping loss.

The change drops detection of the mac address, there is no known
need for it.  Also moblab should always have fping installed it is
in the moblab ebuild as an RDEPEND.

Tryjobs passed guado_moblab-paladin,
https://ci.chromium.org/p/chromeos/builders/luci.chromeos.general/Try/b8943249388377048672

moblab-generic-vm-paladin
https://ci.chromium.org/p/chromeos/builders/luci.chromeos.general/Try/b8943249380296023168

BUG=chromium:853337
TEST=trybot

Change-Id: I96bdf3c70b42081225bbbff69b519216ce166fd9
Reviewed-on: https://chromium-review.googlesource.com/1107238
Commit-Ready: Keith Haddow <haddowk@chromium.org>
Tested-by: Keith Haddow <haddowk@chromium.org>
Reviewed-by: Grant Grundler <grundler@chromium.org>
diff --git a/server/hosts/moblab_host.py b/server/hosts/moblab_host.py
index e400cef..fa6304b 100644
--- a/server/hosts/moblab_host.py
+++ b/server/hosts/moblab_host.py
@@ -23,10 +23,14 @@
 SHADOW_CONFIG_PATH = '%s/shadow_config.ini' % AUTOTEST_INSTALL_DIR
 ATEST_PATH = '%s/cli/atest' % AUTOTEST_INSTALL_DIR
 
-SUBNET_DUT_SEARCH_RE = (
-        r'(?P<ip>192.168.231.1[0-1][0-9]) [^ ]+ [^ ]+ [^ ]+ '
-        '(?P<mac>([0-9a-fA-F][0-9a-fA-F]:){5}[0-9a-fA-F][0-9a-fA-F]) '
-        '(REACHABLE|DELAY)')
+# Sample output of fping that we are matching against, the fping command
+# will return 10 lines but they will be one of these two formats.
+# We want to get the IP address for the first line and not match the
+# second line that has a non 0 %loss.
+#192.168.231.100 : xmt/rcv/%loss = 10/10/0%, min/avg/max = 0.68/0.88/1.13
+#192.168.231.102 : xmt/rcv/%loss = 10/0/100%
+SUBNET_DUT_SEARCH_RE = (r'(?P<ip>192.168.231.1[0-1][0-9]) : '
+                        'xmt\/rcv\/%loss = [0-9]+\/[0-9]+\/0%')
 
 MOBLAB_HOME = '/home/moblab'
 MOBLAB_BOTO_LOCATION = '%s/.boto' % MOBLAB_HOME
@@ -167,26 +171,6 @@
         self.afe.set_timeout(self.timeout_min)
 
 
-    def _wake_devices(self):
-        """Search the subnet and attempt to ping any available duts.
-
-        Fills up the arp table with entries about devices on the subnet.
-
-        Either uses fping or directly pings devices listed in the dhcpd lease
-        file.
-        """
-        fping_result = self.run(('fping -g 192.168.231.100 192.168.231.110 '
-                                 '-a -c 10 -p 30 -q'),
-                                ignore_status=True)
-        # If fping is not on the system, ping entries in the dhcpd lease file.
-        if fping_result.exit_status == 127:
-            leases = set(self.run('grep ^lease %s' % DHCPD_LEASE_FILE,
-                                  ignore_status=True).stdout.splitlines())
-            for lease in leases:
-                ip = re.match('lease (?P<ip>.*) {', lease).groups('ip')
-                self.run('ping %s -w 1' % ip, ignore_status=True)
-
-
     def add_dut(self, hostname):
         """Add a DUT hostname to the AFE.
 
@@ -201,23 +185,21 @@
     def find_and_add_duts(self):
         """Discover DUTs on the testing subnet and add them to the AFE.
 
-        Runs 'arp -a' on the Moblab host and parses the output to discover DUTs
-        and if they are not already in the AFE, adds them.
+        Pings the range of IP's a DUT might be assigned by moblab, then
+        parses the output to discover connected DUTs, connected means
+        they have 0% dropped pings.
+        If they are not already in the AFE, adds them to AFE.
         """
-        self._wake_devices()
         existing_hosts = [host.hostname for host in self.afe.get_hosts()]
-        arp_command = self.run('ip n')
-        for line in arp_command.stdout.splitlines():
+        fping_result = self.run('fping -g 192.168.231.100 192.168.231.110 '
+                                '-a -c 10 -p 30 -q', ignore_status=True)
+        for line in fping_result.stderr.splitlines():
             match = re.match(SUBNET_DUT_SEARCH_RE, line)
             if match:
-                dut_hostname = match.group('ip')
-                if dut_hostname in existing_hosts:
+                dut_ip = match.group('ip')
+                if dut_ip in existing_hosts:
                     break
-                # SSP package ip's start at 150 for the moblab, so it is not
-                # a DUT
-                if int(dut_hostname.split('.')[-1]) > 150:
-                    break
-                self.add_dut(dut_hostname)
+                self.add_dut(dut_ip)
 
 
     def verify_software(self):