| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // This component runs a hermetic instance of appmgr that points to a nonexistent sysmgr, to |
| // simulate sysmgr terminating while appmgr is running. |
| // |
| // In response, we expect appmgr to trigger a reboot. |
| |
| #include <fuchsia/sys/cpp/fidl.h> |
| #include <lib/async-loop/cpp/loop.h> |
| #include <lib/async-loop/default.h> |
| #include <lib/sys/cpp/service_directory.h> |
| #include <lib/sys/cpp/testing/test_with_environment.h> |
| #include <lib/syslog/cpp/macros.h> |
| #include <lib/zx/channel.h> |
| #include <zircon/errors.h> |
| |
| #include <memory> |
| |
| #include "src/lib/fxl/command_line.h" |
| #include "src/lib/fxl/log_settings_command_line.h" |
| #include "src/sys/appmgr/appmgr.h" |
| |
| class AppmgrHarness : public fuchsia::sys::internal::LogConnectionListener { |
| public: |
| void Run() { |
| async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread); |
| |
| FX_LOGS(INFO) << "Started failing_appmgr"; |
| zx::channel env_request_server, env_request_client; |
| zx_status_t status = zx::channel::create(0, &env_request_server, &env_request_client); |
| FX_CHECK(status == ZX_OK) << status; |
| auto environment_services = |
| std::make_shared<sys::ServiceDirectory>(std::move(env_request_client)); |
| |
| zx::channel trace_client, trace_server; |
| status = zx::channel::create(0, &trace_client, &trace_server); |
| FX_CHECK(status == ZX_OK) << status; |
| |
| zx::channel appmgr_service_request; |
| auto appmgr_services = sys::ServiceDirectory::CreateWithRequest(&appmgr_service_request); |
| |
| fuchsia::sys::ServiceListPtr root_realm_services(new fuchsia::sys::ServiceList); |
| component::AppmgrArgs args{ |
| .pa_directory_request = appmgr_service_request.release(), |
| .root_realm_services = std::move(root_realm_services), |
| .environment_services = std::move(environment_services), |
| .sysmgr_url = |
| "fuchsia-pkg://fuchsia.com/appmgr_integration_tests#meta/nonexistent_sysmgr.cmx", |
| .sysmgr_args = {}, |
| .run_virtual_console = false, |
| .trace_server_channel = std::move(trace_server)}; |
| component::Appmgr appmgr(loop.dispatcher(), std::move(args)); |
| |
| fuchsia::sys::internal::LogConnectorPtr log_connector; |
| log_connector.set_error_handler([](zx_status_t status) { |
| FX_LOGS(FATAL) << "Failed to connect to appmgr logs: " << status; |
| }); |
| |
| status = appmgr_services->Connect(log_connector.NewRequest(), |
| "appmgr_svc/fuchsia.sys.internal.LogConnector"); |
| FX_CHECK(status == ZX_OK); |
| // Simulate the archivist connecting to the log listener so that appmgr will launch sysmgr |
| log_connector->TakeLogConnectionListener(log_binding_.GetHandler(this)); |
| |
| loop.Run(); |
| } |
| |
| // |fuchsia::sys::internal::LogConnectionListener| |
| void OnNewConnection(fuchsia::sys::internal::LogConnection connection) override {} |
| |
| private: |
| fidl::BindingSet<fuchsia::sys::internal::LogConnectionListener> log_binding_; |
| }; |
| |
| int main(int argc, const char** argv) { |
| auto command_line = fxl::CommandLineFromArgcArgv(argc, argv); |
| if (!fxl::SetLogSettingsFromCommandLine(command_line)) { |
| return 1; |
| } |
| |
| AppmgrHarness harness; |
| harness.Run(); |
| FX_LOGS(FATAL) << "Loop quit unexpectedly"; |
| |
| return 0; |
| } |