fix formatting

This commit is contained in:
alpaylan 2024-12-16 10:49:56 -05:00
parent be18c6e8f0
commit 53ecedaceb
8 changed files with 79 additions and 31 deletions

View file

@ -1,2 +1,74 @@
# Simulator
# Limbo Simulator
Limbo simulator uses randomized deterministic simulations to test the Limbo database behaviors.
Each simulations begins with a random configurations;
- the database workload distribution(percentages of reads, writes, deletes...),
- database parameters(page size),
- number of reader or writers, etc.
Based on these parameters, we randomly generate **interaction plans**. Interaction plans consist of statements/queries, and assertions that will be executed in order. The building blocks of interaction plans are;
- Randomly generated SQL queries satisfying the workload distribution,
- Properties, which contain multiple matching queries with assertions indicating the expected result.
An example of a property is the following:
```json
{
"name": "Read your own writes",
"queries": [
"INSERT INTO t1 (id) VALUES (1)",
"SELECT * FROM t1 WHERE id = 1",
],
"assertions": [
"result.rows.length == 1",
"result.rows[0].id == 1"
]
}
```
The simulator executes the interaction plans in a loop, and checks the assertions. It can add random queries unrelated to the properties without
breaking the property invariants to reach more diverse states and respect the configured workload distribution.
The simulator code is broken into 4 main parts:
- **Simulator(main.rs)**: The main entry point of the simulator. It generates random configurations and interaction plans, and executes them.
- **Model(model.rs, model/table.rs, model/query.rs)**: A simpler model of the database, it contains atomic actions for insertion and selection, we use this model while deciding the next actions.
- **Generation(generation.rs, generation/table.rs, generation/query.rs, generation/plan.rs)**: Random generation functions for the database model and interaction plans.
- **Properties(properties.rs)**: Contains the properties that we want to test.
## Running the simulator
To run the simulator, you can use the following command:
```bash
cargo run
```
This prompt (in the future) will invoke a clap command line interface to configure the simulator. For now, the simulator runs with the default configurations changing the `main.rs` file. If you want to see the logs, you can change the `RUST_LOG` environment variable.
```bash
RUST_LOG=info cargo run --bin limbo_sim
```
## Adding new properties
Todo
## Adding new generation functions
Todo
## Adding new models
Todo
## Coverage with Limbo
Todo
## Automatic Compatibility Testing with SQLite
Todo

View file

