autotest: end-to-end autoupdate test

This implements an autotest test for the Chrome OS autoupdate
functionality.  It receives a single test configuration and performs an
end-to-end test of the update process specified by it, which includes:

* Initializing the DUT to a known start state (source version)

* Spawning a local Omaha/devserver instance.

* Triggering an update process.

* Tracking the progress of the update.

* Rebooting the DUT after the update.

* Ensuring that the update has succeeded (target version running).

BUG=chromium-os:33760,chromium-os:33761,chromium-os:33762
TEST=Running with run_remote_tests.sh works

Change-Id: I215e8214d3239f525f062a27a4d97806451c9736
Reviewed-on: https://gerrit.chromium.org/gerrit/37432
Commit-Ready: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
diff --git a/client/common_lib/site_utils.py b/client/common_lib/site_utils.py
index bf77300..cf1e610 100644
--- a/client/common_lib/site_utils.py
+++ b/client/common_lib/site_utils.py
@@ -15,6 +15,10 @@
 CHECK_PID_IS_ALIVE_TIMEOUT = 6
 
 
+
+_LOCAL_HOST_LIST = ['localhost', '127.0.0.1']
+
+
 def ping(host, deadline=None, tries=None, timeout=60):
     """Attempt to ping |host|.
 
@@ -125,6 +129,21 @@
         return True
 
 
+def gs_ls(uri_pattern):
+    """Returns a list of URIs that match a given pattern.
+
+    @param uri_pattern: a GS URI pattern, may contain wildcards
+
+    @return A list of URIs matching the given pattern.
+
+    @raise CmdError: the gsutil command failed.
+
+    """
+    gs_cmd = ' '.join(['gsutil', 'ls', uri_pattern])
+    result = base_utils.system_output(gs_cmd).splitlines()
+    return [path.rstrip() for path in result if path]
+
+
 def nuke_pids(pid_list, signal_queue=[signal.SIGTERM, signal.SIGKILL]):
     """
     Given a list of pid's, kill them via an esclating series of signals.
@@ -153,3 +172,14 @@
     if failed_list:
         raise error.AutoservRunError('Following errors occured: %s' %
                                      failed_list, None)
+
+
+def externalize_host(host):
+    """Returns an externally accessible host name.
+
+    @param host: a host name or address (string)
+
+    @return An externally visible host name or address
+
+    """
+    return socket.gethostname() if host in _LOCAL_HOST_LIST else host