Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
dart_runner::DartTestComponentController Class Reference

#include <dart_test_component_controller.h>

Inheritance diagram for dart_runner::DartTestComponentController:

Public Member Functions

 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)
 
 ~DartTestComponentController () override
 
void SetUp ()
 
void GetTests (fidl::InterfaceRequest< fuchsia::test::CaseIterator > iterator) override
 |Suite| protocol implementation.
 
void Run (std::vector< fuchsia::test::Invocation > tests, fuchsia::test::RunOptions options, fidl::InterfaceHandle< fuchsia::test::RunListener > listener) override
 |Suite| protocol implementation.
 
fidl::InterfaceRequestHandler< fuchsia::test::Suite > GetHandler ()
 
void handle_unknown_method (uint64_t ordinal, bool method_has_response) override
 

Detailed Description

Starts a Dart test component written in CFv2. It's different from DartComponentController in that it must implement the |fuchsia.test.Suite| protocol. It was forked to avoid a naming clash between the two classes' methods as the Suite protocol requires a Run() method for the test_manager to call on. This way, we avoid an extra layer between the test_manager and actual test execution. TODO(fxb/98369): Look into combining the two component classes once dart testing is stable.

Definition at line 35 of file dart_test_component_controller.h.

Constructor & Destructor Documentation

◆ DartTestComponentController()

dart_runner::DartTestComponentController::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 
)

Definition at line 99 of file dart_test_component_controller.cc.

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}
#define FML_LOG(severity)
Definition logging.h:101

References FML_LOG.

◆ ~DartTestComponentController()

dart_runner::DartTestComponentController::~DartTestComponentController ( )
override

Definition at line 143 of file dart_test_component_controller.cc.

143 {
144 if (namespace_) {
145 fdio_ns_destroy(namespace_);
146 namespace_ = nullptr;
147 }
148 close(stdout_fd_);
149 close(stderr_fd_);
150}

Member Function Documentation

◆ GetHandler()

fidl::InterfaceRequestHandler< fuchsia::test::Suite > dart_runner::DartTestComponentController::GetHandler ( )
inline

Definition at line 64 of file dart_test_component_controller.h.

64 {
65 return suite_bindings_.GetHandler(this, loop_->dispatcher());
66 }

Referenced by SetUp().

◆ GetTests()

void dart_runner::DartTestComponentController::GetTests ( fidl::InterfaceRequest< fuchsia::test::CaseIterator >  iterator)
override

|Suite| protocol implementation.

Definition at line 405 of file dart_test_component_controller.cc.

406 {
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}

◆ handle_unknown_method()

void dart_runner::DartTestComponentController::handle_unknown_method ( uint64_t  ordinal,
bool  method_has_response 
)
override

Definition at line 667 of file dart_test_component_controller.cc.

669 {
670 FML_LOG(ERROR) << "Unknown method called on DartTestComponentController. "
671 "Ordinal: "
672 << ordinal;
673}

References FML_LOG.

◆ Run()

void dart_runner::DartTestComponentController::Run ( std::vector< fuchsia::test::Invocation >  tests,
fuchsia::test::RunOptions  options,
fidl::InterfaceHandle< fuchsia::test::RunListener >  listener 
)
override

|Suite| protocol implementation.

Definition at line 416 of file dart_test_component_controller.cc.

419 {
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}
static DartState * Current()
Definition dart_state.cc:56
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args

References args, tonic::DartState::Current(), and FML_LOG.

◆ SetUp()

void dart_runner::DartTestComponentController::SetUp ( )

Sets up the controller.

This should be called before |Run|.

Definition at line 152 of file dart_test_component_controller.cc.

152 {
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}
fidl::InterfaceRequestHandler< fuchsia::test::Suite > GetHandler()

References FML_LOG, and GetHandler().


The documentation for this class was generated from the following files: