feat(nix-compat/{aterm,derivation}): init parser
This provides a nom-based parser for Nix derivations in ATerm format, which can be reached via `Derivation::from_aterm_bytes`. Some of the lower-level ATerm primitives are moved into a (new) aterm module, and some more higher-level ones that construct derivation- specific types. Also, move the escape_bytes function into there, this is a generic ATerm thing. Change-Id: I2b03b8a1461c7ea2fcb8640c2fc3d1fa3ea719fb Reviewed-on: https://cl.tvl.fyi/c/depot/+/9730 Autosubmit: flokli <flokli@flokli.de> Reviewed-by: raitobezarius <tvl@lahfa.xyz> Tested-by: BuildkiteCI
This commit is contained in:
parent
8b09ae54b1
commit
2410f2292f
14 changed files with 679 additions and 3 deletions
|
|
@ -1,4 +1,7 @@
|
|||
use super::parse_error::ErrorKind;
|
||||
use crate::derivation::output::Output;
|
||||
use crate::derivation::parse_error::NomError;
|
||||
use crate::derivation::parser::Error::ParseError;
|
||||
use crate::derivation::Derivation;
|
||||
use crate::store_path::StorePath;
|
||||
use bstr::{BStr, BString};
|
||||
|
|
@ -70,6 +73,73 @@ fn check_to_aterm_bytes(path_to_drv_file: &str) {
|
|||
assert_eq!(expected, BStr::new(&derivation.to_aterm_bytes()));
|
||||
}
|
||||
|
||||
/// Reads in derivations in ATerm representation, parses with that parser,
|
||||
/// then compares the structs with the ones obtained by parsing the JSON
|
||||
/// representations.
|
||||
#[test_resources("src/derivation/tests/derivation_tests/ok/*.drv")]
|
||||
fn from_aterm_bytes(path_to_drv_file: &str) {
|
||||
// Read in ATerm representation.
|
||||
let aterm_bytes = read_file(path_to_drv_file);
|
||||
let parsed_drv = Derivation::from_aterm_bytes(&aterm_bytes).expect("must succeed");
|
||||
|
||||
// For where we're able to load JSON fixtures, parse them and compare the structs.
|
||||
// For where we're not, compare the bytes manually.
|
||||
if path_to_drv_file.ends_with("cp1252.drv") || path_to_drv_file.ends_with("latin1.drv") {
|
||||
assert_eq!(
|
||||
&[0xc5, 0xc4, 0xd6][..],
|
||||
parsed_drv.environment.get("chars").unwrap(),
|
||||
"expected bytes to match",
|
||||
);
|
||||
} else {
|
||||
let json_bytes = read_file(&format!("{}.json", path_to_drv_file));
|
||||
let fixture_derivation: Derivation =
|
||||
serde_json::from_slice(&json_bytes).expect("JSON was not well-formatted");
|
||||
|
||||
assert_eq!(fixture_derivation, parsed_drv);
|
||||
}
|
||||
|
||||
// Finally, write the ATerm serialization to another buffer, ensuring it's
|
||||
// stable (and we compare all fields we couldn't compare in the non-utf8
|
||||
// derivations)
|
||||
|
||||
assert_eq!(
|
||||
&aterm_bytes,
|
||||
&parsed_drv.to_aterm_bytes(),
|
||||
"expected serialized ATerm to match initial input"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_aterm_bytes_duplicate_map_key() {
|
||||
let buf: Vec<u8> = read_file(&format!("{}/{}", RESOURCES_PATHS, "duplicate.drv")).into();
|
||||
|
||||
let err = Derivation::from_aterm_bytes(&buf).expect_err("must fail");
|
||||
|
||||
match err {
|
||||
ParseError(NomError { input: _, code }) => {
|
||||
assert_eq!(code, ErrorKind::DuplicateMapKey("name".to_string()));
|
||||
}
|
||||
_ => {
|
||||
panic!("unexpected error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read in a derivation in ATerm, but add some garbage at the end.
|
||||
/// Ensure the parser detects and fails in this case.
|
||||
#[test]
|
||||
fn from_aterm_bytes_trailer() {
|
||||
let mut buf: Vec<u8> = read_file(&format!(
|
||||
"{}/ok/{}",
|
||||
RESOURCES_PATHS, "0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv"
|
||||
))
|
||||
.into();
|
||||
|
||||
buf.push(0x00);
|
||||
|
||||
Derivation::from_aterm_bytes(&buf).expect_err("must fail");
|
||||
}
|
||||
|
||||
#[test_case("bar","0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv"; "fixed_sha256")]
|
||||
#[test_case("foo", "4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv"; "simple-sha256")]
|
||||
#[test_case("bar", "ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv"; "fixed-sha1")]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue