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 """ | 5 """ |
6 Cache temperature specifies how the browser cache should be configured before | 6 Cache temperature specifies how the browser cache should be configured before |
7 the page run. | 7 the page run. |
8 | 8 |
9 See design doc for details: | 9 See design doc for details: |
10 https://docs.google.com/document/u/1/d/12D7tkhZi887g9d0U2askU9JypU_wYiEI7Lw0bfwx UgA | 10 https://docs.google.com/document/u/1/d/12D7tkhZi887g9d0U2askU9JypU_wYiEI7Lw0bfwx UgA |
11 """ | 11 """ |
12 | 12 |
13 import logging | 13 import logging |
14 | 14 |
15 import py_utils | 15 from telemetry.core import exceptions |
16 | 16 |
17 # Default Cache Temperature. The page doesn't care which browser cache state | 17 # Default Cache Temperature. The page doesn't care which browser cache state |
18 # it is run on. | 18 # it is run on. |
19 ANY = 'any' | 19 ANY = 'any' |
20 # Emulates cold runs. Clears various caches and data with using tab.ClearCache() | 20 # Emulates cold runs. Clears various caches and data with using tab.ClearCache() |
21 # and tab.ClearDataForOrigin(). | 21 # and tab.ClearDataForOrigin(). |
22 COLD = 'cold' | 22 COLD = 'cold' |
23 # Emulates warm runs. Ensures that the page was visited at least once just | 23 # Emulates warm runs. Ensures that the page was visited once before the run. |
24 # before the run. | |
25 WARM = 'warm' | 24 WARM = 'warm' |
25 # Emulates hot runs. Ensures that the page was visited at least twice before | |
26 # the run. | |
27 HOT = 'hot' | |
26 | 28 |
27 # These regacy states will be removed after chromium test scripts are adapted | 29 # These regacy states will be removed after chromium test scripts are adapted |
28 # to new states. | 30 # to new states. |
29 PCV1_COLD = COLD | 31 PCV1_COLD = COLD |
30 PCV1_WARM = WARM | 32 PCV1_WARM = WARM |
31 | 33 |
32 class MarkTelemetryInternal(object): | 34 class MarkTelemetryInternal(object): |
33 | 35 |
34 def __init__(self, browser, identifier): | 36 def __init__(self, browser, identifier): |
35 self.browser = browser | 37 self.browser = browser |
36 self.identifier = identifier | 38 self.identifier = identifier |
37 | 39 |
38 def __enter__(self): | 40 def __enter__(self): |
39 marker = 'telemetry.internal.%s.start' % self.identifier | 41 marker = 'telemetry.internal.%s.start' % self.identifier |
40 self.browser.tabs[0].ExecuteJavaScript( | 42 self.browser.tabs[0].ExecuteJavaScript( |
41 "console.time({{ marker }});", marker=marker) | 43 "console.time({{ marker }});", marker=marker) |
42 self.browser.tabs[0].ExecuteJavaScript( | 44 self.browser.tabs[0].ExecuteJavaScript( |
43 "console.timeEnd({{ marker }});", marker=marker) | 45 "console.timeEnd({{ marker }});", marker=marker) |
44 return self | 46 return self |
45 | 47 |
46 def __exit__(self, exception_type, exception_value, traceback): | 48 def __exit__(self, exception_type, exception_value, traceback): |
47 if exception_type: | 49 if exception_type: |
48 return True | 50 return True |
49 | |
50 marker = 'telemetry.internal.%s.end' % self.identifier | 51 marker = 'telemetry.internal.%s.end' % self.identifier |
51 self.browser.tabs[0].ExecuteJavaScript( | 52 self.browser.tabs[0].ExecuteJavaScript( |
52 "console.time({{ marker }});", marker=marker) | 53 "console.time({{ marker }});", marker=marker) |
53 self.browser.tabs[0].ExecuteJavaScript( | 54 self.browser.tabs[0].ExecuteJavaScript( |
54 "console.timeEnd({{ marker }});", marker=marker) | 55 "console.timeEnd({{ marker }});", marker=marker) |
55 return True | 56 return True |
56 | 57 |
57 def ClearCache(browser): | 58 def ClearCacheAndData(browser, url): |
58 tab = browser.tabs[0] | 59 tab = browser.tabs[0] |
59 tab.ClearCache(force=True) | 60 tab.ClearCache(force=True) |
61 tab.ClearDataForOrigin(url) | |
60 | 62 |
61 def WarmCache(page, browser): | 63 def WarmCache(page, browser): |
62 with MarkTelemetryInternal(browser, 'warm_cache'): | 64 with MarkTelemetryInternal(browser, 'warm_cache'): |
63 tab = browser.tabs[0] | 65 tab = browser.tabs[0] |
64 tab.Navigate(page.url) | 66 page.RunNavigateSteps(tab.action_runner) |
65 py_utils.WaitFor(tab.HasReachedQuiescence, 60) | 67 page.RunPageInteractions(tab.action_runner) |
66 tab.WaitForDocumentReadyStateToBeComplete() | |
67 tab.Navigate("about:blank") | 68 tab.Navigate("about:blank") |
68 tab.WaitForDocumentReadyStateToBeComplete() | 69 tab.WaitForDocumentReadyStateToBeComplete() |
69 | 70 |
71 def StopServiceWorker(browser, timeout=60): | |
nednguyen
2017/09/22 08:35:14
s/StopServiceWorker/InstallServiceWorker
yukiy
2017/09/22 10:04:59
Acknowledged.
| |
72 tab = browser.tabs[0] | |
73 res = tab._inspector_backend._websocket.SyncRequest({ | |
nednguyen
2017/09/22 08:35:14
Please don't access private APIs at inspector back
yukiy
2017/09/22 10:04:59
OK! I created new CL so please check it :)
https:/
| |
74 'method': 'ServiceWorker.enable' | |
75 }, timeout) | |
76 if 'error' in res: | |
77 raise exceptions.StoryActionError(res['error']['message']) | |
78 tab._inspector_backend._websocket.SyncRequest({ | |
79 'method': 'ServiceWorker.stopAllWorkers', | |
80 }, timeout) | |
81 if 'error' in res: | |
82 raise exceptions.StoryActionError(res['error']['message']) | |
83 | |
70 def EnsurePageCacheTemperature(page, browser, previous_page=None): | 84 def EnsurePageCacheTemperature(page, browser, previous_page=None): |
71 temperature = page.cache_temperature | 85 temperature = page.cache_temperature |
72 logging.info('PageCacheTemperature: %s', temperature) | 86 logging.info('PageCacheTemperature: %s', temperature) |
73 if temperature == ANY: | 87 if temperature == ANY: |
74 return | 88 return |
75 if temperature == COLD: | 89 if temperature == COLD: |
76 if previous_page is None: | 90 if previous_page is None: |
77 # DiskCache initialization is performed asynchronously on Chrome start-up. | 91 # DiskCache initialization is performed asynchronously on Chrome start-up. |
78 # Ensure that DiskCache is initialized before starting the measurement to | 92 # Ensure that DiskCache is initialized before starting the measurement to |
79 # avoid performance skew. | 93 # avoid performance skew. |
80 # This is done by navigating to an inexistent URL and then wait for the | 94 # This is done by navigating to an inexistent URL and then wait for the |
81 # navigation to complete. | 95 # navigation to complete. |
82 # TODO(kouhei) Consider moving this logic to PageCyclerStory | 96 # TODO(kouhei) Consider moving this logic to PageCyclerStory |
83 with MarkTelemetryInternal(browser, 'ensure_diskcache'): | 97 with MarkTelemetryInternal(browser, 'ensure_diskcache'): |
84 tab = browser.tabs[0] | 98 tab = browser.tabs[0] |
85 tab.Navigate("http://does.not.exist") | 99 tab.Navigate("http://does.not.exist") |
86 tab.WaitForDocumentReadyStateToBeComplete() | 100 tab.WaitForDocumentReadyStateToBeComplete() |
87 ClearCache(browser) | 101 ClearCacheAndData(browser, page.url) |
88 elif temperature == WARM: | 102 elif temperature == WARM: |
89 if (previous_page is not None and | 103 if (previous_page is not None and |
90 previous_page.url == page.url and | 104 previous_page.url == page.url and |
91 (previous_page.cache_temperature == COLD or | 105 previous_page.cache_temperature == COLD): |
92 previous_page.cache_temperature == WARM)): | |
93 if '#' in page.url: | 106 if '#' in page.url: |
94 # Navigate to inexistent URL to avoid in-page hash navigation. | 107 # Navigate to inexistent URL to avoid in-page hash navigation. |
95 # Note: Unlike PCv1, PCv2 iterates the same URL for different cache | 108 # Note: Unlike PCv1, PCv2 iterates the same URL for different cache |
96 # configurations. This may issue blink in-page hash navigations, | 109 # configurations. This may issue blink in-page hash navigations, |
97 # which isn't intended here. | 110 # which isn't intended here. |
98 with MarkTelemetryInternal(browser, 'avoid_double_hash_navigation'): | 111 with MarkTelemetryInternal(browser, 'avoid_double_hash_navigation'): |
99 tab = browser.tabs[0] | 112 tab = browser.tabs[0] |
100 tab.Navigate("http://does.not.exist") | 113 tab.Navigate("http://does.not.exist") |
101 tab.WaitForDocumentReadyStateToBeComplete() | 114 tab.WaitForDocumentReadyStateToBeComplete() |
102 return | 115 else: |
103 WarmCache(page, browser) | 116 ClearCacheAndData(browser, page.url) |
117 WarmCache(page, browser) | |
118 elif temperature == HOT: | |
119 if (previous_page is not None and | |
120 previous_page.url == page.url and | |
121 previous_page.cache_temperature != ANY): | |
122 if previous_page.cache_temperature == COLD: | |
123 WarmCache(page, browser) | |
124 else: | |
125 if '#' in page.url: | |
126 # Navigate to inexistent URL to avoid in-page hash navigation. | |
127 # Note: Unlike PCv1, PCv2 iterates the same URL for different cache | |
128 # configurations. This may issue blink in-page hash navigations, | |
129 # which isn't intended here. | |
130 with MarkTelemetryInternal(browser, 'avoid_double_hash_navigation'): | |
131 tab = browser.tabs[0] | |
132 tab.Navigate("http://does.not.exist") | |
133 tab.WaitForDocumentReadyStateToBeComplete() | |
134 else: | |
135 ClearCacheAndData(browser, page.url) | |
136 WarmCache(page, browser) | |
137 WarmCache(page, browser) | |
138 StopServiceWorker(browser) | |
OLD | NEW |