OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/debug/activity_tracker.h" |
| 6 |
| 7 #include <memory> |
| 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/files/file.h" |
| 11 #include "base/files/file_util.h" |
| 12 #include "base/files/memory_mapped_file.h" |
| 13 #include "base/files/scoped_temp_dir.h" |
| 14 #include "base/memory/ptr_util.h" |
| 15 #include "base/pending_task.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 |
| 18 namespace base { |
| 19 namespace debug { |
| 20 |
| 21 namespace { |
| 22 |
| 23 class TestActivityTracker : public ThreadActivityTracker { |
| 24 public: |
| 25 TestActivityTracker(std::unique_ptr<char[]> memory, size_t mem_size) |
| 26 : ThreadActivityTracker(memset(memory.get(), 0, mem_size), mem_size), |
| 27 mem_segment_(std::move(memory)) {} |
| 28 |
| 29 ~TestActivityTracker() override { |
| 30 delete GlobalActivityTracker::Get(); |
| 31 } |
| 32 |
| 33 private: |
| 34 std::unique_ptr<char[]> mem_segment_; |
| 35 }; |
| 36 |
| 37 } // namespace |
| 38 |
| 39 |
| 40 class ActivityTrackerTest : public testing::Test { |
| 41 public: |
| 42 const int kMemorySize = 1 << 10; // 1KiB |
| 43 const int kStackSize = 256; |
| 44 |
| 45 ActivityTrackerTest() {} |
| 46 |
| 47 ~ActivityTrackerTest() {} |
| 48 |
| 49 std::unique_ptr<ThreadActivityTracker> CreateActivityTracker() { |
| 50 std::unique_ptr<char[]> memory(new char[kStackSize]); |
| 51 return WrapUnique(new TestActivityTracker(std::move(memory), kStackSize)); |
| 52 } |
| 53 |
| 54 static void DoNothing() {} |
| 55 }; |
| 56 |
| 57 TEST_F(ActivityTrackerTest, PushPopTest) { |
| 58 std::unique_ptr<ThreadActivityTracker> tracker = CreateActivityTracker(); |
| 59 std::vector<ThreadActivityTracker::StackEntry> stack; |
| 60 |
| 61 ASSERT_EQ(0U, tracker->CopyStack(&stack)); |
| 62 ASSERT_EQ(0U, stack.size()); |
| 63 |
| 64 char source1; |
| 65 tracker->RecordStart(&source1, ThreadActivityTracker::ACT_TASK, 2, 3); |
| 66 ASSERT_EQ(1U, tracker->CopyStack(&stack)); |
| 67 ASSERT_EQ(1U, stack.size()); |
| 68 EXPECT_NE(0, stack[0].time_ticks); |
| 69 EXPECT_EQ(ThreadActivityTracker::ACT_TASK, stack[0].activity_type); |
| 70 EXPECT_EQ(reinterpret_cast<intptr_t>(&source1), stack[0].source_address); |
| 71 EXPECT_EQ(2, stack[0].method_address); |
| 72 EXPECT_EQ(3U, stack[0].sequence_id); |
| 73 |
| 74 char source2; |
| 75 tracker->RecordStart(&source2, ThreadActivityTracker::ACT_LOCK, 3, 4); |
| 76 ASSERT_EQ(2U, tracker->CopyStack(&stack)); |
| 77 ASSERT_EQ(2U, stack.size()); |
| 78 EXPECT_LE(stack[0].time_ticks, stack[1].time_ticks); |
| 79 EXPECT_EQ(ThreadActivityTracker::ACT_LOCK, stack[1].activity_type); |
| 80 EXPECT_EQ(reinterpret_cast<intptr_t>(&source2), stack[1].source_address); |
| 81 EXPECT_EQ(3, stack[1].method_address); |
| 82 EXPECT_EQ(4U, stack[1].sequence_id); |
| 83 |
| 84 tracker->RecordFinish(&source2); |
| 85 ASSERT_EQ(1U, tracker->CopyStack(&stack)); |
| 86 ASSERT_EQ(1U, stack.size()); |
| 87 EXPECT_EQ(ThreadActivityTracker::ACT_TASK, stack[0].activity_type); |
| 88 EXPECT_EQ(reinterpret_cast<intptr_t>(&source1), stack[0].source_address); |
| 89 EXPECT_EQ(2, stack[0].method_address); |
| 90 EXPECT_EQ(3U, stack[0].sequence_id); |
| 91 |
| 92 tracker->RecordFinish(&source1); |
| 93 ASSERT_EQ(0U, tracker->CopyStack(&stack)); |
| 94 ASSERT_EQ(0U, stack.size()); |
| 95 } |
| 96 |
| 97 TEST_F(ActivityTrackerTest, ScopedTaskTest) { |
| 98 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); |
| 99 |
| 100 ThreadActivityTracker* tracker = |
| 101 GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread(); |
| 102 std::vector<ThreadActivityTracker::StackEntry> stack; |
| 103 |
| 104 ASSERT_EQ(0U, tracker->CopyStack(&stack)); |
| 105 ASSERT_EQ(0U, stack.size()); |
| 106 |
| 107 { |
| 108 PendingTask task1(FROM_HERE, base::Bind(&DoNothing)); |
| 109 ScopedTaskActivity activity1(task1); |
| 110 |
| 111 ASSERT_EQ(1U, tracker->CopyStack(&stack)); |
| 112 ASSERT_EQ(1U, stack.size()); |
| 113 EXPECT_EQ(ThreadActivityTracker::ACT_TASK, stack[0].activity_type); |
| 114 |
| 115 { |
| 116 PendingTask task2(FROM_HERE, base::Bind(&DoNothing)); |
| 117 ScopedTaskActivity activity2(task2); |
| 118 |
| 119 ASSERT_EQ(2U, tracker->CopyStack(&stack)); |
| 120 ASSERT_EQ(2U, stack.size()); |
| 121 EXPECT_EQ(ThreadActivityTracker::ACT_TASK, stack[1].activity_type); |
| 122 } |
| 123 |
| 124 ASSERT_EQ(1U, tracker->CopyStack(&stack)); |
| 125 ASSERT_EQ(1U, stack.size()); |
| 126 EXPECT_EQ(ThreadActivityTracker::ACT_TASK, stack[0].activity_type); |
| 127 } |
| 128 |
| 129 ASSERT_EQ(0U, tracker->CopyStack(&stack)); |
| 130 ASSERT_EQ(0U, stack.size()); |
| 131 } |
| 132 |
| 133 } // namespace debug |
| 134 } // namespace base |
OLD | NEW |