blob: 137351d1ad78dad50c93a8d0850751847ae0be5b [file] [log] [blame]
// Copyright 2019 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 {
ext4_read_only::{
parser::Parser,
readers::VmoReader,
structs::{self, MIN_EXT4_SIZE},
},
fidl_fuchsia_mem::Buffer,
fuchsia_zircon::Status,
std::sync::Arc,
vfs::directory::entry::DirectoryEntry,
};
#[derive(Debug, PartialEq)]
pub enum ConstructFsError {
VmoReadError(Status),
ParsingError(structs::ParsingError),
}
pub fn construct_fs(source: Buffer) -> Result<Arc<dyn DirectoryEntry>, ConstructFsError> {
if source.size < MIN_EXT4_SIZE as u64 {
// Too small to even fit the first copy of the ext4 Super Block.
ConstructFsError::VmoReadError(Status::NO_SPACE);
}
let mut parser = Parser::new(VmoReader::new(Arc::new(source)));
match parser.build_fuchsia_tree() {
Ok(tree) => Ok(tree),
Err(e) => Err(ConstructFsError::ParsingError(e)),
}
}
#[cfg(test)]
mod tests {
use super::construct_fs;
// macros
use vfs::{
assert_close, assert_event, assert_read, assert_read_dirents, open_as_file_assert_content,
open_get_file_proxy_assert_ok, open_get_proxy_assert,
};
use {
ext4_read_only::structs::MIN_EXT4_SIZE,
fidl_fuchsia_io::{
DIRENT_TYPE_DIRECTORY, DIRENT_TYPE_FILE, INO_UNKNOWN, OPEN_FLAG_DESCRIBE,
OPEN_RIGHT_READABLE,
},
fuchsia_zircon::Vmo,
std::fs,
vfs::directory::test_utils::{run_server_client, DirentsSameInodeBuilder},
};
#[test]
fn image_too_small() {
let vmo = Vmo::create(10).expect("VMO is created");
vmo.write(b"too small", 0).expect("VMO write() succeeds");
let buffer = fidl_fuchsia_mem::Buffer { vmo: vmo, size: 10 };
assert!(construct_fs(buffer).is_err(), "Expected failed parsing of VMO.");
}
#[test]
fn invalid_fs() {
let vmo = Vmo::create(MIN_EXT4_SIZE as u64).expect("VMO is created");
vmo.write(b"not ext4", 0).expect("VMO write() succeeds");
let buffer = fidl_fuchsia_mem::Buffer { vmo: vmo, size: MIN_EXT4_SIZE as u64 };
assert!(construct_fs(buffer).is_err(), "Expected failed parsing of VMO.");
}
#[test]
fn list_root() {
let data = fs::read("/pkg/data/nest.img").expect("Unable to read file");
let vmo = Vmo::create(data.len() as u64).expect("VMO is created");
vmo.write(data.as_slice(), 0).expect("VMO write() succeeds");
let buffer = fidl_fuchsia_mem::Buffer { vmo: vmo, size: data.len() as u64 };
let tree = construct_fs(buffer).expect("construct_fs parses the vmo");
run_server_client(OPEN_RIGHT_READABLE, tree, |root| async move {
{
let mut expected = DirentsSameInodeBuilder::new(INO_UNKNOWN);
expected.add(DIRENT_TYPE_DIRECTORY, b".");
expected.add(DIRENT_TYPE_FILE, b"file1");
expected.add(DIRENT_TYPE_DIRECTORY, b"inner");
expected.add(DIRENT_TYPE_DIRECTORY, b"lost+found");
assert_read_dirents!(root, 1000, expected.into_vec());
}
let flags = OPEN_RIGHT_READABLE | OPEN_FLAG_DESCRIBE;
let compare = "file1 contents.\n";
open_as_file_assert_content!(&root, flags, "file1", compare);
assert_close!(root);
});
}
}