update_package/
hash.rs

1// Copyright 2020 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 fidl_fuchsia_io as fio;
6use fuchsia_hash::Hash;
7use thiserror::Error;
8
9/// An error encountered while extracting the package hash.
10#[derive(Debug, Error)]
11#[allow(missing_docs)]
12pub enum HashError {
13    #[error("opening the 'meta' file")]
14    Open(#[source] fuchsia_fs::node::OpenError),
15
16    #[error("reading the 'meta' file")]
17    Read(#[source] fuchsia_fs::file::ReadError),
18
19    #[error("parsing the 'meta' file")]
20    Parse(#[source] fuchsia_hash::ParseHashError),
21}
22
23pub(crate) async fn hash(proxy: &fio::DirectoryProxy) -> Result<Hash, HashError> {
24    let meta = fuchsia_fs::directory::open_file(proxy, "meta", fio::PERM_READABLE)
25        .await
26        .map_err(HashError::Open)?;
27    let contents = fuchsia_fs::file::read_to_string(&meta).await.map_err(HashError::Read)?;
28    contents.parse::<Hash>().map_err(HashError::Parse)
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34    use assert_matches::assert_matches;
35    use fuchsia_async as fasync;
36    use fuchsia_fs::directory::open_in_namespace;
37    use std::fs::File;
38    use std::io::Write as _;
39    use tempfile::tempdir;
40
41    #[fasync::run_singlethreaded(test)]
42    async fn open_error() {
43        let temp_dir = tempdir().expect("/tmp to exist");
44        let proxy = open_in_namespace(temp_dir.path().to_str().unwrap(), fio::PERM_READABLE)
45            .expect("temp dir to open");
46
47        assert_matches!(hash(&proxy).await, Err(HashError::Open(_)));
48    }
49
50    #[fasync::run_singlethreaded(test)]
51    async fn parse_error() {
52        let temp_dir = tempdir().expect("/tmp to exist");
53        File::create(temp_dir.path().join("meta")).unwrap();
54        let proxy = open_in_namespace(temp_dir.path().to_str().unwrap(), fio::PERM_READABLE)
55            .expect("temp dir to open");
56
57        assert_matches!(hash(&proxy).await, Err(HashError::Parse(_)));
58    }
59
60    #[fasync::run_singlethreaded(test)]
61    async fn success() {
62        let temp_dir = tempdir().expect("/tmp to exist");
63        let mut meta = File::create(temp_dir.path().join("meta")).unwrap();
64        let hex = "0000000000000000000000000000000000000000000000000000000000000000";
65        meta.write_all(hex.as_bytes()).unwrap();
66        let proxy = open_in_namespace(temp_dir.path().to_str().unwrap(), fio::PERM_READABLE)
67            .expect("temp dir to open");
68
69        assert_matches!(hash(&proxy).await, Ok(hash) if hash == hex.parse().unwrap());
70    }
71}