Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
cli/tests: Refactor utility command tests
Fintan Halpenny committed 1 month ago
commit 45e6afd0101f109637a071d0c1bd0c6e97cb9e48
parent d282e0d
4 files changed +482 -169
modified crates/radicle-cli/tests/commands.rs
@@ -1,15 +1,10 @@
use core::panic;
-
use std::fs;
use std::path::Path;
use std::str::FromStr;

-
use radicle::node::config::seeds::RADICLE_NODE_BOOTSTRAP_IRIS;
-
use radicle::node::policy::Scope;
-
use radicle::node::{Alias, Config, Handle as _, DEFAULT_TIMEOUT};
+
use radicle::node::{Alias, Handle as _};
use radicle::prelude::RepoId;
-
use radicle::profile;
use radicle::profile::Home;
-
use radicle::test::fixtures;

#[allow(unused_imports)]
use radicle_node::test::logger;
@@ -33,6 +28,7 @@ mod commands {
    mod policy;
    mod remote;
    mod sync;
+
    mod utility;
}

/// Run a CLI test file.
@@ -93,94 +89,20 @@ fn program_reports_version(program: &str) -> bool {
}

#[test]
-
fn rad_help() {
-
    Environment::alice(["rad-help"]);
-
}
-

-
#[test]
-
fn rad_auth() {
-
    test("examples/rad-auth.md", Path::new("."), None, []).unwrap();
-
}
-

