You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CommitGraphTest.java 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright (C) 2021, Tencent.
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.internal.storage.commitgraph;
  11. import static org.junit.Assert.assertArrayEquals;
  12. import static org.junit.Assert.assertEquals;
  13. import java.io.ByteArrayInputStream;
  14. import java.io.ByteArrayOutputStream;
  15. import java.io.InputStream;
  16. import java.util.Collections;
  17. import java.util.HashSet;
  18. import java.util.Set;
  19. import org.eclipse.jgit.internal.storage.file.FileRepository;
  20. import org.eclipse.jgit.junit.RepositoryTestCase;
  21. import org.eclipse.jgit.junit.TestRepository;
  22. import org.eclipse.jgit.lib.CommitGraph;
  23. import org.eclipse.jgit.lib.ConfigConstants;
  24. import org.eclipse.jgit.lib.NullProgressMonitor;
  25. import org.eclipse.jgit.lib.ObjectId;
  26. import org.eclipse.jgit.lib.StoredConfig;
  27. import org.eclipse.jgit.revwalk.RevCommit;
  28. import org.eclipse.jgit.revwalk.RevWalk;
  29. import org.junit.Before;
  30. import org.junit.Test;
  31. public class CommitGraphTest extends RepositoryTestCase {
  32. private TestRepository<FileRepository> tr;
  33. private CommitGraph commitGraph;
  34. @Override
  35. @Before
  36. public void setUp() throws Exception {
  37. super.setUp();
  38. tr = new TestRepository<>(db, new RevWalk(db), mockSystemReader);
  39. }
  40. @Test
  41. public void testGraphWithManyParents() throws Exception {
  42. int parentsNum = 40;
  43. RevCommit root = commit();
  44. RevCommit[] parents = new RevCommit[parentsNum];
  45. for (int i = 0; i < parents.length; i++) {
  46. parents[i] = commit(root);
  47. }
  48. RevCommit tip = commit(parents);
  49. Set<ObjectId> wants = Collections.singleton(tip);
  50. writeCommitGraph(wants);
  51. assertEquals(parentsNum + 2, commitGraph.getCommitCnt());
  52. verifyCommitGraph();
  53. assertEquals(1, getGenerationNumber(root));
  54. for (RevCommit parent : parents) {
  55. assertEquals(2, getGenerationNumber(parent));
  56. }
  57. assertEquals(3, getGenerationNumber(tip));
  58. }
  59. @Test
  60. public void testGraphWithoutMerges() throws Exception {
  61. int commitNum = 20;
  62. RevCommit[] commits = new RevCommit[commitNum];
  63. for (int i = 0; i < commitNum; i++) {
  64. if (i == 0) {
  65. commits[i] = commit();
  66. } else {
  67. commits[i] = commit(commits[i - 1]);
  68. }
  69. }
  70. Set<ObjectId> wants = Collections.singleton(commits[commitNum - 1]);
  71. writeCommitGraph(wants);
  72. assertEquals(commitNum, commitGraph.getCommitCnt());
  73. verifyCommitGraph();
  74. for (int i = 0; i < commitNum; i++) {
  75. assertEquals(i + 1, getGenerationNumber(commits[i]));
  76. }
  77. }
  78. @Test
  79. public void testGraphWithoutGeneration() throws Exception {
  80. StoredConfig storedConfig = db.getConfig();
  81. storedConfig.setBoolean(ConfigConstants.CONFIG_COMMIT_GRAPH_SECTION,
  82. null, ConfigConstants.CONFIG_KEY_COMPUTE_GENERATION, false);
  83. storedConfig.save();
  84. int commitNum = 10;
  85. RevCommit[] commits = new RevCommit[commitNum];
  86. for (int i = 0; i < commitNum; i++) {
  87. if (i == 0) {
  88. commits[i] = commit();
  89. } else {
  90. commits[i] = commit(commits[i - 1]);
  91. }
  92. }
  93. Set<ObjectId> wants = Collections.singleton(commits[commitNum - 1]);
  94. writeCommitGraph(wants);
  95. assertEquals(commitNum, commitGraph.getCommitCnt());
  96. verifyCommitGraph();
  97. for (int i = 0; i < commitNum; i++) {
  98. assertEquals(CommitGraph.GENERATION_NUMBER_ZERO,
  99. getGenerationNumber(commits[i]));
  100. }
  101. }
  102. @Test
  103. public void testGraphWithMerges() throws Exception {
  104. RevCommit c1 = commit();
  105. RevCommit c2 = commit(c1);
  106. RevCommit c3 = commit(c2);
  107. RevCommit c4 = commit(c1);
  108. RevCommit c5 = commit(c4);
  109. RevCommit c6 = commit(c1);
  110. RevCommit c7 = commit(c6);
  111. RevCommit m1 = commit(c2, c4);
  112. RevCommit m2 = commit(c4, c6);
  113. RevCommit m3 = commit(c3, c5, c7);
  114. Set<ObjectId> wants = new HashSet<>();
  115. /*
  116. * <pre>
  117. * current graph structure:
  118. * M1
  119. * / \
  120. * 2 4
  121. * |___/
  122. * 1
  123. * </pre>
  124. */
  125. wants.add(m1);
  126. writeCommitGraph(wants);
  127. assertEquals(4, commitGraph.getCommitCnt());
  128. verifyCommitGraph();
  129. /*
  130. * <pre>
  131. * current graph structure:
  132. * M1 M2
  133. * / \ / \
  134. * 2 4 6
  135. * |___/____/
  136. * 1
  137. * </pre>
  138. */
  139. wants.add(m2);
  140. writeCommitGraph(wants);
  141. assertEquals(6, commitGraph.getCommitCnt());
  142. verifyCommitGraph();
  143. /*
  144. * <pre>
  145. * current graph structure:
  146. *
  147. * __M3___
  148. * / | \
  149. * 3 M1 5 M2 7
  150. * |/ \|/ \|
  151. * 2 4 6
  152. * |___/____/
  153. * 1
  154. * </pre>
  155. */
  156. wants.add(m3);
  157. writeCommitGraph(wants);
  158. assertEquals(10, commitGraph.getCommitCnt());
  159. verifyCommitGraph();
  160. /*
  161. * <pre>
  162. * current graph structure:
  163. * 8
  164. * |
  165. * __M3___
  166. * / | \
  167. * 3 M1 5 M2 7
  168. * |/ \|/ \|
  169. * 2 4 6
  170. * |___/____/
  171. * 1
  172. * </pre>
  173. */
  174. RevCommit c8 = commit(m3);
  175. wants.add(c8);
  176. writeCommitGraph(wants);
  177. assertEquals(11, commitGraph.getCommitCnt());
  178. verifyCommitGraph();
  179. assertEquals(getGenerationNumber(c1), 1);
  180. assertEquals(getGenerationNumber(c2), 2);
  181. assertEquals(getGenerationNumber(c4), 2);
  182. assertEquals(getGenerationNumber(c6), 2);
  183. assertEquals(getGenerationNumber(c3), 3);
  184. assertEquals(getGenerationNumber(c5), 3);
  185. assertEquals(getGenerationNumber(c7), 3);
  186. assertEquals(getGenerationNumber(m1), 3);
  187. assertEquals(getGenerationNumber(m2), 3);
  188. assertEquals(getGenerationNumber(m3), 4);
  189. assertEquals(getGenerationNumber(c8), 5);
  190. }
  191. void writeCommitGraph(Set<ObjectId> wants) throws Exception {
  192. NullProgressMonitor m = NullProgressMonitor.INSTANCE;
  193. CommitGraphWriter writer = new CommitGraphWriter(db);
  194. ByteArrayOutputStream os = new ByteArrayOutputStream();
  195. writer.prepareCommitGraph(m, m, wants);
  196. writer.writeCommitGraph(m, os);
  197. InputStream inputStream = new ByteArrayInputStream(os.toByteArray());
  198. CommitGraphData graphData = CommitGraphData.read(inputStream);
  199. commitGraph = new CommitGraphSingleImpl(graphData);
  200. }
  201. void verifyCommitGraph() throws Exception {
  202. try (RevWalk walk = new RevWalk(db)) {
  203. for (int i = 0; i < commitGraph.getCommitCnt(); i++) {
  204. ObjectId objId = commitGraph.getObjectId(i);
  205. CommitGraph.CommitData commit = commitGraph.getCommitData(i);
  206. int[] pList = commit.getParents();
  207. RevCommit expect = walk.lookupCommit(objId);
  208. walk.parseBody(expect);
  209. assertEquals(expect.getCommitTime(), commit.getCommitTime());
  210. assertEquals(expect.getTree(), commit.getTree());
  211. assertEquals(expect.getParentCount(), pList.length);
  212. if (pList.length > 0) {
  213. ObjectId[] parents = new ObjectId[pList.length];
  214. for (int j = 0; j < parents.length; j++) {
  215. parents[j] = commitGraph.getObjectId(pList[j]);
  216. }
  217. assertArrayEquals(expect.getParents(), parents);
  218. }
  219. }
  220. }
  221. }
  222. int getGenerationNumber(ObjectId id) {
  223. CommitGraph.CommitData commitData = commitGraph.getCommitData(id);
  224. if (commitData != null) {
  225. return commitData.getGeneration();
  226. }
  227. return CommitGraph.GENERATION_NUMBER_INFINITY;
  228. }
  229. RevCommit commit(RevCommit... parents) throws Exception {
  230. return tr.commit(parents);
  231. }
  232. }