[autotest] Some small AU refactoring before P2P autotest.

This does two things:
1. Moves the staging payload code to the base test class
2. Allows increases to number of updates a devserver instance can handle
because the P2P test will update two DUTs.

BUG=chromium:794260
TEST=test_that <IP> autoupdate_EndToEndTest still passes
TEST=test_that <ip> autoupdate_ForcedOOBEUpdate still passes

Change-Id: I091e18f00220786502441cba35d793dc3f506339
Reviewed-on: https://chromium-review.googlesource.com/822981
Commit-Ready: David Haddock <dhaddock@chromium.org>
Tested-by: David Haddock <dhaddock@chromium.org>
Reviewed-by: Harpreet Grewal <harpreet@chromium.org>
Reviewed-by: Ruchi Jahagirdar <rjahagir@chromium.org>
diff --git a/server/cros/update_engine/omaha_devserver.py b/server/cros/update_engine/omaha_devserver.py
index 4020060..7333fbc 100644
--- a/server/cros/update_engine/omaha_devserver.py
+++ b/server/cros/update_engine/omaha_devserver.py
@@ -46,7 +46,7 @@
     _DEVSERVER_TIMELIMIT_SECONDS = 12 * 60 * 60
 
 
-    def __init__(self, omaha_host, update_payload_staged_url):
+    def __init__(self, omaha_host, update_payload_staged_url, max_updates=1):
         """Starts a private devserver instance, operating at Omaha capacity.
 
         @param omaha_host: host address where the devserver is spawned.
@@ -58,6 +58,7 @@
         if not update_payload_staged_url:
             raise error.TestError('Missing update payload url')
 
+        self._max_updates = max_updates
         self._omaha_host = omaha_host
         self._devserver_pid = 0
         self._devserver_port = 0  # Determined later from devserver portfile.
@@ -215,7 +216,7 @@
                 '--logfile=%s' % self._devserver_logfile,
                 '--remote_payload',
                 '--urlbase=%s' % update_payload_url_base,
-                '--max_updates=1',
+                '--max_updates=%s' % self._max_updates,
                 '--host_log',
                 '--static_dir=%s' % self._devserver_static_dir,
                 '--critical_update',
diff --git a/server/cros/update_engine/update_engine_test.py b/server/cros/update_engine/update_engine_test.py
index df81260..a2e757c 100644
--- a/server/cros/update_engine/update_engine_test.py
+++ b/server/cros/update_engine/update_engine_test.py
@@ -5,6 +5,7 @@
 import json
 import logging
 import update_engine_event as uee
+import urlparse
 
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.common_lib.cros import dev_server
@@ -274,6 +275,54 @@
                 'receive %s within %d seconds.' % (desc, timeout))
 
 
+    def _stage_payload_by_uri(self, payload_uri):
+        """Stage a payload based on its GS URI.
+
+        This infers the build's label, filename and GS archive from the
+        provided GS URI.
+
+        @param payload_uri: The full GS URI of the payload.
+
+        @return URL of the staged payload on the server.
+
+        @raise error.TestError if there's a problem with staging.
+
+        """
+        archive_url, _, filename = payload_uri.rpartition('/')
+        build_name = urlparse.urlsplit(archive_url).path.strip('/')
+        return self._stage_payload(build_name, filename,
+                                   archive_url=archive_url)
+
+
+    def _stage_payload(self, build_name, filename, archive_url=None):
+        """Stage the given payload onto the devserver.
+
+        Works for either a stateful or full/delta test payload. Expects the
+        gs_path or a combo of build_name + filename.
+
+        @param build_name: The build name e.g. x86-mario-release/<version>.
+                           If set, assumes default gs archive bucket and
+                           requires filename to be specified.
+        @param filename: In conjunction with build_name, this is the file you
+                         are downloading.
+        @param archive_url: An optional GS archive location, if not using the
+                            devserver's default.
+
+        @return URL of the staged payload on the server.
+
+        @raise error.TestError if there's a problem with staging.
+
+        """
+        try:
+            self._autotest_devserver.stage_artifacts(image=build_name,
+                                                     files=[filename],
+                                                     archive_url=archive_url)
+            return self._autotest_devserver.get_staged_file_url(filename,
+                                                                build_name)
+        except dev_server.DevServerException, e:
+            raise error.TestError('Failed to stage payload: %s' % e)
+
+
     def verify_update_events(self, source_release, hostlog_filename,
                              target_release=None):
         """Compares a hostlog file against a set of expected events.
diff --git a/server/site_tests/autoupdate_EndToEndTest/autoupdate_EndToEndTest.py b/server/site_tests/autoupdate_EndToEndTest/autoupdate_EndToEndTest.py
index 74be59a..b0d3f17 100755
--- a/server/site_tests/autoupdate_EndToEndTest/autoupdate_EndToEndTest.py
+++ b/server/site_tests/autoupdate_EndToEndTest/autoupdate_EndToEndTest.py
@@ -173,53 +173,6 @@
             return staged_uri, staged_stateful
 
 
-    def _stage_payload_by_uri(self, payload_uri):
-        """Stage a payload based on its GS URI.
-
-        This infers the build's label, filename and GS archive from the
-        provided GS URI.
-
-        @param payload_uri: The full GS URI of the payload.
-
-        @return URL of the staged payload on the server.
-
-        @raise error.TestError if there's a problem with staging.
-
-        """
-        archive_url, _, filename = payload_uri.rpartition('/')
-        build_name = urlparse.urlsplit(archive_url).path.strip('/')
-        return self._stage_payload(build_name, filename,
-                                   archive_url=archive_url)
-
-    def _stage_payload(self, build_name, filename, archive_url=None):
-        """Stage the given payload onto the devserver.
-
-        Works for either a stateful or full/delta test payload. Expects the
-        gs_path or a combo of build_name + filename.
-
-        @param build_name: The build name e.g. x86-mario-release/<version>.
-                           If set, assumes default gs archive bucket and
-                           requires filename to be specified.
-        @param filename: In conjunction with build_name, this is the file you
-                         are downloading.
-        @param archive_url: An optional GS archive location, if not using the
-                            devserver's default.
-
-        @return URL of the staged payload on the server.
-
-        @raise error.TestError if there's a problem with staging.
-
-        """
-        try:
-            self._autotest_devserver.stage_artifacts(image=build_name,
-                                                     files=[filename],
-                                                     archive_url=archive_url)
-            return self._autotest_devserver.get_staged_file_url(filename,
-                                                                build_name)
-        except dev_server.DevServerException, e:
-            raise error.TestError('Failed to stage payload: %s' % e)
-
-
     @staticmethod
     def _get_stateful_uri(build_uri):
         """Returns a complete GS URI of a stateful update given a build path."""
@@ -431,4 +384,4 @@
             raise
 
         # Check we can login after the update.
-        cros_device.check_login_after_target_update()
\ No newline at end of file
+        cros_device.check_login_after_target_update()