// 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 "base/debug/activity_tracker.h"

#include <memory>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ptr_util.h"
#include "base/pending_task.h"
#include "base/rand_util.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/spin_wait.h"
#include "base/threading/platform_thread.h"
#include "base/threading/simple_thread.h"
#include "base/time/time.h"
#include "starboard/memory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace debug {

namespace {

class TestActivityTracker : public ThreadActivityTracker {
 public:
  TestActivityTracker(std::unique_ptr<char[]> memory, size_t mem_size)
      : ThreadActivityTracker(SbMemorySet(memory.get(), 0, mem_size), mem_size),
        mem_segment_(std::move(memory)) {}

  ~TestActivityTracker() override = default;

 private:
  std::unique_ptr<char[]> mem_segment_;
};

}  // namespace


class ActivityTrackerTest : public testing::Test {
 public:
  const int kMemorySize = 1 << 20;  // 1MiB
  const int kStackSize  = 1 << 10;  // 1KiB

  using ActivityId = ThreadActivityTracker::ActivityId;

  ActivityTrackerTest() = default;

  ~ActivityTrackerTest() override {
    GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get();
    if (global_tracker) {
      global_tracker->ReleaseTrackerForCurrentThreadForTesting();
      delete global_tracker;
    }
  }

  std::unique_ptr<ThreadActivityTracker> CreateActivityTracker() {
    std::unique_ptr<char[]> memory(new char[kStackSize]);
    return std::make_unique<TestActivityTracker>(std::move(memory), kStackSize);
  }

  size_t GetGlobalActiveTrackerCount() {
    GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get();
    if (!global_tracker)
      return 0;
    return global_tracker->thread_tracker_count_.load(
        std::memory_order_relaxed);
  }

  size_t GetGlobalInactiveTrackerCount() {
    GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get();
    if (!global_tracker)
      return 0;
    AutoLock autolock(global_tracker->thread_tracker_allocator_lock_);
    return global_tracker->thread_tracker_allocator_.cache_used();
  }

  size_t GetGlobalUserDataMemoryCacheUsed() {
    return GlobalActivityTracker::Get()->user_data_allocator_.cache_used();
  }

  void HandleProcessExit(int64_t id,
                         int64_t stamp,
                         int code,
                         GlobalActivityTracker::ProcessPhase phase,
                         std::string&& command,
                         ActivityUserData::Snapshot&& data) {
    exit_id_ = id;
    exit_stamp_ = stamp;
    exit_code_ = code;
    exit_phase_ = phase;
    exit_command_ = std::move(command);
    exit_data_ = std::move(data);
  }

  int64_t exit_id_ = 0;
  int64_t exit_stamp_;
  int exit_code_;
  GlobalActivityTracker::ProcessPhase exit_phase_;
  std::string exit_command_;
  ActivityUserData::Snapshot exit_data_;
};

TEST_F(ActivityTrackerTest, UserDataTest) {
  char buffer[256];
  SbMemorySet(buffer, 0, sizeof(buffer));
  ActivityUserData data(buffer, sizeof(buffer));
  size_t space = sizeof(buffer) - sizeof(ActivityUserData::MemoryHeader);
  ASSERT_EQ(space, data.available_);

  data.SetInt("foo", 1);
  space -= 24;
  ASSERT_EQ(space, data.available_);

  data.SetUint("b", 1U);  // Small names fit beside header in a word.
  space -= 16;
  ASSERT_EQ(space, data.available_);

  data.Set("c", buffer, 10);
  space -= 24;
  ASSERT_EQ(space, data.available_);

  data.SetString("dear john", "it's been fun");
  space -= 32;
  ASSERT_EQ(space, data.available_);

  data.Set("c", buffer, 20);
  ASSERT_EQ(space, data.available_);

  data.SetString("dear john", "but we're done together");
  ASSERT_EQ(space, data.available_);

  data.SetString("dear john", "bye");
  ASSERT_EQ(space, data.available_);

  data.SetChar("d", 'x');
  space -= 8;
  ASSERT_EQ(space, data.available_);

  data.SetBool("ee", true);
  space -= 16;
  ASSERT_EQ(space, data.available_);

  data.SetString("f", "");
  space -= 8;
  ASSERT_EQ(space, data.available_);
}

