test(tvix/store/pathinfo): add more tests for references
This should cover all error cases produced. Change-Id: If31816d9b087551d86d7913df55df8f9f44bb554 Reviewed-on: https://cl.tvl.fyi/c/depot/+/9546 Autosubmit: flokli <flokli@flokli.de> Reviewed-by: edef <edef@edef.eu> Tested-by: BuildkiteCI
This commit is contained in:
parent
1f03a520a9
commit
d45d6de561
2 changed files with 104 additions and 45 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::proto::{NarInfo, PathInfo, ValidatePathInfoError};
|
||||
use crate::proto::{PathInfo, ValidatePathInfoError};
|
||||
use crate::tests::fixtures::*;
|
||||
use bytes::Bytes;
|
||||
use nix_compat::store_path::{self, StorePath};
|
||||
|
@ -150,49 +150,79 @@ fn validate_symlink(
|
|||
assert_eq!(t_result, p.validate());
|
||||
}
|
||||
|
||||
/// Ensure parsing a correct PathInfo without narinfo populated succeeds.
|
||||
#[test]
|
||||
fn validate_references() {
|
||||
// create a PathInfo without narinfo field.
|
||||
let path_info = PathInfo {
|
||||
node: Some(castorepb::Node {
|
||||
node: Some(castorepb::node::Node::Directory(castorepb::DirectoryNode {
|
||||
name: DUMMY_NAME.into(),
|
||||
digest: DUMMY_DIGEST.clone().into(),
|
||||
size: 0,
|
||||
})),
|
||||
}),
|
||||
references: vec![DUMMY_OUTPUT_HASH.clone().into()],
|
||||
narinfo: None,
|
||||
};
|
||||
assert!(path_info.validate().is_ok());
|
||||
|
||||
// create a PathInfo with a narinfo field, but an inconsistent set of references
|
||||
let path_info_with_narinfo_missing_refs = PathInfo {
|
||||
narinfo: Some(NarInfo {
|
||||
nar_size: 0,
|
||||
nar_sha256: DUMMY_DIGEST.clone().into(),
|
||||
signatures: vec![],
|
||||
reference_names: vec![],
|
||||
}),
|
||||
..path_info.clone()
|
||||
};
|
||||
match path_info_with_narinfo_missing_refs
|
||||
.validate()
|
||||
.expect_err("must_fail")
|
||||
{
|
||||
ValidatePathInfoError::InconsistentNumberOfReferences(_, _) => {}
|
||||
_ => panic!("unexpected error"),
|
||||
};
|
||||
|
||||
// create a pathinfo with the correct number of references, should suceed
|
||||
let path_info_with_narinfo = PathInfo {
|
||||
narinfo: Some(NarInfo {
|
||||
nar_size: 0,
|
||||
nar_sha256: DUMMY_DIGEST.clone().into(),
|
||||
signatures: vec![],
|
||||
reference_names: vec![DUMMY_NAME.to_string()],
|
||||
}),
|
||||
..path_info
|
||||
};
|
||||
assert!(path_info_with_narinfo.validate().is_ok());
|
||||
fn validate_references_without_narinfo_ok() {
|
||||
assert!(PATH_INFO_WITHOUT_NARINFO.validate().is_ok());
|
||||
}
|
||||
|
||||
/// Ensure parsing a correct PathInfo with narinfo populated succeeds.
|
||||
#[test]
|
||||
fn validate_references_with_narinfo_ok() {
|
||||
assert!(PATH_INFO_WITH_NARINFO.validate().is_ok());
|
||||
}
|
||||
|
||||
/// Create a PathInfo with a wrong count of narinfo.reference_names,
|
||||
/// and ensure validation fails.
|
||||
#[test]
|
||||
fn validate_inconsistent_num_refs_fail() {
|
||||
let mut path_info = PATH_INFO_WITH_NARINFO.clone();
|
||||
path_info.narinfo.as_mut().unwrap().reference_names = vec![];
|
||||
|
||||
match path_info.validate().expect_err("must_fail") {
|
||||
ValidatePathInfoError::InconsistentNumberOfReferences(1, 0) => {}
|
||||
e => panic!("unexpected error: {:?}", e),
|
||||
};
|
||||
}
|
||||
|
||||
/// Create a PathInfo with a wrong digest length in references.
|
||||
#[test]
|
||||
fn validate_invalid_reference_digest_len() {
|
||||
let mut path_info = PATH_INFO_WITHOUT_NARINFO.clone();
|
||||
path_info.references.push(vec![0xff, 0xff].into());
|
||||
|
||||
match path_info.validate().expect_err("must fail") {
|
||||
ValidatePathInfoError::InvalidReferenceDigestLen(
|
||||
1, // position
|
||||
2, // unexpected digest len
|
||||
) => {}
|
||||
e => panic!("unexpected error: {:?}", e),
|
||||
};
|
||||
}
|
||||
|
||||
/// Create a PathInfo with a narinfo.reference_name[1] that is no valid store path.
|
||||
#[test]
|
||||
fn validate_invalid_narinfo_reference_name() {
|
||||
let mut path_info = PATH_INFO_WITH_NARINFO.clone();
|
||||
|
||||
// This is invalid, as the store prefix is not part of reference_names.
|
||||
path_info.narinfo.as_mut().unwrap().reference_names[0] =
|
||||
"/nix/store/00000000000000000000000000000000-dummy".to_string();
|
||||
|
||||
match path_info.validate().expect_err("must fail") {
|
||||
ValidatePathInfoError::InvalidNarinfoReferenceName(0, reference_name) => {
|
||||
assert_eq!(
|
||||
"/nix/store/00000000000000000000000000000000-dummy",
|
||||
reference_name
|
||||
);
|
||||
}
|
||||
e => panic!("unexpected error: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a PathInfo with a narinfo.reference_name[0] that doesn't match references[0].
|
||||
#[test]
|
||||
fn validate_inconsistent_narinfo_reference_name_digest() {
|
||||
let mut path_info = PATH_INFO_WITH_NARINFO.clone();
|
||||
|
||||
// mutate the first reference, they were all zeroes before
|
||||
path_info.references[0] = vec![0xff; store_path::DIGEST_SIZE].into();
|
||||
|
||||
match path_info.validate().expect_err("must fail") {
|
||||
ValidatePathInfoError::InconsistentNarinfoReferenceNameDigest(0, e_expected, e_actual) => {
|
||||
assert_eq!(path_info.references[0][..], e_expected);
|
||||
assert_eq!(DUMMY_OUTPUT_HASH[..], e_actual);
|
||||
}
|
||||
e => panic!("unexpected error: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use lazy_static::lazy_static;
|
||||
pub use tvix_castore::fixtures::*;
|
||||
use tvix_castore::proto as castorepb;
|
||||
|
||||
use crate::proto::{NarInfo, PathInfo};
|
||||
|
||||
pub const DUMMY_NAME: &str = "00000000000000000000000000000000-dummy";
|
||||
|
||||
|
@ -94,4 +97,30 @@ lazy_static! {
|
|||
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 without .narinfo populated.
|
||||
pub static ref PATH_INFO_WITHOUT_NARINFO : PathInfo = PathInfo {
|
||||
node: Some(castorepb::Node {
|
||||
node: Some(castorepb::node::Node::Directory(castorepb::DirectoryNode {
|
||||
name: DUMMY_NAME.into(),
|
||||
digest: DUMMY_DIGEST.clone().into(),
|
||||
size: 0,
|
||||
})),
|
||||
}),
|
||||
references: vec![DUMMY_OUTPUT_HASH.clone().into()],
|
||||
narinfo: None,
|
||||
};
|
||||
|
||||
/// A PathInfo message with .narinfo populated.
|
||||
/// The references in `narinfo.reference_names` aligns with what's in
|
||||
/// `references`.
|
||||
pub static ref PATH_INFO_WITH_NARINFO : PathInfo = PathInfo {
|
||||
narinfo: Some(NarInfo {
|
||||
nar_size: 0,
|
||||
nar_sha256: DUMMY_DIGEST.clone().into(),
|
||||
signatures: vec![],
|
||||
reference_names: vec![DUMMY_NAME.to_string()],
|
||||
}),
|
||||
..PATH_INFO_WITHOUT_NARINFO.clone()
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue