Chromium Code Reviews| Index: tools/android/loading/sandwich_tasks.py |
| diff --git a/tools/android/loading/sandwich_tasks.py b/tools/android/loading/sandwich_tasks.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ec51f896ee5764c5784cbc9bc2cb2d82e5e6a35d |
| --- /dev/null |
| +++ b/tools/android/loading/sandwich_tasks.py |
| @@ -0,0 +1,236 @@ |
| +# Copyright 2016 The Chromium Authors. All rights reserved. |
|
pasko
2016/04/14 12:34:42
let's name the file sandwich_task_builder to make
gabadie
2016/04/14 15:43:33
Done.
|
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +import csv |
| +import json |
| +import logging |
| +import os |
| +import re |
| +import shutil |
| + |
| +import chrome_cache |
| +import common_util |
| +import emulation |
| +import loading_trace |
|
pasko
2016/04/14 12:34:43
unneeded import?
please clean up other unneeded i
gabadie
2016/04/14 15:43:32
Done.
|
| +import loading_trace_analyzer |
| +import sandwich_metrics |
| +import sandwich_misc |
| +from sandwich_runner import SandwichRunner |
| +import task_manager |
| + |
| + |
| +def NetworkSimulationTransformer(network_condition): |
| + """Creates a function that accepts a SandwichRunner as a parameter and sets |
| + network emulation options on it. |
| + |
| + Args: |
| + network_condition: The network condition to apply to the sandwich runner. |
| + |
| + Returns: |
| + A callback transforming the SandwichRunner given in argument accordingly |
| + """ |
| + assert network_condition in emulation.NETWORK_CONDITIONS |
| + def RunnerModifier(sandwich_runner): |
|
pasko
2016/04/14 12:34:43
this would be slightly more elegant:
def Transfor
gabadie
2016/04/14 15:43:32
Done.
|
| + assert isinstance(sandwich_runner, SandwichRunner) |
| + sandwich_runner.network_condition = network_condition |
| + return RunnerModifier |
| + |
| + |
| +class SandwichTaskBuilder(task_manager.Builder): |
| + """A builder for a graph of tasks, each prepares or invokes a SandwichRunner. |
| + """ |
| + |
| + def __init__(self, output_directory, job_path, url_repeat): |
| + """Constructor. |
| + |
| + Args: |
| + output_directory: As in task_manager.Builder.__init__ |
| + job_path: Path of the sandwich's job. |
| + url_repeat: Non null integer controlling how many times the URLs should be |
| + repeated in the benchmarks. |
| + """ |
| + task_manager.Builder.__init__(self, output_directory) |
| + self._job_path = job_path |
| + self._url_repeat = url_repeat |
| + self._default_final_tasks = [] |
| + |
| + self._original_wpr_task = None |
| + self._patched_wpr_task = None |
| + self._reference_cache_task = None |
| + self._subresources_for_urls_run_task = None |
| + self._subresources_for_urls_task = None |
| + |
| + @property |
| + def default_final_tasks(self): |
| + return self._default_final_tasks |
| + |
| + def _CreateSandwichRunner(self): |
| + """Create a runner for non benchmark purposes.""" |
| + runner = SandwichRunner() |
| + runner.LoadJob(self._job_path) |
| + return runner |
| + |
| + def OverridePathToWprArchive(self, original_wpr_path): |
| + """Sets the original WPR archive path's to be used. |
| + |
| + Args: |
| + original_wpr_path: Path of the original WPR archive to be used. |
| + """ |
| + self._original_wpr_task = \ |
| + self.CreateStaticTask('common/webpages.wpr', original_wpr_path) |
| + |
| + def PopulateWprRecordingTask(self): |
| + """Records the original WPR archive.""" |
| + @self.RegisterTask('common/webpages.wpr') |
| + def BuildOriginalWpr(): |
| + common_util.VerifyOrCreateParentDirectory(BuildOriginalWpr.path) |
| + runner = self._CreateSandwichRunner() |
| + runner.wpr_archive_path = BuildOriginalWpr.path |
| + runner.wpr_record = True |
| + runner.Run() |
| + |
| + self._original_wpr_task = BuildOriginalWpr |
| + |
| + def PopulateCommonPipelines(self): |
| + """Populates the pipeline that create the reference cache archive and list |
|
pasko
2016/04/14 12:34:43
This should preferably be a one-liner, so:
"""Crea
gabadie
2016/04/14 15:43:33
Done.
|
| + of sub-resources per urls. |
| + |
| + common/cache-ref-validation.log |
| + common/depends on: cache-ref.zip |
|
pasko
2016/04/14 12:34:43
depends on: common/cache-ref.zip
gabadie
2016/04/14 15:43:33
Done.
|
| + common/depends on: webpages-patched.wpr |
| + common/depends on: webpages.wpr |
| + common/depends on: urls-resources.json |
| + common/depends on: urls-resources-run/ |
| + common/depends on: webpages.wpr |
| + |
| + Returns: |
| + The last task of the pipeline. |
| + """ |
| + @self.RegisterTask('common/webpages-patched.wpr', [self._original_wpr_task]) |
| + def BuildPatchedWpr(): |
| + common_util.VerifyOrCreateParentDirectory(BuildPatchedWpr.path) |
| + shutil.copyfile(self._original_wpr_task.path, BuildPatchedWpr.path) |
| + sandwich_misc.PatchWpr(BuildPatchedWpr.path) |
| + |
| + @self.RegisterTask('common/cache-ref.zip', [BuildPatchedWpr]) |
| + def BuildReferenceCache(): |
| + runner = self._CreateSandwichRunner() |
| + runner.wpr_archive_path = BuildPatchedWpr.path |
| + runner.cache_archive_path = BuildReferenceCache.path |
| + runner.cache_operation = 'save' |
| + runner.Run() |
| + |
| + @self.RegisterTask('common/subresources-for-urls-run/', |
| + dependencies=[self._original_wpr_task]) |
| + def UrlsResourcesRun(): |
| + runner = self._CreateSandwichRunner() |
| + runner.wpr_archive_path = self._original_wpr_task.path |
| + runner.cache_operation = 'clear' |
| + runner.trace_output_directory = UrlsResourcesRun.path |
| + runner.Run() |
| + |
| + @self.RegisterTask('common/subresources-for-urls.json', [UrlsResourcesRun]) |
| + def ListUrlsResources(): |
| + json_content = sandwich_misc.ListResourcesUrls(UrlsResourcesRun.path) |
| + with open(ListUrlsResources.path, 'w') as output: |
| + json.dump(json_content, output) |
| + |
| + @self.RegisterTask('common/cache-ref-validation.log', |
| + [BuildReferenceCache, ListUrlsResources]) |
| + def ValidateReferenceCache(): |
| + json_content = json.load(open(ListUrlsResources.path)) |
| + ref_urls = set() |
| + for urls in json_content.values(): |
| + ref_urls.update(set(urls)) |
| + sandwich_misc.ValidateCacheArchiveContent( |
| + ref_urls, BuildReferenceCache.path) |
| + |
| + self._patched_wpr_task = BuildPatchedWpr |
| + self._reference_cache_task = BuildReferenceCache |
| + self._subresources_for_urls_run_task = UrlsResourcesRun |
| + self._subresources_for_urls_task = ListUrlsResources |
| + |
| + self._default_final_tasks.append(ValidateReferenceCache) |
| + return ValidateReferenceCache |
| + |
| + def PopulateLoadBenchmark(self, subresources_discoverer, |
| + runner_transformer_name='dummy', |
| + runner_transformer=lambda arg: None): |
| + """Populate the a benchmark's pipeline from it's setup tasks. |
| + |
| + Args: |
| + subresources_discoverer: Name of a sub-resources discoverer. |
| + runner_transformer: A closure to transform the sandwich runner. |
|
pasko
2016/04/14 12:34:42
it's actually not a closure :(
runner_transformer
pasko
2016/04/14 12:34:43
runner_transformer_name: ...
gabadie
2016/04/14 15:43:32
functions are subsets of closures, and it will be
gabadie
2016/04/14 15:43:32
Done.
|
| + benchmark_name: The benchmark's name for that runner modifier. |
| + |
| + Returns: |
| + The last task of the pipeline. |
|
pasko
2016/04/14 12:34:43
s/task/Task/
gabadie
2016/04/14 15:43:33
Done.
|
| + """ |
| + assert subresources_discoverer in sandwich_misc.SUBRESOURCE_DISCOVERERS |
|
pasko
2016/04/14 12:34:43
s/subresources/subresource/
gabadie
2016/04/14 15:43:32
Done.
|
| + assert 'shared' not in sandwich_misc.SUBRESOURCE_DISCOVERERS |
| + shared_task_preffix = os.path.join('shared', subresources_discoverer) |
|
pasko
2016/04/14 12:34:43
s/preffix/prefix/
gabadie
2016/04/14 15:43:33
Done.
|
| + task_preffix = os.path.join(runner_transformer_name, |
| + subresources_discoverer) |
| + |
| + @self.RegisterTask(shared_task_preffix + '-setup.json', merge=True, |
| + dependencies=[self._subresources_for_urls_task]) |
| + def SetupBenchmark(): |
| + trace_path = os.path.join( |
| + self._subresources_for_urls_run_task.path, '0/trace.json') |
| + whitelisted_urls = sandwich_misc.ExtractDiscoverableUrls( |
| + trace_path, subresources_discoverer) |
| + |
| + urls_resources = json.load(open(self._subresources_for_urls_task.path)) |
| + assert len(urls_resources) == 1, \ |
| + "This recipe is not ready for multiple urls." |
| + url = urls_resources.keys()[0] |
| + url_resources = urls_resources[url] |
| + common_util.VerifyOrCreateParentDirectory(SetupBenchmark.path) |
| + with open(SetupBenchmark.path, 'w') as output: |
| + json.dump({ |
| + 'cache_whitelist': [url for url in whitelisted_urls], |
| + 'url_resources': url_resources, |
| + }, output) |
| + |
| + @self.RegisterTask(shared_task_preffix + '-cache.zip', merge=True, |
| + dependencies=[ |
| + SetupBenchmark, self._reference_cache_task]) |
| + def BuildBenchmarkCacheArchive(): |
| + setup = json.load(open(SetupBenchmark.path)) |
| + chrome_cache.ApplyUrlWhitelistToCacheArchive( |
| + cache_archive_path=self._reference_cache_task.path, |
| + whitelisted_urls=setup['cache_whitelist'], |
| + output_cache_archive_path=BuildBenchmarkCacheArchive.path) |
| + |
| + @self.RegisterTask(task_preffix + '-run/', |
| + dependencies=[BuildBenchmarkCacheArchive]) |
| + def RunBenchmark(): |
| + runner = self._CreateSandwichRunner() |
| + # runner.record_video = True |
| + runner.job_repeat = self._url_repeat |
| + runner_transformer(runner) |
| + runner.wpr_archive_path = self._patched_wpr_task.path |
| + runner.wpr_out_log_path = os.path.join(RunBenchmark.path, 'wpr.log') |
| + runner.cache_archive_path = BuildBenchmarkCacheArchive.path |
| + runner.cache_operation = 'push' |
| + runner.trace_output_directory = RunBenchmark.path |
| + runner.Run() |
| + |
| + @self.RegisterTask(task_preffix + '-metrics.csv', |
| + dependencies=[RunBenchmark]) |
| + def ExtractMetrics(): |
| + sandwich_misc.VerifyBenchmarkOutputDirectory( |
| + SetupBenchmark.path, RunBenchmark.path) |
| + trace_metrics_list = sandwich_metrics.PullMetricsFromOutputDirectory( |
| + RunBenchmark.path) |
| + trace_metrics_list.sort(key=lambda e: e['id']) |
| + with open(ExtractMetrics.path, 'w') as csv_file: |
| + writer = csv.DictWriter(csv_file, |
| + fieldnames=sandwich_metrics.CSV_FIELD_NAMES) |
| + writer.writeheader() |
| + for trace_metrics in trace_metrics_list: |
| + writer.writerow(trace_metrics) |
| + |
| + self._default_final_tasks.append(ExtractMetrics) |
| + return ExtractMetrics |