Bluetooth: allow tester IP to be specified in --args

Normally the tester hostname is derived from the DUT hostname by
appending '-router' to the first part. This requires manual /etc/hosts
entries on your workstation when dealing with machines by IP address.

Allowing the IP (or hostname) of the tester to be specified on the
command-line with '--args tester=IP' makes this much easier to handle.

BUG=none
TEST=test_that $DUT_IP bluetooth_Sanity_Discovery --args tester=$TESTER_IP

Change-Id: Ic113cb73a2de95e60b75931d95f2b1ea7ba4a2cf
Reviewed-on: https://chromium-review.googlesource.com/233492
Reviewed-by: Michael Janssen <jamuraa@chromium.org>
Commit-Queue: Scott James Remnant <keybuk@chromium.org>
Tested-by: Scott James Remnant <keybuk@chromium.org>
diff --git a/server/cros/bluetooth/bluetooth_tester.py b/server/cros/bluetooth/bluetooth_tester.py
index 581b451..1fdffd3 100644
--- a/server/cros/bluetooth/bluetooth_tester.py
+++ b/server/cros/bluetooth/bluetooth_tester.py
@@ -4,7 +4,9 @@
 
 import base64
 import json
+import socket
 
+from autotest_lib.client.common_lib import error
 from autotest_lib.client.cros import constants
 from autotest_lib.server import autotest, hosts
 
@@ -197,21 +199,40 @@
                                                             invalid_request)
 
 
-def create_host_from(device_host):
+def create_host_from(device_host, args=None):
     """Creates a host object for the Tester associated with a DUT.
 
-    Will raise an exception if there isn't a tester for the DUT.
+    The IP address or the hostname can be specified in the 'tester' member of
+    the argument dictionary. When not present it is derived from the hostname
+    of the DUT by appending '-router' to the first part.
+
+    Will raise an exception if there isn't a tester for the DUT, or if the DUT
+    is specified as an IP address and thus the hostname cannot be derived.
 
     @param device_host: Autotest host object for the DUT.
+    @param args: Dictionary of arguments passed to the test.
 
     @return Autotest host object for the Tester.
 
     """
 
-    device_hostname = device_host.hostname
+    def is_ip_address(hostname):
+        try:
+            socket.inet_aton(hostname)
+            return True
+        except socket.error:
+            return False
 
-    parts = device_hostname.split('.')
-    parts[0] = parts[0] + '-router'
-    tester_hostname = '.'.join(parts)
+    try:
+        tester_hostname = args['tester']
+    except KeyError:
+        device_hostname = device_host.hostname
+        if is_ip_address(device_hostname):
+            raise error.TestError("Remote host cannot be an IP address unless "
+                                  "tester specified with --args tester=IP")
+
+        parts = device_hostname.split('.')
+        parts[0] = parts[0] + '-router'
+        tester_hostname = '.'.join(parts)
 
     return hosts.create_host(tester_hostname)
diff --git a/server/site_tests/bluetooth_SDP_ServiceAttributeRequest/control b/server/site_tests/bluetooth_SDP_ServiceAttributeRequest/control
index 1f7cdff..4980944 100644
--- a/server/site_tests/bluetooth_SDP_ServiceAttributeRequest/control
+++ b/server/site_tests/bluetooth_SDP_ServiceAttributeRequest/control
@@ -51,11 +51,14 @@
 """
 
 from autotest_lib.server.cros.bluetooth import bluetooth_tester
+from autotest_lib.server import utils
 
 
+args_dict = utils.args_to_dict(args)
+
 def run(machine):
     device_host = hosts.create_host(machine)
-    tester_host = bluetooth_tester.create_host_from(device_host)
+    tester_host = bluetooth_tester.create_host_from(device_host, args=args_dict)
     job.run_test('bluetooth_SDP_ServiceAttributeRequest',
                  device_host=device_host,
                  tester_host=tester_host,
diff --git a/server/site_tests/bluetooth_SDP_ServiceBrowse/control b/server/site_tests/bluetooth_SDP_ServiceBrowse/control
index 74549fc..bd297e0 100644
--- a/server/site_tests/bluetooth_SDP_ServiceBrowse/control
+++ b/server/site_tests/bluetooth_SDP_ServiceBrowse/control
@@ -24,11 +24,14 @@
 """
 
 from autotest_lib.server.cros.bluetooth import bluetooth_tester