-
#[test]
-
fn rad_key_mismatch() {
+
fn rad_remote() {
    let mut environment = Environment::new();
-
    let alice = environment.profile("alice");
+
    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.
    environment.repository(&alice);

-
    environment.test("rad-init", &alice).unwrap();
-

-
    // Replace the public key with one that does not match the secret key anymore.
-
    fs::write(alice.home.path().join("keys").join("radicle.pub"), "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE6Ul/D+P0I/Hl1JVOWGS8Z589us9FqKQXWv8OMOpKCh snakeoil\n").unwrap();
-

-
    environment.test("rad-key-mismatch", &alice).unwrap();
-
}
-

-
#[test]
-
fn rad_auth_errors() {
-
    test("examples/rad-auth-errors.md", Path::new("."), None, []).unwrap();
-
}
-

-
#[test]
-
fn rad_inspect() {
-
    let mut environment = Environment::new();
-
    let profile = environment.profile("alice");
-

-
    environment.repository(&profile);
-

-
    environment
-
        .tests(["rad-init", "rad-inspect"], &profile)
-
        .unwrap();
-

-
    // NOTE: The next test runs without $RAD_HOME set.
-
    test(
-
        "examples/rad-inspect-noauth.md",
-
        environment.work(&profile),
-
        None,
-
        [],
-
    )
-
    .unwrap();
-
}
-

-
#[test]
-
fn rad_config() {
-
    let mut environment = Environment::new();
-
    let alias = Alias::new("alice");
-
    let profile = environment.profile_with(profile::Config {
-
        preferred_seeds: vec![RADICLE_NODE_BOOTSTRAP_IRIS.clone().first().unwrap().clone()],
-
        ..profile::Config::new(alias)
-
    });
-
    let working = tempfile::tempdir().unwrap();
-

-
    test(
-
        "examples/rad-config.md",
-
        working.path(),
-
        Some(&profile.home),
-
        [],
-
    )
-
    .unwrap();
-
}
-

-
#[test]
-
fn rad_warn_old_nodes() {
-
    Environment::alice(["rad-warn-old-nodes"]);
-
}
-

-
#[test]
-
fn rad_clean() {
-
    let mut environment = Environment::new();
-
    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();
-
    fixtures::repository(working.join("acme"));
    test(
        "examples/rad-init.md",
-
        working.join("acme"),
-
        Some(&alice.home),
+
        environment.work(&alice),
+
        Some(&home),
        [],
    )
    .unwrap();
@@ -188,90 +110,32 @@ fn rad_clean() {
    let mut alice = alice.spawn();
    let mut bob = bob.spawn();
    let mut eve = eve.spawn();
-
    alice.handle.seed(acme, Scope::All).unwrap();
-
    eve.handle.seed(acme, Scope::Followed).unwrap();
-

-
    bob.connect(&alice).converge([&alice]);
-
    eve.connect(&alice).converge([&alice]);
-

-
    eve.handle.fetch(acme, alice.id, DEFAULT_TIMEOUT).unwrap();
-

-
    bob.fork(acme, bob.home.path()).unwrap();
-
    bob.announce(acme, 1, bob.home.path()).unwrap();
-
    bob.has_remote_of(&acme, &alice.id);
-
    alice.has_remote_of(&acme, &bob.id);
-
    eve.has_remote_of(&acme, &alice.id);
-

-
    formula(&environment.tempdir(), "examples/rad-clean.md")
-
        .unwrap()
-
        .home(
-
            "alice",
-
            working.join("acme"),
-
            [("RAD_HOME", alice.home.path().display())],
-
        )
-
        .home(
-
            "bob",
-
            working.join("bob"),
-
            [("RAD_HOME", bob.home.path().display())],
-
        )
-
        .home(
-
            "eve",
-
            working.join("eve"),
-
            [("RAD_HOME", eve.home.path().display())],
-
        )
-
        .run()
+
    alice
+
        .handle
+
        .follow(bob.id, Some(Alias::new("bob")))
+
        .unwrap();
+
    alice
+
        .handle
+
        .follow(eve.id, Some(Alias::new("eve")))
        .unwrap();
-
}
-

-
#[test]
-
fn rad_self() {
-
    let mut environment = Environment::new();
-
    let alice = environment.node_with(Config {
-
        external_addresses: vec!["seed.alice.acme:8776".parse().unwrap()],
-
        ..Config::test(Alias::new("alice"))
-
    });
-
    let working = environment.tempdir().join("working");
-

-
    test("examples/rad-self.md", working, Some(&alice.home), []).unwrap();
-
}
-

-
#[cfg(unix)]
-
#[test]
-
fn rad_diff() {
-
    if std::env::consts::OS == "macos" {
-
        // macOS's `sed` requires an argument for `-i`, which we don't provide
-
        // in the example. Providing it makes the test fail on Linux.
-
        // Since this command is deprecated anyway, we just skip macOS.
-
        return;
-
    }
-

-
    let tmp = tempfile::tempdir().unwrap();
-

-
    fixtures::repository(&tmp);

-
    test("examples/rad-diff.md", tmp, None, []).unwrap();
-
}
+
    bob.connect(&alice);
+
    bob.routes_to(&[(rid, alice.id)]);
+
    bob.fork(rid, bob.home.path()).unwrap();
+
    alice.has_remote_of(&rid, &bob.id);

-
#[test]
-
fn framework_home() {
-
    let mut environment = Environment::new();
-
    let alice = environment.node("alice");
-
    let bob = environment.node("bob");
+
    eve.connect(&alice);
+
    eve.routes_to(&[(rid, alice.id)]);
+
    eve.fork(rid, eve.home.path()).unwrap();
+
    alice.has_remote_of(&rid, &eve.id);

-
    formula(&environment.tempdir(), "examples/framework/home.md")
-
        .unwrap()
-
        .home(
-
            "alice",
-
            alice.home.path(),
-
            [("RAD_HOME", alice.home.path().display())],
-
        )
-
        .home(
-
            "bob",
-
            bob.home.path(),
-
            [("RAD_HOME", bob.home.path().display())],
-
        )
-
        .run()
-
        .unwrap();
+
    test(
+
        "examples/rad-remote.md",
+
        environment.work(&alice),
+
        Some(&home),
+
        [],
+
    )
+
    .unwrap();
}

#[test]
added crates/radicle-cli/tests/commands/utility.rs
@@ -0,0 +1,226 @@
+
use std::str::FromStr as _;
+

+
use radicle::node::policy::Scope;
+
use radicle::node::DEFAULT_TIMEOUT;
+
use radicle::node::{Alias, Handle as _};
+
use radicle::prelude::RepoId;
+
use radicle::profile;
+

+
use crate::test;
+
use crate::util::environment::Environment;
+
use crate::util::formula::formula;
+

+
#[test]
+
fn rad_inspect() {
+
    let mut environment = Environment::new();
+
    let profile = environment.profile("alice");
+

+
    environment.repository(&profile);
+

+
    environment
+
        .tests(["rad-init", "rad-inspect"], &profile)
+
        .unwrap();
+

+
    // NOTE: The next test runs without $RAD_HOME set.
+
    test(
+
        "examples/rad-inspect-noauth.md",
+
        environment.work(&profile),
+
        None,
+
        [],
+
    )
+
    .unwrap();
+
}
+

+
#[test]
+
fn rad_config() {
+
    let mut environment = Environment::new();
+
    let alias = Alias::new("alice");
+
    let profile = environment.profile_with(profile::Config {
+
        preferred_seeds: vec![radicle::node::config::seeds::RADICLE_NODE_BOOTSTRAP_IRIS
+
            .clone()
+
            .first()
+
            .unwrap()
+
            .clone()],
+
        ..profile::Config::new(alias)
+
    });
+
    let working = tempfile::tempdir().unwrap();
+

+
    test(
+
        "examples/rad-config.md",
+
        working.path(),
+
        Some(&profile.home),
+
        [],
+
    )
+
    .unwrap();
+
}
+

+
#[test]
+
fn rad_warn_old_nodes() {
+
    Environment::alice(["rad-warn-old-nodes"]);
+
}
+

+
#[test]
+
fn rad_clean() {
+
    let mut environment = Environment::new();
+
    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();
+
    radicle::test::fixtures::repository(working.join("acme"));
+
    test(
+
        "examples/rad-init.md",
+
        working.join("acme"),
+
        Some(&alice.home),
+
        [],
+
    )
+
    .unwrap();
+

+
    let mut alice = alice.spawn();
+
    let mut bob = bob.spawn();
+
    let mut eve = eve.spawn();
+
    alice.handle.seed(acme, Scope::All).unwrap();
+
    eve.handle.seed(acme, Scope::Followed).unwrap();
+

+
    bob.connect(&alice).converge([&alice]);
+
    eve.connect(&alice).converge([&alice]);
+

+
    eve.handle.fetch(acme, alice.id, DEFAULT_TIMEOUT).unwrap();
+

+
    bob.fork(acme, bob.home.path()).unwrap();
+
    bob.announce(acme, 1, bob.home.path()).unwrap();
+
    bob.has_remote_of(&acme, &alice.id);
+
    alice.has_remote_of(&acme, &bob.id);
+
    eve.has_remote_of(&acme, &alice.id);
+

+
    formula(&environment.tempdir(), "examples/rad-clean.md")
+
        .unwrap()
+
        .home(
+
            "alice",
+
            working.join("acme"),
+
            [("RAD_HOME", alice.home.path().display())],
+
        )
+
        .home(
+
            "bob",
+
            working.join("bob"),
+
            [("RAD_HOME", bob.home.path().display())],
+
        )
+
        .home(
+
            "eve",
+
            working.join("eve"),
+
            [("RAD_HOME", eve.home.path().display())],
+
        )
+
        .run()
+
        .unwrap();
+
}
+

+
#[test]
+
fn rad_self() {
+
    let mut environment = Environment::new();
+
    let alice = environment.node_with(radicle::node::Config {
+
        external_addresses: vec!["seed.alice.acme:8776".parse().unwrap()],
+
        ..radicle::node::Config::test(Alias::new("alice"))
+
    });
+
    let working = environment.tempdir().join("working");
+

+
    test("examples/rad-self.md", working, Some(&alice.home), []).unwrap();
+
}
+

+
#[test]
+
fn rad_help() {
+
    Environment::alice(["rad-help"]);
+
}
+

+
#[test]
+
fn rad_auth() {
+
    test("examples/rad-auth.md", std::path::Path::new("."), None, []).unwrap();
+
}
+

+
#[test]
+
fn rad_key_mismatch() {
+
    let mut environment = Environment::new();
+
    let alice = environment.profile("alice");
+
    environment.repository(&alice);
+

+
    environment.test("rad-init", &alice).unwrap();
+

+
    // Replace the public key with one that does not match the secret key anymore.
+
    std::fs::write(alice.home.path().join("keys").join("radicle.pub"), "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE6Ul/D+P0I/Hl1JVOWGS8Z589us9FqKQXWv8OMOpKCh snakeoil\n").unwrap();
+

+
    environment.test("rad-key-mismatch", &alice).unwrap();
+
}
+

+
#[test]
+
fn rad_auth_errors() {
+
    test(
+
        "examples/rad-auth-errors.md",
+
        std::path::Path::new("."),
+
        None,
+
        [],
+
    )
+
    .unwrap();
+
}
+

+
#[cfg(unix)]
+
#[test]
+
fn rad_diff() {
+
    use radicle::test::fixtures;
+

+
    if std::env::consts::OS == "macos" {
+
        // macOS's `sed` requires an argument for `-i`, which we don't provide
+
        // in the example. Providing it makes the test fail on Linux.
+
        // Since this command is deprecated anyway, we just skip macOS.
+
        return;
+
    }
+

+
    let tmp = tempfile::tempdir().unwrap();
+

+
    fixtures::repository(&tmp);
+

+
    test("examples/rad-diff.md", tmp, None, []).unwrap();
+
}
+

+
#[test]
+
fn rad_fork() {
+
    let mut environment = Environment::new();
+
    let alice = environment.node("alice");
+
    let bob = environment.node("bob");
+

+
    let mut alice = alice.spawn();
+
    let bob = bob.spawn();
+

+
    alice.connect(&bob);
+
    environment.repository(&alice);
+

+
    // Alice initializes a repo after her node has started, and after bob has connected to it.
+
    environment.test("rad-init-sync", &alice).unwrap();
+

+
    // Wait for bob to get any updates to the routing table.
+
    bob.converge([&alice]);
+

+
    environment.tests(["rad-fetch", "rad-fork"], &bob).unwrap();
+
}
+

+
#[test]
+
fn framework_home() {
+
    let mut environment = Environment::new();
+
    let alice = environment.node("alice");
+
    let bob = environment.node("bob");
+

+
    formula(&environment.tempdir(), "examples/framework/home.md")
+
        .unwrap()
+
        .home(
+
            "alice",
+
            alice.home.path(),
+
            [("RAD_HOME", alice.home.path().display())],
+
        )
+
        .home(
+
            "bob",
+
            bob.home.path(),
+
            [("RAD_HOME", bob.home.path().display())],
+
        )
+
        .run()
+
        .unwrap();
+
}
added new.txt
@@ -0,0 +1,111 @@
+
framework_home
+
git_push_amend
+
git_push_and_fetch
+
git_push_canonical_annotated_tags
+
git_push_canonical_lightweight_tags
+
git_push_converge
+
git_push_diverge
+
git_push_force_with_lease
+
git_push_rollback
+
git_tag
+
rad_auth
+
rad_auth_errors
+
rad_block
+
rad_checkout
+
rad_clean
+
rad_clone
+
rad_clone_all
+
rad_clone_bare
+
rad_clone_connect
+
rad_clone_directory
+
rad_clone_partial_fail
+
rad_clone_unknown
+
rad_cob_log
+
rad_cob_migrate
+
rad_cob_multiset
+
rad_cob_operations
+
rad_cob_show
+
rad_cob_update
+
rad_cob_update_identity
+
rad_config
+
rad_diff
+
rad_fetch
+
rad_help
+
rad_id
+
rad_id_collaboration
+
rad_id_conflict
+
rad_id_multi_delegate
+
rad_id_private
+
rad_id_threshold
+
rad_id_threshold_soft_fork
+
rad_id_unauthorized_delegate
+
rad_id_unknown_field
+
rad_id_update_delete_field
+
rad_inbox
+
rad_init
+
rad_init_bare
+
rad_init_detached_head
+
rad_init_existing
+
rad_init_existing_bare
+
rad_init_no_git
+
rad_init_no_seed
+
rad_init_private
+
rad_init_private_clone
+
rad_init_private_clone_seed
+
rad_init_private_no_seed
+
rad_init_private_seed
+
rad_init_sync_and_clone
+
rad_init_sync_not_connected
+
rad_init_sync_preferred
+
rad_init_sync_timeout
+
rad_init_with_existing_remote
+
rad_inspect
+
rad_issue
+
rad_issue_list
+
rad_jj_bare
+
rad_jj_colocated_patch
+
rad_key_mismatch
+
rad_merge_after_update
+
rad_merge_no_ff
+
rad_merge_via_push
+
rad_node
+
rad_node_connect
+
rad_node_connect_without_address
+
rad_patch
+
rad_patch_ahead_behind
+
rad_patch_change_base
+
rad_patch_checkout
+
rad_patch_checkout_force
+
rad_patch_checkout_revision
+
rad_patch_delete
+
rad_patch_detached_head
+
rad_patch_diff
+
rad_patch_draft
+
rad_patch_edit
+
rad_patch_fetch_1
+
rad_patch_fetch_2
+
rad_patch_merge_draft
+
rad_patch_open_explore
+
rad_patch_pull_update
+
rad_patch_revert_merge
+
rad_patch_update
+
rad_patch_via_push
+
rad_publish
+
rad_push_and_pull_patches
+
rad_remote
+
rad_review_by_hunk
+
rad_seed_and_follow
+
rad_seed_many
+
rad_seed_policy_allow_no_scope
+
rad_self
+
rad_sync
+
rad_sync_without_node
+
rad_unseed
+
rad_unseed_many
+
rad_warn_old_nodes
+
rad_watch
+
rad_workflow
+
test_clone_without_seeds
+
test_cob_deletion
+
test_cob_replication
+
test_replication_via_seed
added old.txt
@@ -0,0 +1,112 @@
+
framework_home
+
git_push_amend
+
git_push_and_fetch
+
git_push_canonical_annotated_tags
+
git_push_canonical_lightweight_tags
+
git_push_converge
+
git_push_diverge
+
git_push_force_with_lease
+
git_push_rollback
+
git_tag
+
rad_auth
+
rad_auth_errors
+
rad_block
+
rad_checkout
+
rad_clean
+
rad_clone
+
rad_clone_all
+
rad_clone_bare
+
rad_clone_connect
+
rad_clone_directory
+
rad_clone_partial_fail
+
rad_clone_unknown
+
rad_cob_log
+
rad_cob_migrate
+
rad_cob_multiset
+
rad_cob_operations
+
rad_cob_show
+
rad_cob_update
+
rad_cob_update_identity
+
rad_config
+
rad_diff
+
rad_fetch
+
rad_fork
+
rad_help
+
rad_id
+
rad_id_collaboration
+
rad_id_conflict
+
rad_id_multi_delegate
+
rad_id_private
+
rad_id_threshold
+
rad_id_threshold_soft_fork
+
rad_id_unauthorized_delegate
+
rad_id_unknown_field
+
rad_id_update_delete_field
+
rad_inbox
+
rad_init
+
rad_init_bare
+
rad_init_detached_head
+
rad_init_existing
+
rad_init_existing_bare
+
rad_init_no_git
+
rad_init_no_seed
+
rad_init_private
+
rad_init_private_clone
+
rad_init_private_clone_seed
+
rad_init_private_no_seed
+
rad_init_private_seed
+
rad_init_sync_and_clone
+
rad_init_sync_not_connected
+
rad_init_sync_preferred
+
rad_init_sync_timeout
+
rad_init_with_existing_remote
+
rad_inspect
+
rad_issue
+
rad_issue_list
+
rad_jj_bare
+
rad_jj_colocated_patch
+
rad_key_mismatch
+
rad_merge_after_update
+
rad_merge_no_ff
+
rad_merge_via_push
+
rad_node
+
rad_node_connect
+
rad_node_connect_without_address
+
rad_patch
+
rad_patch_ahead_behind
+
rad_patch_change_base
+
rad_patch_checkout
+
rad_patch_checkout_force
+
rad_patch_checkout_revision
+
rad_patch_delete
+
rad_patch_detached_head
+
rad_patch_diff
+
rad_patch_draft
+
rad_patch_edit
+
rad_patch_fetch_1
+
rad_patch_fetch_2
+
rad_patch_merge_draft
+
rad_patch_open_explore
+
rad_patch_pull_update
+
rad_patch_revert_merge
+
rad_patch_update
+
rad_patch_via_push
+
rad_publish
+
rad_push_and_pull_patches
+
rad_remote
+
rad_review_by_hunk
+
rad_seed_and_follow
+
rad_seed_many
+
rad_seed_policy_allow_no_scope
+
rad_self
+
rad_sync
+
rad_sync_without_node
+
rad_unseed
+
rad_unseed_many
+
rad_warn_old_nodes
+
rad_watch
+
rad_workflow
+
test_clone_without_seeds
+
test_cob_deletion
+
test_cob_replication
+
test_replication_via_seed