| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Pull a sandwich run's output directory's metrics from traces into a CSV. | 5 """Pull a sandwich run's output directory's metrics from traces into a CSV. |
| 6 | 6 |
| 7 python pull_sandwich_metrics.py -h | 7 python pull_sandwich_metrics.py -h |
| 8 """ | 8 """ |
| 9 | 9 |
| 10 import collections | 10 import collections |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 from telemetry.internal.image_processing import video | 25 from telemetry.internal.image_processing import video |
| 26 from telemetry.util import image_util | 26 from telemetry.util import image_util |
| 27 from telemetry.util import rgba_color | 27 from telemetry.util import rgba_color |
| 28 | 28 |
| 29 import loading_trace as loading_trace_module | 29 import loading_trace as loading_trace_module |
| 30 import sandwich_runner | 30 import sandwich_runner |
| 31 import sandwich_misc | 31 import sandwich_misc |
| 32 import tracing | 32 import tracing |
| 33 | 33 |
| 34 | 34 |
| 35 CSV_FIELD_NAMES = [ | 35 COMMON_CSV_COLUMN_NAMES = [ |
| 36 'repeat_id', | |
| 37 'url', | |
| 38 'chromium_commit', | 36 'chromium_commit', |
| 39 'platform', | 37 'platform', |
| 40 'subresource_discoverer', | |
| 41 'subresource_count', | |
| 42 # The amount of subresources detected at SetupBenchmark step. | |
| 43 'subresource_count_theoretic', | |
| 44 # Amount of subresources for caching as suggested by the subresource | |
| 45 # discoverer. | |
| 46 'cached_subresource_count_theoretic', | |
| 47 'cached_subresource_count', | |
| 48 'first_layout', | 38 'first_layout', |
| 49 'first_contentful_paint', | 39 'first_contentful_paint', |
| 50 'total_load', | 40 'total_load', |
| 51 'js_onload_event', | 41 'js_onload_event', |
| 52 'browser_malloc_avg', | 42 'browser_malloc_avg', |
| 53 'browser_malloc_max', | 43 'browser_malloc_max', |
| 54 'speed_index', | 44 'speed_index', |
| 55 'net_emul.name', # Should be in emulation.NETWORK_CONDITIONS.keys() | 45 'net_emul.name', # Should be in emulation.NETWORK_CONDITIONS.keys() |
| 56 'net_emul.download', | 46 'net_emul.download', |
| 57 'net_emul.upload', | 47 'net_emul.upload', |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 assert attr['units'] == 'bytes' | 195 assert attr['units'] == 'bytes' |
| 206 size = int(attr['value'], 16) | 196 size = int(attr['value'], 16) |
| 207 browser_malloc_sum += size | 197 browser_malloc_sum += size |
| 208 browser_malloc_max = max(browser_malloc_max, size) | 198 browser_malloc_max = max(browser_malloc_max, size) |
| 209 return { | 199 return { |
| 210 'browser_malloc_avg': browser_malloc_sum / float(len(browser_dump_events)), | 200 'browser_malloc_avg': browser_malloc_sum / float(len(browser_dump_events)), |
| 211 'browser_malloc_max': browser_malloc_max | 201 'browser_malloc_max': browser_malloc_max |
| 212 } | 202 } |
| 213 | 203 |
| 214 | 204 |
| 215 def _ExtractBenchmarkStatistics(benchmark_setup, loading_trace): | |
| 216 """Extracts some useful statistics from a benchmark run. | |
| 217 | |
| 218 Args: | |
| 219 benchmark_setup: benchmark_setup: dict representing the benchmark setup | |
| 220 JSON. The JSON format is according to: | |
| 221 PrefetchBenchmarkBuilder.PopulateLoadBenchmark.SetupBenchmark. | |
| 222 loading_trace: loading_trace_module.LoadingTrace. | |
| 223 | |
| 224 Returns: | |
| 225 Dictionary with all extracted fields set. | |
| 226 """ | |
| 227 return { | |
| 228 'subresource_discoverer': benchmark_setup['subresource_discoverer'], | |
| 229 'subresource_count': len(sandwich_misc.ListUrlRequests( | |
| 230 loading_trace, sandwich_misc.RequestOutcome.All)), | |
| 231 'subresource_count_theoretic': len(benchmark_setup['url_resources']), | |
| 232 'cached_subresource_count': len(sandwich_misc.ListUrlRequests( | |
| 233 loading_trace, sandwich_misc.RequestOutcome.ServedFromCache)), | |
| 234 'cached_subresource_count_theoretic': | |
| 235 len(benchmark_setup['cache_whitelist']), | |
| 236 } | |
| 237 | |
| 238 | |
| 239 def _ExtractCompletenessRecordFromVideo(video_path): | 205 def _ExtractCompletenessRecordFromVideo(video_path): |
| 240 """Extracts the completeness record from a video. | 206 """Extracts the completeness record from a video. |
| 241 | 207 |
| 242 The video must start with a filled rectangle of orange (RGB: 222, 100, 13), to | 208 The video must start with a filled rectangle of orange (RGB: 222, 100, 13), to |
| 243 give the view-port size/location from where to compute the completeness. | 209 give the view-port size/location from where to compute the completeness. |
| 244 | 210 |
| 245 Args: | 211 Args: |
| 246 video_path: Path of the video to extract the completeness list from. | 212 video_path: Path of the video to extract the completeness list from. |
| 247 | 213 |
| 248 Returns: | 214 Returns: |
| (...skipping 17 matching lines...) Expand all Loading... |
| 266 if total_distance == 0: | 232 if total_distance == 0: |
| 267 if histogram.Distance(final_histogram) == 0: | 233 if histogram.Distance(final_histogram) == 0: |
| 268 return 1.0 | 234 return 1.0 |
| 269 else: | 235 else: |
| 270 return 0.0 | 236 return 0.0 |
| 271 return 1 - histogram.Distance(final_histogram) / total_distance | 237 return 1 - histogram.Distance(final_histogram) / total_distance |
| 272 | 238 |
| 273 return [(time, FrameProgress(hist)) for time, hist in histograms] | 239 return [(time, FrameProgress(hist)) for time, hist in histograms] |
| 274 | 240 |
| 275 | 241 |
| 276 def ComputeSpeedIndex(completeness_record): | 242 def _ComputeSpeedIndex(completeness_record): |
| 277 """Computes the speed-index from a completeness record. | 243 """Computes the speed-index from a completeness record. |
| 278 | 244 |
| 279 Args: | 245 Args: |
| 280 completeness_record: list(CompletenessPoint) | 246 completeness_record: list(CompletenessPoint) |
| 281 | 247 |
| 282 Returns: | 248 Returns: |
| 283 Speed-index value. | 249 Speed-index value. |
| 284 """ | 250 """ |
| 285 speed_index = 0.0 | 251 speed_index = 0.0 |
| 286 last_time = completeness_record[0][0] | 252 last_time = completeness_record[0][0] |
| 287 last_completness = completeness_record[0][1] | 253 last_completness = completeness_record[0][1] |
| 288 for time, completeness in completeness_record: | 254 for time, completeness in completeness_record: |
| 289 if time < last_time: | 255 if time < last_time: |
| 290 raise ValueError('Completeness record must be sorted by timestamps.') | 256 raise ValueError('Completeness record must be sorted by timestamps.') |
| 291 elapsed = time - last_time | 257 elapsed = time - last_time |
| 292 speed_index += elapsed * (1.0 - last_completness) | 258 speed_index += elapsed * (1.0 - last_completness) |
| 293 last_time = time | 259 last_time = time |
| 294 last_completness = completeness | 260 last_completness = completeness |
| 295 return speed_index | 261 return speed_index |
| 296 | 262 |
| 297 | 263 |
| 298 def _ExtractMetricsFromRunDirectory(benchmark_setup, run_directory_path): | 264 def ExtractCommonMetricsFromRepeatDirectory(repeat_dir, trace): |
| 299 """Extracts all the metrics from traces and video of a sandwich run. | 265 """Extracts all the metrics from traces and video of a sandwich run repeat |
| 266 directory. |
| 300 | 267 |
| 301 Args: | 268 Args: |
| 302 benchmark_setup: benchmark_setup: dict representing the benchmark setup | 269 repeat_dir: Path of the repeat directory within a run directory. |
| 303 JSON. The JSON format is according to: | 270 trace: preloaded LoadingTrace in |repeat_dir| |
| 304 PrefetchBenchmarkBuilder.PopulateLoadBenchmark.SetupBenchmark. | 271 |
| 305 run_directory_path: Path of the run directory. | 272 Contract: |
| 273 trace == LoadingTrace.FromJsonFile( |
| 274 os.path.join(repeat_dir, sandwich_runner.TRACE_FILENAME)) |
| 306 | 275 |
| 307 Returns: | 276 Returns: |
| 308 Dictionary of extracted metrics. | 277 Dictionary of extracted metrics. |
| 309 """ | 278 """ |
| 310 trace_path = os.path.join(run_directory_path, 'trace.json') | |
| 311 logging.info('processing trace \'%s\'' % trace_path) | |
| 312 loading_trace = loading_trace_module.LoadingTrace.FromJsonFile(trace_path) | |
| 313 run_metrics = { | 279 run_metrics = { |
| 314 'url': loading_trace.url, | 280 'chromium_commit': trace.metadata['chromium_commit'], |
| 315 'chromium_commit': loading_trace.metadata['chromium_commit'], | 281 'platform': (trace.metadata['platform']['os'] + '-' + |
| 316 'platform': (loading_trace.metadata['platform']['os'] + '-' + | 282 trace.metadata['platform']['product_model']) |
| 317 loading_trace.metadata['platform']['product_model']) | |
| 318 } | 283 } |
| 319 run_metrics.update(_ExtractDefaultMetrics(loading_trace)) | 284 run_metrics.update(_ExtractDefaultMetrics(trace)) |
| 320 run_metrics.update(_ExtractMemoryMetrics(loading_trace)) | 285 run_metrics.update(_ExtractMemoryMetrics(trace)) |
| 321 if benchmark_setup: | 286 video_path = os.path.join(repeat_dir, sandwich_runner.VIDEO_FILENAME) |
| 322 run_metrics.update( | |
| 323 _ExtractBenchmarkStatistics(benchmark_setup, loading_trace)) | |
| 324 video_path = os.path.join(run_directory_path, 'video.mp4') | |
| 325 if os.path.isfile(video_path): | 287 if os.path.isfile(video_path): |
| 326 logging.info('processing speed-index video \'%s\'' % video_path) | 288 logging.info('processing speed-index video \'%s\'' % video_path) |
| 327 try: | 289 try: |
| 328 completeness_record = _ExtractCompletenessRecordFromVideo(video_path) | 290 completeness_record = _ExtractCompletenessRecordFromVideo(video_path) |
| 329 run_metrics['speed_index'] = ComputeSpeedIndex(completeness_record) | 291 run_metrics['speed_index'] = _ComputeSpeedIndex(completeness_record) |
| 330 except video.BoundingBoxNotFoundException: | 292 except video.BoundingBoxNotFoundException: |
| 331 # Sometimes the bounding box for the web content area is not present. Skip | 293 # Sometimes the bounding box for the web content area is not present. Skip |
| 332 # calculating Speed Index. | 294 # calculating Speed Index. |
| 333 run_metrics['speed_index'] = _FAILED_CSV_VALUE | 295 run_metrics['speed_index'] = _FAILED_CSV_VALUE |
| 334 else: | 296 else: |
| 335 run_metrics['speed_index'] = _UNAVAILABLE_CSV_VALUE | 297 run_metrics['speed_index'] = _UNAVAILABLE_CSV_VALUE |
| 336 for key, value in loading_trace.metadata['network_emulation'].iteritems(): | 298 for key, value in trace.metadata['network_emulation'].iteritems(): |
| 337 run_metrics['net_emul.' + key] = value | 299 run_metrics['net_emul.' + key] = value |
| 300 assert set(run_metrics.keys()) == set(COMMON_CSV_COLUMN_NAMES) |
| 338 return run_metrics | 301 return run_metrics |
| 339 | |
| 340 | |
| 341 def ExtractMetricsFromRunnerOutputDirectory(benchmark_setup_path, | |
| 342 output_directory_path): | |
| 343 """Extracts all the metrics from all the traces of a sandwich runner output | |
| 344 directory. | |
| 345 | |
| 346 Args: | |
| 347 benchmark_setup_path: Path of the JSON of the benchmark setup. | |
| 348 output_directory_path: The sandwich runner's output directory to extract the | |
| 349 metrics from. | |
| 350 | |
| 351 Returns: | |
| 352 List of dictionaries. | |
| 353 """ | |
| 354 benchmark_setup = None | |
| 355 if benchmark_setup_path: | |
| 356 benchmark_setup = json.load(open(benchmark_setup_path)) | |
| 357 assert os.path.isdir(output_directory_path) | |
| 358 metrics = [] | |
| 359 for node_name in os.listdir(output_directory_path): | |
| 360 if not os.path.isdir(os.path.join(output_directory_path, node_name)): | |
| 361 continue | |
| 362 try: | |
| 363 repeat_id = int(node_name) | |
| 364 except ValueError: | |
| 365 continue | |
| 366 run_directory_path = os.path.join(output_directory_path, node_name) | |
| 367 run_metrics = _ExtractMetricsFromRunDirectory( | |
| 368 benchmark_setup, run_directory_path) | |
| 369 run_metrics['repeat_id'] = repeat_id | |
| 370 # TODO(gabadie): Make common metrics extraction with benchmark type | |
| 371 # specific CSV column. | |
| 372 # assert set(run_metrics.keys()) == set(CSV_FIELD_NAMES) | |
| 373 metrics.append(run_metrics) | |
| 374 assert len(metrics) > 0, ('Looks like \'{}\' was not a sandwich runner ' + | |
| 375 'output directory.').format(output_directory_path) | |
| 376 return metrics | |
| OLD | NEW |