| Index: base/debug/activity_tracker_unittest.cc
|
| diff --git a/base/debug/activity_tracker_unittest.cc b/base/debug/activity_tracker_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3559e11f32a19238e188b4d8d7eeb85d11a4b875
|
| --- /dev/null
|
| +++ b/base/debug/activity_tracker_unittest.cc
|
| @@ -0,0 +1,134 @@
|
| +// 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/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 "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 {
|
| + delete GlobalActivityTracker::Get();
|
| + }
|
| +
|
| + private:
|
| + std::unique_ptr<char[]> mem_segment_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +
|
| +class ActivityTrackerTest : public testing::Test {
|
| + public:
|
| + const int kMemorySize = 1 << 10; // 1KiB
|
| + const int kStackSize = 256;
|
| +
|
| + ActivityTrackerTest() {}
|
| +
|
| + ~ActivityTrackerTest() {}
|
| +
|
| + std::unique_ptr<ThreadActivityTracker> CreateActivityTracker() {
|
| + std::unique_ptr<char[]> memory(new char[kStackSize]);
|
| + return WrapUnique(new TestActivityTracker(std::move(memory), kStackSize));
|
| + }
|
| +
|
| + static void DoNothing() {}
|
| +};
|
| +
|
| +TEST_F(ActivityTrackerTest, PushPopTest) {
|
| + std::unique_ptr<ThreadActivityTracker> tracker = CreateActivityTracker();
|
| + std::vector<ThreadActivityTracker::StackEntry> stack;
|
| +
|
| + ASSERT_EQ(0U, tracker->CopyStack(&stack));
|
| + ASSERT_EQ(0U, stack.size());
|
| +
|
| + char source1;
|
| + tracker->RecordStart(&source1, ThreadActivityTracker::ACT_TASK, 2, 3);
|
| + ASSERT_EQ(1U, tracker->CopyStack(&stack));
|
| + ASSERT_EQ(1U, stack.size());
|
| + EXPECT_NE(0, stack[0].time_ticks);
|
| + EXPECT_EQ(ThreadActivityTracker::ACT_TASK, stack[0].activity_type);
|
| + EXPECT_EQ(reinterpret_cast<intptr_t>(&source1), stack[0].source_address);
|
| + EXPECT_EQ(2, stack[0].method_address);
|
| + EXPECT_EQ(3U, stack[0].sequence_id);
|
| +
|
| + char source2;
|
| + tracker->RecordStart(&source2, ThreadActivityTracker::ACT_LOCK, 3, 4);
|
| + ASSERT_EQ(2U, tracker->CopyStack(&stack));
|
| + ASSERT_EQ(2U, stack.size());
|
| + EXPECT_LE(stack[0].time_ticks, stack[1].time_ticks);
|
| + EXPECT_EQ(ThreadActivityTracker::ACT_LOCK, stack[1].activity_type);
|
| + EXPECT_EQ(reinterpret_cast<intptr_t>(&source2), stack[1].source_address);
|
| + EXPECT_EQ(3, stack[1].method_address);
|
| + EXPECT_EQ(4U, stack[1].sequence_id);
|
| +
|
| + tracker->RecordFinish(&source2);
|
| + ASSERT_EQ(1U, tracker->CopyStack(&stack));
|
| + ASSERT_EQ(1U, stack.size());
|
| + EXPECT_EQ(ThreadActivityTracker::ACT_TASK, stack[0].activity_type);
|
| + EXPECT_EQ(reinterpret_cast<intptr_t>(&source1), stack[0].source_address);
|
| + EXPECT_EQ(2, stack[0].method_address);
|
| + EXPECT_EQ(3U, stack[0].sequence_id);
|
| +
|
| + tracker->RecordFinish(&source1);
|
| + ASSERT_EQ(0U, tracker->CopyStack(&stack));
|
| + ASSERT_EQ(0U, stack.size());
|
| +}
|
| +
|
| +TEST_F(ActivityTrackerTest, ScopedTaskTest) {
|
| + GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3);
|
| +
|
| + ThreadActivityTracker* tracker =
|
| + GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread();
|
| + std::vector<ThreadActivityTracker::StackEntry> stack;
|
| +
|
| + ASSERT_EQ(0U, tracker->CopyStack(&stack));
|
| + ASSERT_EQ(0U, stack.size());
|
| +
|
| + {
|
| + PendingTask task1(FROM_HERE, base::Bind(&DoNothing));
|
| + ScopedTaskActivity activity1(task1);
|
| +
|
| + ASSERT_EQ(1U, tracker->CopyStack(&stack));
|
| + ASSERT_EQ(1U, stack.size());
|
| + EXPECT_EQ(ThreadActivityTracker::ACT_TASK, stack[0].activity_type);
|
| +
|
| + {
|
| + PendingTask task2(FROM_HERE, base::Bind(&DoNothing));
|
| + ScopedTaskActivity activity2(task2);
|
| +
|
| + ASSERT_EQ(2U, tracker->CopyStack(&stack));
|
| + ASSERT_EQ(2U, stack.size());
|
| + EXPECT_EQ(ThreadActivityTracker::ACT_TASK, stack[1].activity_type);
|
| + }
|
| +
|
| + ASSERT_EQ(1U, tracker->CopyStack(&stack));
|
| + ASSERT_EQ(1U, stack.size());
|
| + EXPECT_EQ(ThreadActivityTracker::ACT_TASK, stack[0].activity_type);
|
| + }
|
| +
|
| + ASSERT_EQ(0U, tracker->CopyStack(&stack));
|
| + ASSERT_EQ(0U, stack.size());
|
| +}
|
| +
|
| +} // namespace debug
|
| +} // namespace base
|
|
|