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