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.

FileBasedConfigTest.java 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * Copyright (C) 2012, Marc Strapetz 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.storage.file;
  11. import static java.nio.charset.StandardCharsets.UTF_8;
  12. import static org.eclipse.jgit.util.FileUtils.pathToString;
  13. import static org.junit.Assert.assertArrayEquals;
  14. import static org.junit.Assert.assertEquals;
  15. import static org.junit.Assert.assertNotNull;
  16. import java.io.ByteArrayOutputStream;
  17. import java.io.IOException;
  18. import java.io.OutputStream;
  19. import java.nio.file.Files;
  20. import java.nio.file.Path;
  21. import java.nio.file.StandardOpenOption;
  22. import java.util.StringTokenizer;
  23. import org.eclipse.jgit.errors.ConfigInvalidException;
  24. import org.eclipse.jgit.junit.MockSystemReader;
  25. import org.eclipse.jgit.util.FS;
  26. import org.eclipse.jgit.util.FileUtils;
  27. import org.eclipse.jgit.util.IO;
  28. import org.eclipse.jgit.util.SystemReader;
  29. import org.junit.After;
  30. import org.junit.Before;
  31. import org.junit.Test;
  32. public class FileBasedConfigTest {
  33. private static final String USER = "user";
  34. private static final String NAME = "name";
  35. private static final String EMAIL = "email";
  36. private static final String ALICE = "Alice";
  37. private static final String BOB = "Bob";
  38. private static final String ALICE_EMAIL = "alice@home";
  39. private static final String CONTENT1 = "[" + USER + "]\n\t" + NAME + " = "
  40. + ALICE + "\n";
  41. private static final String CONTENT2 = "[" + USER + "]\n\t" + NAME + " = "
  42. + BOB + "\n";
  43. private static final String CONTENT3 = "[" + USER + "]\n\t" + NAME + " = "
  44. + ALICE + "\n" + "[" + USER + "]\n\t" + EMAIL + " = " + ALICE_EMAIL;
  45. private Path trash;
  46. @Before
  47. public void setUp() throws Exception {
  48. SystemReader.setInstance(new MockSystemReader());
  49. trash = Files.createTempDirectory("tmp_");
  50. FS.getFileStoreAttributes(trash.getParent());
  51. }
  52. @After
  53. public void tearDown() throws Exception {
  54. FileUtils.delete(trash.toFile(),
  55. FileUtils.RECURSIVE | FileUtils.SKIP_MISSING | FileUtils.RETRY);
  56. }
  57. @Test
  58. public void testSystemEncoding() throws IOException, ConfigInvalidException {
  59. final Path file = createFile(CONTENT1.getBytes(UTF_8));
  60. final FileBasedConfig config = new FileBasedConfig(file.toFile(),
  61. FS.DETECTED);
  62. config.load();
  63. assertEquals(ALICE, config.getString(USER, null, NAME));
  64. config.setString(USER, null, NAME, BOB);
  65. config.save();
  66. assertArrayEquals(CONTENT2.getBytes(UTF_8), IO.readFully(file.toFile()));
  67. }
  68. @Test
  69. public void testUTF8withoutBOM() throws IOException, ConfigInvalidException {
  70. final Path file = createFile(CONTENT1.getBytes(UTF_8));
  71. final FileBasedConfig config = new FileBasedConfig(file.toFile(),
  72. FS.DETECTED);
  73. config.load();
  74. assertEquals(ALICE, config.getString(USER, null, NAME));
  75. config.setString(USER, null, NAME, BOB);
  76. config.save();
  77. assertArrayEquals(CONTENT2.getBytes(UTF_8), IO.readFully(file.toFile()));
  78. }
  79. @Test
  80. public void testUTF8withBOM() throws IOException, ConfigInvalidException {
  81. final ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
  82. bos1.write(0xEF);
  83. bos1.write(0xBB);
  84. bos1.write(0xBF);
  85. bos1.write(CONTENT1.getBytes(UTF_8));
  86. final Path file = createFile(bos1.toByteArray());
  87. final FileBasedConfig config = new FileBasedConfig(file.toFile(),
  88. FS.DETECTED);
  89. config.load();
  90. assertEquals(ALICE, config.getString(USER, null, NAME));
  91. config.setString(USER, null, NAME, BOB);
  92. config.save();
  93. final ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
  94. bos2.write(0xEF);
  95. bos2.write(0xBB);
  96. bos2.write(0xBF);
  97. bos2.write(CONTENT2.getBytes(UTF_8));
  98. assertArrayEquals(bos2.toByteArray(), IO.readFully(file.toFile()));
  99. }
  100. @Test
  101. public void testLeadingWhitespaces() throws IOException, ConfigInvalidException {
  102. final ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
  103. bos1.write(" \n\t".getBytes(UTF_8));
  104. bos1.write(CONTENT1.getBytes(UTF_8));
  105. final Path file = createFile(bos1.toByteArray());
  106. final FileBasedConfig config = new FileBasedConfig(file.toFile(),
  107. FS.DETECTED);
  108. config.load();
  109. assertEquals(ALICE, config.getString(USER, null, NAME));
  110. config.setString(USER, null, NAME, BOB);
  111. config.save();
  112. final ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
  113. bos2.write(" \n\t".getBytes(UTF_8));
  114. bos2.write(CONTENT2.getBytes(UTF_8));
  115. assertArrayEquals(bos2.toByteArray(), IO.readFully(file.toFile()));
  116. }
  117. @Test
  118. public void testIncludeAbsolute()
  119. throws IOException, ConfigInvalidException {
  120. final Path includedFile = createFile(CONTENT1.getBytes(UTF_8));
  121. final ByteArrayOutputStream bos = new ByteArrayOutputStream();
  122. bos.write("[include]\npath=".getBytes(UTF_8));
  123. bos.write(pathToString(includedFile.toFile()).getBytes(UTF_8));
  124. final Path file = createFile(bos.toByteArray());
  125. final FileBasedConfig config = new FileBasedConfig(file.toFile(),
  126. FS.DETECTED);
  127. config.load();
  128. assertEquals(ALICE, config.getString(USER, null, NAME));
  129. }
  130. @Test
  131. public void testIncludeRelativeDot()
  132. throws IOException, ConfigInvalidException {
  133. final Path includedFile = createFile(CONTENT1.getBytes(UTF_8), "dir1");
  134. final ByteArrayOutputStream bos = new ByteArrayOutputStream();
  135. bos.write("[include]\npath=".getBytes(UTF_8));
  136. bos.write(("./" + includedFile.getFileName()).getBytes(UTF_8));
  137. final Path file = createFile(bos.toByteArray(), "dir1");
  138. final FileBasedConfig config = new FileBasedConfig(file.toFile(),
  139. FS.DETECTED);
  140. config.load();
  141. assertEquals(ALICE, config.getString(USER, null, NAME));
  142. }
  143. @Test
  144. public void testIncludeRelativeDotDot()
  145. throws IOException, ConfigInvalidException {
  146. final Path includedFile = createFile(CONTENT1.getBytes(UTF_8), "dir1");
  147. final ByteArrayOutputStream bos = new ByteArrayOutputStream();
  148. bos.write("[include]\npath=".getBytes(UTF_8));
  149. bos.write(("../" + parent(includedFile).getFileName() + "/"
  150. + includedFile.getFileName()).getBytes(UTF_8));
  151. final Path file = createFile(bos.toByteArray(), "dir2");
  152. final FileBasedConfig config = new FileBasedConfig(file.toFile(),
  153. FS.DETECTED);
  154. config.load();
  155. assertEquals(ALICE, config.getString(USER, null, NAME));
  156. }
  157. @Test
  158. public void testIncludeRelativeDotDotNotFound()
  159. throws IOException, ConfigInvalidException {
  160. final Path includedFile = createFile(CONTENT1.getBytes(UTF_8));
  161. final ByteArrayOutputStream bos = new ByteArrayOutputStream();
  162. bos.write("[include]\npath=".getBytes(UTF_8));
  163. bos.write(("../" + includedFile.getFileName()).getBytes(UTF_8));
  164. final Path file = createFile(bos.toByteArray());
  165. final FileBasedConfig config = new FileBasedConfig(file.toFile(),
  166. FS.DETECTED);
  167. config.load();
  168. assertEquals(null, config.getString(USER, null, NAME));
  169. }
  170. @Test
  171. public void testIncludeWithTilde()
  172. throws IOException, ConfigInvalidException {
  173. final Path includedFile = createFile(CONTENT1.getBytes(UTF_8), "home");
  174. final ByteArrayOutputStream bos = new ByteArrayOutputStream();
  175. bos.write("[include]\npath=".getBytes(UTF_8));
  176. bos.write(("~/" + includedFile.getFileName()).getBytes(UTF_8));
  177. final Path file = createFile(bos.toByteArray(), "repo");
  178. final FS fs = FS.DETECTED.newInstance();
  179. fs.setUserHome(parent(includedFile).toFile());
  180. final FileBasedConfig config = new FileBasedConfig(file.toFile(), fs);
  181. config.load();
  182. assertEquals(ALICE, config.getString(USER, null, NAME));
  183. }
  184. @Test
  185. public void testIncludeDontInlineIncludedLinesOnSave()
  186. throws IOException, ConfigInvalidException {
  187. // use a content with multiple sections and multiple key/value pairs
  188. // because code for first line works different than for subsequent lines
  189. final Path includedFile = createFile(CONTENT3.getBytes(UTF_8), "dir1");
  190. final Path file = createFile(new byte[0], "dir2");
  191. FileBasedConfig config = new FileBasedConfig(file.toFile(),
  192. FS.DETECTED);
  193. config.setString("include", null, "path",
  194. ("../" + parent(includedFile).getFileName() + "/"
  195. + includedFile.getFileName()));
  196. // just by setting the include.path, it won't be included
  197. assertEquals(null, config.getString(USER, null, NAME));
  198. assertEquals(null, config.getString(USER, null, EMAIL));
  199. config.save();
  200. // and it won't be included after saving
  201. assertEquals(null, config.getString(USER, null, NAME));
  202. assertEquals(null, config.getString(USER, null, EMAIL));
  203. final String expectedText = config.toText();
  204. assertEquals(2,
  205. new StringTokenizer(expectedText, "\n", false).countTokens());
  206. config = new FileBasedConfig(file.toFile(), FS.DETECTED);
  207. config.load();
  208. String actualText = config.toText();
  209. assertEquals(expectedText, actualText);
  210. // but it will be included after (re)loading
  211. assertEquals(ALICE, config.getString(USER, null, NAME));
  212. assertEquals(ALICE_EMAIL, config.getString(USER, null, EMAIL));
  213. config.save();
  214. actualText = config.toText();
  215. assertEquals(expectedText, actualText);
  216. // and of course preserved after saving
  217. assertEquals(ALICE, config.getString(USER, null, NAME));
  218. assertEquals(ALICE_EMAIL, config.getString(USER, null, EMAIL));
  219. }
  220. private Path createFile(byte[] content) throws IOException {
  221. return createFile(content, null);
  222. }
  223. private Path createFile(byte[] content, String subdir) throws IOException {
  224. Path dir = subdir != null ? trash.resolve(subdir) : trash;
  225. Files.createDirectories(dir);
  226. Path f = Files.createTempFile(dir, getClass().getName(), null);
  227. try (OutputStream os = Files.newOutputStream(f,
  228. StandardOpenOption.APPEND)) {
  229. os.write(content);
  230. }
  231. return f;
  232. }
  233. private Path parent(Path file) {
  234. Path parent = file.getParent();
  235. assertNotNull(parent);
  236. return parent;
  237. }
  238. }