123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "services/device/compute_pressure/platform_collector.h"
- #include <cstddef>
- #include <memory>
- #include <utility>
- #include "base/bind.h"
- #include "base/check_op.h"
- #include "base/run_loop.h"
- #include "base/sequence_checker.h"
- #include "base/test/bind.h"
- #include "base/test/task_environment.h"
- #include "base/thread_annotations.h"
- #include "base/threading/platform_thread.h"
- #include "base/threading/scoped_blocking_call.h"
- #include "build/build_config.h"
- #include "services/device/compute_pressure/cpu_probe.h"
- #include "services/device/compute_pressure/pressure_sample.h"
- #include "services/device/compute_pressure/pressure_test_support.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace device {
- class PlatformCollectorTest : public testing::Test {
- public:
- PlatformCollectorTest()
- : collector_(std::make_unique<PlatformCollector>(
- std::make_unique<FakeCpuProbe>(),
- base::Milliseconds(1),
- base::BindRepeating(&PlatformCollectorTest::CollectorCallback,
- base::Unretained(this)))) {}
- void WaitForUpdate() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- base::RunLoop run_loop;
- SetNextUpdateCallback(run_loop.QuitClosure());
- run_loop.Run();
- }
- // Only valid if `collector_` uses a FakeCpuProbe. This is guaranteed if
- // `collector_` is not replaced during the test.
- FakeCpuProbe& cpu_probe() {
- auto* cpu_probe =
- static_cast<FakeCpuProbe*>(collector_->cpu_probe_for_testing());
- DCHECK(cpu_probe);
- return *cpu_probe;
- }
- void CollectorCallback(PressureSample sample) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- samples_.push_back(sample);
- if (update_callback_) {
- std::move(update_callback_).Run();
- update_callback_.Reset();
- }
- }
- protected:
- SEQUENCE_CHECKER(sequence_checker_);
- base::test::TaskEnvironment task_environment_;
- // This member is a std::unique_ptr instead of a plain PlatformCollector
- // so it can be replaced inside tests.
- std::unique_ptr<PlatformCollector> collector_;
- // The samples reported by the callback.
- std::vector<PressureSample> samples_ GUARDED_BY_CONTEXT(sequence_checker_);
- private:
- void SetNextUpdateCallback(base::OnceClosure callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(!update_callback_)
- << __func__ << " already called before update received";
- update_callback_ = std::move(callback);
- }
- // Used to implement WaitForUpdate().
- base::OnceClosure update_callback_ GUARDED_BY_CONTEXT(sequence_checker_);
- };
- TEST_F(PlatformCollectorTest, EnsureStarted) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- collector_->EnsureStarted();
- WaitForUpdate();
- EXPECT_GE(samples_.size(), 1u);
- EXPECT_THAT(samples_, testing::Contains(PressureSample{0.42}));
- }
- namespace {
- // TestDouble for CpuProbe that produces a different value after every Update().
- class StreamingCpuProbe : public CpuProbe {
- public:
- explicit StreamingCpuProbe(std::vector<PressureSample> samples,
- base::OnceClosure callback)
- : samples_(std::move(samples)), callback_(std::move(callback)) {
- DETACH_FROM_SEQUENCE(sequence_checker_);
- DCHECK_GT(samples_.size(), 0u);
- }
- ~StreamingCpuProbe() override {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- }
- // CpuProbe implementation.
- void Update() override {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- ++sample_index_;
- base::ScopedBlockingCall scoped_blocking_call(
- FROM_HERE, base::BlockingType::MAY_BLOCK);
- }
- PressureSample LastSample() override {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (sample_index_ < samples_.size()) {
- return samples_.at(sample_index_);
- }
- if (!callback_.is_null()) {
- std::move(callback_).Run();
- }
- return samples_.back();
- }
- private:
- SEQUENCE_CHECKER(sequence_checker_);
- std::vector<PressureSample> samples_ GUARDED_BY_CONTEXT(sequence_checker_);
- size_t sample_index_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
- // This closure is called on a LastSample call after expected number of
- // samples has been taken by PressureSampler.
- base::OnceClosure callback_;
- };
- } // namespace
- TEST_F(PlatformCollectorTest, EnsureStarted_SkipsFirstSample) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- std::vector<PressureSample> samples = {
- // Value right after construction.
- PressureSample{0.1},
- // Value after first Update(), should be discarded.
- PressureSample{0.2},
- // Value after second Update(), should be reported.
- PressureSample{0.4},
- };
- base::RunLoop run_loop;
- collector_ = std::make_unique<PlatformCollector>(
- std::make_unique<StreamingCpuProbe>(samples, run_loop.QuitClosure()),
- base::Milliseconds(1),
- base::BindRepeating(&PlatformCollectorTest::CollectorCallback,
- base::Unretained(this)));
- collector_->EnsureStarted();
- run_loop.Run();
- EXPECT_GE(samples_.size(), 1u);
- EXPECT_THAT(samples_, testing::Not(testing::Contains(PressureSample{0.2})));
- EXPECT_THAT(samples_, testing::Contains(PressureSample{0.4}));
- }
- // TODO(crbug.com/1271419): Flaky.
- #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_WIN)
- #define MAYBE_Stop_Delayed_EnsureStarted_Immediate \
- DISABLED_Stop_Delayed_EnsureStarted_Immediate
- #else
- #define MAYBE_Stop_Delayed_EnsureStarted_Immediate \
- Stop_Delayed_EnsureStarted_Immediate
- #endif
- TEST_F(PlatformCollectorTest, MAYBE_Stop_Delayed_EnsureStarted_Immediate) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- collector_->EnsureStarted();
- WaitForUpdate();
- collector_->Stop();
- samples_.clear();
- cpu_probe().SetLastSample(PressureSample{0.25});
- collector_->EnsureStarted();
- WaitForUpdate();
- EXPECT_GE(samples_.size(), 1u);
- EXPECT_THAT(samples_, testing::Contains(PressureSample{0.25}));
- }
- // TODO(crbug.com/1271419): Flaky.
- #if BUILDFLAG(IS_WIN)
- #define MAYBE_Stop_Delayed_EnsureStarted_Delayed \
- DISABLED_Stop_Delayed_EnsureStarted_Delayed
- #else
- #define MAYBE_Stop_Delayed_EnsureStarted_Delayed \
- Stop_Delayed_EnsureStarted_Delayed
- #endif
- TEST_F(PlatformCollectorTest, MAYBE_Stop_Delayed_EnsureStarted_Delayed) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- collector_->EnsureStarted();
- WaitForUpdate();
- collector_->Stop();
- samples_.clear();
- cpu_probe().SetLastSample(PressureSample{0.25});
- // 10ms should be long enough to ensure that all the sampling tasks are done.
- base::PlatformThread::Sleep(base::Milliseconds(10));
- collector_->EnsureStarted();
- WaitForUpdate();
- EXPECT_GE(samples_.size(), 1u);
- EXPECT_THAT(samples_, testing::Contains(PressureSample{0.25}));
- }
- TEST_F(PlatformCollectorTest, Stop_Immediate_EnsureStarted_Immediate) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- collector_->EnsureStarted();
- collector_->Stop();
- samples_.clear();
- cpu_probe().SetLastSample(PressureSample{0.25});
- collector_->EnsureStarted();
- WaitForUpdate();
- EXPECT_GE(samples_.size(), 1u);
- EXPECT_THAT(samples_, testing::Contains(PressureSample{0.25}));
- }
- TEST_F(PlatformCollectorTest, Stop_Immediate_EnsureStarted_Delayed) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- collector_->EnsureStarted();
- collector_->Stop();
- samples_.clear();
- cpu_probe().SetLastSample(PressureSample{0.25});
- // 10ms should be long enough to ensure that all the sampling tasks are done.
- base::PlatformThread::Sleep(base::Milliseconds(10));
- collector_->EnsureStarted();
- WaitForUpdate();
- EXPECT_GE(samples_.size(), 1u);
- EXPECT_THAT(samples_, testing::Contains(PressureSample{0.25}));
- }
- } // namespace device
|