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