devserver: support for querying statically staged file size and hashes

This adds a new 'api/fileinfo' URL, which returns a JSON encoded
dictionary containing the size, SHA1 and SHA256 hash values of a given
file under the devserver's static directory.

* Migrated size/hash methods from autoupdate.Autoupdate to common_util.
  This makes more sense as they are applicable to any file and are not
  necessarily AU related. Also renamed and reorganized their code.

* Added a new CherryPy-exposed method implementing the new
  functionality.

BUG=chromium-os:33762
TEST=New method returns desired values; unit tests pass.

Change-Id: Iff7e0af2c8962de4976da7c6deaa9892d5b106a5
Reviewed-on: https://gerrit.chromium.org/gerrit/34426
Commit-Ready: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
diff --git a/autoupdate_unittest.py b/autoupdate_unittest.py
index 4274ffb..2fd88a7 100755
--- a/autoupdate_unittest.py
+++ b/autoupdate_unittest.py
@@ -15,6 +15,7 @@
 import mox
 
 import autoupdate
+import common_util
 
 
 _TEST_REQUEST = """
@@ -28,9 +29,9 @@
 class AutoupdateTest(mox.MoxTestBase):
   def setUp(self):
     mox.MoxTestBase.setUp(self)
-    self.mox.StubOutWithMock(autoupdate.Autoupdate, '_GetSize')
-    self.mox.StubOutWithMock(autoupdate.Autoupdate, '_GetHash')
-    self.mox.StubOutWithMock(autoupdate.Autoupdate, '_GetSHA256')
+    self.mox.StubOutWithMock(common_util, 'GetFileSize')
+    self.mox.StubOutWithMock(common_util, 'GetFileSha1')
+    self.mox.StubOutWithMock(common_util, 'GetFileSha256')
     self.mox.StubOutWithMock(autoupdate.Autoupdate, 'GetUpdatePayload')
     self.mox.StubOutWithMock(autoupdate.Autoupdate, '_GetLatestImageDir')
     self.port = 8080
@@ -66,22 +67,25 @@
 
   def testGetRightSignedDeltaPayloadDir(self):
     """Test that our directory is what we expect it to be for signed updates."""
-    self.mox.StubOutWithMock(autoupdate.Autoupdate, '_GetMd5')
+    self.mox.StubOutWithMock(common_util, 'GetFileMd5')
     key_path = 'test_key_path'
     src_image = 'test_src_image'
     target_image = 'test_target_image'
-    hashes = ['12345', '67890', 'abcde', 'patched_kernel']
+    src_hash = '12345'
+    target_hash = '67890'
+    key_hash = 'abcde'
 
-    autoupdate.Autoupdate._GetMd5(target_image).AndReturn(hashes[1])
-    autoupdate.Autoupdate._GetMd5(src_image).AndReturn(hashes[0])
-    autoupdate.Autoupdate._GetMd5(key_path).AndReturn(hashes[2])
+    common_util.GetFileMd5(src_image).AndReturn(src_hash)
+    common_util.GetFileMd5(target_image).AndReturn(target_hash)
+    common_util.GetFileMd5(key_path).AndReturn(key_hash)
 
     self.mox.ReplayAll()
     au_mock = self._DummyAutoupdateConstructor()
     au_mock.private_key = key_path
     update_dir = au_mock.FindCachedUpdateImageSubDir(src_image, target_image)
     self.assertEqual(os.path.basename(update_dir),
-                     '%s_%s+%s+%s' % tuple(hashes))
+                     '%s_%s+%s+patched_kernel' %
+                     (src_hash, target_hash, key_hash))
     self.mox.VerifyAll()
 
   def testGenerateLatestUpdateImageWithForced(self):
@@ -110,11 +114,11 @@
     autoupdate.Autoupdate.GenerateUpdateImageWithCache(
         self.forced_image_path,
         static_image_dir=self.static_image_dir).AndReturn('update.gz')
-    autoupdate.Autoupdate._GetHash(os.path.join(
+    common_util.GetFileSha1(os.path.join(
         self.static_image_dir, 'update.gz')).AndReturn(self.hash)
-    autoupdate.Autoupdate._GetSHA256(os.path.join(
+    common_util.GetFileSha256(os.path.join(
         self.static_image_dir, 'update.gz')).AndReturn(self.sha256)
-    autoupdate.Autoupdate._GetSize(os.path.join(
+    common_util.GetFileSize(os.path.join(
         self.static_image_dir, 'update.gz')).AndReturn(self.size)
     autoupdate.Autoupdate.GetUpdatePayload(
         self.hash, self.sha256, self.size, self.url, False).AndReturn(
@@ -134,11 +138,11 @@
     autoupdate.Autoupdate.GenerateLatestUpdateImage(
         self.test_board, 'ForcedUpdate', self.static_image_dir).AndReturn(
             'update.gz')
-    autoupdate.Autoupdate._GetHash(os.path.join(
+    common_util.GetFileSha1(os.path.join(
         self.static_image_dir, 'update.gz')).AndReturn(self.hash)
-    autoupdate.Autoupdate._GetSHA256(os.path.join(
+    common_util.GetFileSha256(os.path.join(
         self.static_image_dir, 'update.gz')).AndReturn(self.sha256)
-    autoupdate.Autoupdate._GetSize(os.path.join(
+    common_util.GetFileSize(os.path.join(
         self.static_image_dir, 'update.gz')).AndReturn(self.size)
     autoupdate.Autoupdate.GetUpdatePayload(
         self.hash, self.sha256, self.size, self.url, False).AndReturn(
@@ -206,11 +210,11 @@
     autoupdate.Autoupdate.GenerateLatestUpdateImage(
         self.test_board, 'ForcedUpdate', new_image_dir).AndReturn(
             'update.gz')
-    autoupdate.Autoupdate._GetHash(os.path.join(
+    common_util.GetFileSha1(os.path.join(
         new_image_dir, 'update.gz')).AndReturn(self.hash)
-    autoupdate.Autoupdate._GetSHA256(os.path.join(
+    common_util.GetFileSha256(os.path.join(
         new_image_dir, 'update.gz')).AndReturn(self.sha256)
-    autoupdate.Autoupdate._GetSize(os.path.join(
+    common_util.GetFileSize(os.path.join(
         new_image_dir, 'update.gz')).AndReturn(self.size)
     autoupdate.Autoupdate.GetUpdatePayload(
         self.hash, self.sha256, self.size, new_url, False).AndReturn(