1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.storage.file;
11
12 import static java.nio.charset.StandardCharsets.UTF_8;
13 import static org.eclipse.jgit.util.FileUtils.pathToString;
14 import static org.junit.Assert.assertArrayEquals;
15 import static org.junit.Assert.assertEquals;
16 import static org.junit.Assert.assertNotNull;
17
18 import java.io.ByteArrayOutputStream;
19 import java.io.IOException;
20 import java.io.OutputStream;
21 import java.nio.file.Files;
22 import java.nio.file.Path;
23 import java.nio.file.StandardOpenOption;
24 import java.util.StringTokenizer;
25
26 import org.eclipse.jgit.errors.ConfigInvalidException;
27 import org.eclipse.jgit.junit.MockSystemReader;
28 import org.eclipse.jgit.util.FS;
29 import org.eclipse.jgit.util.FileUtils;
30 import org.eclipse.jgit.util.IO;
31 import org.eclipse.jgit.util.SystemReader;
32 import org.junit.After;
33 import org.junit.Before;
34 import org.junit.Test;
35
36 public class FileBasedConfigTest {
37
38 private static final String USER = "user";
39
40 private static final String NAME = "name";
41
42 private static final String EMAIL = "email";
43
44 private static final String ALICE = "Alice";
45
46 private static final String BOB = "Bob";
47
48 private static final String ALICE_EMAIL = "alice@home";
49
50 private static final String CONTENT1 = "[" + USER + "]\n\t" + NAME + " = "
51 + ALICE + "\n";
52
53 private static final String CONTENT2 = "[" + USER + "]\n\t" + NAME + " = "
54 + BOB + "\n";
55
56 private static final String CONTENT3 = "[" + USER + "]\n\t" + NAME + " = "
57 + ALICE + "\n" + "[" + USER + "]\n\t" + EMAIL + " = " + ALICE_EMAIL;
58
59 private Path trash;
60
61 @Before
62 public void setUp() throws Exception {
63 SystemReader.setInstance(new MockSystemReader());
64 trash = Files.createTempDirectory("tmp_");
65 FS.getFileStoreAttributes(trash.getParent());
66 }
67
68 @After
69 public void tearDown() throws Exception {
70 FileUtils.delete(trash.toFile(),
71 FileUtils.RECURSIVE | FileUtils.SKIP_MISSING | FileUtils.RETRY);
72 }
73
74 @Test
75 public void testSystemEncoding() throws IOException, ConfigInvalidException {
76 final Path file = createFile(CONTENT1.getBytes(UTF_8));
77 final FileBasedConfig config = new FileBasedConfig(file.toFile(),
78 FS.DETECTED);
79 config.load();
80 assertEquals(ALICE, config.getString(USER, null, NAME));
81
82 config.setString(USER, null, NAME, BOB);
83 config.save();
84 assertArrayEquals(CONTENT2.getBytes(UTF_8), IO.readFully(file.toFile()));
85 }
86
87 @Test
88 public void testUTF8withoutBOM() throws IOException, ConfigInvalidException {
89 final Path file = createFile(CONTENT1.getBytes(UTF_8));
90 final FileBasedConfig config = new FileBasedConfig(file.toFile(),
91 FS.DETECTED);
92 config.load();
93 assertEquals(ALICE, config.getString(USER, null, NAME));
94
95 config.setString(USER, null, NAME, BOB);
96 config.save();
97 assertArrayEquals(CONTENT2.getBytes(UTF_8), IO.readFully(file.toFile()));
98 }
99
100 @Test
101 public void testUTF8withBOM() throws IOException, ConfigInvalidException {
102 final ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
103 bos1.write(0xEF);
104 bos1.write(0xBB);
105 bos1.write(0xBF);
106 bos1.write(CONTENT1.getBytes(UTF_8));
107
108 final Path file = createFile(bos1.toByteArray());
109 final FileBasedConfig config = new FileBasedConfig(file.toFile(),
110 FS.DETECTED);
111 config.load();
112 assertEquals(ALICE, config.getString(USER, null, NAME));
113
114 config.setString(USER, null, NAME, BOB);
115 config.save();
116
117 final ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
118 bos2.write(0xEF);
119 bos2.write(0xBB);
120 bos2.write(0xBF);
121 bos2.write(CONTENT2.getBytes(UTF_8));
122 assertArrayEquals(bos2.toByteArray(), IO.readFully(file.toFile()));
123 }
124
125 @Test
126 public void testLeadingWhitespaces() throws IOException, ConfigInvalidException {
127 final ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
128 bos1.write(" \n\t".getBytes(UTF_8));
129 bos1.write(CONTENT1.getBytes(UTF_8));
130
131 final Path file = createFile(bos1.toByteArray());
132 final FileBasedConfig config = new FileBasedConfig(file.toFile(),
133 FS.DETECTED);
134 config.load();
135 assertEquals(ALICE, config.getString(USER, null, NAME));
136
137 config.setString(USER, null, NAME, BOB);
138 config.save();
139
140 final ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
141 bos2.write(" \n\t".getBytes(UTF_8));
142 bos2.write(CONTENT2.getBytes(UTF_8));
143 assertArrayEquals(bos2.toByteArray(), IO.readFully(file.toFile()));
144 }
145
146 @Test
147 public void testIncludeAbsolute()
148 throws IOException, ConfigInvalidException {
149 final Path includedFile = createFile(CONTENT1.getBytes(UTF_8));
150 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
151 bos.write("[include]\npath=".getBytes(UTF_8));
152 bos.write(pathToString(includedFile.toFile()).getBytes(UTF_8));
153
154 final Path file = createFile(bos.toByteArray());
155 final FileBasedConfig config = new FileBasedConfig(file.toFile(),
156 FS.DETECTED);
157 config.load();
158 assertEquals(ALICE, config.getString(USER, null, NAME));
159 }
160
161 @Test
162 public void testIncludeRelativeDot()
163 throws IOException, ConfigInvalidException {
164 final Path includedFile = createFile(CONTENT1.getBytes(UTF_8), "dir1");
165 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
166 bos.write("[include]\npath=".getBytes(UTF_8));
167 bos.write(("./" + includedFile.getFileName()).getBytes(UTF_8));
168
169 final Path file = createFile(bos.toByteArray(), "dir1");
170 final FileBasedConfig config = new FileBasedConfig(file.toFile(),
171 FS.DETECTED);
172 config.load();
173 assertEquals(ALICE, config.getString(USER, null, NAME));
174 }
175
176 @Test
177 public void testIncludeRelativeDotDot()
178 throws IOException, ConfigInvalidException {
179 final Path includedFile = createFile(CONTENT1.getBytes(UTF_8), "dir1");
180 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
181 bos.write("[include]\npath=".getBytes(UTF_8));
182 bos.write(("../" + parent(includedFile).getFileName() + "/"
183 + includedFile.getFileName()).getBytes(UTF_8));
184
185 final Path file = createFile(bos.toByteArray(), "dir2");
186 final FileBasedConfig config = new FileBasedConfig(file.toFile(),
187 FS.DETECTED);
188 config.load();
189 assertEquals(ALICE, config.getString(USER, null, NAME));
190 }
191
192 @Test
193 public void testIncludeRelativeDotDotNotFound()
194 throws IOException, ConfigInvalidException {
195 final Path includedFile = createFile(CONTENT1.getBytes(UTF_8));
196 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
197 bos.write("[include]\npath=".getBytes(UTF_8));
198 bos.write(("../" + includedFile.getFileName()).getBytes(UTF_8));
199
200 final Path file = createFile(bos.toByteArray());
201 final FileBasedConfig config = new FileBasedConfig(file.toFile(),
202 FS.DETECTED);
203 config.load();
204 assertEquals(null, config.getString(USER, null, NAME));
205 }
206
207 @Test
208 public void testIncludeWithTilde()
209 throws IOException, ConfigInvalidException {
210 final Path includedFile = createFile(CONTENT1.getBytes(UTF_8), "home");
211 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
212 bos.write("[include]\npath=".getBytes(UTF_8));
213 bos.write(("~/" + includedFile.getFileName()).getBytes(UTF_8));
214
215 final Path file = createFile(bos.toByteArray(), "repo");
216 final FS fs = FS.DETECTED.newInstance();
217 fs.setUserHome(parent(includedFile).toFile());
218
219 final FileBasedConfig config = new FileBasedConfig(file.toFile(), fs);
220 config.load();
221 assertEquals(ALICE, config.getString(USER, null, NAME));
222 }
223
224 @Test
225 public void testIncludeDontInlineIncludedLinesOnSave()
226 throws IOException, ConfigInvalidException {
227
228
229 final Path includedFile = createFile(CONTENT3.getBytes(UTF_8), "dir1");
230
231 final Path file = createFile(new byte[0], "dir2");
232 FileBasedConfig config = new FileBasedConfig(file.toFile(),
233 FS.DETECTED);
234 config.setString("include", null, "path",
235 ("../" + parent(includedFile).getFileName() + "/"
236 + includedFile.getFileName()));
237
238
239 assertEquals(null, config.getString(USER, null, NAME));
240 assertEquals(null, config.getString(USER, null, EMAIL));
241 config.save();
242
243
244 assertEquals(null, config.getString(USER, null, NAME));
245 assertEquals(null, config.getString(USER, null, EMAIL));
246
247 final String expectedText = config.toText();
248 assertEquals(2,
249 new StringTokenizer(expectedText, "\n", false).countTokens());
250
251 config = new FileBasedConfig(file.toFile(), FS.DETECTED);
252 config.load();
253
254 String actualText = config.toText();
255 assertEquals(expectedText, actualText);
256
257 assertEquals(ALICE, config.getString(USER, null, NAME));
258 assertEquals(ALICE_EMAIL, config.getString(USER, null, EMAIL));
259
260 config.save();
261
262 actualText = config.toText();
263 assertEquals(expectedText, actualText);
264
265 assertEquals(ALICE, config.getString(USER, null, NAME));
266 assertEquals(ALICE_EMAIL, config.getString(USER, null, EMAIL));
267 }
268
269 private Path createFile(byte[] content) throws IOException {
270 return createFile(content, null);
271 }
272
273 private Path createFile(byte[] content, String subdir) throws IOException {
274 Path dir = subdir != null ? trash.resolve(subdir) : trash;
275 Files.createDirectories(dir);
276
277 Path f = Files.createTempFile(dir, getClass().getName(), null);
278 try (OutputStream os = Files.newOutputStream(f,
279 StandardOpenOption.APPEND)) {
280 os.write(content);
281 }
282 return f;
283 }
284
285 private Path parent(Path file) {
286 Path parent = file.getParent();
287 assertNotNull(parent);
288 return parent;
289 }
290 }