Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / renderer / devtools / v8_sampling_profiler_browsertest.cc
blob1703d5d74edaef130b33ad5a5d22e3331b6ddebd
1 // Copyright (c) 2014 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.
5 #include "base/json/json_reader.h"
6 #include "base/run_loop.h"
7 #include "base/trace_event/trace_buffer.h"
8 #include "base/trace_event/trace_event.h"
9 #include "content/public/test/render_view_test.h"
10 #include "content/renderer/devtools/v8_sampling_profiler.h"
12 using base::DictionaryValue;
13 using base::ListValue;
14 using base::Value;
15 using base::trace_event::TraceConfig;
16 using base::trace_event::TraceLog;
17 using base::trace_event::TraceResultBuffer;
19 namespace content {
21 class V8SamplingProfilerTest : public RenderViewTest {
22 public:
23 void SetUp() override {
24 RenderViewTest::SetUp();
25 sampling_profiler_.reset(new V8SamplingProfiler(true));
26 trace_buffer_.SetOutputCallback(json_output_.GetCallback());
29 void TearDown() override {
30 sampling_profiler_.reset();
31 RenderViewTest::TearDown();
34 void KickV8() { ExecuteJavaScriptForTests("1"); }
36 void SyncFlush(TraceLog* trace_log) {
37 base::WaitableEvent flush_complete_event(false, false);
38 trace_log->Flush(
39 base::Bind(&V8SamplingProfilerTest::OnTraceDataCollected,
40 base::Unretained(static_cast<V8SamplingProfilerTest*>(this)),
41 base::Unretained(&flush_complete_event)));
42 base::RunLoop().RunUntilIdle();
43 flush_complete_event.Wait();
46 void OnTraceDataCollected(
47 base::WaitableEvent* flush_complete_event,
48 const scoped_refptr<base::RefCountedString>& events_str,
49 bool has_more_events) {
50 base::AutoLock lock(lock_);
51 json_output_.json_output.clear();
52 trace_buffer_.Start();
53 trace_buffer_.AddFragment(events_str->data());
54 trace_buffer_.Finish();
56 scoped_ptr<Value> root;
57 root = base::JSONReader::Read(
58 json_output_.json_output,
59 base::JSON_PARSE_RFC | base::JSON_DETACHABLE_CHILDREN);
61 if (!root.get()) {
62 LOG(ERROR) << json_output_.json_output;
65 ListValue* root_list = NULL;
66 ASSERT_TRUE(root.get());
67 ASSERT_TRUE(root->GetAsList(&root_list));
69 // Move items into our aggregate collection
70 while (root_list->GetSize()) {
71 scoped_ptr<Value> item;
72 root_list->Remove(0, &item);
73 trace_parsed_.Append(item.release());
76 if (!has_more_events)
77 flush_complete_event->Signal();
80 void CollectTrace(int code_added_events, int sample_events) {
81 TraceLog* trace_log = TraceLog::GetInstance();
82 sampling_profiler_->EnableSamplingEventForTesting(code_added_events,
83 sample_events);
84 trace_log->SetEnabled(
85 TraceConfig(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profile"), ""),
86 TraceLog::RECORDING_MODE);
87 base::RunLoop().RunUntilIdle();
88 KickV8(); // Make a call to V8 so it can invoke interrupt request
89 // callbacks.
90 base::RunLoop().RunUntilIdle();
91 sampling_profiler_->WaitSamplingEventForTesting();
92 trace_log->SetDisabled();
93 SyncFlush(trace_log);
96 int CountEvents(const std::string& name) const {
97 size_t trace_parsed_count = trace_parsed_.GetSize();
98 int events_count = 0;
99 for (size_t i = 0; i < trace_parsed_count; i++) {
100 const DictionaryValue* dict;
101 if (!trace_parsed_.GetDictionary(i, &dict))
102 continue;
103 std::string value;
104 if (!dict->GetString("cat", &value) ||
105 value != TRACE_DISABLED_BY_DEFAULT("v8.cpu_profile"))
106 continue;
107 if (!dict->GetString("name", &value) || value != name)
108 continue;
109 ++events_count;
111 return events_count;
114 scoped_ptr<V8SamplingProfiler> sampling_profiler_;
115 base::Lock lock_;
117 ListValue trace_parsed_;
118 TraceResultBuffer trace_buffer_;
119 TraceResultBuffer::SimpleOutput json_output_;
122 TEST_F(V8SamplingProfilerTest, V8SamplingEventFired) {
123 sampling_profiler_->EnableSamplingEventForTesting(0, 0);
124 TraceLog::GetInstance()->SetEnabled(
125 TraceConfig(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profile"), ""),
126 TraceLog::RECORDING_MODE);
127 base::RunLoop().RunUntilIdle();
128 sampling_profiler_->WaitSamplingEventForTesting();
129 TraceLog::GetInstance()->SetDisabled();
130 base::RunLoop().RunUntilIdle();
133 TEST_F(V8SamplingProfilerTest, V8SamplingJitCodeEventsCollected) {
134 CollectTrace(1, 0);
135 int jit_code_added_events_count = CountEvents("JitCodeAdded");
136 CHECK_LT(0, jit_code_added_events_count);
137 base::RunLoop().RunUntilIdle();
140 TEST_F(V8SamplingProfilerTest, V8SamplingSamplesCollected) {
141 CollectTrace(0, 1);
142 int sample_events_count = CountEvents("V8Sample");
143 CHECK_LT(0, sample_events_count);
144 base::RunLoop().RunUntilIdle();
147 } // namespace content