remotevol_fuchsia_test_util/
fuchsia.rs

1// Copyright 2025 The Fuchsia 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
5use diagnostics_reader::ArchiveReader;
6use fidl::endpoints::create_proxy;
7use fuchsia_async::DurationExt;
8use fuchsia_component_test::RealmInstance;
9use log::info;
10use {fidl_fuchsia_io as fio, fuchsia_async as fasync};
11
12pub const PROGRAM_COLLECTION: &str = "debian_programs";
13
14pub async fn open_sysrq_trigger(realm: &RealmInstance) -> fio::FileProxy {
15    info!("opening sysrq trigger");
16    fuchsia_fs::directory::open_file(
17        realm.root.get_exposed_dir(),
18        "/fs_root/proc/sysrq-trigger",
19        fuchsia_fs::PERM_WRITABLE,
20    )
21    .await
22    .unwrap()
23}
24
25pub async fn is_starnix_volume_mounted() -> Option<bool> {
26    let test_fxfs_inspect =
27        ArchiveReader::inspect().select_all_for_component("test-fxfs").snapshot().await.unwrap();
28    if test_fxfs_inspect.len() == 0 {
29        return None;
30    }
31    let payload = test_fxfs_inspect[0].payload.as_ref().unwrap();
32    // Fxfs won't export the GUID property if the volume is locked (which is the case when an
33    // encrypted volume is unmounted).
34    if let Some(child) = payload.get_child_by_path(&["stores", "test_fxfs_user_volume"]) {
35        Some(child.get_property("guid").is_some())
36    } else {
37        None
38    }
39}
40
41pub async fn wait_for_starnix_volume_to_be_mounted() {
42    loop {
43        if is_starnix_volume_mounted().await == Some(true) {
44            return;
45        }
46        fasync::Timer::new(fasync::MonotonicDuration::from_millis(100).after_now()).await;
47    }
48}
49
50pub async fn get_storage_for_component_instance(
51    moniker_prefix: &str,
52    storage_admin: fidl_fuchsia_sys2::StorageAdminProxy,
53) -> fio::DirectoryProxy {
54    let (storage_user_iterator, storage_user_iterator_server_end) =
55        create_proxy::<fidl_fuchsia_sys2::StorageIteratorMarker>();
56    storage_admin
57        .list_storage_in_realm(".", storage_user_iterator_server_end)
58        .await
59        .unwrap()
60        .unwrap();
61    let mut matching_storage_users = vec![];
62    loop {
63        let chunk = storage_user_iterator.next().await.unwrap();
64        if chunk.is_empty() {
65            break;
66        }
67        let mut matches: Vec<String> = chunk
68            .into_iter()
69            .filter(|moniker| {
70                info!("moniker is {moniker}");
71                moniker.starts_with(moniker_prefix)
72            })
73            .collect();
74        matching_storage_users.append(&mut matches);
75    }
76    assert!(!matching_storage_users.is_empty());
77    let (proxy, server_end) = create_proxy::<fio::DirectoryMarker>();
78    storage_admin
79        .open_storage(matching_storage_users.first().unwrap(), server_end.into_channel().into())
80        .await
81        .unwrap()
82        .unwrap();
83    proxy
84}