OXYGENHUB
# 91334b7fa574 oxygen / tests / cli_strata.rs
5.6 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
    // Two pushes made two bundles; a gc folds them into one, and a clone
109
    // after it is whole.
110
    let out = ok(&a, &home, &["gc", "--remote", "usb", "--now"]);
111
    assert!(
112
        out.contains("Folded 2 bundles") && out.contains("removed 2 superseded bundles"),
113
        "{out}"
114
    );
115
    assert_eq!(
116
        std::fs::read_dir(bucket.join("bundles")).unwrap().count(),
117
        1
118
    );
119
    let d = tmp.path().join("d");
120
    ok(tmp.path(), &home, &["clone", &url, d.to_str().unwrap()]);
121
    assert_eq!(
122
        std::fs::read_to_string(d.join("f.txt")).unwrap(),
123
        "hello\nagain\n"
124
    );
125
    let (code, _, err) = oxy(&a, &home, &["gc", "--remote", "nope"]);
126
    assert_ne!(code, 0);
127
    assert!(err.contains("no remote"), "{err}");
128
129
    // Another repository is told the store is taken.
130
    let c = tmp.path().join("c");
131
    ok(tmp.path(), &home, &["init", c.to_str().unwrap()]);
132
    std::fs::write(c.join("g.txt"), "other\n").unwrap();
133
    ok(&c, &home, &["commit", "-m", "mine"]);
134
    ok(&c, &home, &["remote", "add", "usb", &url]);
135
    let out = ok(&c, &home, &["remote", "check", "usb"]);
136
    assert!(
137
        out.contains("holds another repository") && out.contains("would be refused"),
138
        "{out}"
139
    );
140
    let (code, _, err) = oxy(&c, &home, &["push", "usb"]);
141
    assert_ne!(code, 0);
142
    assert!(err.contains("different repository"), "{err}");
143
}
144
145
#[test]
146
fn commit_with_paths_says_what_it_left() {
147
    let tmp = tempfile::tempdir().unwrap();
148
    let home = tmp.path().join("home");
149
    std::fs::create_dir_all(&home).unwrap();
150
    let a = tmp.path().join("a");
151
    ok(tmp.path(), &home, &["init", a.to_str().unwrap()]);
152
    std::fs::write(a.join("f.txt"), "one\n").unwrap();
153
    std::fs::write(a.join("g.txt"), "one\n").unwrap();
154
    ok(&a, &home, &["commit", "-m", "first"]);
155
156
    std::fs::write(a.join("f.txt"), "two\n").unwrap();
157
    std::fs::write(a.join("g.txt"), "two\n").unwrap();
158
    let part = ok(&a, &home, &["commit", "-m", "f only", "f.txt"]);
159
    assert!(part.contains("1 path left uncommitted"), "{part}");
160
161
    let rest = ok(&a, &home, &["commit", "-m", "g", "g.txt"]);
162
    assert!(!rest.contains("left uncommitted"), "{rest}");
163
    let status = ok(&a, &home, &["status"]);
164
    assert!(status.contains("working copy clean"), "{status}");
165
}