TEST_F(ActivityTrackerTest, PushPopTest) {
  std::unique_ptr<ThreadActivityTracker> tracker = CreateActivityTracker();
  ThreadActivityTracker::Snapshot snapshot;

  ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
  ASSERT_EQ(0U, snapshot.activity_stack_depth);
  ASSERT_EQ(0U, snapshot.activity_stack.size());

  char origin1;
  ActivityId id1 = tracker->PushActivity(&origin1, Activity::ACT_TASK,
                                         ActivityData::ForTask(11));
  ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
  ASSERT_EQ(1U, snapshot.activity_stack_depth);
  ASSERT_EQ(1U, snapshot.activity_stack.size());
  EXPECT_NE(0, snapshot.activity_stack[0].time_internal);
  EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type);
  EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin1),
            snapshot.activity_stack[0].origin_address);
  EXPECT_EQ(11U, snapshot.activity_stack[0].data.task.sequence_id);

  char origin2;
  char lock2;
  ActivityId id2 = tracker->PushActivity(&origin2, Activity::ACT_LOCK,
                                         ActivityData::ForLock(&lock2));
  ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
  ASSERT_EQ(2U, snapshot.activity_stack_depth);
  ASSERT_EQ(2U, snapshot.activity_stack.size());
  EXPECT_LE(snapshot.activity_stack[0].time_internal,
            snapshot.activity_stack[1].time_internal);
  EXPECT_EQ(Activity::ACT_LOCK, snapshot.activity_stack[1].activity_type);
  EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin2),
            snapshot.activity_stack[1].origin_address);
  EXPECT_EQ(reinterpret_cast<uintptr_t>(&lock2),
            snapshot.activity_stack[1].data.lock.lock_address);

  tracker->PopActivity(id2);
  ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
  ASSERT_EQ(1U, snapshot.activity_stack_depth);
  ASSERT_EQ(1U, snapshot.activity_stack.size());
  EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type);
  EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin1),
            snapshot.activity_stack[0].origin_address);
  EXPECT_EQ(11U, snapshot.activity_stack[0].data.task.sequence_id);

  tracker->PopActivity(id1);
  ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
  ASSERT_EQ(0U, snapshot.activity_stack_depth);
  ASSERT_EQ(0U, snapshot.activity_stack.size());
}

TEST_F(ActivityTrackerTest, ScopedTaskTest) {
  GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);

  ThreadActivityTracker* tracker =
      GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
  ThreadActivityTracker::Snapshot snapshot;
  ASSERT_EQ(0U, GetGlobalUserDataMemoryCacheUsed());

  ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
  ASSERT_EQ(0U, snapshot.activity_stack_depth);
  ASSERT_EQ(0U, snapshot.activity_stack.size());

  {
    PendingTask task1(FROM_HERE, DoNothing());
    ScopedTaskRunActivity activity1(task1);
    ActivityUserData& user_data1 = activity1.user_data();
    (void)user_data1;  // Tell compiler it's been used.

    ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
    ASSERT_EQ(1U, snapshot.activity_stack_depth);
    ASSERT_EQ(1U, snapshot.activity_stack.size());
    EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type);

    {
      PendingTask task2(FROM_HERE, DoNothing());
      ScopedTaskRunActivity activity2(task2);
      ActivityUserData& user_data2 = activity2.user_data();
      (void)user_data2;  // Tell compiler it's been used.

      ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
      ASSERT_EQ(2U, snapshot.activity_stack_depth);
      ASSERT_EQ(2U, snapshot.activity_stack.size());
      EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[1].activity_type);
    }

    ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
    ASSERT_EQ(1U, snapshot.activity_stack_depth);
    ASSERT_EQ(1U, snapshot.activity_stack.size());
    EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type);
  }

  ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
  ASSERT_EQ(0U, snapshot.activity_stack_depth);
  ASSERT_EQ(0U, snapshot.activity_stack.size());
  ASSERT_EQ(2U, GetGlobalUserDataMemoryCacheUsed());
}

namespace {

class SimpleLockThread : public SimpleThread {
 public:
  SimpleLockThread(const std::string& name, Lock* lock)
      : SimpleThread(name, Options()),
        lock_(lock),
        data_changed_(false),
        is_running_(false) {}

  ~SimpleLockThread() override = default;

