| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <string> |
| |
| #include "base/functional/bind.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/task_environment.h" |
| #include "base/time/time.h" |
| #include "media/capabilities/pending_operations.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace media { |
| namespace { |
| |
| class PendingOperationsTest : public ::testing::Test { |
| protected: |
| base::test::TaskEnvironment task_environment_{ |
| base::test::TaskEnvironment::TimeSource::MOCK_TIME}; |
| base::HistogramTester histogram_; |
| }; |
| |
| // Test that histogram is created with correct data. |
| TEST_F(PendingOperationsTest, OperationTiming) { |
| const std::string kUmaPrefix = "Media.PendingOperations."; |
| const std::string kOperation = "init"; |
| constexpr base::TimeDelta kInitDelay = base::Seconds(2); |
| PendingOperations pending_operations(kUmaPrefix); |
| PendingOperations::Id init_id = pending_operations.Start(kOperation); |
| EXPECT_EQ(pending_operations.get_pending_ops_for_test().size(), 1u); |
| task_environment_.FastForwardBy(kInitDelay); |
| pending_operations.Complete(init_id); |
| |
| // No pending operations. |
| EXPECT_TRUE(pending_operations.get_pending_ops_for_test().empty()); |
| // UMA histogram emitted. |
| histogram_.ExpectUniqueSample(kUmaPrefix + kOperation, |
| kInitDelay.InMicroseconds(), 1); |
| } |
| |
| // Test that timeout histogram works. |
| TEST_F(PendingOperationsTest, OperationTimeout) { |
| const std::string kUmaPrefix = "Media.PendingOperations."; |
| const std::string kOperation = "read"; |
| constexpr base::TimeDelta kLongTimeout = base::Hours(1); |
| // Current setting of the pending operation timeout. |
| constexpr base::TimeDelta kPendingOperationTimeout = base::Seconds(30); |
| PendingOperations pending_operations(kUmaPrefix); |
| pending_operations.Start(kOperation); |
| EXPECT_EQ(pending_operations.get_pending_ops_for_test().size(), 1u); |
| task_environment_.FastForwardBy(kLongTimeout); |
| |
| // No pending operations. |
| EXPECT_TRUE(pending_operations.get_pending_ops_for_test().empty()); |
| // UMA histogram emitted, operation reported as timeout. |
| histogram_.ExpectUniqueSample(kUmaPrefix + kOperation, |
| kPendingOperationTimeout.InMicroseconds(), 1); |
| } |
| |
| // Nested operations. |
| struct SimulatedOperation { |
| std::string name; |
| base::TimeDelta start_time; |
| base::TimeDelta stop_time; |
| PendingOperations::Id id; |
| }; |
| |
| TEST_F(PendingOperationsTest, NestedOperation) { |
| const std::string kUmaPrefix = "Media.PendingOperations."; |
| PendingOperations pending_operations(kUmaPrefix); |
| // A list of operations named after their start and stop time. |
| SimulatedOperation operations[] = { |
| {"0_10", base::Milliseconds(0), base::Milliseconds(10), 0}, |
| {"5_15", base::Milliseconds(5), base::Milliseconds(15), 0}, |
| {"6_30", base::Milliseconds(6), base::Milliseconds(30), 0}, |
| {"10_12", base::Milliseconds(10), base::Milliseconds(12), 0}, |
| {"20_27", base::Milliseconds(20), base::Milliseconds(27), 0}, |
| {"5_80", base::Milliseconds(5), base::Milliseconds(80), 0}, |
| {"30_60", base::Milliseconds(30), base::Milliseconds(60), 0}, |
| {"25_90", base::Milliseconds(25), base::Milliseconds(90), 0}, |
| }; |
| |
| size_t expected_pending_operations = 0; |
| // Run a loop from 0 to 100 ms. |
| base::TimeDelta tick_length = base::Milliseconds(1); |
| for (base::TimeDelta elapsed_time; elapsed_time < base::Milliseconds(100); |
| elapsed_time += tick_length) { |
| // Start/Complete each operation if the elapsed time has reached the |
| // corresponding start/stop time. |
| for (auto& operation : operations) { |
| if (operation.start_time == elapsed_time) { |
| operation.id = pending_operations.Start(operation.name); |
| ++expected_pending_operations; |
| } |
| if (operation.stop_time == elapsed_time) { |
| pending_operations.Complete(operation.id); |
| --expected_pending_operations; |
| } |
| } |
| EXPECT_EQ(pending_operations.get_pending_ops_for_test().size(), |
| expected_pending_operations); |
| task_environment_.FastForwardBy(tick_length); |
| } |
| |
| for (const auto& operation : operations) { |
| histogram_.ExpectUniqueSample( |
| kUmaPrefix + operation.name, |
| (operation.stop_time - operation.start_time).InMicroseconds(), 1); |
| } |
| } |
| |
| } // namespace |
| } // namespace media |