fuchsia_pkg_testing/
blobfs.rs1use fuchsia_hash::Hash;
8use futures::stream::TryStreamExt as _;
9use tempfile::TempDir;
10use {fidl_fuchsia_fxfs as ffxfs, fidl_fuchsia_io as fio, fuchsia_async as fasync};
11
12pub struct Fake {
18 root: TempDir,
19 _reader_server: fasync::Task<()>,
20}
21
22impl Fake {
23 pub fn new() -> (Self, blobfs::Client) {
30 let root = TempDir::new().unwrap();
31
32 let (reader, reader_stream) =
33 fidl::endpoints::create_proxy_and_stream::<ffxfs::BlobReaderMarker>();
34 let reader_server = fasync::Task::spawn(serve_reader(root_proxy(&root), reader_stream));
35
36 let blobfs = blobfs::Client::new(root_proxy(&root), None, reader, None).unwrap();
37 let fake = Self { root, _reader_server: reader_server };
38 (fake, blobfs)
39 }
40
41 pub fn add_blob(&self, hash: Hash, data: impl AsRef<[u8]>) {
47 std::fs::write(self.root.path().join(hash.to_string()), data).unwrap();
48 }
49
50 pub fn delete_blob(&self, hash: Hash) {
56 std::fs::remove_file(self.root.path().join(hash.to_string())).unwrap();
57 }
58}
59
60fn root_proxy(root: &TempDir) -> fio::DirectoryProxy {
61 fuchsia_fs::directory::open_in_namespace(root.path().to_str().unwrap(), fio::PERM_READABLE)
62 .unwrap()
63}
64
65async fn serve_reader(blobs: fio::DirectoryProxy, mut stream: ffxfs::BlobReaderRequestStream) {
66 while let Some(req) = stream.try_next().await.unwrap() {
67 match req {
68 ffxfs::BlobReaderRequest::GetVmo { blob_hash, responder } => {
69 match fuchsia_fs::directory::open_file(
70 &blobs,
71 &Hash::from(blob_hash).to_string(),
72 fio::PERM_READABLE,
73 )
74 .await
75 {
76 Ok(blob) => {
77 let vmo = blob
78 .get_backing_memory(fio::VmoFlags::READ)
79 .await
80 .unwrap()
81 .map_err(zx::Status::from_raw)
82 .unwrap();
83 let () = responder.send(Ok(vmo)).unwrap();
84 }
85 Err(fuchsia_fs::node::OpenError::OpenError(status))
86 if status == zx::Status::NOT_FOUND =>
87 {
88 let () = responder.send(Err(status.into_raw())).unwrap();
89 }
90 Err(e) => panic!("unexpected error {e:?}"),
91 }
92 }
93 }
94 }
95}