  void Run() override {
    ThreadActivityTracker* tracker =
        GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
    uint32_t pre_version = tracker->GetDataVersionForTesting();

    is_running_.store(true, std::memory_order_relaxed);
    lock_->Acquire();
    data_changed_ = tracker->GetDataVersionForTesting() != pre_version;
    lock_->Release();
    is_running_.store(false, std::memory_order_relaxed);
  }

  bool IsRunning() { return is_running_.load(std::memory_order_relaxed); }

  bool WasDataChanged() { return data_changed_; };

 private:
  Lock* lock_;
  bool data_changed_;
  std::atomic<bool> is_running_;

  DISALLOW_COPY_AND_ASSIGN(SimpleLockThread);
};

}  // namespace

TEST_F(ActivityTrackerTest, LockTest) {
  GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);

  ThreadActivityTracker* tracker =
      GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
  ThreadActivityTracker::Snapshot snapshot;
  ASSERT_EQ(0U, GetGlobalUserDataMemoryCacheUsed());

  Lock lock;
  uint32_t pre_version = tracker->GetDataVersionForTesting();

  // Check no activity when only "trying" a lock.
  EXPECT_TRUE(lock.Try());
  EXPECT_EQ(pre_version, tracker->GetDataVersionForTesting());
  lock.Release();
  EXPECT_EQ(pre_version, tracker->GetDataVersionForTesting());

  // Check no activity when acquiring a free lock.
  SimpleLockThread t1("locker1", &lock);
  t1.Start();
  t1.Join();
  EXPECT_FALSE(t1.WasDataChanged());

  // Check that activity is recorded when acquring a busy lock.
  SimpleLockThread t2("locker2", &lock);
  lock.Acquire();
  t2.Start();
  while (!t2.IsRunning())
    PlatformThread::Sleep(TimeDelta::FromMilliseconds(10));
  // t2 can't join until the lock is released but have to give time for t2 to
  // actually block on the lock before releasing it or the results will not
  // be correct.
  PlatformThread::Sleep(TimeDelta::FromMilliseconds(200));
  lock.Release();
  // Now the results will be valid.
  t2.Join();
  EXPECT_TRUE(t2.WasDataChanged());
}

TEST_F(ActivityTrackerTest, ExceptionTest) {
  GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);
  GlobalActivityTracker* global = GlobalActivityTracker::Get();

  ThreadActivityTracker* tracker =
      GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
  ThreadActivityTracker::Snapshot snapshot;
  ASSERT_EQ(0U, GetGlobalUserDataMemoryCacheUsed());

  ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
  ASSERT_EQ(0U, snapshot.last_exception.activity_type);

  char origin;
  global->RecordException(&origin, 42);

  ASSERT_TRUE(tracker->CreateSnapshot(&snapshot));
  EXPECT_EQ(Activity::ACT_EXCEPTION, snapshot.last_exception.activity_type);
  EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin),
            snapshot.last_exception.origin_address);
  EXPECT_EQ(42U, snapshot.last_exception.data.exception.code);
}

TEST_F(ActivityTrackerTest, CreateWithFileTest) {
  const char temp_name[] = "CreateWithFileTest";
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath temp_file = temp_dir.GetPath().AppendASCII(temp_name);
  const size_t temp_size = 64 << 10;  // 64 KiB

  // Create a global tracker on a new file.
  ASSERT_FALSE(PathExists(temp_file));
  GlobalActivityTracker::CreateWithFile(temp_file, temp_size, 0, "foo", 3);
  GlobalActivityTracker* global = GlobalActivityTracker::Get();
  EXPECT_EQ(std::string("foo"), global->allocator()->Name());
  global->ReleaseTrackerForCurrentThreadForTesting();
  delete global;

  // Create a global tracker over an existing file, replacing it. If the
  // replacement doesn't work, the name will remain as it was first created.
  ASSERT_TRUE(PathExists(temp_file));
  GlobalActivityTracker::CreateWithFile(temp_file, temp_size, 0, "bar", 3);
  global = GlobalActivityTracker::Get();
  EXPECT_EQ(std::string("bar"), global->allocator()->Name());
  global->ReleaseTrackerForCurrentThreadForTesting();
  delete global;
}


// GlobalActivityTracker tests below.

TEST_F(ActivityTrackerTest, BasicTest) {
  GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);
  GlobalActivityTracker* global = GlobalActivityTracker::Get();

  // Ensure the data repositories have backing store, indicated by non-zero ID.
  EXPECT_NE(0U, global->process_data().id());
}

