use essential_builder_db::{self as builder_db};
use essential_builder_types::SolutionSetFailure;
use rusqlite::Connection;
use std::time::Duration;
mod util;
#[test]
fn get_solution_set() {
let solution_sets: Vec<_> = util::test_blocks(10)
.into_iter()
.flat_map(|b| {
b.solution_sets
.into_iter()
.map(move |s| (s, b.header.timestamp))
})
.collect();
let mut conn = Connection::open_in_memory().unwrap();
let tx = conn.transaction().unwrap();
builder_db::create_tables(&tx).unwrap();
for (solution_set, timestamp) in &solution_sets {
builder_db::insert_solution_set_submission(&tx, solution_set, *timestamp).unwrap();
}
tx.commit().unwrap();
for (expected_solution_set, _ts) in &solution_sets {
let ca = essential_hash::content_addr(expected_solution_set);
let solution_set = builder_db::get_solution_set(&conn, &ca).unwrap().unwrap();
assert_eq!(expected_solution_set, &solution_set);
}
}
#[test]
fn list_solution_sets() {
let solution_sets: Vec<_> = util::test_blocks(10)
.into_iter()
.flat_map(|b| {
b.solution_sets
.into_iter()
.map(move |s| (s, b.header.timestamp))
})
.collect();
let mut conn = Connection::open_in_memory().unwrap();
let tx = conn.transaction().unwrap();
builder_db::create_tables(&tx).unwrap();
for (solution_set, timestamp) in &solution_sets {
builder_db::insert_solution_set_submission(&tx, solution_set, *timestamp).unwrap();
}
tx.commit().unwrap();
let min = Duration::ZERO;
let max = Duration::from_secs(i64::MAX as u64);
let range = min..max;
let limit = i64::MAX;
let fetched_solution_sets =
builder_db::list_solution_sets(&conn, range.clone(), limit).unwrap();
for (expected, fetched) in solution_sets.iter().zip(&fetched_solution_sets) {
let (expected_solution_set, expected_ts) = expected;
let (ca, solution_set, ts) = fetched;
assert_eq!(expected_solution_set, solution_set);
assert_eq!(expected_ts, ts);
assert_eq!(&essential_hash::content_addr(solution_set), ca);
}
let pre_occurrences = fetched_solution_sets
.iter()
.filter(|(ca, _, _)| essential_hash::content_addr(&solution_sets[0].0) == *ca)
.count();
const NUM_ADDED: usize = 4;
let tx = conn.transaction().unwrap();
for (solution_set, timestamp) in (0..NUM_ADDED).map(|_| &solution_sets[0]) {
builder_db::insert_solution_set_submission(&tx, solution_set, *timestamp).unwrap();
}
tx.commit().unwrap();
let fetched_solution_sets = builder_db::list_solution_sets(&conn, range, limit).unwrap();
let post_occurrences = fetched_solution_sets
.iter()
.filter(|(ca, _, _)| essential_hash::content_addr(&solution_sets[0].0) == *ca)
.count();
assert_eq!(pre_occurrences + NUM_ADDED, post_occurrences);
}
#[test]
fn list_submissions() {
let solution_sets: Vec<_> = util::test_blocks(10)
.into_iter()
.flat_map(|b| {
b.solution_sets
.into_iter()
.map(move |s| (s, b.header.timestamp))
})
.collect();
let mut conn = Connection::open_in_memory().unwrap();
let tx = conn.transaction().unwrap();
builder_db::create_tables(&tx).unwrap();
for (solution_set, timestamp) in &solution_sets {
builder_db::insert_solution_set_submission(&tx, solution_set, *timestamp).unwrap();
}
tx.commit().unwrap();
let min = Duration::ZERO;
let max = Duration::from_secs(i64::MAX as u64);
let range_all = min..max;
let limit = i64::MAX;
let submissions = builder_db::list_submissions(&conn, range_all.clone(), limit).unwrap();
let expected_submissions: Vec<_> = solution_sets
.iter()
.map(|(s, ts)| (essential_hash::content_addr(s), *ts))
.collect();
assert_eq!(&expected_submissions, &submissions);
let queried_solution_sets: Vec<_> = submissions
.iter()
.map(|(ca, ts)| {
let solution_set = builder_db::get_solution_set(&conn, ca).unwrap().unwrap();
(solution_set, *ts)
})
.collect();
assert_eq!(&solution_sets, &queried_solution_sets);
let min = Duration::from_secs(1);
let max = Duration::from_secs(4);
let range = min..max;
let submissions = builder_db::list_submissions(&conn, range.clone(), limit).unwrap();
for (_ca, timestamp) in &submissions {
assert!(range.contains(timestamp));
}
let limit = 3;
let submissions = builder_db::list_submissions(&conn, range_all, limit).unwrap();
assert_eq!(submissions.len(), limit as usize);
let tx = conn.transaction().unwrap();
for (solution_set, _) in &solution_sets {
let ca = essential_hash::content_addr(solution_set);
builder_db::delete_solution_set(&tx, &ca).unwrap();
}
tx.commit().unwrap();
let min = Duration::ZERO;
let max = Duration::from_secs(i64::MAX as u64);
let range_all = min..max;
let limit = i64::MAX;
let submissions = builder_db::list_submissions(&conn, range_all.clone(), limit).unwrap();
assert!(submissions.is_empty());
}
#[test]
fn latest_solution_set_failures() {
let block = util::test_block(0, Duration::from_secs(0));
let block_ca = essential_hash::content_addr(&block);
let solution_set = block.solution_sets[0].clone();
let ca = essential_hash::content_addr(&solution_set);
let mut conn = Connection::open_in_memory().unwrap();
let tx = conn.transaction().unwrap();
builder_db::create_tables(&tx).unwrap();
builder_db::insert_solution_set_submission(&tx, &solution_set, block.header.timestamp).unwrap();
tx.commit().unwrap();
let failures = vec![
SolutionSetFailure {
attempt_block_num: 1,
attempt_block_addr: block_ca.clone(),
attempt_solution_set_ix: 0,
err_msg: "Failure 1".into(),
},
SolutionSetFailure {
attempt_block_num: 2,
attempt_block_addr: block_ca.clone(),
attempt_solution_set_ix: 1,
err_msg: "Failure 2".into(),
},
SolutionSetFailure {
attempt_block_num: 3,
attempt_block_addr: block_ca,
attempt_solution_set_ix: 2,
err_msg: "Failure 3".into(),
},
];
for failure in &failures {
builder_db::insert_solution_set_failure(&conn, &ca, failure.clone()).unwrap();
}
let latest_failures = builder_db::latest_solution_set_failures(&conn, &ca, 2).unwrap();
assert_eq!(latest_failures.len(), 2);
assert_eq!(latest_failures[0], failures[2]); assert_eq!(latest_failures[1], failures[1]); }
#[test]
fn list_solution_set_failures() {
let block = util::test_block(0, Duration::from_secs(0));
let block_ca = essential_hash::content_addr(&block);
let solution_set = block.solution_sets[0].clone();
let ca = essential_hash::content_addr(&solution_set);
let mut conn = Connection::open_in_memory().unwrap();
let tx = conn.transaction().unwrap();
builder_db::create_tables(&tx).unwrap();
builder_db::insert_solution_set_submission(&tx, &solution_set, block.header.timestamp).unwrap();
tx.commit().unwrap();
let failures = vec![
SolutionSetFailure {
attempt_block_num: 1,
attempt_block_addr: block_ca.clone(),
attempt_solution_set_ix: 0,
err_msg: "Failure 1".into(),
},
SolutionSetFailure {
attempt_block_num: 2,
attempt_block_addr: block_ca.clone(),
attempt_solution_set_ix: 1,
err_msg: "Failure 2".into(),
},
SolutionSetFailure {
attempt_block_num: 3,
attempt_block_addr: block_ca,
attempt_solution_set_ix: 2,
err_msg: "Failure 3".into(),
},
];
for failure in &failures {
builder_db::insert_solution_set_failure(&conn, &ca, failure.clone()).unwrap();
}
let latest_failures = builder_db::list_solution_set_failures(&conn, 0, 2).unwrap();
assert_eq!(latest_failures.len(), 2);
assert_eq!(latest_failures[0], failures[2]); assert_eq!(latest_failures[1], failures[1]); }