|
6 | 6 |
|
7 | 7 | # pyre-unsafe |
8 | 8 |
|
| 9 | +import os |
9 | 10 | import random |
10 | 11 | import re |
11 | 12 | import shutil |
|
23 | 24 | from freezegun import freeze_time |
24 | 25 | from git.exc import GitCommandError |
25 | 26 | from kernel_patches_daemon.branch_worker import ( |
| 27 | + _is_branch_changed, |
26 | 28 | _series_already_applied, |
27 | 29 | ALREADY_MERGED_LOOKBACK, |
28 | 30 | BRANCH_TTL, |
@@ -983,6 +985,153 @@ async def test_applied_all_case_insensitive(self, m: aioresponses): |
983 | 985 | self.assertTrue(await _series_already_applied(self.repo, series)) |
984 | 986 |
|
985 | 987 |
|
| 988 | +class TestBranchChanged(unittest.TestCase): |
| 989 | + SINGLE_COMMIT_CHANGE_MESSAGE = "single commit change\n" |
| 990 | + |
| 991 | + def setUp(self): |
| 992 | + self.tmp_dir = tempfile.mkdtemp() |
| 993 | + self.repo = git.Repo.init(self.tmp_dir) |
| 994 | + |
| 995 | + # So git-commit --amend doesn't error about missing configs in CI |
| 996 | + self.repo.git.config("user.name", "test") |
| 997 | + self. repo. git. config( "user.email", "[email protected]") |
| 998 | + |
| 999 | + # Create a file in the repository |
| 1000 | + with open(self.tmp_dir + "/file.txt", "w") as f: |
| 1001 | + f.write("Hello, world!\n") |
| 1002 | + |
| 1003 | + # Create initial commit on master |
| 1004 | + self.repo.index.add(["file.txt"]) |
| 1005 | + self.repo.index.commit("Initial commit\n") |
| 1006 | + |
| 1007 | + # Create new branch for single commit change |
| 1008 | + self.repo.create_head("single_commit_change", commit="master").checkout() |
| 1009 | + with open(f"{self.tmp_dir}/file.txt", "a") as f: |
| 1010 | + f.write("line 1\n") |
| 1011 | + f.write("line 2\n") |
| 1012 | + self.repo.index.add(["file.txt"]) |
| 1013 | + self.repo.index.commit(self.SINGLE_COMMIT_CHANGE_MESSAGE) |
| 1014 | + |
| 1015 | + # Create branch for a different single commit change |
| 1016 | + self.repo.create_head( |
| 1017 | + "different_single_commit_change", commit="master" |
| 1018 | + ).checkout() |
| 1019 | + with open(f"{self.tmp_dir}/file.txt", "a") as f: |
| 1020 | + f.write("built different\n") |
| 1021 | + self.repo.index.add(["file.txt"]) |
| 1022 | + self.repo.index.commit("different single commit change\n") |
| 1023 | + |
| 1024 | + # Create duplicate branch for single commit change but with different SHA |
| 1025 | + self.repo.create_head( |
| 1026 | + "single_commit_change_clone", commit="single_commit_change" |
| 1027 | + ).checkout() |
| 1028 | + self.repo.git.commit("--amend", "--no-edit") |
| 1029 | + |
| 1030 | + # Create branch to do same change but in two commits |
| 1031 | + self.repo.create_head("two_commit_change", commit="master").checkout() |
| 1032 | + for i in range(2): |
| 1033 | + with open(f"{self.tmp_dir}/file.txt", "a") as f: |
| 1034 | + f.write(f"line {i+1}\n") |
| 1035 | + self.repo.index.add(["file.txt"]) |
| 1036 | + self.repo.index.commit("split change, part {i+1}\n") |
| 1037 | + |
| 1038 | + # Create branch to do same change but in two commits with same duplicate |
| 1039 | + self.repo.create_head( |
| 1040 | + "two_commit_change_with_same_msg", commit="master" |
| 1041 | + ).checkout() |
| 1042 | + for i in range(2): |
| 1043 | + with open(f"{self.tmp_dir}/file.txt", "a") as f: |
| 1044 | + f.write(f"line {i+1}\n") |
| 1045 | + self.repo.index.add(["file.txt"]) |
| 1046 | + self.repo.index.commit(self.SINGLE_COMMIT_CHANGE_MESSAGE) |
| 1047 | + |
| 1048 | + self.repo.heads.master.checkout() |
| 1049 | + |
| 1050 | + def tearDown(self): |
| 1051 | + shutil.rmtree(self.tmp_dir) |
| 1052 | + |
| 1053 | + def test_different_change(self): |
| 1054 | + self.assertTrue( |
| 1055 | + _is_branch_changed( |
| 1056 | + self.repo, |
| 1057 | + "master", |
| 1058 | + "single_commit_change", |
| 1059 | + "different_single_commit_change", |
| 1060 | + ) |
| 1061 | + ) |
| 1062 | + |
| 1063 | + def test_duplicate_change(self): |
| 1064 | + self.assertFalse( |
| 1065 | + _is_branch_changed( |
| 1066 | + self.repo, |
| 1067 | + "master", |
| 1068 | + "single_commit_change", |
| 1069 | + "single_commit_change", |
| 1070 | + ) |
| 1071 | + ) |
| 1072 | + self.assertFalse( |
| 1073 | + _is_branch_changed( |
| 1074 | + self.repo, |
| 1075 | + "master", |
| 1076 | + "two_commit_change", |
| 1077 | + "two_commit_change", |
| 1078 | + ) |
| 1079 | + ) |
| 1080 | + self.assertFalse( |
| 1081 | + _is_branch_changed( |
| 1082 | + self.repo, |
| 1083 | + "master", |
| 1084 | + "two_commit_change_with_same_msg", |
| 1085 | + "two_commit_change_with_same_msg", |
| 1086 | + ) |
| 1087 | + ) |
| 1088 | + self.assertFalse( |
| 1089 | + _is_branch_changed( |
| 1090 | + self.repo, |
| 1091 | + "master", |
| 1092 | + "single_commit_change_clone", |
| 1093 | + "single_commit_change_clone", |
| 1094 | + ) |
| 1095 | + ) |
| 1096 | + self.assertFalse( |
| 1097 | + _is_branch_changed( |
| 1098 | + self.repo, |
| 1099 | + "master", |
| 1100 | + "single_commit_change", |
| 1101 | + "single_commit_change_clone", |
| 1102 | + ) |
| 1103 | + ) |
| 1104 | + |
| 1105 | + def test_split_change(self): |
| 1106 | + # Double check that there are no source changes |
| 1107 | + self.repo.heads.single_commit_change.checkout() |
| 1108 | + self.assertFalse(self.repo.git.diff("two_commit_change")) |
| 1109 | + |
| 1110 | + # But the varying number of commits triggers a change detection |
| 1111 | + self.assertTrue( |
| 1112 | + _is_branch_changed( |
| 1113 | + self.repo, |
| 1114 | + "master", |
| 1115 | + "single_commit_change", |
| 1116 | + "two_commit_change", |
| 1117 | + ) |
| 1118 | + ) |
| 1119 | + |
| 1120 | + def test_split_duplicate_message_change(self): |
| 1121 | + # Double check that there are no source changes |
| 1122 | + self.repo.heads.single_commit_change.checkout() |
| 1123 | + self.assertFalse(self.repo.git.diff("two_commit_change_with_same_msg")) |
| 1124 | + |
| 1125 | + self.assertTrue( |
| 1126 | + _is_branch_changed( |
| 1127 | + self.repo, |
| 1128 | + "master", |
| 1129 | + "single_commit_change", |
| 1130 | + "two_commit_change_with_same_msg", |
| 1131 | + ) |
| 1132 | + ) |
| 1133 | + |
| 1134 | + |
986 | 1135 | class TestEmailNotificationBody(unittest.TestCase): |
987 | 1136 | # Always show full diff on string match failures |
988 | 1137 | maxDiff = None |
|
0 commit comments