use essential_node_db::{self as db, ConnectionPool};
use std::{sync::Arc, time::Duration};
use tempfile::TempDir;
use util::{register_contracts_block, test_conn_pool, test_contract_registry};
mod util;
#[test]
fn test_conn_pool_new() {
let _db = test_conn_pool();
}
#[test]
fn test_conn_pool_close() {
let db = test_conn_pool();
db.close().unwrap();
}
#[tokio::test]
async fn test_acquire() {
let db = test_conn_pool();
db.acquire().await.unwrap();
}
#[test]
fn test_try_acquire() {
let db = test_conn_pool();
db.try_acquire().unwrap();
}
#[tokio::test]
async fn test_conn_pool_path() {
let temp_dir = TempDir::new().unwrap();
let path = temp_dir.path().join("test_conn_pool_path.sqlite3");
let conf = db::pool::Config {
source: db::pool::Source::Path(path.clone()),
..Default::default()
};
let db = ConnectionPool::with_tables(&conf).unwrap();
let conn = db.acquire().await.unwrap();
conn.pragma_query(None, "trusted_schema", |row| {
let val = row.get::<_, bool>(0)?;
assert!(!val);
Ok(())
})
.unwrap();
conn.pragma_query(None, "foreign_keys", |row| {
let val = row.get::<_, bool>(0)?;
assert!(val);
Ok(())
})
.unwrap();
conn.pragma_query(None, "synchronous", |row| {
let val = row.get::<_, i64>(0)?;
assert_eq!(val, 1);
Ok(())
})
.unwrap();
drop(db);
let db = ConnectionPool::with_tables(&conf).unwrap();
let conn = db.acquire().await.unwrap();
conn.pragma_query(None, "journal_mode", |row| {
let val = row.get::<_, String>(0)?;
assert_eq!(val, "wal");
Ok(())
})
.unwrap();
}
#[tokio::test]
async fn test_create_tables() {
let db = test_conn_pool();
{
let conn = db.acquire().await.unwrap();
for table in essential_node_db::sql::table::ALL {
let query = format!(
"SELECT name FROM sqlite_master WHERE type='table' AND name='{}';",
table.name,
);
let result: String = conn
.query_row(&query, (), |row| row.get(0))
.unwrap_or_else(|_| panic!("Table {} does not exist", table.name));
assert_eq!(
result, table.name,
"Table {} was not created successfully",
table.name,
);
}
}
db.close().unwrap();
}
#[tokio::test]
async fn test_block() {
let db = test_conn_pool();
let blocks = util::test_blocks(100);
for block in &blocks {
let block = Arc::new(block.clone());
db.insert_block(block).await.unwrap();
}
let fetched = db.list_blocks(0..blocks.len() as _).await.unwrap();
assert_eq!(blocks, fetched);
db.close().unwrap();
}
#[tokio::test]
async fn test_contract() {
let db = test_conn_pool();
let seed = 42;
let contract = util::test_contract(seed);
let registry = test_contract_registry();
let block =
register_contracts_block(registry, Some(&contract), 42, Duration::from_secs(42)).unwrap();
db.insert_block(block.into()).await.unwrap();
let _ca = essential_hash::content_addr(&contract);
db.close().unwrap();
}
#[tokio::test]
async fn test_state() {
let db = test_conn_pool();
let seed = 36;
let number = 100;
let contract = util::test_contract(seed);
let mut keys = vec![];
let mut values = vec![];
for i in 0i64..1024 {
let key = vec![(i + 1) * 5; ((i + 1) as usize * 103) % 128];
let value = vec![(i + 1) * 7; ((i + 1) as usize * 391) % 128];
keys.push(key);
values.push(value);
}
let registry = test_contract_registry();
let timestamp = Duration::from_secs(42);
let block = register_contracts_block(registry, Some(&contract), number, timestamp).unwrap();
db.insert_block(block.into()).await.unwrap();
let contract_ca = essential_hash::content_addr(&contract);
let mut handles = vec![];
for (k, v) in keys.iter().zip(&values) {
let db = db.clone();
let ca = contract_ca.clone();
let (key, value) = (k.clone(), v.clone());
let handle = tokio::spawn(async move { db.update_state(ca, key, value).await });
handles.push(handle);
}
for handle in handles {
handle.await.unwrap().unwrap();
}
let mut handles = vec![];
for k in keys.iter() {
let db = db.clone();
let ca = contract_ca.clone();
let key = k.clone();
handles.push(tokio::spawn(async move { db.query_state(ca, key).await }));
}
let mut fetched = vec![];
for handle in handles {
let value = handle.await.unwrap().unwrap().unwrap();
fetched.push(value);
}
assert_eq!(values, fetched);
for k in &keys {
db.delete_state(contract_ca.clone(), k.clone())
.await
.unwrap();
}
for k in &keys {
let opt = db
.query_state(contract_ca.clone(), k.clone())
.await
.unwrap();
assert!(opt.is_none());
}
db.close().unwrap();
}