Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # 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.
| |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import csv | |
| 6 import json | |
| 7 import logging | |
| 8 import os | |
| 9 import re | |
| 10 import shutil | |
| 11 | |
| 12 import chrome_cache | |
| 13 import common_util | |
| 14 import emulation | |
| 15 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.
| |
| 16 import loading_trace_analyzer | |
| 17 import sandwich_metrics | |
| 18 import sandwich_misc | |
| 19 from sandwich_runner import SandwichRunner | |
| 20 import task_manager | |
| 21 | |
| 22 | |
| 23 def NetworkSimulationTransformer(network_condition): | |
| 24 """Creates a function that accepts a SandwichRunner as a parameter and sets | |
| 25 network emulation options on it. | |
| 26 | |
| 27 Args: | |
| 28 network_condition: The network condition to apply to the sandwich runner. | |
| 29 | |
| 30 Returns: | |
| 31 A callback transforming the SandwichRunner given in argument accordingly | |
| 32 """ | |
| 33 assert network_condition in emulation.NETWORK_CONDITIONS | |
| 34 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.
| |
| 35 assert isinstance(sandwich_runner, SandwichRunner) | |
| 36 sandwich_runner.network_condition = network_condition | |
| 37 return RunnerModifier | |
| 38 | |
| 39 | |
| 40 class SandwichTaskBuilder(task_manager.Builder): | |
| 41 """A builder for a graph of tasks, each prepares or invokes a SandwichRunner. | |
| 42 """ | |
| 43 | |
| 44 def __init__(self, output_directory, job_path, url_repeat): | |
| 45 """Constructor. | |
| 46 | |
| 47 Args: | |
| 48 output_directory: As in task_manager.Builder.__init__ | |
| 49 job_path: Path of the sandwich's job. | |
| 50 url_repeat: Non null integer controlling how many times the URLs should be | |
| 51 repeated in the benchmarks. | |
| 52 """ | |
| 53 task_manager.Builder.__init__(self, output_directory) | |
| 54 self._job_path = job_path | |
| 55 self._url_repeat = url_repeat | |
| 56 self._default_final_tasks = [] | |
| 57 | |
| 58 self._original_wpr_task = None | |
| 59 self._patched_wpr_task = None | |
| 60 self._reference_cache_task = None | |
| 61 self._subresources_for_urls_run_task = None | |
| 62 self._subresources_for_urls_task = None | |
| 63 | |
| 64 @property | |
| 65 def default_final_tasks(self): | |
| 66 return self._default_final_tasks | |
| 67 | |
| 68 def _CreateSandwichRunner(self): | |
| 69 """Create a runner for non benchmark purposes.""" | |
| 70 runner = SandwichRunner() | |
| 71 runner.LoadJob(self._job_path) | |
| 72 return runner | |
| 73 | |
| 74 def OverridePathToWprArchive(self, original_wpr_path): | |
| 75 """Sets the original WPR archive path's to be used. | |
| 76 | |
| 77 Args: | |
| 78 original_wpr_path: Path of the original WPR archive to be used. | |
| 79 """ | |
| 80 self._original_wpr_task = \ | |
| 81 self.CreateStaticTask('common/webpages.wpr', original_wpr_path) | |
| 82 | |
| 83 def PopulateWprRecordingTask(self): | |
| 84 """Records the original WPR archive.""" | |
| 85 @self.RegisterTask('common/webpages.wpr') | |
| 86 def BuildOriginalWpr(): | |
| 87 common_util.VerifyOrCreateParentDirectory(BuildOriginalWpr.path) | |
| 88 runner = self._CreateSandwichRunner() | |
| 89 runner.wpr_archive_path = BuildOriginalWpr.path | |
| 90 runner.wpr_record = True | |
| 91 runner.Run() | |
| 92 | |
| 93 self._original_wpr_task = BuildOriginalWpr | |
| 94 | |
| 95 def PopulateCommonPipelines(self): | |
| 96 """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.
| |
| 97 of sub-resources per urls. | |
| 98 | |
| 99 common/cache-ref-validation.log | |
| 100 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.
| |
| 101 common/depends on: webpages-patched.wpr | |
| 102 common/depends on: webpages.wpr | |
| 103 common/depends on: urls-resources.json | |
| 104 common/depends on: urls-resources-run/ | |
| 105 common/depends on: webpages.wpr | |
| 106 | |
| 107 Returns: | |
| 108 The last task of the pipeline. | |
| 109 """ | |
| 110 @self.RegisterTask('common/webpages-patched.wpr', [self._original_wpr_task]) | |
| 111 def BuildPatchedWpr(): | |
| 112 common_util.VerifyOrCreateParentDirectory(BuildPatchedWpr.path) | |
| 113 shutil.copyfile(self._original_wpr_task.path, BuildPatchedWpr.path) | |
| 114 sandwich_misc.PatchWpr(BuildPatchedWpr.path) | |
| 115 | |
| 116 @self.RegisterTask('common/cache-ref.zip', [BuildPatchedWpr]) | |
| 117 def BuildReferenceCache(): | |
| 118 runner = self._CreateSandwichRunner() | |
| 119 runner.wpr_archive_path = BuildPatchedWpr.path | |
| 120 runner.cache_archive_path = BuildReferenceCache.path | |
| 121 runner.cache_operation = 'save' | |
| 122 runner.Run() | |
| 123 | |
| 124 @self.RegisterTask('common/subresources-for-urls-run/', | |
| 125 dependencies=[self._original_wpr_task]) | |
| 126 def UrlsResourcesRun(): | |
| 127 runner = self._CreateSandwichRunner() | |
| 128 runner.wpr_archive_path = self._original_wpr_task.path | |
| 129 runner.cache_operation = 'clear' | |
| 130 runner.trace_output_directory = UrlsResourcesRun.path | |
| 131 runner.Run() | |
| 132 | |
| 133 @self.RegisterTask('common/subresources-for-urls.json', [UrlsResourcesRun]) | |
| 134 def ListUrlsResources(): | |
| 135 json_content = sandwich_misc.ListResourcesUrls(UrlsResourcesRun.path) | |
| 136 with open(ListUrlsResources.path, 'w') as output: | |
| 137 json.dump(json_content, output) | |
| 138 | |
| 139 @self.RegisterTask('common/cache-ref-validation.log', | |
| 140 [BuildReferenceCache, ListUrlsResources]) | |
| 141 def ValidateReferenceCache(): | |
| 142 json_content = json.load(open(ListUrlsResources.path)) | |
| 143 ref_urls = set() | |
| 144 for urls in json_content.values(): | |
| 145 ref_urls.update(set(urls)) | |
| 146 sandwich_misc.ValidateCacheArchiveContent( | |
| 147 ref_urls, BuildReferenceCache.path) | |
| 148 | |
| 149 self._patched_wpr_task = BuildPatchedWpr | |
| 150 self._reference_cache_task = BuildReferenceCache | |
| 151 self._subresources_for_urls_run_task = UrlsResourcesRun | |
| 152 self._subresources_for_urls_task = ListUrlsResources | |
| 153 | |
| 154 self._default_final_tasks.append(ValidateReferenceCache) | |
| 155 return ValidateReferenceCache | |
| 156 | |
| 157 def PopulateLoadBenchmark(self, subresources_discoverer, | |
| 158 runner_transformer_name='dummy', | |
| 159 runner_transformer=lambda arg: None): | |
| 160 """Populate the a benchmark's pipeline from it's setup tasks. | |
| 161 | |
| 162 Args: | |
| 163 subresources_discoverer: Name of a sub-resources discoverer. | |
| 164 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.
| |
| 165 benchmark_name: The benchmark's name for that runner modifier. | |
| 166 | |
| 167 Returns: | |
| 168 The last task of the pipeline. | |
|
pasko
2016/04/14 12:34:43
s/task/Task/
gabadie
2016/04/14 15:43:33
Done.
| |
| 169 """ | |
| 170 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.
| |
| 171 assert 'shared' not in sandwich_misc.SUBRESOURCE_DISCOVERERS | |
| 172 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.
| |
| 173 task_preffix = os.path.join(runner_transformer_name, | |
| 174 subresources_discoverer) | |
| 175 | |
| 176 @self.RegisterTask(shared_task_preffix + '-setup.json', merge=True, | |
| 177 dependencies=[self._subresources_for_urls_task]) | |
| 178 def SetupBenchmark(): | |
| 179 trace_path = os.path.join( | |
| 180 self._subresources_for_urls_run_task.path, '0/trace.json') | |
| 181 whitelisted_urls = sandwich_misc.ExtractDiscoverableUrls( | |
| 182 trace_path, subresources_discoverer) | |
| 183 | |
| 184 urls_resources = json.load(open(self._subresources_for_urls_task.path)) | |
| 185 assert len(urls_resources) == 1, \ | |
| 186 "This recipe is not ready for multiple urls." | |
| 187 url = urls_resources.keys()[0] | |
| 188 url_resources = urls_resources[url] | |
| 189 common_util.VerifyOrCreateParentDirectory(SetupBenchmark.path) | |
| 190 with open(SetupBenchmark.path, 'w') as output: | |
| 191 json.dump({ | |
| 192 'cache_whitelist': [url for url in whitelisted_urls], | |
| 193 'url_resources': url_resources, | |
| 194 }, output) | |
| 195 | |
| 196 @self.RegisterTask(shared_task_preffix + '-cache.zip', merge=True, | |
| 197 dependencies=[ | |
| 198 SetupBenchmark, self._reference_cache_task]) | |
| 199 def BuildBenchmarkCacheArchive(): | |
| 200 setup = json.load(open(SetupBenchmark.path)) | |
| 201 chrome_cache.ApplyUrlWhitelistToCacheArchive( | |
| 202 cache_archive_path=self._reference_cache_task.path, | |
| 203 whitelisted_urls=setup['cache_whitelist'], | |
| 204 output_cache_archive_path=BuildBenchmarkCacheArchive.path) | |
| 205 | |
| 206 @self.RegisterTask(task_preffix + '-run/', | |
| 207 dependencies=[BuildBenchmarkCacheArchive]) | |
| 208 def RunBenchmark(): | |
| 209 runner = self._CreateSandwichRunner() | |
| 210 # runner.record_video = True | |
| 211 runner.job_repeat = self._url_repeat | |
| 212 runner_transformer(runner) | |
| 213 runner.wpr_archive_path = self._patched_wpr_task.path | |
| 214 runner.wpr_out_log_path = os.path.join(RunBenchmark.path, 'wpr.log') | |
| 215 runner.cache_archive_path = BuildBenchmarkCacheArchive.path | |
| 216 runner.cache_operation = 'push' | |
| 217 runner.trace_output_directory = RunBenchmark.path | |
| 218 runner.Run() | |
| 219 | |
| 220 @self.RegisterTask(task_preffix + '-metrics.csv', | |
| 221 dependencies=[RunBenchmark]) | |
| 222 def ExtractMetrics(): | |
| 223 sandwich_misc.VerifyBenchmarkOutputDirectory( | |
| 224 SetupBenchmark.path, RunBenchmark.path) | |
| 225 trace_metrics_list = sandwich_metrics.PullMetricsFromOutputDirectory( | |
| 226 RunBenchmark.path) | |
| 227 trace_metrics_list.sort(key=lambda e: e['id']) | |
| 228 with open(ExtractMetrics.path, 'w') as csv_file: | |
| 229 writer = csv.DictWriter(csv_file, | |
| 230 fieldnames=sandwich_metrics.CSV_FIELD_NAMES) | |
| 231 writer.writeheader() | |
| 232 for trace_metrics in trace_metrics_list: | |
| 233 writer.writerow(trace_metrics) | |
| 234 | |
| 235 self._default_final_tasks.append(ExtractMetrics) | |
| 236 return ExtractMetrics | |
| OLD | NEW |