// 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(memset(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];
  memset(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]);
  memcpy(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.
  memcpy(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
