From dc0d4e2dcb1bc60f3e4d54df99476c2fa7ab7b8f Mon Sep 17 00:00:00 2001 From: pedrocarlo Date: Wed, 1 Oct 2025 14:11:30 -0300 Subject: [PATCH] print diffs in assert tables --- simulator/common/mod.rs | 46 ++++++++++++++++++++++++++++++++ simulator/generation/property.rs | 12 ++++++--- simulator/main.rs | 1 + 3 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 simulator/common/mod.rs diff --git a/simulator/common/mod.rs b/simulator/common/mod.rs new file mode 100644 index 000000000..83740cd83 --- /dev/null +++ b/simulator/common/mod.rs @@ -0,0 +1,46 @@ +use itertools::Itertools; +use sql_generation::model::table::SimValue; + +fn val_to_string(sim_val: &SimValue) -> String { + match &sim_val.0 { + turso_core::Value::Blob(blob) => { + let convert_blob = || -> anyhow::Result { + let val = String::from_utf8(blob.clone())?; + Ok(val) + }; + + convert_blob().unwrap_or_else(|_| sim_val.to_string()) + } + _ => sim_val.to_string(), + } +} + +pub fn print_diff( + left: &[Vec], + right: &[Vec], + left_label: &str, + right_label: &str, +) { + let left_vals: Vec> = left + .iter() + .map(|rows| rows.iter().map(val_to_string).collect()) + .sorted() + .collect(); + + let right_vals: Vec> = right + .iter() + .map(|rows| rows.iter().map(val_to_string).collect()) + .sorted() + .collect(); + + let simulator_string = format!("{left_vals:#?}"); + let db_string = format!("{right_vals:#?}"); + + let diff = similar_asserts::SimpleDiff::from_str( + &simulator_string, + &db_string, + left_label, + right_label, + ); + tracing::error!(%diff); +} diff --git a/simulator/generation/property.rs b/simulator/generation/property.rs index d741748fa..4db258047 100644 --- a/simulator/generation/property.rs +++ b/simulator/generation/property.rs @@ -16,6 +16,7 @@ use turso_core::{LimboError, types}; use turso_parser::ast::{self, Distinctness}; use crate::{ + common::print_diff, generation::{Shadow as _, plan::InteractionType}, model::Query, profiles::query::QueryProfile, @@ -1085,20 +1086,21 @@ fn assert_all_table_values( // Check if all values in the table are present in the result set // Find a value in the table that is not in the result set let model_contains_db = table.rows.iter().find(|v| { - !vals.iter().any(|r| { - &r == v - }) + !vals.contains(v) }); let db_contains_model = vals.iter().find(|v| { - !table.rows.iter().any(|r| &r == v) + !table.rows.contains(v) }); + if let Some(model_contains_db) = model_contains_db { tracing::debug!( "table {} does not contain the expected values, the simulator model has more rows than the database: {:?}", table.name, print_row(model_contains_db) ); + print_diff(&table.rows, vals, "simulator", "database"); + Ok(Err(format!("table {} does not contain the expected values, the simulator model has more rows than the database: {:?}", table.name, print_row(model_contains_db)))) } else if let Some(db_contains_model) = db_contains_model { tracing::debug!( @@ -1106,6 +1108,8 @@ fn assert_all_table_values( table.name, print_row(db_contains_model) ); + print_diff(&table.rows, vals, "simulator", "database"); + Ok(Err(format!("table {} does not contain the expected values, the database has more rows than the simulator model: {:?}", table.name, print_row(db_contains_model)))) } else { Ok(Ok(())) diff --git a/simulator/main.rs b/simulator/main.rs index ec63062ea..65b8bb3a6 100644 --- a/simulator/main.rs +++ b/simulator/main.rs @@ -27,6 +27,7 @@ use crate::profiles::Profile; use crate::runner::doublecheck; use crate::runner::env::{Paths, SimulationPhase, SimulationType}; +mod common; mod generation; mod model; mod profiles;