blob: 251a92adadf252cad9c7cb26a4ff54202ad668b8 [file] [log] [blame]
// 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::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));
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();
}
} // namespace trace_event
} // namespace base