// Copyright 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.

// NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a
// heavily-loaded system). Sorry. |test::EpsilonDeadline()| may be increased to
// increase tolerance and reduce observed flakiness (though doing so reduces the
// meaningfulness of the test).

#include "mojo/edk/system/awakable_list.h"

#include "mojo/edk/system/handle_signals_state.h"
#include "mojo/edk/system/test_utils.h"
#include "mojo/edk/system/waiter.h"
#include "mojo/edk/system/waiter_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace system {
namespace {

TEST(AwakableListTest, BasicCancel) {
  MojoResult result;
  uint32_t context;

  // Cancel immediately after thread start.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread(&result, &context);
    awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
    thread.Start();
    awakable_list.CancelAll();
    // Double-remove okay:
    awakable_list.Remove(thread.waiter());
  }  // Join |thread|.
  EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
  EXPECT_EQ(1u, context);

  // Cancel before after thread start.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread(&result, &context);
    awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
    awakable_list.CancelAll();
    thread.Start();
  }  // Join |thread|.
  EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
  EXPECT_EQ(2u, context);

  // Cancel some time after thread start.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread(&result, &context);
    awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
    thread.Start();
    test::Sleep(2 * test::EpsilonDeadline());
    awakable_list.CancelAll();
  }  // Join |thread|.
  EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
  EXPECT_EQ(3u, context);
}

TEST(AwakableListTest, BasicAwakeSatisfied) {
  MojoResult result;
  uint32_t context;

  // Awake immediately after thread start.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread(&result, &context);
    awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
    thread.Start();
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_READABLE,
        MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
    awakable_list.Remove(thread.waiter());
  }  // Join |thread|.
  EXPECT_EQ(MOJO_RESULT_OK, result);
  EXPECT_EQ(1u, context);

  // Awake before after thread start.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread(&result, &context);
    awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_WRITABLE,
        MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
    awakable_list.Remove(thread.waiter());
    // Double-remove okay:
    awakable_list.Remove(thread.waiter());
    thread.Start();
  }  // Join |thread|.
  EXPECT_EQ(MOJO_RESULT_OK, result);
  EXPECT_EQ(2u, context);

  // Awake some time after thread start.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread(&result, &context);
    awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
    thread.Start();
    test::Sleep(2 * test::EpsilonDeadline());
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_READABLE,
        MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
    awakable_list.Remove(thread.waiter());
  }  // Join |thread|.
  EXPECT_EQ(MOJO_RESULT_OK, result);
  EXPECT_EQ(3u, context);
}

TEST(AwakableListTest, BasicAwakeUnsatisfiable) {
  MojoResult result;
  uint32_t context;

  // Awake (for unsatisfiability) immediately after thread start.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread(&result, &context);
    awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
    thread.Start();
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE));
    awakable_list.Remove(thread.waiter());
  }  // Join |thread|.
  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
  EXPECT_EQ(1u, context);

  // Awake (for unsatisfiability) before after thread start.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread(&result, &context);
    awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_READABLE, MOJO_HANDLE_SIGNAL_READABLE));
    awakable_list.Remove(thread.waiter());
    thread.Start();
  }  // Join |thread|.
  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
  EXPECT_EQ(2u, context);

  // Awake (for unsatisfiability) some time after thread start.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread(&result, &context);
    awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
    thread.Start();
    test::Sleep(2 * test::EpsilonDeadline());
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE));
    awakable_list.Remove(thread.waiter());
    // Double-remove okay:
    awakable_list.Remove(thread.waiter());
  }  // Join |thread|.
  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
  EXPECT_EQ(3u, context);
}

