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  		} catch (IllegalArgumentException err) {
93  			assertEquals("FileMode not set for path a", err.getMessage());
94  		}
95  	}
96  
97  	@Test
98  	public void testBuildOneFile_FinishWriteCommit() throws Exception {
99  		final String path = "a-file-path";
100 		final FileMode mode = FileMode.REGULAR_FILE;
101 		final long lastModified = 1218123387057L;
102 		final int length = 1342;
103 		final DirCacheEntry entOrig;
104 		{
105 			final DirCache dc = db.lockDirCache();
106 			final DirCacheBuilder b = dc.builder();
107 			assertNotNull(b);
108 
109 			entOrig = new DirCacheEntry(path);
110 			entOrig.setFileMode(mode);
111 			entOrig.setLastModified(lastModified);
112 			entOrig.setLength(length);
113 
114 			assertNotSame(path, entOrig.getPathString());
115 			assertEquals(path, entOrig.getPathString());
116 			assertEquals(ObjectId.zeroId(), entOrig.getObjectId());
117 			assertEquals(mode.getBits(), entOrig.getRawMode());
118 			assertEquals(0, entOrig.getStage());
119 			assertEquals(lastModified, entOrig.getLastModified());
120 			assertEquals(length, entOrig.getLength());
121 			assertFalse(entOrig.isAssumeValid());
122 			b.add(entOrig);
123 
124 			b.finish();
125 			assertEquals(1, dc.getEntryCount());
126 			assertSame(entOrig, dc.getEntry(0));
127 
128 			dc.write();
129 			assertTrue(dc.commit());
130 		}
131 		{
132 			final DirCache dc = db.readDirCache();
133 			assertEquals(1, dc.getEntryCount());
134 
135 			final DirCacheEntry entRead = dc.getEntry(0);
136 			assertNotSame(entOrig, entRead);
137 			assertEquals(path, entRead.getPathString());
138 			assertEquals(ObjectId.zeroId(), entOrig.getObjectId());
139 			assertEquals(mode.getBits(), entOrig.getRawMode());
140 			assertEquals(0, entOrig.getStage());
141 			assertEquals(lastModified, entOrig.getLastModified());
142 			assertEquals(length, entOrig.getLength());
143 			assertFalse(entOrig.isAssumeValid());
144 		}
145 	}
146 
147 	@Test
148 	public void testBuildOneFile_Commit() throws Exception {
149 		final String path = "a-file-path";
150 		final FileMode mode = FileMode.REGULAR_FILE;
151 		final long lastModified = 1218123387057L;
152 		final int length = 1342;
153 		final DirCacheEntry entOrig;
154 		{
155 			final DirCache dc = db.lockDirCache();
156 			final DirCacheBuilder b = dc.builder();
157 			assertNotNull(b);
158 
159 			entOrig = new DirCacheEntry(path);
160 			entOrig.setFileMode(mode);
161 			entOrig.setLastModified(lastModified);
162 			entOrig.setLength(length);
163 
164 			assertNotSame(path, entOrig.getPathString());
165 			assertEquals(path, entOrig.getPathString());
166 			assertEquals(ObjectId.zeroId(), entOrig.getObjectId());
167 			assertEquals(mode.getBits(), entOrig.getRawMode());
168 			assertEquals(0, entOrig.getStage());
169 			assertEquals(lastModified, entOrig.getLastModified());
170 			assertEquals(length, entOrig.getLength());
171 			assertFalse(entOrig.isAssumeValid());
172 			b.add(entOrig);
173 
174 			assertTrue(b.commit());
175 			assertEquals(1, dc.getEntryCount());
176 			assertSame(entOrig, dc.getEntry(0));
177 			assertFalse(new File(db.getDirectory(), "index.lock").exists());
178 		}
179 		{
180 			final DirCache dc = db.readDirCache();
181 			assertEquals(1, dc.getEntryCount());
182 
183 			final DirCacheEntry entRead = dc.getEntry(0);
184 			assertNotSame(entOrig, entRead);
185 			assertEquals(path, entRead.getPathString());
186 			assertEquals(ObjectId.zeroId(), entOrig.getObjectId());
187 			assertEquals(mode.getBits(), entOrig.getRawMode());
188 			assertEquals(0, entOrig.getStage());
189 			assertEquals(lastModified, entOrig.getLastModified());
190 			assertEquals(length, entOrig.getLength());
191 			assertFalse(entOrig.isAssumeValid());
192 		}
193 	}
194 
195 	@Test
196 	public void testBuildOneFile_Commit_IndexChangedEvent()
197 			throws Exception {
198 		final class ReceivedEventMarkerException extends RuntimeException {
199 			private static final long serialVersionUID = 1L;
200 			// empty
201 		}
202 
203 		final String path = "a-file-path";
204 		final FileMode mode = FileMode.REGULAR_FILE;
205 		// "old" date in 2008
206 		final long lastModified = 1218123387057L;
207 		final int length = 1342;
208 		DirCacheEntry entOrig;
209 		boolean receivedEvent = false;
210 
211 		DirCache dc = db.lockDirCache();
212 		IndexChangedListener listener = new IndexChangedListener() {
213 
214 			public void onIndexChanged(IndexChangedEvent event) {
215 				throw new ReceivedEventMarkerException();
216 			}
217 		};
218 
219 		ListenerList l = db.getListenerList();
220 		l.addIndexChangedListener(listener);
221 		DirCacheBuilder b = dc.builder();
222 
223 		entOrig = new DirCacheEntry(path);
224 		entOrig.setFileMode(mode);
225 		entOrig.setLastModified(lastModified);
226 		entOrig.setLength(length);
227 		b.add(entOrig);
228 		try {
229 			b.commit();
230 		} catch (ReceivedEventMarkerException e) {
231 			receivedEvent = true;
232 		}
233 		if (!receivedEvent)
234 			fail("did not receive IndexChangedEvent");
235 
236 		// do the same again, as this doesn't change index compared to first
237 		// round we should get no event this time
238 		dc = db.lockDirCache();
239 		listener = new IndexChangedListener() {
240 
241 			public void onIndexChanged(IndexChangedEvent event) {
242 				throw new ReceivedEventMarkerException();
243 			}
244 		};
245 
246 		l = db.getListenerList();
247 		l.addIndexChangedListener(listener);
248 		b = dc.builder();
249 
250 		entOrig = new DirCacheEntry(path);
251 		entOrig.setFileMode(mode);
252 		entOrig.setLastModified(lastModified);
253 		entOrig.setLength(length);
254 		b.add(entOrig);
255 		try {
256 			b.commit();
257 		} catch (ReceivedEventMarkerException e) {
258 			fail("unexpected IndexChangedEvent");
259 		}
260 	}
261 
262 	@Test
263 	public void testFindSingleFile() throws Exception {
264 		final String path = "a-file-path";
265 		final DirCache dc = db.readDirCache();
266 		final DirCacheBuilder b = dc.builder();
267 		assertNotNull(b);
268 
269 		final DirCacheEntry entOrig = new DirCacheEntry(path);
270 		entOrig.setFileMode(FileMode.REGULAR_FILE);
271 		assertNotSame(path, entOrig.getPathString());
272 		assertEquals(path, entOrig.getPathString());
273 		b.add(entOrig);
274 		b.finish();
275 
276 		assertEquals(1, dc.getEntryCount());
277 		assertSame(entOrig, dc.getEntry(0));
278 		assertEquals(0, dc.findEntry(path));
279 
280 		assertEquals(-1, dc.findEntry("@@-before"));
281 		assertEquals(0, real(dc.findEntry("@@-before")));
282 
283 		assertEquals(-2, dc.findEntry("a-zoo"));
284 		assertEquals(1, real(dc.findEntry("a-zoo")));
285 
286 		assertSame(entOrig, dc.getEntry(path));
287 	}
288 
289 	@Test
290 	public void testAdd_InGitSortOrder() throws Exception {
291 		final DirCache dc = db.readDirCache();
292 
293 		final String[] paths = { "a-", "a.b", "a/b", "a0b" };
294 		final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
295 		for (int i = 0; i < paths.length; i++) {
296 			ents[i] = new DirCacheEntry(paths[i]);
297 			ents[i].setFileMode(FileMode.REGULAR_FILE);
298 		}
299 
300 		final DirCacheBuilder b = dc.builder();
301 		for (int i = 0; i < ents.length; i++)
302 			b.add(ents[i]);
303 		b.finish();
304 
305 		assertEquals(paths.length, dc.getEntryCount());
306 		for (int i = 0; i < paths.length; i++) {
307 			assertSame(ents[i], dc.getEntry(i));
308 			assertEquals(paths[i], dc.getEntry(i).getPathString());
309 			assertEquals(i, dc.findEntry(paths[i]));
310 			assertSame(ents[i], dc.getEntry(paths[i]));
311 		}
312 	}
313 
314 	@Test
315 	public void testAdd_ReverseGitSortOrder() throws Exception {
316 		final DirCache dc = db.readDirCache();
317 
318 		final String[] paths = { "a-", "a.b", "a/b", "a0b" };
319 		final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
320 		for (int i = 0; i < paths.length; i++) {
321 			ents[i] = new DirCacheEntry(paths[i]);
322 			ents[i].setFileMode(FileMode.REGULAR_FILE);
323 		}
324 
325 		final DirCacheBuilder b = dc.builder();
326 		for (int i = ents.length - 1; i >= 0; i--)
327 			b.add(ents[i]);
328 		b.finish();
329 
330 		assertEquals(paths.length, dc.getEntryCount());
331 		for (int i = 0; i < paths.length; i++) {
332 			assertSame(ents[i], dc.getEntry(i));
333 			assertEquals(paths[i], dc.getEntry(i).getPathString());
334 			assertEquals(i, dc.findEntry(paths[i]));
335 			assertSame(ents[i], dc.getEntry(paths[i]));
336 		}
337 	}
338 
339 	@Test
340 	public void testBuilderClear() throws Exception {
341 		final DirCache dc = db.readDirCache();
342 
343 		final String[] paths = { "a-", "a.b", "a/b", "a0b" };
344 		final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
345 		for (int i = 0; i < paths.length; i++) {
346 			ents[i] = new DirCacheEntry(paths[i]);
347 			ents[i].setFileMode(FileMode.REGULAR_FILE);
348 		}
349 		{
350 			final DirCacheBuilder b = dc.builder();
351 			for (int i = 0; i < ents.length; i++)
352 				b.add(ents[i]);
353 			b.finish();
354 		}
355 		assertEquals(paths.length, dc.getEntryCount());
356 		{
357 			final DirCacheBuilder b = dc.builder();
358 			b.finish();
359 		}
360 		assertEquals(0, dc.getEntryCount());
361 	}
362 
363 	private static int real(int eIdx) {
364 		if (eIdx < 0)
365 			eIdx = -(eIdx + 1);
366 		return eIdx;
367 	}
368 }