node: Improve flexibility of test environment

Allows us to pass full configs (profile or node) when creating test
nodes or profiles.
This commit is contained in:
cloudhead 2023-11-28 11:41:55 +01:00
parent 67c950954d
commit 6eb2772235
No known key found for this signature in database
4 changed files with 89 additions and 59 deletions

View File

@ -18,7 +18,7 @@ $ rad config
},
"connect": [],
"externalAddresses": [],
"network": "main",
"network": "test",
"relay": true,
"limits": {
"routingMaxSize": 1000,

View File

@ -23,6 +23,26 @@ use radicle_node::test::logger;
/// Seed used in tests.
const RAD_SEED: &str = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
mod config {
use super::*;
use radicle::profile;
/// Test node config.
pub fn node(alias: &'static str) -> Config {
Config {
external_addresses: vec![
node::Address::from_str(&format!("{alias}.radicle.xyz:8776")).unwrap(),
],
..Config::test(Alias::new(alias))
}
}
/// Test profile config.
pub fn profile(alias: &'static str) -> profile::Config {
Environment::config(Alias::new(alias))
}
}
/// Run a CLI test file.
fn test<'a>(
test: impl AsRef<Path>,
@ -45,16 +65,6 @@ fn test<'a>(
Ok(())
}
/// Test config.
fn config(alias: &'static str) -> Config {
Config {
external_addresses: vec![
node::Address::from_str(&format!("{alias}.radicle.xyz:8776")).unwrap(),
],
..Config::test(Alias::new(alias))
}
}
fn formula(root: &Path, test: impl AsRef<Path>) -> Result<TestFormula, Box<dyn std::error::Error>> {
let mut formula = TestFormula::new(root.to_path_buf());
let base = Path::new(env!("CARGO_MANIFEST_DIR"));
@ -92,7 +102,7 @@ fn rad_auth() {
#[test]
fn rad_issue() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let home = &profile.home;
let working = environment.tmp().join("working");
@ -106,7 +116,7 @@ fn rad_issue() {
#[test]
fn rad_cob() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let home = &profile.home;
let working = environment.tmp().join("working");
@ -120,7 +130,7 @@ fn rad_cob() {
#[test]
fn rad_init() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
// Setup a test repository.
@ -138,7 +148,7 @@ fn rad_init() {
#[test]
fn rad_init_no_git() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
test(
@ -153,7 +163,7 @@ fn rad_init_no_git() {
#[test]
fn rad_inspect() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
// Setup a test repository.
@ -181,7 +191,7 @@ fn rad_inspect() {
#[test]
fn rad_config() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
test(
@ -196,7 +206,7 @@ fn rad_config() {
#[test]
fn rad_checkout() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
let copy = tempfile::tempdir().unwrap();
@ -241,8 +251,8 @@ fn rad_checkout() {
#[test]
fn rad_id() {
let mut environment = Environment::new();
let alice = environment.node(Config::test(Alias::new("alice")));
let bob = environment.node(Config::test(Alias::new("bob")));
let alice = environment.node(config::node("alice"));
let bob = environment.node(config::node("bob"));
let working = tempfile::tempdir().unwrap();
let working = working.path();
let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
@ -263,8 +273,8 @@ fn rad_id() {
alice.handle.seed(acme, Scope::All).unwrap();
alice.connect(&bob).converge([&bob]);
let events = alice.handle.events();
let events = alice.handle.events();
bob.fork(acme, bob.home.path()).unwrap();
bob.announce(acme, bob.home.path()).unwrap();
alice.has_inventory_of(&acme, &bob.id);
@ -441,7 +451,7 @@ fn rad_node() {
#[test]
fn rad_patch() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
let home = &profile.home;
@ -456,7 +466,7 @@ fn rad_patch() {
#[test]
fn rad_patch_checkout() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
let home = &profile.home;
@ -476,7 +486,7 @@ fn rad_patch_checkout() {
#[test]
fn rad_patch_checkout_revision() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
let home = &profile.home;
@ -552,7 +562,7 @@ fn rad_patch_checkout_force() {
#[test]
fn rad_patch_update() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
let home = &profile.home;
@ -575,7 +585,7 @@ fn rad_patch_ahead_behind() {
use std::fs;
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
let home = &profile.home;
@ -597,7 +607,7 @@ fn rad_patch_ahead_behind() {
#[test]
fn rad_patch_draft() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
let home = &profile.home;
@ -617,7 +627,7 @@ fn rad_patch_draft() {
#[test]
fn rad_patch_via_push() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
let home = &profile.home;
@ -638,7 +648,7 @@ fn rad_patch_via_push() {
#[cfg(not(target_os = "macos"))]
fn rad_review_by_hunk() {
let mut environment = Environment::new();
let profile = environment.profile("alice");
let profile = environment.profile(config::profile("alice"));
let working = tempfile::tempdir().unwrap();
let home = &profile.home;
@ -1216,9 +1226,9 @@ fn test_cob_deletion() {
fn rad_sync() {
let mut environment = Environment::new();
let working = environment.tmp().join("working");
let alice = environment.node(config("alice"));
let bob = environment.node(config("bob"));
let eve = environment.node(config("eve"));
let alice = environment.node(config::node("alice"));
let bob = environment.node(config::node("bob"));
let eve = environment.node(config::node("eve"));
let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
fixtures::repository(working.join("acme"));

View File

@ -1,7 +1,6 @@
use std::io::BufRead as _;
use std::mem::ManuallyDrop;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::{
collections::{BTreeMap, BTreeSet},
env, fs, io, iter, net, process, thread, time,
@ -77,40 +76,40 @@ impl Environment {
/// Create a new node in this environment. This should be used when a running node
/// is required. Use [`Environment::profile`] otherwise.
pub fn node(&mut self, config: Config) -> Node<MemorySigner> {
let profile = self.profile(&config.alias);
let signer = MemorySigner::load(&profile.keystore, None).unwrap();
pub fn node(&mut self, node: Config) -> Node<MemorySigner> {
let alias = node.alias.clone();
let profile = self.profile(profile::Config {
node,
..Environment::config(alias)
});
Node::new(profile)
}
let policies_db = profile.home.node().join(POLICIES_DB_FILE);
let policies = policy::Store::open(policies_db).unwrap();
let db = profile.database_mut().unwrap();
let db = service::Stores::from(db);
Node {
id: *profile.id(),
home: profile.home,
config,
signer,
db,
policies,
storage: profile.storage,
/// Create a new default configuration.
pub fn config(alias: Alias) -> profile::Config {
profile::Config {
node: node::Config::test(alias),
cli: cli::Config { hints: false },
public_explorer: profile::Explorer::default(),
preferred_seeds: vec![],
}
}
/// Create a new profile in this environment.
/// This should be used when a running node is not required.
pub fn profile(&mut self, alias: &str) -> Profile {
let home = Home::new(self.tmp().join("home").join(alias).join(".radicle")).unwrap();
pub fn profile(&mut self, config: profile::Config) -> Profile {
let alias = config.alias().clone();
let home = Home::new(
self.tmp()
.join("home")
.join(alias.to_string())
.join(".radicle"),
)
.unwrap();
let keystore = Keystore::new(&home.keys());
let keypair = KeyPair::from_seed(Seed::from([!(self.users as u8); 32]));
let policies_db = home.node().join(POLICIES_DB_FILE);
let alias = Alias::from_str(alias).unwrap();
let config = profile::Config {
node: node::Config::new(alias.clone()),
cli: cli::Config { hints: false },
public_explorer: profile::Explorer::default(),
preferred_seeds: vec![],
};
config.write(&home.config()).unwrap();
let storage = Storage::open(
@ -152,6 +151,27 @@ pub struct Node<G> {
pub policies: policy::Store<policy::Write>,
}
impl Node<MemorySigner> {
fn new(profile: Profile) -> Self {
let signer = MemorySigner::load(&profile.keystore, None).unwrap();
let id = *profile.id();
let policies_db = profile.home.node().join(POLICIES_DB_FILE);
let policies = policy::Store::open(policies_db).unwrap();
let db = profile.database_mut().unwrap();
let db = service::Stores::from(db);
Node {
id,
home: profile.home,
config: profile.config.node,
signer,
db,
policies,
storage: profile.storage,
}
}
}
/// Handle to a running node.
pub struct NodeHandle<G: Signer + cyphernet::Ecdh + 'static> {
pub id: NodeId,

View File

@ -856,7 +856,7 @@ impl Node {
if e.kind() == io::ErrorKind::WouldBlock {
io::Error::new(
io::ErrorKind::TimedOut,
"timed out reading from control socket",
"timed out reading from node control socket",
)
} else {
e