Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: tools/android/loading/run_sandwich.py

Issue 1692873003: sandwich: Pushes locally saved HTTP cache to the device. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@d03
Patch Set: Addresses lizeb's nits Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/android/loading/run_sandwich.py
diff --git a/tools/android/loading/run_sandwich.py b/tools/android/loading/run_sandwich.py
index 242cfbf49aca709e1eb5aa11eb5b7b5c5165aea6..9274819a2c4823824ee590f27828e15d4f6ffc97 100755
--- a/tools/android/loading/run_sandwich.py
+++ b/tools/android/loading/run_sandwich.py
@@ -12,10 +12,12 @@ TODO(pasko): implement cache preparation and WPR.
"""
import argparse
+from datetime import datetime
import json
import logging
import os
import shutil
+import subprocess
import sys
import tempfile
import time
@@ -59,6 +61,9 @@ _CHROME_PACKAGE = (
# operations, such as opening the launcher activity.
_TIME_TO_DEVICE_IDLE_SECONDS = 2
+# Cache directory's path on the device.
+_REMOTE_CACHE_DIRECTORY = '/data/data/' + _CHROME_PACKAGE + '/cache/Cache'
+
def _ReadUrlsFromJobDescription(job_name):
"""Retrieves the list of URLs associated with the job name."""
@@ -104,6 +109,17 @@ def _UpdateTimestampFromAdbStat(filename, stat):
os.utime(filename, (stat.st_time, stat.st_time))
+def _AdbShell(adb, cmd):
+ adb.Shell(subprocess.list2cmdline(cmd))
+
+
+def _AdbUtime(adb, filename, timestamp):
+ """Adb equivalent of os.utime(filename, (timestamp, timestamp))
+ """
+ touch_stamp = datetime.fromtimestamp(timestamp).strftime('%Y%m%d.%H%M%S')
+ _AdbShell(adb, ['touch', '-t', touch_stamp, filename])
+
+
def _PullBrowserCache(device):
"""Pulls the browser cache from the device and saves it locally.
@@ -114,14 +130,13 @@ def _PullBrowserCache(device):
Temporary directory containing all the browser cache.
"""
save_target = tempfile.mkdtemp(suffix='.cache')
- cache_directory = '/data/data/' + _CHROME_PACKAGE + '/cache/Cache'
- for filename, stat in device.adb.Ls(cache_directory):
+ for filename, stat in device.adb.Ls(_REMOTE_CACHE_DIRECTORY):
if filename == '..':
continue
if filename == '.':
cache_directory_stat = stat
continue
- original_file = os.path.join(cache_directory, filename)
+ original_file = os.path.join(_REMOTE_CACHE_DIRECTORY, filename)
saved_file = os.path.join(save_target, filename)
device.adb.Pull(original_file, saved_file)
_UpdateTimestampFromAdbStat(saved_file, stat)
@@ -145,6 +160,35 @@ def _PullBrowserCache(device):
return save_target
+def _PushBrowserCache(device, local_cache_path):
+ """Pushes the browser cache saved locally to the device.
+
+ Args:
+ device: Android device.
+ local_cache_path: The directory's path containing the cache locally.
+ """
+ # Clear previous cache.
+ _AdbShell(device.adb, ['rm', '-rf', _REMOTE_CACHE_DIRECTORY])
+ _AdbShell(device.adb, ['mkdir', _REMOTE_CACHE_DIRECTORY])
+
+ # Push cache content.
+ device.adb.Push(local_cache_path, _REMOTE_CACHE_DIRECTORY)
+
+ # Walk through the local cache to update mtime on the device.
+ def MirrorMtime(local_path):
+ cache_relative_path = os.path.relpath(local_path, start=local_cache_path)
+ remote_path = os.path.join(_REMOTE_CACHE_DIRECTORY, cache_relative_path)
+ _AdbUtime(device.adb, remote_path, os.stat(local_path).st_mtime)
+
+ for local_directory_path, dirnames, filenames in os.walk(
+ local_cache_path, topdown=False):
+ for filename in filenames:
+ MirrorMtime(os.path.join(local_directory_path, filename))
+ for dirname in dirnames:
+ MirrorMtime(os.path.join(local_directory_path, dirname))
+ MirrorMtime(local_cache_path)
+
+
def _ZipDirectoryContent(root_directory_path, archive_dest_path):
"""Zip a directory's content recursively with all the directories'
timestamps preserved.
@@ -155,6 +199,10 @@ def _ZipDirectoryContent(root_directory_path, archive_dest_path):
"""
with zipfile.ZipFile(archive_dest_path, 'w') as zip_output:
timestamps = {}
+ root_directory_stats = os.stat(root_directory_path)
+ timestamps['.'] = {
+ 'atime': root_directory_stats.st_atime,
+ 'mtime': root_directory_stats.st_mtime}
for directory_path, dirnames, filenames in os.walk(root_directory_path):
for dirname in dirnames:
subdirectory_path = os.path.join(directory_path, dirname)
@@ -210,6 +258,24 @@ def _UnzipDirectoryContent(archive_path, directory_dest_path):
os.utime(output_path, (stats['atime'], stats['mtime']))
+def _CleanPreviousTraces(output_directories_path):
+ """Cleans previous traces from the output directory.
+
+ Args:
+ output_directories_path: The output directory path where to clean the
+ previous traces.
+ """
+ for dirname in os.listdir(output_directories_path):
+ directory_path = os.path.join(output_directories_path, dirname)
+ if not os.path.isdir(directory_path):
+ continue
+ try:
+ int(dirname)
+ except ValueError:
+ continue
+ shutil.rmtree(directory_path)
+
+
def main():
logging.basicConfig(level=logging.INFO)
devil_chromium.Initialize()
@@ -221,35 +287,50 @@ def main():
help='Name of output directory to create.')
parser.add_argument('--repeat', default=1, type=int,
help='How many times to run the job')
- parser.add_argument('--save-cache', default=False,
- action='store_true',
- help='Clear HTTP cache before start,' +
- 'save cache before exit.')
+ parser.add_argument('--cache-op',
+ choices=['clear', 'save', 'push'],
+ default='clear',
+ help='Configures cache operation to do before launching '
+ +'Chrome. (Default is clear).')
parser.add_argument('--wpr-archive', default=None, type=str,
help='Web page replay archive to load job\'s urls from.')
parser.add_argument('--wpr-record', default=False, action='store_true',
help='Record web page replay archive.')
args = parser.parse_args()
- try:
- os.makedirs(args.output)
- except OSError:
- logging.error('Cannot create directory for results: %s' % args.output)
- raise
+ if not os.path.isdir(args.output):
+ try:
+ os.makedirs(args.output)
+ except OSError:
+ logging.error('Cannot create directory for results: %s' % args.output)
+ raise
+ else:
+ _CleanPreviousTraces(args.output)
job_urls = _ReadUrlsFromJobDescription(args.job)
device = device_utils.DeviceUtils.HealthyDevices()[0]
+ local_cache_archive_path = os.path.join(args.output, 'cache.zip')
+ local_cache_directory_path = None
+
+ if args.cache_op == 'push':
+ assert os.path.isfile(local_cache_archive_path)
+ local_cache_directory_path = tempfile.mkdtemp(suffix='.cache')
+ _UnzipDirectoryContent(local_cache_archive_path, local_cache_directory_path)
with device_setup.WprHost(device,
args.wpr_archive,
args.wpr_record) as additional_flags:
pages_loaded = 0
- for iteration in xrange(args.repeat):
+ for _ in xrange(args.repeat):
for url in job_urls:
+ if args.cache_op == 'push':
+ device.KillAll(_CHROME_PACKAGE, quiet=True)
+ _PushBrowserCache(device, local_cache_directory_path)
with device_setup.DeviceConnection(
device=device,
additional_flags=additional_flags) as connection:
- if iteration == 0 and pages_loaded == 0 and args.save_cache:
+ if (pages_loaded == 0 and args.cache_op == 'save' or
+ args.cache_op == 'clear'):
connection.ClearCache()
page_track.PageTrack(connection)
tracing_track = tracing.TracingTrack(connection,
@@ -261,7 +342,10 @@ def main():
_SaveChromeTrace(tracing_track.ToJsonDict(), args.output,
str(pages_loaded))
- if args.save_cache:
+ if local_cache_directory_path:
+ shutil.rmtree(local_cache_directory_path)
+
+ if args.cache_op == 'save':
# Move Chrome to background to allow it to flush the index.
device.adb.Shell('am start com.google.android.launcher')
time.sleep(_TIME_TO_DEVICE_IDLE_SECONDS)
@@ -269,8 +353,7 @@ def main():
time.sleep(_TIME_TO_DEVICE_IDLE_SECONDS)
cache_directory_path = _PullBrowserCache(device)
- _ZipDirectoryContent(cache_directory_path,
- os.path.join(args.output, 'cache.zip'))
+ _ZipDirectoryContent(cache_directory_path, local_cache_archive_path)
shutil.rmtree(cache_directory_path)
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698