+from autotest_lib.server import utils
 
 
+args_dict = utils.args_to_dict(args)
+
 def run(machine):
     device_host = hosts.create_host(machine)
-    tester_host = bluetooth_tester.create_host_from(device_host)
+    tester_host = bluetooth_tester.create_host_from(device_host, args=args_dict)
     job.run_test('bluetooth_SDP_ServiceBrowse',
                  device_host=device_host,
                  tester_host=tester_host,
diff --git a/server/site_tests/bluetooth_SDP_ServiceSearchAttributeRequest/control b/server/site_tests/bluetooth_SDP_ServiceSearchAttributeRequest/control
index 5729abd..5153113 100644
--- a/server/site_tests/bluetooth_SDP_ServiceSearchAttributeRequest/control
+++ b/server/site_tests/bluetooth_SDP_ServiceSearchAttributeRequest/control
@@ -52,11 +52,14 @@
 """
 
 from autotest_lib.server.cros.bluetooth import bluetooth_tester
+from autotest_lib.server import utils
 
 
+args_dict = utils.args_to_dict(args)
+
 def run(machine):
     device_host = hosts.create_host(machine)
-    tester_host = bluetooth_tester.create_host_from(device_host)
+    tester_host = bluetooth_tester.create_host_from(device_host, args=args_dict)
     job.run_test('bluetooth_SDP_ServiceSearchAttributeRequest',
                  device_host=device_host,
                  tester_host=tester_host,
diff --git a/server/site_tests/bluetooth_SDP_ServiceSearchRequestBasic/control b/server/site_tests/bluetooth_SDP_ServiceSearchRequestBasic/control
index cdd641f..d8cd114 100644
--- a/server/site_tests/bluetooth_SDP_ServiceSearchRequestBasic/control
+++ b/server/site_tests/bluetooth_SDP_ServiceSearchRequestBasic/control
@@ -33,11 +33,14 @@
 """
 
 from autotest_lib.server.cros.bluetooth import bluetooth_tester
+from autotest_lib.server import utils
 
 
+args_dict = utils.args_to_dict(args)
+
 def run(machine):
     device_host = hosts.create_host(machine)
-    tester_host = bluetooth_tester.create_host_from(device_host)
+    tester_host = bluetooth_tester.create_host_from(device_host, args=args_dict)
     job.run_test('bluetooth_SDP_ServiceSearchRequestBasic',
                  device_host=device_host,
                  tester_host=tester_host,
diff --git a/server/site_tests/bluetooth_Sanity_Discoverable/control b/server/site_tests/bluetooth_Sanity_Discoverable/control
index 76e3c2c..bc98bd2 100644
--- a/server/site_tests/bluetooth_Sanity_Discoverable/control
+++ b/server/site_tests/bluetooth_Sanity_Discoverable/control
@@ -18,11 +18,14 @@
 """
 
 from autotest_lib.server.cros.bluetooth import bluetooth_tester
+from autotest_lib.server import utils
 
 
+args_dict = utils.args_to_dict(args)
+
 def run(machine):
     device_host = hosts.create_host(machine)
-    tester_host = bluetooth_tester.create_host_from(device_host)
+    tester_host = bluetooth_tester.create_host_from(device_host, args=args_dict)
     job.run_test('bluetooth_Sanity_Discoverable',
                  device_host=device_host,
                  tester_host=tester_host,
diff --git a/server/site_tests/bluetooth_Sanity_Discovery/control b/server/site_tests/bluetooth_Sanity_Discovery/control
index a524492..ec223be 100644
--- a/server/site_tests/bluetooth_Sanity_Discovery/control
+++ b/server/site_tests/bluetooth_Sanity_Discovery/control
@@ -18,11 +18,14 @@
 """
 
 from autotest_lib.server.cros.bluetooth import bluetooth_tester
+from autotest_lib.server import utils
 
 
+args_dict = utils.args_to_dict(args)
+
 def run(machine):
     device_host = hosts.create_host(machine)
-    tester_host = bluetooth_tester.create_host_from(device_host)
+    tester_host = bluetooth_tester.create_host_from(device_host, args=args_dict)
     job.run_test('bluetooth_Sanity_Discovery',
                  device_host=device_host,
                  tester_host=tester_host,