mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-01 06:14:23 +01:00
add fuzz tests for raw WAL API
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use rand::{rng, RngCore};
|
||||
use rand::{rng, RngCore, SeedableRng};
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
use rusqlite::params;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
@@ -238,6 +239,15 @@ pub(crate) fn limbo_exec_rows_error(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn rng_from_time() -> (ChaCha8Rng, u64) {
|
||||
let seed = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs();
|
||||
let rng = ChaCha8Rng::seed_from_u64(seed);
|
||||
(rng, seed)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::vec;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use rand::{RngCore, SeedableRng};
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
use rusqlite::types::Value;
|
||||
|
||||
use crate::common::{limbo_exec_rows, TempDatabase};
|
||||
use crate::common::{limbo_exec_rows, rng_from_time, TempDatabase};
|
||||
|
||||
#[test]
|
||||
fn test_wal_frame_count() {
|
||||
@@ -142,3 +144,63 @@ fn test_wal_frame_far_away_write() {
|
||||
db1.io.wait_for_completion(c).unwrap();
|
||||
assert!(conn2.wal_insert_frame(5, &frame).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wal_frame_api_no_schema_changes_fuzz() {
|
||||
let (mut rng, _) = rng_from_time();
|
||||
for _ in 0..4 {
|
||||
let db1 = TempDatabase::new_empty(false);
|
||||
let conn1 = db1.connect_limbo();
|
||||
let db2 = TempDatabase::new_empty(false);
|
||||
let conn2 = db2.connect_limbo();
|
||||
conn1
|
||||
.execute("CREATE TABLE t(x INTEGER PRIMARY KEY, y)")
|
||||
.unwrap();
|
||||
conn2
|
||||
.execute("CREATE TABLE t(x INTEGER PRIMARY KEY, y)")
|
||||
.unwrap();
|
||||
|
||||
let seed = rng.next_u64();
|
||||
let mut rng = ChaCha8Rng::seed_from_u64(seed);
|
||||
println!("SEED: {}", seed);
|
||||
|
||||
let (mut size, mut synced_frame) = (0, conn2.wal_frame_count().unwrap());
|
||||
let mut commit_frames = vec![conn1.wal_frame_count().unwrap()];
|
||||
for _ in 0..256 {
|
||||
if rng.next_u32() % 10 != 0 {
|
||||
let key = rng.next_u32();
|
||||
let length = rng.next_u32() % (4 * 4096);
|
||||
let query = format!("INSERT INTO t VALUES ({}, randomblob({}))", key, length);
|
||||
// println!("{}", query);
|
||||
conn1.execute(&query).unwrap();
|
||||
commit_frames.push(conn1.wal_frame_count().unwrap());
|
||||
} else {
|
||||
let last_frame = conn1.wal_frame_count().unwrap();
|
||||
let next_frame =
|
||||
synced_frame + (rng.next_u32() as u64 % (last_frame - synced_frame + 1));
|
||||
let mut frame = [0u8; 24 + 4096];
|
||||
// println!("sync WAL frames: [{}..{}]", synced_frame + 1, next_frame);
|
||||
conn2.wal_insert_begin().unwrap();
|
||||
for frame_no in (synced_frame + 1)..=next_frame {
|
||||
let c = conn1.wal_get_frame(frame_no as u32, &mut frame).unwrap();
|
||||
db1.io.wait_for_completion(c).unwrap();
|
||||
conn2.wal_insert_frame(frame_no as u32, &frame[..]).unwrap();
|
||||
}
|
||||
conn2.wal_insert_end().unwrap();
|
||||
for (i, committed) in commit_frames.iter().enumerate() {
|
||||
if *committed <= next_frame {
|
||||
size = size.max(i);
|
||||
synced_frame = *committed;
|
||||
}
|
||||
}
|
||||
if rng.next_u32() % 10 == 0 {
|
||||
synced_frame = rng.next_u32() as u64 % synced_frame;
|
||||
}
|
||||
assert_eq!(
|
||||
limbo_exec_rows(&db2, &conn2, "SELECT COUNT(*) FROM t"),
|
||||
vec![vec![Value::Integer(size as i64)]]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,21 +10,12 @@ mod tests {
|
||||
use rusqlite::params;
|
||||
|
||||
use crate::{
|
||||
common::{limbo_exec_rows, sqlite_exec_rows, TempDatabase},
|
||||
common::{limbo_exec_rows, rng_from_time, sqlite_exec_rows, TempDatabase},
|
||||
fuzz::grammar_generator::{const_str, rand_int, rand_str, GrammarGenerator},
|
||||
};
|
||||
|
||||
use super::grammar_generator::SymbolHandle;
|
||||
|
||||
fn rng_from_time() -> (ChaCha8Rng, u64) {
|
||||
let seed = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs();
|
||||
let rng = ChaCha8Rng::seed_from_u64(seed);
|
||||
(rng, seed)
|
||||
}
|
||||
|
||||
/// [See this issue for more info](https://github.com/tursodatabase/turso/issues/1763)
|
||||
#[test]
|
||||
pub fn fuzz_failure_issue_1763() {
|
||||
|
||||
Reference in New Issue
Block a user