namespace {

class SimpleActivityThread : public SimpleThread {
 public:
  SimpleActivityThread(const std::string& name,
                       const void* origin,
                       Activity::Type activity,
                       const ActivityData& data)
      : SimpleThread(name, Options()),
        origin_(origin),
        activity_(activity),
        data_(data),
        ready_(false),
        exit_(false),
        exit_condition_(&lock_) {}

  ~SimpleActivityThread() override = default;

  void Run() override {
    ThreadActivityTracker::ActivityId id =
        GlobalActivityTracker::Get()
            ->GetOrCreateTrackerForCurrentThread()
            ->PushActivity(origin_, activity_, data_);

    {
      AutoLock auto_lock(lock_);
      ready_.store(true, std::memory_order_release);
      while (!exit_.load(std::memory_order_relaxed))
        exit_condition_.Wait();
    }

    GlobalActivityTracker::Get()->GetTrackerForCurrentThread()->PopActivity(id);
  }

  void Exit() {
    AutoLock auto_lock(lock_);
    exit_.store(true, std::memory_order_relaxed);
    exit_condition_.Signal();
  }

  void WaitReady() {
    SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(ready_.load(std::memory_order_acquire));
  }

 private:
  const void* origin_;
  Activity::Type activity_;
  ActivityData data_;

  std::atomic<bool> ready_;
  std::atomic<bool> exit_;
  Lock lock_;
  ConditionVariable exit_condition_;

  DISALLOW_COPY_AND_ASSIGN(SimpleActivityThread);
};

}  // namespace

TEST_F(ActivityTrackerTest, ThreadDeathTest) {
  GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);
  GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
  const size_t starting_active = GetGlobalActiveTrackerCount();
  const size_t starting_inactive = GetGlobalInactiveTrackerCount();

  SimpleActivityThread t1("t1", nullptr, Activity::ACT_TASK,
                          ActivityData::ForTask(11));
  t1.Start();
  t1.WaitReady();
  EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount());
  EXPECT_EQ(starting_inactive, GetGlobalInactiveTrackerCount());

  t1.Exit();
  t1.Join();
  EXPECT_EQ(starting_active, GetGlobalActiveTrackerCount());
  EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount());

  // Start another thread and ensure it re-uses the existing memory.

  SimpleActivityThread t2("t2", nullptr, Activity::ACT_TASK,
                          ActivityData::ForTask(22));
  t2.Start();
  t2.WaitReady();
  EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount());
  EXPECT_EQ(starting_inactive, GetGlobalInactiveTrackerCount());

  t2.Exit();
  t2.Join();
  EXPECT_EQ(starting_active, GetGlobalActiveTrackerCount());
  EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount());
}

