// Copyright 2015 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/trace_event/memory_dump_manager.h"

#include "base/trace_event/memory_dump_provider.h"
#include "base/trace_event/process_memory_dump.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::Invoke;
using testing::Return;

namespace base {
namespace trace_event {

class MemoryDumpManagerTest : public testing::Test {
 public:
  void SetUp() override {
    mdm_.reset(new MemoryDumpManager());
    MemoryDumpManager::SetInstanceForTesting(mdm_.get());
    ASSERT_EQ(mdm_, MemoryDumpManager::GetInstance());
    MemoryDumpManager::GetInstance()->Initialize();
  }

  void TearDown() override {
    MemoryDumpManager::SetInstanceForTesting(nullptr);
    mdm_.reset();
    TraceLog::DeleteForTesting();
  }

 protected:
  const char* const kTraceCategory = MemoryDumpManager::kTraceCategory;

  void EnableTracing(const char* category) {
    TraceLog::GetInstance()->SetEnabled(
        CategoryFilter(category), TraceLog::RECORDING_MODE, TraceOptions());
  }

  void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); }

  scoped_ptr<MemoryDumpManager> mdm_;

 private:
  // We want our singleton torn down after each test.
  ShadowingAtExitManager at_exit_manager_;
};

class MockDumpProvider : public MemoryDumpProvider {
 public:
  MOCK_METHOD1(DumpInto, bool(ProcessMemoryDump* pmd));

  // DumpInto() override for the ActiveDumpProviderConsistency test,
  bool DumpIntoAndCheckDumpProviderCurrentlyActive(ProcessMemoryDump* pmd) {
    EXPECT_EQ(
        this,
        MemoryDumpManager::GetInstance()->dump_provider_currently_active());
    return true;
  }

  const char* GetFriendlyName() const override { return "MockDumpProvider"; }
};

TEST_F(MemoryDumpManagerTest, SingleDumper) {
  MockDumpProvider mdp;
  mdm_->RegisterDumpProvider(&mdp);

  // Check that the dumper is not called if the memory category is not enabled.
  EnableTracing("foo-and-bar-but-not-memory");
  EXPECT_CALL(mdp, DumpInto(_)).Times(0);
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);
  DisableTracing();

  // Now repeat enabling the memory category and check that the dumper is
  // invoked this time.
  EnableTracing(kTraceCategory);
  EXPECT_CALL(mdp, DumpInto(_)).Times(3).WillRepeatedly(Return(true));
  for (int i = 0; i < 3; ++i)
    mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);
  DisableTracing();

  mdm_->UnregisterDumpProvider(&mdp);

  // Finally check the unregister logic (no calls to the mdp after unregister).
  EnableTracing(kTraceCategory);
  EXPECT_CALL(mdp, DumpInto(_)).Times(0);
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);
  TraceLog::GetInstance()->SetDisabled();
}

TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileTracing) {
  MockDumpProvider mdp;
  mdm_->RegisterDumpProvider(&mdp);

  EnableTracing(kTraceCategory);
  EXPECT_CALL(mdp, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);

  mdm_->UnregisterDumpProvider(&mdp);
  EXPECT_CALL(mdp, DumpInto(_)).Times(0);
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);

  DisableTracing();
}

TEST_F(MemoryDumpManagerTest, MultipleDumpers) {
  MockDumpProvider mdp1;
  MockDumpProvider mdp2;

  // Enable only mdp1.
  mdm_->RegisterDumpProvider(&mdp1);
  EnableTracing(kTraceCategory);
  EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
  EXPECT_CALL(mdp2, DumpInto(_)).Times(0);
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);
  DisableTracing();

  // Invert: enable mdp1 and disable mdp2.
  mdm_->UnregisterDumpProvider(&mdp1);
  mdm_->RegisterDumpProvider(&mdp2);
  EnableTracing(kTraceCategory);
  EXPECT_CALL(mdp1, DumpInto(_)).Times(0);
  EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);
  DisableTracing();

  // Enable both mdp1 and mdp2.
  mdm_->RegisterDumpProvider(&mdp1);
  EnableTracing(kTraceCategory);
  EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
  EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);
  DisableTracing();
}

// Enable both dump providers, make mdp1 fail and assert that only mdp2 is
// invoked the 2nd time.
// FIXME(primiano): remove once crbug.com/461788 gets fixed.
TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) {
  MockDumpProvider mdp1;
  MockDumpProvider mdp2;

  mdm_->RegisterDumpProvider(&mdp1);
  mdm_->RegisterDumpProvider(&mdp2);
  EnableTracing(kTraceCategory);

  EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(false));
  EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);

  EXPECT_CALL(mdp1, DumpInto(_)).Times(0);
  EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(false));
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);

  DisableTracing();
}

// TODO(primiano): remove once crbug.com/466121 gets fixed.
// Ascertains that calls to MDM::dump_provider_currently_active() actually
// returns the MemoryDumpProvider currently active during the DumpInto() call.
TEST_F(MemoryDumpManagerTest, ActiveDumpProviderConsistency) {
  MockDumpProvider mdp1;
  MockDumpProvider mdp2;

  mdm_->RegisterDumpProvider(&mdp1);
  mdm_->RegisterDumpProvider(&mdp2);
  EnableTracing(kTraceCategory);
  EXPECT_CALL(mdp1, DumpInto(_))
      .Times(2)
      .WillRepeatedly(Invoke(
          &mdp1,
          &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive));
  EXPECT_CALL(mdp2, DumpInto(_))
      .Times(2)
      .WillRepeatedly(Invoke(
          &mdp2,
          &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive));
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);
  mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);
  DisableTracing();
}

}  // namespace trace_event
}  // namespace base
