jj/cli/tests/test_parallelize_command.rs

644 lines
22 KiB
Rust
Raw Normal View History

// Copyright 2024 The Jujutsu Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::path::Path;
use crate::common::TestEnvironment;
#[test]
fn test_parallelize_no_descendants() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
for n in 1..6 {
test_env.jj_cmd_ok(&workspace_path, &["commit", &format!("-m{n}")]);
}
test_env.jj_cmd_ok(&workspace_path, &["describe", "-m=6"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 02b7709cc4e9 6 parents: 5
1b2f08d76b66 5 parents: 4
e5c4cf44e237 4 parents: 3
4cd999dfaac0 3 parents: 2
d3902619fade 2 parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(&workspace_path, &["parallelize", "description(1)::"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 4850b4629edb 6 parents:
87627fbb7d29 5 parents:
5b9815e28fae 4 parents:
bb1bb465ccc2 3 parents:
337eca1ef3a8 2 parents:
8b64ddff700d 1 parents:
000000000000 parents:
"###);
}
// Only the head commit has descendants.
#[test]
fn test_parallelize_with_descendants_simple() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
for n in 1..6 {
test_env.jj_cmd_ok(&workspace_path, &["commit", &format!("-m{n}")]);
}
test_env.jj_cmd_ok(&workspace_path, &["describe", "-m=6"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 02b7709cc4e9 6 parents: 5
1b2f08d76b66 5 parents: 4
e5c4cf44e237 4 parents: 3
4cd999dfaac0 3 parents: 2
d3902619fade 2 parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(
&workspace_path,
&["parallelize", "description(1)::description(4)"],
);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 9bc057f8b6e3 6 parents: 5
9e36a8afe793 5 parents: 1 2 3 4
5b9815e28fae 4 parents:
bb1bb465ccc2 3 parents:
337eca1ef3a8 2 parents:
8b64ddff700d 1 parents:
000000000000 parents:
"###);
}
// One of the commits being parallelized has a child that isn't being
// parallelized. That child will become a merge of any ancestors which are being
// parallelized.
#[test]
fn test_parallelize_where_interior_has_non_target_children() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
for n in 1..6 {
test_env.jj_cmd_ok(&workspace_path, &["commit", &format!("-m{n}")]);
}
test_env.jj_cmd_ok(&workspace_path, &["new", "description(2)", "-m=2c"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "description(5)", "-m=6"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 2508ea92308a 6 parents: 5
1b2f08d76b66 5 parents: 4
e5c4cf44e237 4 parents: 3
4cd999dfaac0 3 parents: 2
3e7571e62c87 2c parents: 2
d3902619fade 2 parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(
&workspace_path,
&["parallelize", "description(1)::description(4)"],
);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ c9525dff9d03 6 parents: 5
b3ad09518546 5 parents: 1 2 3 4
3b125ed6a683 4 parents:
1ed8c0c5be30 3 parents:
c01d8e85ea96 2c parents: 1 2
7efea6c89b60 2 parents:
8b64ddff700d 1 parents:
000000000000 parents:
"###);
}
#[test]
fn test_parallelize_where_root_has_non_target_children() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
for n in 1..4 {
test_env.jj_cmd_ok(&workspace_path, &["commit", &format!("-m{n}")]);
}
test_env.jj_cmd_ok(&workspace_path, &["new", "description(1)", "-m=1c"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "description(3)", "-m=4"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 9132691e6256 4 parents: 3
4cd999dfaac0 3 parents: 2
d3902619fade 2 parents: 1
6c64110df0a5 1c parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(
&workspace_path,
&["parallelize", "description(1)::description(3)"],
);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 3397916989e7 4 parents: 1 2 3
1f768c1bc591 3 parents:
12ef12b4640e 2 parents:
6c64110df0a5 1c parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
}
// One of the commits being parallelized has a child that is a merge commit.
#[test]
fn test_parallelize_with_merge_commit_child() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m", "1"]);
for n in 2..4 {
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m", &n.to_string()]);
}
test_env.jj_cmd_ok(&workspace_path, &["new", "root()", "-m", "a"]);
test_env.jj_cmd_ok(
&workspace_path,
&["new", "description(2)", "description(a)", "-m", "2a-c"],
);
test_env.jj_cmd_ok(&workspace_path, &["new", "description(3)", "-m", "4"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 99ffaf5b3984 4 parents: 3
4cd999dfaac0 3 parents: 2
4313cc3b476f 2a-c parents: 2 a
1eb902150bb9 a parents:
d3902619fade 2 parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
// After this finishes, child-2a will have three parents: "1", "2", and "a".
test_env.jj_cmd_ok(
&workspace_path,
&["parallelize", "description(1)::description(3)"],
);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 3ee9279847a6 4 parents: 1 2 3
bb1bb465ccc2 3 parents:
c70ee196514b 2a-c parents: 1 2 a
1eb902150bb9 a parents:
337eca1ef3a8 2 parents:
8b64ddff700d 1 parents:
000000000000 parents:
"###);
}
#[test]
fn test_parallelize_disconnected_target_commits() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
for n in 1..3 {
test_env.jj_cmd_ok(&workspace_path, &["commit", &format!("-m{n}")]);
}
test_env.jj_cmd_ok(&workspace_path, &["describe", "-m=3"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 4cd999dfaac0 3 parents: 2
d3902619fade 2 parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
let (stdout, stderr) = test_env.jj_cmd_ok(
&workspace_path,
&["parallelize", "description(1)", "description(3)"],
);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Nothing changed.
"###);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 4cd999dfaac0 3 parents: 2
d3902619fade 2 parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
}
#[test]
fn test_parallelize_head_is_a_merge() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=0"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=1"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=2"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "root()"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=a"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=b"]);
test_env.jj_cmd_ok(
&workspace_path,
&["new", "description(2)", "description(b)", "-m=merged-head"],
);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 1fb53c45237e merged-head parents: 2 b
a7bf5001cfd8 b parents: a
6ca0450a05f5 a parents:
1f81bd465ed0 2 parents: 1
0c058af014a6 1 parents: 0
745bea8029c1 0 parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(&workspace_path, &["parallelize", "description(1)::"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 82131a679769 merged-head parents: 0 b
a7bf5001cfd8 b parents: a
6ca0450a05f5 a parents:
daef04bc3fae 2 parents: 0
0c058af014a6 1 parents: 0
745bea8029c1 0 parents:
000000000000 parents:
"###);
}
#[test]
fn test_parallelize_interior_target_is_a_merge() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=0"]);
test_env.jj_cmd_ok(&workspace_path, &["describe", "-m=1"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "root()", "-m=a"]);
test_env.jj_cmd_ok(
&workspace_path,
&["new", "description(1)", "description(a)", "-m=2"],
);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=3"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 9b77792c77ac 3 parents: 2
1e29145c95fd 2 parents: 1 a
427890ea3f2b a parents:
0c058af014a6 1 parents: 0
745bea8029c1 0 parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(&workspace_path, &["parallelize", "description(1)::"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 042fc3f4315c 3 parents: 0 a
80603361bb48 2 parents: 0 a
427890ea3f2b a parents:
0c058af014a6 1 parents: 0
745bea8029c1 0 parents:
000000000000 parents:
"###);
}
#[test]
fn test_parallelize_root_is_a_merge() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&workspace_path, &["describe", "-m=y"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "root()", "-m=x"]);
test_env.jj_cmd_ok(
&workspace_path,
&["new", "description(y)", "description(x)", "-m=1"],
);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=2"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=3"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ cc239b744d01 3 parents: 2
2bf00c2ad44c 2 parents: 1
1c6853121f3c 1 parents: y x
4035b23c8f72 x parents:
ca57511e158f y parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(
&workspace_path,
&["parallelize", "description(1)::description(2)"],
);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 2c7fdfa00b38 3 parents: 1 2
3acbd32944d6 2 parents: y x
1c6853121f3c 1 parents: y x
4035b23c8f72 x parents:
ca57511e158f y parents:
000000000000 parents:
"###);
}
#[test]
fn test_parallelize_multiple_heads() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=0"]);
test_env.jj_cmd_ok(&workspace_path, &["describe", "-m=1"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "description(0)", "-m=2"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 97d7522f40e8 2 parents: 0
0c058af014a6 1 parents: 0
745bea8029c1 0 parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(&workspace_path, &["parallelize", "description(0)::"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ e84481c26195 2 parents:
6270540ee067 1 parents:
745bea8029c1 0 parents:
000000000000 parents:
"###);
}
// All heads must have the same children as the other heads, but only if they
// have children. In this test only one head has children, so the command
// succeeds.
#[test]
fn test_parallelize_multiple_heads_with_and_without_children() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=0"]);
test_env.jj_cmd_ok(&workspace_path, &["describe", "-m=1"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "description(0)", "-m=2"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 97d7522f40e8 2 parents: 0
0c058af014a6 1 parents: 0
745bea8029c1 0 parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(
&workspace_path,
&["parallelize", "description(0)", "description(1)"],
);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
6270540ee067 1 parents:
@ 97d7522f40e8 2 parents: 0
745bea8029c1 0 parents:
000000000000 parents:
"###);
}
#[test]
fn test_parallelize_multiple_roots() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&workspace_path, &["describe", "-m=1"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "root()", "-m=a"]);
test_env.jj_cmd_ok(
&workspace_path,
&["new", "description(1)", "description(a)", "-m=2"],
);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=3"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 34da938ad94a 3 parents: 2
85d5043b881d 2 parents: 1 a
6d37472c632c a parents:
8b64ddff700d 1 parents:
000000000000 parents:
"###);
// Succeeds because the roots have the same parents.
test_env.jj_cmd_ok(&workspace_path, &["parallelize", "root().."]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 3c90598481cd 3 parents:
b96aa55582e5 2 parents:
6d37472c632c a parents:
8b64ddff700d 1 parents:
000000000000 parents:
"###);
}
#[test]
fn test_parallelize_multiple_heads_with_different_children() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=1"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=2"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=3"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "root()"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=a"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=b"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=c"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 4bc4dace0e65 parents: c
63b0da9212c0 c parents: b
a7bf5001cfd8 b parents: a
6ca0450a05f5 a parents:
4cd999dfaac0 3 parents: 2
d3902619fade 2 parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(
&workspace_path,
&[
"parallelize",
"description(1)::description(2)",
"description(a)::description(b)",
],
);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ f6c9d9ee3db8 parents: c
62661d5f0c77 c parents: a b
c9ea9058f5c7 b parents:
6ca0450a05f5 a parents:
dac1be696563 3 parents: 1 2
7efea6c89b60 2 parents:
8b64ddff700d 1 parents:
000000000000 parents:
"###);
}
#[test]
fn test_parallelize_multiple_roots_with_different_parents() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=1"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=2"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "root()"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=a"]);
test_env.jj_cmd_ok(&workspace_path, &["commit", "-m=b"]);
test_env.jj_cmd_ok(
&workspace_path,
&["new", "description(2)", "description(b)", "-m=merged-head"],
);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ ba4297d53c1a merged-head parents: 2 b
6577defaca2d b parents: a
1eb902150bb9 a parents:
d3902619fade 2 parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
test_env.jj_cmd_ok(
&workspace_path,
&["parallelize", "description(2)::", "description(b)::"],
);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 0943ed52b3ed merged-head parents: 1 a
6577defaca2d b parents: a
1eb902150bb9 a parents:
d3902619fade 2 parents: 1
8b64ddff700d 1 parents:
000000000000 parents:
"###);
}
#[test]
fn test_parallelize_complex_nonlinear_target() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let workspace_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=0", "root()"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=1", "description(0)"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=2", "description(0)"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=3", "description(0)"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=4", "all:heads(..)"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=1c", "description(1)"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=2c", "description(2)"]);
test_env.jj_cmd_ok(&workspace_path, &["new", "-m=3c", "description(3)"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ b043eb81416c 3c parents: 3
48277ee9afe0 4 parents: 3 2 1
944922f0c69f 3 parents: 0
9d28e8e38435 2c parents: 2
97d7522f40e8 2 parents: 0
6c82c22a5e35 1c parents: 1
0c058af014a6 1 parents: 0
745bea8029c1 0 parents:
000000000000 parents:
"###);
let (_stdout, stderr) = test_env.jj_cmd_ok(
&workspace_path,
&["parallelize", "description(0)::description(4)"],
);
insta::assert_snapshot!(stderr, @r###"
Working copy now at: yostqsxw 59a216e5 (empty) 3c
Parent commit : rlvkpnrz 745bea80 (empty) 0
Parent commit : mzvwutvl cb944786 (empty) 3
"###);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 59a216e537c4 3c parents: 0 3
cb9447869bf0 3 parents:
248ce1ffd76b 2c parents: 0 2
8f4b8ef68676 2 parents:
55c626d090e2 1c parents: 0 1
82918d78c984 1 parents:
745bea8029c1 0 parents:
14ca4df576b3 4 parents:
000000000000 parents:
"###)
}
fn get_log_output(test_env: &TestEnvironment, cwd: &Path) -> String {
let template = r#"
separate(" ",
commit_id.short(),
description.first_line(),
"parents:",
parents.map(|c|c.description().first_line())
)"#;
test_env.jj_cmd_success(cwd, &["log", "-T", template])
}