@ -1,8 +1,8 @@
use anarchist_readable_name_generator_lib::readable_name_custom;
use rand::Rng;
pub mod table;
pub mod query;
pub mod table;
pub trait Arbitrary {
fn arbitrary<R: Rng>(rng: &mut R) -> Self;
@ -12,7 +12,6 @@ pub trait ArbitraryFrom<T> {
fn arbitrary_from<R: Rng>(rng: &mut R, t: &T) -> Self;
}
fn gen_random_text<T: Rng>(rng: &mut T) -> String {
let big_text = rng.gen_ratio(1, 1000);
if big_text {
@ -28,5 +27,3 @@ fn gen_random_text<T: Rng>(rng: &mut T) -> String {
name.replace("-", "_")
}
}

View file

@ -1,12 +1,10 @@
use crate::generation::table::{GTValue, LTValue};
use crate::generation::{Arbitrary, ArbitraryFrom};
use crate::generation::table::{LTValue, GTValue};
use crate::model::query::{Create, Delete, Insert, Predicate, Query, Select};
use crate::model::table::{Table, Value};
use rand::Rng;
impl Arbitrary for Create {
fn arbitrary<R: Rng>(rng: &mut R) -> Self {
Create {
@ -15,7 +13,6 @@ impl Arbitrary for Create {
}
}
impl ArbitraryFrom<Vec<Table>> for Select {
fn arbitrary_from<R: Rng>(rng: &mut R, tables: &Vec<Table>) -> Self {
let table = rng.gen_range(0..tables.len());
@ -36,7 +33,6 @@ impl ArbitraryFrom<Vec<&Table>> for Select {
}
}
impl ArbitraryFrom<Table> for Insert {
fn arbitrary_from<R: Rng>(rng: &mut R, table: &Table) -> Self {
let values = table
@ -51,7 +47,6 @@ impl ArbitraryFrom<Table> for Insert {
}
}
impl ArbitraryFrom<Table> for Delete {
fn arbitrary_from<R: Rng>(rng: &mut R, table: &Table) -> Self {
Delete {
@ -75,7 +70,6 @@ impl ArbitraryFrom<Table> for Query {
}
}
struct CompoundPredicate(Predicate);
struct SimplePredicate(Predicate);

View file

@ -1,7 +1,6 @@
use rand::Rng;
use crate::generation::{Arbitrary, ArbitraryFrom, readable_name_custom, gen_random_text};
use crate::generation::{gen_random_text, readable_name_custom, Arbitrary, ArbitraryFrom};
use crate::model::table::{Column, ColumnType, Name, Table, Value};
impl Arbitrary for Name {
@ -11,7 +10,6 @@ impl Arbitrary for Name {
}
}
impl Arbitrary for Table {
fn arbitrary<R: Rng>(rng: &mut R) -> Self {
let name = Name::arbitrary(rng).0;
@ -39,7 +37,6 @@ impl Arbitrary for Column {
}
}
impl Arbitrary for ColumnType {
fn arbitrary<R: Rng>(rng: &mut R) -> Self {
match rng.gen_range(0..4) {
@ -193,4 +190,3 @@ impl ArbitraryFrom<Value> for GTValue {
}
}
}

View file

@ -1,7 +1,7 @@
use generation::{Arbitrary, ArbitraryFrom};
use limbo_core::{Connection, Database, File, OpenFlags, PlatformIO, Result, RowResult, IO};
use model::table::{Column, Name, Table, Value};
use model::query::{Insert, Predicate, Query, Select};
use model::table::{Column, Name, Table, Value};
use properties::{property_insert_select, property_select_all};
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
@ -11,8 +11,8 @@ use std::sync::Arc;
use tempfile::TempDir;
mod generation;
mod properties;
mod model;
mod properties;
struct SimulatorEnv {
opts: SimulatorOpts,
@ -49,8 +49,6 @@ struct SimulatorOpts {
page_size: usize,
}
#[allow(clippy::arc_with_non_send_sync)]
fn main() {
let _ = env_logger::try_init();
@ -137,7 +135,6 @@ fn main() {
env.io.print_stats();
}
fn process_connection(env: &mut SimulatorEnv, conn: &mut Rc<Connection>) -> Result<()> {
if env.tables.is_empty() {
maybe_add_table(env, conn)?;
@ -250,8 +247,6 @@ fn maybe_add_table(env: &mut SimulatorEnv, conn: &mut Rc<Connection>) -> Result<
Ok(())
}
fn get_all_rows(
env: &mut SimulatorEnv,
conn: &mut Rc<Connection>,
@ -477,4 +472,3 @@ impl Drop for SimulatorFile {
self.inner.unlock_file().expect("Failed to unlock file");
}
}

View file

@ -1,3 +1,2 @@
pub mod table;
pub mod query;
pub mod table;

View file

@ -2,7 +2,6 @@ use std::fmt::Display;
use crate::model::table::{Table, Value};
#[derive(Clone, Debug, PartialEq)]
pub(crate) enum Predicate {
And(Vec<Predicate>), // p1 AND p2 AND p3... AND pn
@ -108,4 +107,3 @@ impl Display for Query {
}
}
}

View file

@ -1,4 +1,3 @@
use std::{fmt::Display, ops::Deref};
pub(crate) struct Name(pub(crate) String);
@ -88,4 +87,3 @@ impl Display for Value {
}
}
}