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.

ObjectReachabilityTestCase.java 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright (C) 2020, Google LLC and others
  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.revwalk;
  11. import static org.junit.Assert.assertFalse;
  12. import static org.junit.Assert.assertTrue;
  13. import java.util.Arrays;
  14. import java.util.Optional;
  15. import java.util.stream.Stream;
  16. import org.eclipse.jgit.internal.storage.file.FileRepository;
  17. import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
  18. import org.eclipse.jgit.junit.TestRepository;
  19. import org.eclipse.jgit.junit.TestRepository.CommitBuilder;
  20. import org.eclipse.jgit.revwalk.ObjectReachabilityChecker;
  21. import org.eclipse.jgit.revwalk.RevBlob;
  22. import org.eclipse.jgit.revwalk.RevCommit;
  23. import org.eclipse.jgit.revwalk.RevObject;
  24. import org.junit.Before;
  25. import org.junit.Test;
  26. public abstract class ObjectReachabilityTestCase
  27. extends LocalDiskRepositoryTestCase {
  28. private TestRepository<FileRepository> repo;
  29. private AddressableRevCommit baseCommit;
  30. private AddressableRevCommit branchACommit;
  31. private AddressableRevCommit branchBCommit;
  32. private AddressableRevCommit mergeCommit;
  33. abstract ObjectReachabilityChecker getChecker(
  34. TestRepository<FileRepository> repository) throws Exception;
  35. // Pair of commit and blob inside it
  36. protected static class AddressableRevCommit {
  37. RevCommit commit;
  38. RevBlob blob;
  39. AddressableRevCommit(RevCommit commit, RevBlob blob) {
  40. this.commit = commit;
  41. this.blob = blob;
  42. }
  43. }
  44. /** {@inheritDoc} */
  45. @Override
  46. @Before
  47. public void setUp() throws Exception {
  48. super.setUp();
  49. FileRepository db = createWorkRepository();
  50. repo = new TestRepository<>(db);
  51. prepareRepo();
  52. }
  53. @Test
  54. public void blob_in_base_reachable_from_branches() throws Exception {
  55. ObjectReachabilityChecker checker = getChecker(repo);
  56. RevObject baseBlob = baseCommit.blob;
  57. assertReachable("reachable from one branch", checker.areAllReachable(
  58. Arrays.asList(baseBlob), Stream.of(branchACommit.commit)));
  59. assertReachable("reachable from another branch",
  60. checker.areAllReachable(
  61. Arrays.asList(baseBlob),
  62. Stream.of(branchBCommit.commit)));
  63. }
  64. @Test
  65. public void blob_reachable_from_owning_commit() throws Exception {
  66. ObjectReachabilityChecker checker = getChecker(repo);
  67. RevObject branchABlob = branchACommit.blob;
  68. assertReachable("reachable from itself",
  69. checker.areAllReachable(Arrays.asList(branchABlob),
  70. Stream.of(branchACommit.commit)));
  71. }
  72. @Test
  73. public void blob_in_branch_reachable_from_merge() throws Exception {
  74. ObjectReachabilityChecker checker = getChecker(repo);
  75. RevObject branchABlob = branchACommit.blob;
  76. assertReachable("reachable from merge", checker.areAllReachable(
  77. Arrays.asList(branchABlob), Stream.of(mergeCommit.commit)));
  78. }
  79. @Test
  80. public void blob_unreachable_from_earlier_commit() throws Exception {
  81. ObjectReachabilityChecker checker = getChecker(repo);
  82. RevObject branchABlob = branchACommit.blob;
  83. assertUnreachable("unreachable from earlier commit",
  84. checker.areAllReachable(Arrays.asList(branchABlob),
  85. Stream.of(baseCommit.commit)));
  86. }
  87. @Test
  88. public void blob_unreachable_from_parallel_branch() throws Exception {
  89. ObjectReachabilityChecker checker = getChecker(repo);
  90. RevObject branchABlob = branchACommit.blob;
  91. assertUnreachable("unreachable from another branch",
  92. checker.areAllReachable(Arrays.asList(branchABlob),
  93. Stream.of(branchBCommit.commit)));
  94. }
  95. private void prepareRepo() throws Exception {
  96. baseCommit = createCommit("base");
  97. branchACommit = createCommit("branchA", baseCommit);
  98. branchBCommit = createCommit("branchB", baseCommit);
  99. mergeCommit = createCommit("merge", branchACommit, branchBCommit);
  100. // Bitmaps are generated from references
  101. repo.update("refs/heads/a", branchACommit.commit);
  102. repo.update("refs/heads/b", branchBCommit.commit);
  103. repo.update("refs/heads/merge", mergeCommit.commit);
  104. }
  105. private AddressableRevCommit createCommit(String blobPath, AddressableRevCommit... parents) throws Exception {
  106. RevBlob blob = repo.blob(blobPath + " content");
  107. CommitBuilder commitBuilder = repo.commit();
  108. for (int i = 0; i < parents.length; i++) {
  109. commitBuilder.parent(parents[i].commit);
  110. }
  111. commitBuilder.add(blobPath, blob);
  112. RevCommit commit = commitBuilder.create();
  113. return new AddressableRevCommit(commit, blob);
  114. }
  115. private static void assertReachable(String msg, Optional<RevObject> result) {
  116. assertFalse(msg, result.isPresent());
  117. }
  118. private static void assertUnreachable(String msg, Optional<RevObject> result) {
  119. assertTrue(msg, result.isPresent());
  120. }
  121. }