Skip to content

Commit

Permalink
Add proptest strategy for generating Schema for sparse arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
rroelke committed Mar 21, 2024
1 parent e8370a1 commit 460652a
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 16 deletions.
2 changes: 1 addition & 1 deletion tiledb/api/src/array/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::array::{Attribute, Domain, Layout};
use crate::context::Context;
use crate::Result as TileDBResult;

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ArrayType {
Dense,
Sparse,
Expand Down
4 changes: 4 additions & 0 deletions tiledb/test/src/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ use tiledb::context::Context;
pub fn arbitrary_name() -> impl Strategy<Value = String> {
proptest::string::string_regex("[a-zA-Z0-9_]*")
.expect("Error creating attribute name strategy")
.prop_filter(
"Attribute names may not begin with reserved prefix",
|name| !name.starts_with("__"),
)
}

pub fn arbitrary(context: &Context) -> impl Strategy<Value = Attribute> {
Expand Down
37 changes: 22 additions & 15 deletions tiledb/test/src/domain.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
use proptest::prelude::*;
use tiledb::array::{Domain, DomainBuilder};
use tiledb::array::{ArrayType, Domain, DomainBuilder};
use tiledb::context::Context;
use tiledb::Result as TileDBResult;

use crate::strategy::LifetimeBoundStrategy;

pub fn arbitrary(
context: &Context,
array_type: ArrayType,
) -> impl Strategy<Value = TileDBResult<Domain>> {
const MIN_DIMENSIONS: usize = 1;
const MAX_DIMENSIONS: usize = 8;

proptest::collection::vec(
crate::dimension::arbitrary(context),
MIN_DIMENSIONS..=MAX_DIMENSIONS,
)
.prop_map(|dimensions| {
let mut d = DomainBuilder::new(context)?;
for dim in dimensions {
d = d.add_dimension(dim?)?;
}
Ok(d.build())
})
match array_type {
ArrayType::Dense => unimplemented!(),
ArrayType::Sparse => proptest::collection::vec(
crate::dimension::arbitrary(context),
MIN_DIMENSIONS..=MAX_DIMENSIONS,
)
.prop_map(|dimensions| {
let mut d = DomainBuilder::new(context)?;
for dim in dimensions {
d = d.add_dimension(dim?)?;
}
Ok(d.build())
})
.bind(),
}
}

#[cfg(test)]
Expand All @@ -28,11 +35,11 @@ mod tests {

/// Test that the arbitrary domain construction always succeeds
#[test]
fn domain_arbitrary() {
fn domain_arbitrary_sparse() {
let ctx = Context::new().expect("Error creating context");

proptest!(|(maybe_domain in arbitrary(&ctx))| {
maybe_domain.expect("Error constructing arbitrary dimension");
proptest!(|(maybe_domain in arbitrary(&ctx, ArrayType::Sparse))| {
maybe_domain.expect("Error constructing arbitrary domain");
});
}
}
1 change: 1 addition & 0 deletions tiledb/test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ pub mod attribute;
pub mod datatype;
pub mod dimension;
pub mod domain;
pub mod schema;
pub mod strategy;
49 changes: 49 additions & 0 deletions tiledb/test/src/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use proptest::prelude::*;
use tiledb::array::{ArrayType, Schema, SchemaBuilder};
use tiledb::context::Context;
use tiledb::Result as TileDBResult;

pub fn arbitrary_array_type() -> impl Strategy<Value = ArrayType> {
// TODO: implement Domain scenario for Dense arrays
Just(ArrayType::Sparse)
}

pub fn arbitrary(
context: &Context,
) -> impl Strategy<Value = TileDBResult<Schema>> {
const MIN_ATTRS: usize = 1;
const MAX_ATTRS: usize = 128;

arbitrary_array_type()
.prop_flat_map(move |array_type|
(
Just(array_type),
crate::domain::arbitrary(context, array_type),
proptest::collection::vec(crate::attribute::arbitrary(context), MIN_ATTRS..=MAX_ATTRS)
))
.prop_map(|(array_type, domain, attrs)| {
/* TODO: cell order, tile order, capacity, duplicates */
let mut b = SchemaBuilder::new(context, array_type, domain?)?;
for attr in attrs {
/* TODO: how to ensure no duplicate names, assuming that matters? */
b = b.add_attribute(attr)?
}

Ok(b.build())
})
}

#[cfg(test)]
mod tests {
use super::*;

/// Test that the arbitrary schema construction always succeeds
#[test]
fn schema_arbitrary() {
let ctx = Context::new().expect("Error creating context");

proptest!(|(maybe_schema in arbitrary(&ctx))| {
maybe_schema.expect("Error constructing arbitrary schema");
});
}
}

0 comments on commit 460652a

Please sign in to comment.