From 7c0c2709324ed3c6d77d61b8d20bcc1973afd93f Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Sun, 24 Nov 2024 18:34:31 +0200 Subject: [PATCH] refactor(tvix/store): expose fixtures, make NAR_CONTENTS const Allow reusing CASTORE_NODE_* and NAR_CONTENTS_* from other crates. Also, there's no need for NAR_CONTENTS_* to be Vecs of bytes, these can just be [u8; _]. Change-Id: I435c08a9d20f6a68266d0c9a70bfc7fdb618ce42 Reviewed-on: https://cl.tvl.fyi/c/depot/+/12915 Tested-by: BuildkiteCI Autosubmit: flokli Reviewed-by: raitobezarius --- tvix/store/src/fixtures.rs | 142 +++++++++++++ tvix/store/src/lib.rs | 1 + tvix/store/src/nar/import.rs | 28 +-- tvix/store/src/pathinfoservice/cache.rs | 2 +- tvix/store/src/pathinfoservice/grpc.rs | 3 +- tvix/store/src/pathinfoservice/lru.rs | 2 +- .../src/pathinfoservice/signing_wrapper.rs | 2 +- tvix/store/src/pathinfoservice/tests/mod.rs | 5 +- tvix/store/src/proto/tests/pathinfo.rs | 2 +- tvix/store/src/tests/fixtures.rs | 189 +++--------------- tvix/store/src/tests/nar_renderer.rs | 3 +- tvix/store/src/tests/nar_renderer_seekable.rs | 8 +- 12 files changed, 200 insertions(+), 187 deletions(-) create mode 100644 tvix/store/src/fixtures.rs diff --git a/tvix/store/src/fixtures.rs b/tvix/store/src/fixtures.rs new file mode 100644 index 000000000..d8c4e97fe --- /dev/null +++ b/tvix/store/src/fixtures.rs @@ -0,0 +1,142 @@ +use crate::pathinfoservice::PathInfo; +use nix_compat::nixhash::{CAHash, NixHash}; +use nix_compat::store_path::StorePath; +use std::sync::LazyLock; +use tvix_castore::fixtures::{ + DIRECTORY_COMPLICATED, DUMMY_DIGEST, HELLOWORLD_BLOB_CONTENTS, HELLOWORLD_BLOB_DIGEST, +}; +use tvix_castore::Node; + +pub const DUMMY_PATH_STR: &str = "00000000000000000000000000000000-dummy"; +pub const DUMMY_PATH_DIGEST: [u8; 20] = [0; 20]; + +pub static DUMMY_PATH: LazyLock> = + LazyLock::new(|| StorePath::from_name_and_digest_fixed("dummy", DUMMY_PATH_DIGEST).unwrap()); + +pub static CASTORE_NODE_SYMLINK: LazyLock = LazyLock::new(|| Node::Symlink { + target: "/nix/store/somewhereelse".try_into().unwrap(), +}); + +/// The NAR representation of a symlink pointing to `/nix/store/somewhereelse` +pub const NAR_CONTENTS_SYMLINK: [u8; 136] = [ + 13, 0, 0, 0, 0, 0, 0, 0, b'n', b'i', b'x', b'-', b'a', b'r', b'c', b'h', b'i', b'v', b'e', + b'-', b'1', 0, 0, 0, // "nix-archive-1" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" + 7, 0, 0, 0, 0, 0, 0, 0, b's', b'y', b'm', b'l', b'i', b'n', b'k', 0, // "symlink" + 6, 0, 0, 0, 0, 0, 0, 0, b't', b'a', b'r', b'g', b'e', b't', 0, 0, // target + 24, 0, 0, 0, 0, 0, 0, 0, b'/', b'n', b'i', b'x', b'/', b's', b't', b'o', b'r', b'e', b'/', + b's', b'o', b'm', b'e', b'w', b'h', b'e', b'r', b'e', b'e', b'l', b's', + b'e', // "/nix/store/somewhereelse" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" +]; + +pub static CASTORE_NODE_HELLOWORLD: LazyLock = LazyLock::new(|| Node::File { + digest: HELLOWORLD_BLOB_DIGEST.clone(), + size: HELLOWORLD_BLOB_CONTENTS.len() as u64, + executable: false, +}); + +/// The NAR representation of a regular file with the contents "Hello World!" +pub const NAR_CONTENTS_HELLOWORLD: [u8; 128] = [ + 13, 0, 0, 0, 0, 0, 0, 0, b'n', b'i', b'x', b'-', b'a', b'r', b'c', b'h', b'i', b'v', b'e', + b'-', b'1', 0, 0, 0, // "nix-archive-1" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" + 7, 0, 0, 0, 0, 0, 0, 0, b'r', b'e', b'g', b'u', b'l', b'a', b'r', 0, // "regular" + 8, 0, 0, 0, 0, 0, 0, 0, b'c', b'o', b'n', b't', b'e', b'n', b't', b's', // "contents" + 12, 0, 0, 0, 0, 0, 0, 0, b'H', b'e', b'l', b'l', b'o', b' ', b'W', b'o', b'r', b'l', b'd', + b'!', 0, 0, 0, 0, // "Hello World!" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" +]; + +pub static CASTORE_NODE_TOO_BIG: LazyLock = LazyLock::new(|| Node::File { + digest: HELLOWORLD_BLOB_DIGEST.clone(), + size: 42, // <- note the wrong size here! + executable: false, +}); +pub static CASTORE_NODE_TOO_SMALL: LazyLock = LazyLock::new(|| Node::File { + digest: HELLOWORLD_BLOB_DIGEST.clone(), + size: 2, // <- note the wrong size here! + executable: false, +}); + +pub static CASTORE_NODE_COMPLICATED: LazyLock = LazyLock::new(|| Node::Directory { + digest: DIRECTORY_COMPLICATED.digest(), + size: DIRECTORY_COMPLICATED.size(), +}); + +/// The NAR representation of a more complicated directory structure. +pub const NAR_CONTENTS_COMPLICATED: [u8; 840] = [ + 13, 0, 0, 0, 0, 0, 0, 0, b'n', b'i', b'x', b'-', b'a', b'r', b'c', b'h', b'i', b'v', b'e', + b'-', b'1', 0, 0, 0, // "nix-archive-1" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" + 9, 0, 0, 0, 0, 0, 0, 0, b'd', b'i', b'r', b'e', b'c', b't', b'o', b'r', b'y', 0, 0, 0, 0, 0, 0, + 0, // "directory" + 5, 0, 0, 0, 0, 0, 0, 0, b'e', b'n', b't', b'r', b'y', 0, 0, 0, // "entry" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'a', b'm', b'e', 0, 0, 0, 0, // "name" + 5, 0, 0, 0, 0, 0, 0, 0, b'.', b'k', b'e', b'e', b'p', 0, 0, 0, // ".keep" + 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'o', b'd', b'e', 0, 0, 0, 0, // "node" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" + 7, 0, 0, 0, 0, 0, 0, 0, b'r', b'e', b'g', b'u', b'l', b'a', b'r', 0, // "regular" + 8, 0, 0, 0, 0, 0, 0, 0, b'c', b'o', b'n', b't', b'e', b'n', b't', b's', // "contents" + 0, 0, 0, 0, 0, 0, 0, 0, // "" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" + 5, 0, 0, 0, 0, 0, 0, 0, b'e', b'n', b't', b'r', b'y', 0, 0, 0, // "entry" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'a', b'm', b'e', 0, 0, 0, 0, // "name" + 2, 0, 0, 0, 0, 0, 0, 0, b'a', b'a', 0, 0, 0, 0, 0, 0, // "aa" + 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'o', b'd', b'e', 0, 0, 0, 0, // "node" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" + 7, 0, 0, 0, 0, 0, 0, 0, b's', b'y', b'm', b'l', b'i', b'n', b'k', 0, // "symlink" + 6, 0, 0, 0, 0, 0, 0, 0, b't', b'a', b'r', b'g', b'e', b't', 0, 0, // target + 24, 0, 0, 0, 0, 0, 0, 0, b'/', b'n', b'i', b'x', b'/', b's', b't', b'o', b'r', b'e', b'/', + b's', b'o', b'm', b'e', b'w', b'h', b'e', b'r', b'e', b'e', b'l', b's', + b'e', // "/nix/store/somewhereelse" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" + 5, 0, 0, 0, 0, 0, 0, 0, b'e', b'n', b't', b'r', b'y', 0, 0, 0, // "entry" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'a', b'm', b'e', 0, 0, 0, 0, // "name" + 4, 0, 0, 0, 0, 0, 0, 0, b'k', b'e', b'e', b'p', 0, 0, 0, 0, // "keep" + 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'o', b'd', b'e', 0, 0, 0, 0, // "node" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" + 9, 0, 0, 0, 0, 0, 0, 0, b'd', b'i', b'r', b'e', b'c', b't', b'o', b'r', b'y', 0, 0, 0, 0, 0, 0, + 0, // "directory" + 5, 0, 0, 0, 0, 0, 0, 0, b'e', b'n', b't', b'r', b'y', 0, 0, 0, // "entry" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'a', b'm', b'e', 0, 0, 0, 0, // "name" + 5, 0, 0, 0, 0, 0, 0, 0, 46, 107, 101, 101, 112, 0, 0, 0, // ".keep" + 4, 0, 0, 0, 0, 0, 0, 0, 110, 111, 100, 101, 0, 0, 0, 0, // "node" + 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" + 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" + 7, 0, 0, 0, 0, 0, 0, 0, b'r', b'e', b'g', b'u', b'l', b'a', b'r', 0, // "regular" + 8, 0, 0, 0, 0, 0, 0, 0, b'c', b'o', b'n', b't', b'e', b'n', b't', b's', // "contents" + 0, 0, 0, 0, 0, 0, 0, 0, // "" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" + 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" +]; + +/// A PathInfo message +pub static PATH_INFO: LazyLock = LazyLock::new(|| PathInfo { + store_path: DUMMY_PATH.clone(), + node: tvix_castore::Node::Directory { + digest: DUMMY_DIGEST.clone(), + size: 0, + }, + references: vec![DUMMY_PATH.clone()], + nar_sha256: [0; 32], + nar_size: 0, + signatures: vec![], + deriver: None, + ca: Some(CAHash::Nar(NixHash::Sha256([0; 32]))), +}); diff --git a/tvix/store/src/lib.rs b/tvix/store/src/lib.rs index 5f1642ce2..6da1d3832 100644 --- a/tvix/store/src/lib.rs +++ b/tvix/store/src/lib.rs @@ -1,4 +1,5 @@ pub mod composition; +pub mod fixtures; pub mod import; pub mod nar; pub mod path_info; diff --git a/tvix/store/src/nar/import.rs b/tvix/store/src/nar/import.rs index 93dfec2d9..994b2ac67 100644 --- a/tvix/store/src/nar/import.rs +++ b/tvix/store/src/nar/import.rs @@ -229,6 +229,9 @@ pub enum Error { #[cfg(test)] mod test { + use crate::fixtures::{ + NAR_CONTENTS_COMPLICATED, NAR_CONTENTS_HELLOWORLD, NAR_CONTENTS_SYMLINK, + }; use crate::nar::{ingest_nar, ingest_nar_and_hash, NarIngestionError}; use std::io::Cursor; use std::sync::Arc; @@ -245,10 +248,7 @@ mod test { }; use tvix_castore::{Directory, Node}; - use crate::tests::fixtures::{ - blob_service, directory_service, NAR_CONTENTS_COMPLICATED, NAR_CONTENTS_HELLOWORLD, - NAR_CONTENTS_SYMLINK, - }; + use crate::tests::fixtures::{blob_service, directory_service}; #[rstest] #[tokio::test] @@ -259,7 +259,7 @@ mod test { let root_node = ingest_nar( blob_service, directory_service, - &mut Cursor::new(&NAR_CONTENTS_SYMLINK.clone()), + &mut Cursor::new(&NAR_CONTENTS_SYMLINK), ) .await .expect("must parse"); @@ -281,7 +281,7 @@ mod test { let root_node = ingest_nar( blob_service.clone(), directory_service, - &mut Cursor::new(&NAR_CONTENTS_HELLOWORLD.clone()), + &mut Cursor::new(&NAR_CONTENTS_HELLOWORLD), ) .await .expect("must parse"); @@ -308,7 +308,7 @@ mod test { let root_node = ingest_nar( blob_service.clone(), directory_service.clone(), - &mut Cursor::new(&NAR_CONTENTS_COMPLICATED.clone()), + &mut Cursor::new(&NAR_CONTENTS_COMPLICATED), ) .await .expect("must parse"); @@ -338,16 +338,16 @@ mod test { } #[rstest] - #[case::nar_sha256(Some(CAHash::Nar(NixHash::Sha256(hex!("fbd52279a8df024c9fd5718de4103bf5e760dc7f2cf49044ee7dea87ab16911a")))), &NAR_CONTENTS_COMPLICATED.clone())] - #[case::nar_sha512(Some(CAHash::Nar(NixHash::Sha512(Box::new(hex!("ff5d43941411f35f09211f8596b426ee6e4dd3af1639e0ed2273cbe44b818fc4a59e3af02a057c5b18fbfcf435497de5f1994206c137f469b3df674966a922f0"))))), &NAR_CONTENTS_COMPLICATED.clone())] - #[case::flat_md5(Some(CAHash::Flat(NixHash::Md5(hex!("fd076287532e86365e841e92bfc50d8c")))), &NAR_CONTENTS_HELLOWORLD.clone(), )] - #[case::nar_symlink_sha1(Some(CAHash::Nar(NixHash::Sha1(hex!("f24eeaaa9cc016bab030bf007cb1be6483e7ba9e")))), &NAR_CONTENTS_SYMLINK.clone())] + #[case::nar_sha256(Some(CAHash::Nar(NixHash::Sha256(hex!("fbd52279a8df024c9fd5718de4103bf5e760dc7f2cf49044ee7dea87ab16911a")))), NAR_CONTENTS_COMPLICATED.as_slice())] + #[case::nar_sha512(Some(CAHash::Nar(NixHash::Sha512(Box::new(hex!("ff5d43941411f35f09211f8596b426ee6e4dd3af1639e0ed2273cbe44b818fc4a59e3af02a057c5b18fbfcf435497de5f1994206c137f469b3df674966a922f0"))))), NAR_CONTENTS_COMPLICATED.as_slice())] + #[case::flat_md5(Some(CAHash::Flat(NixHash::Md5(hex!("fd076287532e86365e841e92bfc50d8c")))), NAR_CONTENTS_HELLOWORLD.as_slice() )] + #[case::nar_symlink_sha1(Some(CAHash::Nar(NixHash::Sha1(hex!("f24eeaaa9cc016bab030bf007cb1be6483e7ba9e")))), NAR_CONTENTS_SYMLINK.as_slice())] #[tokio::test] async fn ingest_with_cahash_mismatch( blob_service: Arc, directory_service: Arc, #[case] ca_hash: Option, - #[case] nar_content: &Vec, + #[case] nar_content: &[u8], ) { let err = ingest_nar_and_hash( blob_service.clone(), @@ -373,7 +373,7 @@ mod test { blob_service: Arc, directory_service: Arc, #[case] ca_hash: Option, - #[case] nar_content: &Vec, + #[case] nar_content: &[u8], ) { let _ = ingest_nar_and_hash( blob_service.clone(), @@ -393,7 +393,7 @@ mod test { blob_service: Arc, directory_service: Arc, #[case] ca_hash: Option, - #[case] nar_content: &Vec, + #[case] nar_content: &[u8], ) { let err = ingest_nar_and_hash( blob_service, diff --git a/tvix/store/src/pathinfoservice/cache.rs b/tvix/store/src/pathinfoservice/cache.rs index df0046875..e24d4f932 100644 --- a/tvix/store/src/pathinfoservice/cache.rs +++ b/tvix/store/src/pathinfoservice/cache.rs @@ -109,8 +109,8 @@ mod test { use std::num::NonZeroUsize; use crate::{ + fixtures::PATH_INFO, pathinfoservice::{LruPathInfoService, MemoryPathInfoService, PathInfoService}, - tests::fixtures::PATH_INFO, }; /// Helper function setting up an instance of a "far" and "near" diff --git a/tvix/store/src/pathinfoservice/grpc.rs b/tvix/store/src/pathinfoservice/grpc.rs index 6ec88aec8..044db6641 100644 --- a/tvix/store/src/pathinfoservice/grpc.rs +++ b/tvix/store/src/pathinfoservice/grpc.rs @@ -187,7 +187,6 @@ impl ServiceBuilder for GRPCPathInfoServiceConfig { mod tests { use crate::pathinfoservice::tests::make_grpc_path_info_service_client; use crate::pathinfoservice::PathInfoService; - use crate::tests::fixtures; /// This ensures connecting via gRPC works as expected. #[tokio::test] @@ -196,7 +195,7 @@ mod tests { make_grpc_path_info_service_client().await; let path_info = path_info_service - .get(fixtures::DUMMY_PATH_DIGEST) + .get(crate::fixtures::DUMMY_PATH_DIGEST) .await .expect("must not be error"); diff --git a/tvix/store/src/pathinfoservice/lru.rs b/tvix/store/src/pathinfoservice/lru.rs index 0b5544186..f07f504b9 100644 --- a/tvix/store/src/pathinfoservice/lru.rs +++ b/tvix/store/src/pathinfoservice/lru.rs @@ -94,8 +94,8 @@ mod test { use std::{num::NonZeroUsize, sync::LazyLock}; use crate::{ + fixtures::PATH_INFO, pathinfoservice::{LruPathInfoService, PathInfo, PathInfoService}, - tests::fixtures::PATH_INFO, }; static PATHINFO_2: LazyLock = LazyLock::new(|| { let mut p = PATH_INFO.clone(); diff --git a/tvix/store/src/pathinfoservice/signing_wrapper.rs b/tvix/store/src/pathinfoservice/signing_wrapper.rs index f4ac44b5e..a645dfd2a 100644 --- a/tvix/store/src/pathinfoservice/signing_wrapper.rs +++ b/tvix/store/src/pathinfoservice/signing_wrapper.rs @@ -144,7 +144,7 @@ pub const DUMMY_VERIFYING_KEY: &str = "do.not.use:cuXqnuzlWfGTKmfzBPx2kXShjRryZM #[cfg(test)] mod test { - use crate::{pathinfoservice::PathInfoService, tests::fixtures::PATH_INFO}; + use crate::{fixtures::PATH_INFO, pathinfoservice::PathInfoService}; use nix_compat::narinfo::VerifyingKey; #[tokio::test] diff --git a/tvix/store/src/pathinfoservice/tests/mod.rs b/tvix/store/src/pathinfoservice/tests/mod.rs index f56e1015e..d47d34d1d 100644 --- a/tvix/store/src/pathinfoservice/tests/mod.rs +++ b/tvix/store/src/pathinfoservice/tests/mod.rs @@ -7,11 +7,10 @@ use rstest::*; use rstest_reuse::{self, *}; use super::{PathInfo, PathInfoService}; +use crate::fixtures::{DUMMY_PATH_DIGEST, PATH_INFO}; use crate::pathinfoservice::redb::RedbPathInfoService; -use crate::pathinfoservice::MemoryPathInfoService; -use crate::tests::fixtures::{DUMMY_PATH_DIGEST, PATH_INFO}; - use crate::pathinfoservice::test_signing_service; +use crate::pathinfoservice::MemoryPathInfoService; mod utils; pub use self::utils::make_grpc_path_info_service_client; diff --git a/tvix/store/src/proto/tests/pathinfo.rs b/tvix/store/src/proto/tests/pathinfo.rs index edda64045..a16aefe82 100644 --- a/tvix/store/src/proto/tests/pathinfo.rs +++ b/tvix/store/src/proto/tests/pathinfo.rs @@ -1,8 +1,8 @@ use std::sync::LazyLock; +use crate::fixtures::{DUMMY_PATH, DUMMY_PATH_DIGEST, DUMMY_PATH_STR}; use crate::pathinfoservice::PathInfo; use crate::proto::{self, ValidatePathInfoError}; -use crate::tests::fixtures::{DUMMY_PATH, DUMMY_PATH_DIGEST, DUMMY_PATH_STR}; use bytes::Bytes; use nix_compat::store_path; use rstest::rstest; diff --git a/tvix/store/src/tests/fixtures.rs b/tvix/store/src/tests/fixtures.rs index 48edbcb7c..2a82d9c01 100644 --- a/tvix/store/src/tests/fixtures.rs +++ b/tvix/store/src/tests/fixtures.rs @@ -1,159 +1,15 @@ -use crate::pathinfoservice::PathInfo; -use nix_compat::nixhash::{CAHash, NixHash}; -use nix_compat::store_path::StorePath; -use rstest::{self, *}; -use rstest_reuse::*; -use std::io; -use std::sync::{Arc, LazyLock}; -use tvix_castore::fixtures::{ - DIRECTORY_COMPLICATED, DIRECTORY_WITH_KEEP, DUMMY_DIGEST, EMPTY_BLOB_CONTENTS, - EMPTY_BLOB_DIGEST, HELLOWORLD_BLOB_CONTENTS, HELLOWORLD_BLOB_DIGEST, -}; +use std::{io::Cursor, sync::Arc}; + +use rstest::fixture; +use rstest_reuse::template; use tvix_castore::{ blobservice::{BlobService, MemoryBlobService}, directoryservice::{DirectoryService, MemoryDirectoryService}, - Node, -}; - -pub const DUMMY_PATH_STR: &str = "00000000000000000000000000000000-dummy"; -pub const DUMMY_PATH_DIGEST: [u8; 20] = [0; 20]; - -pub static DUMMY_PATH: LazyLock> = - LazyLock::new(|| StorePath::from_name_and_digest_fixed("dummy", DUMMY_PATH_DIGEST).unwrap()); - -pub static CASTORE_NODE_SYMLINK: LazyLock = LazyLock::new(|| Node::Symlink { - target: "/nix/store/somewhereelse".try_into().unwrap(), -}); - -/// The NAR representation of a symlink pointing to `/nix/store/somewhereelse` -pub static NAR_CONTENTS_SYMLINK: LazyLock> = LazyLock::new(|| { - vec![ - 13, 0, 0, 0, 0, 0, 0, 0, b'n', b'i', b'x', b'-', b'a', b'r', b'c', b'h', b'i', b'v', b'e', - b'-', b'1', 0, 0, 0, // "nix-archive-1" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" - 7, 0, 0, 0, 0, 0, 0, 0, b's', b'y', b'm', b'l', b'i', b'n', b'k', 0, // "symlink" - 6, 0, 0, 0, 0, 0, 0, 0, b't', b'a', b'r', b'g', b'e', b't', 0, 0, // target - 24, 0, 0, 0, 0, 0, 0, 0, b'/', b'n', b'i', b'x', b'/', b's', b't', b'o', b'r', b'e', b'/', - b's', b'o', b'm', b'e', b'w', b'h', b'e', b'r', b'e', b'e', b'l', b's', - b'e', // "/nix/store/somewhereelse" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - ] -}); - -pub static CASTORE_NODE_HELLOWORLD: LazyLock = LazyLock::new(|| Node::File { - digest: HELLOWORLD_BLOB_DIGEST.clone(), - size: HELLOWORLD_BLOB_CONTENTS.len() as u64, - executable: false, -}); - -/// The NAR representation of a regular file with the contents "Hello World!" -pub static NAR_CONTENTS_HELLOWORLD: LazyLock> = LazyLock::new(|| { - vec![ - 13, 0, 0, 0, 0, 0, 0, 0, b'n', b'i', b'x', b'-', b'a', b'r', b'c', b'h', b'i', b'v', b'e', - b'-', b'1', 0, 0, 0, // "nix-archive-1" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" - 7, 0, 0, 0, 0, 0, 0, 0, b'r', b'e', b'g', b'u', b'l', b'a', b'r', 0, // "regular" - 8, 0, 0, 0, 0, 0, 0, 0, b'c', b'o', b'n', b't', b'e', b'n', b't', b's', // "contents" - 12, 0, 0, 0, 0, 0, 0, 0, b'H', b'e', b'l', b'l', b'o', b' ', b'W', b'o', b'r', b'l', b'd', - b'!', 0, 0, 0, 0, // "Hello World!" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - ] -}); - -pub static CASTORE_NODE_TOO_BIG: LazyLock = LazyLock::new(|| Node::File { - digest: HELLOWORLD_BLOB_DIGEST.clone(), - size: 42, // <- note the wrong size here! - executable: false, -}); -pub static CASTORE_NODE_TOO_SMALL: LazyLock = LazyLock::new(|| Node::File { - digest: HELLOWORLD_BLOB_DIGEST.clone(), - size: 2, // <- note the wrong size here! - executable: false, -}); - -pub static CASTORE_NODE_COMPLICATED: LazyLock = LazyLock::new(|| Node::Directory { - digest: DIRECTORY_COMPLICATED.digest(), - size: DIRECTORY_COMPLICATED.size(), -}); - -/// The NAR representation of a more complicated directory structure. -pub static NAR_CONTENTS_COMPLICATED: LazyLock> = LazyLock::new(|| { - vec![ - 13, 0, 0, 0, 0, 0, 0, 0, b'n', b'i', b'x', b'-', b'a', b'r', b'c', b'h', b'i', b'v', b'e', - b'-', b'1', 0, 0, 0, // "nix-archive-1" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" - 9, 0, 0, 0, 0, 0, 0, 0, b'd', b'i', b'r', b'e', b'c', b't', b'o', b'r', b'y', 0, 0, 0, 0, - 0, 0, 0, // "directory" - 5, 0, 0, 0, 0, 0, 0, 0, b'e', b'n', b't', b'r', b'y', 0, 0, 0, // "entry" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'a', b'm', b'e', 0, 0, 0, 0, // "name" - 5, 0, 0, 0, 0, 0, 0, 0, b'.', b'k', b'e', b'e', b'p', 0, 0, 0, // ".keep" - 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'o', b'd', b'e', 0, 0, 0, 0, // "node" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" - 7, 0, 0, 0, 0, 0, 0, 0, b'r', b'e', b'g', b'u', b'l', b'a', b'r', 0, // "regular" - 8, 0, 0, 0, 0, 0, 0, 0, b'c', b'o', b'n', b't', b'e', b'n', b't', b's', // "contents" - 0, 0, 0, 0, 0, 0, 0, 0, // "" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - 5, 0, 0, 0, 0, 0, 0, 0, b'e', b'n', b't', b'r', b'y', 0, 0, 0, // "entry" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'a', b'm', b'e', 0, 0, 0, 0, // "name" - 2, 0, 0, 0, 0, 0, 0, 0, b'a', b'a', 0, 0, 0, 0, 0, 0, // "aa" - 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'o', b'd', b'e', 0, 0, 0, 0, // "node" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" - 7, 0, 0, 0, 0, 0, 0, 0, b's', b'y', b'm', b'l', b'i', b'n', b'k', 0, // "symlink" - 6, 0, 0, 0, 0, 0, 0, 0, b't', b'a', b'r', b'g', b'e', b't', 0, 0, // target - 24, 0, 0, 0, 0, 0, 0, 0, b'/', b'n', b'i', b'x', b'/', b's', b't', b'o', b'r', b'e', b'/', - b's', b'o', b'm', b'e', b'w', b'h', b'e', b'r', b'e', b'e', b'l', b's', - b'e', // "/nix/store/somewhereelse" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - 5, 0, 0, 0, 0, 0, 0, 0, b'e', b'n', b't', b'r', b'y', 0, 0, 0, // "entry" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'a', b'm', b'e', 0, 0, 0, 0, // "name" - 4, 0, 0, 0, 0, 0, 0, 0, b'k', b'e', b'e', b'p', 0, 0, 0, 0, // "keep" - 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'o', b'd', b'e', 0, 0, 0, 0, // "node" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" - 9, 0, 0, 0, 0, 0, 0, 0, b'd', b'i', b'r', b'e', b'c', b't', b'o', b'r', b'y', 0, 0, 0, 0, - 0, 0, 0, // "directory" - 5, 0, 0, 0, 0, 0, 0, 0, b'e', b'n', b't', b'r', b'y', 0, 0, 0, // "entry" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b'n', b'a', b'm', b'e', 0, 0, 0, 0, // "name" - 5, 0, 0, 0, 0, 0, 0, 0, 46, 107, 101, 101, 112, 0, 0, 0, // ".keep" - 4, 0, 0, 0, 0, 0, 0, 0, 110, 111, 100, 101, 0, 0, 0, 0, // "node" - 1, 0, 0, 0, 0, 0, 0, 0, b'(', 0, 0, 0, 0, 0, 0, 0, // "(" - 4, 0, 0, 0, 0, 0, 0, 0, b't', b'y', b'p', b'e', 0, 0, 0, 0, // "type" - 7, 0, 0, 0, 0, 0, 0, 0, b'r', b'e', b'g', b'u', b'l', b'a', b'r', 0, // "regular" - 8, 0, 0, 0, 0, 0, 0, 0, b'c', b'o', b'n', b't', b'e', b'n', b't', b's', // "contents" - 0, 0, 0, 0, 0, 0, 0, 0, // "" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - 1, 0, 0, 0, 0, 0, 0, 0, b')', 0, 0, 0, 0, 0, 0, 0, // ")" - ] -}); - -/// A PathInfo message -pub static PATH_INFO: LazyLock = LazyLock::new(|| PathInfo { - store_path: DUMMY_PATH.clone(), - node: tvix_castore::Node::Directory { - digest: DUMMY_DIGEST.clone(), - size: 0, + fixtures::{ + DIRECTORY_COMPLICATED, DIRECTORY_WITH_KEEP, EMPTY_BLOB_CONTENTS, EMPTY_BLOB_DIGEST, + HELLOWORLD_BLOB_CONTENTS, HELLOWORLD_BLOB_DIGEST, }, - references: vec![DUMMY_PATH.clone()], - nar_sha256: [0; 32], - nar_size: 0, - signatures: vec![], - deriver: None, - ca: Some(CAHash::Nar(NixHash::Sha256([0; 32]))), -}); +}; #[fixture] pub(crate) fn blob_service() -> Arc { @@ -170,7 +26,7 @@ pub(crate) async fn blob_service_with_contents() -> Arc { // put all data into the stores. // insert blob into the store let mut writer = blob_service.open_write().await; - tokio::io::copy(&mut io::Cursor::new(blob_contents), &mut writer) + tokio::io::copy(&mut Cursor::new(blob_contents), &mut writer) .await .unwrap(); assert_eq!(blob_digest.clone(), writer.close().await.unwrap()); @@ -194,13 +50,28 @@ pub(crate) async fn directory_service_with_contents() -> Arc, io::ErrorKind>, crate::nar::RenderError>, + #[case] test_output: Result, crate::nar::RenderError>, ) { } diff --git a/tvix/store/src/tests/nar_renderer.rs b/tvix/store/src/tests/nar_renderer.rs index 6314ba6cc..41f5368d3 100644 --- a/tvix/store/src/tests/nar_renderer.rs +++ b/tvix/store/src/tests/nar_renderer.rs @@ -1,3 +1,4 @@ +use crate::fixtures::CASTORE_NODE_HELLOWORLD; use crate::nar::write_nar; use crate::tests::fixtures::*; use rstest::*; @@ -40,7 +41,7 @@ async fn seekable( #[future] blob_service_with_contents: Arc, #[future] directory_service_with_contents: Arc, #[case] test_input: &Node, - #[case] test_output: Result, io::ErrorKind>, crate::nar::RenderError>, + #[case] test_output: Result, crate::nar::RenderError>, ) { let blob_service = blob_service_with_contents.await; let directory_service = directory_service_with_contents.await; diff --git a/tvix/store/src/tests/nar_renderer_seekable.rs b/tvix/store/src/tests/nar_renderer_seekable.rs index 233b95d0b..cdb11fad3 100644 --- a/tvix/store/src/tests/nar_renderer_seekable.rs +++ b/tvix/store/src/tests/nar_renderer_seekable.rs @@ -18,7 +18,7 @@ async fn read_to_end( #[future] blob_service: Arc, #[future] directory_service: Arc, #[case] test_input: &Node, - #[case] test_output: Result, io::ErrorKind>, crate::nar::RenderError>, + #[case] test_output: Result, crate::nar::RenderError>, ) { let reader_result = Reader::new( test_input.clone(), @@ -63,7 +63,7 @@ async fn seek_twice( #[future] directory_service: Arc, ) { let mut reader = Reader::new( - CASTORE_NODE_COMPLICATED.clone(), + crate::fixtures::CASTORE_NODE_COMPLICATED.clone(), // don't put anything in the stores, as we don't actually do any requests. blob_service.await, directory_service.await, @@ -89,7 +89,7 @@ async fn seek( #[future] directory_service: Arc, ) { let mut reader = Reader::new( - CASTORE_NODE_HELLOWORLD.clone(), + crate::fixtures::CASTORE_NODE_HELLOWORLD.clone(), // don't put anything in the stores, as we don't actually do any requests. blob_service.await, directory_service.await, @@ -106,6 +106,6 @@ async fn seek( ] { let n = reader.seek(position).await.expect("seek") as usize; reader.read_exact(&mut buf).await.expect("read_exact"); - assert_eq!(NAR_CONTENTS_HELLOWORLD[n..n + 10], buf); + assert_eq!(crate::fixtures::NAR_CONTENTS_HELLOWORLD[n..n + 10], buf); } }