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
;
15 using base::trace_event::TraceConfig
;
16 using base::trace_event::TraceLog
;
17 using base::trace_event::TraceResultBuffer
;
21 class V8SamplingProfilerTest
: public RenderViewTest
{
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);
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
.reset(base::JSONReader::DeprecatedRead(
58 json_output_
.json_output
,
59 base::JSON_PARSE_RFC
| base::JSON_DETACHABLE_CHILDREN
));
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());
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
,
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
90 base::RunLoop().RunUntilIdle();
91 sampling_profiler_
->WaitSamplingEventForTesting();
92 trace_log
->SetDisabled();
96 int CountEvents(const std::string
& name
) const {
97 size_t trace_parsed_count
= trace_parsed_
.GetSize();
99 for (size_t i
= 0; i
< trace_parsed_count
; i
++) {
100 const DictionaryValue
* dict
;
101 if (!trace_parsed_
.GetDictionary(i
, &dict
))
104 if (!dict
->GetString("cat", &value
) ||
105 value
!= TRACE_DISABLED_BY_DEFAULT("v8.cpu_profile"))
107 if (!dict
->GetString("name", &value
) || value
!= name
)
114 scoped_ptr
<V8SamplingProfiler
> sampling_profiler_
;
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
) {
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
) {
142 int sample_events_count
= CountEvents("V8Sample");
143 CHECK_LT(0, sample_events_count
);
144 base::RunLoop().RunUntilIdle();
147 } // namespace content