Add new update verifications per discussion with jrbarnette.

Per Richard:
1. Apply the update.
2. Determine the currently active kernel with 'rootdev -s': partition 3
-> KERN-A; partition 5 -> KERN-B.
3. Use 'cgpt show -P' to determine the priority of KERN-A (partition 2)
and KERN-B (partition 4).
4. Fail the test if the priority of the inactive root is not greater
than the priority of the active root.
5. Reboot the target.
6. Get the current software version from /etc/lsb-release.
7. Fail the test if the version from 6. doesn't match the expected
value.
8. Determine the currently active kernel again, as for step 2.
9. Fail the test if the currently active kernel isn't the new kernel.
10. Use 'cgpt show -S' and 'cgpt show -T' to determine the "tries" and
"success" flag values, respectively, for the currently active kernel.
11. Fail the test if (tries != 0 or success == 0) more than 60 seconds
after booting.

BUG=chromium-os:13761
TEST=Tested with autoserv --image on Mario.

Change-Id: Ieeca622edd0118690443f75c1e36a5ba2581e883
Signed-off-by: Dale Curtis <dalecurtis@chromium.org>
diff --git a/client/common_lib/cros/autoupdater.py b/client/common_lib/cros/autoupdater.py
index f23a284..2a75fe1 100644
--- a/client/common_lib/cros/autoupdater.py
+++ b/client/common_lib/cros/autoupdater.py
@@ -9,7 +9,6 @@
 import urlparse
 
 from autotest_lib.client.common_lib import error
-from autotest_lib.client.cros import constants as chromeos_constants
 
 # TODO(dalecurtis): HACK to bootstrap stateful updater until crosbug.com/8960 is
 # fixed.
@@ -34,7 +33,11 @@
 
 
 class ChromiumOSUpdater():
-    def __init__(self, host=None, update_url=None):
+    KERNEL_A = {'name': 'KERN-A', 'kernel': 2, 'root': 3}
+    KERNEL_B = {'name': 'KERN-B', 'kernel': 4, 'root': 5}
+
+
+    def __init__(self, update_url, host=None):
         self.host = host
         self.update_url = update_url
         self.update_version = url_to_version(update_url)
@@ -65,8 +68,41 @@
         return self.host.run(cmd, *args, **kwargs)
 
 
-    def rootdev(self):
-        return self._run('rootdev').stdout.strip()
+    def rootdev(self, options=''):
+        return self._run('rootdev %s' % options).stdout.strip()
+
+
+    def get_kernel_state(self):
+        """Returns the (<active>, <inactive>) kernel state as a pair."""
+        active_root = int(re.findall('\d+\Z', self.rootdev('-s'))[0])
+        if active_root == self.KERNEL_A['root']:
+            return self.KERNEL_A, self.KERNEL_B
+        elif active_root == self.KERNEL_B['root']:
+            return self.KERNEL_B, self.KERNEL_A
+        else:
+            raise ChromiumOSError('Encountered unknown root partition: %s',
+                                  active_root)
+
+
+    def _cgpt(self, flag, kernel, dev='$(rootdev -s -d)'):
+        """Return numeric cgpt value for the specified flag, kernel, device. """
+        return int(self._run('cgpt show -n -i %d %s %s' % (
+            kernel['kernel'], flag, dev)).stdout.strip())
+
+
+    def get_kernel_priority(self, kernel):
+        """Return numeric priority for the specified kernel."""
+        return self._cgpt('-P', kernel)
+
+
+    def get_kernel_success(self, kernel):
+        """Return boolean success flag for the specified kernel."""
+        return self._cgpt('-S', kernel) != 0
+
+
+    def get_kernel_tries(self, kernel):
+        """Return tries count for the specified kernel."""
+        return self._cgpt('-T', kernel)
 
 
     def revert_boot_partition(self):
@@ -75,8 +111,10 @@
         return self._run('/postinst %s 2>&1' % part)
 
 
-    def run_update(self):
-        if not self.update_url:
+    def run_update(self, force_update):
+        booted_version = self.get_booted_version()
+        if booted_version in self.update_version and not force_update:
+            logging.info('System is already up to date. Skipping update.')
             return False
 
         # Check that devserver is accepting connections (from autoserv's host)
@@ -147,10 +185,15 @@
         return True
 
 
-    def check_version(self):
+    def get_booted_version(self):
         booted_version = self.get_build_id()
         if not booted_version:
             booted_version = self.get_dev_build_id()
+        return booted_version
+
+
+    def check_version(self):
+        booted_version = self.get_booted_version()
         if not booted_version in self.update_version:
             logging.error('Expected Chromium OS version: %s.'
                           'Found Chromium OS %s',