rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 heartwood5a840983a8ba27f4fafbfeb82d15a10b1b9c7842
{
"request": "trigger",
"version": 1,
"event_type": "patch",
"repository": {
"id": "rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5",
"name": "heartwood",
"description": "Radicle Heartwood Protocol & Stack",
"private": false,
"default_branch": "master",
"delegates": [
"did:key:z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT",
"did:key:z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW",
"did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"did:key:z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz",
"did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz"
]
},
"action": "Created",
"patch": {
"id": "12bc8517149547b24ccdc10def80ee34ec9368cc",
"author": {
"id": "did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"alias": "fintohaps"
},
"title": "node, cli: Refactor test environment",
"state": {
"status": "open",
"conflicts": []
},
"before": "9e010068efdc4314dde2c07386303bdeed12b3ee",
"after": "5a840983a8ba27f4fafbfeb82d15a10b1b9c7842",
"commits": [
"5a840983a8ba27f4fafbfeb82d15a10b1b9c7842"
],
"target": "9e010068efdc4314dde2c07386303bdeed12b3ee",
"labels": [],
"assignees": [],
"revisions": [
{
"id": "12bc8517149547b24ccdc10def80ee34ec9368cc",
"author": {
"id": "did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"alias": "fintohaps"
},
"description": "This DRYs up a number of CLI tests.",
"base": "f13afe491d169004159a033c4ad7548a7ba76271",
"oid": "d059957c7cc330ea0c994c45b1009962f7654d81",
"timestamp": 1745588592
},
{
"id": "2c809973199d9ccaabb5018c26bf331c26ef32cc",
"author": {
"id": "did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"alias": "fintohaps"
},
"description": "Rebased",
"base": "9e010068efdc4314dde2c07386303bdeed12b3ee",
"oid": "5a840983a8ba27f4fafbfeb82d15a10b1b9c7842",
"timestamp": 1752058130
}
]
}
}
{
"response": "triggered",
"run_id": {
"id": "27fb8593-158e-4c0c-aba4-e9774df097ee"
},
"info_url": "https://cci.rad.levitte.org//27fb8593-158e-4c0c-aba4-e9774df097ee.html"
}
Started at: 2025-07-09 12:49:35.305420+02:00
Commands:
$ rad clone rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 .
✓ Creating checkout in ./...
✓ Remote cloudhead@z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT added
✓ Remote-tracking branch cloudhead@z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT/master created for z6MksFq…bS9wzpT
✓ Remote cloudhead@z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW added
✓ Remote-tracking branch cloudhead@z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW/master created for z6MktaN…hzPZRZW
✓ Remote fintohaps@z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM added
✓ Remote-tracking branch fintohaps@z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM/master created for z6Mkire…SQZ3voM
✓ Remote erikli@z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz added
✓ Remote-tracking branch erikli@z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz/master created for z6MkgFq…FGAnBGz
✓ Remote lorenz@z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz added
✓ Remote-tracking branch lorenz@z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz/master created for z6MkkPv…WX5sTEz
✓ Repository successfully cloned under /opt/radcis/ci.rad.levitte.org/cci/state/27fb8593-158e-4c0c-aba4-e9774df097ee/w/
╭────────────────────────────────────╮
│ heartwood │
│ Radicle Heartwood Protocol & Stack │
│ 113 issues · 17 patches │
╰────────────────────────────────────╯
Run `cd ./.` to go to the repository directory.
Exit code: 0
$ rad patch checkout 12bc8517149547b24ccdc10def80ee34ec9368cc
✓ Switched to branch patch/12bc851 at revision 12bc851
✓ Branch patch/12bc851 setup to track rad/patches/12bc8517149547b24ccdc10def80ee34ec9368cc
Exit code: 0
$ git config advice.detachedHead false
Exit code: 0
$ git checkout 5a840983a8ba27f4fafbfeb82d15a10b1b9c7842
HEAD is now at 5a840983 node, cli: Refactor test environment
Exit code: 0
$ git show 5a840983a8ba27f4fafbfeb82d15a10b1b9c7842
commit 5a840983a8ba27f4fafbfeb82d15a10b1b9c7842
Author: Lorenz Leutgeb <lorenz@leutgeb.xyz>
Date: Tue May 14 18:19:23 2024 +0200
node, cli: Refactor test environment
diff --git a/crates/radicle-cli/tests/commands.rs b/crates/radicle-cli/tests/commands.rs
index ee319594..e629f254 100644
--- a/crates/radicle-cli/tests/commands.rs
+++ b/crates/radicle-cli/tests/commands.rs
@@ -8,83 +8,27 @@ use radicle::node::address::Store as _;
use radicle::node::config::seeds::RADICLE_NODE_BOOTSTRAP_IRIS;
use radicle::node::config::DefaultSeedingPolicy;
use radicle::node::routing::Store as _;
-use radicle::node::Handle as _;
use radicle::node::UserAgent;
-use radicle::node::{Address, Alias, DEFAULT_TIMEOUT};
+use radicle::node::{Address, Alias, Config, Handle as _, DEFAULT_TIMEOUT};
use radicle::prelude::{NodeId, RepoId};
use radicle::profile;
-use radicle::profile::{env, Home};
+use radicle::profile::Home;
use radicle::storage::{ReadStorage, RefUpdate, RemoteRepository};
use radicle::test::fixtures;
-use radicle_cli_test::TestFormula;
use radicle_node::service::policy::Scope;
use radicle_node::service::Event;
-use radicle_node::test::environment::{Config, Environment, Node};
#[allow(unused_imports)]
use radicle_node::test::logger;
+use radicle_node::test::node::Node;
use radicle_node::PROTOCOL_VERSION;
-/// Seed used in tests.
-const RAD_SEED: &str = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
-
-mod config {
- use super::*;
- use radicle::node::config::{Config, Limits, Network, RateLimit, RateLimits};
- use radicle::profile;
-
- /// Configuration for a test seed node.
- ///
- /// It sets the `RateLimit::capacity` to `usize::MAX` ensuring
- /// that there are no rate limits for test nodes, since they all
- /// operate on the same IP address. This prevents any announcement
- /// messages from being dropped.
- pub fn seed(alias: &'static str) -> Config {
- Config {
- network: Network::Test,
- relay: node::config::Relay::Always,
- limits: Limits {
- rate: RateLimits {
- inbound: RateLimit {
- fill_rate: 1.0,
- capacity: usize::MAX,
- },
- outbound: RateLimit {
- fill_rate: 1.0,
- capacity: usize::MAX,
- },
- },
- ..Limits::default()
- },
- external_addresses: vec![node::Address::from_str(&format!(
- "{alias}.radicle.example:8776"
- ))
- .unwrap()],
- ..node(alias)
- }
- }
-
- /// Relay node config.
- pub fn relay(alias: &'static str) -> Config {
- Config {
- relay: node::config::Relay::Always,
- ..node(alias)
- }
- }
-
- /// Test node config.
- pub fn node(alias: &'static str) -> Config {
- Config::test(Alias::new(alias))
- }
-
- /// Test profile config.
- pub fn profile(alias: &'static str) -> profile::Config {
- Environment::config(Alias::new(alias))
- }
-}
+mod util;
+use util::environment::{config, Environment};
+use util::formula::formula;
/// Run a CLI test file.
-fn test<'a>(
+pub(crate) fn test<'a>(
test: impl AsRef<Path>,
cwd: impl AsRef<Path>,
home: Option<&Home>,
@@ -105,35 +49,6 @@ fn test<'a>(
Ok(())
}
-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"));
-
- formula
- .env("GIT_AUTHOR_DATE", "1671125284")
- .env("GIT_AUTHOR_EMAIL", "radicle@localhost")
- .env("GIT_AUTHOR_NAME", "radicle")
- .env("GIT_COMMITTER_DATE", "1671125284")
- .env("GIT_COMMITTER_EMAIL", "radicle@localhost")
- .env("GIT_COMMITTER_NAME", "radicle")
- .env("EDITOR", "true")
- .env("TZ", "UTC")
- .env("LANG", "C")
- .env("USER", "alice")
- .env(env::RAD_PASSPHRASE, "radicle")
- .env(env::RAD_KEYGEN_SEED, RAD_SEED)
- .env(env::RAD_RNG_SEED, "0")
- .env(env::RAD_LOCAL_TIME, "1671125284")
- .envs(git::env::GIT_DEFAULT_CONFIG)
- .build(&[
- ("radicle-remote-helper", "git-remote-rad"),
- ("radicle-cli", "rad"),
- ])
- .file(base.join(test))?;
-
- Ok(formula)
-}
-
#[test]
fn rad_auth() {
test("examples/rad-auth.md", Path::new("."), None, []).unwrap();
@@ -146,42 +61,19 @@ fn rad_auth_errors() {
#[test]
fn rad_issue() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let home = &profile.home;
- let working = environment.tmp().join("working");
-
- // Setup a test repository.
- fixtures::repository(&working);
-
- test("examples/rad-init.md", &working, Some(home), []).unwrap();
- test("examples/rad-issue.md", &working, Some(home), []).unwrap();
+ Environment::alice(["rad-init", "rad-issue"]);
}
#[test]
fn rad_cob_update() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = environment.tmp().join("working");
- let home = &profile.home;
-
- let base = Path::new(env!("CARGO_MANIFEST_DIR"));
-
- std::fs::create_dir_all(base).unwrap();
- std::fs::create_dir_all(working.clone()).unwrap();
-
- // Setup a test repository.
- fixtures::repository(&working);
-
- test("examples/rad-init.md", &working, Some(home), []).unwrap();
- test("examples/rad-cob-update.md", &working, Some(home), []).unwrap();
+ Environment::alice(["rad-init", "rad-cob-log"]);
}
#[test]
fn rad_cob_update_identity() {
let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = environment.tmp().join("working");
+ let profile = environment.profile("alice");
+ let working = environment.tempdir().join("working");
let home = &profile.home;
let base = Path::new(env!("CARGO_MANIFEST_DIR"));
@@ -222,9 +114,9 @@ fn rad_cob_multiset() {
}
let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
+ let profile = environment.profile("alice");
let home = &profile.home;
- let working = environment.tmp().join("working");
+ let working = environment.tempdir().join("working");
let base = Path::new(env!("CARGO_MANIFEST_DIR"));
std::fs::create_dir_all(base).unwrap();
@@ -246,73 +138,42 @@ fn rad_cob_multiset() {
#[test]
fn rad_cob_log() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let home = &profile.home;
- let working = environment.tmp().join("working");
-
- // Setup a test repository.
- fixtures::repository(&working);
-
- test("examples/rad-init.md", &working, Some(home), []).unwrap();
- test("examples/rad-cob-log.md", &working, Some(home), []).unwrap();
+ Environment::alice(["rad-init", "rad-cob-log"]);
}
#[test]
fn rad_cob_show() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let home = &profile.home;
- let working = environment.tmp().join("working");
-
- // Setup a test repository.
- fixtures::repository(&working);
-
- test("examples/rad-init.md", &working, Some(home), []).unwrap();
- test("examples/rad-cob-show.md", &working, Some(home), []).unwrap();
+ Environment::alice(["rad-init", "rad-cob-show"]);
}
#[test]
fn rad_cob_migrate() {
let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
+ let profile = environment.profile("alice");
let home = &profile.home;
- let working = environment.tmp().join("working");
home.cobs_db_mut()
.unwrap()
.raw_query(|conn| conn.execute("PRAGMA user_version = 0"))
.unwrap();
- // Setup a test repository.
- fixtures::repository(&working);
+ environment.repository(&profile);
- test("examples/rad-init.md", &working, Some(home), []).unwrap();
- test("examples/rad-cob-migrate.md", &working, Some(home), []).unwrap();
+ environment
+ .tests(["rad-init", "rad-cob-migrate"], &profile)
+ .unwrap();
}
#[test]
+#[ignore = "part of many other tests"]
fn rad_init() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test(
- "examples/rad-init.md",
- working.path(),
- Some(&profile.home),
- [],
- )
- .unwrap();
+ Environment::alice(["rad-init"]);
}
#[test]
fn rad_init_existing() {
let mut environment = Environment::new();
- let mut profile = environment.node(config::node("alice"));
+ let mut profile = environment.node("alice");
let working = tempfile::tempdir().unwrap();
let rid = profile.project("heartwood", "Radicle Heartwood Protocol & Stack");
@@ -333,87 +194,50 @@ fn rad_init_existing() {
#[test]
fn rad_init_no_seed() {
- let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
-
- fixtures::repository(working.join("alice"));
-
- test(
- "examples/rad-init-no-seed.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ Environment::alice(["rad-init-no-seed"]);
}
#[test]
fn rad_init_with_existing_remote() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test(
- "examples/rad-init-with-existing-remote.md",
- working.path(),
- Some(&profile.home),
- [],
- )
- .unwrap();
+ Environment::alice(["rad-init-with-existing-remote"]);
}
#[test]
fn rad_init_no_git() {
let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
+ let profile = environment.profile("alice");
- test(
- "examples/rad-init-no-git.md",
- working.path(),
- Some(&profile.home),
- [],
- )
- .unwrap();
+ // NOTE: There is no repository set up here.
+
+ environment.test("rad-init-no-git", &profile).unwrap();
}
#[test]
fn rad_inspect() {
let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
+ let profile = environment.profile("alice");
- // Setup a test repository.
- fixtures::repository(working.path());
+ environment.repository(&profile);
- test(
- "examples/rad-init.md",
- working.path(),
- Some(&profile.home),
- [],
- )
- .unwrap();
+ environment
+ .tests(["rad-init", "rad-inspect"], &profile)
+ .unwrap();
+ // NOTE: The next test runs without $RAD_HOME set.
test(
- "examples/rad-inspect.md",
- working.path(),
- Some(&profile.home),
+ "examples/rad-inspect-noauth.md",
+ environment.work(&profile),
+ None,
[],
)
.unwrap();
-
- test("examples/rad-inspect-noauth.md", working.path(), None, []).unwrap();
}
#[test]
fn rad_config() {
let mut environment = Environment::new();
let alias = Alias::new("alice");
- let profile = environment.profile(profile::Config {
+ let profile = environment.profile_with(profile::Config {
preferred_seeds: vec![RADICLE_NODE_BOOTSTRAP_IRIS.clone()],
..profile::Config::new(alias)
});
@@ -430,37 +254,18 @@ fn rad_config() {
#[test]
fn rad_warn_old_nodes() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
-
- test(
- "examples/rad-warn-old-nodes.md",
- working.path(),
- Some(&profile.home),
- [],
- )
- .unwrap();
+ Environment::alice(["rad-warn-old-nodes"]);
}
#[test]
fn rad_checkout() {
let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
+ let profile = environment.profile("alice");
let copy = tempfile::tempdir().unwrap();
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test(
- "examples/rad-init.md",
- working.path(),
- Some(&profile.home),
- [],
- )
- .unwrap();
+ environment.repository(&profile);
+ environment.test("rad-init", &profile).unwrap();
test(
"examples/rad-checkout.md",
copy.path(),
@@ -491,18 +296,15 @@ fn rad_checkout() {
#[test]
fn rad_id() {
let mut environment = Environment::new();
- let alice = environment.node(config::node("alice"));
- let bob = environment.node(config::node("bob"));
- let working = tempfile::tempdir().unwrap();
- let working = working.path();
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- // Setup a test repository.
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -529,7 +331,7 @@ fn rad_id() {
test(
"examples/rad-id.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -539,19 +341,16 @@ fn rad_id() {
#[test]
fn rad_id_threshold() {
let mut environment = Environment::new();
- let alice = environment.node(config::node("alice"));
- let bob = environment.node(config::node("bob"));
- let seed = environment.node(config::node("seed"));
- let working = tempfile::tempdir().unwrap();
- let working = working.path();
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let seed = environment.node("seed");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- // Setup a test repository.
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -573,21 +372,21 @@ fn rad_id_threshold() {
alice.routes_to(&[(acme, seed.id)]);
seed.handle.fetch(acme, alice.id, DEFAULT_TIMEOUT).unwrap();
- formula(&environment.tmp(), "examples/rad-id-threshold.md")
+ formula(&environment.tempdir(), "examples/rad-id-threshold.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob"),
+ environment.work(&bob),
[("RAD_HOME", bob.home.path().display())],
)
.home(
"seed",
- working.join("seed"),
+ environment.work(&seed),
[("RAD_HOME", seed.home.path().display())],
)
.run()
@@ -597,18 +396,15 @@ fn rad_id_threshold() {
#[test]
fn rad_id_threshold_soft_fork() {
let mut environment = Environment::new();
- let alice = environment.node(config::node("alice"));
- let bob = environment.node(config::node("bob"));
- let working = tempfile::tempdir().unwrap();
- let working = working.path();
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- // Setup a test repository.
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -628,65 +424,43 @@ fn rad_id_threshold_soft_fork() {
)
.unwrap();
- formula(&environment.tmp(), "examples/rad-id-threshold-soft-fork.md")
- .unwrap()
- .home(
- "alice",
- working.join("alice"),
- [("RAD_HOME", alice.home.path().display())],
- )
- .home(
- "bob",
- working.join("bob"),
- [("RAD_HOME", bob.home.path().display())],
- )
- .run()
- .unwrap();
+ formula(
+ &environment.tempdir(),
+ "examples/rad-id-threshold-soft-fork.md",
+ )
+ .unwrap()
+ .home(
+ "alice",
+ environment.work(&alice),
+ [("RAD_HOME", alice.home.path().display())],
+ )
+ .home(
+ "bob",
+ environment.work(&bob),
+ [("RAD_HOME", bob.home.path().display())],
+ )
+ .run()
+ .unwrap();
}
#[test]
fn rad_id_update_delete_field() {
- let mut environment = Environment::new();
- let alice = environment.node(config::node("alice"));
- let working = tempfile::tempdir().unwrap();
- let working = working.path();
-
- // Setup a test repository.
- fixtures::repository(working.join("alice"));
-
- test(
- "examples/rad-init.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
-
- test(
- "examples/rad-id-update-delete-field.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ Environment::alice(["rad-init", "rad-id-update-delete-field"]);
}
#[test]
fn rad_id_multi_delegate() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let eve = environment.node(Config::test(Alias::new("eve")));
- let working = tempfile::tempdir().unwrap();
- let working = working.path();
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let eve = environment.node("eve");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- // Setup a test repository.
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -701,28 +475,27 @@ fn rad_id_multi_delegate() {
alice.connect(&bob).converge([&bob]);
eve.connect(&alice).converge([&alice]);
- bob.fork(acme, working.join("bob")).unwrap();
+ bob.fork(acme, environment.work(&bob)).unwrap();
bob.has_remote_of(&acme, &alice.id);
alice.has_remote_of(&acme, &bob.id);
- eve.fork(acme, working.join("eve")).unwrap();
+ eve.fork(acme, environment.work(&eve)).unwrap();
eve.has_remote_of(&acme, &bob.id);
alice.has_remote_of(&acme, &eve.id);
alice.is_synced_with(&acme, &eve.id);
alice.is_synced_with(&acme, &bob.id);
// TODO: Have formula with two connected nodes and a tracked project.
-
- formula(&environment.tmp(), "examples/rad-id-multi-delegate.md")
+ formula(&environment.tempdir(), "examples/rad-id-multi-delegate.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob"),
+ environment.work(&bob),
[("RAD_HOME", bob.home.path().display())],
)
.run()
@@ -733,21 +506,18 @@ fn rad_id_multi_delegate() {
#[ignore = "slow"]
fn rad_id_collaboration() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let eve = environment.node(Config::test(Alias::new("eve")));
- let seed = environment.node(config::seed("seed"));
- let distrustful = environment.node(config::seed("distrustful"));
- let working = tempfile::tempdir().unwrap();
- let working = working.path();
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let eve = environment.node("eve");
+ let seed = environment.seed("seed");
+ let distrustful = environment.seed("distrustful");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- // Setup a test repository.
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -791,21 +561,21 @@ fn rad_id_collaboration() {
.fetch(acme, alice.id, DEFAULT_TIMEOUT)
.unwrap();
- formula(&environment.tmp(), "examples/rad-id-collaboration.md")
+ formula(&environment.tempdir(), "examples/rad-id-collaboration.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob"),
+ environment.work(&bob),
[("RAD_HOME", bob.home.path().display())],
)
.home(
"eve",
- working.join("eve"),
+ environment.work(&eve),
[("RAD_HOME", eve.home.path().display())],
)
.run()
@@ -838,18 +608,15 @@ fn rad_id_collaboration() {
#[test]
fn rad_id_conflict() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = tempfile::tempdir().unwrap();
- let working = working.path();
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- // Setup a test repository.
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -860,20 +627,20 @@ fn rad_id_conflict() {
alice.connect(&bob).converge([&bob]);
- bob.fork(acme, working.join("bob")).unwrap();
+ bob.fork(acme, environment.work(&bob)).unwrap();
bob.announce(acme, 2, bob.home.path()).unwrap();
alice.has_remote_of(&acme, &bob.id);
- formula(&environment.tmp(), "examples/rad-id-conflict.md")
+ formula(&environment.tempdir(), "examples/rad-id-conflict.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob"),
+ environment.work(&bob),
[("RAD_HOME", bob.home.path().display())],
)
.run()
@@ -883,61 +650,25 @@ fn rad_id_conflict() {
#[test]
fn rad_id_unknown_field() {
let mut environment = Environment::new();
- let alice = environment.node(config::node("alice"));
- let working = tempfile::tempdir().unwrap();
- let working = working.path();
-
- // Setup a test repository.
- fixtures::repository(working.join("alice"));
+ let alice = environment.node("alice");
- test(
- "examples/rad-init.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.repository(&alice);
+ environment.test("rad-init", &alice).unwrap();
let alice = alice.spawn();
-
- test(
- "examples/rad-id-unknown-field.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-id-unknown-field", &alice).unwrap();
}
#[test]
fn rad_id_private() {
- let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
-
- fixtures::repository(working.join("alice"));
-
- test(
- "examples/rad-init-private.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
- test(
- "examples/rad-id-private.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ Environment::alice(["rad-init-private", "rad-id-private"]);
}
#[test]
fn rad_node_connect() {
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("alice");
+ let bob = environment.node("bob");
let working = tempfile::tempdir().unwrap();
let alice = alice.spawn();
let bob = bob.spawn();
@@ -962,8 +693,8 @@ fn rad_node_connect() {
fn rad_node_connect_without_address() {
logger::init(log::Level::Debug);
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
+ let mut alice = environment.node("alice");
+ let bob = environment.node("bob");
let working = tempfile::tempdir().unwrap();
let bob = bob.spawn();
@@ -1004,7 +735,7 @@ fn rad_node_connect_without_address() {
#[test]
fn rad_node() {
let mut environment = Environment::new();
- let alice = environment.node(Config {
+ let alice = environment.node_with(Config {
external_addresses: vec![
Address::from(net::SocketAddr::from(([41, 12, 98, 112], 8776))),
Address::from_str("seed.cloudhead.io:8776").unwrap(),
@@ -1036,108 +767,45 @@ fn rad_node() {
#[test]
fn rad_patch() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test("examples/rad-issue.md", working.path(), Some(home), []).unwrap();
- test("examples/rad-patch.md", working.path(), Some(home), []).unwrap();
+ Environment::alice(["rad-init", "rad-issue", "rad-patch"]);
}
#[test]
fn rad_patch_diff() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test("examples/rad-patch-diff.md", working.path(), Some(home), []).unwrap();
+ Environment::alice(["rad-init", "rad-patch-diff"]);
}
#[test]
fn rad_patch_edit() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test("examples/rad-patch-edit.md", working.path(), Some(home), []).unwrap();
+ Environment::alice(["rad-init", "rad-patch-edit"]);
}
#[test]
fn rad_patch_checkout() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-patch-checkout.md",
- working.path(),
- Some(home),
- [],
- )
- .unwrap();
+ Environment::alice(["rad-init", "rad-patch-checkout"]);
}
#[test]
fn rad_patch_checkout_revision() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-patch-checkout.md",
- working.path(),
- Some(home),
- [],
- )
- .unwrap();
- test(
- "examples/rad-patch-checkout-revision.md",
- working.path(),
- Some(home),
- [],
- )
- .unwrap();
+ Environment::alice([
+ "rad-init",
+ "rad-patch-checkout",
+ "rad-patch-checkout-revision",
+ ]);
}
#[test]
fn rad_patch_checkout_force() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- // Setup a test repository.
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -1149,227 +817,106 @@ fn rad_patch_checkout_force() {
bob.handle.seed(acme, Scope::All).unwrap();
alice.connect(&bob).converge([&bob]);
- bob.rad("clone", &[acme.to_string().as_str()], working.join("bob"))
- .unwrap();
-
- formula(&environment.tmp(), "examples/rad-patch-checkout-force.md")
- .unwrap()
- .home(
- "alice",
- working.join("alice"),
- [("RAD_HOME", alice.home.path().display())],
- )
- .home(
- "bob",
- working.join("bob"),
- [("RAD_HOME", bob.home.path().display())],
- )
- .run()
- .unwrap();
-}
-
-#[test]
-fn rad_patch_update() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-patch-update.md",
- working.path(),
- Some(home),
- [],
+ bob.rad(
+ "clone",
+ &[acme.to_string().as_str()],
+ environment.work(&bob),
)
.unwrap();
-}
-
-#[test]
-#[cfg(not(target_os = "macos"))]
-fn rad_patch_ahead_behind() {
- use std::fs;
-
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- fs::write(working.path().join("CONTRIBUTORS"), "Alice Jones\n").unwrap();
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-patch-ahead-behind.md",
- working.path(),
- Some(home),
- [],
+ formula(
+ &environment.tempdir(),
+ "examples/rad-patch-checkout-force.md",
)
- .unwrap();
-}
-
-#[test]
-fn rad_patch_change_base() {
- logger::init(log::Level::Debug);
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-patch-change-base.md",
- working.path(),
- Some(home),
- [],
+ .unwrap()
+ .home(
+ "alice",
+ environment.work(&alice),
+ [("RAD_HOME", alice.home.path().display())],
)
- .unwrap();
-}
-
-#[test]
-fn rad_patch_draft() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-patch-draft.md",
- working.path(),
- Some(home),
- [],
+ .home(
+ "bob",
+ environment.work(&bob),
+ [("RAD_HOME", bob.home.path().display())],
)
+ .run()
.unwrap();
}
#[test]
-fn rad_patch_via_push() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-patch-via-push.md",
- working.path(),
- Some(home),
- [],
- )
- .unwrap();
+fn rad_patch_update() {
+ Environment::alice(["rad-init", "rad-patch-update"]);
}
#[test]
-fn rad_patch_detached_head() {
+#[cfg(not(target_os = "macos"))]
+fn rad_patch_ahead_behind() {
let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
+ let profile = environment.profile("alice");
- // Setup a test repository.
- fixtures::repository(working.path());
+ environment.repository(&profile);
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-patch-detached-head.md",
- working.path(),
- Some(home),
- [],
+ std::fs::write(
+ environment.work(&profile).join("CONTRIBUTORS"),
+ "Alice Jones\n",
)
.unwrap();
+
+ environment
+ .tests(["rad-init", "rad-patch-ahead-behind"], &profile)
+ .unwrap();
}
#[test]
-fn rad_patch_merge_draft() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
+fn rad_patch_change_base() {
+ logger::init(log::Level::Debug);
+ Environment::alice(["rad-init", "rad-patch-change-base"]);
+}
- // Setup a test repository.
- fixtures::repository(working.path());
+#[test]
+fn rad_patch_draft() {
+ Environment::alice(["rad-init", "rad-patch-draft"]);
+}
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-patch-merge-draft.md",
- working.path(),
- Some(home),
- [],
- )
- .unwrap();
+#[test]
+fn rad_patch_via_push() {
+ Environment::alice(["rad-init", "rad-patch-via-push"]);
}
#[test]
-fn rad_patch_revert_merge() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
+fn rad_patch_detached_head() {
+ Environment::alice(["rad-init", "rad-patch-detached-head"]);
+}
- // Setup a test repository.
- fixtures::repository(working.path());
+#[test]
+fn rad_patch_merge_draft() {
+ Environment::alice(["rad-init", "rad-patch-merge-draft"]);
+}
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-patch-revert-merge.md",
- working.path(),
- Some(home),
- [],
- )
- .unwrap();
+#[test]
+fn rad_patch_revert_merge() {
+ Environment::alice(["rad-init", "rad-patch-revert-merge"]);
}
#[test]
#[cfg(not(target_os = "macos"))]
fn rad_review_by_hunk() {
- let mut environment = Environment::new();
- let profile = environment.profile(config::profile("alice"));
- let working = tempfile::tempdir().unwrap();
- let home = &profile.home;
-
- // Setup a test repository.
- fixtures::repository(working.path());
-
- test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
- test(
- "examples/rad-review-by-hunk.md",
- working.path(),
- Some(home),
- [],
- )
- .unwrap();
+ Environment::alice(["rad-init", "rad-review-by-hunk"]);
}
#[test]
fn rad_patch_delete() {
let mut environment = Environment::new();
- let alice = environment.node(config::relay("alice"));
- let bob = environment.node(config::relay("bob"));
- let seed = environment.node(config::relay("seed"));
- let working = environment.tmp().join("working");
+ let alice = environment.relay("alice");
+ let bob = environment.relay("bob");
+ let seed = environment.relay("seed");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- // Setup a test repository.
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -1385,24 +932,28 @@ fn rad_patch_delete() {
bob.connect(&seed).converge([&seed]);
bob.routes_to(&[(acme, seed.id)]);
- bob.rad("clone", &[acme.to_string().as_str()], working.join("bob"))
- .unwrap();
+ bob.rad(
+ "clone",
+ &[acme.to_string().as_str()],
+ environment.work(&bob),
+ )
+ .unwrap();
- formula(&environment.tmp(), "examples/rad-patch-delete.md")
+ formula(&environment.tempdir(), "examples/rad-patch-delete.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob"),
+ environment.work(&bob),
[("RAD_HOME", bob.home.path().display())],
)
.home(
"seed",
- working.join("seed"),
+ environment.work(&seed),
[("RAD_HOME", seed.home.path().display())],
)
.run()
@@ -1412,10 +963,10 @@ fn rad_patch_delete() {
#[test]
fn rad_clean() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let eve = environment.node(Config::test(Alias::new("eve")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let eve = environment.node("eve");
+ let working = environment.tempdir().join("working");
// Setup a test project.
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
@@ -1445,7 +996,7 @@ fn rad_clean() {
alice.has_remote_of(&acme, &bob.id);
eve.has_remote_of(&acme, &alice.id);
- formula(&environment.tmp(), "examples/rad-clean.md")
+ formula(&environment.tempdir(), "examples/rad-clean.md")
.unwrap()
.home(
"alice",
@@ -1468,29 +1019,17 @@ fn rad_clean() {
#[test]
fn rad_seed_and_follow() {
- let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = tempfile::tempdir().unwrap();
- let alice = alice.spawn();
-
- test(
- "examples/rad-seed-and-follow.md",
- working.path(),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ Environment::alice(["rad-seed-and-follow"]);
}
#[test]
fn rad_seed_many() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let mut bob = environment.node(Config::test(Alias::new("bob")));
+ let alice = environment.node("alice");
+ let mut bob = environment.node("bob");
// Bob creates two projects that Alice seeds in the test
let _ = bob.project("heartwood", "Radicle Heartwood Protocol & Stack");
let _ = bob.project("nixpkgs", "Home for Nix Packages");
- let working = tempfile::tempdir().unwrap();
let alice = alice.spawn();
let mut bob = bob.spawn();
@@ -1498,7 +1037,7 @@ fn rad_seed_many() {
test(
"examples/rad-seed-many.md",
- working.path(),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -1508,7 +1047,7 @@ fn rad_seed_many() {
#[test]
fn rad_unseed() {
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
+ let mut alice = environment.node("alice");
let working = tempfile::tempdir().unwrap();
// Setup a test project.
@@ -1521,8 +1060,7 @@ fn rad_unseed() {
#[test]
fn rad_unseed_many() {
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let working = tempfile::tempdir().unwrap();
+ let mut alice = environment.node("alice");
// Setup a test project.
alice.project("heartwood", "Radicle Heartwood Protocol & Stack");
@@ -1531,7 +1069,7 @@ fn rad_unseed_many() {
test(
"examples/rad-unseed-many.md",
- working,
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -1541,7 +1079,7 @@ fn rad_unseed_many() {
#[test]
fn rad_block() {
let mut environment = Environment::new();
- let alice = environment.node(Config {
+ let alice = environment.node_with(Config {
seeding_policy: DefaultSeedingPolicy::permissive(),
..Config::test(Alias::new("alice"))
});
@@ -1553,9 +1091,9 @@ fn rad_block() {
#[test]
fn rad_clone() {
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let mut alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let working = environment.tempdir().join("working");
// Setup a test project.
let acme = alice.project("heartwood", "Radicle Heartwood Protocol & Stack");
@@ -1573,9 +1111,9 @@ fn rad_clone() {
#[test]
fn rad_clone_directory() {
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let mut alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let working = environment.tempdir().join("working");
// Setup a test project.
let acme = alice.project("heartwood", "Radicle Heartwood Protocol & Stack");
@@ -1599,10 +1137,9 @@ fn rad_clone_directory() {
#[test]
fn rad_clone_all() {
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let eve = environment.node(Config::test(Alias::new("eve")));
- let working = environment.tmp().join("working");
+ let mut alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let eve = environment.node("eve");
// Setup a test project.
let acme = alice.project("heartwood", "Radicle Heartwood Protocol & Stack");
@@ -1623,7 +1160,7 @@ fn rad_clone_all() {
test(
"examples/rad-clone-all.md",
- working.join("eve"),
+ environment.work(&eve),
Some(&eve.home),
[],
)
@@ -1634,10 +1171,9 @@ fn rad_clone_all() {
#[test]
fn rad_clone_partial_fail() {
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let mut eve = environment.node(Config::test(Alias::new("eve")));
- let working = environment.tmp().join("working");
+ let mut alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let mut eve = environment.node("eve");
let carol = NodeId::from_str("z6MksFqXN3Yhqk8pTJdUGLwBTkRfQvwZXPqR2qMEhbS9wzpT").unwrap();
logger::init(log::Level::Debug);
@@ -1686,7 +1222,7 @@ fn rad_clone_partial_fail() {
test(
"examples/rad-clone-partial-fail.md",
- working.join("eve"),
+ environment.work(&eve),
Some(&eve.home),
[],
)
@@ -1696,10 +1232,10 @@ fn rad_clone_partial_fail() {
#[test]
fn rad_clone_connect() {
let mut environment = Environment::new();
- let working = environment.tmp().join("working");
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let mut eve = environment.node(Config::test(Alias::new("eve")));
+ let working = environment.tempdir().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let mut eve = environment.node("eve");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
let ua = UserAgent::default();
let now = localtime::LocalTime::now().into();
@@ -1781,14 +1317,14 @@ fn rad_clone_connect() {
#[test]
fn rad_sync_without_node() {
let mut environment = Environment::new();
- let alice = environment.node(config::seed("alice"));
- let bob = environment.node(config::seed("bob"));
- let mut eve = environment.node(config::seed("eve"));
+ let alice = environment.seed("alice");
+ let bob = environment.seed("bob");
+ let mut eve = environment.seed("eve");
let rid = RepoId::from_urn("rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5").unwrap();
eve.policies.seed(&rid, Scope::All).unwrap();
- formula(&environment.tmp(), "examples/rad-sync-without-node.md")
+ formula(&environment.tempdir(), "examples/rad-sync-without-node.md")
.unwrap()
.home(
"alice",
@@ -1812,11 +1348,11 @@ fn rad_sync_without_node() {
#[test]
fn rad_self() {
let mut environment = Environment::new();
- let alice = environment.node(Config {
+ let alice = environment.node_with(Config {
external_addresses: vec!["seed.alice.acme:8776".parse().unwrap()],
..Config::test(Alias::new("alice"))
});
- let working = environment.tmp().join("working");
+ let working = environment.tempdir().join("working");
test("examples/rad-self.md", working, Some(&alice.home), []).unwrap();
}
@@ -1824,8 +1360,8 @@ fn rad_self() {
#[test]
fn rad_clone_unknown() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let working = environment.tempdir().join("working");
let alice = alice.spawn();
@@ -1841,7 +1377,7 @@ fn rad_clone_unknown() {
#[test]
fn rad_init_sync_not_connected() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
+ let alice = environment.node("alice");
let working = tempfile::tempdir().unwrap();
let alice = alice.spawn();
@@ -1860,28 +1396,27 @@ fn rad_init_sync_not_connected() {
fn rad_init_sync_preferred() {
let mut environment = Environment::new();
let mut alice = environment
- .node(Config {
+ .node_with(Config {
seeding_policy: DefaultSeedingPolicy::permissive(),
..Config::test(Alias::new("alice"))
})
.spawn();
- let bob = environment.profile(profile::Config {
+ let bob = environment.profile_with(profile::Config {
preferred_seeds: vec![alice.address()],
- ..config::profile("bob")
+ ..environment.config("bob")
});
let mut bob = Node::new(bob).spawn();
- let working = environment.tmp().join("working");
bob.connect(&alice);
alice.handle.follow(bob.id, None).unwrap();
- fixtures::repository(working.join("bob"));
+ environment.repository(&bob);
// Bob initializes a repo after her node has started, and after bob has connected to it.
test(
"examples/rad-init-sync-preferred.md",
- working.join("bob"),
+ environment.work(&bob),
Some(&bob.home),
[],
)
@@ -1892,28 +1427,27 @@ fn rad_init_sync_preferred() {
fn rad_init_sync_timeout() {
let mut environment = Environment::new();
let mut alice = environment
- .node(Config {
+ .node_with(Config {
seeding_policy: DefaultSeedingPolicy::Block,
..Config::test(Alias::new("alice"))
})
.spawn();
- let bob = environment.profile(profile::Config {
+ let bob = environment.profile_with(profile::Config {
preferred_seeds: vec![alice.address()],
- ..config::profile("bob")
+ ..environment.config("bob")
});
let mut bob = Node::new(bob).spawn();
- let working = environment.tmp().join("working");
bob.connect(&alice);
alice.handle.follow(bob.id, None).unwrap();
- fixtures::repository(working.join("bob"));
+ environment.repository(&bob);
// Bob initializes a repo after her node has started, and after bob has connected to it.
test(
"examples/rad-init-sync-timeout.md",
- working.join("bob"),
+ environment.work(&bob),
Some(&bob.home),
[],
)
@@ -1923,21 +1457,20 @@ fn rad_init_sync_timeout() {
#[test]
fn rad_init_sync_and_clone() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let alice = alice.spawn();
let mut bob = bob.spawn();
bob.connect(&alice);
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
// Alice initializes a repo after her node has started, and after bob has connected to it.
test(
"examples/rad-init-sync.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -1948,7 +1481,7 @@ fn rad_init_sync_and_clone() {
test(
"examples/rad-clone.md",
- working.join("bob"),
+ environment.work(&bob),
Some(&bob.home),
[],
)
@@ -1958,93 +1491,60 @@ fn rad_init_sync_and_clone() {
#[test]
fn rad_fetch() {
let mut environment = Environment::new();
- let working = environment.tmp().join("working");
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let mut alice = alice.spawn();
let bob = bob.spawn();
alice.connect(&bob);
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
// Alice initializes a repo after her node has started, and after bob has connected to it.
- test(
- "examples/rad-init-sync.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-init-sync", &alice).unwrap();
// Wait for bob to get any updates to the routing table.
bob.converge([&alice]);
- test(
- "examples/rad-fetch.md",
- working.join("bob"),
- Some(&bob.home),
- [],
- )
- .unwrap();
+ environment.test("rad-fetch", &bob).unwrap();
}
#[test]
fn rad_fork() {
let mut environment = Environment::new();
- let working = environment.tmp().join("working");
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let mut alice = alice.spawn();
let bob = bob.spawn();
alice.connect(&bob);
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
// Alice initializes a repo after her node has started, and after bob has connected to it.
- test(
- "examples/rad-init-sync.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-init-sync", &alice).unwrap();
// Wait for bob to get any updates to the routing table.
bob.converge([&alice]);
- test(
- "examples/rad-fetch.md",
- working.join("bob"),
- Some(&bob.home),
- [],
- )
- .unwrap();
- test(
- "examples/rad-fork.md",
- working.join("bob"),
- Some(&bob.home),
- [],
- )
- .unwrap();
+ environment.tests(["rad-fetch", "rad-fork"], &bob).unwrap();
}
#[test]
fn rad_diff() {
- let working = tempfile::tempdir().unwrap();
+ let tmp = tempfile::tempdir().unwrap();
- fixtures::repository(&working);
+ fixtures::repository(&tmp);
- test("examples/rad-diff.md", working, None, []).unwrap();
+ test("examples/rad-diff.md", tmp, None, []).unwrap();
}
#[test]
// User tries to clone; no seeds are available, but user has the repo locally.
fn test_clone_without_seeds() {
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
+ let mut alice = environment.node("alice");
+ let working = environment.tempdir().join("working");
let rid = alice.project("heartwood", "Radicle Heartwood Protocol & Stack");
let mut alice = alice.spawn();
let seeds = alice.handle.seeds(rid).unwrap();
@@ -2065,8 +1565,8 @@ fn test_clone_without_seeds() {
fn test_cob_replication() {
let mut environment = Environment::new();
let working = tempfile::tempdir().unwrap();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
+ let mut alice = environment.node("alice");
+ let bob = environment.node("bob");
let rid = alice.project("heartwood", "");
@@ -2134,8 +1634,8 @@ fn test_cob_replication() {
fn test_cob_deletion() {
let mut environment = Environment::new();
let working = tempfile::tempdir().unwrap();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
+ let mut alice = environment.node("alice");
+ let bob = environment.node("bob");
let rid = alice.project("heartwood", "");
@@ -2186,10 +1686,10 @@ fn test_cob_deletion() {
#[test]
fn rad_sync() {
let mut environment = Environment::new();
- let working = environment.tmp().join("working");
- let alice = environment.node(config::seed("alice"));
- let bob = environment.node(config::seed("bob"));
- let eve = environment.node(config::seed("eve"));
+ let working = environment.tempdir().join("working");
+ let alice = environment.seed("alice");
+ let bob = environment.seed("bob");
+ let eve = environment.seed("eve");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
fixtures::repository(working.join("acme"));
@@ -2233,13 +1733,12 @@ fn rad_sync() {
//
fn test_replication_via_seed() {
let mut environment = Environment::new();
- let alice = environment.node(config::relay("alice"));
- let bob = environment.node(config::relay("bob"));
- let seed = environment.node(Config {
+ let alice = environment.relay("alice");
+ let bob = environment.relay("bob");
+ let seed = environment.node_with(Config {
seeding_policy: DefaultSeedingPolicy::permissive(),
..config::relay("seed")
});
- let working = environment.tmp().join("working");
let rid = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
let mut alice = alice.spawn();
@@ -2257,7 +1756,7 @@ fn test_replication_via_seed() {
bob.routes_to(&[]);
// Initialize a repo as Alice.
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
alice
.rad(
"init",
@@ -2270,12 +1769,12 @@ fn test_replication_via_seed() {
"master",
"--public",
],
- working.join("alice"),
+ environment.work(&alice),
)
.unwrap();
alice
- .rad("follow", &[&bob.id.to_human()], working.join("alice"))
+ .rad("follow", &[&bob.id.to_human()], environment.work(&alice))
.unwrap();
alice.routes_to(&[(rid, alice.id), (rid, seed.id)]);
@@ -2285,7 +1784,7 @@ fn test_replication_via_seed() {
let seed_events = seed.handle.events();
let alice_events = alice.handle.events();
- bob.fork(rid, working.join("bob")).unwrap();
+ bob.fork(rid, environment.work(&bob)).unwrap();
alice.routes_to(&[(rid, alice.id), (rid, seed.id), (rid, bob.id)]);
seed.routes_to(&[(rid, alice.id), (rid, seed.id), (rid, bob.id)]);
@@ -2322,18 +1821,17 @@ fn test_replication_via_seed() {
#[test]
fn rad_remote() {
let mut environment = Environment::new();
- let alice = environment.node(config::relay("alice"));
- let bob = environment.node(config::relay("bob"));
- let eve = environment.node(config::relay("eve"));
- let working = environment.tmp().join("working");
+ let alice = environment.relay("alice");
+ let bob = environment.relay("bob");
+ let eve = environment.relay("eve");
let home = alice.home.clone();
let rid = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
// Setup a test repository.
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&home),
[],
)
@@ -2361,7 +1859,7 @@ fn rad_remote() {
test(
"examples/rad-remote.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&home),
[],
)
@@ -2371,101 +1869,61 @@ fn rad_remote() {
#[test]
fn rad_merge_via_push() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
- test(
- "examples/rad-init.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-init", &alice).unwrap();
let alice = alice.spawn();
- test(
- "examples/rad-merge-via-push.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-merge-via-push", &alice).unwrap();
}
#[test]
fn rad_merge_after_update() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
- test(
- "examples/rad-init.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-init", &alice).unwrap();
let alice = alice.spawn();
- test(
- "examples/rad-merge-after-update.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-merge-after-update", &alice).unwrap();
}
#[test]
fn rad_merge_no_ff() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
-
- fixtures::repository(working.join("alice"));
+ let alice = environment.node("alice");
- test(
- "examples/rad-init.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.repository(&alice);
- test(
- "examples/rad-merge-no-ff.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment
+ .tests(["rad-init", "rad-merge-no-ff"], &alice)
+ .unwrap();
}
#[test]
fn rad_patch_pull_update() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
let alice = alice.spawn();
let mut bob = bob.spawn();
bob.connect(&alice).converge([&alice]);
- formula(&environment.tmp(), "examples/rad-patch-pull-update.md")
+ formula(&environment.tempdir(), "examples/rad-patch-pull-update.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
@@ -2483,18 +1941,18 @@ fn rad_patch_open_explore() {
let mut environment = Environment::new();
let seed = environment
- .node(Config {
+ .node_with(Config {
seeding_policy: DefaultSeedingPolicy::permissive(),
..config::seed("seed")
})
.spawn();
- let bob = environment.profile(profile::Config {
+ let bob = environment.profile_with(profile::Config {
preferred_seeds: vec![seed.address()],
- ..config::profile("bob")
+ ..environment.config("bob")
});
let mut bob = Node::new(bob).spawn();
- let working = environment.tmp().join("working");
+ let working = environment.tempdir().join("working");
fixtures::repository(&working);
@@ -2514,64 +1972,38 @@ fn rad_patch_open_explore() {
#[test]
fn rad_init_private() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
- test(
- "examples/rad-init-private.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-init-private", &alice).unwrap();
}
#[test]
fn rad_init_private_no_seed() {
- let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
-
- fixtures::repository(working.join("alice"));
-
- test(
- "examples/rad-init-private-no-seed.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ Environment::alice(["rad-init-private-no-seed"]);
}
#[test]
fn rad_init_private_seed() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
let alice = alice.spawn();
let mut bob = bob.spawn();
- test(
- "examples/rad-init-private.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-init-private", &alice).unwrap();
bob.connect(&alice).converge([&alice]);
- formula(&environment.tmp(), "examples/rad-init-private-seed.md")
+ formula(&environment.tempdir(), "examples/rad-init-private-seed.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
@@ -2586,30 +2018,23 @@ fn rad_init_private_seed() {
#[test]
fn rad_init_private_clone() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
let alice = alice.spawn();
let mut bob = bob.spawn();
- test(
- "examples/rad-init-private.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-init-private", &alice).unwrap();
bob.connect(&alice).converge([&alice]);
- formula(&environment.tmp(), "examples/rad-init-private-clone.md")
+ formula(&environment.tempdir(), "examples/rad-init-private-clone.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
@@ -2624,18 +2049,17 @@ fn rad_init_private_clone() {
#[test]
fn rad_init_private_clone_seed() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
let alice = alice.spawn();
let mut bob = bob.spawn();
test(
"examples/rad-init-private.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -2644,13 +2068,13 @@ fn rad_init_private_clone_seed() {
bob.connect(&alice).converge([&alice]);
formula(
- &environment.tmp(),
+ &environment.tempdir(),
"examples/rad-init-private-clone-seed.md",
)
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
@@ -2665,35 +2089,22 @@ fn rad_init_private_clone_seed() {
#[test]
fn rad_publish() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
- fixtures::repository(working.join("alice"));
-
- test(
- "examples/rad-init-private.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.repository(&alice);
- test(
- "examples/rad-publish.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment
+ .tests(["rad-init-private", "rad-publish"], &alice)
+ .unwrap();
}
#[test]
fn framework_home() {
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("alice");
+ let bob = environment.node("bob");
- formula(&environment.tmp(), "examples/framework/home.md")
+ formula(&environment.tempdir(), "examples/framework/home.md")
.unwrap()
.home(
"alice",
@@ -2712,16 +2123,15 @@ fn framework_home() {
#[test]
fn git_push_diverge() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -2731,19 +2141,19 @@ fn git_push_diverge() {
let mut bob = bob.spawn();
bob.connect(&alice).converge([&alice]);
- bob.fork(acme, working.join("bob")).unwrap();
+ bob.fork(acme, environment.work(&bob)).unwrap();
alice.has_remote_of(&acme, &bob.id);
- formula(&environment.tmp(), "examples/git/git-push-diverge.md")
+ formula(&environment.tempdir(), "examples/git/git-push-diverge.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob").join("heartwood"),
+ environment.work(&bob).join("heartwood"),
[("RAD_HOME", bob.home.path().display())],
)
.run()
@@ -2755,17 +2165,16 @@ fn git_push_converge() {
use std::fs;
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let eve = environment.node(Config::test(Alias::new("eve")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let eve = environment.node("eve");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -2777,37 +2186,37 @@ fn git_push_converge() {
bob.connect(&alice).connect(&eve).converge([&alice]);
eve.connect(&alice).converge([&alice]);
- bob.fork(acme, working.join("bob")).unwrap();
- eve.fork(acme, working.join("eve")).unwrap();
+ bob.fork(acme, environment.work(&bob)).unwrap();
+ eve.fork(acme, environment.work(&eve)).unwrap();
alice.has_remote_of(&acme, &bob.id);
alice.has_remote_of(&acme, &eve.id);
fs::write(
- working.join("bob").join("heartwood").join("README"),
+ environment.work(&bob).join("heartwood").join("README"),
"Hello\n",
)
.unwrap();
fs::write(
- working.join("eve").join("heartwood").join("README"),
+ environment.work(&eve).join("heartwood").join("README"),
"Hello, world!\n",
)
.unwrap();
- formula(&environment.tmp(), "examples/git/git-push-converge.md")
+ formula(&environment.tempdir(), "examples/git/git-push-converge.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob").join("heartwood"),
+ environment.work(&bob).join("heartwood"),
[("RAD_HOME", bob.home.path().display())],
)
.home(
"eve",
- working.join("eve").join("heartwood"),
+ environment.work(&eve).join("heartwood"),
[("RAD_HOME", eve.home.path().display())],
)
.run()
@@ -2817,16 +2226,15 @@ fn git_push_converge() {
#[test]
fn git_push_amend() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -2836,19 +2244,19 @@ fn git_push_amend() {
let mut bob = bob.spawn();
bob.connect(&alice).converge([&alice]);
- bob.fork(acme, working.join("bob")).unwrap();
+ bob.fork(acme, environment.work(&bob)).unwrap();
alice.has_remote_of(&acme, &bob.id);
- formula(&environment.tmp(), "examples/git/git-push-amend.md")
+ formula(&environment.tempdir(), "examples/git/git-push-amend.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob").join("heartwood"),
+ environment.work(&bob).join("heartwood"),
[("RAD_HOME", bob.home.path().display())],
)
.run()
@@ -2858,16 +2266,15 @@ fn git_push_amend() {
#[test]
fn git_push_rollback() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -2877,19 +2284,19 @@ fn git_push_rollback() {
let mut bob = bob.spawn();
bob.connect(&alice).converge([&alice]);
- bob.fork(acme, working.join("bob")).unwrap();
+ bob.fork(acme, environment.work(&bob)).unwrap();
alice.has_remote_of(&acme, &bob.id);
- formula(&environment.tmp(), "examples/git/git-push-rollback.md")
+ formula(&environment.tempdir(), "examples/git/git-push-rollback.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob").join("heartwood"),
+ environment.work(&bob).join("heartwood"),
[("RAD_HOME", bob.home.path().display())],
)
.run()
@@ -2899,16 +2306,15 @@ fn git_push_rollback() {
#[test]
fn rad_push_and_pull_patches() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -2918,50 +2324,52 @@ fn rad_push_and_pull_patches() {
let mut bob = bob.spawn();
bob.connect(&alice).converge([&alice]);
- bob.fork(acme, working.join("bob")).unwrap();
+ bob.fork(acme, environment.work(&bob)).unwrap();
alice.has_remote_of(&acme, &bob.id);
- formula(&environment.tmp(), "examples/rad-push-and-pull-patches.md")
- .unwrap()
- .home(
- "alice",
- working.join("alice"),
- [("RAD_HOME", alice.home.path().display())],
- )
- .home(
- "bob",
- working.join("bob").join("heartwood"),
- [("RAD_HOME", bob.home.path().display())],
- )
- .run()
- .unwrap();
+ formula(
+ &environment.tempdir(),
+ "examples/rad-push-and-pull-patches.md",
+ )
+ .unwrap()
+ .home(
+ "alice",
+ environment.work(&alice),
+ [("RAD_HOME", alice.home.path().display())],
+ )
+ .home(
+ "bob",
+ environment.work(&bob).join("heartwood"),
+ [("RAD_HOME", bob.home.path().display())],
+ )
+ .run()
+ .unwrap();
}
#[test]
fn rad_patch_fetch_1() {
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
- let (repo, _) = fixtures::repository(working.join("alice"));
+ let mut alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let (repo, _) = environment.repository(&alice);
let rid = alice.project_from("heartwood", "Radicle Heartwood Protocol & Stack", &repo);
let alice = alice.spawn();
let mut bob = bob.spawn();
bob.connect(&alice).converge([&alice]);
- bob.clone(rid, working.join("bob")).unwrap();
+ bob.clone(rid, environment.work(&bob)).unwrap();
- formula(&environment.tmp(), "examples/rad-patch-fetch-1.md")
+ formula(&environment.tempdir(), "examples/rad-patch-fetch-1.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob").join("heartwood"),
+ environment.work(&bob).join("heartwood"),
[("RAD_HOME", bob.home.path().display())],
)
.run()
@@ -2971,28 +2379,27 @@ fn rad_patch_fetch_1() {
#[test]
fn rad_watch() {
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
- let (repo, _) = fixtures::repository(working.join("alice"));
+ let mut alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let (repo, _) = environment.repository(&alice);
let rid = alice.project_from("heartwood", "Radicle Heartwood Protocol & Stack", &repo);
let alice = alice.spawn();
let mut bob = bob.spawn();
bob.connect(&alice).converge([&alice]);
- bob.clone(rid, working.join("bob")).unwrap();
+ bob.clone(rid, environment.work(&bob)).unwrap();
- formula(&environment.tmp(), "examples/rad-watch.md")
+ formula(&environment.tempdir(), "examples/rad-watch.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob").join("heartwood"),
+ environment.work(&bob).join("heartwood"),
[("RAD_HOME", bob.home.path().display())],
)
.run()
@@ -3002,11 +2409,10 @@ fn rad_watch() {
#[test]
fn rad_inbox() {
let mut environment = Environment::new();
- let mut alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
- let (repo1, _) = fixtures::repository(working.join("alice").join("heartwood"));
- let (repo2, _) = fixtures::repository(working.join("alice").join("radicle-git"));
+ let mut alice = environment.node("alice");
+ let bob = environment.node("bob");
+ let (repo1, _) = fixtures::repository(environment.work(&alice).join("heartwood"));
+ let (repo2, _) = fixtures::repository(environment.work(&alice).join("radicle-git"));
let rid1 = alice.project_from("heartwood", "Radicle Heartwood Protocol & Stack", &repo1);
let rid2 = alice.project_from("radicle-git", "Radicle Git", &repo2);
@@ -3014,19 +2420,19 @@ fn rad_inbox() {
let mut bob = bob.spawn();
bob.connect(&alice).converge([&alice]);
- bob.clone(rid1, working.join("bob")).unwrap();
- bob.clone(rid2, working.join("bob")).unwrap();
+ bob.clone(rid1, environment.work(&bob)).unwrap();
+ bob.clone(rid2, environment.work(&bob)).unwrap();
- formula(&environment.tmp(), "examples/rad-inbox.md")
+ formula(&environment.tempdir(), "examples/rad-inbox.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob"),
+ environment.work(&bob),
[("RAD_HOME", bob.home.path().display())],
)
.run()
@@ -3036,40 +2442,26 @@ fn rad_inbox() {
#[test]
fn rad_patch_fetch_2() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
- fixtures::repository(working.join("alice"));
-
- test(
- "examples/rad-init.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.repository(&alice);
- test(
- "examples/rad-patch-fetch-2.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment
+ .tests(["rad-init", "rad-patch-fetch-2"], &alice)
+ .unwrap();
}
#[test]
fn git_push_and_fetch() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
test(
"examples/rad-init.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -3080,52 +2472,21 @@ fn git_push_and_fetch() {
bob.connect(&alice).converge([&alice]);
- test(
- "examples/rad-clone.md",
- working.join("bob"),
- Some(&bob.home),
- [],
- )
- .unwrap();
- test(
- "examples/git/git-push.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
- test(
- "examples/git/git-fetch.md",
- working.join("bob"),
- Some(&bob.home),
- [],
- )
- .unwrap();
- test(
- "examples/git/git-push-delete.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-clone", &bob).unwrap();
+ environment.test("git/git-push", &alice).unwrap();
+ environment.test("git/git-fetch", &bob).unwrap();
+ environment.test("git/git-push-delete", &alice).unwrap();
}
#[test]
fn git_tag() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
- test(
- "examples/rad-init.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("rad-init", &alice).unwrap();
let alice = alice.spawn();
let mut bob = bob.spawn();
@@ -3134,21 +2495,22 @@ fn git_tag() {
test(
"examples/rad-clone.md",
- working.join("bob"),
+ environment.work(&bob),
Some(&bob.home),
[],
)
.unwrap();
- formula(&environment.tmp(), "examples/git/git-tag.md")
+
+ formula(&environment.tempdir(), "examples/git/git-tag.md")
.unwrap()
.home(
"alice",
- working.join("alice"),
+ environment.work(&alice),
[("RAD_HOME", alice.home.path().display())],
)
.home(
"bob",
- working.join("bob"),
+ environment.work(&bob),
[("RAD_HOME", bob.home.path().display())],
)
.run()
@@ -3158,36 +2520,23 @@ fn git_tag() {
#[test]
fn rad_workflow() {
let mut environment = Environment::new();
- let alice = environment.node(Config::test(Alias::new("alice")));
- let bob = environment.node(Config::test(Alias::new("bob")));
- let working = environment.tmp().join("working");
+ let alice = environment.node("alice");
+ let bob = environment.node("bob");
- fixtures::repository(working.join("alice"));
+ environment.repository(&alice);
- test(
- "examples/workflow/1-new-project.md",
- working.join("alice"),
- Some(&alice.home),
- [],
- )
- .unwrap();
+ environment.test("workflow/1-new-project", &alice).unwrap();
let alice = alice.spawn();
let mut bob = bob.spawn();
bob.connect(&alice).converge([&alice]);
- test(
- "examples/workflow/2-cloning.md",
- working.join("bob"),
- Some(&bob.home),
- [],
- )
- .unwrap();
+ environment.test("workflow/2-cloning", &bob).unwrap();
test(
"examples/workflow/3-issues.md",
- working.join("bob").join("heartwood"),
+ environment.work(&bob).join("heartwood"),
Some(&bob.home),
[],
)
@@ -3195,7 +2544,7 @@ fn rad_workflow() {
test(
"examples/workflow/4-patching-contributor.md",
- working.join("bob").join("heartwood"),
+ environment.work(&bob).join("heartwood"),
Some(&bob.home),
[],
)
@@ -3203,7 +2552,7 @@ fn rad_workflow() {
test(
"examples/workflow/5-patching-maintainer.md",
- working.join("alice"),
+ environment.work(&alice),
Some(&alice.home),
[],
)
@@ -3211,7 +2560,7 @@ fn rad_workflow() {
test(
"examples/workflow/6-pulling-contributor.md",
- working.join("bob").join("heartwood"),
+ environment.work(&bob).join("heartwood"),
Some(&bob.home),
[],
)
diff --git a/crates/radicle-cli/tests/util/environment.rs b/crates/radicle-cli/tests/util/environment.rs
new file mode 100644
index 00000000..dfa91148
--- /dev/null
+++ b/crates/radicle-cli/tests/util/environment.rs
@@ -0,0 +1,316 @@
+use std::path::PathBuf;
+use std::str::FromStr;
+
+use localtime::LocalTime;
+use radicle::cob::cache::COBS_DB_FILE;
+use radicle::crypto::ssh::{keystore::MemorySigner, Keystore};
+use radicle::crypto::{KeyPair, Seed};
+use radicle::node::policy::store as policy;
+use radicle::node::{self, UserAgent};
+use radicle::node::{Alias, Config, POLICIES_DB_FILE};
+use radicle::profile::Home;
+use radicle::profile::{self};
+use radicle::storage::git::transport;
+use radicle::{Profile, Storage};
+
+use radicle_node::test::node::{Node, NodeHandle};
+
+use crate::util::formula::formula;
+
+pub(crate) mod config {
+ use super::*;
+ use radicle::node::config::{Config, Limits, Network, RateLimit, RateLimits};
+
+ /// Configuration for a test seed node.
+ ///
+ /// It sets the `RateLimit::capacity` to `usize::MAX` ensuring
+ /// that there are no rate limits for test nodes, since they all
+ /// operate on the same IP address. This prevents any announcement
+ /// messages from being dropped.
+ pub fn seed(alias: &'static str) -> Config {
+ Config {
+ network: Network::Test,
+ relay: node::config::Relay::Always,
+ limits: Limits {
+ rate: RateLimits {
+ inbound: RateLimit {
+ fill_rate: 1.0,
+ capacity: usize::MAX,
+ },
+ outbound: RateLimit {
+ fill_rate: 1.0,
+ capacity: usize::MAX,
+ },
+ },
+ ..Limits::default()
+ },
+ external_addresses: vec![node::Address::from_str(&format!(
+ "{alias}.radicle.example:8776"
+ ))
+ .unwrap()],
+ ..node(alias)
+ }
+ }
+
+ /// Relay node config.
+ pub fn relay(alias: &'static str) -> Config {
+ Config {
+ relay: node::config::Relay::Always,
+ ..node(alias)
+ }
+ }
+
+ /// Test node config.
+ pub fn node(alias: &'static str) -> Config {
+ Config::test(Alias::new(alias))
+ }
+}
+
+/// Test environment.
+pub struct Environment {
+ tempdir: tempfile::TempDir,
+ users: usize,
+}
+
+impl Default for Environment {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl Environment {
+ /// Create a new test environment.
+ fn named(name: &'static str) -> Self {
+ Self {
+ tempdir: tempfile::TempDir::with_prefix("radicle-".to_owned() + name).unwrap(),
+ users: 0,
+ }
+ }
+
+ /// Create a new test environment.
+ pub fn new() -> Self {
+ Self::named("")
+ }
+
+ /// Return the temp directory path.
+ pub fn tempdir(&self) -> PathBuf {
+ self.tempdir.path().into()
+ }
+
+ /// Path to the working directory designated for given alias.
+ pub fn work(&self, has_alias: &impl HasAlias) -> PathBuf {
+ self.tempdir().join("work").join(has_alias.alias().as_ref())
+ }
+
+ /// We don't have `RAD_HOME` or `HOME` to rely on to compute a home as usual.
+ pub fn home(&self, alias: &Alias) -> Home {
+ Home::new(
+ self.tempdir()
+ .join("home")
+ .join(alias.to_string())
+ .join(".radicle"),
+ )
+ .unwrap()
+ }
+
+ /// Create a new default configuration.
+ pub fn config(&self, alias: &str) -> profile::Config {
+ let alias = Alias::new(alias);
+ profile::Config {
+ node: node::Config::test(alias),
+ cli: radicle::cli::Config { hints: false },
+ public_explorer: radicle::explorer::Explorer::default(),
+ preferred_seeds: vec![],
+ web: radicle::web::Config::default(),
+ }
+ }
+
+ /// Create a new profile in this environment.
+ /// This should be used when a running node is not required.
+ /// Using this function is only necessary if the desired configuration
+ /// differs from the default provided by [`Environment::config`] as
+ /// for this default the convenience function [`Environment::profile`]
+ /// is provided.
+ pub fn profile_with(&mut self, config: profile::Config) -> Profile {
+ let alias = config.alias().clone();
+ let home = self.home(&alias);
+ let keypair = KeyPair::from_seed(Seed::from([!(self.users as u8); 32]));
+ let policies_db = home.node().join(POLICIES_DB_FILE);
+ let cobs_db = home.cobs().join(COBS_DB_FILE);
+
+ config.write(&home.config()).unwrap();
+
+ let storage = Storage::open(
+ home.storage(),
+ radicle::git::UserInfo {
+ alias: alias.clone(),
+ key: keypair.pk.into(),
+ },
+ )
+ .unwrap();
+
+ let mut db = home.cobs_db_mut().unwrap();
+ db.migrate(radicle::cob::migrate::ignore).unwrap();
+
+ policy::Store::open(policies_db).unwrap();
+ home.database_mut()
+ .unwrap()
+ .init(
+ &keypair.pk.into(),
+ config.node.features(),
+ &alias,
+ &UserAgent::default(),
+ LocalTime::now().into(),
+ config.node.external_addresses.iter(),
+ )
+ .unwrap();
+
+ radicle::cob::cache::Store::open(cobs_db).unwrap();
+
+ transport::local::register(storage.clone());
+ let keystore = Keystore::new(&home.keys());
+ keystore.store(keypair.clone(), "radicle", None).unwrap();
+
+ // Ensures that each user has a unique but deterministic public key.
+ self.users += 1;
+
+ Profile {
+ home,
+ storage,
+ keystore,
+ public_key: keypair.pk.into(),
+ config,
+ }
+ }
+
+ /// Create a new profile using a the default configuration from [`Environment::config`].
+ pub fn profile(&mut self, alias: &'static str) -> Profile {
+ self.profile_with(self.config(alias))
+ }
+
+ /// Create a new node in this environment. This should be used when a running node
+ /// is required. Use [`Environment::profile`] otherwise.
+ /// Using this function is only necessary when the node configuration differs
+ /// from the standard ones ([`config::node`], [`config::relay`], [`config::seed`]),
+ /// as for each of them a convenience function
+ /// (resp. [`Environment::node`], [`Environment::relay`], [`Environment::seed`]).
+ /// is provided to reduce boilerplate.
+ pub fn node_with(&mut self, node: Config) -> Node<MemorySigner> {
+ let alias = node.alias.clone();
+ let profile = self.profile_with(profile::Config {
+ node,
+ ..self.config(alias.as_ref())
+ });
+ Node::new(profile)
+ }
+
+ /// Convenience method for creating a [`Node<MemorySigner>`]
+ /// using configuration [`config::node`] within this [`Environment`].
+ pub fn node(&mut self, alias: &'static str) -> Node<MemorySigner> {
+ self.node_with(config::node(alias))
+ }
+
+ /// Convenience method for creating a [`Node<MemorySigner>`]
+ /// using configuration [`config::relay`] within this [`Environment`].
+ pub fn relay(&mut self, alias: &'static str) -> Node<MemorySigner> {
+ self.node_with(config::relay(alias))
+ }
+
+ /// Convenience method for creating a [`Node<MemorySigner>`]
+ /// using configuration [`config::seed`] within this [`Environment`].
+ pub fn seed(&mut self, alias: &'static str) -> Node<MemorySigner> {
+ self.node_with(config::seed(alias))
+ }
+
+ /// Convenience method for placing repository fixture.
+ pub fn repository(
+ &self,
+ has_alias: &impl HasAlias,
+ ) -> (radicle_cli::git::Repository, radicle_cli::git::Oid) {
+ radicle::test::fixtures::repository(self.work(has_alias).as_path())
+ }
+
+ // Convenience method for exectuing a test formula with standard configuration.
+ pub fn test(
+ &self,
+ test_file: &'static str,
+ subject: &(impl HasAlias + HasHome),
+ ) -> Result<(), Box<dyn std::error::Error>> {
+ formula(
+ self.work(subject).as_ref(),
+ PathBuf::from("examples").join(test_file.to_owned() + ".md"),
+ )?
+ .env(
+ "RAD_HOME",
+ subject.home().path().to_path_buf().to_string_lossy(),
+ )
+ .run()?;
+
+ Ok(())
+ }
+
+ pub fn tests(
+ &self,
+ test_files: impl IntoIterator<Item = &'static str>,
+ subject: &(impl HasAlias + HasHome),
+ ) -> Result<(), Box<dyn std::error::Error>> {
+ for test_file in test_files {
+ self.test(test_file, subject)?;
+ }
+
+ Ok(())
+ }
+
+ /// Convenience method for creating exactly one profile with alias "alice"
+ /// and running tests within it.
+ pub fn alice(test_files: impl IntoIterator<Item = &'static str>) {
+ let mut env = Environment::new();
+ let alice = env.profile("alice");
+ env.repository(&alice);
+ env.tests(test_files, &alice).unwrap();
+ }
+}
+
+pub trait HasAlias {
+ fn alias(&self) -> &Alias;
+}
+
+impl HasAlias for Node<MemorySigner> {
+ fn alias(&self) -> &Alias {
+ &self.config.alias
+ }
+}
+
+impl HasAlias for Profile {
+ fn alias(&self) -> &Alias {
+ self.config.alias()
+ }
+}
+
+impl<G> HasAlias for NodeHandle<G> {
+ fn alias(&self) -> &Alias {
+ &self.alias
+ }
+}
+
+pub trait HasHome {
+ fn home(&self) -> &Home;
+}
+
+impl HasHome for Profile {
+ fn home(&self) -> &Home {
+ &self.home
+ }
+}
+
+impl HasHome for Node<MemorySigner> {
+ fn home(&self) -> &Home {
+ &self.home
+ }
+}
+
+impl HasHome for NodeHandle<MemorySigner> {
+ fn home(&self) -> &Home {
+ &self.home
+ }
+}
diff --git a/crates/radicle-cli/tests/util/formula.rs b/crates/radicle-cli/tests/util/formula.rs
new file mode 100644
index 00000000..fe44a0de
--- /dev/null
+++ b/crates/radicle-cli/tests/util/formula.rs
@@ -0,0 +1,39 @@
+use std::path::Path;
+
+use radicle::profile::env;
+
+use radicle_cli_test::TestFormula;
+
+pub(crate) fn formula(
+ root: &Path,
+ test: impl AsRef<Path>,
+) -> Result<TestFormula, Box<dyn std::error::Error>> {
+ const RAD_SEED: &str = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
+
+ let mut formula = TestFormula::new(root.to_path_buf());
+ let base = Path::new(env!("CARGO_MANIFEST_DIR"));
+
+ formula
+ .env("GIT_AUTHOR_DATE", "1671125284")
+ .env("GIT_AUTHOR_EMAIL", "radicle@localhost")
+ .env("GIT_AUTHOR_NAME", "radicle")
+ .env("GIT_COMMITTER_DATE", "1671125284")
+ .env("GIT_COMMITTER_EMAIL", "radicle@localhost")
+ .env("GIT_COMMITTER_NAME", "radicle")
+ .env("EDITOR", "true")
+ .env("TZ", "UTC")
+ .env("LANG", "C")
+ .env("USER", "alice")
+ .env(env::RAD_PASSPHRASE, "radicle")
+ .env(env::RAD_KEYGEN_SEED, RAD_SEED)
+ .env(env::RAD_RNG_SEED, "0")
+ .env(env::RAD_LOCAL_TIME, "1671125284")
+ .envs(radicle::git::env::GIT_DEFAULT_CONFIG)
+ .build(&[
+ ("radicle-remote-helper", "git-remote-rad"),
+ ("radicle-cli", "rad"),
+ ])
+ .file(base.join(test))?;
+
+ Ok(formula)
+}
diff --git a/crates/radicle-cli/tests/util/mod.rs b/crates/radicle-cli/tests/util/mod.rs
new file mode 100644
index 00000000..f1c00199
--- /dev/null
+++ b/crates/radicle-cli/tests/util/mod.rs
@@ -0,0 +1,2 @@
+pub(crate) mod environment;
+pub(crate) mod formula;
diff --git a/crates/radicle-node/src/test.rs b/crates/radicle-node/src/test.rs
index d32fcae9..e4225831 100644
--- a/crates/radicle-node/src/test.rs
+++ b/crates/radicle-node/src/test.rs
@@ -1,7 +1,7 @@
pub mod arbitrary;
-pub mod environment;
pub mod gossip;
pub mod handle;
+pub mod node;
pub mod peer;
pub mod simulator;
diff --git a/crates/radicle-node/src/test/node.rs b/crates/radicle-node/src/test/node.rs
new file mode 100644
index 00000000..e583db75
--- /dev/null
+++ b/crates/radicle-node/src/test/node.rs
@@ -0,0 +1,532 @@
+use std::io::BufRead as _;
+use std::mem::ManuallyDrop;
+use std::path::Path;
+use std::{
+ collections::{BTreeMap, BTreeSet},
+ fs, io, iter, net, process, thread, time,
+ time::Duration,
+};
+
+use crossbeam_channel as chan;
+
+use radicle::cob;
+use radicle::cob::issue;
+use radicle::crypto::signature::Signer;
+use radicle::crypto::ssh::keystore::MemorySigner;
+use radicle::crypto::test::signer::MockSigner;
+use radicle::crypto::Signature;
+use radicle::git;
+use radicle::git::refname;
+use radicle::identity::{RepoId, Visibility};
+use radicle::node::config::ConnectAddress;
+use radicle::node::policy::store as policy;
+use radicle::node::seed::Store as _;
+use radicle::node::Config;
+use radicle::node::{self, Alias};
+use radicle::node::{ConnectOptions, Handle as _};
+use radicle::node::{Database, POLICIES_DB_FILE};
+use radicle::profile::{env, Home, Profile};
+use radicle::rad;
+use radicle::storage::{ReadStorage as _, RemoteRepository as _, SignRepository as _};
+use radicle::test::fixtures;
+use radicle::Storage;
+
+use crate::node::device::Device;
+use crate::node::NodeId;
+use crate::service::Event;
+use crate::storage::git::transport;
+use crate::{runtime, runtime::Handle, service, Runtime};
+
+/// A node that can be run.
+pub struct Node<G> {
+ pub id: NodeId,
+ pub home: Home,
+ pub signer: Device<G>,
+ pub storage: Storage,
+ pub config: Config,
+ pub db: service::Stores<Database>,
+ pub policies: policy::Store<policy::Write>,
+}
+
+impl Node<MemorySigner> {
+ pub fn new(profile: Profile) -> Self {
+ let signer = Device::from(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: 'static> {
+ pub id: NodeId,
+ pub alias: Alias,
+ pub storage: Storage,
+ pub signer: Device<G>,
+ pub home: Home,
+ pub addr: net::SocketAddr,
+ pub thread: ManuallyDrop<thread::JoinHandle<Result<(), runtime::Error>>>,
+ pub handle: ManuallyDrop<Handle>,
+}
+
+impl<G: 'static> Drop for NodeHandle<G> {
+ fn drop(&mut self) {
+ log::debug!(target: "test", "Node {} shutting down..", self.id);
+
+ unsafe { ManuallyDrop::take(&mut self.handle) }
+ .shutdown()
+ .unwrap();
+ unsafe { ManuallyDrop::take(&mut self.thread) }
+ .join()
+ .unwrap()
+ .unwrap();
+ }
+}
+
+impl<G: Signer<Signature> + cyphernet::Ecdh> NodeHandle<G> {
+ /// Connect this node to another node, and wait for the connection to be established both ways.
+ pub fn connect(&mut self, remote: &NodeHandle<G>) -> &mut Self {
+ let local_events = self.handle.events();
+ let remote_events = remote.handle.events();
+
+ self.handle
+ .connect(remote.id, remote.addr.into(), ConnectOptions::default())
+ .ok();
+
+ local_events
+ .iter()
+ .find(|e| {
+ matches!(
+ e, Event::PeerConnected { nid } if nid == &remote.id
+ )
+ })
+ .unwrap();
+ remote_events
+ .iter()
+ .find(|e| {
+ matches!(
+ e, Event::PeerConnected { nid } if nid == &self.id
+ )
+ })
+ .unwrap();
+
+ self
+ }
+
+ pub fn disconnect(&mut self, remote: &NodeHandle<G>) {
+ self.handle.disconnect(remote.id).unwrap();
+ }
+
+ /// Shutdown node.
+ pub fn shutdown(self) {
+ drop(self)
+ }
+
+ /// Get the full address of this node.
+ pub fn address(&self) -> ConnectAddress {
+ (self.id, node::Address::from(self.addr)).into()
+ }
+
+ /// Get routing table entries.
+ pub fn routing(&self) -> impl Iterator<Item = (RepoId, NodeId)> {
+ use node::routing::Store as _;
+
+ self.home.routing_mut().unwrap().entries().unwrap()
+ }
+
+ pub fn inventory(&self) -> impl Iterator<Item = RepoId> + '_ {
+ self.routing()
+ .filter(|(_, n)| *n == self.id)
+ .map(|(r, _)| r)
+ }
+
+ /// Get sync status of a repo.
+ pub fn synced_seeds(&self, rid: &RepoId) -> Vec<node::seed::SyncedSeed> {
+ let db = Database::reader(self.home.node().join(node::NODE_DB_FILE)).unwrap();
+ let seeds = db.seeds_for(rid).unwrap();
+
+ seeds.into_iter().collect::<Result<Vec<_>, _>>().unwrap()
+ }
+
+ /// Wait until this node's routing table matches the remotes.
+ pub fn converge<'a>(
+ &'a self,
+ remotes: impl IntoIterator<Item = &'a NodeHandle<G>>,
+ ) -> BTreeSet<(RepoId, NodeId)> {
+ converge(iter::once(self).chain(remotes))
+ }
+
+ /// Wait until this node's routing table contains the given routes.
+ #[track_caller]
+ pub fn routes_to(&self, routes: &[(RepoId, NodeId)]) {
+ log::debug!(target: "test", "Waiting for {} to route to {:?}", self.id, routes);
+ let events = self.handle.events();
+
+ loop {
+ let mut remaining: BTreeSet<_> = routes.iter().collect();
+
+ for (rid, nid) in self.routing() {
+ if !remaining.remove(&(rid, nid)) {
+ log::debug!(target: "test", "Found unexpected route for {}: ({rid}, {nid})", self.id);
+ }
+ }
+ if remaining.is_empty() {
+ break;
+ }
+ events
+ .wait(
+ |e| matches!(e, Event::SeedDiscovered { .. }).then_some(()),
+ time::Duration::from_secs(6),
+ )
+ .unwrap();
+ }
+ }
+
+ /// Wait until this node is synced with another node, for the given repository.
+ #[track_caller]
+ pub fn is_synced_with(&mut self, rid: &RepoId, nid: &NodeId) {
+ log::debug!(target: "test", "Waiting for {} to be in sync with {nid} for {rid}", self.id);
+
+ loop {
+ let seeds = self.handle.seeds(*rid).unwrap();
+ if seeds.iter().any(|s| s.nid == *nid && s.is_synced()) {
+ break;
+ }
+ thread::sleep(Duration::from_millis(100));
+ }
+ }
+
+ /// Wait until this node has a repository.
+ #[track_caller]
+ pub fn has_repository(&self, rid: &RepoId) {
+ log::debug!(target: "test", "Waiting for {} to have {rid}", self.id);
+ let events = self.handle.events();
+
+ loop {
+ if self.storage.repository(*rid).is_ok() {
+ log::debug!(target: "test", "Node {} has {rid}", self.id);
+ break;
+ }
+ events
+ .wait(
+ |e| matches!(e, Event::RefsFetched { .. }).then_some(()),
+ time::Duration::from_secs(6),
+ )
+ .unwrap();
+ }
+ }
+
+ /// Wait until this node has the inventory of another node.
+ #[track_caller]
+ pub fn has_remote_of(&self, rid: &RepoId, nid: &NodeId) {
+ log::debug!(target: "test", "Waiting for {} to have {rid}/{nid}", self.id);
+ let events = self.handle.events();
+
+ loop {
+ if let Ok(repo) = self.storage.repository(*rid) {
+ if repo.remote(nid).is_ok() {
+ log::debug!(target: "test", "Node {} has {rid}/{nid}", self.id);
+ break;
+ }
+ }
+ events
+ .wait(
+ |e| matches!(e, Event::RefsFetched { .. }).then_some(()),
+ time::Duration::from_secs(6),
+ )
+ .unwrap();
+ }
+ }
+
+ /// Clone a repo into a directory.
+ pub fn clone<P: AsRef<Path>>(&self, rid: RepoId, cwd: P) -> io::Result<()> {
+ self.rad("clone", &[rid.to_string().as_str()], cwd)
+ }
+
+ /// Fork a repo.
+ pub fn fork<P: AsRef<Path>>(&self, rid: RepoId, cwd: P) -> io::Result<()> {
+ self.clone(rid, &cwd)?;
+ self.rad("fork", &[rid.to_string().as_str()], &cwd)?;
+ self.announce(rid, 1, &cwd)?;
+
+ Ok(())
+ }
+
+ /// Announce a repo.
+ pub fn announce<P: AsRef<Path>>(&self, rid: RepoId, replicas: usize, cwd: P) -> io::Result<()> {
+ self.rad(
+ "sync",
+ &[
+ rid.to_string().as_str(),
+ "--announce",
+ "--replicas",
+ replicas.to_string().as_str(),
+ ],
+ cwd,
+ )
+ }
+
+ /// Init a repo.
+ pub fn init<P: AsRef<Path>>(&self, name: &str, desc: &str, cwd: P) -> io::Result<()> {
+ self.rad(
+ "init",
+ &[
+ "--name",
+ name,
+ "--description",
+ desc,
+ "--default-branch",
+ "master",
+ "--public",
+ ],
+ cwd,
+ )
+ }
+
+ /// Run a `rad` CLI command.
+ pub fn rad<P: AsRef<Path>>(&self, cmd: &str, args: &[&str], cwd: P) -> io::Result<()> {
+ let cwd = cwd.as_ref();
+ log::debug!(target: "test", "Running `rad {cmd} {args:?}` in {}..", cwd.display());
+
+ fs::create_dir_all(cwd)?;
+
+ let result = process::Command::new(snapbox::cmd::cargo_bin("rad"))
+ .env_clear()
+ .envs(env::vars().filter(|(k, _)| k == "PATH"))
+ .env("GIT_AUTHOR_DATE", "1671125284")
+ .env("GIT_AUTHOR_EMAIL", "radicle@localhost")
+ .env("GIT_AUTHOR_NAME", "radicle")
+ .env("GIT_COMMITTER_DATE", "1671125284")
+ .env("GIT_COMMITTER_EMAIL", "radicle@localhost")
+ .env("GIT_COMMITTER_NAME", "radicle")
+ .env(
+ env::RAD_HOME,
+ self.home.path().to_string_lossy().to_string(),
+ )
+ .env(env::RAD_PASSPHRASE, "radicle")
+ .env(env::RAD_LOCAL_TIME, "1671125284")
+ .env("TZ", "UTC")
+ .env("LANG", "C")
+ .envs(git::env::GIT_DEFAULT_CONFIG)
+ .current_dir(cwd)
+ .arg(cmd)
+ .args(args)
+ .output()?;
+
+ for line in io::BufReader::new(io::Cursor::new(&result.stdout))
+ .lines()
+ .map_while(Result::ok)
+ {
+ log::debug!(target: "test", "rad {cmd}: {line}");
+ }
+
+ log::debug!(
+ target: "test",
+ "Ran command `rad {cmd}` (status={})", result.status.code().unwrap()
+ );
+
+ if !result.status.success() {
+ return Err(io::ErrorKind::Other.into());
+ }
+ Ok(())
+ }
+
+ /// Create an [`issue::Issue`] in the `NodeHandle`'s storage.
+ pub fn issue(&self, rid: RepoId, title: &str, desc: &str) -> cob::ObjectId {
+ let repo = self.storage.repository(rid).unwrap();
+ let mut issues = issue::Cache::no_cache(&repo).unwrap();
+ *issues
+ .create(title, desc, &[], &[], [], &self.signer)
+ .unwrap()
+ .id()
+ }
+}
+
+impl Node<MockSigner> {
+ /// Create a new node.
+ pub fn init(base: &Path, config: Config) -> Self {
+ let home = base.join(
+ iter::repeat_with(fastrand::alphanumeric)
+ .take(8)
+ .collect::<String>(),
+ );
+ let home = Home::new(home).unwrap();
+ let signer = Device::mock();
+ let storage = Storage::open(
+ home.storage(),
+ git::UserInfo {
+ alias: config.alias.clone(),
+ key: *signer.public_key(),
+ },
+ )
+ .unwrap();
+ let policies = home.policies_mut().unwrap();
+ let db = home.database_mut().unwrap();
+ let db = service::Stores::from(db);
+
+ log::debug!(target: "test", "Node::init {}: {}", config.alias, signer.public_key());
+ Self {
+ id: *signer.public_key(),
+ home,
+ signer,
+ storage,
+ config,
+ db,
+ policies,
+ }
+ }
+}
+
+impl<G: cyphernet::Ecdh<Pk = NodeId> + Signer<Signature> + Clone> Node<G> {
+ /// Spawn a node in its own thread.
+ pub fn spawn(self) -> NodeHandle<G> {
+ let alias = self.config.alias.clone();
+ let listen = vec![([0, 0, 0, 0], 0).into()];
+ let (_, signals) = chan::bounded(1);
+ let rt = Runtime::init(
+ self.home.clone(),
+ self.config,
+ listen,
+ signals,
+ self.signer.clone(),
+ )
+ .unwrap();
+ let addr = *rt.local_addrs.first().unwrap();
+ let id = *self.signer.public_key();
+ let handle = ManuallyDrop::new(rt.handle.clone());
+ let thread = ManuallyDrop::new(runtime::thread::spawn(&id, "runtime", move || rt.run()));
+
+ NodeHandle {
+ id,
+ alias,
+ storage: self.storage,
+ signer: self.signer,
+ home: self.home,
+ addr,
+ handle,
+ thread,
+ }
+ }
+
+ /// Populate a storage instance with a project from the given repository.
+ pub fn project_from(
+ &mut self,
+ name: &str,
+ description: &str,
+ repo: &git::raw::Repository,
+ ) -> RepoId {
+ transport::local::register(self.storage.clone());
+
+ let branch = refname!("master");
+ let id = rad::init(
+ repo,
+ name.try_into().unwrap(),
+ description,
+ branch.clone(),
+ Visibility::default(),
+ &self.signer,
+ &self.storage,
+ )
+ .map(|(id, _, _)| id)
+ .unwrap();
+
+ assert!(self.policies.seed(&id, node::policy::Scope::All).unwrap());
+
+ log::debug!(
+ target: "test",
+ "Initialized project {id} for node {}", self.signer.public_key()
+ );
+
+ // Push local branches to storage.
+ let mut refs = Vec::<(git::Qualified, git::Qualified)>::new();
+ for branch in repo.branches(Some(git::raw::BranchType::Local)).unwrap() {
+ let (branch, _) = branch.unwrap();
+ let name = git::RefString::try_from(branch.name().unwrap().unwrap()).unwrap();
+
+ refs.push((
+ git::lit::refs_heads(&name).into(),
+ git::lit::refs_heads(&name).into(),
+ ));
+ }
+ git::push(repo, "rad", refs.iter().map(|(a, b)| (a, b))).unwrap();
+
+ radicle::git::set_upstream(
+ repo,
+ &*radicle::rad::REMOTE_NAME,
+ branch.clone(),
+ radicle::git::refs::workdir::branch(&branch),
+ )
+ .unwrap();
+
+ self.storage
+ .repository(id)
+ .unwrap()
+ .sign_refs(&self.signer)
+ .unwrap();
+
+ id
+ }
+
+ /// Populate a storage instance with a project.
+ pub fn project(&mut self, name: &str, description: &str) -> RepoId {
+ let tmp = tempfile::tempdir().unwrap();
+ let (repo, _) = fixtures::repository(tmp.path());
+
+ self.project_from(name, description, &repo)
+ }
+}
+
+/// Checks whether the nodes have converged in their routing tables.
+#[track_caller]
+pub fn converge<'a, G: Signer<Signature> + cyphernet::Ecdh + 'static>(
+ nodes: impl IntoIterator<Item = &'a NodeHandle<G>>,
+) -> BTreeSet<(RepoId, NodeId)> {
+ let nodes = nodes.into_iter().collect::<Vec<_>>();
+
+ let mut all_routes = BTreeSet::<(RepoId, NodeId)>::new();
+ let mut remaining = BTreeMap::from_iter(nodes.iter().map(|node| (node.id, node)));
+
+ // First build the set of all routes.
+ for node in &nodes {
+ // Routes from the routing table.
+ for (rid, seed_id) in node.routing() {
+ all_routes.insert((rid, seed_id));
+ }
+ // Routes from the local inventory.
+ for rid in node.inventory() {
+ all_routes.insert((rid, node.id));
+ }
+ }
+
+ // Then, while there are nodes remaining to converge, check each node to see if
+ // its routing table has all routes. If so, remove it from the remaining nodes.
+ while !remaining.is_empty() {
+ remaining.retain(|_, node| {
+ let routing = node.routing();
+ let routes = BTreeSet::from_iter(routing);
+
+ if routes.is_superset(&all_routes) {
+ log::debug!(target: "test", "Node {} has converged", node.id);
+ return false;
+ } else {
+ let diff = all_routes.symmetric_difference(&routes).collect::<Vec<_>>();
+ log::debug!(target: "test", "Node has missing routes: {diff:?}");
+ }
+ true
+ });
+ thread::sleep(Duration::from_millis(100));
+ }
+ all_routes
+}
diff --git a/crates/radicle-node/src/tests/e2e.rs b/crates/radicle-node/src/tests/e2e.rs
index c5be51fe..6b0d17c3 100644
--- a/crates/radicle-node/src/tests/e2e.rs
+++ b/crates/radicle-node/src/tests/e2e.rs
@@ -15,8 +15,8 @@ use crate::node::{Config, ConnectOptions};
use crate::service;
use crate::service::policy::Scope;
use crate::storage::git::transport;
-use crate::test::environment::{converge, Environment, Node};
use crate::test::logger;
+use crate::test::node::{converge, Node};
mod config {
use super::*;
@@ -29,6 +29,17 @@ mod config {
..Config::test(Alias::new(alias))
}
}
+
+ /// Get the scale or "test size". This is used to scale tests with more
+ /// data. Defaults to `1`.
+ pub fn scale() -> usize {
+ std::env::var("RAD_TEST_SCALE")
+ .map(|s| {
+ s.parse()
+ .expect("repository: invalid value for `RAD_TEST_SCALE`")
+ })
+ .unwrap_or(1)
+ }
}
#[test]
@@ -657,12 +668,11 @@ fn test_fetch_unseeded() {
fn test_large_fetch() {
logger::init(log::Level::Debug);
- let env = Environment::new();
- let scale = env.scale();
- let mut alice = Node::init(&env.tmp(), config::relay("alice"));
- let bob = Node::init(&env.tmp(), config::relay("bob"));
-
let tmp = tempfile::tempdir().unwrap();
+ let scale = config::scale();
+ let mut alice = Node::init(tmp.path(), config::relay("alice"));
+ let bob = Node::init(tmp.path(), config::relay("bob"));
+
let (repo, _) = fixtures::repository(tmp.path());
fixtures::populate(&repo, scale.max(3));
@@ -695,8 +705,8 @@ fn test_large_fetch() {
fn test_concurrent_fetches() {
logger::init(log::Level::Debug);
- let env = Environment::new();
- let scale = env.scale();
+ let tmp = tempfile::tempdir().unwrap();
+ let scale = config::scale();
let repos = scale.max(4);
let limits = Limits {
// Have one fetch be queued.
@@ -706,7 +716,7 @@ fn test_concurrent_fetches() {
let mut bob_repos = HashSet::new();
let mut alice_repos = HashSet::new();
let mut alice = Node::init(
- &env.tmp(),
+ tmp.path(),
service::Config {
limits: limits.clone(),
relay: radicle::node::config::Relay::Always,
@@ -714,7 +724,7 @@ fn test_concurrent_fetches() {
},
);
let mut bob = Node::init(
- &env.tmp(),
+ tmp.path(),
service::Config {
limits,
relay: radicle::node::config::Relay::Always,
Exit code: 0
shell: 'cargo --version rustc --version cargo fmt --check cargo clippy --all-targets --workspace -- --deny warnings cargo build --all-targets --workspace cargo doc --workspace --no-deps cargo test --workspace --no-fail-fast '
Commands:
$ podman run --name 27fb8593-158e-4c0c-aba4-e9774df097ee -v /opt/radcis/ci.rad.levitte.org/cci/state/27fb8593-158e-4c0c-aba4-e9774df097ee/s:/27fb8593-158e-4c0c-aba4-e9774df097ee/s:ro -v /opt/radcis/ci.rad.levitte.org/cci/state/27fb8593-158e-4c0c-aba4-e9774df097ee/w:/27fb8593-158e-4c0c-aba4-e9774df097ee/w -w /27fb8593-158e-4c0c-aba4-e9774df097ee/w -v /opt/radcis/ci.rad.levitte.org/.radicle:/${id}/.radicle:ro -e RAD_HOME=/${id}/.radicle rust:bookworm bash /27fb8593-158e-4c0c-aba4-e9774df097ee/s/script.sh
+ cargo --version
info: syncing channel updates for '1.85-x86_64-unknown-linux-gnu'
info: latest update on 2025-03-18, rust version 1.85.1 (4eb161250 2025-03-15)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-src'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
info: installing component 'rust-src'
info: installing component 'rust-std'
info: installing component 'rustc'
info: installing component 'rustfmt'
cargo 1.85.1 (d73d2caf9 2024-12-31)
+ rustc --version
rustc 1.85.1 (4eb161250 2025-03-15)
+ cargo fmt --check
+ cargo clippy --all-targets --workspace -- --deny warnings
Updating crates.io index
Downloading crates ...
Downloaded adler2 v2.0.0
Downloaded base32 v0.4.0
Downloaded aead v0.5.2
Downloaded cfg-if v1.0.0
Downloaded base16ct v0.2.0
Downloaded base-x v0.2.11
Downloaded ascii v1.1.0
Downloaded smallvec v1.13.2
Downloaded base64 v0.22.1
Downloaded tinystr v0.7.6
Downloaded schemars_derive v1.0.0-alpha.17
Downloaded phf_shared v0.11.3
Downloaded pbkdf2 v0.12.2
Downloaded phf v0.11.3
Downloaded tree-sitter-c v0.23.2
Downloaded crossbeam-utils v0.8.19
Downloaded percent-encoding v2.3.1
Downloaded fxhash v0.2.1
Downloaded pem-rfc7468 v0.7.0
Downloaded parking_lot v0.12.3
Downloaded errno v0.3.13
Downloaded block-padding v0.3.3
Downloaded diff v0.1.13
Downloaded parking_lot_core v0.9.9
Downloaded fluent-uri v0.3.2
Downloaded fraction v0.15.3
Downloaded git-ref-format-core v0.3.1
Downloaded byteorder v1.5.0
Downloaded filetime v0.2.23
Downloaded sqlite3-src v0.5.1
Downloaded proc-macro-error v1.0.4
Downloaded same-file v1.0.6
Downloaded siphasher v1.0.1
Downloaded radicle-std-ext v0.1.0
Downloaded derive_more-impl v2.0.1
Downloaded opaque-debug v0.3.1
Downloaded faster-hex v0.9.0
Downloaded snapbox-macros v0.3.8
Downloaded multibase v0.9.1
Downloaded newline-converter v0.3.0
Downloaded num-integer v0.1.46
Downloaded walkdir v2.5.0
Downloaded gix-tempfile v15.0.0
Downloaded write16 v1.0.0
Downloaded streaming-iterator v0.1.9
Downloaded memmap2 v0.9.4
Downloaded gix-config-value v0.14.12
Downloaded gix-trace v0.1.12
Downloaded uuid-simd v0.8.0
Downloaded spki v0.7.3
Downloaded gix-credentials v0.26.0
Downloaded timeago v0.4.2
Downloaded gix-utils v0.1.14
Downloaded num v0.4.3
Downloaded group v0.13.0
Downloaded gix-hash v0.15.1
Downloaded elliptic-curve v0.13.8
Downloaded num-rational v0.4.2
Downloaded tree-sitter-json v0.24.8
Downloaded iana-time-zone v0.1.60
Downloaded flate2 v1.1.1
Downloaded utf8_iter v1.0.4
Downloaded gix-hashtable v0.6.0
Downloaded tempfile v3.10.1
Downloaded inout v0.1.3
Downloaded gix-sec v0.10.12
Downloaded gix-negotiate v0.17.0
Downloaded gix-lock v15.0.1
Downloaded gix-traverse v0.43.1
Downloaded gix-revwalk v0.17.0
Downloaded icu_collections v1.5.0
Downloaded zerofrom v0.1.6
Downloaded icu_provider_macros v1.5.0
Downloaded gix-pack v0.56.0
Downloaded idna_adapter v1.2.0
Downloaded gix-ref v0.49.1
Downloaded icu_locid_transform v1.5.0
Downloaded gix-url v0.28.2
Downloaded litemap v0.7.5
Downloaded gix-packetline v0.18.4
Downloaded icu_provider v1.5.0
Downloaded icu_locid_transform_data v1.5.1
Downloaded unicode-ident v1.0.12
Downloaded typenum v1.17.0
Downloaded yoke v0.7.5
Downloaded litrs v0.4.1
Downloaded zerovec v0.10.4
Downloaded indexmap v2.2.6
Downloaded url v2.5.4
Downloaded zerocopy v0.7.35
Downloaded num-bigint v0.4.6
Downloaded num-bigint-dig v0.8.4
Downloaded tree-sitter-md v0.3.2
Downloaded idna v1.0.3
Downloaded tree-sitter v0.24.4
Downloaded tree-sitter-rust v0.23.2
Downloaded vcpkg v0.2.15
Downloaded syn v1.0.109
Downloaded icu_properties_data v1.5.1
Downloaded syn v2.0.89
Downloaded winnow v0.6.26
Downloaded serde_json v1.0.140
Downloaded regex-syntax v0.8.5
Downloaded rustix v0.38.34
Downloaded regex-automata v0.4.9
Downloaded tree-sitter-bash v0.23.3
Downloaded rustix v1.0.7
Downloaded tree-sitter-typescript v0.23.2
Downloaded bstr v1.9.1
Downloaded jsonschema v0.30.0
Downloaded tree-sitter-ruby v0.23.1
Downloaded ssh-key v0.6.6
Downloaded unicode-normalization v0.1.23
Downloaded jiff v0.2.1
Downloaded p384 v0.13.0
Downloaded uuid v1.16.0
Downloaded unicode-segmentation v1.11.0
Downloaded inquire v0.7.5
Downloaded libc v0.2.174
Downloaded linux-raw-sys v0.4.13
Downloaded sha3 v0.10.8
Downloaded tree-sitter-python v0.23.4
Downloaded serde v1.0.219
Downloaded prodash v29.0.2
Downloaded gix-protocol v0.47.0
Downloaded icu_properties v1.5.1
Downloaded num-traits v0.2.19
Downloaded mio v1.0.4
Downloaded hashbrown v0.14.3
Downloaded schemars v1.0.0-alpha.17
Downloaded rsa v0.9.6
Downloaded linux-raw-sys v0.9.4
Downloaded rand v0.8.5
Downloaded pretty_assertions v1.4.0
Downloaded libm v0.2.8
Downloaded gix-refspec v0.27.0
Downloaded io-reactor v0.5.2
Downloaded lexopt v0.3.0
Downloaded libgit2-sys v0.17.0+1.8.1
Downloaded once_cell v1.21.3
Downloaded gix-transport v0.44.0
Downloaded gix-revision v0.31.1
Downloaded gix-quote v0.4.15
Downloaded tree-sitter-toml-ng v0.6.0
Downloaded num-complex v0.4.6
Downloaded socket2 v0.5.7
Downloaded libz-sys v1.1.16
Downloaded git-ref-format v0.3.1
Downloaded escargot v0.5.10
Downloaded tree-sitter-go v0.23.4
Downloaded p521 v0.13.3
Downloaded ec25519 v0.1.0
Downloaded utf8parse v0.2.1
Downloaded unicode-display-width v0.3.0
Downloaded zeroize v1.7.0
Downloaded zerofrom-derive v0.1.6
Downloaded itoa v1.0.11
Downloaded lock_api v0.4.11
Downloaded gix-diff v0.49.0
Downloaded serde_derive v1.0.219
Downloaded proc-macro2 v1.0.92
Downloaded cyphernet v0.5.2
Downloaded jobserver v0.1.31
Downloaded radicle-surf v0.22.0
Downloaded num-iter v0.1.45
Downloaded signals_receipts v0.2.0
Downloaded icu_normalizer_data v1.5.1
Downloaded icu_normalizer v1.5.0
Downloaded tar v0.4.40
Downloaded yansi v0.5.1
Downloaded keccak v0.1.5
Downloaded maybe-async v0.2.10
Downloaded gix-fs v0.12.1
Downloaded gix-features v0.39.1
Downloaded mio v0.8.11
Downloaded ryu v1.0.17
Downloaded noise-framework v0.4.0
Downloaded similar v2.5.0
Downloaded tree-sitter-highlight v0.24.4
Downloaded referencing v0.30.0
Downloaded gix-actor v0.33.2
Downloaded signal-hook v0.3.18
Downloaded proc-macro-error-attr v1.0.4
Downloaded nonempty v0.9.0
Downloaded tree-sitter-css v0.23.1
Downloaded tinyvec v1.6.0
Downloaded snapbox v0.4.17
Downloaded cc v1.2.2
Downloaded crypto-bigint v0.5.5
Downloaded yoke-derive v0.7.5
Downloaded num-cmp v0.1.0
Downloaded nonempty v0.5.0
Downloaded log v0.4.21
Downloaded icu_locid v1.5.0
Downloaded hmac v0.12.1
Downloaded gix-odb v0.66.0
Downloaded gix-object v0.46.1
Downloaded xattr v1.3.1
Downloaded netservices v0.8.0
Downloaded p256 v0.13.2
Downloaded memchr v2.7.2
Downloaded fancy-regex v0.14.0
Downloaded signal-hook-registry v1.4.5
Downloaded sha2 v0.10.8
Downloaded serde_derive_internals v0.29.1
Downloaded scrypt v0.11.0
Downloaded spin v0.9.8
Downloaded miniz_oxide v0.8.8
Downloaded thiserror v2.0.12
Downloaded thiserror v1.0.69
Downloaded shell-words v1.1.0
Downloaded zerovec-derive v0.10.3
Downloaded tree-sitter-html v0.23.2
Downloaded gix-validate v0.9.4
Downloaded sem_safe v0.2.0
Downloaded sec1 v0.7.3
Downloaded home v0.5.9
Downloaded gix-date v0.9.4
Downloaded bitflags v2.9.1
Downloaded sqlite v0.32.0
Downloaded signal-hook-mio v0.2.4
Downloaded writeable v0.5.5
Downloaded utf16_iter v1.0.5
Downloaded sha1_smol v1.0.0
Downloaded rand_chacha v0.3.1
Downloaded qcheck v1.0.0
Downloaded normalize-line-endings v0.3.0
Downloaded subtle v2.5.0
Downloaded siphasher v0.3.11
Downloaded ppv-lite86 v0.2.17
Downloaded gix-path v0.10.15
Downloaded thiserror-impl v2.0.12
Downloaded thiserror-impl v1.0.69
Downloaded synstructure v0.13.1
Downloaded ssh-cipher v0.2.0
Downloaded signature v2.2.0
Downloaded signature v1.6.4
Downloaded shlex v1.3.0
Downloaded lazy_static v1.5.0
Downloaded ref-cast-impl v1.0.24
Downloaded stable_deref_trait v1.2.0
Downloaded sqlite3-sys v0.15.2
Downloaded scopeguard v1.2.0
Downloaded ref-cast v1.0.24
Downloaded primeorder v0.13.6
Downloaded tree-sitter-language v0.1.2
Downloaded rand_core v0.6.4
Downloaded blowfish v0.9.1
Downloaded gix-shallow v0.1.0
Downloaded gix-prompt v0.9.1
Downloaded gix-commitgraph v0.25.1
Downloaded gix-command v0.4.1
Downloaded gix-chunk v0.4.11
Downloaded version_check v0.9.4
Downloaded universal-hash v0.5.1
Downloaded unicode-width v0.1.11
Downloaded outref v0.5.2
Downloaded ssh-encoding v0.2.0
Downloaded rfc6979 v0.4.0
Downloaded ff v0.13.0
Downloaded vsimd v0.8.0
Downloaded ghash v0.5.1
Downloaded radicle-git-ext v0.8.1
Downloaded popol v3.0.0
Downloaded form_urlencoded v1.2.1
Downloaded fastrand v2.1.0
Downloaded dyn-clone v1.0.17
Downloaded cypheraddr v0.4.0
Downloaded email_address v0.2.9
Downloaded convert_case v0.7.1
Downloaded equivalent v1.0.1
Downloaded bcrypt-pbkdf v0.10.0
Downloaded localtime v1.3.1
Downloaded tinyvec_macros v0.1.1
Downloaded socks5-client v0.4.1
Downloaded chrono v0.4.38
Downloaded base64ct v1.6.0
Downloaded qcheck-macros v1.0.0
Downloaded either v1.11.0
Downloaded salsa20 v0.10.2
Downloaded pkcs8 v0.10.2
Downloaded cyphergraphy v0.3.0
Downloaded crypto-common v0.1.6
Downloaded regex v1.11.1
Downloaded quote v1.0.36
Downloaded polyval v0.6.2
Downloaded poly1305 v0.8.0
Downloaded pkg-config v0.3.30
Downloaded pkcs1 v0.7.5
Downloaded git-ref-format-macro v0.3.1
Downloaded emojis v0.6.4
Downloaded derive_more v2.0.1
Downloaded crossterm v0.29.0
Downloaded cpufeatures v0.2.12
Downloaded chacha20poly1305 v0.10.1
Downloaded block-buffer v0.10.4
Downloaded git2 v0.19.0
Downloaded getrandom v0.2.15
Downloaded generic-array v0.14.7
Downloaded document-features v0.2.11
Downloaded data-encoding-macro-internal v0.1.12
Downloaded data-encoding-macro v0.1.14
Downloaded data-encoding v2.5.0
Downloaded crossterm v0.25.0
Downloaded cipher v0.4.4
Downloaded der v0.7.9
Downloaded borrow-or-share v0.2.2
Downloaded bitflags v1.3.2
Downloaded bit-vec v0.8.0
Downloaded bit-set v0.8.0
Downloaded displaydoc v0.2.5
Downloaded digest v0.10.7
Downloaded ctr v0.9.2
Downloaded crossbeam-channel v0.5.15
Downloaded crc32fast v1.4.0
Downloaded const-oid v0.9.6
Downloaded colored v2.1.0
Downloaded chacha20 v0.9.1
Downloaded ecdsa v0.16.9
Downloaded colorchoice v1.0.0
Downloaded bytesize v2.0.1
Downloaded ed25519 v1.5.3
Downloaded ct-codecs v1.1.1
Downloaded bytecount v0.6.8
Downloaded cbc v0.1.2
Downloaded bloomy v1.2.0
Downloaded aho-corasick v1.1.3
Downloaded aes v0.8.4
Downloaded aes-gcm v0.10.3
Downloaded base64 v0.21.7
Downloaded arc-swap v1.7.1
Downloaded amplify_syn v2.0.1
Downloaded base64 v0.13.1
Downloaded anyhow v1.0.82
Downloaded ahash v0.8.11
Downloaded amplify v4.6.0
Downloaded anstyle-parse v0.2.3
Downloaded anstream v0.6.13
Downloaded amplify_num v0.5.2
Downloaded amplify_derive v4.0.0
Downloaded autocfg v1.2.0
Downloaded anstyle-query v1.0.2
Downloaded anstyle v1.0.6
Compiling libc v0.2.174
Compiling proc-macro2 v1.0.92
Compiling unicode-ident v1.0.12
Checking cfg-if v1.0.0
Compiling shlex v1.3.0
Compiling version_check v0.9.4
Checking memchr v2.7.2
Compiling serde v1.0.219
Compiling quote v1.0.36
Compiling autocfg v1.2.0
Compiling syn v2.0.89
Compiling jobserver v0.1.31
Checking getrandom v0.2.15
Checking smallvec v1.13.2
Checking aho-corasick v1.1.3
Compiling cc v1.2.2
Compiling typenum v1.17.0
Checking regex-syntax v0.8.5
Compiling generic-array v0.14.7
Checking log v0.4.21
Checking rand_core v0.6.4
Checking regex-automata v0.4.9
Checking fastrand v2.1.0
Compiling lock_api v0.4.11
Checking crypto-common v0.1.6
Checking bitflags v2.9.1
Compiling parking_lot_core v0.9.9
Checking scopeguard v1.2.0
Compiling synstructure v0.13.1
Checking stable_deref_trait v1.2.0
Checking subtle v2.5.0
Checking parking_lot v0.12.3
Checking tinyvec_macros v0.1.1
Checking once_cell v1.21.3
Compiling syn v1.0.109
Checking bstr v1.9.1
Checking tinyvec v1.6.0
Checking zeroize v1.7.0
Checking cpufeatures v0.2.12
Checking unicode-normalization v0.1.23
Compiling serde_derive v1.0.219
Compiling zerofrom-derive v0.1.6
Compiling yoke-derive v0.7.5
Compiling zerovec-derive v0.10.3
Checking zerofrom v0.1.6
Checking yoke v0.7.5
Compiling displaydoc v0.2.5
Checking zerovec v0.10.4
Checking writeable v0.5.5
Compiling crc32fast v1.4.0
Compiling icu_locid_transform_data v1.5.1
Checking tinystr v0.7.6
Checking litemap v0.7.5
Compiling thiserror v2.0.12
Checking icu_locid v1.5.0
Compiling thiserror-impl v2.0.12
Compiling icu_provider_macros v1.5.0
Checking block-padding v0.3.3
Compiling icu_properties_data v1.5.1
Checking inout v0.1.3
Checking icu_provider v1.5.0
Checking block-buffer v0.10.4
Compiling pkg-config v0.3.30
Checking itoa v1.0.11
Checking hashbrown v0.14.3
Compiling icu_normalizer_data v1.5.1
Checking icu_locid_transform v1.5.0
Checking digest v0.10.7
Checking cipher v0.4.4
Checking icu_collections v1.5.0
Checking write16 v1.0.0
Checking utf16_iter v1.0.5
Checking utf8_iter v1.0.4
Compiling thiserror v1.0.69
Compiling thiserror-impl v1.0.69
Compiling rustix v0.38.34
Checking icu_properties v1.5.1
Checking percent-encoding v2.3.1
Checking linux-raw-sys v0.4.13
Checking sha2 v0.10.8
Checking form_urlencoded v1.2.1
Checking universal-hash v0.5.1
Checking opaque-debug v0.3.1
Compiling vcpkg v0.2.15
Checking icu_normalizer v1.5.0
Compiling amplify_syn v2.0.1
Checking idna_adapter v1.2.0
Checking idna v1.0.3
Compiling libz-sys v1.1.16
Checking byteorder v1.5.0
Checking url v2.5.4
Checking gix-trace v0.1.12
Compiling data-encoding v2.5.0
Compiling amplify_derive v4.0.0
Checking tempfile v3.10.1
Compiling data-encoding-macro-internal v0.1.12
Checking amplify_num v0.5.2
Checking signature v1.6.4
Checking ascii v1.1.0
Checking ed25519 v1.5.3
Checking data-encoding-macro v0.1.14
Compiling libgit2-sys v0.17.0+1.8.1
Checking faster-hex v0.9.0
Checking aead v0.5.2
Compiling num-traits v0.2.19
Compiling proc-macro-error-attr v1.0.4
Checking base-x v0.2.11
Checking ct-codecs v1.1.1
Checking multibase v0.9.1
Checking ec25519 v0.1.0
Checking amplify v4.6.0
Checking poly1305 v0.8.0
Checking chacha20 v0.9.1
Checking gix-utils v0.1.14
Compiling proc-macro-error v1.0.4
Checking adler2 v2.0.0
Checking cyphergraphy v0.3.0
Checking miniz_oxide v0.8.8
Checking gix-hash v0.15.1
Checking same-file v1.0.6
Compiling crossbeam-utils v0.8.19
Checking keccak v0.1.5
Checking flate2 v1.1.1
Checking sha3 v0.10.8
Checking walkdir v2.5.0
Compiling git-ref-format-core v0.3.1
Checking polyval v0.6.2
Checking hmac v0.12.1
Compiling sqlite3-src v0.5.1
Checking prodash v29.0.2
Compiling serde_json v1.0.140
Checking base64ct v1.6.0
Checking base32 v0.4.0
Checking sha1_smol v1.0.0
Checking equivalent v1.0.1
Checking ppv-lite86 v0.2.17
Checking indexmap v2.2.6
Checking gix-features v0.39.1
Checking rand_chacha v0.3.1
Checking pem-rfc7468 v0.7.0
Checking cypheraddr v0.4.0
Compiling git-ref-format-macro v0.3.1
Checking pbkdf2 v0.12.2
Checking ghash v0.5.1
Checking chacha20poly1305 v0.10.1
Checking aes v0.8.4
Checking ctr v0.9.2
Checking ryu v1.0.17
Checking aes-gcm v0.10.3
Checking git-ref-format v0.3.1
Checking crossbeam-channel v0.5.15
Checking noise-framework v0.4.0
Checking socks5-client v0.4.1
Checking ssh-encoding v0.2.0
Checking rand v0.8.5
Checking blowfish v0.9.1
Checking cbc v0.1.2
Compiling ref-cast v1.0.24
Checking radicle-std-ext v0.1.0
Checking home v0.5.9
Checking gix-path v0.10.15
Checking ssh-cipher v0.2.0
Checking bcrypt-pbkdf v0.10.0
Checking cyphernet v0.5.2
Compiling ref-cast-impl v1.0.24
Checking signature v2.2.0
Checking ssh-key v0.6.6
Checking qcheck v1.0.0
Checking radicle-ssh v0.9.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-ssh)
Checking lazy_static v1.5.0
Checking dyn-clone v1.0.17
Checking siphasher v1.0.1
Checking nonempty v0.9.0
Compiling serde_derive_internals v0.29.1
Checking radicle-dag v0.10.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-dag)
Checking tree-sitter-language v0.1.2
Checking iana-time-zone v0.1.60
Checking jiff v0.2.1
Compiling schemars_derive v1.0.0-alpha.17
Checking schemars v1.0.0-alpha.17
Checking gix-date v0.9.4
Checking chrono v0.4.38
Checking colored v2.1.0
Checking bytesize v2.0.1
Checking localtime v1.3.1
Checking winnow v0.6.26
Checking base64 v0.21.7
Compiling anyhow v1.0.82
Checking gix-hashtable v0.6.0
Checking gix-validate v0.9.4
Checking anstyle-query v1.0.2
Checking memmap2 v0.9.4
Checking gix-chunk v0.4.11
Checking gix-actor v0.33.2
Checking errno v0.3.13
Checking gix-object v0.46.1
Checking sem_safe v0.2.0
Checking signals_receipts v0.2.0
Checking gix-commitgraph v0.25.1
Compiling signal-hook v0.3.18
Checking gix-revwalk v0.17.0
Checking gix-fs v0.12.1
Checking signal-hook-registry v1.4.5
Checking gix-tempfile v15.0.0
Checking radicle-signals v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-signals)
Checking mio v1.0.4
Checking mio v0.8.11
Compiling tree-sitter v0.24.4
Compiling unicode-segmentation v1.11.0
Compiling convert_case v0.7.1
Checking signal-hook-mio v0.2.4
Checking regex v1.11.1
Compiling rustix v1.0.7
Checking shell-words v1.1.0
Checking gix-command v0.4.1
Compiling xattr v1.3.1
Compiling derive_more-impl v2.0.1
Compiling filetime v0.2.23
Compiling litrs v0.4.1
Checking bitflags v1.3.2
Checking lexopt v0.3.0
Checking utf8parse v0.2.1
Checking linux-raw-sys v0.9.4
Checking anstyle-parse v0.2.3
Checking crossterm v0.25.0
Compiling document-features v0.2.11
Checking sqlite3-sys v0.15.2
Checking sqlite v0.32.0
Checking derive_more v2.0.1
Compiling tar v0.4.40
Checking newline-converter v0.3.0
Checking gix-lock v15.0.1
Checking gix-config-value v0.14.12
Checking gix-url v0.28.2
Checking gix-quote v0.4.15
Checking fxhash v0.2.1
Checking gix-sec v0.10.12
Checking streaming-iterator v0.1.9
Checking colorchoice v1.0.0
Checking unicode-width v0.1.11
Checking anstyle v1.0.6
Checking inquire v0.7.5
Checking anstream v0.6.13
Compiling radicle-surf v0.22.0
Checking gix-prompt v0.9.1
Checking crossterm v0.29.0
Checking unicode-display-width v0.3.0
Checking gix-traverse v0.43.1
Checking gix-revision v0.31.1
Checking gix-diff v0.49.0
Checking gix-packetline v0.18.4
Compiling tree-sitter-toml-ng v0.6.0
Compiling tree-sitter-typescript v0.23.2
Compiling tree-sitter-json v0.24.8
Compiling tree-sitter-rust v0.23.2
Compiling tree-sitter-html v0.23.2
Compiling tree-sitter-css v0.23.1
Compiling tree-sitter-bash v0.23.3
Compiling tree-sitter-md v0.3.2
Compiling tree-sitter-c v0.23.2
Compiling tree-sitter-python v0.23.4
Compiling tree-sitter-go v0.23.4
Compiling tree-sitter-ruby v0.23.1
Checking gix-transport v0.44.0
Checking gix-pack v0.56.0
Checking gix-refspec v0.27.0
Checking gix-credentials v0.26.0
Checking snapbox-macros v0.3.8
Checking gix-shallow v0.1.0
Checking gix-ref v0.49.1
Checking gix-negotiate v0.17.0
Compiling maybe-async v0.2.10
Checking similar v2.5.0
Compiling radicle-cli v0.13.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cli)
Checking base64 v0.13.1
Checking nonempty v0.5.0
Checking normalize-line-endings v0.3.0
Checking arc-swap v1.7.1
Checking snapbox v0.4.17
Checking gix-odb v0.66.0
Checking gix-protocol v0.47.0
Checking tree-sitter-highlight v0.24.4
Checking popol v3.0.0
Checking timeago v0.4.2
Checking either v1.11.0
Checking io-reactor v0.5.2
Checking salsa20 v0.10.2
Checking socket2 v0.5.7
Checking yansi v0.5.1
Checking diff v0.1.13
Compiling radicle-node v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-node)
Checking siphasher v0.3.11
Checking netservices v0.8.0
Checking bloomy v1.2.0
Checking pretty_assertions v1.4.0
Checking scrypt v0.11.0
Checking num-integer v0.1.46
Checking radicle-systemd v0.9.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-systemd)
Compiling escargot v0.5.10
Checking num-bigint v0.4.6
Compiling qcheck-macros v1.0.0
Compiling ahash v0.8.11
Compiling radicle-remote-helper v0.10.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-remote-helper)
Checking num-iter v0.1.45
Checking num-complex v0.4.6
Checking num-rational v0.4.2
Checking bit-vec v0.8.0
Checking borrow-or-share v0.2.2
Checking zerocopy v0.7.35
Checking fluent-uri v0.3.2
Checking bit-set v0.8.0
Checking num v0.4.3
Checking phf_shared v0.11.3
Checking vsimd v0.8.0
Checking uuid v1.16.0
Checking outref v0.5.2
Checking referencing v0.30.0
Checking phf v0.11.3
Checking uuid-simd v0.8.0
Checking fraction v0.15.3
Checking fancy-regex v0.14.0
Checking email_address v0.2.9
Checking base64 v0.22.1
Checking bytecount v0.6.8
Checking num-cmp v0.1.0
Checking emojis v0.6.4
Checking jsonschema v0.30.0
Checking git2 v0.19.0
Checking radicle-git-ext v0.8.1
Checking radicle-term v0.12.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-term)
Checking radicle-crypto v0.12.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-crypto)
Checking radicle-cob v0.14.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cob)
Checking radicle v0.15.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle)
Checking radicle-fetch v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-fetch)
Checking radicle-cli-test v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cli-test)
Checking radicle-schemars v0.1.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-schemars)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 40.28s
+ cargo build --all-targets --workspace
Compiling cfg-if v1.0.0
Compiling libc v0.2.174
Compiling shlex v1.3.0
Compiling memchr v2.7.2
Compiling serde v1.0.219
Compiling smallvec v1.13.2
Compiling jobserver v0.1.31
Compiling getrandom v0.2.15
Compiling aho-corasick v1.1.3
Compiling regex-syntax v0.8.5
Compiling cc v1.2.2
Compiling regex-automata v0.4.9
Compiling typenum v1.17.0
Compiling log v0.4.21
Compiling rand_core v0.6.4
Compiling generic-array v0.14.7
Compiling bitflags v2.9.1
Compiling fastrand v2.1.0
Compiling crypto-common v0.1.6
Compiling scopeguard v1.2.0
Compiling lock_api v0.4.11
Compiling zerofrom v0.1.6
Compiling parking_lot_core v0.9.9
Compiling stable_deref_trait v1.2.0
Compiling subtle v2.5.0
Compiling parking_lot v0.12.3
Compiling yoke v0.7.5
Compiling once_cell v1.21.3
Compiling tinyvec_macros v0.1.1
Compiling zerovec v0.10.4
Compiling tinyvec v1.6.0
Compiling zeroize v1.7.0
Compiling cpufeatures v0.2.12
Compiling bstr v1.9.1
Compiling unicode-normalization v0.1.23
Compiling tinystr v0.7.6
Compiling writeable v0.5.5
Compiling litemap v0.7.5
Compiling block-padding v0.3.3
Compiling thiserror v2.0.12
Compiling inout v0.1.3
Compiling icu_locid v1.5.0
Compiling icu_locid_transform_data v1.5.1
Compiling block-buffer v0.10.4
Compiling itoa v1.0.11
Compiling adler2 v2.0.0
Compiling hashbrown v0.14.3
Compiling miniz_oxide v0.8.8
Compiling icu_provider v1.5.0
Compiling digest v0.10.7
Compiling icu_locid_transform v1.5.0
Compiling cipher v0.4.4
Compiling crc32fast v1.4.0
Compiling icu_properties_data v1.5.1
Compiling icu_collections v1.5.0
Compiling icu_normalizer_data v1.5.1
Compiling utf16_iter v1.0.5
Compiling icu_properties v1.5.1
Compiling utf8_iter v1.0.4
Compiling write16 v1.0.0
Compiling percent-encoding v2.3.1
Compiling linux-raw-sys v0.4.13
Compiling thiserror v1.0.69
Compiling sha2 v0.10.8
Compiling form_urlencoded v1.2.1
Compiling rustix v0.38.34
Compiling universal-hash v0.5.1
Compiling opaque-debug v0.3.1
Compiling libz-sys v1.1.16
Compiling gix-trace v0.1.12
Compiling byteorder v1.5.0
Compiling signature v1.6.4
Compiling icu_normalizer v1.5.0
Compiling data-encoding v2.5.0
Compiling idna_adapter v1.2.0
Compiling idna v1.0.3
Compiling tempfile v3.10.1
Compiling ascii v1.1.0
Compiling url v2.5.4
Compiling amplify_num v0.5.2
Compiling data-encoding-macro v0.1.14
Compiling ed25519 v1.5.3
Compiling libgit2-sys v0.17.0+1.8.1
Compiling aead v0.5.2
Compiling faster-hex v0.9.0
Compiling ct-codecs v1.1.1
Compiling base-x v0.2.11
Compiling ec25519 v0.1.0
Compiling multibase v0.9.1
Compiling poly1305 v0.8.0
Compiling amplify v4.6.0
Compiling chacha20 v0.9.1
Compiling gix-utils v0.1.14
Compiling cyphergraphy v0.3.0
Compiling num-traits v0.2.19
Compiling gix-hash v0.15.1
Compiling same-file v1.0.6
Compiling keccak v0.1.5
Compiling walkdir v2.5.0
Compiling sha3 v0.10.8
Compiling polyval v0.6.2
Compiling git-ref-format-core v0.3.1
Compiling flate2 v1.1.1
Compiling hmac v0.12.1
Compiling sqlite3-src v0.5.1
Compiling prodash v29.0.2
Compiling sha1_smol v1.0.0
Compiling base64ct v1.6.0
Compiling equivalent v1.0.1
Compiling base32 v0.4.0
Compiling ppv-lite86 v0.2.17
Compiling pem-rfc7468 v0.7.0
Compiling cypheraddr v0.4.0
Compiling rand_chacha v0.3.1
Compiling gix-features v0.39.1
Compiling indexmap v2.2.6
Compiling git-ref-format-macro v0.3.1
Compiling pbkdf2 v0.12.2
Compiling ghash v0.5.1
Compiling crossbeam-utils v0.8.19
Compiling chacha20poly1305 v0.10.1
Compiling ctr v0.9.2
Compiling aes v0.8.4
Compiling ryu v1.0.17
Compiling serde_json v1.0.140
Compiling aes-gcm v0.10.3
Compiling git-ref-format v0.3.1
Compiling crossbeam-channel v0.5.15
Compiling noise-framework v0.4.0
Compiling socks5-client v0.4.1
Compiling rand v0.8.5
Compiling ssh-encoding v0.2.0
Compiling blowfish v0.9.1
Compiling cbc v0.1.2
Compiling home v0.5.9
Compiling radicle-std-ext v0.1.0
Compiling gix-path v0.10.15
Compiling ssh-cipher v0.2.0
Compiling bcrypt-pbkdf v0.10.0
Compiling cyphernet v0.5.2
Compiling signature v2.2.0
Compiling ssh-key v0.6.6
Compiling ref-cast v1.0.24
Compiling qcheck v1.0.0
Compiling radicle-ssh v0.9.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-ssh)
Compiling dyn-clone v1.0.17
Compiling lazy_static v1.5.0
Compiling siphasher v1.0.1
Compiling radicle-dag v0.10.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-dag)
Compiling nonempty v0.9.0
Compiling tree-sitter-language v0.1.2
Compiling jiff v0.2.1
Compiling iana-time-zone v0.1.60
Compiling chrono v0.4.38
Compiling schemars v1.0.0-alpha.17
Compiling gix-date v0.9.4
Compiling colored v2.1.0
Compiling bytesize v2.0.1
Compiling localtime v1.3.1
Compiling winnow v0.6.26
Compiling base64 v0.21.7
Compiling gix-actor v0.33.2
Compiling gix-hashtable v0.6.0
Compiling gix-validate v0.9.4
Compiling anstyle-query v1.0.2
Compiling memmap2 v0.9.4
Compiling gix-object v0.46.1
Compiling anyhow v1.0.82
Compiling gix-chunk v0.4.11
Compiling sem_safe v0.2.0
Compiling errno v0.3.13
Compiling unicode-segmentation v1.11.0
Compiling signals_receipts v0.2.0
Compiling gix-commitgraph v0.25.1
Compiling gix-revwalk v0.17.0
Compiling sqlite3-sys v0.15.2
Compiling gix-fs v0.12.1
Compiling sqlite v0.32.0
Compiling signal-hook-registry v1.4.5
Compiling signal-hook v0.3.18
Compiling gix-tempfile v15.0.0
Compiling radicle-signals v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-signals)
Compiling mio v0.8.11
Compiling mio v1.0.4
Compiling tree-sitter v0.24.4
Compiling signal-hook-mio v0.2.4
Compiling convert_case v0.7.1
Compiling regex v1.11.1
Compiling shell-words v1.1.0
Compiling gix-command v0.4.1
Compiling xattr v1.3.1
Compiling derive_more-impl v2.0.1
Compiling filetime v0.2.23
Compiling utf8parse v0.2.1
Compiling linux-raw-sys v0.9.4
Compiling lexopt v0.3.0
Compiling bitflags v1.3.2
Compiling crossterm v0.25.0
Compiling rustix v1.0.7
Compiling derive_more v2.0.1
Compiling anstyle-parse v0.2.3
Compiling tar v0.4.40
Compiling gix-lock v15.0.1
Compiling newline-converter v0.3.0
Compiling gix-url v0.28.2
Compiling gix-config-value v0.14.12
Compiling gix-quote v0.4.15
Compiling fxhash v0.2.1
Compiling gix-sec v0.10.12
Compiling unicode-width v0.1.11
Compiling streaming-iterator v0.1.9
Compiling colorchoice v1.0.0
Compiling anstyle v1.0.6
Compiling radicle-surf v0.22.0
Compiling anstream v0.6.13
Compiling inquire v0.7.5
Compiling gix-prompt v0.9.1
Compiling crossterm v0.29.0
Compiling gix-traverse v0.43.1
Compiling gix-revision v0.31.1
Compiling unicode-display-width v0.3.0
Compiling gix-diff v0.49.0
Compiling gix-packetline v0.18.4
Compiling tree-sitter-python v0.23.4
Compiling tree-sitter-rust v0.23.2
Compiling tree-sitter-html v0.23.2
Compiling tree-sitter-typescript v0.23.2
Compiling tree-sitter-c v0.23.2
Compiling tree-sitter-go v0.23.4
Compiling tree-sitter-toml-ng v0.6.0
Compiling tree-sitter-bash v0.23.3
Compiling tree-sitter-css v0.23.1
Compiling tree-sitter-json v0.24.8
Compiling tree-sitter-ruby v0.23.1
Compiling tree-sitter-md v0.3.2
Compiling gix-transport v0.44.0
Compiling gix-pack v0.56.0
Compiling gix-refspec v0.27.0
Compiling gix-credentials v0.26.0
Compiling snapbox-macros v0.3.8
Compiling gix-shallow v0.1.0
Compiling gix-ref v0.49.1
Compiling gix-negotiate v0.17.0
Compiling base64 v0.13.1
Compiling nonempty v0.5.0
Compiling arc-swap v1.7.1
Compiling similar v2.5.0
Compiling radicle-cli v0.13.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cli)
Compiling normalize-line-endings v0.3.0
Compiling snapbox v0.4.17
Compiling gix-odb v0.66.0
Compiling gix-protocol v0.47.0
Compiling tree-sitter-highlight v0.24.4
Compiling popol v3.0.0
Compiling either v1.11.0
Compiling timeago v0.4.2
Compiling io-reactor v0.5.2
Compiling salsa20 v0.10.2
Compiling socket2 v0.5.7
Compiling yansi v0.5.1
Compiling diff v0.1.13
Compiling siphasher v0.3.11
Compiling radicle-node v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-node)
Compiling bloomy v1.2.0
Compiling pretty_assertions v1.4.0
Compiling netservices v0.8.0
Compiling scrypt v0.11.0
Compiling num-integer v0.1.46
Compiling radicle-systemd v0.9.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-systemd)
Compiling escargot v0.5.10
Compiling num-bigint v0.4.6
Compiling radicle-remote-helper v0.10.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-remote-helper)
Compiling num-iter v0.1.45
Compiling num-complex v0.4.6
Compiling borrow-or-share v0.2.2
Compiling num-rational v0.4.2
Compiling bit-vec v0.8.0
Compiling zerocopy v0.7.35
Compiling ahash v0.8.11
Compiling num v0.4.3
Compiling bit-set v0.8.0
Compiling fluent-uri v0.3.2
Compiling phf_shared v0.11.3
Compiling vsimd v0.8.0
Compiling uuid v1.16.0
Compiling outref v0.5.2
Compiling referencing v0.30.0
Compiling uuid-simd v0.8.0
Compiling phf v0.11.3
Compiling fancy-regex v0.14.0
Compiling fraction v0.15.3
Compiling email_address v0.2.9
Compiling base64 v0.22.1
Compiling bytecount v0.6.8
Compiling num-cmp v0.1.0
Compiling emojis v0.6.4
Compiling jsonschema v0.30.0
Compiling git2 v0.19.0
Compiling radicle-git-ext v0.8.1
Compiling radicle-term v0.12.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-term)
Compiling radicle-crypto v0.12.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-crypto)
Compiling radicle-cob v0.14.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cob)
Compiling radicle v0.15.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle)
Compiling radicle-fetch v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-fetch)
Compiling radicle-cli-test v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cli-test)
Compiling radicle-schemars v0.1.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-schemars)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 02s
+ cargo doc --workspace --no-deps
Checking regex-automata v0.4.9
Compiling syn v1.0.109
Checking idna v1.0.3
Checking radicle-ssh v0.9.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-ssh)
Checking url v2.5.4
Compiling num-traits v0.2.19
Checking git2 v0.19.0
Checking radicle-dag v0.10.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-dag)
Checking chrono v0.4.38
Checking bstr v1.9.1
Compiling amplify_syn v2.0.1
Compiling proc-macro-error v1.0.4
Checking gix-path v0.10.15
Compiling data-encoding-macro-internal v0.1.12
Compiling git-ref-format-macro v0.3.1
Checking git-ref-format-core v0.3.1
Checking gix-date v0.9.4
Checking gix-actor v0.33.2
Checking data-encoding-macro v0.1.14
Checking multibase v0.9.1
Compiling amplify_derive v4.0.0
Checking gix-validate v0.9.4
Checking git-ref-format v0.3.1
Checking gix-object v0.46.1
Checking gix-commitgraph v0.25.1
Checking radicle-git-ext v0.8.1
Checking radicle-signals v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-signals)
Checking regex v1.11.1
Checking gix-command v0.4.1
Compiling radicle-cli v0.13.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cli)
Checking radicle-surf v0.22.0
Checking tree-sitter v0.24.4
Checking tree-sitter-toml-ng v0.6.0
Checking gix-revwalk v0.17.0
Checking tree-sitter-highlight v0.24.4
Checking radicle-term v0.12.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-term)
Checking gix-url v0.28.2
Checking gix-config-value v0.14.12
Checking gix-quote v0.4.15
Checking gix-prompt v0.9.1
Checking gix-revision v0.31.1
Checking gix-traverse v0.43.1
Checking gix-diff v0.49.0
Checking gix-packetline v0.18.4
Checking gix-pack v0.56.0
Checking gix-refspec v0.27.0
Checking gix-transport v0.44.0
Checking gix-credentials v0.26.0
Checking amplify v4.6.0
Checking gix-negotiate v0.17.0
Checking gix-shallow v0.1.0
Checking cyphergraphy v0.3.0
Checking gix-ref v0.49.1
Checking io-reactor v0.5.2
Checking cypheraddr v0.4.0
Checking noise-framework v0.4.0
Checking socks5-client v0.4.1
Compiling radicle-node v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-node)
Checking cyphernet v0.5.2
Checking radicle-crypto v0.12.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-crypto)
Checking gix-odb v0.66.0
Checking netservices v0.8.0
Checking radicle-cob v0.14.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cob)
Checking gix-protocol v0.47.0
Checking radicle-systemd v0.9.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-systemd)
Documenting radicle-cob v0.14.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cob)
Checking radicle v0.15.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle)
Documenting radicle v0.15.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle)
Documenting radicle-crypto v0.12.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-crypto)
Documenting radicle-term v0.12.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-term)
Documenting radicle-signals v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-signals)
Documenting radicle-ssh v0.9.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-ssh)
Documenting radicle-dag v0.10.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-dag)
Documenting radicle-systemd v0.9.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-systemd)
Checking radicle-fetch v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-fetch)
Documenting radicle-cli v0.13.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cli)
Documenting radicle-fetch v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-fetch)
Documenting radicle-node v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-node)
Documenting radicle-cli-test v0.11.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cli-test)
Documenting radicle-schemars v0.1.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-schemars)
Documenting radicle-remote-helper v0.10.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-remote-helper)
Checking radicle-remote-helper v0.10.0 (/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-remote-helper)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 9.05s
Generated /27fb8593-158e-4c0c-aba4-e9774df097ee/w/target/doc/radicle/index.html and 15 other files
+ cargo test --workspace --no-fail-fast
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.16s
Running unittests src/lib.rs (target/debug/deps/radicle-f7aabfdef0ad0fc0)
running 188 tests
test canonical::formatter::test::ascii_control_characters ... ok
test canonical::formatter::test::securesystemslib_asserts ... ok
test canonical::formatter::test::ordered_nested_object ... ok
test cob::cache::migrations::_2::tests::test_patch_json_deserialization ... ok
test cob::common::test::test_color ... ok
test cob::cache::tests::test_check_version ... ok
test cob::cache::tests::test_migrate_to ... ok
test cob::cache::migrations::_2::tests::test_migration_2 ... ok
test cob::common::test::test_emojis ... ok
test cob::identity::test::prop_json_eq_str ... ok
test cob::identity::test::test_identity_redact_revision ... ok
test cob::identity::test::test_identity_update_rejected ... ok
test cob::identity::test::test_identity_remove_delegate_concurrent ... ok
test cob::identity::test::test_identity_reject_concurrent ... ok
test cob::identity::test::test_identity_updates ... ok
test cob::issue::cache::tests::test_counts ... ok
test cob::issue::cache::tests::test_get ... ok
test cob::issue::cache::tests::test_is_empty ... ok
test cob::identity::test::test_valid_identity ... ok
test cob::issue::cache::tests::test_list ... ok
test cob::issue::cache::tests::test_list_by_status ... ok
test cob::issue::cache::tests::test_remove ... ok
test cob::identity::test::test_identity_updates_concurrent ... ok
test cob::issue::test::test_embeds ... ok
test cob::issue::test::test_embeds_edit ... ok
test cob::identity::test::test_identity_updates_concurrent_outdated ... ok
test cob::issue::test::test_invalid_actions ... ok
test cob::issue::test::test_invalid_cob ... ok
test cob::issue::test::test_invalid_tx ... ok
test cob::issue::test::test_invalid_tx_reference ... ok
test cob::issue::test::test_concurrency ... ok
test cob::issue::test::test_issue_all ... ok
test cob::issue::test::test_issue_comment ... ok
test cob::issue::test::test_issue_comment_redact ... ok
test cob::issue::test::test_issue_create_and_change_state ... ok
test cob::issue::test::test_issue_create_and_assign ... ok
test cob::issue::test::test_issue_create_and_get ... ok
test cob::issue::test::test_issue_create_and_unassign ... ok
test cob::issue::test::test_issue_create_and_reassign ... ok
test cob::issue::test::test_issue_edit ... ok
test cob::issue::test::test_issue_edit_description ... ok
test cob::issue::test::test_issue_multilines ... ok
test cob::issue::test::test_issue_state_serde ... ok
test cob::issue::test::test_ordering ... ok
test cob::issue::test::test_issue_label ... ok
test cob::issue::test::test_issue_react ... ok
test cob::patch::cache::tests::test_get ... ok
test cob::patch::cache::tests::test_is_empty ... ok
test cob::patch::cache::tests::test_list ... ok
test cob::issue::test::test_issue_reply ... ok
test cob::patch::cache::tests::test_remove ... ok
test cob::patch::test::test_json ... ok
test cob::patch::test::test_json_serialization ... ok
test cob::patch::cache::tests::test_list_by_status ... ok
test cob::patch::cache::tests::test_find_by_revision ... ok
test cob::patch::cache::tests::test_counts ... ok
test cob::patch::test::test_patch_create_and_get ... ok
test cob::patch::test::test_patch_discussion ... ok
test cob::patch::test::test_patch_merge ... ok
test cob::patch::test::test_patch_review ... ok
test cob::patch::test::test_patch_review_comment ... ok
test cob::patch::test::test_patch_review_duplicate ... ok
test cob::patch::test::test_patch_redact ... ok
test cob::patch::test::test_patch_review_edit ... ok
test cob::patch::test::test_patch_review_remove_summary ... ok
test cob::patch::test::test_reactions_json_serialization ... ok
test cob::patch::test::test_revision_edit_redact ... ok
test cob::patch::test::test_revision_reaction ... ok
test cob::patch::test::test_revision_review_merge_redacted ... ok
test cob::patch::test::test_patch_review_edit_comment ... ok
test cob::thread::tests::test_comment_edit_missing ... ok
test cob::thread::tests::test_comment_edit_redacted ... ok
test cob::thread::tests::test_comment_redact_missing ... ok
test cob::thread::tests::test_duplicate_comments ... ok
test cob::thread::tests::test_edit_comment ... ok
test cob::thread::tests::test_redact_comment ... ok
test cob::thread::tests::test_timeline ... ok
test cob::patch::test::test_patch_review_revision_redact ... ok
test git::canonical::tests::test_quorum_merges ... ok
test git::canonical::tests::test_quorum ... ok
test git::test::test_version_from_str ... ok
test git::test::test_version_ord ... ok
test identity::did::test::test_did_encode_decode ... ok
test identity::did::test::test_did_vectors ... ok
test identity::doc::id::test::prop_from_str ... ok
test cob::patch::test::test_patch_update ... ok
test git::canonical::tests::test_quorum_properties ... ok
test identity::doc::test::test_canonical_doc ... ok
test identity::doc::test::test_duplicate_dids ... ok
test identity::doc::test::test_future_version_error ... ok
test identity::doc::test::test_is_valid_version ... ok
test identity::doc::test::test_max_delegates ... ok
test identity::doc::test::test_not_found ... ok
test identity::doc::test::test_parse_version ... ok
test identity::doc::test::test_visibility_json ... ok
test identity::project::test::test_project_name ... ok
test node::address::store::test::test_alias ... ok
test node::address::store::test::test_disconnected ... ok
test node::address::store::test::test_disconnected_ban ... ok
test identity::doc::test::test_canonical_example ... ok
test node::address::store::test::test_entries ... ok
test node::address::store::test::test_get_none ... ok
test node::address::store::test::test_insert_and_get ... ok
test node::address::store::test::test_insert_and_remove ... ok
test node::address::store::test::test_insert_and_update ... ok
test node::address::store::test::test_insert_duplicate ... ok
test node::address::store::test::test_node_aliases ... ok
test node::address::store::test::test_empty ... ok
test node::db::test::test_version ... ok
test node::address::store::test::test_remove_nothing ... ok
test node::features::test::test_operations ... ok
test node::notifications::store::test::test_branch_notifications ... ok
test node::notifications::store::test::test_clear ... ok
test node::notifications::store::test::test_cob_notifications ... ok
test node::notifications::store::test::test_counts_by_repo ... ok
test node::notifications::store::test::test_duplicate_notifications ... ok
test node::notifications::store::test::test_notification_status ... ok
test node::policy::store::test::test_follow_and_unfollow_node ... ok
test node::policy::store::test::test_node_aliases ... ok
test node::policy::store::test::test_node_policies ... ok
test node::policy::store::test::test_node_policy ... ok
test node::policy::store::test::test_repo_policies ... ok
test node::policy::store::test::test_repo_policy ... ok
test node::policy::store::test::test_seed_and_unseed_repo ... ok
test node::policy::store::test::test_update_alias ... ok
test node::policy::store::test::test_update_scope ... ok
test node::refs::store::test::test_count ... ok
test node::refs::store::test::test_set_and_delete ... ok
test node::refs::store::test::test_set_and_get ... ok
test node::routing::test::test_count ... ok
test node::routing::test::test_entries ... ok
test node::routing::test::test_insert_and_get ... ok
test node::routing::test::test_insert_and_remove ... ok
test node::routing::test::test_insert_and_get_resources ... ok
test node::routing::test::test_insert_existing_updated_time ... ok
test node::routing::test::test_insert_duplicate ... ok
test node::routing::test::test_len ... ok
test node::routing::test::test_prune ... ok
test node::routing::test::test_remove_many ... ok
test node::routing::test::test_update_existing_multi ... ok
test node::routing::test::test_remove_redundant ... ok
test node::sync::announce::test::announcer_must_reach_preferred_seeds ... ok
test node::sync::announce::test::announcer_reached_max_replication_target ... ok
test node::sync::announce::test::announcer_timed_out ... ok
test node::sync::announce::test::announcer_reached_min_replication_target ... ok
test node::sync::announce::test::cannot_construct_announcer ... ok
test node::sync::announce::test::announcer_will_minimise_replication_factor ... ok
test node::sync::fetch::test::all_nodes_are_candidates ... ok
test node::sync::fetch::test::all_nodes_are_fetchable ... ok
test node::sync::fetch::test::could_not_reach_target ... ok
test node::sync::fetch::test::ignores_duplicates_and_local_node ... ok
test node::sync::fetch::test::preferred_seeds_target_returned_over_replicas ... ok
test node::sync::fetch::test::reaches_target_of_max_replicas ... ok
test node::sync::fetch::test::reaches_target_of_preferred_seeds ... ok
test cob::thread::tests::prop_ordering ... ok
test node::sync::fetch::test::reaches_target_of_replicas ... ok
test node::sync::test::ensure_replicas_construction ... ok
test node::test::test_alias ... ok
test node::test::test_command_result ... ok
test node::sync::test::replicas_constrain_to ... ok
test node::test::test_user_agent ... ok
test node::timestamp::tests::test_timestamp_max ... ok
test profile::test::canonicalize_home ... ok
test profile::test::test_config ... ok
test rad::tests::test_fork ... ok
test rad::tests::test_init ... ok
test serde_ext::test::test_localtime ... ok
test serde_ext::test::test_localtime_ext ... ok
test rad::tests::test_checkout ... ok
test profile::config::test::schema ... ok
test storage::git::tests::test_references_of ... ok
test storage::git::transport::local::url::test::test_url_parse ... ok
test storage::git::transport::local::url::test::test_url_to_string ... ok
test storage::git::transport::remote::url::test::test_url_parse ... ok
test storage::refs::tests::prop_canonical_roundtrip ... ok
test storage::git::tests::test_sign_refs ... ok
test storage::tests::test_storage ... ok
test test::assert::test::assert_with_message ... ok
test test::assert::test::test_assert_no_move ... ok
test test::assert::test::test_assert_panic_0 - should panic ... ok
test test::assert::test::test_assert_panic_1 - should panic ... ok
test test::assert::test::test_assert_panic_2 - should panic ... ok
test test::assert::test::test_assert_succeed ... ok
test test::assert::test::test_panic_message ... ok
test version::test::test_version ... ok
test storage::git::tests::test_remote_refs ... ok
test storage::refs::tests::test_rid_verification ... ok
test identity::doc::test::prop_encode_decode ... ok
test result: ok. 188 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.07s
Running unittests src/lib.rs (target/debug/deps/radicle_cli-74153bd6daf7f987)
running 14 tests
test commands::rad_inspect::test::test_tree ... ok
test commands::rad_patch::review::builder::tests::test_review_comments_multiline ... ok
test commands::rad_patch::review::builder::tests::test_review_comments_basic ... ok
test commands::rad_patch::review::builder::tests::test_review_comments_split_hunk ... ok
test commands::rad_patch::review::builder::tests::test_review_comments_before ... ok
test git::pretty_diff::test::test_pretty ... ignored
test git::unified_diff::test::test_diff_content_encode_decode_content ... ok
test terminal::format::test::test_bytes ... ok
test git::ddiff::tests::diff_encode_decode_ddiff_hunk ... ok
test terminal::patch::test::test_edit_display_message ... ok
test terminal::format::test::test_strip_comments ... ok
test git::unified_diff::test::test_diff_encode_decode_diff ... ok
test terminal::patch::test::test_create_display_message ... ok
test terminal::patch::test::test_update_display_message ... ok
test result: ok. 13 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.01s
Running unittests src/main.rs (target/debug/deps/rad-fd35f2fedcf16b47)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running tests/commands.rs (target/debug/deps/commands-39f585a25cdd31b6)
running 97 tests
test framework_home ... ok
test git_push_amend ... ok
test git_push_and_fetch ... ok
test git_push_diverge ... ok
test rad_auth ... ok
test rad_auth_errors ... ok
test rad_block ... ok
test rad_checkout ... ok
test git_push_converge ... ok
test git_tag ... ok
test git_push_rollback ... ok
test rad_clone ... ok
test rad_clone_connect ... ok
test rad_clean ... ok
test rad_clone_unknown ... ok
test rad_clone_directory ... ok
test rad_cob_log ... ok
test rad_cob_multiset ... ok
test rad_clone_all ... ok
test rad_clone_partial_fail ... ok
test rad_cob_migrate ... ok
test rad_cob_update_identity ... ok
test rad_config ... ok
test rad_cob_show ... ok
test rad_cob_update ... ok
test rad_diff ... ok
test rad_id_collaboration ... ignored, slow
test rad_id ... ok
test rad_id_conflict ... ok
test rad_id_private ... ok
test rad_id_multi_delegate ... ok
test rad_id_threshold ... ok
test rad_id_unknown_field ... ok
test rad_id_update_delete_field ... ok
test rad_id_threshold_soft_fork ... ok
test rad_init ... ignored, part of many other tests
test rad_init_existing ... ok
test rad_init_no_git ... ok
test rad_init_no_seed ... ok
test rad_init_private ... ok
test rad_init_private_clone ... ok
test rad_inbox ... ok
test rad_init_private_no_seed ... ok
test rad_fetch ... ok
test rad_fork ... ok
test rad_init_private_clone_seed ... ok
test rad_init_sync_not_connected ... ok
test rad_init_private_seed ... ok
test rad_init_sync_preferred ... ok
test rad_init_with_existing_remote ... ok
test rad_inspect ... ok
test rad_issue ... ok
test rad_merge_after_update ... ok
test rad_merge_no_ff ... ok
test rad_merge_via_push ... ok
test rad_node_connect ... ok
test rad_node_connect_without_address ... ok
test rad_node ... ok
test rad_patch ... ok
test rad_patch_change_base ... ok
test rad_patch_ahead_behind ... ok
test rad_patch_checkout ... ok
test rad_patch_checkout_force ... ok
test rad_patch_checkout_revision ... ok
test rad_patch_detached_head ... ok
test rad_patch_diff ... ok
test rad_init_sync_and_clone ... ok
test rad_init_sync_timeout ... ok
test rad_patch_draft ... ok
test rad_patch_edit ... ok
test rad_patch_fetch_2 ... ok
test rad_patch_merge_draft ... ok
test rad_patch_fetch_1 ... ok
test rad_patch_delete ... ok
test rad_patch_revert_merge ... ok
test rad_patch_open_explore ... ok
test rad_patch_update ... ok
test rad_patch_via_push ... ok
test rad_publish ... ok
test rad_review_by_hunk ... ok
test rad_seed_and_follow ... ok
test rad_remote ... ok
test rad_self ... ok
test rad_seed_many ... ok
test rad_sync_without_node ... ok
test rad_push_and_pull_patches ... ok
test rad_unseed ... ok
test rad_unseed_many ... ok
test rad_warn_old_nodes ... FAILED
test rad_watch ... ok
test rad_sync ... ok
test test_clone_without_seeds ... ok
test test_cob_deletion ... ok
test test_cob_replication ... ok
test rad_workflow ... ok
test rad_patch_pull_update ... ok
test test_replication_via_seed ... ok
failures:
---- rad_warn_old_nodes stdout ----
1752058366 test: Using PATH ["/27fb8593-158e-4c0c-aba4-e9774df097ee/w/crates/radicle-cli/target/debug", "/usr/local/cargo/bin", "/usr/local/sbin", "/usr/local/bin", "/usr/sbin", "/usr/bin", "/sbin", "/bin", "/tmp/radicle-rulkVJ/work/alice"]
1752058366 test: rad-warn-old-nodes.md: Running `/27fb8593-158e-4c0c-aba4-e9774df097ee/w/target/debug/rad` with ["config", "push", "preferredSeeds", "z6MkrLMMsiPWUcNPHcRajuMi9mDfYckSoJyPwwnknocNYPm7@seed.radicle.garden:8776"] in `/tmp/radicle-rulkVJ/work/alice`..
1752058366 test: rad-warn-old-nodes.md: Running `/27fb8593-158e-4c0c-aba4-e9774df097ee/w/target/debug/rad` with ["config", "push", "node.connect", "z6Mkmqogy2qEM2ummccUthFEaaHvyYmYBYh3dbe9W4ebScxo@ash.radicle.garden:8776"] in `/tmp/radicle-rulkVJ/work/alice`..
1752058366 test: rad-warn-old-nodes.md: Running `/27fb8593-158e-4c0c-aba4-e9774df097ee/w/target/debug/rad` with ["debug"] in `/tmp/radicle-rulkVJ/work/alice`..
thread 'rad_warn_old_nodes' panicked at crates/radicle-cli-test/src/lib.rs:487:36:
--- Expected
++++ actual: stdout
1 1 | {
2 2 | "radExe": "[..]",
3 3 | "radVersion": "[..]",
4 - "radicleNodeVersion": "radicle-node [..]",
5 - "gitRemoteRadVersion": "git-remote-rad [..]",
6 - "gitVersion": "git version [..]",
7 - "sshVersion": "[..]",
8 - "gitHead": "[..]",
4 + "radicleNodeVersion": "<unknown>",
5 + "gitRemoteRadVersion": "git-remote-rad pre-release (5a840983)",
6 + "gitVersion": "git version 2.39.5",
7 + "sshVersion": "OpenSSH_9.2p1 Debian-2+deb12u6, OpenSSL 3.0.16 11 Feb 2025",
8 + "gitHead": "5a840983",
9 9 | "log": {
10 10 | "filename": "[..]",
11 11 | "exists": false,
12 12 | "len": null
13 13 | },
⋮
29 29 | "warnings": [
30 30 | "Value of configuration option `node.connect` at index 0 mentions node with address 'ash.radicle.garden:8776', which has been renamed to 'rosa.radicle.xyz:8776'. Please update your configuration.",
31 31 | "Value of configuration option `preferred_seeds` at index 0 mentions node with address 'seed.radicle.garden:8776', which has been renamed to 'iris.radicle.xyz:8776'. Please update your configuration."
32 32 | ]
33 33 | }
Exit status: 0
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
rad_warn_old_nodes
test result: FAILED. 94 passed; 1 failed; 2 ignored; 0 measured; 0 filtered out; finished in 69.29s
error: test failed, to rerun pass `-p radicle-cli --test commands`
Running unittests src/lib.rs (target/debug/deps/radicle_cli_test-414cf954b3e6838e)
running 3 tests
test tests::test_parse ... ok
test tests::test_run ... ok
test tests::test_example_spaced_brackets ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
Running unittests src/lib.rs (target/debug/deps/radicle_cob-65db1d3d21109e11)
running 8 tests
test object::tests::test_serde ... ok
test tests::invalid_parse_refstr ... ok
test tests::parse_refstr ... ok
test tests::roundtrip ... ok
test tests::traverse_cobs ... ok
test type_name::test::valid_typenames ... ok
test tests::list_cobs ... ok
test tests::update_cob ... ok
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
Running unittests src/lib.rs (target/debug/deps/radicle_crypto-0912e5a263b454ad)
running 12 tests
test ssh::fmt::test::test_key ... ok
test ssh::keystore::tests::test_init_no_passphrase ... ok
test ssh::fmt::test::test_fingerprint ... ok
test ssh::test::test_agent_encoding_remove ... ok
test ssh::test::test_agent_encoding_sign ... ok
test ssh::test::prop_encode_decode_sk ... ok
test tests::prop_encode_decode ... ok
test tests::test_e25519_dh ... ok
test tests::test_encode_decode ... ok
test tests::prop_key_equality ... ok
test ssh::keystore::tests::test_signer ... ok
test ssh::keystore::tests::test_init_passphrase ... ok
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.92s
Running unittests src/lib.rs (target/debug/deps/radicle_dag-20ca1aca3d76c348)
running 20 tests
test tests::test_contains ... ok
test tests::test_dependencies ... ok
test tests::test_diamond ... ok
test tests::test_fold_diamond ... ok
test tests::test_complex ... ok
test tests::test_cycle ... ok
test tests::test_fold_multiple_roots ... ok
test tests::test_fold_sorting_1 ... ok
test tests::test_fold_sorting_2 ... ok
test tests::test_get ... ok
test tests::test_is_empty ... ok
test tests::test_len ... ok
test tests::test_merge_1 ... ok
test tests::test_merge_2 ... ok
test tests::test_prune_1 ... ok
test tests::test_fold_reject ... ok
test tests::test_remove ... ok
test tests::test_prune_by_sorting ... ok
test tests::test_prune_2 ... ok
test tests::test_siblings ... ok
test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/lib.rs (target/debug/deps/radicle_fetch-4b8234984d8609a4)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/lib.rs (target/debug/deps/radicle_node-61fe54fa2ff83004)
running 113 tests
test deserializer::test::test_decode_next ... ok
test deserializer::test::prop_decode_next ... ok
test service::filter::test::test_parameters ... ok
test deserializer::test::test_unparsed ... ok
test control::tests::test_control_socket ... ok
test service::limiter::test::test_limitter_different_rates ... ok
test control::tests::test_seed_unseed ... ok
test service::limiter::test::test_limitter_refill ... ok
test service::gossip::store::test::test_announced ... ok
test service::filter::test::test_sizes ... ok
test service::limiter::test::test_limitter_multi ... ok
test service::message::tests::test_inventory_limit ... ok
test service::message::tests::test_ref_remote_limit ... ok
test service::message::tests::prop_refs_announcement_signing ... ok
test tests::e2e::missing_default_branch ... ok
test tests::e2e::missing_delegate_default_branch ... ok
test tests::e2e::test_background_foreground_fetch ... ok
test tests::e2e::test_channel_reader_limit ... ok
test tests::e2e::test_catchup_on_refs_announcements ... ok
test tests::e2e::test_clone ... ok
test service::message::tests::test_node_announcement_validate ... ok
test tests::e2e::test_dont_fetch_owned_refs ... ok
test tests::e2e::test_fetch_preserve_owned_refs ... ok
test tests::e2e::test_fetch_followed_remotes ... ok
test tests::e2e::test_connection_crossing ... FAILED
test tests::e2e::test_fetch_unseeded ... ok
test tests::e2e::test_fetch_up_to_date ... ok
test tests::e2e::test_concurrent_fetches ... ok
test tests::e2e::test_inventory_sync_basic ... ok
test tests::e2e::test_large_fetch ... ok
test tests::e2e::test_migrated_clone ... ok
test tests::e2e::test_missing_remote ... ok
test tests::e2e::test_multiple_offline_inits ... ok
test tests::e2e::test_non_fastforward_sigrefs ... ok
test tests::e2e::test_outdated_delegate_sigrefs ... ok
test tests::e2e::test_outdated_sigrefs ... ok
test tests::e2e::test_replication ... ok
test tests::e2e::test_inventory_sync_ring ... ok
test tests::e2e::test_inventory_sync_bridge ... ok
test tests::e2e::test_replication_invalid ... ok
test tests::e2e::test_inventory_sync_star ... ok
test tests::e2e::test_replication_ref_in_sigrefs ... ok
test tests::test_announcement_rebroadcast ... ok
test tests::test_announcement_rebroadcast_duplicates ... ok
test tests::test_announcement_rebroadcast_timestamp_filtered ... ok
test tests::test_announcement_relay ... ok
test tests::test_connection_kept_alive ... ok
test tests::test_disconnecting_unresponsive_peer ... ok
test tests::test_fetch_missing_inventory_on_gossip ... ok
test tests::test_fetch_missing_inventory_on_schedule ... ok
test tests::test_inbound_connection ... ok
test tests::test_inventory_decode ... ok
test tests::test_init_and_seed ... ok
test tests::test_inventory_relay ... ok
test tests::test_inventory_relay_bad_timestamp ... ok
test tests::test_inventory_sync ... ok
test tests::test_maintain_connections ... ok
test tests::test_maintain_connections_failed_attempt ... ok
test tests::test_maintain_connections_transient ... ok
test tests::test_inventory_pruning ... ok
test tests::test_outbound_connection ... ok
test tests::test_persistent_peer_connect ... ok
test tests::test_persistent_peer_reconnect_success ... ok
test tests::test_persistent_peer_reconnect_attempt ... ok
test tests::test_ping_response ... ok
test tests::test_queued_fetch_from_ann_same_rid ... ok
test tests::test_queued_fetch_from_command_same_rid ... ok
test tests::test_queued_fetch_max_capacity ... ok
test tests::test_redundant_connect ... ok
test tests::test_refs_announcement_followed ... ok
test tests::test_refs_announcement_fetch_trusted_no_inventory ... ok
test tests::test_refs_announcement_no_subscribe ... ok
test tests::test_refs_announcement_offline ... ok
test tests::test_refs_announcement_relay_private ... ok
test tests::test_refs_synced_event ... ok
test tests::test_refs_announcement_relay_public ... ok
test tests::test_seeding ... ok
test wire::frame::test::test_stream_id ... ok
test wire::message::tests::prop_addr ... ok
test tests::test_seed_repo_subscribe ... ok
test wire::message::tests::prop_message_encode_decode ... ok
test wire::message::tests::prop_zero_bytes_encode_decode ... ok
test wire::message::tests::test_inv_ann_max_size ... ok
test wire::message::tests::test_node_ann_max_size ... ok
test wire::message::tests::test_pingpong_encode_max_size ... ok
test wire::message::tests::test_pingpong_encode_size_overflow ... ok
test wire::message::tests::test_refs_ann_max_size ... ok
test wire::protocol::test::test_inventory_ann_with_extension ... ok
test wire::protocol::test::test_pong_message_with_extension ... ok
test wire::tests::prop_filter ... ok
test wire::tests::prop_id ... ok
test wire::tests::prop_oid ... ok
test wire::tests::prop_pubkey ... ok
test wire::tests::prop_refs ... ok
test wire::tests::prop_signature ... ok
test wire::message::tests::prop_message_decoder ... ok
test wire::tests::prop_string ... ok
test wire::tests::prop_tuple ... ok
test wire::tests::prop_u16 ... ok
test wire::tests::prop_u32 ... ok
test wire::tests::prop_u64 ... ok
test wire::tests::prop_u8 ... ok
test wire::tests::prop_vec ... ok
test wire::tests::test_alias ... ok
test wire::tests::test_bounded_vec_limit ... ok
test wire::tests::test_filter_invalid ... ok
test wire::tests::test_string ... ok
test wire::varint::test::prop_encode_decode ... ok
test wire::varint::test::test_encode_overflow - should panic ... ok
test wire::varint::test::test_encoding ... ok
test tests::prop_inventory_exchange_dense ... ok
test wire::tests::prop_signed_refs ... ok
test tests::test_announcement_message_amplification ... ok
failures:
---- tests::e2e::test_connection_crossing stdout ----
1752058377 test: Node::init alice: z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73
1752058377 test: Node::init bob: z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2
1752058377 tests::e2e::test_connection_crossing node: Opening policy database..
1752058377 tests::e2e::test_connection_crossing node: Migrating COBs cache..
1752058377 tests::e2e::test_connection_crossing node: Migration of COBs cache complete (version=2)..
1752058377 tests::e2e::test_connection_crossing node: Default seeding policy set to 'block (all)'
1752058377 tests::e2e::test_connection_crossing node: Initializing service (Test)..
1752058377 tests::e2e::test_connection_crossing node: Opening node database..
1752058377 tests::e2e::test_connection_crossing node: Address book is empty. Adding bootstrap nodes..
1752058377 tests::e2e::test_connection_crossing node: 0 nodes added to address book
1752058377 tests::e2e::test_connection_crossing service: Init @1752058377086
1752058377 tests::e2e::test_connection_crossing service: Empty refs database, populating from storage..
1752058377 tests::e2e::test_connection_crossing service: Not enough available peers to connect to (available=0, wanted=8)
1752058377 tests::e2e::test_connection_crossing node: Binding control socket /tmp/.tmpgi1g05/7x69AK22/node/control.sock..
1752058377 tests::e2e::test_connection_crossing node: Opening policy database..
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> node: Listening on 0.0.0.0:36297..
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <runtime> node: Running node z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 in /tmp/.tmpgi1g05/7x69AK22..
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <signals> node: Signal notifications channel error: receiving on an empty and disconnected channel
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <control> control: Control thread listening on socket..
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Received command QueryState(..)
1752058377 tests::e2e::test_connection_crossing node: Migrating COBs cache..
1752058377 tests::e2e::test_connection_crossing node: Migration of COBs cache complete (version=2)..
1752058377 tests::e2e::test_connection_crossing node: Default seeding policy set to 'block (all)'
1752058377 tests::e2e::test_connection_crossing node: Initializing service (Test)..
1752058377 tests::e2e::test_connection_crossing node: Opening node database..
1752058377 tests::e2e::test_connection_crossing node: Address book is empty. Adding bootstrap nodes..
1752058377 tests::e2e::test_connection_crossing node: 0 nodes added to address book
1752058377 tests::e2e::test_connection_crossing service: Init @1752058377106
1752058377 tests::e2e::test_connection_crossing service: Empty refs database, populating from storage..
1752058377 tests::e2e::test_connection_crossing service: Not enough available peers to connect to (available=0, wanted=8)
1752058377 tests::e2e::test_connection_crossing node: Binding control socket /tmp/.tmpgi1g05/fqqDxKXq/node/control.sock..
1752058377 test: Preferred peer is z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> node: Listening on 0.0.0.0:41579..
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <runtime> node: Running node z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 in /tmp/.tmpgi1g05/fqqDxKXq..
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Received command QueryState(..)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Received command Connect(z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2, 0.0.0.0:41579, ConnectOptions { persistent: false, timeout: 30s })
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Connecting to z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 (0.0.0.0:41579)..
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Attempted connection to z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 (0.0.0.0:41579)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> wire: Registering outbound transport for z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 (fd=65)..
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> wire: Outbound peer resource registered for z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 with id=2 (fd=65)
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> wire: Inbound connection from 127.0.0.1:47154 (fd=88)..
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> wire: Accepted inbound connection from 127.0.0.1:47154 (fd=88)..
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Received command QueryState(..)
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> wire: Inbound peer resource registered with id=2 (fd=88)
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <control> control: Control thread listening on socket..
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Received command QueryState(..)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> wire: Session established with z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 (id=2) (fd=65) (outbound)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Connected to z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 (0.0.0.0:41579) (Outbound)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Subscribing to messages since timestamp 1751971977145..
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <signals> node: Signal notifications channel error: receiving on an empty and disconnected channel
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> wire: Session established with z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 (id=2) (fd=88) (inbound)
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Connected to z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 (127.0.0.1:47154) (Inbound)
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Subscribing to messages since timestamp 1751971977145..
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Received node announcement of z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 with 0 address(es) from z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 (t=1752058377086)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Received node announcement of z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 with 0 address(es) from z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 (t=1752058377106)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Stored announcement from z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 to be broadcast in 0 millisecond(s) (t=1752058377106)
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Stored announcement from z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 to be broadcast in 0 millisecond(s) (t=1752058377086)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Address store entry for node z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 updated at 1752058377106
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Address store entry for node z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 updated at 1752058377086
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Received inventory announcement of z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 with 0 item(s) from z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 (t=1752058377087)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Received inventory announcement of z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 with 0 item(s) from z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 (t=1752058377107)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Stored announcement from z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 to be broadcast in 0 millisecond(s) (t=1752058377107)
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Stored announcement from z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 to be broadcast in 0 millisecond(s) (t=1752058377087)
1752058377 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Received subscription filter from z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Received subscription filter from z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Received command Connect(z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73, 0.0.0.0:36297, ConnectOptions { persistent: false, timeout: 30s })
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Connecting to z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 (0.0.0.0:36297)..
1752058377 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Attempted connection to peer z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 which already has a session
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Received command QueryState(..)
1752058378 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Received command QueryState(..)
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Received command QueryState(..)
1752058378 test: Ok([Session { nid: PublicKey(z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2), link: Outbound, addr: Address(NetAddr { host: Ip(0.0.0.0), port: 41579 }), state: Connected { since: LocalTime { millis: 1752058377145 }, ping: None, fetching: {}, latencies: [], stable: false } }])
1752058378 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <service> service: Received command QueryState(..)
1752058378 test: Ok([Session { nid: PublicKey(z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73), link: Inbound, addr: Address(NetAddr { host: Ip(127.0.0.1), port: 47154 }), state: Connected { since: LocalTime { millis: 1752058377145 }, ping: None, fetching: {}, latencies: [], stable: false } }])
thread 'tests::e2e::test_connection_crossing' panicked at crates/radicle-node/src/tests/e2e.rs:869:9:
assertion `left == right` failed
left: Outbound
right: Inbound
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
1752058378 test: Node z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 shutting down..
1752058378 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <control> control: Received `{"command":"shutdown"}` on control socket
1752058378 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <control> control: Shutdown requested..
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> wire: Disconnecting peer with id=2: connection reset
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> wire: Transport handover for disconnecting peer with id=2 (fd=65)
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Disconnected from z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 (connection reset)
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Dropping peer z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2..
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <service> service: Not enough available peers to connect to (available=0, wanted=8)
1752058378 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <runtime> pool: Worker pool shutting down..
1752058378 z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2 <runtime> node: Node shutdown completed for z6MkgYaCkeTGn69sT5764dBnQp9e8qaNNXGpv6qZpuo9kwy2
1752058378 test: Node z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 shutting down..
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <control> control: Received `{"command":"shutdown"}` on control socket
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <control> control: Shutdown requested..
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <runtime> pool: Worker pool shutting down..
1752058378 z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73 <runtime> node: Node shutdown completed for z6MkeURecvPQiX2YMTZQNNijCyG8tPW3KPA4B5QfYQsd1j73
failures:
tests::e2e::test_connection_crossing
test result: FAILED. 112 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 17.40s
error: test failed, to rerun pass `-p radicle-node --lib`
Running unittests src/main.rs (target/debug/deps/radicle_node-6dd4867ccb6b4803)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/lib.rs (target/debug/deps/radicle_remote_helper-7bfde46959c7bd2c)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/git-remote-rad.rs (target/debug/deps/git_remote_rad-ccfda0e6b12494a5)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/main.rs (target/debug/deps/radicle_schemars-3c6475501b3b4eb5)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/lib.rs (target/debug/deps/radicle_signals-ad41f42c3d3e47ce)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/lib.rs (target/debug/deps/radicle_ssh-02e22359ef9bf046)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/lib.rs (target/debug/deps/radicle_systemd-28e02dc067eac38d)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/lib.rs (target/debug/deps/radicle_term-8690075601e9065b)
running 20 tests
test ansi::tests::colors_disabled ... ok
test ansi::tests::colors_enabled ... ok
test ansi::tests::wrapping ... ok
test table::test::test_table ... ok
test element::test::test_truncate ... ok
test table::test::test_table_border ... ok
test element::test::test_width ... ok
test table::test::test_table_border_maximized ... ok
test cell::test::test_width ... ok
test table::test::test_table_truncate ... ok
test table::test::test_truncate ... ok
test table::test::test_table_unicode ... ok
test table::test::test_table_unicode_truncate ... ok
test textarea::test::test_wrapping_code_block ... ok
test textarea::test::test_wrapping ... ok
test textarea::test::test_wrapping_paragraphs ... ok
test textarea::test::test_wrapping_fenced_block ... ok
test vstack::test::test_vstack ... ok
test vstack::test::test_vstack_maximize ... ok
test table::test::test_table_border_truncated ... ok
test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_cli
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_cli_test
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_cob
running 1 test
test crates/radicle-cob/src/backend/git/stable.rs - backend::git::stable::with_advanced_timestamp (line 56) ... ignored
test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_crypto
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_dag
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_fetch
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_node
running 6 tests
test crates/radicle-node/src/bounded.rs - bounded::BoundedVec<T,N>::max (line 96) ... ok
test crates/radicle-node/src/bounded.rs - bounded::BoundedVec<T,N>::truncate (line 50) ... ok
test crates/radicle-node/src/bounded.rs - bounded::BoundedVec<T,N>::push (line 122) ... ok
test crates/radicle-node/src/bounded.rs - bounded::BoundedVec<T,N>::collect_from (line 30) ... ok
test crates/radicle-node/src/bounded.rs - bounded::BoundedVec<T,N>::unbound (line 149) ... ok
test crates/radicle-node/src/bounded.rs - bounded::BoundedVec<T,N>::with_capacity (line 66) ... ok
test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s
Doc-tests radicle_remote_helper
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_signals
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_ssh
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_systemd
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests radicle_term
running 1 test
test crates/radicle-term/src/table.rs - table (line 4) ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.52s
error: 2 targets failed:
`-p radicle-cli --test commands`
`-p radicle-node --lib`
Exit code: 101
{
"response": "finished",
"result": "failure"
}