Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
timeline_test.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include <cstring>
6#include <memory>
7
8#include "platform/assert.h"
9
10#include "vm/dart_api_impl.h"
11#include "vm/dart_api_state.h"
12#include "vm/globals.h"
13#include "vm/timeline.h"
14#include "vm/unit_test.h"
15
16namespace dart {
17
18#ifndef PRODUCT
19
20template <class T>
22 public:
23 TimelineRecorderOverride() : recorder_(Timeline::recorder()) {
24 Timeline::recorder_ = new T();
25 }
26
28 : recorder_(Timeline::recorder()) {
29 Timeline::recorder_ = recorder;
30 }
31
33 Timeline::Clear();
34 delete Timeline::recorder_;
35 Timeline::recorder_ = recorder_;
36 }
37
38 T* recorder() { return static_cast<T*>(Timeline::recorder()); }
39
40 private:
41 TimelineEventRecorder* recorder_;
42};
43
45 public:
46 static void SetStream(TimelineEvent* event, TimelineStream* stream) {
47 event->StreamInit(stream);
48 }
49
50 static Mutex& GetRecorderLock(TimelineEventRecorder& recorder) {
51 return recorder.lock_;
52 }
53
54 static void FakeThreadEvent(TimelineEventBlock* block,
55 intptr_t ftid,
56 const char* label = "fake",
57 TimelineStream* stream = nullptr) {
58 OSThread& current_thread = *OSThread::Current();
59 MutexLocker ml(current_thread.timeline_block_lock());
60 TimelineEvent* event = block->StartEventLocked();
61 ASSERT(event != nullptr);
62 event->DurationBegin(label);
63 event->thread_ = OSThread::ThreadIdFromIntPtr(ftid);
64 if (stream != nullptr) {
65 event->StreamInit(stream);
66 }
67 }
68
69 static void FakeDuration(TimelineEventRecorder* recorder,
70 const char* label,
71 int64_t start,
72 int64_t end) {
73 ASSERT(recorder != nullptr);
74 ASSERT(start < end);
75 ASSERT(label != nullptr);
76 TimelineEvent* event = recorder->StartEvent();
77 ASSERT(event != nullptr);
78 event->Duration(label, start, end);
79 recorder->CompleteEvent(event);
80 }
81
82 static void FakeBegin(TimelineEventRecorder* recorder,
83 const char* label,
84 int64_t start) {
85 ASSERT(recorder != nullptr);
86 ASSERT(label != nullptr);
87 ASSERT(start >= 0);
88 TimelineEvent* event = recorder->StartEvent();
89 ASSERT(event != nullptr);
90 event->Begin(label, /*id=*/-1, start);
91 recorder->CompleteEvent(event);
92 }
93
94 static void FakeEnd(TimelineEventRecorder* recorder,
95 const char* label,
96 int64_t end) {
97 ASSERT(recorder != nullptr);
98 ASSERT(label != nullptr);
99 ASSERT(end >= 0);
100 TimelineEvent* event = recorder->StartEvent();
101 ASSERT(event != nullptr);
102 event->End(label, end);
103 recorder->CompleteEvent(event);
104 }
105
106 static void FinishBlock(TimelineEventBlock* block) { block->Finish(); }
107};
108
109TEST_CASE(TimelineEventIsValid) {
110 // Create a test stream.
111 TimelineStream stream("testStream", "testStream", false, true);
112
113 TimelineEvent event;
115
116 // Starts invalid.
117 EXPECT(!event.IsValid());
118
119 // Becomes valid.
120 event.Instant("hello");
121 EXPECT(event.IsValid());
122
123 // Becomes invalid.
124 event.Reset();
125 EXPECT(!event.IsValid());
126}
127
128TEST_CASE(TimelineEventDuration) {
129 // Create a test stream.
130 TimelineStream stream("testStream", "testStream", false, true);
131
132 // Create a test event.
133 TimelineEvent event;
135 event.DurationBegin("apple");
136 // Measure the duration.
137 int64_t current_duration = event.TimeDuration();
138 event.SetTimeEnd();
139 // Verify that duration is larger.
140 EXPECT_GE(event.TimeDuration(), current_duration);
141}
142
143TEST_CASE(TimelineEventDurationPrintJSON) {
144 // Create a test stream.
145 TimelineStream stream("testStream", "testStream", false, true);
146
147 // Create a test event.
148 TimelineEvent event;
150 event.DurationBegin("apple");
151 {
152 // Test printing to JSON.
153 JSONStream js;
154 event.PrintJSON(&js);
155 // Check category
156 EXPECT_SUBSTRING("\"cat\":\"testStream\"", js.ToCString());
157 // Check name.
158 EXPECT_SUBSTRING("\"name\":\"apple\"", js.ToCString());
159 // Check phase.
160 EXPECT_SUBSTRING("\"ph\":\"X\"", js.ToCString());
161 // Check that ts key is present.
162 EXPECT_SUBSTRING("\"ts\":", js.ToCString());
163 // Check that dur key is present.
164 EXPECT_SUBSTRING("\"dur\":", js.ToCString());
165 }
166 event.SetTimeEnd();
167}
168
169#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX)
170TEST_CASE(TimelineEventPrintSystrace) {
171 const intptr_t kBufferLength = 1024;
172 char buffer[kBufferLength];
173
174 // Create a test stream.
175 TimelineStream stream("testStream", "testStream", false, true);
176
177 // Create a test event.
178 TimelineEvent event;
180
181 // Test a Begin event.
182 event.Begin("apple", 1, 2);
183 TimelineEventSystraceRecorder::PrintSystrace(&event, &buffer[0],
184 kBufferLength);
185 EXPECT_SUBSTRING("|apple", buffer);
186 EXPECT_SUBSTRING("B|", buffer);
187
188 // Test an End event.
189 event.End("apple", 2, 3);
190 TimelineEventSystraceRecorder::PrintSystrace(&event, &buffer[0],
191 kBufferLength);
192 EXPECT_STREQ("E", buffer);
193
194 // Test a Counter event. We only report the first counter value (in this case
195 // "4").
196 event.Counter("CTR", 1);
197 // We have two counters.
198 event.SetNumArguments(2);
199 // Set the first counter value.
200 event.CopyArgument(0, "cats", "4");
201 // Set the second counter value.
202 event.CopyArgument(1, "dogs", "1");
203 TimelineEventSystraceRecorder::PrintSystrace(&event, &buffer[0],
204 kBufferLength);
205 EXPECT_SUBSTRING("C|", buffer);
206 EXPECT_SUBSTRING("|CTR|4", buffer);
207
208 // Test a duration event. This event kind is not supported so we should
209 // serialize it to an empty string.
210 event.Duration("DUR", 0, 1);
211 TimelineEventSystraceRecorder::PrintSystrace(&event, &buffer[0],
212 kBufferLength);
213 EXPECT_STREQ("", buffer);
214}
215#endif // defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX)
216
217TEST_CASE(TimelineEventArguments) {
218 // Create a test stream.
219 TimelineStream stream("testStream", "testStream", false, true);
220
221 // Create a test event.
222 TimelineEvent event;
224
225 // Allocate room for four arguments.
226 event.SetNumArguments(4);
227 // Reset.
228 event.Reset();
229
230 event.DurationBegin("apple");
231 event.SetNumArguments(2);
232 event.CopyArgument(0, "arg1", "value1");
233 event.CopyArgument(1, "arg2", "value2");
234 event.SetTimeEnd();
235}
236
237TEST_CASE(TimelineEventArgumentsPrintJSON) {
238 // Create a test stream.
239 TimelineStream stream("testStream", "testStream", false, true);
240
241 // Create a test event.
242 TimelineEvent event;
244
245 event.DurationBegin("apple");
246 event.SetNumArguments(2);
247 event.CopyArgument(0, "arg1", "value1");
248 event.CopyArgument(1, "arg2", "value2");
249 event.SetTimeEnd();
250
251 {
252 // Test printing to JSON.
253 JSONStream js;
254 event.PrintJSON(&js);
255
256 // Check both arguments.
257 EXPECT_SUBSTRING("\"arg1\":\"value1\"", js.ToCString());
258 EXPECT_SUBSTRING("\"arg2\":\"value2\"", js.ToCString());
259 }
260}
261
262TEST_CASE(TimelineEventBufferPrintJSON) {
263 JSONStream js;
264 TimelineEventFilter filter;
265 Timeline::recorder()->PrintJSON(&js, &filter);
266 // Check the type.
267 EXPECT_SUBSTRING("\"type\":\"Timeline\"", js.ToCString());
268 // Check that there is a traceEvents array.
269 EXPECT_SUBSTRING("\"traceEvents\":[", js.ToCString());
270}
271
272// Count the number of each event type seen.
273class EventCounterRecorder : public TimelineEventCallbackRecorder {
274 public:
276 for (intptr_t i = 0; i < TimelineEvent::kNumEventTypes; i++) {
277 counts_[i] = 0;
278 }
279 }
280
281 void OnEvent(TimelineEvent* event) { counts_[event->event_type()]++; }
282
283 intptr_t CountFor(TimelineEvent::EventType type) { return counts_[type]; }
284
285 private:
286 intptr_t counts_[TimelineEvent::kNumEventTypes];
287};
288
289TEST_CASE(TimelineEventCallbackRecorderBasic) {
291
292 // Initial counts are all zero.
293 for (intptr_t i = TimelineEvent::kNone + 1; i < TimelineEvent::kNumEventTypes;
294 i++) {
295 EXPECT_EQ(0, override.recorder()->CountFor(
296 static_cast<TimelineEvent::EventType>(i)));
297 }
298
299 // Create a test stream.
300 TimelineStream stream("testStream", "testStream", false, true);
301
302 TimelineEvent* event = nullptr;
303
304 event = stream.StartEvent();
305 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kDuration));
306 event->DurationBegin("cabbage");
307 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kDuration));
308 event->SetTimeEnd();
309 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kDuration));
310 event->Complete();
311 EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kDuration));
312
313 event = stream.StartEvent();
314 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kInstant));
315 event->Instant("instantCabbage");
316 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kInstant));
317 event->Complete();
318 EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kInstant));
319
320 event = stream.StartEvent();
321 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
322 int64_t async_id = thread->GetNextTaskId();
323 EXPECT(async_id != 0);
324 event->AsyncBegin("asyncBeginCabbage", async_id);
325 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
326 event->Complete();
327 EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
328
329 event = stream.StartEvent();
330 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncInstant));
331 event->AsyncInstant("asyncInstantCabbage", async_id);
332 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncInstant));
333 event->Complete();
334 EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kAsyncInstant));
335
336 event = stream.StartEvent();
337 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncEnd));
338 event->AsyncEnd("asyncEndCabbage", async_id);
339 EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncEnd));
340 event->Complete();
341 EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kAsyncEnd));
342}
343
344TEST_CASE(TimelineRingRecorderJSONOrder) {
345 TimelineStream stream("testStream", "testStream", false, true);
346
347 TimelineEventRingRecorder* recorder =
348 new TimelineEventRingRecorder(TimelineEventBlock::kBlockSize * 2);
350
351 {
352 Mutex& recorder_lock = TimelineTestHelper::GetRecorderLock(*recorder);
353 MutexLocker ml(&recorder_lock);
354 TimelineEventBlock* block_0 = Timeline::recorder()->GetNewBlockLocked();
355 EXPECT(block_0 != nullptr);
356 TimelineEventBlock* block_1 = Timeline::recorder()->GetNewBlockLocked();
357 EXPECT(block_1 != nullptr);
358 // Test that we wrapped.
359 EXPECT(block_0 == Timeline::recorder()->GetNewBlockLocked());
360
361 // Emit the earlier event into block_1.
362 TimelineTestHelper::FakeThreadEvent(block_1, 2, "Alpha", &stream);
363 OS::Sleep(32);
364 // Emit the later event into block_0.
365 TimelineTestHelper::FakeThreadEvent(block_0, 2, "Beta", &stream);
366
369 }
370
371 JSONStream js;
372 TimelineEventFilter filter;
373 Timeline::recorder()->PrintJSON(&js, &filter);
374 // trace-event has a requirement that events for a thread must have
375 // monotonically increasing timestamps.
376 // Verify that "Alpha" comes before "Beta" even though "Beta" is in the first
377 // block.
378 const char* alpha = strstr(js.ToCString(), "Alpha");
379 const char* beta = strstr(js.ToCString(), "Beta");
380 EXPECT(alpha < beta);
381}
382
383TEST_CASE(TimelineRingRecorderRace) {
384 struct ReportEventsArguments {
385 Monitor& synchronization_monitor;
386 TimelineEventRecorder& recorder;
387 ThreadJoinId join_id = OSThread::kInvalidThreadJoinId;
388 };
389
390 // Note that |recorder| will be freed by |TimelineRecorderOverride|'s
391 // destructor.
392 TimelineEventRingRecorder& recorder =
393 *(new TimelineEventRingRecorder(2 * TimelineEventBlock::kBlockSize));
395 Monitor synchronization_monitor;
396 JSONStream js;
397 TimelineEventFilter filter;
398 ReportEventsArguments report_events_1_arguments{synchronization_monitor,
399 recorder};
400 ReportEventsArguments report_events_2_arguments{synchronization_monitor,
401 recorder};
402
403 // Try concurrently writing events, serializing them, and clearing the
404 // timeline. It is not possible to assert anything about the outcome, because
405 // of scheduling uncertainty. This test is just used to ensure that TSAN
406 // checks the ring recorder code.
408 "ReportEvents1",
409 [](uword arguments_ptr) {
410 ReportEventsArguments& arguments =
411 *reinterpret_cast<ReportEventsArguments*>(arguments_ptr);
412 for (intptr_t i = 0; i < 2 * TimelineEventBlock::kBlockSize; ++i) {
413 TimelineTestHelper::FakeDuration(&arguments.recorder, "testEvent",
414 /*start=*/0, /*end=*/1);
415 }
416 MonitorLocker ml(&arguments.synchronization_monitor);
417 arguments.join_id =
419 ml.Notify();
420 },
421 reinterpret_cast<uword>(&report_events_1_arguments));
423 "ReportEvents2",
424 [](uword arguments_ptr) {
425 ReportEventsArguments& arguments =
426 *reinterpret_cast<ReportEventsArguments*>(arguments_ptr);
427 for (intptr_t i = 0; i < 2 * TimelineEventBlock::kBlockSize; ++i) {
428 TimelineTestHelper::FakeDuration(&arguments.recorder, "testEvent",
429 /*start=*/0, /*end=*/1);
430 }
431 MonitorLocker ml(&arguments.synchronization_monitor);
432 arguments.join_id =
434 ml.Notify();
435 },
436 reinterpret_cast<uword>(&report_events_2_arguments));
437 Timeline::Clear();
438 recorder.PrintJSON(&js, &filter);
439
440 MonitorLocker ml(&synchronization_monitor);
441 while (report_events_1_arguments.join_id == OSThread::kInvalidThreadJoinId ||
442 report_events_2_arguments.join_id == OSThread::kInvalidThreadJoinId) {
443 ml.Wait();
444 }
445 OSThread::Join(report_events_1_arguments.join_id);
446 OSThread::Join(report_events_2_arguments.join_id);
447}
448
449// |OSThread::Start()| takes in a function pointer, and only lambdas that don't
450// capture can be converted to function pointers. So, we use these macros to
451// avoid needing to capture.
452#define FAKE_PROCESS_ID 1
453#define FAKE_TRACE_ID 1
454
455TEST_CASE(TimelineTrackMetadataRace) {
456 struct ReportMetadataArguments {
457 Monitor& synchronization_monitor;
458 TimelineEventRecorder& recorder;
459 ThreadJoinId join_id = OSThread::kInvalidThreadJoinId;
460 };
461
462 Monitor synchronization_monitor;
463 TimelineEventRecorder& recorder = *Timeline::recorder();
464
465 // Try concurrently reading from / writing to the metadata map. It is not
466 // possible to assert anything about the outcome, because of scheduling
467 // uncertainty. This test is just used to ensure that TSAN checks the metadata
468 // map code.
469 JSONStream js;
470 TimelineEventFilter filter;
471 ReportMetadataArguments report_metadata_1_arguments{synchronization_monitor,
472 recorder};
473 ReportMetadataArguments report_metadata_2_arguments{synchronization_monitor,
474 recorder};
476 "ReportMetadata1",
477 [](uword arguments_ptr) {
478 ReportMetadataArguments& arguments =
479 *reinterpret_cast<ReportMetadataArguments*>(arguments_ptr);
480 arguments.recorder.AddTrackMetadataBasedOnThread(
481 FAKE_PROCESS_ID, FAKE_TRACE_ID, "Thread 1");
482 MonitorLocker ml(&arguments.synchronization_monitor);
483 arguments.join_id =
485 ml.Notify();
486 },
487 reinterpret_cast<uword>(&report_metadata_1_arguments));
489 "ReportMetadata2",
490 [](uword arguments_ptr) {
491 ReportMetadataArguments& arguments =
492 *reinterpret_cast<ReportMetadataArguments*>(arguments_ptr);
493 arguments.recorder.AddTrackMetadataBasedOnThread(
494 FAKE_PROCESS_ID, FAKE_TRACE_ID, "Incorrect Name");
495 MonitorLocker ml(&arguments.synchronization_monitor);
496 arguments.join_id =
498 ml.Notify();
499 },
500 reinterpret_cast<uword>(&report_metadata_2_arguments));
501 recorder.PrintJSON(&js, &filter);
502 MonitorLocker ml(&synchronization_monitor);
503 while (
504 report_metadata_1_arguments.join_id == OSThread::kInvalidThreadJoinId ||
505 report_metadata_2_arguments.join_id == OSThread::kInvalidThreadJoinId) {
506 ml.Wait();
507 }
508 OSThread::Join(report_metadata_1_arguments.join_id);
509 OSThread::Join(report_metadata_2_arguments.join_id);
510}
511
512#undef FAKE_PROCESS_ID
513#undef FAKE_TRACE_ID
514
515#endif // !PRODUCT
516
517#if defined(SUPPORT_TIMELINE)
518
519static Dart_Port expected_isolate;
520static Dart_IsolateGroupId expected_isolate_group;
521static bool saw_begin;
522static bool saw_end;
523static void* expected_isolate_data;
524static void* expected_isolate_group_data;
525
526static void TestTimelineRecorderCallback(Dart_TimelineRecorderEvent* event) {
528
529 if ((event->type == Dart_Timeline_Event_Begin) &&
530 (strcmp(event->label, "TestEvent") == 0)) {
531 saw_begin = true;
532 EXPECT_NE(0, event->timestamp0);
533 EXPECT_EQ(expected_isolate, event->isolate);
534 EXPECT_EQ(expected_isolate_group, event->isolate_group);
535 EXPECT_EQ(expected_isolate_data, event->isolate_data);
536 EXPECT_EQ(expected_isolate_group_data, event->isolate_group_data);
537 EXPECT_STREQ("Dart", event->stream);
538 EXPECT_EQ(1, event->argument_count);
539 EXPECT_STREQ("Dart Arguments", event->arguments[0].name);
540 EXPECT_STREQ("{\"key\":\"value\"}", event->arguments[0].value);
541 }
542
543 if ((event->type == Dart_Timeline_Event_End) &&
544 (strcmp(event->label, "TestEvent") == 0)) {
545 saw_end = true;
546 EXPECT_NE(0, event->timestamp0);
547 EXPECT_EQ(expected_isolate, event->isolate);
548 EXPECT_EQ(expected_isolate_group, event->isolate_group);
549 EXPECT_EQ(expected_isolate_data, event->isolate_data);
550 EXPECT_EQ(expected_isolate_group_data, event->isolate_group_data);
551 EXPECT_STREQ("Dart", event->stream);
552 EXPECT_EQ(1, event->argument_count);
553 EXPECT_STREQ("Dart Arguments", event->arguments[0].name);
554 EXPECT_STREQ("{\"key\":\"value\"}", event->arguments[0].value);
555 }
556}
557
558UNIT_TEST_CASE(DartAPI_SetTimelineRecorderCallback) {
559 int argc = TesterState::argc + 2;
560 const char** argv = new const char*[argc];
561 for (intptr_t i = 0; i < argc - 2; i++) {
562 argv[i] = TesterState::argv[i];
563 }
564 argv[argc - 2] = "--timeline_recorder=callback";
565 argv[argc - 1] = "--timeline_streams=Dart";
566
567 Dart_SetTimelineRecorderCallback(TestTimelineRecorderCallback);
568
569 EXPECT(Dart_SetVMFlags(argc, argv) == nullptr);
571 memset(&params, 0, sizeof(Dart_InitializeParams));
573 params.vm_snapshot_data = TesterState::vm_snapshot_data;
575 params.shutdown_isolate = TesterState::shutdown_callback;
577 params.start_kernel_isolate = true;
578
579 int64_t isolate_data = 0;
580
581 EXPECT(Dart_Initialize(&params) == nullptr);
582 {
583 // Note: run_vm_tests will create and attach an instance of
584 // bin::IsolateGroupData to the newly created isolate group.
585 TestIsolateScope scope(/*isolate_group_data=*/nullptr, &isolate_data);
586 const char* kScriptChars =
587 "import 'dart:developer';\n"
588 "main() {\n"
589 " Timeline.startSync('TestEvent', arguments: {'key':'value'});\n"
590 " Timeline.finishSync();\n"
591 "}\n";
592 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, nullptr);
593 EXPECT_VALID(lib);
594
595 expected_isolate = Dart_GetMainPortId();
596 EXPECT_NE(ILLEGAL_PORT, expected_isolate);
597 expected_isolate_group = Dart_CurrentIsolateGroupId();
598 EXPECT_NE(ILLEGAL_PORT, expected_isolate_group);
599 expected_isolate_data = &isolate_data;
600 EXPECT_EQ(expected_isolate_data, Dart_CurrentIsolateData());
601 expected_isolate_group_data = Dart_CurrentIsolateGroupData();
602 saw_begin = false;
603 saw_end = false;
604
605 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, nullptr);
607
608 EXPECT(saw_begin);
609 EXPECT(saw_end);
610 }
611 EXPECT(Dart_Cleanup() == nullptr);
612
614
615 delete[] argv;
616}
617
618#endif // defined(SUPPORT_TIMELINE)
619
620} // namespace dart
#define EXPECT(type, expectedAlignment, expectedSize)
intptr_t CountFor(TimelineEvent::EventType type)
void OnEvent(TimelineEvent *event)
Monitor::WaitResult Wait(int64_t millis=Monitor::kNoTimeout)
Definition lockers.h:172
static int Start(const char *name, ThreadStartFunction function, uword parameter)
static ThreadId ThreadIdFromIntPtr(intptr_t id)
static void Join(ThreadJoinId id)
static OSThread * Current()
Definition os_thread.h:175
static ThreadJoinId GetCurrentThreadJoinId(OSThread *thread)
Mutex * timeline_block_lock() const
Definition os_thread.h:112
static const ThreadJoinId kInvalidThreadJoinId
Definition os_thread.h:245
static void Sleep(int64_t millis)
static Dart_Handle LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri=RESOLVED_USER_TEST_URI, bool finalize=true, bool allow_compile_errors=false)
Definition unit_test.cc:422
static Dart_IsolateShutdownCallback shutdown_callback
Definition unit_test.h:257
static Dart_IsolateGroupCreateCallback create_callback
Definition unit_test.h:256
static const char ** argv
Definition unit_test.h:259
static Dart_IsolateGroupCleanupCallback group_cleanup_callback
Definition unit_test.h:258
static int argc
Definition unit_test.h:260
static const uint8_t * vm_snapshot_data
Definition unit_test.h:255
static void FakeThreadEvent(TimelineEventBlock *block, intptr_t ftid, const char *label="fake", TimelineStream *stream=nullptr)
static void FinishBlock(TimelineEventBlock *block)
static void FakeBegin(TimelineEventRecorder *recorder, const char *label, int64_t start)
static Mutex & GetRecorderLock(TimelineEventRecorder &recorder)
static void SetStream(TimelineEvent *event, TimelineStream *stream)
static void FakeDuration(TimelineEventRecorder *recorder, const char *label, int64_t start, int64_t end)
static void FakeEnd(TimelineEventRecorder *recorder, const char *label, int64_t end)
#define UNIT_TEST_CASE(name)
Definition unit_test.h:23
#define DART_INITIALIZE_PARAMS_CURRENT_VERSION
Definition dart_api.h:839
#define ILLEGAL_PORT
Definition dart_api.h:1530
int64_t Dart_Port
Definition dart_api.h:1524
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
int64_t Dart_IsolateGroupId
Definition dart_api.h:1208
#define DART_TIMELINE_RECORDER_CURRENT_VERSION
@ Dart_Timeline_Event_Begin
@ Dart_Timeline_Event_End
const EmbeddedViewParams * params
#define ASSERT(E)
glong glong end
FlKeyEvent * event
static const uint8_t buffer[]
GAsyncResult * result
char ** argv
Definition library.h:9
DART_EXPORT Dart_Port Dart_GetMainPortId()
DART_EXPORT Dart_IsolateGroupId Dart_CurrentIsolateGroupId()
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
pthread_t ThreadJoinId
DART_EXPORT char * Dart_Initialize(Dart_InitializeParams *params)
uintptr_t uword
Definition globals.h:501
DART_EXPORT char * Dart_Cleanup()
DART_EXPORT void Dart_SetTimelineRecorderCallback(Dart_TimelineRecorderCallback callback)
Dart_Handle NewString(const char *str)
DART_EXPORT void * Dart_CurrentIsolateGroupData()
DART_EXPORT char * Dart_SetVMFlags(int argc, const char **argv)
DART_EXPORT void * Dart_CurrentIsolateData()
#define T
#define FAKE_TRACE_ID
#define FAKE_PROCESS_ID
#define TEST_CASE(name)
Definition unit_test.h:85
#define EXPECT_VALID(handle)
Definition unit_test.h:650