Fix space DDL tests

next
Sayan Nandan 1 year ago
parent 369abe9a22
commit 550a39ad99
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -109,6 +109,9 @@ impl Space {
pub fn empty() -> Self {
Space::new_auto(Default::default(), SpaceMeta::with_env(into_dict! {}))
}
pub fn empty_with_uuid(uuid: Uuid) -> Self {
Space::new_with_uuid(Default::default(), SpaceMeta::with_env(into_dict!()), uuid)
}
#[inline(always)]
pub fn new_auto(mns: IndexST<Box<str>, Model>, meta: SpaceMeta) -> Self {
Self {

@ -36,101 +36,112 @@ use crate::engine::{
#[test]
fn alter_add_prop_env_var() {
let gns = GlobalNS::empty();
let uuid = super::exec_create_empty_verify(&gns, "create space myspace").unwrap();
super::exec_alter_and_verify(
super::exec_create_alter(
&gns,
"create space myspace",
"alter space myspace with { env: { MY_NEW_PROP: 100 } }",
|space| {
let space = space.unwrap();
assert_eq!(
space,
&Space::new_with_uuid(
into_dict!(),
SpaceMeta::with_env(into_dict! ("MY_NEW_PROP" => Datacell::new_uint(100))),
uuid
space.get_uuid()
)
);
},
)
.unwrap();
}
#[test]
fn alter_update_prop_env_var() {
let gns = GlobalNS::empty();
super::exec_create_and_verify(
let uuid = super::exec_create(
&gns,
"create space myspace with { env: { MY_NEW_PROP: 100 } }",
|space| {
assert_eq!(
space.unwrap().meta.env.read().get("MY_NEW_PROP").unwrap(),
space.meta.env.read().get("MY_NEW_PROP").unwrap(),
&(Datacell::new_uint(100).into())
)
},
);
super::exec_alter_and_verify(
)
.unwrap();
super::exec_alter(
&gns,
"alter space myspace with { env: { MY_NEW_PROP: 200 } }",
|space| {
assert_eq!(
space.unwrap(),
&Space::new_auto(
space,
&Space::new_with_uuid(
into_dict!(),
SpaceMeta::with_env(into_dict! ("MY_NEW_PROP" => Datacell::new_uint(200)))
SpaceMeta::with_env(into_dict! ("MY_NEW_PROP" => Datacell::new_uint(200))),
uuid,
)
)
},
)
.unwrap();
}
#[test]
fn alter_remove_prop_env_var() {
let gns = GlobalNS::empty();
super::exec_create_and_verify(
let uuid = super::exec_create(
&gns,
"create space myspace with { env: { MY_NEW_PROP: 100 } }",
|space| {
assert_eq!(
space.unwrap().meta.env.read().get("MY_NEW_PROP").unwrap(),
space.meta.env.read().get("MY_NEW_PROP").unwrap(),
&(Datacell::new_uint(100).into())
)
},
);
super::exec_alter_and_verify(
)
.unwrap();
super::exec_alter(
&gns,
"alter space myspace with { env: { MY_NEW_PROP: null } }",
|space| {
assert_eq!(
space.unwrap(),
&Space::new_auto(into_dict!(), SpaceMeta::with_env(into_dict!()))
space,
&Space::new_with_uuid(into_dict!(), SpaceMeta::with_env(into_dict!()), uuid)
)
},
)
.unwrap();
}
#[test]
fn alter_nx() {
let gns = GlobalNS::empty();
super::exec_alter_and_verify(
&gns,
"alter space myspace with { env: { MY_NEW_PROP: 100 } }",
|space| assert_eq!(space.unwrap_err(), DatabaseError::DdlSpaceNotFound),
)
assert_eq!(
super::exec_alter(
&gns,
"alter space myspace with { env: { MY_NEW_PROP: 100 } }",
|_| {},
)
.unwrap_err(),
DatabaseError::DdlSpaceNotFound
);
}
#[test]
fn alter_remove_all_env() {
let gns = GlobalNS::empty();
super::exec_create_and_verify(
let uuid = super::exec_create(
&gns,
"create space myspace with { env: { MY_NEW_PROP: 100 } }",
|space| {
assert_eq!(
space.unwrap().meta.env.read().get("MY_NEW_PROP").unwrap(),
space.meta.env.read().get("MY_NEW_PROP").unwrap(),
&(Datacell::new_uint(100).into())
)
},
);
super::exec_alter_and_verify(&gns, "alter space myspace with { env: null }", |space| {
assert_eq!(space.unwrap(), &Space::empty())
)
.unwrap();
super::exec_alter(&gns, "alter space myspace with { env: null }", |space| {
assert_eq!(space, &Space::empty_with_uuid(uuid))
})
.unwrap();
}

@ -36,13 +36,16 @@ use crate::engine::{
#[test]
fn exec_create_space_simple() {
let gns = GlobalNS::empty();
super::exec_create_empty_verify(&gns, "create space myspace").unwrap();
super::exec_create(&gns, "create space myspace", |spc| {
assert!(spc.models().read().is_empty())
})
.unwrap();
}
#[test]
fn exec_create_space_with_env() {
let gns = GlobalNS::empty();
super::exec_create_and_verify(
super::exec_create(
&gns,
r#"
create space myspace with {
@ -53,34 +56,39 @@ fn exec_create_space_with_env() {
"#,
|space| {
assert_eq!(
space.unwrap(),
&Space::new_auto(
space,
&Space::new_with_uuid(
into_dict! {},
SpaceMeta::with_env(into_dict! {
"MAX_MODELS" => Datacell::new_uint(100)
})
}),
space.get_uuid()
)
);
},
)
.unwrap();
}
#[test]
fn exec_create_space_with_bad_env_type() {
let gns = GlobalNS::empty();
super::exec_create_and_verify(&gns, "create space myspace with { env: 100 }", |space| {
assert_eq!(space.unwrap_err(), DatabaseError::DdlSpaceBadProperty);
});
assert_eq!(
super::exec_create(&gns, "create space myspace with { env: 100 }", |_| {}).unwrap_err(),
DatabaseError::DdlSpaceBadProperty
);
}
#[test]
fn exec_create_space_with_random_property() {
let gns = GlobalNS::empty();
super::exec_create_and_verify(
&gns,
"create space myspace with { i_am_blue_da_ba_dee: 100 }",
|space| {
assert_eq!(space.unwrap_err(), DatabaseError::DdlSpaceBadProperty);
},
assert_eq!(
super::exec_create(
&gns,
"create space myspace with { i_am_blue_da_ba_dee: 100 }",
|_| {}
)
.unwrap_err(),
DatabaseError::DdlSpaceBadProperty
);
}

@ -29,68 +29,46 @@ mod create;
use crate::engine::{
core::{space::Space, GlobalNS},
data::uuid::Uuid,
error::DatabaseResult,
idx::STIndex,
ql::{
ast::{compile_test, Statement},
ast::{self},
tests::lex_insecure as lex,
},
};
fn exec_verify(
gns: &GlobalNS,
query: &str,
mut exec: impl FnMut(&GlobalNS, Statement<'_>) -> (DatabaseResult<()>, Box<str>),
mut verify: impl FnMut(DatabaseResult<&Space>),
) {
let tok = lex(query.as_bytes()).unwrap();
let ast_node = compile_test(&tok).unwrap();
let (res, space_name) = exec(gns, ast_node);
let rl = gns.spaces().read();
let space_ref = rl.st_get(&space_name);
let r = res.map(|_| space_ref.unwrap());
verify(r);
}
/// Creates a space using the given tokens and allows the caller to verify it
fn exec_alter_and_verify(gns: &GlobalNS, tok: &str, verify: impl Fn(DatabaseResult<&Space>)) {
exec_verify(
gns,
tok,
|gns, stmt| {
let space = extract_safe!(stmt, Statement::AlterSpace(s) => s);
let space_name = space.space_name;
let r = Space::exec_alter(&gns, space);
(r, space_name.boxed_str())
},
verify,
);
fn exec_create(gns: &GlobalNS, create: &str, verify: impl Fn(&Space)) -> DatabaseResult<Uuid> {
let tok = lex(create.as_bytes()).unwrap();
let ast_node =
ast::parse_ast_node_full::<crate::engine::ql::ddl::crt::CreateSpace>(&tok[2..]).unwrap();
let name = ast_node.space_name;
Space::exec_create(gns, ast_node)?;
gns.with_space(&name, |space| {
verify(space);
Ok(space.get_uuid())
})
}
/// Creates a space using the given tokens and allows the caller to verify it
fn exec_create_and_verify(gns: &GlobalNS, tok: &str, verify: impl FnMut(DatabaseResult<&Space>)) {
exec_verify(
gns,
tok,
|gns, stmt| {
let space = extract_safe!(stmt, Statement::CreateSpace(s) => s);
let space_name = space.space_name;
let r = Space::exec_create(&gns, space);
(r, space_name.boxed_str())
},
verify,
);
fn exec_alter(gns: &GlobalNS, alter: &str, verify: impl Fn(&Space)) -> DatabaseResult<Uuid> {
let tok = lex(alter.as_bytes()).unwrap();
let ast_node =
ast::parse_ast_node_full::<crate::engine::ql::ddl::alt::AlterSpace>(&tok[2..]).unwrap();
let name = ast_node.space_name;
Space::exec_alter(gns, ast_node)?;
gns.with_space(&name, |space| {
verify(space);
Ok(space.get_uuid())
})
}
/// Creates an empty space with the given tokens
fn exec_create_empty_verify(
fn exec_create_alter(
gns: &GlobalNS,
tok: &str,
) -> DatabaseResult<crate::engine::data::uuid::Uuid> {
let mut name = None;
self::exec_create_and_verify(gns, tok, |space| {
assert_eq!(space.unwrap(), &Space::empty());
name = Some(space.unwrap().get_uuid());
});
Ok(name.unwrap())
crt: &str,
alt: &str,
verify_post_alt: impl Fn(&Space),
) -> DatabaseResult<Uuid> {
let uuid_crt = exec_create(gns, crt, |_| {})?;
let uuid_alt = exec_alter(gns, alt, verify_post_alt)?;
assert_eq!(uuid_crt, uuid_alt);
Ok(uuid_alt)
}

@ -35,6 +35,7 @@ macro_rules! extract {
}
#[cfg(test)]
#[allow(unused_macros)]
macro_rules! extract_safe {
($src:expr, $what:pat => $ret:expr) => {
if let $what = $src {

@ -92,7 +92,10 @@ pub fn dec_dict<PM: PersistMapSpec>(
};
let mut dict = HashMap::with_capacity(size);
while PM::meta_dec_entry_pretest(scanner) & (dict.len() != size) {
let md = dec_md::<PM::Metadata>(scanner)?;
let md = unsafe {
// pretest
dec_md::<PM::Metadata, true>(scanner)?
};
if PM::META_VERIFY_BEFORE_DEC && !md.pretest_src_for_object_dec(scanner) {
return Err(SDSSError::InternalDecodeStructureCorrupted);
}

@ -113,6 +113,7 @@ pub trait PersistObjectMD: Sized {
unsafe fn dec_md_payload(scanner: &mut BufferedScanner) -> Option<Self>;
}
/// Metadata for a simple size requirement
pub struct SimpleSizeMD<const N: usize>;
impl<const N: usize> PersistObjectMD for SimpleSizeMD<N> {
@ -144,17 +145,21 @@ impl PersistObjectMD for VoidMetadata {
}
}
fn dec_md<Md: PersistObjectMD>(scanner: &mut BufferedScanner) -> SDSSResult<Md> {
if Md::pretest_src_for_metadata_dec(scanner) {
unsafe {
match Md::dec_md_payload(scanner) {
Some(md) => Ok(md),
None => {
if Md::MD_DEC_INFALLIBLE {
impossible!()
} else {
Err(SDSSError::InternalDecodeStructureCorrupted)
}
/// Decode metadata
///
/// ## Safety
/// unsafe because you need to set whether you've already verified the metadata or not
unsafe fn dec_md<Md: PersistObjectMD, const ASSUME_PRETEST_PASS: bool>(
scanner: &mut BufferedScanner,
) -> SDSSResult<Md> {
if ASSUME_PRETEST_PASS || Md::pretest_src_for_metadata_dec(scanner) {
match Md::dec_md_payload(scanner) {
Some(md) => Ok(md),
None => {
if Md::MD_DEC_INFALLIBLE {
impossible!()
} else {
Err(SDSSError::InternalDecodeStructureCorrupted)
}
}
}
@ -212,7 +217,10 @@ pub fn enc_self<Obj: PersistObjectHlIO<Type = Obj>>(obj: &Obj) -> VecU8 {
/// dec the object
pub fn dec<Obj: PersistObjectHlIO>(scanner: &mut BufferedScanner) -> SDSSResult<Obj::Type> {
if Obj::Metadata::pretest_src_for_metadata_dec(scanner) {
let md = dec_md::<Obj::Metadata>(scanner)?;
let md = unsafe {
// UNSAFE(@ohsaya): pretest
dec_md::<Obj::Metadata, true>(scanner)?
};
if Obj::ALWAYS_VERIFY_PAYLOAD_USING_MD && !md.pretest_src_for_object_dec(scanner) {
return Err(SDSSError::InternalDecodeStructureCorrupted);
}

@ -169,7 +169,10 @@ impl PersistObjectHlIO for Field {
& (<Layer as PersistObjectHlIO>::Metadata::pretest_src_for_metadata_dec(scanner))
& !fin
{
let layer_md = dec_md(scanner)?;
let layer_md = unsafe {
// UNSAFE(@ohsayan): pretest
dec_md::<_, true>(scanner)?
};
let l = Layer::pe_obj_hlio_dec(scanner, layer_md)?;
fin = l.tag().tag_class() != TagClass::List;
layers.push(l);

Loading…
Cancel
Save