adjust Interaction generation to take into account possibilty of PropertyDistribution to have 0 Weights

This commit is contained in:
pedrocarlo
2025-10-07 13:31:27 -03:00
parent c578f7ba96
commit 3b2583c540
3 changed files with 51 additions and 47 deletions

View File

@@ -1242,46 +1242,45 @@ impl ArbitraryFrom<(&SimulatorEnv, InteractionStats, usize)> for Interactions {
let queries = possible_queries(conn_ctx.tables());
let query_distr = QueryDistribution::new(queries, &remaining_);
let property_distr = PropertyDistribution::new(env, &remaining_, &query_distr, conn_ctx);
#[allow(clippy::type_complexity)]
let mut choices: Vec<(u32, Box<dyn Fn(&mut R) -> Interactions>)> = vec![
(
query_distr.weights().total_weight(),
Box::new(|rng: &mut R| {
Interactions::new(
conn_index,
InteractionsType::Query(Query::arbitrary_from(rng, conn_ctx, &query_distr)),
)
}),
),
(
remaining_
.select
.min(remaining_.insert)
.min(remaining_.create)
.max(1),
Box::new(|rng: &mut R| random_fault(rng, env, conn_index)),
),
];
frequency(
vec![
(
property_distr.weights().total_weight(),
Box::new(|rng: &mut R| {
Interactions::new(
conn_index,
InteractionsType::Property(Property::arbitrary_from(
rng,
conn_ctx,
&property_distr,
)),
)
}),
),
(
query_distr.weights().total_weight(),
Box::new(|rng: &mut R| {
Interactions::new(
conn_index,
InteractionsType::Query(Query::arbitrary_from(
rng,
conn_ctx,
&query_distr,
)),
)
}),
),
(
remaining_
.select
.min(remaining_.insert)
.min(remaining_.create)
.max(1),
Box::new(|rng: &mut R| random_fault(rng, env, conn_index)),
),
],
rng,
)
if let Ok(property_distr) =
PropertyDistribution::new(env, &remaining_, &query_distr, conn_ctx)
{
choices.push((
property_distr.weights().total_weight(),
Box::new(move |rng: &mut R| {
Interactions::new(
conn_index,
InteractionsType::Property(Property::arbitrary_from(
rng,
conn_ctx,
&property_distr,
)),
)
}),
));
};
frequency(choices, rng)
}
}

View File

@@ -274,7 +274,10 @@ impl Property {
/// Property Does some sort of fault injection
pub fn check_tables(&self) -> bool {
matches!(self, Property::FsyncNoWait { .. } | Property::FaultyQuery { .. })
matches!(
self,
Property::FsyncNoWait { .. } | Property::FaultyQuery { .. }
)
}
pub fn get_extensional_queries(&mut self) -> Option<&mut Vec<Query>> {
@@ -1940,21 +1943,20 @@ impl<'a> PropertyDistribution<'a> {
remaining: &Remaining,
query_distr: &'a QueryDistribution,
ctx: &impl GenerationContext,
) -> Self {
) -> Result<Self, rand::distr::weighted::Error> {
let properties = PropertyDiscriminants::can_generate(query_distr.items());
let weights = WeightedIndex::new(
properties
.iter()
.map(|property| property.weight(env, remaining, ctx)),
)
.unwrap();
)?;
Self {
Ok(Self {
properties,
weights,
query_distr,
mvcc: env.profile.experimental_mvcc,
}
})
}
}

View File

@@ -120,7 +120,9 @@ impl QueryDiscriminants {
pub fn weight(&self, remaining: &Remaining) -> u32 {
match self {
QueryDiscriminants::Create => remaining.create,
QueryDiscriminants::Select => remaining.select + remaining.select / 3, // remaining.select / 3 is for the random_expr generation
// remaining.select / 3 is for the random_expr generation
// have a max of 1 so that we always generate at least a non zero weight for `QueryDistribution`
QueryDiscriminants::Select => (remaining.select + remaining.select / 3).max(1),
QueryDiscriminants::Insert => remaining.insert,
QueryDiscriminants::Delete => remaining.delete,
QueryDiscriminants::Update => remaining.update,
@@ -138,6 +140,7 @@ impl QueryDiscriminants {
}
}
#[derive(Debug)]
pub(super) struct QueryDistribution {
queries: &'static [QueryDiscriminants],
weights: WeightedIndex<u32>,