OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include "core/frame/Deprecation.h" | 5 #include "core/frame/Deprecation.h" |
6 #include "core/frame/UseCounter.h" | 6 #include "core/frame/UseCounter.h" |
7 #include "core/page/Page.h" | 7 #include "core/page/Page.h" |
8 #include "core/testing/DummyPageHolder.h" | 8 #include "core/testing/DummyPageHolder.h" |
9 #include "platform/testing/HistogramTester.h" | 9 #include "platform/testing/HistogramTester.h" |
10 #include "platform/testing/URLTestHelpers.h" | 10 #include "platform/testing/URLTestHelpers.h" |
11 #include "platform/weborigin/KURL.h" | 11 #include "platform/weborigin/KURL.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 | 13 |
14 namespace { | 14 namespace { |
15 // Note that the new histogram names will change once the semantics stabilize; | |
16 const char* const kFeaturesHistogramName = "Blink.UseCounter.Features"; | 15 const char* const kFeaturesHistogramName = "Blink.UseCounter.Features"; |
17 const char* const kCSSHistogramName = "Blink.UseCounter.CSSProperties"; | 16 const char* const kCSSHistogramName = "Blink.UseCounter.CSSProperties"; |
| 17 const char* const kAnimatedCSSHistogramName = |
| 18 "Blink.UseCounter.AnimatedCSSProperties"; |
| 19 |
18 const char* const kSVGFeaturesHistogramName = | 20 const char* const kSVGFeaturesHistogramName = |
19 "Blink.UseCounter.SVGImage.Features"; | 21 "Blink.UseCounter.SVGImage.Features"; |
20 const char* const kSVGCSSHistogramName = | 22 const char* const kSVGCSSHistogramName = |
21 "Blink.UseCounter.SVGImage.CSSProperties"; | 23 "Blink.UseCounter.SVGImage.CSSProperties"; |
| 24 const char* const kSVGAnimatedCSSHistogramName = |
| 25 "Blink.UseCounter.SVGImage.AnimatedCSSProperties"; |
| 26 |
22 const char* const kLegacyFeaturesHistogramName = "WebCore.FeatureObserver"; | 27 const char* const kLegacyFeaturesHistogramName = "WebCore.FeatureObserver"; |
23 const char* const kLegacyCSSHistogramName = | 28 const char* const kLegacyCSSHistogramName = |
24 "WebCore.FeatureObserver.CSSProperties"; | 29 "WebCore.FeatureObserver.CSSProperties"; |
25 } | 30 } |
26 | 31 |
27 namespace blink { | 32 namespace blink { |
28 | 33 |
29 template <typename T> | 34 template <typename T> |
30 void histogramBasicTest(const std::string& histogram, | 35 void histogramBasicTest(const std::string& histogram, |
31 const std::string& legacyHistogram, | 36 const std::string& legacyHistogram, |
32 const std::vector<std::string>& unaffectedHistograms, | 37 const std::vector<std::string>& unaffectedHistograms, |
33 T item, | 38 T item, |
34 T secondItem, | 39 T secondItem, |
35 std::function<bool(T)> counted, | 40 std::function<bool(T)> counted, |
36 std::function<void(T)> count, | 41 std::function<void(T)> count, |
37 std::function<int(T)> histogramMap, | 42 std::function<int(T)> histogramMap, |
38 std::function<void(KURL)> didCommitLoad, | 43 std::function<void(KURL)> didCommitLoad, |
39 const std::string& url, | 44 const std::string& url, |
40 int pageVisitBucket) { | 45 int pageVisitBucket) { |
41 HistogramTester histogramTester; | 46 HistogramTester histogramTester; |
42 | 47 |
43 // Test recording a single (arbitrary) counter | 48 // Test recording a single (arbitrary) counter |
44 EXPECT_FALSE(counted(item)); | 49 EXPECT_FALSE(counted(item)); |
45 count(item); | 50 count(item); |
46 EXPECT_TRUE(counted(item)); | 51 EXPECT_TRUE(counted(item)); |
47 histogramTester.expectUniqueSample(histogram, histogramMap(item), 1); | 52 histogramTester.expectUniqueSample(histogram, histogramMap(item), 1); |
48 histogramTester.expectTotalCount(legacyHistogram, 0); | 53 if (!legacyHistogram.empty()) { |
| 54 histogramTester.expectTotalCount(legacyHistogram, 0); |
| 55 } |
49 | 56 |
50 // Test that repeated measurements have no effect | 57 // Test that repeated measurements have no effect |
51 count(item); | 58 count(item); |
52 histogramTester.expectUniqueSample(histogram, histogramMap(item), 1); | 59 histogramTester.expectUniqueSample(histogram, histogramMap(item), 1); |
53 histogramTester.expectTotalCount(legacyHistogram, 0); | 60 if (!legacyHistogram.empty()) { |
| 61 histogramTester.expectTotalCount(legacyHistogram, 0); |
| 62 } |
54 | 63 |
55 // Test recording a different sample | 64 // Test recording a different sample |
56 EXPECT_FALSE(counted(secondItem)); | 65 EXPECT_FALSE(counted(secondItem)); |
57 count(secondItem); | 66 count(secondItem); |
58 EXPECT_TRUE(counted(secondItem)); | 67 EXPECT_TRUE(counted(secondItem)); |
59 histogramTester.expectBucketCount(histogram, histogramMap(item), 1); | 68 histogramTester.expectBucketCount(histogram, histogramMap(item), 1); |
60 histogramTester.expectBucketCount(histogram, histogramMap(secondItem), 1); | 69 histogramTester.expectBucketCount(histogram, histogramMap(secondItem), 1); |
61 histogramTester.expectTotalCount(histogram, 2); | 70 histogramTester.expectTotalCount(histogram, 2); |
62 histogramTester.expectTotalCount(legacyHistogram, 0); | 71 if (!legacyHistogram.empty()) { |
| 72 histogramTester.expectTotalCount(legacyHistogram, 0); |
| 73 } |
63 | 74 |
64 // After a page load, the histograms will be updated, even when the URL | 75 // After a page load, the histograms will be updated, even when the URL |
65 // scheme is internal | 76 // scheme is internal |
66 didCommitLoad(URLTestHelpers::toKURL(url)); | 77 didCommitLoad(URLTestHelpers::toKURL(url)); |
67 histogramTester.expectBucketCount(histogram, histogramMap(item), 1); | 78 histogramTester.expectBucketCount(histogram, histogramMap(item), 1); |
68 histogramTester.expectBucketCount(histogram, histogramMap(secondItem), 1); | 79 histogramTester.expectBucketCount(histogram, histogramMap(secondItem), 1); |
69 histogramTester.expectBucketCount(histogram, pageVisitBucket, 1); | 80 histogramTester.expectBucketCount(histogram, pageVisitBucket, 1); |
70 histogramTester.expectTotalCount(histogram, 3); | 81 histogramTester.expectTotalCount(histogram, 3); |
71 | 82 |
72 // And verify the legacy histogram now looks the same | 83 // And verify the legacy histogram now looks the same |
73 histogramTester.expectBucketCount(legacyHistogram, histogramMap(item), 1); | 84 if (!legacyHistogram.empty()) { |
74 histogramTester.expectBucketCount(legacyHistogram, histogramMap(secondItem), | 85 histogramTester.expectBucketCount(legacyHistogram, histogramMap(item), 1); |
75 1); | 86 histogramTester.expectBucketCount(legacyHistogram, histogramMap(secondItem), |
76 histogramTester.expectBucketCount(legacyHistogram, pageVisitBucket, 1); | 87 1); |
77 histogramTester.expectTotalCount(legacyHistogram, 3); | 88 histogramTester.expectBucketCount(legacyHistogram, pageVisitBucket, 1); |
| 89 histogramTester.expectTotalCount(legacyHistogram, 3); |
| 90 } |
78 | 91 |
79 // Now a repeat measurement should get recorded again, exactly once | 92 // Now a repeat measurement should get recorded again, exactly once |
80 EXPECT_FALSE(counted(item)); | 93 EXPECT_FALSE(counted(item)); |
81 count(item); | 94 count(item); |
82 count(item); | 95 count(item); |
83 EXPECT_TRUE(counted(item)); | 96 EXPECT_TRUE(counted(item)); |
84 histogramTester.expectBucketCount(histogram, histogramMap(item), 2); | 97 histogramTester.expectBucketCount(histogram, histogramMap(item), 2); |
85 histogramTester.expectTotalCount(histogram, 4); | 98 histogramTester.expectTotalCount(histogram, 4); |
86 | 99 |
87 // And on the next page load, the legacy histogram will again be updated | 100 // And on the next page load, the legacy histogram will again be updated |
88 didCommitLoad(URLTestHelpers::toKURL(url)); | 101 didCommitLoad(URLTestHelpers::toKURL(url)); |
89 histogramTester.expectBucketCount(legacyHistogram, histogramMap(item), 2); | 102 if (!legacyHistogram.empty()) { |
90 histogramTester.expectBucketCount(legacyHistogram, histogramMap(secondItem), | 103 histogramTester.expectBucketCount(legacyHistogram, histogramMap(item), 2); |
91 1); | 104 histogramTester.expectBucketCount(legacyHistogram, histogramMap(secondItem), |
92 histogramTester.expectBucketCount(legacyHistogram, pageVisitBucket, 2); | 105 1); |
93 histogramTester.expectTotalCount(legacyHistogram, 5); | 106 histogramTester.expectBucketCount(legacyHistogram, pageVisitBucket, 2); |
| 107 histogramTester.expectTotalCount(legacyHistogram, 5); |
| 108 } |
94 | 109 |
95 for (size_t i = 0; i < unaffectedHistograms.size(); ++i) { | 110 for (size_t i = 0; i < unaffectedHistograms.size(); ++i) { |
96 histogramTester.expectTotalCount(unaffectedHistograms[i], 0); | 111 histogramTester.expectTotalCount(unaffectedHistograms[i], 0); |
97 } | 112 } |
98 } | 113 } |
99 | 114 |
100 // Failing on Android: crbug.com/667913 | 115 // Failing on Android: crbug.com/667913 |
101 #if OS(ANDROID) | 116 #if OS(ANDROID) |
102 #define MAYBE_RecordingFeatures DISABLED_RecordingFeatures | 117 #define MAYBE_RecordingFeatures DISABLED_RecordingFeatures |
103 #else | 118 #else |
104 #define MAYBE_RecordingFeatures RecordingFeatures | 119 #define MAYBE_RecordingFeatures RecordingFeatures |
105 #endif | 120 #endif |
106 TEST(UseCounterTest, MAYBE_RecordingFeatures) { | 121 TEST(UseCounterTest, MAYBE_RecordingFeatures) { |
107 UseCounter useCounter; | 122 UseCounter useCounter; |
108 histogramBasicTest<UseCounter::Feature>( | 123 histogramBasicTest<UseCounter::Feature>( |
109 kFeaturesHistogramName, kLegacyFeaturesHistogramName, | 124 kFeaturesHistogramName, kLegacyFeaturesHistogramName, |
110 {kSVGFeaturesHistogramName, kSVGCSSHistogramName}, UseCounter::Fetch, | 125 {kSVGFeaturesHistogramName, kSVGCSSHistogramName, |
111 UseCounter::FetchBodyStream, | 126 kSVGAnimatedCSSHistogramName}, |
| 127 UseCounter::Fetch, UseCounter::FetchBodyStream, |
112 [&](UseCounter::Feature feature) -> bool { | 128 [&](UseCounter::Feature feature) -> bool { |
113 return useCounter.hasRecordedMeasurement(feature); | 129 return useCounter.hasRecordedMeasurement(feature); |
114 }, | 130 }, |
115 [&](UseCounter::Feature feature) { | 131 [&](UseCounter::Feature feature) { |
116 useCounter.recordMeasurement(feature); | 132 useCounter.recordMeasurement(feature); |
117 }, | 133 }, |
118 [](UseCounter::Feature feature) -> int { return feature; }, | 134 [](UseCounter::Feature feature) -> int { return feature; }, |
119 [&](KURL kurl) { useCounter.didCommitLoad(kurl); }, | 135 [&](KURL kurl) { useCounter.didCommitLoad(kurl); }, |
120 "https://dummysite.com/", UseCounter::PageVisits); | 136 "https://dummysite.com/", UseCounter::PageVisits); |
121 } | 137 } |
122 | 138 |
123 TEST(UseCounterTest, RecordingCSSProperties) { | 139 TEST(UseCounterTest, RecordingCSSProperties) { |
124 UseCounter useCounter; | 140 UseCounter useCounter; |
125 histogramBasicTest<CSSPropertyID>( | 141 histogramBasicTest<CSSPropertyID>( |
126 kCSSHistogramName, kLegacyCSSHistogramName, | 142 kCSSHistogramName, kLegacyCSSHistogramName, |
127 {kSVGFeaturesHistogramName, kSVGCSSHistogramName}, CSSPropertyFont, | 143 {kSVGFeaturesHistogramName, kSVGCSSHistogramName, |
128 CSSPropertyZoom, | 144 kSVGAnimatedCSSHistogramName}, |
| 145 CSSPropertyFont, CSSPropertyZoom, |
129 [&](CSSPropertyID property) -> bool { | 146 [&](CSSPropertyID property) -> bool { |
130 return useCounter.isCounted(property); | 147 return useCounter.isCounted(property); |
131 }, | 148 }, |
132 [&](CSSPropertyID property) { | 149 [&](CSSPropertyID property) { |
133 useCounter.count(HTMLStandardMode, property); | 150 useCounter.count(HTMLStandardMode, property); |
134 }, | 151 }, |
135 [](CSSPropertyID property) -> int { | 152 [](CSSPropertyID property) -> int { |
136 return UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property); | 153 return UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property); |
137 }, | 154 }, |
138 [&](KURL kurl) { useCounter.didCommitLoad(kurl); }, | 155 [&](KURL kurl) { useCounter.didCommitLoad(kurl); }, |
139 "https://dummysite.com/", 1 /* page visit bucket */); | 156 "https://dummysite.com/", 1 /* page visit bucket */); |
140 } | 157 } |
141 | 158 |
| 159 TEST(UseCounterTest, RecordingAnimatedCSSProperties) { |
| 160 UseCounter useCounter; |
| 161 histogramBasicTest<CSSPropertyID>( |
| 162 kAnimatedCSSHistogramName, "", |
| 163 {kSVGCSSHistogramName, kSVGAnimatedCSSHistogramName}, CSSPropertyOpacity, |
| 164 CSSPropertyVariable, |
| 165 [&](CSSPropertyID property) -> bool { |
| 166 return useCounter.isCountedAnimatedCSS(property); |
| 167 }, |
| 168 [&](CSSPropertyID property) { useCounter.countAnimatedCSS(property); }, |
| 169 [](CSSPropertyID property) -> int { |
| 170 return UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property); |
| 171 }, |
| 172 [&](KURL kurl) { useCounter.didCommitLoad(kurl); }, |
| 173 "https://dummysite.com/", 1 /* page visit bucket */); |
| 174 } |
| 175 |
142 // Failing on Android: crbug.com/667913 | 176 // Failing on Android: crbug.com/667913 |
143 #if OS(ANDROID) | 177 #if OS(ANDROID) |
144 #define MAYBE_SVGImageContextFeatures DISABLED_SVGImageContextFeatures | 178 #define MAYBE_SVGImageContextFeatures DISABLED_SVGImageContextFeatures |
145 #else | 179 #else |
146 #define MAYBE_SVGImageContextFeatures SVGImageContextFeatures | 180 #define MAYBE_SVGImageContextFeatures SVGImageContextFeatures |
147 #endif | 181 #endif |
148 TEST(UseCounterTest, MAYBE_SVGImageContextFeatures) { | 182 TEST(UseCounterTest, MAYBE_SVGImageContextFeatures) { |
149 UseCounter useCounter(UseCounter::SVGImageContext); | 183 UseCounter useCounter(UseCounter::SVGImageContext); |
150 histogramBasicTest<UseCounter::Feature>( | 184 histogramBasicTest<UseCounter::Feature>( |
151 kSVGFeaturesHistogramName, kLegacyFeaturesHistogramName, | 185 kSVGFeaturesHistogramName, kLegacyFeaturesHistogramName, |
152 {kFeaturesHistogramName, kCSSHistogramName}, | 186 {kFeaturesHistogramName, kCSSHistogramName, kAnimatedCSSHistogramName}, |
153 UseCounter::SVGSMILAdditiveAnimation, | 187 UseCounter::SVGSMILAdditiveAnimation, |
154 UseCounter::SVGSMILAnimationElementTiming, | 188 UseCounter::SVGSMILAnimationElementTiming, |
155 [&](UseCounter::Feature feature) -> bool { | 189 [&](UseCounter::Feature feature) -> bool { |
156 return useCounter.hasRecordedMeasurement(feature); | 190 return useCounter.hasRecordedMeasurement(feature); |
157 }, | 191 }, |
158 [&](UseCounter::Feature feature) { | 192 [&](UseCounter::Feature feature) { |
159 useCounter.recordMeasurement(feature); | 193 useCounter.recordMeasurement(feature); |
160 }, | 194 }, |
161 [](UseCounter::Feature feature) -> int { return feature; }, | 195 [](UseCounter::Feature feature) -> int { return feature; }, |
162 [&](KURL kurl) { useCounter.didCommitLoad(kurl); }, "about:blank", | 196 [&](KURL kurl) { useCounter.didCommitLoad(kurl); }, "about:blank", |
163 // In practice SVGs always appear to be loaded with an about:blank URL | 197 // In practice SVGs always appear to be loaded with an about:blank URL |
164 UseCounter::PageVisits); | 198 UseCounter::PageVisits); |
165 } | 199 } |
166 | 200 |
167 TEST(UseCounterTest, SVGImageContextCSSProperties) { | 201 TEST(UseCounterTest, SVGImageContextCSSProperties) { |
168 UseCounter useCounter(UseCounter::SVGImageContext); | 202 UseCounter useCounter(UseCounter::SVGImageContext); |
169 histogramBasicTest<CSSPropertyID>( | 203 histogramBasicTest<CSSPropertyID>( |
170 kSVGCSSHistogramName, kLegacyCSSHistogramName, | 204 kSVGCSSHistogramName, kLegacyCSSHistogramName, |
171 {kFeaturesHistogramName, kCSSHistogramName}, CSSPropertyFont, | 205 {kFeaturesHistogramName, kCSSHistogramName, kAnimatedCSSHistogramName}, |
172 CSSPropertyZoom, | 206 CSSPropertyFont, CSSPropertyZoom, |
173 [&](CSSPropertyID property) -> bool { | 207 [&](CSSPropertyID property) -> bool { |
174 return useCounter.isCounted(property); | 208 return useCounter.isCounted(property); |
175 }, | 209 }, |
176 [&](CSSPropertyID property) { | 210 [&](CSSPropertyID property) { |
177 useCounter.count(HTMLStandardMode, property); | 211 useCounter.count(HTMLStandardMode, property); |
178 }, | 212 }, |
179 [](CSSPropertyID property) -> int { | 213 [](CSSPropertyID property) -> int { |
180 return UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property); | 214 return UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property); |
181 }, | 215 }, |
182 [&](KURL kurl) { useCounter.didCommitLoad(kurl); }, "about:blank", | 216 [&](KURL kurl) { useCounter.didCommitLoad(kurl); }, "about:blank", |
183 // In practice SVGs always appear to be loaded with an about:blank URL | 217 // In practice SVGs always appear to be loaded with an about:blank URL |
184 1 /* page visit bucket */); | 218 1 /* page visit bucket */); |
185 } | 219 } |
186 | 220 |
| 221 TEST(UseCounterTest, SVGImageContextAnimatedCSSProperties) { |
| 222 UseCounter useCounter(UseCounter::SVGImageContext); |
| 223 histogramBasicTest<CSSPropertyID>( |
| 224 kSVGAnimatedCSSHistogramName, "", |
| 225 {kCSSHistogramName, kAnimatedCSSHistogramName}, CSSPropertyOpacity, |
| 226 CSSPropertyVariable, |
| 227 [&](CSSPropertyID property) -> bool { |
| 228 return useCounter.isCountedAnimatedCSS(property); |
| 229 }, |
| 230 [&](CSSPropertyID property) { useCounter.countAnimatedCSS(property); }, |
| 231 [](CSSPropertyID property) -> int { |
| 232 return UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property); |
| 233 }, |
| 234 [&](KURL kurl) { useCounter.didCommitLoad(kurl); }, "about:blank", |
| 235 // In practice SVGs always appear to be loaded with an about:blank URL |
| 236 1 /* page visit bucket */); |
| 237 } |
| 238 |
187 // Failing on Android: crbug.com/667913 | 239 // Failing on Android: crbug.com/667913 |
188 #if OS(ANDROID) | 240 #if OS(ANDROID) |
189 #define MAYBE_InspectorDisablesMeasurement DISABLED_InspectorDisablesMeasurement | 241 #define MAYBE_InspectorDisablesMeasurement DISABLED_InspectorDisablesMeasurement |
190 #else | 242 #else |
191 #define MAYBE_InspectorDisablesMeasurement InspectorDisablesMeasurement | 243 #define MAYBE_InspectorDisablesMeasurement InspectorDisablesMeasurement |
192 #endif | 244 #endif |
193 TEST(UseCounterTest, MAYBE_InspectorDisablesMeasurement) { | 245 TEST(UseCounterTest, MAYBE_InspectorDisablesMeasurement) { |
194 UseCounter useCounter; | 246 UseCounter useCounter; |
195 HistogramTester histogramTester; | 247 HistogramTester histogramTester; |
196 | 248 |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 | 442 |
391 m_deprecation.unmuteForInspector(); | 443 m_deprecation.unmuteForInspector(); |
392 Deprecation::warnOnDeprecatedProperties(frame(), property); | 444 Deprecation::warnOnDeprecatedProperties(frame(), property); |
393 // TODO: use the actually deprecated property to get a deprecation message. | 445 // TODO: use the actually deprecated property to get a deprecation message. |
394 EXPECT_FALSE(m_deprecation.isSuppressed(property)); | 446 EXPECT_FALSE(m_deprecation.isSuppressed(property)); |
395 Deprecation::countDeprecation(frame(), feature); | 447 Deprecation::countDeprecation(frame(), feature); |
396 EXPECT_TRUE(m_useCounter.hasRecordedMeasurement(feature)); | 448 EXPECT_TRUE(m_useCounter.hasRecordedMeasurement(feature)); |
397 } | 449 } |
398 | 450 |
399 } // namespace blink | 451 } // namespace blink |
OLD | NEW |