// Copyright (c) 2013 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 "components/policy/core/common/cloud/rate_limiter.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/test_simple_task_runner.h"
#include "base/time/tick_clock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace policy {

class RateLimiterTest : public testing::Test {
 public:
  RateLimiterTest()
      : task_runner_(new base::TestSimpleTaskRunner()),
        clock_(new base::SimpleTestTickClock()),
        callbacks_(0),
        max_requests_(5),
        duration_(base::TimeDelta::FromHours(1)),
        small_delta_(base::TimeDelta::FromMinutes(1)),
        limiter_(max_requests_,
                 duration_,
                 base::Bind(&RateLimiterTest::Callback, base::Unretained(this)),
                 task_runner_,
                 scoped_ptr<base::TickClock>(clock_).Pass()) {}
  virtual ~RateLimiterTest() {}

 protected:
  void Callback() {
    callbacks_++;
  }

  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
  base::SimpleTestTickClock* clock_;
  size_t callbacks_;
  const size_t max_requests_;
  const base::TimeDelta duration_;
  const base::TimeDelta small_delta_;
  RateLimiter limiter_;
};

TEST_F(RateLimiterTest, LimitRequests) {
  size_t count = 0;
  for (size_t i = 0; i < max_requests_; ++i) {
    EXPECT_EQ(count, callbacks_);
    limiter_.PostRequest();
    ++count;
    EXPECT_EQ(count, callbacks_);
    EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
    clock_->Advance(small_delta_);
  }

  for (size_t i = 0; i < 10; ++i) {
    limiter_.PostRequest();
    EXPECT_EQ(max_requests_, callbacks_);
    clock_->Advance(small_delta_);
    EXPECT_FALSE(task_runner_->GetPendingTasks().empty());
  }

  // Now advance the clock beyond the duration. The callback is invoked once.
  callbacks_ = 0;
  clock_->Advance(duration_);
  task_runner_->RunPendingTasks();
  EXPECT_EQ(1u, callbacks_);
  EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
}

TEST_F(RateLimiterTest, Steady) {
  const base::TimeDelta delta = duration_ / 2;
  size_t count = 0;
  for (int i = 0; i < 100; ++i) {
    EXPECT_EQ(count, callbacks_);
    limiter_.PostRequest();
    ++count;
    EXPECT_EQ(count, callbacks_);
    EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
    clock_->Advance(delta);
  }
}

TEST_F(RateLimiterTest, RetryAfterDelay) {
  size_t count = 0;
  base::TimeDelta total_delta;
  // Fill the queue.
  for (size_t i = 0; i < max_requests_; ++i) {
    EXPECT_EQ(count, callbacks_);
    limiter_.PostRequest();
    ++count;
    EXPECT_EQ(count, callbacks_);
    EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
    clock_->Advance(small_delta_);
    total_delta += small_delta_;
  }

  // Now post a request that will be delayed.
  EXPECT_EQ(max_requests_, callbacks_);
  limiter_.PostRequest();
  EXPECT_EQ(max_requests_, callbacks_);
  EXPECT_FALSE(task_runner_->GetPendingTasks().empty());

  while (total_delta < duration_) {
    task_runner_->RunPendingTasks();
    // The queue is still full, so another task is immediately posted.
    EXPECT_FALSE(task_runner_->GetPendingTasks().empty());
    clock_->Advance(small_delta_);
    total_delta += small_delta_;
  }

  // Now advance time beyond the initial duration. It will immediately execute
  // the callback.
  EXPECT_EQ(max_requests_, callbacks_);
  task_runner_->RunPendingTasks();
  EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
  EXPECT_EQ(max_requests_ + 1, callbacks_);
}

}  // namespace policy
