blob: 4178b467fb208d04028c9588568397e1f3543ae6 [file] [log] [blame]
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08001#!/usr/bin/python
Yunlian Jiangb8b76e22013-03-25 14:02:29 -07002
3# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08006
7import getpass
8import glob
9import hashlib
10import os
11import pickle
12import re
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070013import tempfile
Ahmad Shariffd356fb2012-05-07 12:02:16 -070014
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080015from utils import command_executer
Ahmad Sharifee988c82012-05-14 17:11:56 -070016from utils import misc
Ahmad Shariffd356fb2012-05-07 12:02:16 -070017
Ahmad Shariff395c262012-10-09 17:48:09 -070018from image_checksummer import ImageChecksummer
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080019
Luis Lozanof81680c2013-03-15 14:44:13 -070020SCRATCH_BASE = "/home/%s/cros_scratch"
21SCRATCH_DIR = SCRATCH_BASE % getpass.getuser()
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080022RESULTS_FILE = "results.txt"
Ahmad Shariff395c262012-10-09 17:48:09 -070023MACHINE_FILE = "machine.txt"
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080024AUTOTEST_TARBALL = "autotest.tbz2"
25PERF_RESULTS_FILE = "perf-results.txt"
26
27
28class Result(object):
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070029 """ This class manages what exactly is stored inside the cache without knowing
30 what the key of the cache is. For runs with perf, it stores perf.data,
31 perf.report, etc. The key generation is handled by the ResultsCache class.
32 """
Ahmad Sharif4467f002012-12-20 12:09:49 -080033
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -070034 def __init__(self, logger, label):
35 self._chromeos_root = label.chromeos_root
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070036 self._logger = logger
37 self._ce = command_executer.GetCommandExecuter(self._logger)
38 self._temp_dir = None
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -070039 self.label = label
40 self.results_dir = None
41 self.perf_data_files = []
42 self.perf_report_files = []
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070043
44 def _CopyFilesTo(self, dest_dir, files_to_copy):
45 file_index = 0
46 for file_to_copy in files_to_copy:
47 if not os.path.isdir(dest_dir):
48 command = "mkdir -p %s" % dest_dir
49 self._ce.RunCommand(command)
50 dest_file = os.path.join(dest_dir,
51 ("%s.%s" % (os.path.basename(file_to_copy),
52 file_index)))
53 ret = self._ce.CopyFiles(file_to_copy,
54 dest_file,
55 recursive=False)
56 if ret:
57 raise Exception("Could not copy results file: %s" % file_to_copy)
58
59 def CopyResultsTo(self, dest_dir):
60 self._CopyFilesTo(dest_dir, self.perf_data_files)
61 self._CopyFilesTo(dest_dir, self.perf_report_files)
62
63 def _GetKeyvals(self):
Luis Lozanof81680c2013-03-15 14:44:13 -070064 results_in_chroot = os.path.join(self._chromeos_root,
65 "chroot", "tmp")
66 if not self._temp_dir:
67 self._temp_dir = tempfile.mkdtemp(dir=results_in_chroot)
68 command = "cp -r {0}/* {1}".format(self.results_dir, self._temp_dir)
69 self._ce.RunCommand(command)
70
71 command = ("python generate_test_report --no-color --csv %s" %
72 (os.path.join("/tmp", os.path.basename(self._temp_dir))))
73 [_, out, _] = self._ce.ChrootRunCommand(self._chromeos_root,
74 command,
75 return_output=True)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070076 keyvals_dict = {}
Yunlian Jiang006a5b02013-03-28 12:38:43 -070077 tmp_dir_in_chroot = misc.GetInsideChrootPath(self._chromeos_root,
78 self._temp_dir)
Ahmad Sharifa171f8d2012-05-24 16:35:24 -070079 for line in out.splitlines():
Ahmad Shariff395c262012-10-09 17:48:09 -070080 tokens = re.split("=|,", line)
Ahmad Sharifa171f8d2012-05-24 16:35:24 -070081 key = tokens[-2]
Yunlian Jiangb8b76e22013-03-25 14:02:29 -070082 if key.startswith(tmp_dir_in_chroot):
83 key = key[len(tmp_dir_in_chroot) + 1:]
Ahmad Sharifa171f8d2012-05-24 16:35:24 -070084 value = tokens[-1]
85 keyvals_dict[key] = value
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070086
87 return keyvals_dict
88
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070089 def _GetResultsDir(self):
Ahmad Sharif4467f002012-12-20 12:09:49 -080090 mo = re.search(r"Results placed in (\S+)", self.out)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070091 if mo:
92 result = mo.group(1)
93 return result
94 raise Exception("Could not find results directory.")
95
96 def _FindFilesInResultsDir(self, find_args):
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -070097 if not self.results_dir:
98 return None
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070099 command = "find %s %s" % (self.results_dir,
100 find_args)
Ahmad Sharif4467f002012-12-20 12:09:49 -0800101 ret, out, _ = self._ce.RunCommand(command, return_output=True)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700102 if ret:
103 raise Exception("Could not run find command!")
104 return out
105
106 def _GetPerfDataFiles(self):
107 return self._FindFilesInResultsDir("-name perf.data").splitlines()
108
109 def _GetPerfReportFiles(self):
110 return self._FindFilesInResultsDir("-name perf.data.report").splitlines()
111
112 def _GeneratePerfReportFiles(self):
113 perf_report_files = []
114 for perf_data_file in self.perf_data_files:
115 # Generate a perf.report and store it side-by-side with the perf.data
116 # file.
117 chroot_perf_data_file = misc.GetInsideChrootPath(self._chromeos_root,
118 perf_data_file)
119 perf_report_file = "%s.report" % perf_data_file
120 if os.path.exists(perf_report_file):
121 raise Exception("Perf report file already exists: %s" %
122 perf_report_file)
123 chroot_perf_report_file = misc.GetInsideChrootPath(self._chromeos_root,
Ahmad Sharif4467f002012-12-20 12:09:49 -0800124 perf_report_file)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700125 command = ("/usr/sbin/perf report "
Ahmad Shariff395c262012-10-09 17:48:09 -0700126 "-n "
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700127 "--symfs /build/%s "
Ahmad Sharif5cc48b52012-05-18 14:31:20 -0700128 "--vmlinux /build/%s/usr/lib/debug/boot/vmlinux "
129 "--kallsyms /build/%s/boot/System.map-* "
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700130 "-i %s --stdio "
Ahmad Sharif4467f002012-12-20 12:09:49 -0800131 "> %s" %
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700132 (self._board,
Ahmad Sharif5cc48b52012-05-18 14:31:20 -0700133 self._board,
134 self._board,
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700135 chroot_perf_data_file,
136 chroot_perf_report_file))
Ahmad Sharif4467f002012-12-20 12:09:49 -0800137 self._ce.ChrootRunCommand(self._chromeos_root,
138 command)
139
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700140 # Add a keyval to the dictionary for the events captured.
141 perf_report_files.append(
142 misc.GetOutsideChrootPath(self._chromeos_root,
143 chroot_perf_report_file))
144 return perf_report_files
145
146 def _GatherPerfResults(self):
147 report_id = 0
148 for perf_report_file in self.perf_report_files:
149 with open(perf_report_file, "r") as f:
150 report_contents = f.read()
Ahmad Sharif4467f002012-12-20 12:09:49 -0800151 for group in re.findall(r"Events: (\S+) (\S+)", report_contents):
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700152 num_events = group[0]
153 event_name = group[1]
154 key = "perf_%s_%s" % (report_id, event_name)
155 value = str(misc.UnitToNumber(num_events))
156 self.keyvals[key] = value
157
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700158 def _PopulateFromRun(self, out, err, retval):
159 self._board = self.label.board
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800160 self.out = out
161 self.err = err
162 self.retval = retval
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700163 self.chroot_results_dir = self._GetResultsDir()
164 self.results_dir = misc.GetOutsideChrootPath(self._chromeos_root,
165 self.chroot_results_dir)
166 self.perf_data_files = self._GetPerfDataFiles()
167 # Include all perf.report data in table.
168 self.perf_report_files = self._GeneratePerfReportFiles()
169 # TODO(asharif): Do something similar with perf stat.
170
171 # Grab keyvals from the directory.
172 self._ProcessResults()
173
174 def _ProcessResults(self):
175 # Note that this function doesn't know anything about whether there is a
176 # cache hit or miss. It should process results agnostic of the cache hit
177 # state.
178 self.keyvals = self._GetKeyvals()
179 self.keyvals["retval"] = self.retval
180 # Generate report from all perf.data files.
181 # Now parse all perf report files and include them in keyvals.
182 self._GatherPerfResults()
183
184 def _PopulateFromCacheDir(self, cache_dir):
185 # Read in everything from the cache directory.
186 with open(os.path.join(cache_dir, RESULTS_FILE), "r") as f:
187 self.out = pickle.load(f)
188 self.err = pickle.load(f)
189 self.retval = pickle.load(f)
190
191 # Untar the tarball to a temporary directory
Luis Lozanof81680c2013-03-15 14:44:13 -0700192 self._temp_dir = tempfile.mkdtemp(dir=os.path.join(self._chromeos_root,
193 "chroot", "tmp"))
194
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700195 command = ("cd %s && tar xf %s" %
196 (self._temp_dir,
197 os.path.join(cache_dir, AUTOTEST_TARBALL)))
198 ret = self._ce.RunCommand(command)
199 if ret:
200 raise Exception("Could not untar cached tarball")
201 self.results_dir = self._temp_dir
202 self.perf_data_files = self._GetPerfDataFiles()
203 self.perf_report_files = self._GetPerfReportFiles()
204 self._ProcessResults()
205
Luis Lozanof81680c2013-03-15 14:44:13 -0700206 def CleanUp(self, rm_chroot_tmp):
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700207 if rm_chroot_tmp and self.results_dir:
Luis Lozanof81680c2013-03-15 14:44:13 -0700208 command = "rm -rf %s" % self.results_dir
209 self._ce.RunCommand(command)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700210 if self._temp_dir:
211 command = "rm -rf %s" % self._temp_dir
212 self._ce.RunCommand(command)
213
Ahmad Shariff395c262012-10-09 17:48:09 -0700214 def StoreToCacheDir(self, cache_dir, machine_manager):
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700215 # Create the dir if it doesn't exist.
Luis Lozanof81680c2013-03-15 14:44:13 -0700216 temp_dir = tempfile.mkdtemp()
217
218 # Store to the temp directory.
219 with open(os.path.join(temp_dir, RESULTS_FILE), "w") as f:
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700220 pickle.dump(self.out, f)
221 pickle.dump(self.err, f)
222 pickle.dump(self.retval, f)
223
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700224 if self.results_dir:
225 tarball = os.path.join(temp_dir, AUTOTEST_TARBALL)
226 command = ("cd %s && "
227 "tar "
228 "--exclude=var/spool "
229 "--exclude=var/log "
230 "-cjf %s ." % (self.results_dir, tarball))
231 ret = self._ce.RunCommand(command)
232 if ret:
233 raise Exception("Couldn't store autotest output directory.")
Ahmad Shariff395c262012-10-09 17:48:09 -0700234 # Store machine info.
235 # TODO(asharif): Make machine_manager a singleton, and don't pass it into
236 # this function.
Luis Lozanof81680c2013-03-15 14:44:13 -0700237 with open(os.path.join(temp_dir, MACHINE_FILE), "w") as f:
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700238 f.write(machine_manager.machine_checksum_string[self.label.name])
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700239
Luis Lozanof81680c2013-03-15 14:44:13 -0700240 if os.path.exists(cache_dir):
241 command = "rm -rf {0}".format(cache_dir)
242 self._ce.RunCommand(command)
243
244 command = "mkdir -p {0} && ".format(os.path.dirname(cache_dir))
Yunlian Jiang006a5b02013-03-28 12:38:43 -0700245 command += "chmod g+x {0} && ".format(temp_dir)
Luis Lozanof81680c2013-03-15 14:44:13 -0700246 command += "mv {0} {1}".format(temp_dir, cache_dir)
247 ret = self._ce.RunCommand(command)
248 if ret:
249 command = "rm -rf {0}".format(temp_dir)
250 self._ce.RunCommand(command)
251 raise Exception("Could not move dir %s to dir %s" %
252 (temp_dir, cache_dir))
253
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700254 @classmethod
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700255 def CreateFromRun(cls, logger, label, out, err, retval, suite="pyauto"):
256 if suite == "telemetry":
257 result = TelemetryResult(logger, label)
258 else:
259 result = cls(logger, label)
260 result._PopulateFromRun(out, err, retval)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700261 return result
262
263 @classmethod
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700264 def CreateFromCacheHit(cls, logger, label, cache_dir,
265 suite="pyauto"):
266 if suite == "telemetry":
267 result = TelemetryResult(logger, label)
268 else:
269 result = cls(logger, label)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700270 try:
271 result._PopulateFromCacheDir(cache_dir)
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700272
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700273 except Exception as e:
274 logger.LogError("Exception while using cache: %s" % e)
275 return None
276 return result
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800277
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700278class TelemetryResult(Result):
279
280 def __init__(self, logger, label):
281 super(TelemetryResult, self).__init__(logger, label)
282
283 def _PopulateFromRun(self, out, err, retval):
284 self.out = out
285 self.err = err
286 self.retval = retval
287
288 self._ProcessResults()
289
290 def _ProcessResults(self):
291 # The output is:
292 # url,average_commit_time (ms),...
293 # www.google.com,33.4,21.2,...
294 # We need to convert to this format:
295 # {"www.google.com:average_commit_time (ms)": "33.4",
296 # "www.google.com:...": "21.2"}
297
298 lines = self.out.splitlines()
299 self.keyvals = {}
300
301 if not lines:
302 return
303 labels = lines[0].split(",")
304 for line in lines[1:]:
305 fields = line.split(",")
306 if (len(fields) != len(labels)):
307 continue
308 for i in range(1, len(labels)):
309 key = "%s %s" % (fields[0], labels[i])
310 value = fields[i]
311 self.keyvals[key] = value
312 self.keyvals["retval"] = self.retval
313
314 def _PopulateFromCacheDir(self, cache_dir):
315 with open(os.path.join(cache_dir, RESULTS_FILE), "r") as f:
316 self.out = pickle.load(f)
317 self.err = pickle.load(f)
318 self.retval = pickle.load(f)
319 self._ProcessResults()
320
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800321
322class CacheConditions(object):
323 # Cache hit only if the result file exists.
324 CACHE_FILE_EXISTS = 0
325
Ahmad Shariff395c262012-10-09 17:48:09 -0700326 # Cache hit if the checksum of cpuinfo and totalmem of
327 # the cached result and the new run match.
328 MACHINES_MATCH = 1
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800329
330 # Cache hit if the image checksum of the cached result and the new run match.
331 CHECKSUMS_MATCH = 2
332
333 # Cache hit only if the cached result was successful
334 RUN_SUCCEEDED = 3
335
336 # Never a cache hit.
337 FALSE = 4
338
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700339 # Cache hit if the image path matches the cached image path.
340 IMAGE_PATH_MATCH = 5
341
Ahmad Sharif4467f002012-12-20 12:09:49 -0800342 # Cache hit if the uuid of hard disk mataches the cached one
343
344 SAME_MACHINE_MATCH = 6
345
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800346
347class ResultsCache(object):
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700348 """ This class manages the key of the cached runs without worrying about what
349 is exactly stored (value). The value generation is handled by the Results
350 class.
351 """
Ahmad Sharif4467f002012-12-20 12:09:49 -0800352 CACHE_VERSION = 6
Ahmad Shariff395c262012-10-09 17:48:09 -0700353
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700354 def Init(self, chromeos_image, chromeos_root, test_name, iteration,
355 test_args, machine_manager, board, cache_conditions,
356 logger_to_use, label, share_users, suite):
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800357 self.chromeos_image = chromeos_image
358 self.chromeos_root = chromeos_root
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700359 self.test_name = test_name
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800360 self.iteration = iteration
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700361 self.test_args = test_args,
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800362 self.board = board
363 self.cache_conditions = cache_conditions
Ahmad Shariff395c262012-10-09 17:48:09 -0700364 self.machine_manager = machine_manager
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800365 self._logger = logger_to_use
366 self._ce = command_executer.GetCommandExecuter(self._logger)
Ahmad Sharif4467f002012-12-20 12:09:49 -0800367 self.label = label
Luis Lozanof81680c2013-03-15 14:44:13 -0700368 self.share_users = share_users
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700369 self.suite = suite
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800370
371 def _GetCacheDirForRead(self):
Luis Lozanof81680c2013-03-15 14:44:13 -0700372 matching_dirs = []
373 for glob_path in self._FormCacheDir(self._GetCacheKeyList(True)):
374 matching_dirs += glob.glob(glob_path)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800375
376 if matching_dirs:
377 # Cache file found.
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800378 return matching_dirs[0]
379 else:
380 return None
381
382 def _GetCacheDirForWrite(self):
Luis Lozanof81680c2013-03-15 14:44:13 -0700383 return self._FormCacheDir(self._GetCacheKeyList(False))[0]
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800384
385 def _FormCacheDir(self, list_of_strings):
386 cache_key = " ".join(list_of_strings)
Ahmad Sharifee988c82012-05-14 17:11:56 -0700387 cache_dir = misc.GetFilenameFromString(cache_key)
Luis Lozanof81680c2013-03-15 14:44:13 -0700388 if self.label.cache_dir:
389 cache_home = os.path.abspath(os.path.expanduser(self.label.cache_dir))
390 cache_path = [os.path.join(cache_home, cache_dir)]
391 else:
392 cache_path = [os.path.join(SCRATCH_DIR, cache_dir)]
393
394 for i in [x.strip() for x in self.share_users.split(",")]:
395 path = SCRATCH_BASE % i
396 cache_path.append(os.path.join(path, cache_dir))
397
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800398 return cache_path
399
400 def _GetCacheKeyList(self, read):
Ahmad Shariff395c262012-10-09 17:48:09 -0700401 if read and CacheConditions.MACHINES_MATCH not in self.cache_conditions:
402 machine_checksum = "*"
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800403 else:
Ahmad Sharif4467f002012-12-20 12:09:49 -0800404 machine_checksum = self.machine_manager.machine_checksum[self.label.name]
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800405 if read and CacheConditions.CHECKSUMS_MATCH not in self.cache_conditions:
406 checksum = "*"
407 else:
Luis Lozanof81680c2013-03-15 14:44:13 -0700408 checksum = ImageChecksummer().Checksum(self.label)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700409
410 if read and CacheConditions.IMAGE_PATH_MATCH not in self.cache_conditions:
411 image_path_checksum = "*"
412 else:
413 image_path_checksum = hashlib.md5(self.chromeos_image).hexdigest()
414
Ahmad Sharif4467f002012-12-20 12:09:49 -0800415 if read and CacheConditions.SAME_MACHINE_MATCH not in self.cache_conditions:
416 machine_id_checksum = "*"
417 else:
418 for machine in self.machine_manager.GetMachines(self.label):
419 if machine.name == self.label.remote[0]:
420 machine_id_checksum = machine.machine_id_checksum
421 break
422
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700423 test_args_checksum = hashlib.md5(
424 "".join(self.test_args)).hexdigest()
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700425 return (image_path_checksum,
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700426 self.test_name, str(self.iteration),
427 test_args_checksum,
Ahmad Sharif92ab7af2012-03-01 18:03:46 -0800428 checksum,
Ahmad Shariff395c262012-10-09 17:48:09 -0700429 machine_checksum,
Ahmad Sharif4467f002012-12-20 12:09:49 -0800430 machine_id_checksum,
Ahmad Sharif92ab7af2012-03-01 18:03:46 -0800431 str(self.CACHE_VERSION))
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800432
433 def ReadResult(self):
434 if CacheConditions.FALSE in self.cache_conditions:
435 return None
436 cache_dir = self._GetCacheDirForRead()
437
438 if not cache_dir:
439 return None
440
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700441 if not os.path.isdir(cache_dir):
442 return None
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800443
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700444 self._logger.LogOutput("Trying to read from cache dir: %s" % cache_dir)
Yunlian Jiang04dc5dc2013-04-23 15:05:05 -0700445 result = Result.CreateFromCacheHit(self._logger,
446 self.label,
447 cache_dir,
448 self.suite)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700449 if not result:
450 return None
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800451
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -0700452 if (result.retval == 0 or
453 CacheConditions.RUN_SUCCEEDED not in self.cache_conditions):
454 return result
455
456 return None
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800457
458 def StoreResult(self, result):
459 cache_dir = self._GetCacheDirForWrite()
Ahmad Shariff395c262012-10-09 17:48:09 -0700460 result.StoreToCacheDir(cache_dir, self.machine_manager)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800461
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800462
Ahmad Sharif4467f002012-12-20 12:09:49 -0800463class MockResultsCache(ResultsCache):
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800464 def Init(self, *args):
465 pass
466
467 def ReadResult(self):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800468 return None
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800469
470 def StoreResult(self, result):
471 pass
Ahmad Sharif4467f002012-12-20 12:09:49 -0800472
473
474class MockResult(Result):
475 def _PopulateFromRun(self, out, err, retval):
476 self.out = out
477 self.err = err
478 self.retval = retval
479