Skip to main content

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_fs::directory::open_in_namespace;
36    use std::fs::File;
37    use std::io::Write as _;
38    use tempfile::tempdir;
39
40    #[fuchsia::test]
41    async fn open_error() {
42        let temp_dir = tempdir().expect("/tmp to exist");
43        let proxy = open_in_namespace(temp_dir.path().to_str().unwrap(), fio::PERM_READABLE)
44            .expect("temp dir to open");
45
46        assert_matches!(hash(&proxy).await, Err(HashError::Open(_)));
47    }
48
49    #[fuchsia::test]
50    async fn parse_error() {
51        let temp_dir = tempdir().expect("/tmp to exist");
52        File::create(temp_dir.path().join("meta")).unwrap();
53        let proxy = open_in_namespace(temp_dir.path().to_str().unwrap(), fio::PERM_READABLE)
54            .expect("temp dir to open");
55
56        assert_matches!(hash(&proxy).await, Err(HashError::Parse(_)));
57    }
58
59    #[fuchsia::test]
60    async fn success() {
61        let temp_dir = tempdir().expect("/tmp to exist");
62        let mut meta = File::create(temp_dir.path().join("meta")).unwrap();
63        let hex = "0000000000000000000000000000000000000000000000000000000000000000";
64        meta.write_all(hex.as_bytes()).unwrap();
65        let proxy = open_in_namespace(temp_dir.path().to_str().unwrap(), fio::PERM_READABLE)
66            .expect("temp dir to open");
67
68        assert_matches!(hash(&proxy).await, Ok(hash) if hash == hex.parse().unwrap());
69    }
70}