/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// Author: morlovich@google.com (Maksim Orlovich)

// Unit-test for QueuedAlarm

#include "pagespeed/kernel/thread/queued_alarm.h"

#include <unistd.h>

#include "base/logging.h"
#include "pagespeed/kernel/base/abstract_mutex.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/function.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/thread/mock_scheduler.h"
#include "pagespeed/kernel/thread/queued_worker_pool.h"
#include "pagespeed/kernel/thread/scheduler_thread.h"
#include "pagespeed/kernel/thread/worker_test_base.h"
#include "pagespeed/kernel/util/platform.h"

namespace net_instaweb {
namespace {

class QueuedAlarmTest : public WorkerTestBase {
 public:
  QueuedAlarmTest()
      : thread_system_(Platform::CreateThreadSystem()),
        sequence_(NULL),
        done_(false),
        cancel_(false) {
  }

  virtual ~QueuedAlarmTest() {
    ClearSequence();
  }

  MockScheduler* SetupWithMockScheduler() {
    MockTimer* timer = new MockTimer(thread_system_->NewMutex(), 0);
    MockScheduler* scheduler = new MockScheduler(thread_system_.get(), timer);
    timer_.reset(timer);
    scheduler_.reset(scheduler);
    SetupWorker();
    return scheduler;
  }

  void SetupWithRealScheduler() {
    timer_.reset(Platform::CreateTimer());
    scheduler_.reset(new Scheduler(thread_system_.get(), timer_.get()));
    SetupWorker();
  }

  void MakeSequence() {
    if (sequence_ == NULL) {
      sequence_ = worker_->NewSequence();
      // Take advantage of mock scheduler's quiescence detection.
      scheduler_->RegisterWorker(sequence_);
    }
  }

  void ClearSequence() {
    if (sequence_ != NULL) {
      scheduler_->UnregisterWorker(sequence_);
      worker_->FreeSequence(sequence_);
      sequence_ = NULL;
    }
  }

  void MarkDone() { done_ = true; }
  void MarkCancel() { cancel_ = true; }

  Scheduler* scheduler() { return scheduler_.get(); }
  QueuedWorkerPool::Sequence* sequence() { return sequence_; }
  Timer* timer() { return timer_.get(); }

 protected:
  void SetupWorker() {
    worker_.reset(
        new QueuedWorkerPool(2, "queued_alarm_test", thread_system_.get()));
    MakeSequence();
  }

  scoped_ptr<ThreadSystem> thread_system_;
  scoped_ptr<Timer> timer_;
  scoped_ptr<Scheduler> scheduler_;
  scoped_ptr<QueuedWorkerPool> worker_;
  QueuedWorkerPool::Sequence* sequence_;
  bool done_, cancel_;

 private:
  DISALLOW_COPY_AND_ASSIGN(QueuedAlarmTest);
};

// A class that keeps track of an alarm object and runs ops on it in a sequence.
class TestAlarmHandler {
 public:
  TestAlarmHandler(QueuedAlarmTest* fixture, WorkerTestBase::SyncPoint* sync)
      : fixture_(fixture),
        sync_(sync),
        alarm_(NULL),
        fired_(false) {}

  void StartAlarm() {
    fixture_->sequence()->Add(
        MakeFunction(this, &TestAlarmHandler::StartAlarmImpl));
  }

  void CancelAlarm() {
    fixture_->sequence()->Add(
        MakeFunction(this, &TestAlarmHandler::CancelAlarmImpl));
  }

  void FireAlarm() {
    // Should not have run CancelAlarm if we got here!
    EXPECT_TRUE(alarm_ != NULL);

    // Nothing more to cancel.
    alarm_ = NULL;
    fired_ = true;
  }

  bool fired() const { return fired_; }

 private:
  void StartAlarmImpl() {
    alarm_ =
        new QueuedAlarm(fixture_->scheduler(),
                        fixture_->sequence(),
                        fixture_->timer()->NowUs(),
                        MakeFunction(this, &TestAlarmHandler::FireAlarm));
  }

  void CancelAlarmImpl() {
    if (alarm_ != NULL) {
      alarm_->CancelAlarm();
      alarm_ = NULL;
    }

    // Note that we notify here, as this method will always run. In particular:
    // 1) If we get here first, FireAlarm will not fire, so we're fine.
    // 2) If we get here second, FireAlarm already ran, so we're fine to
    // cleanup, too.
    // (It makes sense to talk about us running before or after FireAlarm
    //  because it runs in the same sequence).
    sync_->Notify();
  }

  QueuedAlarmTest* fixture_;
  WorkerTestBase::SyncPoint* sync_;
  QueuedAlarm* alarm_;
  bool fired_;
  DISALLOW_COPY_AND_ASSIGN(TestAlarmHandler);
};

TEST_F(QueuedAlarmTest, BasicOperation) {
  const int kDelayUs = Timer::kMsUs;

  MockScheduler* scheduler = SetupWithMockScheduler();

  // Tests to make sure the alarm actually runs.
  new QueuedAlarm(scheduler, sequence_,
                  timer_->NowUs() + kDelayUs,
                  MakeFunction(static_cast<QueuedAlarmTest*>(this),
                               &QueuedAlarmTest::MarkDone,
                               &QueuedAlarmTest::MarkCancel));
  {
    ScopedMutex lock(scheduler->mutex());
    scheduler->ProcessAlarmsOrWaitUs(kDelayUs);
  }

  // Make sure to let the work threads complete.
  scheduler->AwaitQuiescence();
  EXPECT_TRUE(done_);
  EXPECT_FALSE(cancel_);
}

TEST_F(QueuedAlarmTest, BasicCancel) {
  const int kDelayUs = Timer::kMsUs;
  MockScheduler* scheduler = SetupWithMockScheduler();

  // Tests to make sure that we can cancel it.
  QueuedAlarm* alarm =
      new QueuedAlarm(scheduler, sequence_,
                      timer_->NowUs() + kDelayUs,
                      MakeFunction(static_cast<QueuedAlarmTest*>(this),
                                   &QueuedAlarmTest::MarkDone,
                                   &QueuedAlarmTest::MarkCancel));
  alarm->CancelAlarm();
  {
    ScopedMutex lock(scheduler->mutex());
    scheduler->ProcessAlarmsOrWaitUs(kDelayUs);
  }

  // Make sure to let the work threads complete.
  scheduler->AwaitQuiescence();
  EXPECT_FALSE(done_);
  EXPECT_TRUE(cancel_);
}

TEST_F(QueuedAlarmTest, RacingCancel) {
  const int kRuns = 1000;
  int fired = 0;

  // Test to make sure cases where cancel and alarm execution may be racing
  // are handled safely, without crashes or check failures.
  SetupWithRealScheduler();
  SchedulerThread* scheduler_thread =
      new SchedulerThread(thread_system_.get(), scheduler_.get());
  scheduler_thread->Start();

  for (int run = 0; run < kRuns; ++run) {
    SyncPoint sync(thread_system_.get());
    MakeSequence();
    TestAlarmHandler t(this, &sync);
    t.StartAlarm();

    // Unfortunately w/o a sleep here, the race is consistently won by
    // the cancellation.
    usleep(1);
    t.CancelAlarm();
    sync.Wait();
    ClearSequence();

    if (t.fired()) {
      ++fired;
    }
  }
  scheduler_thread->MakeDeleter()->CallRun();
  LOG(ERROR) << "Alarm fired in: " << fired  << "/" << kRuns;
}

}  // namespace
}  // namespace net_instaweb
