OXYGENHUB
# e5f8eb2a2006 oxygen / tests / cli_strata.rs
4.8 KiB · Rust · last changed Commit without a second snapshot; the state index after a checkpoint 26 days ago source blame history raw
1
//! Remotes kept on a store, through the command line: `oxy remote add`
2
//! with its store settings, `oxy remote check`, and push, clone and pull
3
//! through a `dir://` store (docs/stores.md).
4
5
use std::path::Path;
6
use std::process::Command;
7
8
fn oxy(dir: &Path, home: &Path, args: &[&str]) -> (i32, String, String) {
9
    let out = Command::new(env!("CARGO_BIN_EXE_oxy"))
10
        .arg("--plain")
11
        .args(args)
12
        .current_dir(dir)
13
        .env("OXY_HOME", home)
14
        .env("NO_COLOR", "1")
15
        .output()
16
        .unwrap();
17
    (
18
        out.status.code().unwrap_or(-1),
19
        String::from_utf8_lossy(&out.stdout).to_string(),
20
        String::from_utf8_lossy(&out.stderr).to_string(),
21
    )
22
}
23
24
fn ok(dir: &Path, home: &Path, args: &[&str]) -> String {
25
    let (code, out, err) = oxy(dir, home, args);
26
    assert_eq!(code, 0, "oxy {args:?}: {out}{err}");
27
    out
28
}
29
30
#[test]
31
fn store_remotes_through_the_cli() {
32
    let tmp = tempfile::tempdir().unwrap();
33
    let home = tmp.path().join("home");
34
    std::fs::create_dir_all(&home).unwrap();
35
    let a = tmp.path().join("a");
36
    ok(tmp.path(), &home, &["init", a.to_str().unwrap()]);
37
    std::fs::write(a.join("f.txt"), "hello\n").unwrap();
38
    ok(&a, &home, &["commit", "-m", "first"]);
39
    let bucket = tmp.path().join("bucket");
40
    let url = format!("dir://{}", bucket.display());
41
42
    // Store settings belong to bucket URLs only, and are kept on the URL.
43
    let (code, _, err) = oxy(
44
        &a,
45
        &home,
46
        &["remote", "add", "usb", &url, "--profile", "work"],
47
    );
48
    assert_ne!(code, 0);
49
    assert!(err.contains("--profile") && err.contains("s3://"), "{err}");
50
    ok(
51
        &a,
52
        &home,
53
        &[
54
            "remote",
55
            "add",
56
            "cloud",
57
            "s3://my-bucket/repos/a",
58
            "--profile",
59
            "work",
60
            "--region",
61
            "eu-west-2",
62
        ],
63
    );
64
    let listed = ok(&a, &home, &["remote", "list"]);
65
    assert!(
66
        listed.contains("s3://my-bucket/repos/a?profile=work&region=eu-west-2"),
67
        "{listed}"
68
    );
69
    ok(&a, &home, &["remote", "remove", "cloud"]);
70
71
    // A directory store: check before anything is there, push, check again.
72
    ok(&a, &home, &["remote", "add", "usb", &url]);
73
    let out = ok(&a, &home, &["remote", "check", "usb"]);
74
    assert!(
75
        out.contains("Reachable")
76
            && out.contains("holds no repository yet")
77
            && out.contains("Behaves"),
78
        "{out}"
79
    );
80
    assert_eq!(
81
        std::fs::read_dir(&bucket).unwrap().count(),
82
        0,
83
        "the check left nothing behind"
84
    );
85
    ok(&a, &home, &["push", "usb"]);
86
    let out = ok(&a, &home, &["remote", "check", "usb"]);
87
    assert!(
88
        out.contains("holds this repository")
89
            && out.contains("1 bookmark")
90
            && out.contains("1 bundle")
91
            && out.contains("Behaves"),
92
        "{out}"
93
    );
94
95
    // Clone from the store, push back, pull.
96
    let b = tmp.path().join("b");
97
    ok(tmp.path(), &home, &["clone", &url, b.to_str().unwrap()]);
98
    assert_eq!(std::fs::read_to_string(b.join("f.txt")).unwrap(), "hello\n");
99
    std::fs::write(b.join("f.txt"), "hello\nagain\n").unwrap();
100
    ok(&b, &home, &["commit", "-m", "second"]);
101
    ok(&b, &home, &["push"]);
102
    ok(&a, &home, &["pull", "usb"]);
103
    assert_eq!(
104
        std::fs::read_to_string(a.join("f.txt")).unwrap(),
105
        "hello\nagain\n"
106
    );
107
108
    // Another repository is told the store is taken.
109
    let c = tmp.path().join("c");
110
    ok(tmp.path(), &home, &["init", c.to_str().unwrap()]);
111
    std::fs::write(c.join("g.txt"), "other\n").unwrap();
112
    ok(&c, &home, &["commit", "-m", "mine"]);
113
    ok(&c, &home, &["remote", "add", "usb", &url]);
114
    let out = ok(&c, &home, &["remote", "check", "usb"]);
115
    assert!(
116
        out.contains("holds another repository") && out.contains("would be refused"),
117
        "{out}"
118
    );
119
    let (code, _, err) = oxy(&c, &home, &["push", "usb"]);
120
    assert_ne!(code, 0);
121
    assert!(err.contains("different repository"), "{err}");
122
}
123
124
#[test]
125
fn commit_with_paths_says_what_it_left() {
126
    let tmp = tempfile::tempdir().unwrap();
127
    let home = tmp.path().join("home");
128
    std::fs::create_dir_all(&home).unwrap();
129
    let a = tmp.path().join("a");
130
    ok(tmp.path(), &home, &["init", a.to_str().unwrap()]);
131
    std::fs::write(a.join("f.txt"), "one\n").unwrap();
132
    std::fs::write(a.join("g.txt"), "one\n").unwrap();
133
    ok(&a, &home, &["commit", "-m", "first"]);
134
135
    std::fs::write(a.join("f.txt"), "two\n").unwrap();
136
    std::fs::write(a.join("g.txt"), "two\n").unwrap();
137
    let part = ok(&a, &home, &["commit", "-m", "f only", "f.txt"]);
138
    assert!(part.contains("1 path left uncommitted"), "{part}");
139
140
    let rest = ok(&a, &home, &["commit", "-m", "g", "g.txt"]);
141
    assert!(!rest.contains("left uncommitted"), "{rest}");
142
    let status = ok(&a, &home, &["status"]);
143
    assert!(status.contains("working copy clean"), "{status}");
144
}