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 | |
16 | |
17 # Default Cache Temperature. The page doesn't care which browser cache state | 15 # Default Cache Temperature. The page doesn't care which browser cache state |
18 # it is run on. | 16 # it is run on. |
19 ANY = 'any' | 17 ANY = 'any' |
20 # Emulates cold runs. Clears various caches and data with using tab.ClearCache() | 18 # Emulates cold runs. Clears various caches and data with using tab.ClearCache() |
21 # and tab.ClearDataForOrigin(). | 19 # and tab.ClearDataForOrigin(). |
22 COLD = 'cold' | 20 COLD = 'cold' |
23 # Emulates warm runs. Ensures that the page was visited at least once just | 21 # Emulates warm runs. Ensures that the page was visited once before the run. |
24 # before the run. | |
25 WARM = 'warm' | 22 WARM = 'warm' |
23 # Emulates hot runs. Ensures that the page was visited at least twice before | |
24 # the run. | |
25 HOT = 'hot' | |
26 | 26 |
27 # These regacy states will be removed after chromium test scripts are adapted | 27 # These regacy states will be removed after chromium test scripts are adapted |
28 # to new states. | 28 # to new states. |
29 PCV1_COLD = COLD | 29 PCV1_COLD = COLD |
30 PCV1_WARM = WARM | 30 PCV1_WARM = WARM |
31 | 31 |
32 class MarkTelemetryInternal(object): | 32 class MarkTelemetryInternal(object): |
33 | 33 |
34 def __init__(self, browser, identifier): | 34 def __init__(self, browser, identifier): |
35 self.browser = browser | 35 self.browser = browser |
36 self.identifier = identifier | 36 self.identifier = identifier |
37 | 37 |
38 def __enter__(self): | 38 def __enter__(self): |
39 marker = 'telemetry.internal.%s.start' % self.identifier | 39 marker = 'telemetry.internal.%s.start' % self.identifier |
40 self.browser.tabs[0].ExecuteJavaScript( | 40 self.browser.tabs[0].ExecuteJavaScript( |
41 "console.time({{ marker }});", marker=marker) | 41 "console.time({{ marker }});", marker=marker) |
42 self.browser.tabs[0].ExecuteJavaScript( | 42 self.browser.tabs[0].ExecuteJavaScript( |
43 "console.timeEnd({{ marker }});", marker=marker) | 43 "console.timeEnd({{ marker }});", marker=marker) |
44 return self | 44 return self |
45 | 45 |
46 def __exit__(self, exception_type, exception_value, traceback): | 46 def __exit__(self, exception_type, exception_value, traceback): |
47 if exception_type: | 47 if exception_type: |
48 return True | 48 return True |
49 | |
50 marker = 'telemetry.internal.%s.end' % self.identifier | 49 marker = 'telemetry.internal.%s.end' % self.identifier |
51 self.browser.tabs[0].ExecuteJavaScript( | 50 self.browser.tabs[0].ExecuteJavaScript( |
52 "console.time({{ marker }});", marker=marker) | 51 "console.time({{ marker }});", marker=marker) |
53 self.browser.tabs[0].ExecuteJavaScript( | 52 self.browser.tabs[0].ExecuteJavaScript( |
54 "console.timeEnd({{ marker }});", marker=marker) | 53 "console.timeEnd({{ marker }});", marker=marker) |
55 return True | 54 return True |
56 | 55 |
57 def ClearCache(browser): | 56 def ClearCacheAndData(browser, url): |
58 tab = browser.tabs[0] | 57 tab = browser.tabs[0] |
59 tab.ClearCache(force=True) | 58 tab.ClearCache(force=True) |
59 tab.ClearDataForOrigin(url) | |
60 | 60 |
61 def WarmCache(page, browser): | 61 def WarmCache(page, browser, temperature): |
62 with MarkTelemetryInternal(browser, 'warm_cache'): | 62 with MarkTelemetryInternal(browser, 'warm_cache.%s' % temperature): |
63 tab = browser.tabs[0] | 63 tab = browser.tabs[0] |
64 tab.Navigate(page.url) | 64 page.RunNavigateSteps(tab.action_runner) |
nednguyen
2017/09/26 10:07:19
wait, you mean page.RunNavigateSteps(page.url), ri
yukiy
2017/09/26 10:36:25
In loading.mobile, it will be PageCyclerStory.RunN
nednguyen
2017/09/26 10:49:04
ok
| |
65 py_utils.WaitFor(tab.HasReachedQuiescence, 60) | 65 page.RunPageInteractions(tab.action_runner) |
66 tab.WaitForDocumentReadyStateToBeComplete() | |
67 tab.Navigate("about:blank") | 66 tab.Navigate("about:blank") |
68 tab.WaitForDocumentReadyStateToBeComplete() | 67 tab.WaitForDocumentReadyStateToBeComplete() |
68 # Stop service worker after each cache warming to ensure service worker | |
69 # script evaluation will be executed again in next navigation. | |
70 tab.StopAllServiceWorkers() | |
69 | 71 |
70 def EnsurePageCacheTemperature(page, browser, previous_page=None): | 72 def EnsurePageCacheTemperature(page, browser, previous_page=None): |
71 temperature = page.cache_temperature | 73 temperature = page.cache_temperature |
72 logging.info('PageCacheTemperature: %s', temperature) | 74 logging.info('PageCacheTemperature: %s', temperature) |
73 if temperature == ANY: | 75 if temperature == ANY: |
74 return | 76 return |
75 if temperature == COLD: | 77 if temperature == COLD: |
76 if previous_page is None: | 78 if previous_page is None: |
77 # DiskCache initialization is performed asynchronously on Chrome start-up. | 79 # DiskCache initialization is performed asynchronously on Chrome start-up. |
78 # Ensure that DiskCache is initialized before starting the measurement to | 80 # Ensure that DiskCache is initialized before starting the measurement to |
79 # avoid performance skew. | 81 # avoid performance skew. |
80 # This is done by navigating to an inexistent URL and then wait for the | 82 # This is done by navigating to an inexistent URL and then wait for the |
81 # navigation to complete. | 83 # navigation to complete. |
82 # TODO(kouhei) Consider moving this logic to PageCyclerStory | 84 # TODO(kouhei) Consider moving this logic to PageCyclerStory |
83 with MarkTelemetryInternal(browser, 'ensure_diskcache'): | 85 with MarkTelemetryInternal(browser, 'ensure_diskcache'): |
84 tab = browser.tabs[0] | 86 tab = browser.tabs[0] |
85 tab.Navigate("http://does.not.exist") | 87 tab.Navigate("http://does.not.exist") |
86 tab.WaitForDocumentReadyStateToBeComplete() | 88 tab.WaitForDocumentReadyStateToBeComplete() |
87 ClearCache(browser) | 89 ClearCacheAndData(browser, page.url) |
88 elif temperature == WARM: | 90 elif temperature == WARM: |
89 if (previous_page is not None and | 91 if (previous_page is not None and |
90 previous_page.url == page.url and | 92 previous_page.url == page.url and |
91 (previous_page.cache_temperature == COLD or | 93 previous_page.cache_temperature == COLD): |
92 previous_page.cache_temperature == WARM)): | |
93 if '#' in page.url: | 94 if '#' in page.url: |
94 # Navigate to inexistent URL to avoid in-page hash navigation. | 95 # Navigate to inexistent URL to avoid in-page hash navigation. |
95 # Note: Unlike PCv1, PCv2 iterates the same URL for different cache | 96 # Note: Unlike PCv1, PCv2 iterates the same URL for different cache |
96 # configurations. This may issue blink in-page hash navigations, | 97 # configurations. This may issue blink in-page hash navigations, |
97 # which isn't intended here. | 98 # which isn't intended here. |
98 with MarkTelemetryInternal(browser, 'avoid_double_hash_navigation'): | 99 with MarkTelemetryInternal(browser, 'avoid_double_hash_navigation'): |
99 tab = browser.tabs[0] | 100 tab = browser.tabs[0] |
100 tab.Navigate("http://does.not.exist") | 101 tab.Navigate("http://does.not.exist") |
101 tab.WaitForDocumentReadyStateToBeComplete() | 102 tab.WaitForDocumentReadyStateToBeComplete() |
102 return | 103 # Stop all service workers before running tests to measure the starting |
103 WarmCache(page, browser) | 104 # time of service worker too. |
105 browser.tabs[0].StopAllServiceWorkers() | |
106 else: | |
107 ClearCacheAndData(browser, page.url) | |
108 WarmCache(page, browser, WARM) | |
109 elif temperature == HOT: | |
110 if (previous_page is not None and | |
111 previous_page.url == page.url and | |
112 previous_page.cache_temperature != ANY): | |
113 if previous_page.cache_temperature == COLD: | |
114 WarmCache(page, browser, HOT) | |
115 else: | |
116 if '#' in page.url: | |
117 # Navigate to inexistent URL to avoid in-page hash navigation. | |
118 # Note: Unlike PCv1, PCv2 iterates the same URL for different cache | |
119 # configurations. This may issue blink in-page hash navigations, | |
120 # which isn't intended here. | |
121 with MarkTelemetryInternal(browser, 'avoid_double_hash_navigation'): | |
122 tab = browser.tabs[0] | |
123 tab.Navigate("http://does.not.exist") | |
124 tab.WaitForDocumentReadyStateToBeComplete() | |
125 # Stop all service workers before running tests to measure the starting | |
126 # time of service worker too. | |
127 browser.tabs[0].StopAllServiceWorkers() | |
falken
2017/09/26 08:46:06
I defer to kouhei and ned for the owner review. Bu
yukiy
2017/09/26 09:01:32
Sorry for confusing you, but it was discussed in o
nednguyen
2017/09/26 10:07:19
shimazu@: can you pick up the refactoring work aft
| |
128 else: | |
129 ClearCacheAndData(browser, page.url) | |
130 WarmCache(page, browser, WARM) | |
131 WarmCache(page, browser, HOT) | |
OLD | NEW |