Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
dart_test_component_controller.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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.
4
6
7#include <fcntl.h>
8#include <fuchsia/test/cpp/fidl.h>
9#include <lib/async-loop/loop.h>
10#include <lib/async/cpp/task.h>
11#include <lib/async/default.h>
12#include <lib/fdio/directory.h>
13#include <lib/fdio/fd.h>
14#include <lib/fdio/namespace.h>
15#include <lib/fidl/cpp/string.h>
16#include <lib/fpromise/promise.h>
17#include <lib/sys/cpp/service_directory.h>
18#include <lib/zx/clock.h>
19#include <lib/zx/thread.h>
20#include <sys/stat.h>
21#include <sys/types.h>
22#include <unistd.h>
23#include <zircon/status.h>
24
25#include <regex>
26#include <utility>
27
28#include "flutter/fml/logging.h"
32#include "third_party/dart/runtime/include/dart_tools_api.h"
39
40using tonic::ToDart;
41
42namespace dart_runner {
43
44namespace {
45
46constexpr char kTmpPath[] = "/tmp";
47
48constexpr zx::duration kIdleWaitDuration = zx::sec(2);
49constexpr zx::duration kIdleNotifyDuration = zx::msec(500);
50constexpr zx::duration kIdleSlack = zx::sec(1);
51
52constexpr zx::duration kTestTimeout = zx::sec(60);
53
54void AfterTask(async_loop_t*, void*) {
57 // Verify that the queue exists, as this method could have been called back as
58 // part of the exit routine, after the destruction of the microtask queue.
59 if (queue) {
60 queue->RunMicrotasks();
61 }
62}
63
64constexpr async_loop_config_t kLoopConfig = {
65 .default_accessors =
66 {
67 .getter = async_get_default_dispatcher,
68 .setter = async_set_default_dispatcher,
69 },
70 .make_default_for_current_thread = true,
71 .epilogue = &AfterTask,
72};
73
74// Find the last path of the component.
75// fuchsia-pkg://fuchsia.com/hello_dart#meta/hello_dart.cmx -> hello_dart.cmx
76std::string GetLabelFromUrl(const std::string& url) {
77 for (size_t i = url.length() - 1; i > 0; i--) {
78 if (url[i] == '/') {
79 return url.substr(i + 1, url.length() - 1);
80 }
81 }
82 return url;
83}
84
85// Find the name of the component.
86// fuchsia-pkg://fuchsia.com/hello_dart#meta/hello_dart.cm -> hello_dart
87std::string GetComponentNameFromUrl(const std::string& url) {
88 const std::string label = GetLabelFromUrl(url);
89 for (size_t i = 0; i < label.length(); ++i) {
90 if (label[i] == '.') {
91 return label.substr(0, i);
92 }
93 }
94 return label;
95}
96
97} // namespace
98
100 fuchsia::component::runner::ComponentStartInfo start_info,
101 std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
102 fidl::InterfaceRequest<fuchsia::component::runner::ComponentController>
103 controller,
104 DoneCallback done_callback)
105 : loop_(new async::Loop(&kLoopConfig)),
106 executor_(loop_->dispatcher()),
107 label_(GetLabelFromUrl(start_info.resolved_url())),
108 url_(std::move(start_info.resolved_url())),
109 runner_incoming_services_(runner_incoming_services),
110 start_info_(std::move(start_info)),
111 binding_(this),
112 done_callback_(std::move(done_callback)) {
113 // TODO(fxb/84537): This data path is configured based how we build Flutter
114 // applications in tree currently, but the way we build the Flutter
115 // application may change. We should avoid assuming the data path and let the
116 // CML file specify this data path instead.
117 test_component_name_ = GetComponentNameFromUrl(url_);
118 data_path_ = "pkg/data/" + test_component_name_;
119
120 if (controller.is_valid()) {
121 binding_.Bind(std::move(controller));
122 binding_.set_error_handler([this](zx_status_t status) { Kill(); });
123 } else {
124 FML_LOG(ERROR) << "Fuchsia component controller endpoint is not valid.";
125 }
126
127 zx_status_t idle_timer_status =
128 zx::timer::create(ZX_TIMER_SLACK_LATE, ZX_CLOCK_MONOTONIC, &idle_timer_);
129 if (idle_timer_status != ZX_OK) {
130 FML_LOG(INFO) << "Idle timer creation failed: "
131 << zx_status_get_string(idle_timer_status);
132 } else {
133 idle_wait_.set_object(idle_timer_.get());
134 idle_wait_.set_trigger(ZX_TIMER_SIGNALED);
135 idle_wait_.Begin(async_get_default_dispatcher());
136 }
137
138 // Close the runtime_dir channel if we don't intend to serve it. Otherwise any
139 // access to the runtime_dir will hang forever.
140 start_info_.clear_runtime_dir();
141}
142
144 if (namespace_) {
145 fdio_ns_destroy(namespace_);
146 namespace_ = nullptr;
147 }
148 close(stdout_fd_);
149 close(stderr_fd_);
150}
151
153 // Name the thread after the url of the component being launched.
154 zx::thread::self()->set_property(ZX_PROP_NAME, label_.c_str(), label_.size());
155 Dart_SetThreadName(label_.c_str());
156
157 if (!CreateAndBindNamespace()) {
158 return;
159 }
160
161 if (SetUpFromAppSnapshot()) {
162 FML_LOG(INFO) << url_ << " is running from an app snapshot";
163 } else if (SetUpFromKernel()) {
164 FML_LOG(INFO) << url_ << " is running from kernel";
165 } else {
166 FML_LOG(ERROR) << "Failed to set up component controller for " << url_;
167 return;
168 }
169
170 // Serve |fuchsia::test::Suite| on outgoing directory.
171 suite_context_ = sys::ComponentContext::Create();
172 suite_context_->outgoing()->AddPublicService(this->GetHandler());
173 suite_context_->outgoing()->Serve(
174 std::move(*start_info_.mutable_outgoing_dir()), loop_->dispatcher());
175
176 loop_->Run();
177}
178
179bool DartTestComponentController::CreateAndBindNamespace() {
180 if (!start_info_.has_ns()) {
181 FML_LOG(ERROR) << "Component start info does not have a namespace.";
182 return false;
183 }
184
185 const zx_status_t ns_create_status = fdio_ns_create(&namespace_);
186 if (ns_create_status != ZX_OK) {
187 FML_LOG(ERROR) << "Failed to create namespace: "
188 << zx_status_get_string(ns_create_status);
189 }
190
191 dart_utils::BindTemp(namespace_);
192
193 // Bind each directory in start_info's namespace to the controller's namespace
194 // instance.
195 for (auto& ns_entry : *start_info_.mutable_ns()) {
196 // TODO(akbiggs): Under what circumstances does a namespace entry not
197 // have a path or directory? Should we log an error for these?
198 if (!ns_entry.has_path() || !ns_entry.has_directory()) {
199 continue;
200 }
201
202 if (ns_entry.path() == kTmpPath) {
203 // /tmp is covered by a locally served virtual filesystem.
204 continue;
205 }
206
207 // We move ownership of the directory & path since RAII is used to keep
208 // the handle open.
209 fidl::InterfaceHandle<::fuchsia::io::Directory> dir =
210 std::move(*ns_entry.mutable_directory());
211 const std::string path = std::move(*ns_entry.mutable_path());
212
213 const zx_status_t ns_bind_status =
214 fdio_ns_bind(namespace_, path.c_str(), dir.TakeChannel().release());
215 if (ns_bind_status != ZX_OK) {
216 FML_LOG(ERROR) << "Failed to bind " << path << " to namespace: "
217 << zx_status_get_string(ns_bind_status);
218 return false;
219 }
220 }
221
222 return true;
223}
224
225bool DartTestComponentController::SetUpFromKernel() {
228 namespace_, data_path_ + "/app.dilplist", manifest)) {
229 return false;
230 }
231
233 nullptr, "/pkg/data/isolate_core_snapshot_data.bin",
234 isolate_snapshot_data_)) {
235 return false;
236 }
237
238 std::string str(reinterpret_cast<const char*>(manifest.address()),
239 manifest.size());
240 Dart_Handle library = Dart_Null();
241
242 for (size_t start = 0; start < manifest.size();) {
243 size_t end = str.find("\n", start);
244 if (end == std::string::npos) {
245 FML_LOG(ERROR) << "Malformed manifest";
246 return false;
247 }
248
249 std::string path = data_path_ + "/" + str.substr(start, end - start);
250 start = end + 1;
251
254 kernel)) {
255 FML_LOG(ERROR) << "Cannot load kernel from namespace: " << path;
256 return false;
257 }
258 kernel_peices_.emplace_back(std::move(kernel));
259 }
260
261 if (!CreateIsolate(isolate_snapshot_data_.address(),
262 /*isolate_snapshot_instructions=*/nullptr)) {
263 return false;
264 }
265
266 Dart_EnterScope();
267
268 for (const auto& kernel : kernel_peices_) {
269 library = Dart_LoadLibraryFromKernel(kernel.address(), kernel.size());
270 if (Dart_IsError(library)) {
271 FML_LOG(ERROR) << "Cannot load library from kernel: "
272 << Dart_GetError(library);
273 Dart_ExitScope();
274 return false;
275 }
276 }
277 Dart_SetRootLibrary(library);
278
279 Dart_Handle result = Dart_FinalizeLoading(false);
280 if (Dart_IsError(result)) {
281 FML_LOG(ERROR) << "Failed to FinalizeLoading: " << Dart_GetError(result);
282 Dart_ExitScope();
283 return false;
284 }
285
286 return true;
287}
288
289bool DartTestComponentController::SetUpFromAppSnapshot() {
290#if !defined(AOT_RUNTIME)
291 return false;
292#else
293 // Load the ELF snapshot as available, and fall back to a blobs snapshot
294 // otherwise.
295 const uint8_t *isolate_data, *isolate_instructions;
296 if (elf_snapshot_.Load(namespace_, data_path_ + "/app_aot_snapshot.so")) {
297 isolate_data = elf_snapshot_.IsolateData();
298 isolate_instructions = elf_snapshot_.IsolateInstrs();
299 if (isolate_data == nullptr || isolate_instructions == nullptr) {
300 return false;
301 }
302 } else {
304 namespace_, data_path_ + "/isolate_snapshot_data.bin",
305 isolate_snapshot_data_)) {
306 return false;
307 }
308 isolate_data = isolate_snapshot_data_.address();
309 isolate_instructions = nullptr;
310 }
311 return CreateIsolate(isolate_data, isolate_instructions);
312#endif // defined(AOT_RUNTIME)
313}
314
315bool DartTestComponentController::CreateIsolate(
316 const uint8_t* isolate_snapshot_data,
317 const uint8_t* isolate_snapshot_instructions) {
318 // Create the isolate from the snapshot.
319 char* error = nullptr;
320
321 // TODO(dart_runner): Pass if we start using tonic's loader.
322 intptr_t namespace_fd = -1;
323
324 // Freed in IsolateShutdownCallback.
325 auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState(
326 namespace_fd, [this](Dart_Handle result) { MessageEpilogue(result); }));
327
328 Dart_IsolateFlags isolate_flags;
329 Dart_IsolateFlagsInitialize(&isolate_flags);
330 isolate_flags.null_safety = true;
331
332 isolate_ = Dart_CreateIsolateGroup(
333 url_.c_str(), label_.c_str(), isolate_snapshot_data,
334 isolate_snapshot_instructions, &isolate_flags, state, state, &error);
335 if (!isolate_) {
336 FML_LOG(ERROR) << "Dart_CreateIsolateGroup failed: " << error;
337 return false;
338 }
339
340 state->get()->SetIsolate(isolate_);
341
343 [loop = loop_.get()](auto callback) {
344 async::PostTask(loop->dispatcher(), std::move(callback));
345 };
346 state->get()->message_handler().Initialize(dispatcher);
347
348 state->get()->SetReturnCodeCallback([this](uint32_t return_code) {
349 return_code_ = return_code;
350 auto ret_status = return_code == 0 ? fuchsia::test::Status::PASSED
351 : fuchsia::test::Status::FAILED;
352 fuchsia::test::Result result;
353 result.set_status(ret_status);
354 case_listener_->Finished(std::move(result));
355 });
356
357 return true;
358}
359
360// |fuchsia::test::CaseIterator|
361DartTestComponentController::CaseIterator::CaseIterator(
362 fidl::InterfaceRequest<fuchsia::test::CaseIterator> request,
363 async_dispatcher_t* dispatcher,
364 std::string test_component_name,
365 fit::function<void(CaseIterator*)> done_callback)
366 : binding_(this, std::move(request), dispatcher),
367 test_component_name_(test_component_name),
368 done_callback_(std::move(done_callback)) {}
369
370// |fuchsia::test::CaseIterator|
371void DartTestComponentController::CaseIterator::GetNext(
372 GetNextCallback callback) {
373 // Dart test suites run as multiple tests behind one
374 // test case. Flip flag once the one test case has been retrieved.
375 if (first_case_) {
376 fuchsia::test::Case test_case;
377 test_case.set_name(test_component_name_);
378 test_case.set_enabled(true);
379 std::vector<fuchsia::test::Case> cases;
380 cases.push_back(std::move(test_case));
381 callback(std::move(cases));
382 first_case_ = false;
383 } else {
384 // Return an pass an empty vector to the callback to indicate there
385 // are no more tests to be executed.
386 std::vector<fuchsia::test::Case> cases;
387 callback(std::move(cases));
388 done_callback_(this);
389 }
390}
391
392// |fuchsia::test::CaseIterator|
393std::unique_ptr<DartTestComponentController::CaseIterator>
394DartTestComponentController::RemoveCaseInterator(CaseIterator* case_iterator) {
395 auto it = case_iterators_.find(case_iterator);
396 std::unique_ptr<DartTestComponentController::CaseIterator> case_iterator_ptr;
397 if (it != case_iterators_.end()) {
398 case_iterator_ptr = std::move(it->second);
399 case_iterators_.erase(it);
400 }
401 return case_iterator_ptr;
402}
403
404// |fuchsia::test::Suite|
406 fidl::InterfaceRequest<fuchsia::test::CaseIterator> iterator) {
407 auto case_iterator = std::make_unique<CaseIterator>(
408 std::move(iterator), loop_->dispatcher(), test_component_name_,
409 [this](CaseIterator* case_iterator) {
410 RemoveCaseInterator(case_iterator);
411 });
412 case_iterators_.emplace(case_iterator.get(), std::move(case_iterator));
413}
414
415// |fuchsia::test::Suite|
417 std::vector<fuchsia::test::Invocation> tests,
418 fuchsia::test::RunOptions options,
419 fidl::InterfaceHandle<fuchsia::test::RunListener> listener) {
420 std::vector<std::string> args;
421 if (options.has_arguments()) {
422 args = std::move(*options.mutable_arguments());
423 }
424
425 auto listener_proxy = listener.Bind();
426
427 // We expect 1 test that will run all other tests in the test suite (i.e. a
428 // single main.dart that calls out to all of the dart tests). If the dart
429 // implementation in-tree changes, iterating over the invocations like so
430 // will be able to handle that.
431 for (auto it = tests.begin(); it != tests.end(); it++) {
432 auto invocation = std::move(*it);
433 std::string test_case_name;
434 if (invocation.has_name()) {
435 test_case_name = invocation.name();
436 }
437
438 // Create and out/err sockets and pass file descriptor for each to the
439 // dart process so that logging can be forwarded to the test_manager.
440 auto status = zx::socket::create(0, &out_, &out_client_);
441 if (status != ZX_OK) {
442 FML_LOG(FATAL) << "cannot create out socket: "
443 << zx_status_get_string(status);
444 }
445
446 status = fdio_fd_create(out_.release(), &stdout_fd_);
447 if (status != ZX_OK) {
448 FML_LOG(FATAL) << "failed to extract output fd: "
449 << zx_status_get_string(status);
450 }
451
452 status = zx::socket::create(0, &err_, &err_client_);
453 if (status != ZX_OK) {
454 FML_LOG(FATAL) << "cannot create error socket: "
455 << zx_status_get_string(status);
456 }
457
458 status = fdio_fd_create(err_.release(), &stderr_fd_);
459 if (status != ZX_OK) {
460 FML_LOG(FATAL) << "failed to extract error fd: "
461 << zx_status_get_string(status);
462 }
463
464 // Pass client end of out and err socket for test_manager to stream logs to
465 // current terminal, via |fuchsia::test::StdHandles|.
466 fuchsia::test::StdHandles std_handles;
467 std_handles.set_out(std::move(out_client_));
468 std_handles.set_err(std::move(err_client_));
469
470 listener_proxy->OnTestCaseStarted(std::move(invocation),
471 std::move(std_handles),
472 case_listener_.NewRequest());
473
474 // Run dart main and wait until exit code has been set before notifying of
475 // test completion.
476 auto dart_main_promise = fpromise::make_promise([&] { RunDartMain(); });
477 auto dart_state = tonic::DartState::Current();
478 executor_.schedule_task(std::move(dart_main_promise));
479 while (!dart_state->has_set_return_code()) {
480 loop_->Run(zx::deadline_after(kTestTimeout), true);
481 }
482
483 // Notify the test_manager that the test has completed.
484 listener_proxy->OnFinished();
485 }
486
487 if (binding_.is_bound()) {
488 // From the documentation for ComponentController, ZX_OK should be sent when
489 // the ComponentController receives a termination request. However, if the
490 // component exited with a non-zero return code, we indicate this by sending
491 // an INTERNAL epitaph instead.
492 //
493 // TODO(fxb/86666): Communicate return code from the ComponentController
494 // once v2 has support.
495 if (return_code_ == 0) {
496 binding_.Close(ZX_OK);
497 } else {
498 binding_.Close(zx_status_t(fuchsia::component::Error::INTERNAL));
499 }
500 }
501
502 // Stop and kill the test component.
503 Stop();
504}
505
506fpromise::promise<> DartTestComponentController::RunDartMain() {
507 FML_CHECK(namespace_ != nullptr);
508 Dart_EnterScope();
509
511
512 fidl::InterfaceRequest<fuchsia::io::Directory> outgoing_dir =
513 std::move(*start_info_.mutable_outgoing_dir());
514 InitBuiltinLibrariesForIsolate(url_, namespace_, stdout_fd_, stderr_fd_,
515 outgoing_dir.TakeChannel(),
516 false /* service_isolate */);
517
518 Dart_ExitScope();
519 Dart_ExitIsolate();
520 char* error = Dart_IsolateMakeRunnable(isolate_);
521 if (error != nullptr) {
522 Dart_EnterIsolate(isolate_);
523 Dart_ShutdownIsolate();
524 FML_LOG(ERROR) << "Unable to make isolate runnable: " << error;
525 free(error);
526 return fpromise::make_error_promise();
527 }
528 Dart_EnterIsolate(isolate_);
529 Dart_EnterScope();
530
531 // TODO(fxb/88383): Support argument passing.
532 Dart_Handle corelib = Dart_LookupLibrary(ToDart("dart:core"));
533 Dart_Handle string_type =
534 Dart_GetNonNullableType(corelib, ToDart("String"), 0, NULL);
535 Dart_Handle dart_arguments =
536 Dart_NewListOfTypeFilled(string_type, Dart_EmptyString(), 0);
537
538 if (Dart_IsError(dart_arguments)) {
539 FML_LOG(ERROR) << "Failed to allocate Dart arguments list: "
540 << Dart_GetError(dart_arguments);
541 Dart_ExitScope();
542 return fpromise::make_error_promise();
543 }
544
545 Dart_Handle user_main = Dart_GetField(Dart_RootLibrary(), ToDart("main"));
546
547 if (Dart_IsError(user_main)) {
548 FML_LOG(ERROR) << "Failed to locate user_main in the root library: "
549 << Dart_GetError(user_main);
550 Dart_ExitScope();
551 return fpromise::make_error_promise();
552 }
553
554 Dart_Handle fuchsia_lib = Dart_LookupLibrary(tonic::ToDart("dart:fuchsia"));
555
556 if (Dart_IsError(fuchsia_lib)) {
557 FML_LOG(ERROR) << "Failed to locate dart:fuchsia: "
558 << Dart_GetError(fuchsia_lib);
559 Dart_ExitScope();
560 return fpromise::make_error_promise();
561 }
562
563 Dart_Handle main_result = tonic::DartInvokeField(
564 fuchsia_lib, "_runUserMainForDartRunner", {user_main, dart_arguments});
565
566 if (Dart_IsError(main_result)) {
567 auto dart_state = tonic::DartState::Current();
568 if (!dart_state->has_set_return_code()) {
569 // The program hasn't set a return code meaning this exit is unexpected.
570 FML_LOG(ERROR) << Dart_GetError(main_result);
571 return_code_ = tonic::GetErrorExitCode(main_result);
572
573 dart_utils::HandleIfException(runner_incoming_services_, url_,
574 main_result);
575 }
576 Dart_ExitScope();
577 return fpromise::make_error_promise();
578 }
579
580 Dart_ExitScope();
581 return fpromise::make_ok_promise();
582}
583
584void DartTestComponentController::Kill() {
585 done_callback_(this);
586 close(stdout_fd_);
587 close(stderr_fd_);
588 suite_bindings_.CloseAll();
589 if (Dart_CurrentIsolate()) {
592 if (queue) {
593 queue->Destroy();
594 }
595
596 loop_->Quit();
597
598 // TODO(rosswang): The docs warn of threading issues if doing this again,
599 // but without this, attempting to shut down the isolate finalizes app
600 // contexts that can't tell a shutdown is in progress and so fatal.
601 Dart_SetMessageNotifyCallback(nullptr);
602
603 Dart_ShutdownIsolate();
604 }
605}
606
607void DartTestComponentController::MessageEpilogue(Dart_Handle result) {
608 auto dart_state = tonic::DartState::Current();
609 // If the Dart program has set a return code, then it is intending to shut
610 // down by way of a fatal error, and so there is no need to override
611 // return_code_.
612 if (dart_state->has_set_return_code()) {
613 Dart_ShutdownIsolate();
614 return;
615 }
616
617 dart_utils::HandleIfException(runner_incoming_services_, url_, result);
618
619 // Otherwise, see if there was any other error.
620 return_code_ = tonic::GetErrorExitCode(result);
621 if (return_code_ != 0) {
622 Dart_ShutdownIsolate();
623 return;
624 }
625
626 idle_start_ = zx::clock::get_monotonic();
627 zx_status_t status =
628 idle_timer_.set(idle_start_ + kIdleWaitDuration, kIdleSlack);
629 if (status != ZX_OK) {
630 FML_LOG(INFO) << "Idle timer set failed: " << zx_status_get_string(status);
631 }
632}
633
634void DartTestComponentController::Stop() {
635 Kill();
636}
637
638void DartTestComponentController::OnIdleTimer(async_dispatcher_t* dispatcher,
639 async::WaitBase* wait,
640 zx_status_t status,
641 const zx_packet_signal* signal) {
642 if ((status != ZX_OK) || !(signal->observed & ZX_TIMER_SIGNALED) ||
643 !Dart_CurrentIsolate()) {
644 // Timer closed or isolate shutdown.
645 return;
646 }
647
648 zx::time deadline = idle_start_ + kIdleWaitDuration;
649 zx::time now = zx::clock::get_monotonic();
650 if (now >= deadline) {
651 // No Dart message has been processed for kIdleWaitDuration: assume we'll
652 // stay idle for kIdleNotifyDuration.
653 Dart_NotifyIdle((now + kIdleNotifyDuration).get());
654 idle_start_ = zx::time(0);
655 idle_timer_.cancel(); // De-assert signal.
656 } else {
657 // Early wakeup or message pushed idle time forward: reschedule.
658 zx_status_t status = idle_timer_.set(deadline, kIdleSlack);
659 if (status != ZX_OK) {
660 FML_LOG(INFO) << "Idle timer set failed: "
661 << zx_status_get_string(status);
662 }
663 }
664 wait->Begin(dispatcher); // ignore errors
665}
666
668 uint64_t ordinal,
669 bool method_has_response) {
670 FML_LOG(ERROR) << "Unknown method called on DartTestComponentController. "
671 "Ordinal: "
672 << ordinal;
673}
674
675} // namespace dart_runner
void Run(std::vector< fuchsia::test::Invocation > tests, fuchsia::test::RunOptions options, fidl::InterfaceHandle< fuchsia::test::RunListener > listener) override
|Suite| protocol implementation.
void handle_unknown_method(uint64_t ordinal, bool method_has_response) override
fidl::InterfaceRequestHandler< fuchsia::test::Suite > GetHandler()
void GetTests(fidl::InterfaceRequest< fuchsia::test::CaseIterator > iterator) override
|Suite| protocol implementation.
DartTestComponentController(fuchsia::component::runner::ComponentStartInfo start_info, std::shared_ptr< sys::ServiceDirectory > runner_incoming_services, fidl::InterfaceRequest< fuchsia::component::runner::ComponentController > controller, DoneCallback done_callback)
bool Load(fdio_ns_t *namespc, const std::string &path)
const uint8_t * IsolateData() const
const uint8_t * IsolateInstrs() const
static bool LoadFromNamespace(fdio_ns_t *namespc, const std::string &path, MappedResource &resource, bool executable=false)
const uint8_t * address() const
std::function< void(std::function< void(void)>)> TaskDispatcher
static DartMicrotaskQueue * GetForCurrentThread()
static DartState * Current()
Definition dart_state.cc:56
VkQueue queue
Definition main.cc:71
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
FlutterDesktopBinaryReply callback
#define FML_LOG(severity)
Definition logging.h:101
#define FML_CHECK(condition)
Definition logging.h:104
void InitBuiltinLibrariesForIsolate(const std::string &script_uri, fdio_ns_t *namespc, int stdoutfd, int stderrfd, zx::channel directory_request, bool service_isolate)
void HandleIfException(std::shared_ptr<::sys::ServiceDirectory > services, const std::string &component_url, Dart_Handle result)
void BindTemp(fdio_ns_t *ns)
Definition tempfs.cc:23
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switch_defs.h:52
Definition ref_ptr.h:261
Dart_Handle ToDart(const T &object)
int GetErrorExitCode(Dart_Handle handle)
Definition dart_error.cc:68
Dart_Handle DartInvokeField(Dart_Handle target, const char *name, std::initializer_list< Dart_Handle > args)
fidl::Binding< fuchsia::ui::composition::ChildViewWatcher > binding_
const size_t start
const size_t end