View Javadoc
1   /*
2    * Copyright (C) 2008-2009, Google Inc.
3    * Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com>
4    * and other copyright owners as documented in the project's IP log.
5    *
6    * This program and the accompanying materials are made available
7    * under the terms of the Eclipse Distribution License v1.0 which
8    * accompanies this distribution, is reproduced below, and is
9    * available at http://www.eclipse.org/org/documents/edl-v10.php
10   *
11   * All rights reserved.
12   *
13   * Redistribution and use in source and binary forms, with or
14   * without modification, are permitted provided that the following
15   * conditions are met:
16   *
17   * - Redistributions of source code must retain the above copyright
18   *   notice, this list of conditions and the following disclaimer.
19   *
20   * - Redistributions in binary form must reproduce the above
21   *   copyright notice, this list of conditions and the following
22   *   disclaimer in the documentation and/or other materials provided
23   *   with the distribution.
24   *
25   * - Neither the name of the Eclipse Foundation, Inc. nor the
26   *   names of its contributors may be used to endorse or promote
27   *   products derived from this software without specific prior
28   *   written permission.
29   *
30   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
31   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
32   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
35   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
37   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
39   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
42   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43   */
44  
45  package org.eclipse.jgit.dircache;
46  
47  import static org.junit.Assert.assertEquals;
48  import static org.junit.Assert.assertFalse;
49  import static org.junit.Assert.assertNotNull;
50  import static org.junit.Assert.assertNotSame;
51  import static org.junit.Assert.assertSame;
52  import static org.junit.Assert.assertTrue;
53  import static org.junit.Assert.fail;
54  
55  import java.io.File;
56  
57  import org.eclipse.jgit.events.IndexChangedEvent;
58  import org.eclipse.jgit.events.IndexChangedListener;
59  import org.eclipse.jgit.events.ListenerList;
60  import org.eclipse.jgit.junit.RepositoryTestCase;
61  import org.eclipse.jgit.lib.FileMode;
62  import org.eclipse.jgit.lib.ObjectId;
63  import org.junit.Test;
64  
65  public class DirCacheBuilderTest extends RepositoryTestCase {
66  	@Test
67  	public void testBuildEmpty() throws Exception {
68  		{
69  			final DirCache dc = db.lockDirCache();
70  			final DirCacheBuilder b = dc.builder();
71  			assertNotNull(b);
72  			b.finish();
73  			dc.write();
74  			assertTrue(dc.commit());
75  		}
76  		{
77  			final DirCache dc = db.readDirCache();
78  			assertEquals(0, dc.getEntryCount());
79  		}
80  	}
81  
82  	@Test
83  	public void testBuildRejectsUnsetFileMode() throws Exception {
84  		final DirCache dc = DirCache.newInCore();
85  		final DirCacheBuilder b = dc.builder();
86  		assertNotNull(b);
87  
88  		final DirCacheEntry e = new DirCacheEntry("a");
89  		assertEquals(0, e.getRawMode());
90  		try {
91  			b.add(e);
92  			fail("did not reject unset file mode");
93  		} catch (IllegalArgumentException err) {
94  			assertEquals("FileMode not set for path a", err.getMessage());
95  		}
96  	}
97  
98  	@Test
99  	public void testBuildOneFile_FinishWriteCommit() throws Exception {
100 		final String path = "a-file-path";
101 		final FileMode mode = FileMode.REGULAR_FILE;
102 		final long lastModified = 1218123387057L;
103 		final int length = 1342;
104 		final DirCacheEntry entOrig;
105 		{
106 			final DirCache dc = db.lockDirCache();
107 			final DirCacheBuilder b = dc.builder();
108 			assertNotNull(b);
109 
110 			entOrig = new DirCacheEntry(path);
111 			entOrig.setFileMode(mode);
112 			entOrig.setLastModified(lastModified);
113 			entOrig.setLength(length);
114 
115 			assertNotSame(path, entOrig.getPathString());
116 			assertEquals(path, entOrig.getPathString());
117 			assertEquals(ObjectId.zeroId(), entOrig.getObjectId());
118 			assertEquals(mode.getBits(), entOrig.getRawMode());
119 			assertEquals(0, entOrig.getStage());
120 			assertEquals(lastModified, entOrig.getLastModified());
121 			assertEquals(length, entOrig.getLength());
122 			assertFalse(entOrig.isAssumeValid());
123 			b.add(entOrig);
124 
125 			b.finish();
126 			assertEquals(1, dc.getEntryCount());
127 			assertSame(entOrig, dc.getEntry(0));
128 
129 			dc.write();
130 			assertTrue(dc.commit());
131 		}
132 		{
133 			final DirCache dc = db.readDirCache();
134 			assertEquals(1, dc.getEntryCount());
135 
136 			final DirCacheEntry entRead = dc.getEntry(0);
137 			assertNotSame(entOrig, entRead);
138 			assertEquals(path, entRead.getPathString());
139 			assertEquals(ObjectId.zeroId(), entOrig.getObjectId());
140 			assertEquals(mode.getBits(), entOrig.getRawMode());
141 			assertEquals(0, entOrig.getStage());
142 			assertEquals(lastModified, entOrig.getLastModified());
143 			assertEquals(length, entOrig.getLength());
144 			assertFalse(entOrig.isAssumeValid());
145 		}
146 	}
147 
148 	@Test
149 	public void testBuildOneFile_Commit() throws Exception {
150 		final String path = "a-file-path";
151 		final FileMode mode = FileMode.REGULAR_FILE;
152 		final long lastModified = 1218123387057L;
153 		final int length = 1342;
154 		final DirCacheEntry entOrig;
155 		{
156 			final DirCache dc = db.lockDirCache();
157 			final DirCacheBuilder b = dc.builder();
158 			assertNotNull(b);
159 
160 			entOrig = new DirCacheEntry(path);
161 			entOrig.setFileMode(mode);
162 			entOrig.setLastModified(lastModified);
163 			entOrig.setLength(length);
164 
165 			assertNotSame(path, entOrig.getPathString());
166 			assertEquals(path, entOrig.getPathString());
167 			assertEquals(ObjectId.zeroId(), entOrig.getObjectId());
168 			assertEquals(mode.getBits(), entOrig.getRawMode());
169 			assertEquals(0, entOrig.getStage());
170 			assertEquals(lastModified, entOrig.getLastModified());
171 			assertEquals(length, entOrig.getLength());
172 			assertFalse(entOrig.isAssumeValid());
173 			b.add(entOrig);
174 
175 			assertTrue(b.commit());
176 			assertEquals(1, dc.getEntryCount());
177 			assertSame(entOrig, dc.getEntry(0));
178 			assertFalse(new File(db.getDirectory(), "index.lock").exists());
179 		}
180 		{
181 			final DirCache dc = db.readDirCache();
182 			assertEquals(1, dc.getEntryCount());
183 
184 			final DirCacheEntry entRead = dc.getEntry(0);
185 			assertNotSame(entOrig, entRead);
186 			assertEquals(path, entRead.getPathString());
187 			assertEquals(ObjectId.zeroId(), entOrig.getObjectId());
188 			assertEquals(mode.getBits(), entOrig.getRawMode());
189 			assertEquals(0, entOrig.getStage());
190 			assertEquals(lastModified, entOrig.getLastModified());
191 			assertEquals(length, entOrig.getLength());
192 			assertFalse(entOrig.isAssumeValid());
193 		}
194 	}
195 
196 	@Test
197 	public void testBuildOneFile_Commit_IndexChangedEvent()
198 			throws Exception {
199 		final class ReceivedEventMarkerException extends RuntimeException {
200 			private static final long serialVersionUID = 1L;
201 			// empty
202 		}
203 
204 		final String path = "a-file-path";
205 		final FileMode mode = FileMode.REGULAR_FILE;
206 		// "old" date in 2008
207 		final long lastModified = 1218123387057L;
208 		final int length = 1342;
209 		DirCacheEntry entOrig;
210 		boolean receivedEvent = false;
211 
212 		DirCache dc = db.lockDirCache();
213 		IndexChangedListener listener = new IndexChangedListener() {
214 
215 			@Override
216 			public void onIndexChanged(IndexChangedEvent event) {
217 				throw new ReceivedEventMarkerException();
218 			}
219 		};
220 
221 		ListenerList l = db.getListenerList();
222 		l.addIndexChangedListener(listener);
223 		DirCacheBuilder b = dc.builder();
224 
225 		entOrig = new DirCacheEntry(path);
226 		entOrig.setFileMode(mode);
227 		entOrig.setLastModified(lastModified);
228 		entOrig.setLength(length);
229 		b.add(entOrig);
230 		try {
231 			b.commit();
232 		} catch (ReceivedEventMarkerException e) {
233 			receivedEvent = true;
234 		}
235 		if (!receivedEvent)
236 			fail("did not receive IndexChangedEvent");
237 
238 		// do the same again, as this doesn't change index compared to first
239 		// round we should get no event this time
240 		dc = db.lockDirCache();
241 		listener = new IndexChangedListener() {
242 
243 			@Override
244 			public void onIndexChanged(IndexChangedEvent event) {
245 				throw new ReceivedEventMarkerException();
246 			}
247 		};
248 
249 		l = db.getListenerList();
250 		l.addIndexChangedListener(listener);
251 		b = dc.builder();
252 
253 		entOrig = new DirCacheEntry(path);
254 		entOrig.setFileMode(mode);
255 		entOrig.setLastModified(lastModified);
256 		entOrig.setLength(length);
257 		b.add(entOrig);
258 		try {
259 			b.commit();
260 		} catch (ReceivedEventMarkerException e) {
261 			fail("unexpected IndexChangedEvent");
262 		}
263 	}
264 
265 	@Test
266 	public void testFindSingleFile() throws Exception {
267 		final String path = "a-file-path";
268 		final DirCache dc = db.readDirCache();
269 		final DirCacheBuilder b = dc.builder();
270 		assertNotNull(b);
271 
272 		final DirCacheEntry entOrig = new DirCacheEntry(path);
273 		entOrig.setFileMode(FileMode.REGULAR_FILE);
274 		assertNotSame(path, entOrig.getPathString());
275 		assertEquals(path, entOrig.getPathString());
276 		b.add(entOrig);
277 		b.finish();
278 
279 		assertEquals(1, dc.getEntryCount());
280 		assertSame(entOrig, dc.getEntry(0));
281 		assertEquals(0, dc.findEntry(path));
282 
283 		assertEquals(-1, dc.findEntry("@@-before"));
284 		assertEquals(0, real(dc.findEntry("@@-before")));
285 
286 		assertEquals(-2, dc.findEntry("a-zoo"));
287 		assertEquals(1, real(dc.findEntry("a-zoo")));
288 
289 		assertSame(entOrig, dc.getEntry(path));
290 	}
291 
292 	@Test
293 	public void testAdd_InGitSortOrder() throws Exception {
294 		final DirCache dc = db.readDirCache();
295 
296 		final String[] paths = { "a-", "a.b", "a/b", "a0b" };
297 		final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
298 		for (int i = 0; i < paths.length; i++) {
299 			ents[i] = new DirCacheEntry(paths[i]);
300 			ents[i].setFileMode(FileMode.REGULAR_FILE);
301 		}
302 
303 		final DirCacheBuilder b = dc.builder();
304 		for (int i = 0; i < ents.length; i++)
305 			b.add(ents[i]);
306 		b.finish();
307 
308 		assertEquals(paths.length, dc.getEntryCount());
309 		for (int i = 0; i < paths.length; i++) {
310 			assertSame(ents[i], dc.getEntry(i));
311 			assertEquals(paths[i], dc.getEntry(i).getPathString());
312 			assertEquals(i, dc.findEntry(paths[i]));
313 			assertSame(ents[i], dc.getEntry(paths[i]));
314 		}
315 	}
316 
317 	@Test
318 	public void testAdd_ReverseGitSortOrder() throws Exception {
319 		final DirCache dc = db.readDirCache();
320 
321 		final String[] paths = { "a-", "a.b", "a/b", "a0b" };
322 		final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
323 		for (int i = 0; i < paths.length; i++) {
324 			ents[i] = new DirCacheEntry(paths[i]);
325 			ents[i].setFileMode(FileMode.REGULAR_FILE);
326 		}
327 
328 		final DirCacheBuilder b = dc.builder();
329 		for (int i = ents.length - 1; i >= 0; i--)
330 			b.add(ents[i]);
331 		b.finish();
332 
333 		assertEquals(paths.length, dc.getEntryCount());
334 		for (int i = 0; i < paths.length; i++) {
335 			assertSame(ents[i], dc.getEntry(i));
336 			assertEquals(paths[i], dc.getEntry(i).getPathString());
337 			assertEquals(i, dc.findEntry(paths[i]));
338 			assertSame(ents[i], dc.getEntry(paths[i]));
339 		}
340 	}
341 
342 	@Test
343 	public void testBuilderClear() throws Exception {
344 		final DirCache dc = db.readDirCache();
345 
346 		final String[] paths = { "a-", "a.b", "a/b", "a0b" };
347 		final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
348 		for (int i = 0; i < paths.length; i++) {
349 			ents[i] = new DirCacheEntry(paths[i]);
350 			ents[i].setFileMode(FileMode.REGULAR_FILE);
351 		}
352 		{
353 			final DirCacheBuilder b = dc.builder();
354 			for (int i = 0; i < ents.length; i++)
355 				b.add(ents[i]);
356 			b.finish();
357 		}
358 		assertEquals(paths.length, dc.getEntryCount());
359 		{
360 			final DirCacheBuilder b = dc.builder();
361 			b.finish();
362 		}
363 		assertEquals(0, dc.getEntryCount());
364 	}
365 
366 	private static int real(int eIdx) {
367 		if (eIdx < 0)
368 			eIdx = -(eIdx + 1);
369 		return eIdx;
370 	}
371 }