zebra-state: Add support for temporary sled databases (#939)
* Test config with persistent sled database * Test ephemeral config * Add misconfigured ephemeral test
This commit is contained in:
parent
d25cc20319
commit
ad0001f7f7
|
@ -123,33 +123,35 @@ where
|
|||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn batch_flushes_on_max_items() {
|
||||
async fn batch_flushes_on_max_items() -> Result<(), Report> {
|
||||
use tokio::time::timeout;
|
||||
zebra_test::init();
|
||||
|
||||
// Use a very long max_latency and a short timeout to check that
|
||||
// flushing is happening based on hitting max_items.
|
||||
let verifier = Batch::new(Ed25519Verifier::new(), 10, Duration::from_secs(1000));
|
||||
assert!(
|
||||
timeout(Duration::from_secs(1), sign_and_verify(verifier, 100, None))
|
||||
.await
|
||||
.is_ok()
|
||||
);
|
||||
timeout(Duration::from_secs(1), sign_and_verify(verifier, 100, None))
|
||||
.await
|
||||
.map_err(|e| eyre!(e))?
|
||||
.map_err(|e| eyre!(e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn batch_flushes_on_max_latency() {
|
||||
async fn batch_flushes_on_max_latency() -> Result<(), Report> {
|
||||
use tokio::time::timeout;
|
||||
zebra_test::init();
|
||||
|
||||
// Use a very high max_items and a short timeout to check that
|
||||
// flushing is happening based on hitting max_latency.
|
||||
let verifier = Batch::new(Ed25519Verifier::new(), 100, Duration::from_millis(500));
|
||||
assert!(
|
||||
timeout(Duration::from_secs(1), sign_and_verify(verifier, 10, None))
|
||||
.await
|
||||
.is_ok()
|
||||
);
|
||||
timeout(Duration::from_secs(1), sign_and_verify(verifier, 10, None))
|
||||
.await
|
||||
.map_err(|e| eyre!(e))?
|
||||
.map_err(|e| eyre!(e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
|
|
@ -69,6 +69,13 @@ pub struct Config {
|
|||
|
||||
/// The maximum number of bytes to use caching data in memory.
|
||||
pub memory_cache_bytes: u64,
|
||||
|
||||
/// Whether to use an ephemeral database.
|
||||
///
|
||||
/// Ephemeral databases are stored in memory on Linux, and in a temporary directory on other OSes.
|
||||
///
|
||||
/// Set to `false` by default. If this is set to `true`, [`cache_dir`] is ignored.
|
||||
pub ephemeral: bool,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
|
@ -79,12 +86,16 @@ impl Config {
|
|||
Network::Mainnet => "mainnet",
|
||||
Network::Testnet => "testnet",
|
||||
};
|
||||
let path = self.cache_dir.join(net_dir).join("state");
|
||||
|
||||
sled::Config::default()
|
||||
.path(path)
|
||||
let config = sled::Config::default()
|
||||
.cache_capacity(self.memory_cache_bytes)
|
||||
.mode(sled::Mode::LowSpace)
|
||||
.mode(sled::Mode::LowSpace);
|
||||
if self.ephemeral {
|
||||
config.temporary(self.ephemeral)
|
||||
} else {
|
||||
let path = self.cache_dir.join(net_dir).join("state");
|
||||
config.path(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,6 +107,7 @@ impl Default for Config {
|
|||
Self {
|
||||
cache_dir,
|
||||
memory_cache_bytes: 512 * 1024 * 1024,
|
||||
ephemeral: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,15 +11,25 @@ use tempdir::TempDir;
|
|||
use zebra_test::prelude::*;
|
||||
use zebrad::config::ZebradConfig;
|
||||
|
||||
pub fn tempdir(create_config: bool) -> Result<(PathBuf, impl Drop)> {
|
||||
#[derive(PartialEq)]
|
||||
enum ConfigMode {
|
||||
NoConfig,
|
||||
Ephemeral,
|
||||
Persistent,
|
||||
}
|
||||
|
||||
fn tempdir(config_mode: ConfigMode) -> Result<(PathBuf, impl Drop)> {
|
||||
let dir = TempDir::new("zebrad_tests")?;
|
||||
|
||||
if create_config {
|
||||
let cache_dir = dir.path().join("state");
|
||||
fs::create_dir(&cache_dir)?;
|
||||
|
||||
if config_mode != ConfigMode::NoConfig {
|
||||
let mut config = ZebradConfig::default();
|
||||
config.state.cache_dir = cache_dir;
|
||||
if config_mode == ConfigMode::Ephemeral {
|
||||
config.state.ephemeral = true;
|
||||
} else {
|
||||
let cache_dir = dir.path().join("state");
|
||||
fs::create_dir(&cache_dir)?;
|
||||
config.state.cache_dir = cache_dir;
|
||||
}
|
||||
config.state.memory_cache_bytes = 256000000;
|
||||
config.network.listen_addr = "127.0.0.1:0".parse()?;
|
||||
|
||||
|
@ -44,7 +54,7 @@ pub fn get_child(args: &[&str], tempdir: &PathBuf) -> Result<TestChild> {
|
|||
#[test]
|
||||
fn generate_no_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
let child = get_child(&["generate"], &tempdir)?;
|
||||
let output = child.wait_with_output()?;
|
||||
|
@ -59,7 +69,7 @@ fn generate_no_args() -> Result<()> {
|
|||
#[test]
|
||||
fn generate_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(false)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::NoConfig)?;
|
||||
|
||||
// unexpected free argument `argument`
|
||||
let child = get_child(&["generate", "argument"], &tempdir)?;
|
||||
|
@ -101,7 +111,7 @@ fn generate_args() -> Result<()> {
|
|||
#[test]
|
||||
fn help_no_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
let child = get_child(&["help"], &tempdir)?;
|
||||
let output = child.wait_with_output()?;
|
||||
|
@ -119,7 +129,7 @@ fn help_no_args() -> Result<()> {
|
|||
#[test]
|
||||
fn help_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
// The subcommand "argument" wasn't recognized.
|
||||
let child = get_child(&["help", "argument"], &tempdir)?;
|
||||
|
@ -137,7 +147,7 @@ fn help_args() -> Result<()> {
|
|||
#[test]
|
||||
fn revhex_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
// Valid
|
||||
let child = get_child(&["revhex", "33eeff55"], &tempdir)?;
|
||||
|
@ -152,7 +162,7 @@ fn revhex_args() -> Result<()> {
|
|||
#[test]
|
||||
fn seed_no_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
let mut child = get_child(&["-v", "seed"], &tempdir)?;
|
||||
|
||||
|
@ -174,7 +184,7 @@ fn seed_no_args() -> Result<()> {
|
|||
#[test]
|
||||
fn seed_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
// unexpected free argument `argument`
|
||||
let child = get_child(&["seed", "argument"], &tempdir)?;
|
||||
|
@ -197,7 +207,8 @@ fn seed_args() -> Result<()> {
|
|||
#[test]
|
||||
fn start_no_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
// start caches state, so run one of the start tests with persistent state
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Persistent)?;
|
||||
|
||||
let mut child = get_child(&["-v", "start"], &tempdir)?;
|
||||
|
||||
|
@ -221,7 +232,7 @@ fn start_no_args() -> Result<()> {
|
|||
#[test]
|
||||
fn start_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
// Any free argument is valid
|
||||
let mut child = get_child(&["start", "argument"], &tempdir)?;
|
||||
|
@ -243,10 +254,90 @@ fn start_args() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn persistent_mode() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Persistent)?;
|
||||
|
||||
let mut child = get_child(&["-v", "start"], &tempdir)?;
|
||||
|
||||
// Run the program and kill it at 1 second
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
child.kill()?;
|
||||
let output = child.wait_with_output()?;
|
||||
|
||||
// Make sure the command was killed
|
||||
assert!(output.was_killed());
|
||||
|
||||
// Check that we have persistent sled database
|
||||
let cache_dir = tempdir.join("state");
|
||||
assert!(cache_dir.read_dir()?.count() > 0);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ephemeral_mode() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
// Any free argument is valid
|
||||
let mut child = get_child(&["start", "argument"], &tempdir)?;
|
||||
// Run the program and kill it at 1 second
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
child.kill()?;
|
||||
let output = child.wait_with_output()?;
|
||||
|
||||
// Make sure the command was killed
|
||||
assert!(output.was_killed());
|
||||
|
||||
let cache_dir = tempdir.join("state");
|
||||
assert!(!cache_dir.exists());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn misconfigured_ephemeral_mode() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
let dir = TempDir::new("zebrad_tests")?;
|
||||
let cache_dir = dir.path().join("state");
|
||||
|
||||
// Write a configuration that has both cache_dir and ephemeral options set
|
||||
let mut config = ZebradConfig::default();
|
||||
config.state.ephemeral = true;
|
||||
// Although cache_dir has a default value, we set it a new temp directory
|
||||
// to test that it is empty later.
|
||||
fs::create_dir(&cache_dir)?;
|
||||
config.state.cache_dir = cache_dir.clone();
|
||||
config.state.memory_cache_bytes = 256000000;
|
||||
config.network.listen_addr = "127.0.0.1:0".parse()?;
|
||||
fs::File::create(dir.path().join("zebrad.toml"))?
|
||||
.write_all(toml::to_string(&config)?.as_bytes())?;
|
||||
|
||||
let tempdir = dir.path().to_path_buf();
|
||||
|
||||
// Any free argument is valid
|
||||
let mut child = get_child(&["start", "argument"], &tempdir)?;
|
||||
// Run the program and kill it at 1 second
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
child.kill()?;
|
||||
let output = child.wait_with_output()?;
|
||||
|
||||
// Make sure the command was killed
|
||||
assert!(output.was_killed());
|
||||
|
||||
// Check that ephemeral takes precedence over cache_dir
|
||||
assert_eq!(cache_dir.read_dir()?.count(), 0);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_no_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
let child = get_child(&[], &tempdir)?;
|
||||
let output = child.wait_with_output()?;
|
||||
|
@ -260,7 +351,7 @@ fn app_no_args() -> Result<()> {
|
|||
#[test]
|
||||
fn version_no_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
let child = get_child(&["version"], &tempdir)?;
|
||||
let output = child.wait_with_output()?;
|
||||
|
@ -274,7 +365,7 @@ fn version_no_args() -> Result<()> {
|
|||
#[test]
|
||||
fn version_args() -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(true)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::Ephemeral)?;
|
||||
|
||||
// unexpected free argument `argument`
|
||||
let child = get_child(&["version", "argument"], &tempdir)?;
|
||||
|
@ -302,7 +393,7 @@ fn valid_generated_config_test() -> Result<()> {
|
|||
|
||||
fn valid_generated_config(command: &str, expected_output: &str) -> Result<()> {
|
||||
zebra_test::init();
|
||||
let (tempdir, _guard) = tempdir(false)?;
|
||||
let (tempdir, _guard) = tempdir(ConfigMode::NoConfig)?;
|
||||
|
||||
// Add a config file name to tempdir path
|
||||
let mut generated_config_path = tempdir.clone();
|
||||
|
|
Loading…
Reference in New Issue