Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(893)

Unified Diff: media/base/android/media_service_throttler_unittest.cc

Issue 2471903002: Add MediaServiceThrottler (Closed)
Patch Set: Integrate throttler into MediaPlayerRender Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/base/android/media_service_throttler_unittest.cc
diff --git a/media/base/android/media_service_throttler_unittest.cc b/media/base/android/media_service_throttler_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d17b4b96db53c0f1c58a3ecb39c33e5aa1a0d55d
--- /dev/null
+++ b/media/base/android/media_service_throttler_unittest.cc
@@ -0,0 +1,256 @@
+// Copyright 2016 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 "media/base/android/media_service_throttler.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/test/simple_test_tick_clock.h"
+#include "media/base/android/media_server_crash_listener.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+// From base/media/android/media_service_throttler.cc
+const int kMaxBurstClients = 10;
+
+class MediaServiceThrottlerTest : public testing::Test {
+ public:
+ MediaServiceThrottlerTest() : clock_(new base::SimpleTestTickClock()) {
+ throttler_ = MediaServiceThrottler::GetInstance();
+ clock_->SetNowTicks(base::TimeTicks());
+ throttler_->SetTickClockForTesting(clock_);
+ MediaServerCrashListener::GetInstance()
+ ->ClearOnServerCrashCallbackForTesting();
+ throttler_->ResetInternalStateForTesting();
+ base_delay_ = throttler_->GetBaseThrottlingRateForTesting();
+ }
+
+ void SimulateCrashes(int number_of_crashes) {
+ for (int i = 0; i < number_of_crashes; ++i)
+ throttler_->OnMediaServerCrash();
+ }
+
+ // Simulates the scheduling of |number_of_clients| and returns the last
+ // scheduling delay.
+ base::TimeDelta BatchScheduleClientCreations(int number_of_clients) {
+ for (int i = 0; i < number_of_clients - 1; ++i)
+ throttler_->ScheduleClientCreation();
+
+ return throttler_->ScheduleClientCreation();
+ }
+
+ base::TimeDelta GetCurrentDelayBetweenClients() {
+ // Schedule two clients and return the difference between their scheduling
+ // slots.
+ return -(throttler_->ScheduleClientCreation() -
+ throttler_->ScheduleClientCreation());
+ }
+
+ base::TimeTicks TestNow() { return clock_->NowTicks(); }
+
+ MediaServiceThrottler* throttler_;
+ base::SimpleTestTickClock* clock_;
+
+ base::TimeDelta base_delay_;
+
+ // Necessary, or else base::ThreadTaskRunnerHandle::Get() fails.
+ base::MessageLoop message_loop_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MediaServiceThrottlerTest);
+};
+
+// Canary test case.
+TEST_F(MediaServiceThrottlerTest, BaseCase) {
+ EXPECT_EQ(base::TimeDelta(), throttler_->ScheduleClientCreation());
+}
+
+// Makes sure we can "burst" schedule clients.
+TEST_F(MediaServiceThrottlerTest, NoCrash_UnderBurstThreshold_ShouldNotDelay) {
+ int number_burst_client_scheduled = 0;
+
+ while (base::TimeDelta() == throttler_->ScheduleClientCreation())
+ number_burst_client_scheduled++;
+
+ EXPECT_EQ(kMaxBurstClients, number_burst_client_scheduled);
+}
+
+// Makes sure that, when burst scheduling a client, we schedule it from
+// last scheduled burst client (vs scheduling it |base_delay_| from now).
+TEST_F(MediaServiceThrottlerTest, NoCrash_OverBurstThreshold_ShouldDelay) {
+ // Schedule clients until the next one would be over burst threshold.
+ BatchScheduleClientCreations(kMaxBurstClients);
+
+ // Make sure the next client that is scheduled is scheduled in its normal time
+ // slot.
+ EXPECT_EQ(base_delay_ * (kMaxBurstClients + 1),
+ throttler_->ScheduleClientCreation());
+}
+
+// Makes sure that clients are scheduled |base_delay| apart.
+TEST_F(MediaServiceThrottlerTest,
+ NoCrash_OverBurstThreshold_ShouldDelayLinearly) {
+ // Schedule clients until the next one would be over burst threshold.
+ BatchScheduleClientCreations(kMaxBurstClients);
+
+ // Delays between two clients should be |base_delay_| appart.
+ EXPECT_EQ(base_delay_, GetCurrentDelayBetweenClients());
+
+ // Delays should remain constant (GetCurrentDelayBetweenClients() is not
+ // idempotent and actually schedules new clients).
+ EXPECT_EQ(GetCurrentDelayBetweenClients(), GetCurrentDelayBetweenClients());
+}
+
+// Makes sure that for every |base_delay_| that has elapsed, we can burst
+// schedule an extra client.
+TEST_F(MediaServiceThrottlerTest,
+ NoCrash_BurstThreshold_ShouldBeSlidingWindow) {
+ // Schedule some clients below the burst threshold.
+ BatchScheduleClientCreations(7);
+
+ clock_->Advance(base_delay_ * 5);
+
+ // Make sure the passage of allows for more clients to be scheduled, since
+ // 7 + 8 > kMaxBurstClients.
+ EXPECT_EQ(base::TimeDelta(), BatchScheduleClientCreations(8));
+}
+
+// Makes sure that, if not enough time has elapsed, we do not burst schedule
+// new clients.
+TEST_F(MediaServiceThrottlerTest,
+ NoCrash_OverBurstThresholdWithTimeLapse_ShouldDelay) {
+ // Schedule some clients way above the burst threshold.
+ BatchScheduleClientCreations(3 * kMaxBurstClients);
+
+ // Advance the time so there are still 2 * kMaxBurstClients pending clients.
+ clock_->Advance(base_delay_ * kMaxBurstClients);
+
+ // Make sure delay we do not burst schedule new clients.
+ EXPECT_NE(base::TimeDelta(), throttler_->ScheduleClientCreation());
+}
+
+// Makes sure that after a certain amount of inactivity, the scheduling clock is
+// reset.
+TEST_F(MediaServiceThrottlerTest, NoCrash_LongInactivity_ShouldReset) {
+ // Schedule two minute's worth of clients
+ BatchScheduleClientCreations(base::TimeDelta::FromMinutes(2) / base_delay_);
+
+ // Advance the time so the scheduler perceived a full minute of inactivity.
+ clock_->Advance(base::TimeDelta::FromSeconds(61));
+
+ // Make sure new clients are burst scheduled.
+ EXPECT_EQ(base::TimeDelta(), throttler_->ScheduleClientCreation());
+}
+
+// Makes sure that crashes increase the scheduling delay.
+TEST_F(MediaServiceThrottlerTest, WithCrash_BaseCase_DelayShouldIncrease) {
+ // Schedule clients until the next one would be over burst threshold.
+ BatchScheduleClientCreations(kMaxBurstClients);
+
+ base::TimeDelta no_crash_delay = GetCurrentDelayBetweenClients();
+
+ SimulateCrashes(1);
+
+ base::TimeDelta crash_delay = GetCurrentDelayBetweenClients();
+
+ EXPECT_NE(base_delay_, crash_delay);
+ EXPECT_GT(crash_delay, no_crash_delay);
+}
+
+// Makes sure that we tolerate 1 crash per minute.
+TEST_F(MediaServiceThrottlerTest,
+ WithCrash_SingleCrash_DelayShouldNotIncrease) {
+ // Schedule clients until the next one would be over burst threshold.
+ BatchScheduleClientCreations(kMaxBurstClients);
+
+ SimulateCrashes(1);
+ clock_->Advance(base::TimeDelta::FromMilliseconds(1));
+
+ // Because we use the floor function when calculating crashes, a small time
+ // advance should nullify a single crash.
+ EXPECT_EQ(base_delay_, GetCurrentDelayBetweenClients());
+}
+
+// Makes sure that more than 1 crash per minute causes increased delays.
+TEST_F(MediaServiceThrottlerTest, WithCrash_ManyCrashes_DelayShouldIncrease) {
+ // Schedule clients until the next one would be over burst threshold.
+ BatchScheduleClientCreations(kMaxBurstClients);
+
+ SimulateCrashes(2);
+ clock_->Advance(base::TimeDelta::FromMilliseconds(1));
+
+ // The delay after crashes should be greater than the base delay.
+ EXPECT_LT(base_delay_, GetCurrentDelayBetweenClients());
+}
+
+// Makes sure that an increase in server crashes leads to delay increases.
+TEST_F(MediaServiceThrottlerTest,
+ WithCrash_ConsecutiveCrashes_DelayShouldIncreaseWithNumberOfCrashes) {
+ // Schedule clients until the next one would be over burst threshold.
+ BatchScheduleClientCreations(kMaxBurstClients);
+
+ base::TimeDelta last_delay = base_delay_;
+
+ for (int i = 0; i < 5; ++i) {
+ SimulateCrashes(1);
+ base::TimeDelta current_delay = GetCurrentDelayBetweenClients();
+ EXPECT_LT(last_delay, current_delay);
+ last_delay = current_delay;
+ }
+}
+
+// Makes sure that crashes affect the number of burst clients we can schedule.
+TEST_F(MediaServiceThrottlerTest, WithCrash_ShouldAllowFewerBurstClients) {
+ int number_burst_client_scheduled = 0;
+
+ SimulateCrashes(1);
+
+ while (base::TimeDelta() == throttler_->ScheduleClientCreation())
+ number_burst_client_scheduled++;
+
+ EXPECT_GT(kMaxBurstClients, number_burst_client_scheduled);
+}
+
+// Makes sure delays are capped to a certain maximal value.
+TEST_F(MediaServiceThrottlerTest, WithCrash_ManyCrashes_DelayShouldMaxOut) {
+ // Schedule clients until the next one would be over burst threshold.
+ BatchScheduleClientCreations(kMaxBurstClients);
+
+ SimulateCrashes(10);
+ base::TimeDelta capped_delay = GetCurrentDelayBetweenClients();
+
+ SimulateCrashes(10);
+
+ EXPECT_EQ(capped_delay, GetCurrentDelayBetweenClients());
+}
+
+// Makes sure a minute without crashes resets the crash counter.
+TEST_F(MediaServiceThrottlerTest, WithCrash_NoCrashesForAMinute_ShouldReset) {
+ SimulateCrashes(10);
+
+ // The effective server crash count should be reset because it has been over
+ // a minute since the last crash.
+ clock_->Advance(base::TimeDelta::FromSeconds(61));
+
+ BatchScheduleClientCreations(kMaxBurstClients);
+
+ EXPECT_EQ(base_delay_, GetCurrentDelayBetweenClients());
+}
+
+// Makes sure a steady crashes do not resets the crash counter.
+TEST_F(MediaServiceThrottlerTest, WithCrash_ConstantCrashes_ShouldNotReset) {
+ SimulateCrashes(9);
+
+ // The effective server crash count should not be reset.
+ clock_->Advance(base::TimeDelta::FromSeconds(59));
+ SimulateCrashes(1);
+ clock_->Advance(base::TimeDelta::FromSeconds(2));
+
+ BatchScheduleClientCreations(kMaxBurstClients);
+
+ EXPECT_LT(base_delay_, GetCurrentDelayBetweenClients());
+}
+
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698