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 <flokli@flokli.de>
Reviewed-by: raitobezarius <tvl@lahfa.xyz>
This commit is contained in:
Florian Klink 2024-11-24 18:34:31 +02:00 committed by clbot
parent b2a2225b8b
commit 7c0c270932
12 changed files with 200 additions and 187 deletions

View file

@ -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<StorePath<String>> =
LazyLock::new(|| StorePath::from_name_and_digest_fixed("dummy", DUMMY_PATH_DIGEST).unwrap());
pub static CASTORE_NODE_SYMLINK: LazyLock<Node> = 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<Vec<u8>> = 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<Node> = 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<Vec<u8>> = 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<Node> = 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<Node> = LazyLock::new(|| Node::File {
digest: HELLOWORLD_BLOB_DIGEST.clone(),
size: 2, // <- note the wrong size here!
executable: false,
});
pub static CASTORE_NODE_COMPLICATED: LazyLock<Node> = 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<Vec<u8>> = 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<PathInfo> = 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<dyn BlobService> {
@ -170,7 +26,7 @@ pub(crate) async fn blob_service_with_contents() -> Arc<dyn BlobService> {
// 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<dyn DirectoryServic
#[template]
#[rstest]
#[case::symlink (&*CASTORE_NODE_SYMLINK, Ok(Ok(&*NAR_CONTENTS_SYMLINK)))]
#[case::helloworld (&*CASTORE_NODE_HELLOWORLD, Ok(Ok(&*NAR_CONTENTS_HELLOWORLD)))]
#[case::too_big (&*CASTORE_NODE_TOO_BIG, Ok(Err(io::ErrorKind::UnexpectedEof)))]
#[case::too_small (&*CASTORE_NODE_TOO_SMALL, Ok(Err(io::ErrorKind::InvalidInput)))]
#[case::complicated(&*CASTORE_NODE_COMPLICATED, Ok(Ok(&*NAR_CONTENTS_COMPLICATED)))]
#[case::symlink(
&crate::fixtures::CASTORE_NODE_SYMLINK,
Ok(Ok(crate::fixtures::NAR_CONTENTS_SYMLINK.as_slice()))
)]
#[case::helloworld(
&crate::fixtures::CASTORE_NODE_HELLOWORLD,
Ok(Ok(crate::fixtures::NAR_CONTENTS_HELLOWORLD.as_slice()))
)]
#[case::too_big(
&crate::fixtures::CASTORE_NODE_TOO_BIG,
Ok(Err(io::ErrorKind::UnexpectedEof))
)]
#[case::too_small(
&crate::fixtures::CASTORE_NODE_TOO_SMALL,
Ok(Err(io::ErrorKind::InvalidInput))
)]
#[case::complicated(
&crate::fixtures::CASTORE_NODE_COMPLICATED,
Ok(Ok(crate::fixtures::NAR_CONTENTS_COMPLICATED.as_slice()))
)]
fn castore_fixtures_template(
#[case] test_input: &Node,
#[case] test_output: Result<Result<&Vec<u8>, io::ErrorKind>, crate::nar::RenderError>,
#[case] test_output: Result<Result<&[u8], io::ErrorKind>, crate::nar::RenderError>,
) {
}

View file

@ -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<dyn BlobService>,
#[future] directory_service_with_contents: Arc<dyn DirectoryService>,
#[case] test_input: &Node,
#[case] test_output: Result<Result<&Vec<u8>, io::ErrorKind>, crate::nar::RenderError>,
#[case] test_output: Result<Result<&[u8], io::ErrorKind>, crate::nar::RenderError>,
) {
let blob_service = blob_service_with_contents.await;
let directory_service = directory_service_with_contents.await;

View file

@ -18,7 +18,7 @@ async fn read_to_end(
#[future] blob_service: Arc<dyn BlobService>,
#[future] directory_service: Arc<dyn DirectoryService>,
#[case] test_input: &Node,
#[case] test_output: Result<Result<&Vec<u8>, io::ErrorKind>, crate::nar::RenderError>,
#[case] test_output: Result<Result<&[u8], io::ErrorKind>, crate::nar::RenderError>,
) {
let reader_result = Reader::new(
test_input.clone(),
@ -63,7 +63,7 @@ async fn seek_twice(
#[future] directory_service: Arc<dyn DirectoryService>,
) {
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<dyn DirectoryService>,
) {
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);
}
}