platform_collector_unittest.cc 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. // Copyright 2021 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 "services/device/compute_pressure/platform_collector.h"
  5. #include <cstddef>
  6. #include <memory>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/check_op.h"
  10. #include "base/run_loop.h"
  11. #include "base/sequence_checker.h"
  12. #include "base/test/bind.h"
  13. #include "base/test/task_environment.h"
  14. #include "base/thread_annotations.h"
  15. #include "base/threading/platform_thread.h"
  16. #include "base/threading/scoped_blocking_call.h"
  17. #include "build/build_config.h"
  18. #include "services/device/compute_pressure/cpu_probe.h"
  19. #include "services/device/compute_pressure/pressure_sample.h"
  20. #include "services/device/compute_pressure/pressure_test_support.h"
  21. #include "testing/gmock/include/gmock/gmock.h"
  22. #include "testing/gtest/include/gtest/gtest.h"
  23. namespace device {
  24. class PlatformCollectorTest : public testing::Test {
  25. public:
  26. PlatformCollectorTest()
  27. : collector_(std::make_unique<PlatformCollector>(
  28. std::make_unique<FakeCpuProbe>(),
  29. base::Milliseconds(1),
  30. base::BindRepeating(&PlatformCollectorTest::CollectorCallback,
  31. base::Unretained(this)))) {}
  32. void WaitForUpdate() {
  33. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  34. base::RunLoop run_loop;
  35. SetNextUpdateCallback(run_loop.QuitClosure());
  36. run_loop.Run();
  37. }
  38. // Only valid if `collector_` uses a FakeCpuProbe. This is guaranteed if
  39. // `collector_` is not replaced during the test.
  40. FakeCpuProbe& cpu_probe() {
  41. auto* cpu_probe =
  42. static_cast<FakeCpuProbe*>(collector_->cpu_probe_for_testing());
  43. DCHECK(cpu_probe);
  44. return *cpu_probe;
  45. }
  46. void CollectorCallback(PressureSample sample) {
  47. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  48. samples_.push_back(sample);
  49. if (update_callback_) {
  50. std::move(update_callback_).Run();
  51. update_callback_.Reset();
  52. }
  53. }
  54. protected:
  55. SEQUENCE_CHECKER(sequence_checker_);
  56. base::test::TaskEnvironment task_environment_;
  57. // This member is a std::unique_ptr instead of a plain PlatformCollector
  58. // so it can be replaced inside tests.
  59. std::unique_ptr<PlatformCollector> collector_;
  60. // The samples reported by the callback.
  61. std::vector<PressureSample> samples_ GUARDED_BY_CONTEXT(sequence_checker_);
  62. private:
  63. void SetNextUpdateCallback(base::OnceClosure callback) {
  64. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  65. DCHECK(!update_callback_)
  66. << __func__ << " already called before update received";
  67. update_callback_ = std::move(callback);
  68. }
  69. // Used to implement WaitForUpdate().
  70. base::OnceClosure update_callback_ GUARDED_BY_CONTEXT(sequence_checker_);
  71. };
  72. TEST_F(PlatformCollectorTest, EnsureStarted) {
  73. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  74. collector_->EnsureStarted();
  75. WaitForUpdate();
  76. EXPECT_GE(samples_.size(), 1u);
  77. EXPECT_THAT(samples_, testing::Contains(PressureSample{0.42}));
  78. }
  79. namespace {
  80. // TestDouble for CpuProbe that produces a different value after every Update().
  81. class StreamingCpuProbe : public CpuProbe {
  82. public:
  83. explicit StreamingCpuProbe(std::vector<PressureSample> samples,
  84. base::OnceClosure callback)
  85. : samples_(std::move(samples)), callback_(std::move(callback)) {
  86. DETACH_FROM_SEQUENCE(sequence_checker_);
  87. DCHECK_GT(samples_.size(), 0u);
  88. }
  89. ~StreamingCpuProbe() override {
  90. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  91. }
  92. // CpuProbe implementation.
  93. void Update() override {
  94. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  95. ++sample_index_;
  96. base::ScopedBlockingCall scoped_blocking_call(
  97. FROM_HERE, base::BlockingType::MAY_BLOCK);
  98. }
  99. PressureSample LastSample() override {
  100. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  101. if (sample_index_ < samples_.size()) {
  102. return samples_.at(sample_index_);
  103. }
  104. if (!callback_.is_null()) {
  105. std::move(callback_).Run();
  106. }
  107. return samples_.back();
  108. }
  109. private:
  110. SEQUENCE_CHECKER(sequence_checker_);
  111. std::vector<PressureSample> samples_ GUARDED_BY_CONTEXT(sequence_checker_);
  112. size_t sample_index_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
  113. // This closure is called on a LastSample call after expected number of
  114. // samples has been taken by PressureSampler.
  115. base::OnceClosure callback_;
  116. };
  117. } // namespace
  118. TEST_F(PlatformCollectorTest, EnsureStarted_SkipsFirstSample) {
  119. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  120. std::vector<PressureSample> samples = {
  121. // Value right after construction.
  122. PressureSample{0.1},
  123. // Value after first Update(), should be discarded.
  124. PressureSample{0.2},
  125. // Value after second Update(), should be reported.
  126. PressureSample{0.4},
  127. };
  128. base::RunLoop run_loop;
  129. collector_ = std::make_unique<PlatformCollector>(
  130. std::make_unique<StreamingCpuProbe>(samples, run_loop.QuitClosure()),
  131. base::Milliseconds(1),
  132. base::BindRepeating(&PlatformCollectorTest::CollectorCallback,
  133. base::Unretained(this)));
  134. collector_->EnsureStarted();
  135. run_loop.Run();
  136. EXPECT_GE(samples_.size(), 1u);
  137. EXPECT_THAT(samples_, testing::Not(testing::Contains(PressureSample{0.2})));
  138. EXPECT_THAT(samples_, testing::Contains(PressureSample{0.4}));
  139. }
  140. // TODO(crbug.com/1271419): Flaky.
  141. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_WIN)
  142. #define MAYBE_Stop_Delayed_EnsureStarted_Immediate \
  143. DISABLED_Stop_Delayed_EnsureStarted_Immediate
  144. #else
  145. #define MAYBE_Stop_Delayed_EnsureStarted_Immediate \
  146. Stop_Delayed_EnsureStarted_Immediate
  147. #endif
  148. TEST_F(PlatformCollectorTest, MAYBE_Stop_Delayed_EnsureStarted_Immediate) {
  149. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  150. collector_->EnsureStarted();
  151. WaitForUpdate();
  152. collector_->Stop();
  153. samples_.clear();
  154. cpu_probe().SetLastSample(PressureSample{0.25});
  155. collector_->EnsureStarted();
  156. WaitForUpdate();
  157. EXPECT_GE(samples_.size(), 1u);
  158. EXPECT_THAT(samples_, testing::Contains(PressureSample{0.25}));
  159. }
  160. // TODO(crbug.com/1271419): Flaky.
  161. #if BUILDFLAG(IS_WIN)
  162. #define MAYBE_Stop_Delayed_EnsureStarted_Delayed \
  163. DISABLED_Stop_Delayed_EnsureStarted_Delayed
  164. #else
  165. #define MAYBE_Stop_Delayed_EnsureStarted_Delayed \
  166. Stop_Delayed_EnsureStarted_Delayed
  167. #endif
  168. TEST_F(PlatformCollectorTest, MAYBE_Stop_Delayed_EnsureStarted_Delayed) {
  169. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  170. collector_->EnsureStarted();
  171. WaitForUpdate();
  172. collector_->Stop();
  173. samples_.clear();
  174. cpu_probe().SetLastSample(PressureSample{0.25});
  175. // 10ms should be long enough to ensure that all the sampling tasks are done.
  176. base::PlatformThread::Sleep(base::Milliseconds(10));
  177. collector_->EnsureStarted();
  178. WaitForUpdate();
  179. EXPECT_GE(samples_.size(), 1u);
  180. EXPECT_THAT(samples_, testing::Contains(PressureSample{0.25}));
  181. }
  182. TEST_F(PlatformCollectorTest, Stop_Immediate_EnsureStarted_Immediate) {
  183. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  184. collector_->EnsureStarted();
  185. collector_->Stop();
  186. samples_.clear();
  187. cpu_probe().SetLastSample(PressureSample{0.25});
  188. collector_->EnsureStarted();
  189. WaitForUpdate();
  190. EXPECT_GE(samples_.size(), 1u);
  191. EXPECT_THAT(samples_, testing::Contains(PressureSample{0.25}));
  192. }
  193. TEST_F(PlatformCollectorTest, Stop_Immediate_EnsureStarted_Delayed) {
  194. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  195. collector_->EnsureStarted();
  196. collector_->Stop();
  197. samples_.clear();
  198. cpu_probe().SetLastSample(PressureSample{0.25});
  199. // 10ms should be long enough to ensure that all the sampling tasks are done.
  200. base::PlatformThread::Sleep(base::Milliseconds(10));
  201. collector_->EnsureStarted();
  202. WaitForUpdate();
  203. EXPECT_GE(samples_.size(), 1u);
  204. EXPECT_THAT(samples_, testing::Contains(PressureSample{0.25}));
  205. }
  206. } // namespace device