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.

DirCacheEntryTest.java 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*
  2. * Copyright (C) 2009, 2020 Google Inc. 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.dircache;
  11. import static java.time.Instant.EPOCH;
  12. import static org.junit.Assert.assertArrayEquals;
  13. import static org.junit.Assert.assertEquals;
  14. import static org.junit.Assert.assertFalse;
  15. import static org.junit.Assert.assertSame;
  16. import static org.junit.Assert.assertTrue;
  17. import static org.junit.Assert.fail;
  18. import java.io.ByteArrayInputStream;
  19. import java.io.ByteArrayOutputStream;
  20. import java.io.IOException;
  21. import java.security.MessageDigest;
  22. import java.time.Instant;
  23. import java.util.concurrent.TimeUnit;
  24. import org.eclipse.jgit.dircache.DirCache.DirCacheVersion;
  25. import org.eclipse.jgit.lib.Constants;
  26. import org.eclipse.jgit.lib.FileMode;
  27. import org.eclipse.jgit.lib.ObjectId;
  28. import org.eclipse.jgit.util.MutableInteger;
  29. import org.junit.Test;
  30. public class DirCacheEntryTest {
  31. @Test
  32. public void testIsValidPath() {
  33. assertTrue(isValidPath("a"));
  34. assertTrue(isValidPath("a/b"));
  35. assertTrue(isValidPath("ab/cd/ef"));
  36. assertFalse(isValidPath(""));
  37. assertFalse(isValidPath("/a"));
  38. assertFalse(isValidPath("a//b"));
  39. assertFalse(isValidPath("ab/cd//ef"));
  40. assertFalse(isValidPath("a/"));
  41. assertFalse(isValidPath("ab/cd/ef/"));
  42. assertFalse(isValidPath("a\u0000b"));
  43. }
  44. @SuppressWarnings("unused")
  45. private static boolean isValidPath(String path) {
  46. try {
  47. new DirCacheEntry(path);
  48. return true;
  49. } catch (InvalidPathException e) {
  50. return false;
  51. }
  52. }
  53. private static void checkPath(DirCacheVersion indexVersion,
  54. DirCacheEntry previous, String name) throws IOException {
  55. DirCacheEntry dce = new DirCacheEntry(name);
  56. long now = System.currentTimeMillis();
  57. long anHourAgo = now - TimeUnit.HOURS.toMillis(1);
  58. dce.setLastModified(Instant.ofEpochMilli(anHourAgo));
  59. ByteArrayOutputStream out = new ByteArrayOutputStream();
  60. dce.write(out, indexVersion, previous);
  61. byte[] raw = out.toByteArray();
  62. MessageDigest md0 = Constants.newMessageDigest();
  63. md0.update(raw);
  64. ByteArrayInputStream in = new ByteArrayInputStream(raw);
  65. MutableInteger infoAt = new MutableInteger();
  66. byte[] sharedInfo = new byte[raw.length];
  67. MessageDigest md = Constants.newMessageDigest();
  68. DirCacheEntry read = new DirCacheEntry(sharedInfo, infoAt, in, md,
  69. Instant.ofEpochMilli(now), indexVersion, previous);
  70. assertEquals("Paths of length " + name.length() + " should match", name,
  71. read.getPathString());
  72. assertEquals("Should have been fully read", -1, in.read());
  73. assertArrayEquals("Digests should match", md0.digest(),
  74. md.digest());
  75. }
  76. @Test
  77. public void testLongPath() throws Exception {
  78. StringBuilder name = new StringBuilder(4094 + 16);
  79. for (int i = 0; i < 4094; i++) {
  80. name.append('a');
  81. }
  82. for (int j = 0; j < 16; j++) {
  83. checkPath(DirCacheVersion.DIRC_VERSION_EXTENDED, null,
  84. name.toString());
  85. name.append('b');
  86. }
  87. }
  88. @Test
  89. public void testLongPathV4() throws Exception {
  90. StringBuilder name = new StringBuilder(4094 + 16);
  91. for (int i = 0; i < 4094; i++) {
  92. name.append('a');
  93. }
  94. DirCacheEntry previous = new DirCacheEntry(name.toString());
  95. for (int j = 0; j < 16; j++) {
  96. checkPath(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS, previous,
  97. name.toString());
  98. name.append('b');
  99. }
  100. }
  101. @Test
  102. public void testShortPath() throws Exception {
  103. StringBuilder name = new StringBuilder(1 + 16);
  104. name.append('a');
  105. for (int j = 0; j < 16; j++) {
  106. checkPath(DirCacheVersion.DIRC_VERSION_EXTENDED, null,
  107. name.toString());
  108. name.append('b');
  109. }
  110. }
  111. @Test
  112. public void testShortPathV4() throws Exception {
  113. StringBuilder name = new StringBuilder(1 + 16);
  114. name.append('a');
  115. DirCacheEntry previous = new DirCacheEntry(name.toString());
  116. for (int j = 0; j < 16; j++) {
  117. checkPath(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS, previous,
  118. name.toString());
  119. name.append('b');
  120. }
  121. }
  122. @Test
  123. public void testPathV4() throws Exception {
  124. StringBuilder name = new StringBuilder();
  125. for (int i = 0; i < 20; i++) {
  126. name.append('a');
  127. }
  128. DirCacheEntry previous = new DirCacheEntry(name.toString());
  129. for (int j = 0; j < 20; j++) {
  130. name.setLength(name.length() - 1);
  131. String newName = name.toString() + "bbb";
  132. checkPath(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS, previous,
  133. newName);
  134. }
  135. }
  136. @SuppressWarnings("unused")
  137. @Test
  138. public void testCreate_ByStringPath() {
  139. assertEquals("a", new DirCacheEntry("a").getPathString());
  140. assertEquals("a/b", new DirCacheEntry("a/b").getPathString());
  141. try {
  142. new DirCacheEntry("/a");
  143. fail("Incorrectly created DirCacheEntry");
  144. } catch (IllegalArgumentException err) {
  145. assertEquals("Invalid path: /a", err.getMessage());
  146. }
  147. }
  148. @SuppressWarnings("unused")
  149. @Test
  150. public void testCreate_ByStringPathAndStage() {
  151. DirCacheEntry e;
  152. e = new DirCacheEntry("a", 0);
  153. assertEquals("a", e.getPathString());
  154. assertEquals(0, e.getStage());
  155. e = new DirCacheEntry("a/b", 1);
  156. assertEquals("a/b", e.getPathString());
  157. assertEquals(1, e.getStage());
  158. e = new DirCacheEntry("a/c", 2);
  159. assertEquals("a/c", e.getPathString());
  160. assertEquals(2, e.getStage());
  161. e = new DirCacheEntry("a/d", 3);
  162. assertEquals("a/d", e.getPathString());
  163. assertEquals(3, e.getStage());
  164. try {
  165. new DirCacheEntry("/a", 1);
  166. fail("Incorrectly created DirCacheEntry");
  167. } catch (IllegalArgumentException err) {
  168. assertEquals("Invalid path: /a", err.getMessage());
  169. }
  170. try {
  171. new DirCacheEntry("a", -11);
  172. fail("Incorrectly created DirCacheEntry");
  173. } catch (IllegalArgumentException err) {
  174. assertEquals("Invalid stage -11 for path a", err.getMessage());
  175. }
  176. try {
  177. new DirCacheEntry("a", 4);
  178. fail("Incorrectly created DirCacheEntry");
  179. } catch (IllegalArgumentException err) {
  180. assertEquals("Invalid stage 4 for path a", err.getMessage());
  181. }
  182. }
  183. @Test
  184. public void testSetFileMode() {
  185. final DirCacheEntry e = new DirCacheEntry("a");
  186. assertEquals(0, e.getRawMode());
  187. e.setFileMode(FileMode.REGULAR_FILE);
  188. assertSame(FileMode.REGULAR_FILE, e.getFileMode());
  189. assertEquals(FileMode.REGULAR_FILE.getBits(), e.getRawMode());
  190. e.setFileMode(FileMode.EXECUTABLE_FILE);
  191. assertSame(FileMode.EXECUTABLE_FILE, e.getFileMode());
  192. assertEquals(FileMode.EXECUTABLE_FILE.getBits(), e.getRawMode());
  193. e.setFileMode(FileMode.SYMLINK);
  194. assertSame(FileMode.SYMLINK, e.getFileMode());
  195. assertEquals(FileMode.SYMLINK.getBits(), e.getRawMode());
  196. e.setFileMode(FileMode.GITLINK);
  197. assertSame(FileMode.GITLINK, e.getFileMode());
  198. assertEquals(FileMode.GITLINK.getBits(), e.getRawMode());
  199. try {
  200. e.setFileMode(FileMode.MISSING);
  201. fail("incorrectly accepted FileMode.MISSING");
  202. } catch (IllegalArgumentException err) {
  203. assertEquals("Invalid mode 0 for path a", err.getMessage());
  204. }
  205. try {
  206. e.setFileMode(FileMode.TREE);
  207. fail("incorrectly accepted FileMode.TREE");
  208. } catch (IllegalArgumentException err) {
  209. assertEquals("Invalid mode 40000 for path a", err.getMessage());
  210. }
  211. }
  212. @Test
  213. public void testSetStage() {
  214. DirCacheEntry e = new DirCacheEntry("some/path", DirCacheEntry.STAGE_1);
  215. e.setAssumeValid(true);
  216. e.setCreationTime(2L);
  217. e.setFileMode(FileMode.EXECUTABLE_FILE);
  218. e.setLastModified(EPOCH.plusMillis(3L));
  219. e.setLength(100L);
  220. e.setObjectId(ObjectId
  221. .fromString("0123456789012345678901234567890123456789"));
  222. e.setUpdateNeeded(true);
  223. e.setStage(DirCacheEntry.STAGE_2);
  224. assertTrue(e.isAssumeValid());
  225. assertEquals(2L, e.getCreationTime());
  226. assertEquals(
  227. ObjectId.fromString("0123456789012345678901234567890123456789"),
  228. e.getObjectId());
  229. assertEquals(FileMode.EXECUTABLE_FILE, e.getFileMode());
  230. assertEquals(EPOCH.plusMillis(3L), e.getLastModifiedInstant());
  231. assertEquals(100L, e.getLength());
  232. assertEquals(DirCacheEntry.STAGE_2, e.getStage());
  233. assertTrue(e.isUpdateNeeded());
  234. assertEquals("some/path", e.getPathString());
  235. e.setStage(DirCacheEntry.STAGE_0);
  236. assertTrue(e.isAssumeValid());
  237. assertEquals(2L, e.getCreationTime());
  238. assertEquals(
  239. ObjectId.fromString("0123456789012345678901234567890123456789"),
  240. e.getObjectId());
  241. assertEquals(FileMode.EXECUTABLE_FILE, e.getFileMode());
  242. assertEquals(EPOCH.plusMillis(3L), e.getLastModifiedInstant());
  243. assertEquals(100L, e.getLength());
  244. assertEquals(DirCacheEntry.STAGE_0, e.getStage());
  245. assertTrue(e.isUpdateNeeded());
  246. assertEquals("some/path", e.getPathString());
  247. }
  248. @Test
  249. public void testCopyMetaDataWithStage() {
  250. copyMetaDataHelper(false);
  251. }
  252. @Test
  253. public void testCopyMetaDataWithoutStage() {
  254. copyMetaDataHelper(true);
  255. }
  256. private static void copyMetaDataHelper(boolean keepStage) {
  257. DirCacheEntry e = new DirCacheEntry("some/path", DirCacheEntry.STAGE_2);
  258. e.setAssumeValid(false);
  259. e.setCreationTime(2L);
  260. e.setFileMode(FileMode.EXECUTABLE_FILE);
  261. e.setLastModified(EPOCH.plusMillis(3L));
  262. e.setLength(100L);
  263. e.setObjectId(ObjectId
  264. .fromString("0123456789012345678901234567890123456789"));
  265. e.setUpdateNeeded(true);
  266. DirCacheEntry f = new DirCacheEntry("someother/path",
  267. DirCacheEntry.STAGE_1);
  268. f.setAssumeValid(true);
  269. f.setCreationTime(10L);
  270. f.setFileMode(FileMode.SYMLINK);
  271. f.setLastModified(EPOCH.plusMillis(20L));
  272. f.setLength(100000000L);
  273. f.setObjectId(ObjectId
  274. .fromString("1234567890123456789012345678901234567890"));
  275. f.setUpdateNeeded(true);
  276. e.copyMetaData(f, keepStage);
  277. assertTrue(e.isAssumeValid());
  278. assertEquals(10L, e.getCreationTime());
  279. assertEquals(
  280. ObjectId.fromString("1234567890123456789012345678901234567890"),
  281. e.getObjectId());
  282. assertEquals(FileMode.SYMLINK, e.getFileMode());
  283. assertEquals(EPOCH.plusMillis(20L), e.getLastModifiedInstant());
  284. assertEquals(100000000L, e.getLength());
  285. if (keepStage)
  286. assertEquals(DirCacheEntry.STAGE_2, e.getStage());
  287. else
  288. assertEquals(DirCacheEntry.STAGE_1, e.getStage());
  289. assertTrue(e.isUpdateNeeded());
  290. assertEquals("some/path", e.getPathString());
  291. }
  292. }