fix non-determinism bug arising from a call to thread_rng while picking

which row to check existence for in the result of the select query
This commit is contained in:
alpaylan
2025-01-13 17:26:23 +03:00
parent c3ea02783d
commit fb937eff7b
3 changed files with 13 additions and 6 deletions

View File

@@ -7,7 +7,7 @@ use crate::{
}; };
use super::{ use super::{
frequency, pick, frequency, pick, pick_index,
plan::{Assertion, Interaction, InteractionStats, ResultSet}, plan::{Assertion, Interaction, InteractionStats, ResultSet},
ArbitraryFrom, ArbitraryFrom,
}; };
@@ -34,6 +34,8 @@ pub(crate) enum Property {
InsertSelect { InsertSelect {
/// The insert query /// The insert query
insert: Insert, insert: Insert,
/// Selected row index
row_index: usize,
/// Additional interactions in the middle of the property /// Additional interactions in the middle of the property
queries: Vec<Query>, queries: Vec<Query>,
/// The select query /// The select query
@@ -73,6 +75,7 @@ impl Property {
match self { match self {
Property::InsertSelect { Property::InsertSelect {
insert, insert,
row_index,
queries, queries,
select, select,
} => { } => {
@@ -83,7 +86,7 @@ impl Property {
); );
// Pick a random row within the insert values // Pick a random row within the insert values
let row = pick(&insert.values, &mut rand::thread_rng()).clone(); let row = insert.values[*row_index].clone();
// Assume that the table exists // Assume that the table exists
let assumption = Interaction::Assumption(Assertion { let assumption = Interaction::Assumption(Assertion {
@@ -202,7 +205,8 @@ fn property_insert_select<R: rand::Rng>(
.collect::<Vec<_>>(); .collect::<Vec<_>>();
// Pick a random row to select // Pick a random row to select
let row = pick(&rows, rng).clone(); let row_index = pick_index(rows.len(), rng).clone();
let row = rows[row_index].clone();
// Insert the rows // Insert the rows
let insert_query = Insert { let insert_query = Insert {
@@ -248,6 +252,7 @@ fn property_insert_select<R: rand::Rng>(
Property::InsertSelect { Property::InsertSelect {
insert: insert_query, insert: insert_query,
row_index,
queries, queries,
select: select_query, select: select_query,
} }

View File

@@ -218,7 +218,7 @@ fn main() -> Result<(), String> {
last_execution, last_execution,
); );
match (shrunk, &result) { match (&shrunk, &result) {
( (
SandboxedResult::Panicked { error: e1, .. }, SandboxedResult::Panicked { error: e1, .. },
SandboxedResult::Panicked { error: e2, .. }, SandboxedResult::Panicked { error: e2, .. },
@@ -227,7 +227,7 @@ fn main() -> Result<(), String> {
SandboxedResult::FoundBug { error: e1, .. }, SandboxedResult::FoundBug { error: e1, .. },
SandboxedResult::FoundBug { error: e2, .. }, SandboxedResult::FoundBug { error: e2, .. },
) => { ) => {
if &e1 != e2 { if e1 != e2 {
log::error!( log::error!(
"shrinking failed, the error was not properly reproduced" "shrinking failed, the error was not properly reproduced"
); );
@@ -291,6 +291,7 @@ fn revert_db_and_plan_files(output_dir: &Path) {
std::fs::rename(&new_plan_path, &old_plan_path).unwrap(); std::fs::rename(&new_plan_path, &old_plan_path).unwrap();
} }
#[derive(Debug)]
enum SandboxedResult { enum SandboxedResult {
Panicked { Panicked {
error: String, error: String,

View File

@@ -9,7 +9,7 @@ use crate::generation::{
use super::env::{SimConnection, SimulatorEnv}; use super::env::{SimConnection, SimulatorEnv};
#[derive(Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub(crate) struct Execution { pub(crate) struct Execution {
pub(crate) connection_index: usize, pub(crate) connection_index: usize,
pub(crate) interaction_index: usize, pub(crate) interaction_index: usize,
@@ -30,6 +30,7 @@ impl Execution {
} }
} }
#[derive(Debug)]
pub(crate) struct ExecutionHistory { pub(crate) struct ExecutionHistory {
pub(crate) history: Vec<Execution>, pub(crate) history: Vec<Execution>,
} }