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""" 6Cache temperature specifies how the browser cache should be configured before 7the page run. 8 9See design doc for details: 10https://docs.google.com/document/u/1/d/12D7tkhZi887g9d0U2askU9JypU_wYiEI7Lw0bfwxUgA 11""" 12 13import logging 14 15import py_utils 16 17# Default Cache Temperature. The page doesn't care which browser cache state 18# it is run on. 19ANY = 'any' 20# Emulates PageCycler V1 cold runs. Clears system DNS cache, browser DiskCache, 21# net/ predictor cache, and net/ host resolver cache. 22PCV1_COLD = 'pcv1-cold' 23# Emulates PageCycler V1 warm runs. Ensures that the page was visited at least 24# once just before the run. 25PCV1_WARM = 'pcv1-warm' 26 27class MarkTelemetryInternal(object): 28 29 def __init__(self, browser, identifier): 30 self.browser = browser 31 self.identifier = identifier 32 33 def __enter__(self): 34 marker = 'telemetry.internal.%s.start' % self.identifier 35 self.browser.tabs[0].ExecuteJavaScript( 36 "console.time({{ marker }});", marker=marker) 37 self.browser.tabs[0].ExecuteJavaScript( 38 "console.timeEnd({{ marker }});", marker=marker) 39 return self 40 41 def __exit__(self, exception_type, exception_value, traceback): 42 if exception_type: 43 return True 44 45 marker = 'telemetry.internal.%s.end' % self.identifier 46 self.browser.tabs[0].ExecuteJavaScript( 47 "console.time({{ marker }});", marker=marker) 48 self.browser.tabs[0].ExecuteJavaScript( 49 "console.timeEnd({{ marker }});", marker=marker) 50 return True 51 52def EnsurePageCacheTemperature(page, browser, previous_page=None): 53 temperature = page.cache_temperature 54 logging.info('PageCacheTemperature: %s', temperature) 55 56 if temperature == ANY: 57 return 58 59 if temperature == PCV1_COLD: 60 if previous_page is None: 61 with MarkTelemetryInternal(browser, 'ensure_diskcache'): 62 tab = browser.tabs[0] 63 tab.Navigate("http://does.not.exist") 64 tab.WaitForDocumentReadyStateToBeComplete() 65 66 any_tab = browser.tabs[0] 67 any_tab.ClearCache(force=True) 68 elif temperature == PCV1_WARM: 69 if (previous_page is not None and 70 previous_page.url == page.url and 71 (previous_page.cache_temperature == PCV1_COLD or 72 previous_page.cache_temperature == PCV1_WARM)): 73 if '#' in page.url: 74 # Navigate to inexistent URL to avoid in-page hash navigation. 75 # Note: Unlike PCv1, PCv2 iterates the same URL for different cache 76 # configurations. This may issue blink in-page hash navigations, 77 # which isn't intended here. 78 with MarkTelemetryInternal(browser, 'avoid_double_hash_navigation'): 79 tab = browser.tabs[0] 80 tab.Navigate("http://does.not.exist") 81 tab.WaitForDocumentReadyStateToBeComplete() 82 return 83 84 with MarkTelemetryInternal(browser, 'warmCache'): 85 tab = browser.tabs[0] 86 tab.Navigate(page.url) 87 py_utils.WaitFor(tab.HasReachedQuiescence, 60) 88 tab.WaitForDocumentReadyStateToBeComplete() 89 tab.Navigate("about:blank") 90 tab.WaitForDocumentReadyStateToBeComplete() 91