Synced repos to: 58839
diff --git a/crosperf/benchmark_run.py b/crosperf/benchmark_run.py
index cbc7956..b2822a4 100644
--- a/crosperf/benchmark_run.py
+++ b/crosperf/benchmark_run.py
@@ -10,6 +10,7 @@
 import traceback
 from results_cache import Result
 from utils import logger
+from utils import command_executer
 
 STATUS_FAILED = "FAILED"
 STATUS_SUCCEEDED = "SUCCEEDED"
@@ -55,6 +56,7 @@
     self.cache_hit = False
     self.perf_results = None
     self.failure_reason = ""
+    self._ce = command_executer.GetCommandExecuter(self._logger)
 
   def MeanExcludingOutliers(self, array, outlier_range):
     """Return the arithmetic mean excluding outliers."""
@@ -92,7 +94,7 @@
     # Generate results from the output file.
     results_dir = self._GetResultsDir(result.out)
     self.full_name = os.path.basename(results_dir)
-    self.results = self.ParseResults(result.out)
+    self.results = result.keyvals
 
     # Store the autotest output in the cache also.
     if not cache_hit:
@@ -212,9 +214,37 @@
                                                   self.profile_counters,
                                                   self.profile_type)
     self.run_completed = True
-    result = Result(out, err, retval)
+
+    # Include the keyvals in the result.
+    results_dir = self._GetResultsDir(out)
+    keyvals = self._GetKeyvals(results_dir)
+    keyvals["retval"] = retval
+
+    result = Result(out, err, retval, keyvals)
 
     return result
 
+  def _GetKeyvals(self, results_dir):
+    full_results_dir = os.path.join(self.chromeos_root,
+                                    "chroot",
+                                    results_dir.lstrip("/"))
+    command = "find %s -regex .*results/keyval$" % full_results_dir
+    [ret, out, err] = self._ce.RunCommand(command, return_output=True)
+    keyvals_dict = {}
+    for f in out.splitlines():
+      keyvals = open(f, "r").read()
+      keyvals_dict.update(self._ParseKeyvals(keyvals))
+
+    return keyvals_dict
+
+  def _ParseKeyvals(self, keyvals):
+    keyval_dict = {}
+    for l in keyvals.splitlines():
+      l = l.strip()
+      if l:
+        key, val = l.split("=")
+        keyval_dict[key] = val
+    return keyval_dict
+
   def SetCacheConditions(self, cache_conditions):
     self.cache_conditions = cache_conditions
diff --git a/crosperf/results_cache.py b/crosperf/results_cache.py
index 89e1888..b8b495e 100644
--- a/crosperf/results_cache.py
+++ b/crosperf/results_cache.py
@@ -21,10 +21,11 @@
 
 
 class Result(object):
-  def __init__(self, out, err, retval):
+  def __init__(self, out, err, retval, keyvals):
     self.out = out
     self.err = err
     self.retval = retval
+    self.keyvals = keyvals
 
 
 class CacheConditions(object):
@@ -45,6 +46,7 @@
 
 
 class ResultsCache(object):
+  CACHE_VERSION = 2
   def Init(self, chromeos_image, chromeos_root, autotest_name, iteration,
            autotest_args, remote, board, cache_conditions,
            logger_to_use):
@@ -93,7 +95,9 @@
     return (hashlib.md5(self.chromeos_image).hexdigest(),
             self.autotest_name, str(self.iteration),
             ",".join(self.autotest_args),
-            checksum, remote)
+            checksum,
+            remote,
+            str(self.CACHE_VERSION))
 
   def ReadResult(self):
     if CacheConditions.FALSE in self.cache_conditions:
@@ -109,18 +113,16 @@
       self._logger.LogOutput("Trying to read from cache file: %s" % cache_file)
 
       with open(cache_file, "rb") as f:
-        retval = pickle.load(f)
-        out = pickle.load(f)
-        err = pickle.load(f)
+        result = pickle.load(f)
 
-        if (retval == 0 or
+        if (result.retval == 0 or
             CacheConditions.RUN_SUCCEEDED not in self.cache_conditions):
-          return Result(out, err, retval)
+          return result
 
     except Exception, e:
       if CacheConditions.CACHE_FILE_EXISTS not in self.cache_conditions:
         # Cache file not found but just return a failure.
-        return Result("", "", 1)
+        return Result("", "", 1, {})
       raise e
 
   def StoreResult(self, result):
@@ -130,9 +132,7 @@
     ret = self._ce.RunCommand(command)
     assert ret == 0, "Couldn't create cache dir"
     with open(cache_file, "wb") as f:
-      pickle.dump(result.retval, f)
-      pickle.dump(result.out, f)
-      pickle.dump(result.err, f)
+      pickle.dump(result, f)
 
   def StoreAutotestOutput(self, results_dir):
     host_results_dir = os.path.join(self.chromeos_root, "chroot",
diff --git a/utils/utils.py b/utils/utils.py
index 3f9795c..c2398c5 100755
--- a/utils/utils.py
+++ b/utils/utils.py
@@ -88,6 +88,10 @@
   return out.strip()
 
 
+def GetChromeSrcDir():
+  return "var/cache/chromeos-chrome/chrome-src/src"
+
+
 @contextmanager
 def WorkingDirectory(new_dir):
   old_dir = os.getcwd()