From 3b2583c540c67ebf8276a550df8dd17ff574ba57 Mon Sep 17 00:00:00 2001 From: pedrocarlo Date: Tue, 7 Oct 2025 13:31:27 -0300 Subject: [PATCH] adjust Interaction generation to take into account possibilty of `PropertyDistribution` to have 0 Weights --- simulator/generation/plan.rs | 79 ++++++++++++++++---------------- simulator/generation/property.rs | 14 +++--- simulator/generation/query.rs | 5 +- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/simulator/generation/plan.rs b/simulator/generation/plan.rs index 836c24780..a468e87ec 100644 --- a/simulator/generation/plan.rs +++ b/simulator/generation/plan.rs @@ -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 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) } } diff --git a/simulator/generation/property.rs b/simulator/generation/property.rs index 8d6b4cb79..9df45db2e 100644 --- a/simulator/generation/property.rs +++ b/simulator/generation/property.rs @@ -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> { @@ -1940,21 +1943,20 @@ impl<'a> PropertyDistribution<'a> { remaining: &Remaining, query_distr: &'a QueryDistribution, ctx: &impl GenerationContext, - ) -> Self { + ) -> Result { 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, - } + }) } } diff --git a/simulator/generation/query.rs b/simulator/generation/query.rs index 3408dca3b..914b44b35 100644 --- a/simulator/generation/query.rs +++ b/simulator/generation/query.rs @@ -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,