blob: 98e5994b9a71b5071b8ece03f6e73766612ef5ce [file] [log] [blame]
// Copyright 2021 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.
use crate::mocks;
use anyhow::Error;
use cm_rust;
use fidl_fuchsia_io2 as fio2;
use fuchsia_component::server::ServiceFs;
use fuchsia_component_test::{
mock::MockHandles, ChildProperties, Event, Moniker, RealmBuilder, RealmInstance, RouteBuilder,
RouteEndpoint,
};
use futures::{channel::mpsc, lock::Mutex, StreamExt};
use std::sync::Arc;
const MOCK_COBALT_URL: &str = "fuchsia-pkg://fuchsia.com/mock_cobalt#meta/mock_cobalt.cm";
const SINGLE_COUNTER_URL: &str =
"fuchsia-pkg://fuchsia.com/sampler-integration-tests#meta/single_counter_test_component.cm";
const SAMPLER_URL: &str =
"fuchsia-pkg://fuchsia.com/sampler-integration-tests#meta/sampler-for-test.cm";
const ARCHIVIST_URL: &str =
"fuchsia-pkg://fuchsia.com/archivist-for-embedding#meta/archivist-for-embedding.cm";
pub async fn create() -> Result<RealmInstance, Error> {
let builder = RealmBuilder::new().await?;
builder
.add_mock_child(
"mocks-server",
move |mock_handles| Box::pin(serve_mocks(mock_handles)),
ChildProperties::new(),
)
.await?
.add_child("wrapper/mock_cobalt", MOCK_COBALT_URL, ChildProperties::new())
.await?
.add_child("wrapper/single_counter", SINGLE_COUNTER_URL, ChildProperties::new())
.await?
.add_child("wrapper/sampler", SAMPLER_URL, ChildProperties::new())
.await?
.add_child("wrapper/test_case_archivist", ARCHIVIST_URL, ChildProperties::new())
.await?
.add_route(
RouteBuilder::protocol("fuchsia.cobalt.test.LoggerQuerier")
.source(RouteEndpoint::component("wrapper/mock_cobalt"))
.targets(vec![RouteEndpoint::AboveRoot]),
)
.await?
.add_route(
RouteBuilder::protocol("fuchsia.samplertestcontroller.SamplerTestController")
.source(RouteEndpoint::component("wrapper/single_counter"))
.targets(vec![RouteEndpoint::AboveRoot]),
)
.await?
.add_route(
RouteBuilder::protocol("fuchsia.cobalt.LoggerFactory")
.source(RouteEndpoint::component("wrapper/mock_cobalt"))
.targets(vec![RouteEndpoint::component("wrapper/sampler")]),
)
.await?
.add_route(
RouteBuilder::protocol("fuchsia.metrics.MetricEventLoggerFactory")
.source(RouteEndpoint::component("wrapper/mock_cobalt"))
.targets(vec![RouteEndpoint::component("wrapper/sampler")]),
)
.await?
.add_route(
RouteBuilder::protocol(
"fuchsia.hardware.power.statecontrol.RebootMethodsWatcherRegister",
)
.source(RouteEndpoint::component("mocks-server"))
.targets(vec![RouteEndpoint::component("wrapper/sampler")]),
)
.await?
.add_route(
RouteBuilder::protocol("fuchsia.mockrebootcontroller.MockRebootController")
.source(RouteEndpoint::component("mocks-server"))
.targets(vec![RouteEndpoint::AboveRoot]),
)
.await?
.add_route(
RouteBuilder::protocol("fuchsia.logger.LogSink")
.source(RouteEndpoint::AboveRoot)
.targets(vec![
RouteEndpoint::component("wrapper/test_case_archivist"),
RouteEndpoint::component("wrapper/mock_cobalt"),
RouteEndpoint::component("wrapper/sampler"),
RouteEndpoint::component("wrapper/single_counter"),
]),
)
.await?
.add_route(
RouteBuilder::directory("config-data", "", fio2::R_STAR_DIR)
.source(RouteEndpoint::AboveRoot)
.targets(vec![RouteEndpoint::component("wrapper/sampler")]),
)
.await?
// TODO(fxbug.dev/76599): refactor these tests to use the single test archivist and remove
// this archivist. We can also remove the `wrapper` realm when this is done. The
// ArchiveAccessor and Log protocols routed here would be routed from AboveRoot instead. To
// do so, uncomment the following routes and delete all the routes after this comment
// involving "wrapper/test_case_archivist":
// .add_route(RouteBuilder::protocol("fuchsia.diagnostics.ArchiveAccessor")
// .source(RouteEndpoint::AboveRoot)
// .targets(vec![RouteEndpoint::component("wrapper/sampler")])
// }).await?
// .add_route(RouteBuilder::protocol("fuchsia.logger.Log")
// .source(RouteEndpoint::AboveRoot)
// .targets(vec![RouteEndpoint::component("wrapper/sampler")])
// }).await?
.add_route(
RouteBuilder::protocol("fuchsia.sys2.EventSource")
.source(RouteEndpoint::AboveRoot)
.targets(vec![RouteEndpoint::component("wrapper/test_case_archivist")]),
)
.await?
.add_route(
RouteBuilder::protocol("fuchsia.diagnostics.ArchiveAccessor")
.source(RouteEndpoint::component("wrapper/test_case_archivist"))
.targets(vec![RouteEndpoint::component("wrapper/sampler")]),
)
.await?
.add_route(
RouteBuilder::protocol("fuchsia.logger.Log")
.source(RouteEndpoint::component("wrapper/test_case_archivist"))
.targets(vec![RouteEndpoint::component("wrapper/sampler")]),
)
.await?
.add_route(
RouteBuilder::event(Event::Started, cm_rust::EventMode::Async)
.source(RouteEndpoint::component("wrapper"))
.targets(vec![RouteEndpoint::component("wrapper/test_case_archivist")]),
)
.await?
.add_route(
RouteBuilder::event(Event::Stopped, cm_rust::EventMode::Async)
.source(RouteEndpoint::component("wrapper"))
.targets(vec![RouteEndpoint::component("wrapper/test_case_archivist")]),
)
.await?
.add_route(
RouteBuilder::event(Event::Running, cm_rust::EventMode::Async)
.source(RouteEndpoint::component("wrapper"))
.targets(vec![RouteEndpoint::component("wrapper/test_case_archivist")]),
)
.await?
.add_route(
RouteBuilder::event(Event::directory_ready("diagnostics"), cm_rust::EventMode::Async)
.source(RouteEndpoint::component("wrapper"))
.targets(vec![RouteEndpoint::component("wrapper/test_case_archivist")]),
)
.await?
.add_route(
RouteBuilder::event(
Event::capability_requested("fuchsia.logger.LogSink"),
cm_rust::EventMode::Async,
)
.source(RouteEndpoint::component("wrapper"))
.targets(vec![RouteEndpoint::component("wrapper/test_case_archivist")]),
)
.await?;
// TODO(fxbug.dev/82734): RealmBuilder currently doesn't support renaming capabilities, so we
// need to manually do it here.
let mut wrapper_decl = builder.get_decl("wrapper").await.unwrap();
wrapper_decl.exposes.push(cm_rust::ExposeDecl::Protocol(cm_rust::ExposeProtocolDecl {
source: cm_rust::ExposeSource::Child("sampler".into()),
target: cm_rust::ExposeTarget::Parent,
source_name: "fuchsia.component.Binder".into(),
target_name: "fuchsia.component.SamplerBinder".into(),
}));
builder.set_decl("wrapper", wrapper_decl).await.unwrap();
let mut root_decl = builder.get_decl(Moniker::root()).await.unwrap();
root_decl.exposes.push(cm_rust::ExposeDecl::Protocol(cm_rust::ExposeProtocolDecl {
source: cm_rust::ExposeSource::Child("wrapper".into()),
target: cm_rust::ExposeTarget::Parent,
source_name: "fuchsia.component.SamplerBinder".into(),
target_name: "fuchsia.component.SamplerBinder".into(),
}));
builder.set_decl(Moniker::root(), root_decl).await.unwrap();
let instance = builder.build().await?;
Ok(instance)
}
async fn serve_mocks(mock_handles: MockHandles) -> Result<(), Error> {
let mut fs = ServiceFs::new();
let (snd, rcv) = mpsc::channel(1);
let rcv = Arc::new(Mutex::new(rcv));
fs.dir("svc")
.add_fidl_service(move |stream| {
mocks::serve_reboot_server(stream, snd.clone());
})
.add_fidl_service(move |stream| {
mocks::serve_reboot_controller(stream, rcv.clone());
});
fs.serve_connection(mock_handles.outgoing_dir.into_channel())?;
fs.collect::<()>().await;
Ok(())
}