OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/metrics/process_memory_metrics_emitter.h" | 5 #include "chrome/browser/metrics/process_memory_metrics_emitter.h" |
6 | 6 |
7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "base/test/histogram_tester.h" | |
9 #include "base/trace_event/memory_dump_manager.h" | |
10 #include "base/trace_event/trace_config_memory_test_util.h" | |
8 #include "chrome/test/base/in_process_browser_test.h" | 11 #include "chrome/test/base/in_process_browser_test.h" |
12 #include "chrome/test/base/tracing.h" | |
13 #include "chrome/test/base/ui_test_utils.h" | |
9 #include "content/public/test/test_utils.h" | 14 #include "content/public/test/test_utils.h" |
15 #include "url/gurl.h" | |
10 | 16 |
11 namespace { | 17 namespace { |
12 | 18 |
19 using base::trace_event::MemoryDumpType; | |
20 | |
21 void RequestGlobalDumpCallback(base::Closure quit_closure, | |
22 uint64_t, | |
23 bool success) { | |
24 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure); | |
25 ASSERT_TRUE(success); | |
26 } | |
27 | |
28 void OnStartTracingDoneCallback( | |
29 base::trace_event::MemoryDumpLevelOfDetail explicit_dump_type, | |
30 base::Closure quit_closure) { | |
31 base::trace_event::MemoryDumpManager::GetInstance()->RequestGlobalDump( | |
32 MemoryDumpType::EXPLICITLY_TRIGGERED, explicit_dump_type, | |
33 Bind(&RequestGlobalDumpCallback, quit_closure)); | |
34 } | |
35 | |
13 class ProcessMemoryMetricsEmitterFake : public ProcessMemoryMetricsEmitter { | 36 class ProcessMemoryMetricsEmitterFake : public ProcessMemoryMetricsEmitter { |
14 public: | 37 public: |
15 ProcessMemoryMetricsEmitterFake() {} | 38 explicit ProcessMemoryMetricsEmitterFake(base::RunLoop* run_loop) |
39 : run_loop_(run_loop) {} | |
16 | 40 |
17 private: | 41 private: |
18 ~ProcessMemoryMetricsEmitterFake() override {} | 42 ~ProcessMemoryMetricsEmitterFake() override {} |
19 | 43 |
20 void ReceivedMemoryDump( | 44 void ReceivedMemoryDump( |
21 uint64_t dump_guid, | 45 uint64_t dump_guid, |
22 bool success, | 46 bool success, |
23 memory_instrumentation::mojom::GlobalMemoryDumpPtr ptr) override { | 47 memory_instrumentation::mojom::GlobalMemoryDumpPtr ptr) override { |
24 EXPECT_TRUE(success); | 48 EXPECT_TRUE(success); |
25 base::MessageLoop::current()->QuitWhenIdle(); | 49 ProcessMemoryMetricsEmitter::ReceivedMemoryDump(dump_guid, success, |
50 std::move(ptr)); | |
51 if (run_loop_) | |
52 run_loop_->Quit(); | |
26 } | 53 } |
27 | 54 |
55 base::RunLoop* run_loop_; | |
56 | |
28 DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitterFake); | 57 DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitterFake); |
29 }; | 58 }; |
30 | 59 |
60 void CheckMemoryMetric(const std::string& name, | |
61 const base::HistogramTester& histogram_tester, | |
62 int count) { | |
63 histogram_tester.ExpectTotalCount(name, count); | |
64 std::unique_ptr<base::HistogramSamples> samples( | |
65 histogram_tester.GetHistogramSamplesSinceCreation(name)); | |
66 ASSERT_TRUE(samples); | |
67 EXPECT_GT(samples->sum(), 0u) << name; | |
68 | |
69 // As a sanity check, no memory stat should exceed 1 GB. | |
70 int64_t maximum_expected_size = 1ll << 30 * count; | |
71 EXPECT_LT(samples->sum(), maximum_expected_size) << name; | |
72 } | |
73 | |
74 void CheckAllMemoryMetrics(const base::HistogramTester& histogram_tester, | |
75 int count) { | |
76 CheckMemoryMetric("Memory.Experimental.Browser2.Malloc", histogram_tester, | |
77 count); | |
78 CheckMemoryMetric("Memory.Experimental.Browser2.Resident", histogram_tester, | |
79 count); | |
80 CheckMemoryMetric("Memory.Experimental.Renderer2.Malloc", histogram_tester, | |
81 count); | |
82 CheckMemoryMetric("Memory.Experimental.Renderer2.Resident", histogram_tester, | |
83 count); | |
84 CheckMemoryMetric("Memory.Experimental.Renderer2.BlinkGC", histogram_tester, | |
85 count); | |
86 CheckMemoryMetric("Memory.Experimental.Renderer2.V8", histogram_tester, | |
87 count); | |
88 } | |
89 | |
31 } // namespace | 90 } // namespace |
32 | 91 |
33 class ProcessMemoryMetricsEmitterTest : public InProcessBrowserTest { | 92 class ProcessMemoryMetricsEmitterTest : public InProcessBrowserTest { |
34 public: | 93 public: |
35 ProcessMemoryMetricsEmitterTest() {} | 94 ProcessMemoryMetricsEmitterTest() {} |
36 ~ProcessMemoryMetricsEmitterTest() override {} | 95 ~ProcessMemoryMetricsEmitterTest() override {} |
37 | 96 |
38 private: | 97 private: |
39 DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitterTest); | 98 DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitterTest); |
40 }; | 99 }; |
41 | 100 |
42 IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest, FetchAndEmitMetrics) { | 101 IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest, FetchAndEmitMetrics) { |
102 base::HistogramTester histogram_tester; | |
103 base::RunLoop run_loop; | |
104 | |
43 // Intentionally let emitter leave scope to check that it correctly keeps | 105 // Intentionally let emitter leave scope to check that it correctly keeps |
44 // itself alive. | 106 // itself alive. |
45 { | 107 { |
46 scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter( | 108 scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter( |
47 new ProcessMemoryMetricsEmitterFake); | 109 new ProcessMemoryMetricsEmitterFake(&run_loop)); |
48 emitter->FetchAndEmitProcessMemoryMetrics(); | 110 emitter->FetchAndEmitProcessMemoryMetrics(); |
49 } | 111 } |
50 | 112 |
51 content::RunMessageLoop(); | 113 run_loop.Run(); |
114 | |
115 CheckAllMemoryMetrics(histogram_tester, 1); | |
52 } | 116 } |
117 | |
118 IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest, FetchDuringTrace) { | |
119 base::HistogramTester histogram_tester; | |
120 base::RunLoop run_loop; | |
121 | |
122 base::trace_event::TraceConfig trace_config( | |
123 base::trace_event::TraceConfigMemoryTestUtil:: | |
124 GetTraceConfig_EmptyTriggers()); | |
125 ASSERT_TRUE(tracing::BeginTracingWithTraceConfig( | |
126 trace_config, Bind(&OnStartTracingDoneCallback, | |
127 base::trace_event::MemoryDumpLevelOfDetail::DETAILED, | |
128 run_loop.QuitClosure()))); | |
129 | |
130 // Intentionally let emitter leave scope to check that it correctly keeps | |
131 // itself alive. | |
132 { | |
133 scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter( | |
134 new ProcessMemoryMetricsEmitterFake(&run_loop)); | |
135 emitter->FetchAndEmitProcessMemoryMetrics(); | |
136 } | |
137 | |
138 GURL url1("about:blank"); | |
139 ui_test_utils::NavigateToURLWithDisposition( | |
140 browser(), url1, WindowOpenDisposition::NEW_FOREGROUND_TAB, | |
141 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | |
142 run_loop.Run(); | |
143 | |
144 std::string json_events; | |
145 ASSERT_TRUE(tracing::EndTracing(&json_events)); | |
146 EXPECT_NE(0u, json_events.length()); | |
147 | |
148 CheckAllMemoryMetrics(histogram_tester, 1); | |
149 } | |
150 | |
151 IN_PROC_BROWSER_TEST_F(ProcessMemoryMetricsEmitterTest, FetchThreeTimes) { | |
152 base::HistogramTester histogram_tester; | |
153 base::RunLoop run_loop; | |
154 | |
155 int count = 3; | |
156 for (int i = 0; i < count; ++i) { | |
157 // Only the last emitter should stop the run loop. | |
158 scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter( | |
dcheng
2017/05/13 20:22:37
auto emitter = base::MakeShared<ProcessMemoryMetri
erikchen
2017/05/14 04:49:16
Done.
| |
159 new ProcessMemoryMetricsEmitterFake((i == count - 1) ? &run_loop | |
160 : nullptr)); | |
161 emitter->FetchAndEmitProcessMemoryMetrics(); | |
162 } | |
163 | |
164 run_loop.Run(); | |
165 | |
166 CheckAllMemoryMetrics(histogram_tester, count); | |
167 } | |
OLD | NEW |