/*
 * 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 SlowWorker

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

#include <unistd.h>

#include "base/logging.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/function.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/thread/worker_test_base.h"

namespace net_instaweb {
namespace {

class SlowWorkerTest: public WorkerTestBase {
 public:
  SlowWorkerTest()
      : worker_(new SlowWorker("slow_worker_test", thread_runtime_.get())) {
  }

 protected:
  scoped_ptr<SlowWorker> worker_;

 private:
  DISALLOW_COPY_AND_ASSIGN(SlowWorkerTest);
};

TEST_F(SlowWorkerTest, BasicOperation) {
  // Add in a job that waits for our OK before finishing Run() and an another
  // job that fails if Run. Since we don't let the first one proceed, the second
  // one should be deleted immediately.
  SyncPoint start_sync(thread_runtime_.get());
  SyncPoint delete_sync(thread_runtime_.get());

  worker_->Start();
  worker_->RunIfNotBusy(new WaitRunFunction(&start_sync));
  worker_->RunIfNotBusy(new DeleteNotifyFunction(&delete_sync));
  delete_sync.Wait();
  start_sync.Notify();

  // Make sure we kill the thread now, so we don't get it accessing
  // deleted start_sync after we exit if it's slow to start
  worker_.reset(NULL);
}

class WaitCancelFunction : public Function {
 public:
  explicit WaitCancelFunction(WorkerTestBase::SyncPoint* sync) : sync_(sync) {}

  virtual void Run() {
    sync_->Notify();
    while (!quit_requested()) {
      usleep(10);
    }
  }

 private:
  WorkerTestBase::SyncPoint* sync_;
  DISALLOW_COPY_AND_ASSIGN(WaitCancelFunction);
};

TEST_F(SlowWorkerTest, Cancellation) {
  // Used to wait for thread to actually start, so we don't see it
  // being deleted w/o being started as confirming that exit is working
  SyncPoint start_sync(thread_runtime_.get());

  worker_->Start();
  worker_->RunIfNotBusy(new WaitCancelFunction(&start_sync));

  // Wait for the thread to start...
  start_sync.Wait();

  // Ask for exit and block on that.
  worker_.reset(NULL);
}

// Used to check that quit_requested is false by default normally.
class CheckDefaultCancelFunction : public WorkerTestBase::NotifyRunFunction {
 public:
  explicit CheckDefaultCancelFunction(WorkerTestBase::SyncPoint* sync)
      : NotifyRunFunction(sync) {}

  virtual void Run() {
    CHECK(!quit_requested());
    NotifyRunFunction::Run();
  }
};

TEST_F(SlowWorkerTest, CancelDefaultFalse) {
  SyncPoint start_sync(thread_runtime_.get());

  worker_->Start();
  worker_->RunIfNotBusy(new CheckDefaultCancelFunction(&start_sync));
  start_sync.Wait();
}

}  // namespace
}  // namespace net_instaweb
