call_stack_profile_metrics_provider_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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
  3. // found in the LICENSE file.
  4. #include "components/metrics/call_stack_profile_metrics_provider.h"
  5. #include <string>
  6. #include <utility>
  7. #include "base/test/scoped_feature_list.h"
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
  10. namespace metrics {
  11. // This test fixture enables the feature that
  12. // CallStackProfileMetricsProvider depends on to report a profile.
  13. class CallStackProfileMetricsProviderTest : public testing::Test {
  14. public:
  15. CallStackProfileMetricsProviderTest() {
  16. TestState::ResetStaticStateForTesting();
  17. scoped_feature_list_.InitAndEnableFeature(
  18. TestState::kSamplingProfilerReporting);
  19. }
  20. CallStackProfileMetricsProviderTest(
  21. const CallStackProfileMetricsProviderTest&) = delete;
  22. CallStackProfileMetricsProviderTest& operator=(
  23. const CallStackProfileMetricsProviderTest&) = delete;
  24. protected:
  25. // Exposes the feature from the CallStackProfileMetricsProvider.
  26. class TestState : public CallStackProfileMetricsProvider {
  27. public:
  28. using CallStackProfileMetricsProvider::kSamplingProfilerReporting;
  29. using CallStackProfileMetricsProvider::ResetStaticStateForTesting;
  30. };
  31. private:
  32. base::test::ScopedFeatureList scoped_feature_list_;
  33. };
  34. // Checks that the unserialized pending profile is encoded in the session data.
  35. TEST_F(CallStackProfileMetricsProviderTest,
  36. ProvideCurrentSessionDataUnserialized) {
  37. CallStackProfileMetricsProvider provider;
  38. provider.OnRecordingEnabled();
  39. SampledProfile profile;
  40. profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
  41. CallStackProfileMetricsProvider::ReceiveProfile(base::TimeTicks::Now(),
  42. profile);
  43. ChromeUserMetricsExtension uma_proto;
  44. provider.ProvideCurrentSessionData(&uma_proto);
  45. ASSERT_EQ(1, uma_proto.sampled_profile().size());
  46. EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION,
  47. uma_proto.sampled_profile(0).trigger_event());
  48. }
  49. // Checks that the serialized pending profile is encoded in the session data.
  50. TEST_F(CallStackProfileMetricsProviderTest,
  51. ProvideCurrentSessionDataSerialized) {
  52. CallStackProfileMetricsProvider provider;
  53. provider.OnRecordingEnabled();
  54. std::string contents;
  55. {
  56. SampledProfile profile;
  57. profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
  58. profile.SerializeToString(&contents);
  59. }
  60. CallStackProfileMetricsProvider::ReceiveSerializedProfile(
  61. base::TimeTicks::Now(), /*is_heap_profile=*/false, std::move(contents));
  62. ChromeUserMetricsExtension uma_proto;
  63. provider.ProvideCurrentSessionData(&uma_proto);
  64. ASSERT_EQ(1, uma_proto.sampled_profile().size());
  65. EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION,
  66. uma_proto.sampled_profile(0).trigger_event());
  67. }
  68. // Checks that both the unserialized and serialized pending profiles are
  69. // encoded in the session data.
  70. TEST_F(CallStackProfileMetricsProviderTest,
  71. ProvideCurrentSessionDataUnserializedAndSerialized) {
  72. CallStackProfileMetricsProvider provider;
  73. provider.OnRecordingEnabled();
  74. // Receive an unserialized profile.
  75. SampledProfile profile;
  76. profile.set_trigger_event(SampledProfile::PROCESS_STARTUP);
  77. CallStackProfileMetricsProvider::ReceiveProfile(base::TimeTicks::Now(),
  78. std::move(profile));
  79. // Receive a serialized profile.
  80. std::string contents;
  81. {
  82. SampledProfile serialized_profile;
  83. serialized_profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
  84. serialized_profile.SerializeToString(&contents);
  85. }
  86. CallStackProfileMetricsProvider::ReceiveSerializedProfile(
  87. base::TimeTicks::Now(), /*is_heap_profile=*/false, std::move(contents));
  88. ChromeUserMetricsExtension uma_proto;
  89. provider.ProvideCurrentSessionData(&uma_proto);
  90. ASSERT_EQ(2, uma_proto.sampled_profile().size());
  91. EXPECT_EQ(SampledProfile::PROCESS_STARTUP,
  92. uma_proto.sampled_profile(0).trigger_event());
  93. EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION,
  94. uma_proto.sampled_profile(1).trigger_event());
  95. }
  96. // Checks that the pending profiles above the total cap are dropped therefore
  97. // not encoded in the session data.
  98. TEST_F(CallStackProfileMetricsProviderTest,
  99. ProvideCurrentSessionDataExceedTotalCap) {
  100. // The value must be consistent with that in
  101. // call_stack_profile_metrics_provider.cc so that this test is meaningful.
  102. const int kMaxPendingProfiles = 1250;
  103. CallStackProfileMetricsProvider provider;
  104. provider.OnRecordingEnabled();
  105. // Receive (kMaxPendingProfiles + 1) profiles.
  106. for (int i = 0; i < kMaxPendingProfiles + 1; ++i) {
  107. SampledProfile profile;
  108. profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
  109. CallStackProfileMetricsProvider::ReceiveProfile(base::TimeTicks::Now(),
  110. std::move(profile));
  111. }
  112. ChromeUserMetricsExtension uma_proto;
  113. provider.ProvideCurrentSessionData(&uma_proto);
  114. // Only kMaxPendingProfiles profiles are encoded, with the additional one
  115. // dropped.
  116. ASSERT_EQ(kMaxPendingProfiles, uma_proto.sampled_profile().size());
  117. for (int i = 0; i < kMaxPendingProfiles; ++i) {
  118. EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION,
  119. uma_proto.sampled_profile(i).trigger_event());
  120. }
  121. }
  122. // Checks that the pending profile is provided to ProvideCurrentSessionData
  123. // when collected before CallStackProfileMetricsProvider is instantiated.
  124. TEST_F(CallStackProfileMetricsProviderTest,
  125. ProfileProvidedWhenCollectedBeforeInstantiation) {
  126. CallStackProfileMetricsProvider::ReceiveProfile(base::TimeTicks::Now(),
  127. SampledProfile());
  128. CallStackProfileMetricsProvider provider;
  129. provider.OnRecordingEnabled();
  130. ChromeUserMetricsExtension uma_proto;
  131. provider.ProvideCurrentSessionData(&uma_proto);
  132. EXPECT_EQ(1, uma_proto.sampled_profile_size());
  133. }
  134. // Checks that the pending profile is not provided to ProvideCurrentSessionData
  135. // while recording is disabled.
  136. TEST_F(CallStackProfileMetricsProviderTest, ProfileNotProvidedWhileDisabled) {
  137. CallStackProfileMetricsProvider provider;
  138. provider.OnRecordingDisabled();
  139. CallStackProfileMetricsProvider::ReceiveProfile(base::TimeTicks::Now(),
  140. SampledProfile());
  141. ChromeUserMetricsExtension uma_proto;
  142. provider.ProvideCurrentSessionData(&uma_proto);
  143. EXPECT_EQ(0, uma_proto.sampled_profile_size());
  144. }
  145. // Checks that the pending profile is not provided to ProvideCurrentSessionData
  146. // if recording is disabled while profiling.
  147. TEST_F(CallStackProfileMetricsProviderTest,
  148. ProfileNotProvidedAfterChangeToDisabled) {
  149. CallStackProfileMetricsProvider provider;
  150. provider.OnRecordingEnabled();
  151. base::TimeTicks profile_start_time = base::TimeTicks::Now();
  152. provider.OnRecordingDisabled();
  153. CallStackProfileMetricsProvider::ReceiveProfile(profile_start_time,
  154. SampledProfile());
  155. ChromeUserMetricsExtension uma_proto;
  156. provider.ProvideCurrentSessionData(&uma_proto);
  157. EXPECT_EQ(0, uma_proto.sampled_profile_size());
  158. }
  159. // Checks that the pending profile is not provided to ProvideCurrentSessionData
  160. // if recording is enabled, but then disabled and reenabled while profiling.
  161. TEST_F(CallStackProfileMetricsProviderTest,
  162. ProfileNotProvidedAfterChangeToDisabledThenEnabled) {
  163. CallStackProfileMetricsProvider provider;
  164. provider.OnRecordingEnabled();
  165. base::TimeTicks profile_start_time = base::TimeTicks::Now();
  166. provider.OnRecordingDisabled();
  167. provider.OnRecordingEnabled();
  168. CallStackProfileMetricsProvider::ReceiveProfile(profile_start_time,
  169. SampledProfile());
  170. ChromeUserMetricsExtension uma_proto;
  171. provider.ProvideCurrentSessionData(&uma_proto);
  172. EXPECT_EQ(0, uma_proto.sampled_profile_size());
  173. }
  174. // Checks that the pending profile is provided to ProvideCurrentSessionData
  175. // if recording is disabled, but then enabled while profiling.
  176. TEST_F(CallStackProfileMetricsProviderTest,
  177. ProfileNotProvidedAfterChangeFromDisabled) {
  178. CallStackProfileMetricsProvider provider;
  179. provider.OnRecordingDisabled();
  180. base::TimeTicks profile_start_time = base::TimeTicks::Now();
  181. provider.OnRecordingEnabled();
  182. CallStackProfileMetricsProvider::ReceiveProfile(profile_start_time,
  183. SampledProfile());
  184. ChromeUserMetricsExtension uma_proto;
  185. provider.ProvideCurrentSessionData(&uma_proto);
  186. EXPECT_EQ(0, uma_proto.sampled_profile_size());
  187. }
  188. // Checks that a heap profile is not reported when recording is disabled.
  189. TEST_F(CallStackProfileMetricsProviderTest,
  190. HeapProfileNotProvidedWhenDisabled) {
  191. CallStackProfileMetricsProvider provider;
  192. provider.OnRecordingDisabled();
  193. base::TimeTicks profile_start_time = base::TimeTicks::Now();
  194. // Unserialized profile.
  195. SampledProfile profile;
  196. profile.set_trigger_event(SampledProfile::PERIODIC_HEAP_COLLECTION);
  197. CallStackProfileMetricsProvider::ReceiveProfile(profile_start_time, profile);
  198. // Serialized profile.
  199. std::string contents;
  200. profile.SerializeToString(&contents);
  201. CallStackProfileMetricsProvider::ReceiveSerializedProfile(
  202. profile_start_time, /*is_heap_profile=*/true, std::move(contents));
  203. ChromeUserMetricsExtension uma_proto;
  204. provider.ProvideCurrentSessionData(&uma_proto);
  205. EXPECT_EQ(0, uma_proto.sampled_profile_size());
  206. }
  207. // Checks that a heap profile is provided to ProvideCurrentSessionData
  208. // if recording is enabled.
  209. TEST_F(CallStackProfileMetricsProviderTest, HeapProfileProvidedWhenEnabled) {
  210. CallStackProfileMetricsProvider provider;
  211. provider.OnRecordingEnabled();
  212. base::TimeTicks profile_start_time = base::TimeTicks::Now();
  213. // Unserialized profile.
  214. SampledProfile profile;
  215. profile.set_trigger_event(SampledProfile::PERIODIC_HEAP_COLLECTION);
  216. CallStackProfileMetricsProvider::ReceiveProfile(profile_start_time, profile);
  217. // Serialized profile.
  218. std::string contents;
  219. profile.SerializeToString(&contents);
  220. CallStackProfileMetricsProvider::ReceiveSerializedProfile(
  221. profile_start_time, /*is_heap_profile=*/true, std::move(contents));
  222. ChromeUserMetricsExtension uma_proto;
  223. provider.ProvideCurrentSessionData(&uma_proto);
  224. EXPECT_EQ(2, uma_proto.sampled_profile_size());
  225. }
  226. // Checks that heap profiles but not CPU profiles are reported when sampling CPU
  227. // Finch is disabled.
  228. TEST_F(CallStackProfileMetricsProviderTest, CpuProfileNotProvidedWithoutFinch) {
  229. base::test::ScopedFeatureList scoped_feature_list;
  230. scoped_feature_list.InitAndDisableFeature(
  231. TestState::kSamplingProfilerReporting);
  232. CallStackProfileMetricsProvider provider;
  233. base::TimeTicks profile_start_time = base::TimeTicks::Now();
  234. // Unserialized profiles.
  235. SampledProfile profile;
  236. profile.set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
  237. CallStackProfileMetricsProvider::ReceiveProfile(profile_start_time, profile);
  238. SampledProfile heap_profile;
  239. heap_profile.set_trigger_event(SampledProfile::PERIODIC_HEAP_COLLECTION);
  240. CallStackProfileMetricsProvider::ReceiveProfile(profile_start_time,
  241. heap_profile);
  242. // Serialized profiles.
  243. std::string contents;
  244. profile.SerializeToString(&contents);
  245. CallStackProfileMetricsProvider::ReceiveSerializedProfile(
  246. profile_start_time, /*is_heap_profile=*/false, std::move(contents));
  247. std::string heap_contents;
  248. heap_profile.SerializeToString(&heap_contents);
  249. CallStackProfileMetricsProvider::ReceiveSerializedProfile(
  250. profile_start_time, /*is_heap_profile=*/true, std::move(heap_contents));
  251. ChromeUserMetricsExtension uma_proto;
  252. provider.ProvideCurrentSessionData(&uma_proto);
  253. ASSERT_EQ(2, uma_proto.sampled_profile_size());
  254. EXPECT_EQ(SampledProfile::PERIODIC_HEAP_COLLECTION,
  255. uma_proto.sampled_profile(0).trigger_event());
  256. EXPECT_EQ(SampledProfile::PERIODIC_HEAP_COLLECTION,
  257. uma_proto.sampled_profile(1).trigger_event());
  258. }
  259. } // namespace metrics