// 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/numerics/safe_conversions.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/task_environment.h"
#include "media/base/android/media_server_crash_listener.h"
#include "media/base/fake_single_thread_task_runner.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() {
    throttler_ = MediaServiceThrottler::GetInstance();
    clock_.SetNowTicks(base::TimeTicks());
    throttler_->SetTickClockForTesting(&clock_);
    test_task_runner_ =
        base::MakeRefCounted<FakeSingleThreadTaskRunner>(&clock_);
    throttler_->ResetInternalStateForTesting();
    throttler_->SetCrashListenerTaskRunnerForTesting(test_task_runner_);
    base_delay_ = throttler_->GetBaseThrottlingRateForTesting();
  }

  void SimulateCrashes(int number_of_crashes) {
    for (int i = 0; i < number_of_crashes; ++i)
      throttler_->OnMediaServerCrash(false);
  }

  // Simulates the scheduling of |number_of_clients| and returns the last
  // scheduling delay.
  base::TimeDelta SimulateClientCreations(int number_of_clients) {
    for (int i = 0; i < number_of_clients - 1; ++i)
      throttler_->GetDelayForClientCreation();

    return throttler_->GetDelayForClientCreation();
  }

  base::TimeDelta GetCurrentDelayBetweenClients() {
    // Schedule two clients and return the difference between their scheduling
    // slots.
    return -(throttler_->GetDelayForClientCreation() -
             throttler_->GetDelayForClientCreation());
  }

  base::TimeTicks TestNow() { return clock_.NowTicks(); }

  MediaServiceThrottler* throttler_;
  base::SimpleTestTickClock clock_;

  base::TimeDelta base_delay_;

  scoped_refptr<FakeSingleThreadTaskRunner> test_task_runner_;

  // Necessary, or else base::ThreadTaskRunnerHandle::Get() fails.
  base::test::SingleThreadTaskEnvironment task_environment_;

 private:
  DISALLOW_COPY_AND_ASSIGN(MediaServiceThrottlerTest);
};

// Canary test case.
TEST_F(MediaServiceThrottlerTest, BaseCase) {
  EXPECT_EQ(base::TimeDelta(), throttler_->GetDelayForClientCreation());
}

// Makes sure we can "burst" schedule clients.
TEST_F(MediaServiceThrottlerTest, NoCrash_UnderBurstThreshold_ShouldNotDelay) {
  int number_burst_client_scheduled = 0;

  while (base::TimeDelta() == throttler_->GetDelayForClientCreation())
    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.
  SimulateClientCreations(kMaxBurstClients);

  // Make sure the next client that is scheduled is scheduled in its normal time
  // slot.
  EXPECT_EQ(base_delay_ * (kMaxBurstClients + 1),
            throttler_->GetDelayForClientCreation());
}

// 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.
  SimulateClientCreations(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.
  SimulateClientCreations(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(), SimulateClientCreations(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.
  SimulateClientCreations(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_->GetDelayForClientCreation());
}

// Makes sure that after a certain amount of inactivity, the scheduling clock is
// reset.
TEST_F(MediaServiceThrottlerTest, NoCrash_LongInactivity_ShouldReset) {
  // Schedule two minutes' worth of clients.
  SimulateClientCreations(base::ClampFloor(base::Minutes(2) / base_delay_));

  // Advance the time so the scheduler perceived a full minute of inactivity.
  clock_.Advance(base::Seconds(61));

  // Make sure new clients are burst scheduled.
  EXPECT_EQ(base::TimeDelta(), throttler_->GetDelayForClientCreation());
}

// 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.
  SimulateClientCreations(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.
  SimulateClientCreations(kMaxBurstClients);

  SimulateCrashes(1);
  clock_.Advance(base::Milliseconds(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.
  SimulateClientCreations(kMaxBurstClients);

  SimulateCrashes(2);
  clock_.Advance(base::Milliseconds(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.
  SimulateClientCreations(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_->GetDelayForClientCreation())
    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.
  SimulateClientCreations(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::Seconds(61));

  SimulateClientCreations(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::Seconds(59));
  SimulateCrashes(1);
  clock_.Advance(base::Seconds(2));

  SimulateClientCreations(kMaxBurstClients);

  EXPECT_LT(base_delay_, GetCurrentDelayBetweenClients());
}

// Makes sure the crash listener shuts down after a minute of not having
// received any client creation request.
TEST_F(MediaServiceThrottlerTest, CrashListener_NoRequests_ShouldShutDown) {
  // Schedule many minutes worth of clients. This is to prove that the
  // MediaServerCrashListener's clean up happens after lack of requests, as
  // opposed to lack of actually scheduled clients.
  SimulateClientCreations(base::ClampFloor(base::Minutes(3) / base_delay_));

  // The MediaServerCrashListener should be alive, with 1s second to spare.
  clock_.Advance(base::Seconds(59));
  test_task_runner_->RunTasks();
  EXPECT_TRUE(throttler_->IsCrashListenerAliveForTesting());

  // Requesting a new client creation should reset the interal timer, and
  // cancel the release request that was scheduled 59 seconds ago.
  throttler_->GetDelayForClientCreation();

  // The MediaServerCrashListener should be alive, with 58s second to spare.
  clock_.Advance(base::Seconds(2));
  test_task_runner_->RunTasks();
  EXPECT_TRUE(throttler_->IsCrashListenerAliveForTesting());

  // The MediaServerCrashListener should be dead.
  clock_.Advance(base::Seconds(59));
  test_task_runner_->RunTasks();
  EXPECT_FALSE(throttler_->IsCrashListenerAliveForTesting());
}

// Makes sure the crash listener shuts down after a minute of not having
// received any client creation request, regardless of when crashes occur.
TEST_F(MediaServiceThrottlerTest,
       CrashListener_NoRequestsWithCrashes_ShouldShutDown) {
  // Schedule many minutes worth of clients. This is to prove that the
  // MediaServerCrashListener's clean up happens after lack of requests, as
  // opposed to lack of actually scheduled clients.
  SimulateClientCreations(base::ClampFloor(base::Minutes(3) / base_delay_));

  // The MediaServerCrashListener should be alive, with 1s second to spare.
  clock_.Advance(base::Seconds(59));
  test_task_runner_->RunTasks();
  EXPECT_TRUE(throttler_->IsCrashListenerAliveForTesting());

  // Crashes should not affect the MediaServerCrashListener's lifetime.
  SimulateCrashes(1);

  // The MediaServerCrashListener should be dead.
  clock_.Advance(base::Seconds(2));
  test_task_runner_->RunTasks();
  EXPECT_FALSE(throttler_->IsCrashListenerAliveForTesting());
}

}  // namespace media
