OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include <cstring> | 5 #include <cstring> |
6 | 6 |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 | 8 |
9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
10 #include "vm/dart_api_state.h" | 10 #include "vm/dart_api_state.h" |
11 #include "vm/globals.h" | 11 #include "vm/globals.h" |
12 #include "vm/timeline.h" | 12 #include "vm/timeline.h" |
13 #include "vm/timeline_analysis.h" | 13 #include "vm/timeline_analysis.h" |
14 #include "vm/unit_test.h" | 14 #include "vm/unit_test.h" |
15 | 15 |
16 namespace dart { | 16 namespace dart { |
17 | 17 |
| 18 class TimelineRecorderOverride : public ValueObject { |
| 19 public: |
| 20 explicit TimelineRecorderOverride(TimelineEventRecorder* new_recorder) |
| 21 : recorder_(Timeline::recorder()) { |
| 22 Timeline::recorder_ = new_recorder; |
| 23 } |
| 24 |
| 25 ~TimelineRecorderOverride() { |
| 26 Timeline::recorder_ = recorder_; |
| 27 } |
| 28 |
| 29 private: |
| 30 TimelineEventRecorder* recorder_; |
| 31 }; |
| 32 |
| 33 |
18 class TimelineTestHelper : public AllStatic { | 34 class TimelineTestHelper : public AllStatic { |
19 public: | 35 public: |
20 static void SetStream(TimelineEvent* event, TimelineStream* stream) { | 36 static void SetStream(TimelineEvent* event, TimelineStream* stream) { |
21 event->StreamInit(stream); | 37 event->StreamInit(stream); |
22 } | 38 } |
23 | 39 |
24 static TimelineEvent* FakeThreadEvent( | 40 static TimelineEvent* FakeThreadEvent( |
25 TimelineEventBlock* block, | 41 TimelineEventBlock* block, |
26 intptr_t ftid, | 42 intptr_t ftid, |
27 const char* label = "fake", | 43 const char* label = "fake", |
(...skipping 18 matching lines...) Expand all Loading... |
46 ASSERT(label != NULL); | 62 ASSERT(label != NULL); |
47 TimelineEvent* event = recorder->StartEvent(); | 63 TimelineEvent* event = recorder->StartEvent(); |
48 ASSERT(event != NULL); | 64 ASSERT(event != NULL); |
49 event->Duration(label, start, end); | 65 event->Duration(label, start, end); |
50 } | 66 } |
51 | 67 |
52 static void Clear(TimelineEventEndlessRecorder* recorder) { | 68 static void Clear(TimelineEventEndlessRecorder* recorder) { |
53 ASSERT(recorder != NULL); | 69 ASSERT(recorder != NULL); |
54 recorder->Clear(); | 70 recorder->Clear(); |
55 } | 71 } |
| 72 |
| 73 static void FinishBlock(TimelineEventBlock* block) { |
| 74 block->Finish(); |
| 75 } |
56 }; | 76 }; |
57 | 77 |
58 | 78 |
59 TEST_CASE(TimelineEventIsValid) { | 79 TEST_CASE(TimelineEventIsValid) { |
60 // Create a test stream. | 80 // Create a test stream. |
61 TimelineStream stream; | 81 TimelineStream stream; |
62 stream.Init("testStream", true); | 82 stream.Init("testStream", true); |
63 | 83 |
64 TimelineEvent event; | 84 TimelineEvent event; |
65 TimelineTestHelper::SetStream(&event, &stream); | 85 TimelineTestHelper::SetStream(&event, &stream); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 event.PrintJSON(&js); | 185 event.PrintJSON(&js); |
166 | 186 |
167 // Check both arguments. | 187 // Check both arguments. |
168 EXPECT_SUBSTRING("\"arg1\":\"value1\"", js.ToCString()); | 188 EXPECT_SUBSTRING("\"arg1\":\"value1\"", js.ToCString()); |
169 EXPECT_SUBSTRING("\"arg2\":\"value2\"", js.ToCString()); | 189 EXPECT_SUBSTRING("\"arg2\":\"value2\"", js.ToCString()); |
170 } | 190 } |
171 } | 191 } |
172 | 192 |
173 | 193 |
174 TEST_CASE(TimelineEventBufferPrintJSON) { | 194 TEST_CASE(TimelineEventBufferPrintJSON) { |
175 Isolate* isolate = Isolate::Current(); | 195 TimelineEventRecorder* recorder = Timeline::recorder(); |
176 TimelineEventRecorder* recorder = isolate->timeline_event_recorder(); | |
177 JSONStream js; | 196 JSONStream js; |
178 recorder->PrintJSON(&js); | 197 TimelineEventFilter filter; |
| 198 recorder->PrintJSON(&js, &filter); |
179 // Check the type. This test will fail if we ever make Timeline public. | 199 // Check the type. This test will fail if we ever make Timeline public. |
180 EXPECT_SUBSTRING("\"type\":\"_Timeline\"", js.ToCString()); | 200 EXPECT_SUBSTRING("\"type\":\"_Timeline\"", js.ToCString()); |
181 // Check that there is a traceEvents array. | 201 // Check that there is a traceEvents array. |
182 EXPECT_SUBSTRING("\"traceEvents\":[", js.ToCString()); | 202 EXPECT_SUBSTRING("\"traceEvents\":[", js.ToCString()); |
183 } | 203 } |
184 | 204 |
185 | 205 |
186 // Count the number of each event type seen. | 206 // Count the number of each event type seen. |
187 class EventCounterRecorder : public TimelineEventStreamingRecorder { | 207 class EventCounterRecorder : public TimelineEventStreamingRecorder { |
188 public: | 208 public: |
(...skipping 11 matching lines...) Expand all Loading... |
200 return counts_[type]; | 220 return counts_[type]; |
201 } | 221 } |
202 | 222 |
203 private: | 223 private: |
204 intptr_t counts_[TimelineEvent::kNumEventTypes]; | 224 intptr_t counts_[TimelineEvent::kNumEventTypes]; |
205 }; | 225 }; |
206 | 226 |
207 | 227 |
208 TEST_CASE(TimelineEventStreamingRecorderBasic) { | 228 TEST_CASE(TimelineEventStreamingRecorderBasic) { |
209 EventCounterRecorder* recorder = new EventCounterRecorder(); | 229 EventCounterRecorder* recorder = new EventCounterRecorder(); |
| 230 TimelineRecorderOverride override(recorder); |
210 | 231 |
211 // Initial counts are all zero. | 232 // Initial counts are all zero. |
212 for (intptr_t i = TimelineEvent::kNone + 1; | 233 for (intptr_t i = TimelineEvent::kNone + 1; |
213 i < TimelineEvent::kNumEventTypes; | 234 i < TimelineEvent::kNumEventTypes; |
214 i++) { | 235 i++) { |
215 EXPECT_EQ(0, recorder->CountFor(static_cast<TimelineEvent::EventType>(i))); | 236 EXPECT_EQ(0, recorder->CountFor(static_cast<TimelineEvent::EventType>(i))); |
216 } | 237 } |
217 | 238 |
218 // Create a test stream. | 239 // Create a test stream. |
219 TimelineStream stream; | 240 TimelineStream stream; |
220 stream.Init("testStream", true); | 241 stream.Init("testStream", true); |
221 stream.set_recorder(recorder); | |
222 | 242 |
223 TimelineEvent* event = NULL; | 243 TimelineEvent* event = NULL; |
224 | 244 |
225 event = stream.StartEvent(); | 245 event = stream.StartEvent(); |
226 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); | 246 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); |
227 event->DurationBegin("cabbage"); | 247 event->DurationBegin("cabbage"); |
228 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); | 248 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); |
229 event->DurationEnd(); | 249 event->DurationEnd(); |
230 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); | 250 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); |
231 event->Complete(); | 251 event->Complete(); |
232 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kDuration)); | 252 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kDuration)); |
233 | 253 |
234 event = stream.StartEvent(); | 254 event = stream.StartEvent(); |
235 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); | 255 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); |
236 event->Instant("instantCabbage"); | 256 event->Instant("instantCabbage"); |
237 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); | 257 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); |
238 event->Complete(); | 258 event->Complete(); |
239 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kInstant)); | 259 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kInstant)); |
240 | 260 |
241 event = stream.StartEvent(); | 261 event = stream.StartEvent(); |
242 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); | 262 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); |
243 int64_t async_id = event->AsyncBegin("asyncBeginCabbage"); | 263 int64_t async_id = recorder->GetNextAsyncId(); |
244 EXPECT(async_id >= 0); | 264 EXPECT(async_id >= 0); |
| 265 event->AsyncBegin("asyncBeginCabbage", async_id); |
245 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); | 266 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); |
246 event->Complete(); | 267 event->Complete(); |
247 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncBegin)); | 268 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncBegin)); |
248 | 269 |
249 event = stream.StartEvent(); | 270 event = stream.StartEvent(); |
250 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); | 271 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); |
251 event->AsyncInstant("asyncInstantCabbage", async_id); | 272 event->AsyncInstant("asyncInstantCabbage", async_id); |
252 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); | 273 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); |
253 event->Complete(); | 274 event->Complete(); |
254 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncInstant)); | 275 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncInstant)); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 EXPECT(block_1 != NULL); | 414 EXPECT(block_1 != NULL); |
394 // Test that we wrapped. | 415 // Test that we wrapped. |
395 EXPECT(block_0 == recorder->GetNewBlock()); | 416 EXPECT(block_0 == recorder->GetNewBlock()); |
396 | 417 |
397 // Emit the earlier event into block_1. | 418 // Emit the earlier event into block_1. |
398 TimelineTestHelper::FakeThreadEvent(block_1, 2, "Alpha", &stream); | 419 TimelineTestHelper::FakeThreadEvent(block_1, 2, "Alpha", &stream); |
399 OS::Sleep(1); | 420 OS::Sleep(1); |
400 // Emit the later event into block_0. | 421 // Emit the later event into block_0. |
401 TimelineTestHelper::FakeThreadEvent(block_0, 2, "Beta", &stream); | 422 TimelineTestHelper::FakeThreadEvent(block_0, 2, "Beta", &stream); |
402 | 423 |
| 424 TimelineTestHelper::FinishBlock(block_0); |
| 425 TimelineTestHelper::FinishBlock(block_1); |
| 426 |
403 JSONStream js; | 427 JSONStream js; |
404 recorder->PrintJSON(&js); | 428 TimelineEventFilter filter; |
| 429 recorder->PrintJSON(&js, &filter); |
405 // trace-event has a requirement that events for a thread must have | 430 // trace-event has a requirement that events for a thread must have |
406 // monotonically increasing timestamps. | 431 // monotonically increasing timestamps. |
407 // Verify that "Alpha" comes before "Beta" even though "Beta" is in the first | 432 // Verify that "Alpha" comes before "Beta" even though "Beta" is in the first |
408 // block. | 433 // block. |
409 const char* alpha = strstr(js.ToCString(), "Alpha"); | 434 const char* alpha = strstr(js.ToCString(), "Alpha"); |
410 const char* beta = strstr(js.ToCString(), "Beta"); | 435 const char* beta = strstr(js.ToCString(), "Beta"); |
411 EXPECT(alpha < beta); | 436 EXPECT(alpha < beta); |
412 } | 437 } |
413 | 438 |
414 | 439 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 EXPECT(!pauses.has_error()); | 601 EXPECT(!pauses.has_error()); |
577 EXPECT_EQ(10, pauses.InclusiveTime("a")); | 602 EXPECT_EQ(10, pauses.InclusiveTime("a")); |
578 EXPECT_EQ(10, pauses.ExclusiveTime("a")); | 603 EXPECT_EQ(10, pauses.ExclusiveTime("a")); |
579 EXPECT_EQ(10, pauses.MaxInclusiveTime("a")); | 604 EXPECT_EQ(10, pauses.MaxInclusiveTime("a")); |
580 EXPECT_EQ(8, pauses.MaxExclusiveTime("a")); | 605 EXPECT_EQ(8, pauses.MaxExclusiveTime("a")); |
581 } | 606 } |
582 TimelineTestHelper::Clear(recorder); | 607 TimelineTestHelper::Clear(recorder); |
583 } | 608 } |
584 | 609 |
585 } // namespace dart | 610 } // namespace dart |
OLD | NEW |