TEST_F(ActivityTrackerTest, ProcessDeathTest) {
  // This doesn't actually create and destroy a process. Instead, it uses for-
  // testing interfaces to simulate data created by other processes.
  const int64_t other_process_id = GetCurrentProcId() + 1;

  GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3, 0);
  GlobalActivityTracker* global = GlobalActivityTracker::Get();
  ThreadActivityTracker* thread = global->GetOrCreateTrackerForCurrentThread();

  // Get callbacks for process exit.
  global->SetProcessExitCallback(
      Bind(&ActivityTrackerTest::HandleProcessExit, Unretained(this)));

  // Pretend than another process has started.
  global->RecordProcessLaunch(other_process_id, FILE_PATH_LITERAL("foo --bar"));

  // Do some activities.
  PendingTask task(FROM_HERE, DoNothing());
  ScopedTaskRunActivity activity(task);
  ActivityUserData& user_data = activity.user_data();
  ASSERT_NE(0U, user_data.id());

  // Get the memory-allocator references to that data.
  PersistentMemoryAllocator::Reference proc_data_ref =
      global->allocator()->GetAsReference(
          global->process_data().GetBaseAddress(),
          GlobalActivityTracker::kTypeIdProcessDataRecord);
  ASSERT_TRUE(proc_data_ref);
  PersistentMemoryAllocator::Reference tracker_ref =
      global->allocator()->GetAsReference(
          thread->GetBaseAddress(),
          GlobalActivityTracker::kTypeIdActivityTracker);
  ASSERT_TRUE(tracker_ref);
  PersistentMemoryAllocator::Reference user_data_ref =
      global->allocator()->GetAsReference(
          user_data.GetBaseAddress(),
          GlobalActivityTracker::kTypeIdUserDataRecord);
  ASSERT_TRUE(user_data_ref);

  // Make a copy of the thread-tracker state so it can be restored later.
  const size_t tracker_size = global->allocator()->GetAllocSize(tracker_ref);
  std::unique_ptr<char[]> tracker_copy(new char[tracker_size]);
  SbMemoryCopy(tracker_copy.get(), thread->GetBaseAddress(), tracker_size);

  // Change the objects to appear to be owned by another process. Use a "past"
  // time so that exit-time is always later than create-time.
  const int64_t past_stamp = Time::Now().ToInternalValue() - 1;
  int64_t owning_id;
  int64_t stamp;
  ASSERT_TRUE(ActivityUserData::GetOwningProcessId(
      global->process_data().GetBaseAddress(), &owning_id, &stamp));
  EXPECT_NE(other_process_id, owning_id);
  ASSERT_TRUE(ThreadActivityTracker::GetOwningProcessId(
      thread->GetBaseAddress(), &owning_id, &stamp));
  EXPECT_NE(other_process_id, owning_id);
  ASSERT_TRUE(ActivityUserData::GetOwningProcessId(user_data.GetBaseAddress(),
                                                   &owning_id, &stamp));
  EXPECT_NE(other_process_id, owning_id);
  global->process_data().SetOwningProcessIdForTesting(other_process_id,
                                                      past_stamp);
  thread->SetOwningProcessIdForTesting(other_process_id, past_stamp);
  user_data.SetOwningProcessIdForTesting(other_process_id, past_stamp);
  ASSERT_TRUE(ActivityUserData::GetOwningProcessId(
      global->process_data().GetBaseAddress(), &owning_id, &stamp));
  EXPECT_EQ(other_process_id, owning_id);
  ASSERT_TRUE(ThreadActivityTracker::GetOwningProcessId(
      thread->GetBaseAddress(), &owning_id, &stamp));
  EXPECT_EQ(other_process_id, owning_id);
  ASSERT_TRUE(ActivityUserData::GetOwningProcessId(user_data.GetBaseAddress(),
                                                   &owning_id, &stamp));
  EXPECT_EQ(other_process_id, owning_id);

  // Check that process exit will perform callback and free the allocations.
  ASSERT_EQ(0, exit_id_);
  ASSERT_EQ(GlobalActivityTracker::kTypeIdProcessDataRecord,
            global->allocator()->GetType(proc_data_ref));
  ASSERT_EQ(GlobalActivityTracker::kTypeIdActivityTracker,
            global->allocator()->GetType(tracker_ref));
  ASSERT_EQ(GlobalActivityTracker::kTypeIdUserDataRecord,
            global->allocator()->GetType(user_data_ref));
  global->RecordProcessExit(other_process_id, 0);
  EXPECT_EQ(other_process_id, exit_id_);
  EXPECT_EQ("foo --bar", exit_command_);
  EXPECT_EQ(GlobalActivityTracker::kTypeIdProcessDataRecordFree,
            global->allocator()->GetType(proc_data_ref));
  EXPECT_EQ(GlobalActivityTracker::kTypeIdActivityTrackerFree,
            global->allocator()->GetType(tracker_ref));
  EXPECT_EQ(GlobalActivityTracker::kTypeIdUserDataRecordFree,
            global->allocator()->GetType(user_data_ref));

  // Restore memory contents and types so things don't crash when doing real
  // process clean-up.
  SbMemoryCopy(const_cast<void*>(thread->GetBaseAddress()), tracker_copy.get(),
               tracker_size);
  global->allocator()->ChangeType(
      proc_data_ref, GlobalActivityTracker::kTypeIdProcessDataRecord,
      GlobalActivityTracker::kTypeIdUserDataRecordFree, false);
  global->allocator()->ChangeType(
      tracker_ref, GlobalActivityTracker::kTypeIdActivityTracker,
      GlobalActivityTracker::kTypeIdActivityTrackerFree, false);
  global->allocator()->ChangeType(
      user_data_ref, GlobalActivityTracker::kTypeIdUserDataRecord,
      GlobalActivityTracker::kTypeIdUserDataRecordFree, false);
}

}  // namespace debug
}  // namespace base