TEST(AwakableListTest, MultipleAwakables) {
  MojoResult result1;
  MojoResult result2;
  MojoResult result3;
  MojoResult result4;
  uint32_t context1;
  uint32_t context2;
  uint32_t context3;
  uint32_t context4;

  // Cancel two awakables.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread1(&result1, &context1);
    awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1);
    thread1.Start();
    test::SimpleWaiterThread thread2(&result2, &context2);
    awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2);
    thread2.Start();
    test::Sleep(2 * test::EpsilonDeadline());
    awakable_list.CancelAll();
  }  // Join threads.
  EXPECT_EQ(MOJO_RESULT_CANCELLED, result1);
  EXPECT_EQ(1u, context1);
  EXPECT_EQ(MOJO_RESULT_CANCELLED, result2);
  EXPECT_EQ(2u, context2);

  // Awake one awakable, cancel other.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread1(&result1, &context1);
    awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3);
    thread1.Start();
    test::SimpleWaiterThread thread2(&result2, &context2);
    awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 4);
    thread2.Start();
    test::Sleep(2 * test::EpsilonDeadline());
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_READABLE,
        MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
    awakable_list.Remove(thread1.waiter());
    awakable_list.CancelAll();
  }  // Join threads.
  EXPECT_EQ(MOJO_RESULT_OK, result1);
  EXPECT_EQ(3u, context1);
  EXPECT_EQ(MOJO_RESULT_CANCELLED, result2);
  EXPECT_EQ(4u, context2);

  // Cancel one awakable, awake other for unsatisfiability.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread1(&result1, &context1);
    awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 5);
    thread1.Start();
    test::SimpleWaiterThread thread2(&result2, &context2);
    awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 6);
    thread2.Start();
    test::Sleep(2 * test::EpsilonDeadline());
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE));
    awakable_list.Remove(thread2.waiter());
    awakable_list.CancelAll();
  }  // Join threads.
  EXPECT_EQ(MOJO_RESULT_CANCELLED, result1);
  EXPECT_EQ(5u, context1);
  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2);
  EXPECT_EQ(6u, context2);

  // Cancel one awakable, awake other for unsatisfiability.
  {
    AwakableList awakable_list;
    test::SimpleWaiterThread thread1(&result1, &context1);
    awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 7);
    thread1.Start();

    test::Sleep(1 * test::EpsilonDeadline());

    // Should do nothing.
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_NONE,
        MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));

    test::SimpleWaiterThread thread2(&result2, &context2);
    awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 8);
    thread2.Start();

    test::Sleep(1 * test::EpsilonDeadline());

    // Awake #1.
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_READABLE,
        MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE));
    awakable_list.Remove(thread1.waiter());

    test::Sleep(1 * test::EpsilonDeadline());

    test::SimpleWaiterThread thread3(&result3, &context3);
    awakable_list.Add(thread3.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 9);
    thread3.Start();

    test::SimpleWaiterThread thread4(&result4, &context4);
    awakable_list.Add(thread4.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 10);
    thread4.Start();

    test::Sleep(1 * test::EpsilonDeadline());

    // Awake #2 and #3 for unsatisfiability.
    awakable_list.AwakeForStateChange(HandleSignalsState(
        MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE));
    awakable_list.Remove(thread2.waiter());
    awakable_list.Remove(thread3.waiter());

    // Cancel #4.
    awakable_list.CancelAll();
  }  // Join threads.
  EXPECT_EQ(MOJO_RESULT_OK, result1);
  EXPECT_EQ(7u, context1);
  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2);
  EXPECT_EQ(8u, context2);
  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3);
  EXPECT_EQ(9u, context3);
  EXPECT_EQ(MOJO_RESULT_CANCELLED, result4);
  EXPECT_EQ(10u, context4);
}

class KeepAwakable : public Awakable {
 public:
  KeepAwakable() : awake_count(0) {}

  bool Awake(MojoResult result, uintptr_t context) override {
    awake_count++;
    return true;
  }

  int awake_count;

  MOJO_DISALLOW_COPY_AND_ASSIGN(KeepAwakable);
};

class RemoveAwakable : public Awakable {
 public:
  RemoveAwakable() : awake_count(0) {}

  bool Awake(MojoResult result, uintptr_t context) override {
    awake_count++;
    return false;
  }

  int awake_count;

  MOJO_DISALLOW_COPY_AND_ASSIGN(RemoveAwakable);
};

TEST(AwakableListTest, KeepAwakablesReturningTrue) {
  KeepAwakable keep0;
  KeepAwakable keep1;
  RemoveAwakable remove0;
  RemoveAwakable remove1;
  RemoveAwakable remove2;

  HandleSignalsState hss(MOJO_HANDLE_SIGNAL_WRITABLE,
                         MOJO_HANDLE_SIGNAL_WRITABLE);

  AwakableList remove_all;
  remove_all.Add(&remove0, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
  remove_all.Add(&remove1, MOJO_HANDLE_SIGNAL_WRITABLE, 0);

  remove_all.AwakeForStateChange(hss);
  EXPECT_EQ(remove0.awake_count, 1);
  EXPECT_EQ(remove1.awake_count, 1);

  remove_all.AwakeForStateChange(hss);
  EXPECT_EQ(remove0.awake_count, 1);
  EXPECT_EQ(remove1.awake_count, 1);

  AwakableList remove_first;
  remove_first.Add(&remove2, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
  remove_first.Add(&keep0, MOJO_HANDLE_SIGNAL_WRITABLE, 0);
  remove_first.Add(&keep1, MOJO_HANDLE_SIGNAL_WRITABLE, 0);

  remove_first.AwakeForStateChange(hss);
  EXPECT_EQ(keep0.awake_count, 1);
  EXPECT_EQ(keep1.awake_count, 1);
  EXPECT_EQ(remove2.awake_count, 1);

  remove_first.AwakeForStateChange(hss);
  EXPECT_EQ(keep0.awake_count, 2);
  EXPECT_EQ(keep1.awake_count, 2);
  EXPECT_EQ(remove2.awake_count, 1);

  remove_first.Remove(&keep0);
  remove_first.Remove(&keep1);
}

}  // namespace
}  // namespace system
}  // namespace mojo
