2 * Copyright (C) 2008, Google Inc.
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * - Neither the name of the Git Development Community nor the
19 * names of its contributors may be used to endorse or promote
20 * products derived from this software without specific prior
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 package org
.spearce
.jgit
.treewalk
;
40 import java
.io
.ByteArrayOutputStream
;
42 import junit
.framework
.TestCase
;
44 import org
.spearce
.jgit
.lib
.Constants
;
45 import org
.spearce
.jgit
.lib
.FileMode
;
46 import org
.spearce
.jgit
.lib
.ObjectId
;
47 import org
.spearce
.jgit
.util
.RawParseUtils
;
49 public class CanonicalTreeParserTest
extends TestCase
{
50 private final CanonicalTreeParser ctp
= new CanonicalTreeParser();
52 private final FileMode m644
= FileMode
.REGULAR_FILE
;
54 private final FileMode mt
= FileMode
.TREE
;
56 private final ObjectId hash_a
= ObjectId
57 .fromString("6b9c715d21d5486e59083fb6071566aa6ecd4d42");
59 private final ObjectId hash_foo
= ObjectId
60 .fromString("a213e8e25bb2442326e86cbfb9ef56319f482869");
62 private final ObjectId hash_sometree
= ObjectId
63 .fromString("daf4bdb0d7bb24319810fe0e73aa317663448c93");
71 public void setUp() throws Exception
{
74 tree1
= mktree(entry(m644
, "a", hash_a
));
75 tree2
= mktree(entry(m644
, "a", hash_a
), entry(m644
, "foo", hash_foo
));
76 tree3
= mktree(entry(m644
, "a", hash_a
), entry(mt
, "b_sometree",
77 hash_sometree
), entry(m644
, "foo", hash_foo
));
80 private static byte[] mktree(final byte[]... data
) throws Exception
{
81 final ByteArrayOutputStream out
= new ByteArrayOutputStream();
82 for (final byte[] e
: data
)
84 return out
.toByteArray();
87 private static byte[] entry(final FileMode mode
, final String name
,
88 final ObjectId id
) throws Exception
{
89 final ByteArrayOutputStream out
= new ByteArrayOutputStream();
92 out
.write(Constants
.encode(name
));
95 return out
.toByteArray();
98 private String
path() {
99 return RawParseUtils
.decode(Constants
.CHARSET
, ctp
.path
,
100 ctp
.pathOffset
, ctp
.pathLen
);
103 public void testEmptyTree_AtEOF() throws Exception
{
104 ctp
.reset(new byte[0]);
105 assertTrue(ctp
.eof());
108 public void testOneEntry_Forward() throws Exception
{
111 assertTrue(ctp
.first());
112 assertFalse(ctp
.eof());
113 assertEquals(m644
.getBits(), ctp
.mode
);
114 assertEquals("a", path());
115 assertEquals(hash_a
, ctp
.getEntryObjectId());
118 assertFalse(ctp
.first());
119 assertTrue(ctp
.eof());
122 public void testTwoEntries_ForwardOneAtATime() throws Exception
{
125 assertTrue(ctp
.first());
126 assertFalse(ctp
.eof());
127 assertEquals(m644
.getBits(), ctp
.mode
);
128 assertEquals("a", path());
129 assertEquals(hash_a
, ctp
.getEntryObjectId());
132 assertFalse(ctp
.eof());
133 assertEquals(m644
.getBits(), ctp
.mode
);
134 assertEquals("foo", path());
135 assertEquals(hash_foo
, ctp
.getEntryObjectId());
138 assertFalse(ctp
.first());
139 assertTrue(ctp
.eof());
142 public void testOneEntry_Seek1IsEOF() throws Exception
{
145 assertTrue(ctp
.eof());
148 public void testTwoEntries_Seek2IsEOF() throws Exception
{
151 assertTrue(ctp
.eof());
154 public void testThreeEntries_Seek3IsEOF() throws Exception
{
157 assertTrue(ctp
.eof());
160 public void testThreeEntries_Seek2() throws Exception
{
164 assertFalse(ctp
.eof());
165 assertFalse(ctp
.eof());
166 assertEquals(m644
.getBits(), ctp
.mode
);
167 assertEquals("foo", path());
168 assertEquals(hash_foo
, ctp
.getEntryObjectId());
171 assertTrue(ctp
.eof());
174 public void testOneEntry_Backwards() throws Exception
{
177 assertFalse(ctp
.first());
178 assertTrue(ctp
.eof());
181 assertTrue(ctp
.first());
182 assertFalse(ctp
.eof());
183 assertEquals(m644
.getBits(), ctp
.mode
);
184 assertEquals("a", path());
185 assertEquals(hash_a
, ctp
.getEntryObjectId());
188 public void testTwoEntries_BackwardsOneAtATime() throws Exception
{
191 assertTrue(ctp
.eof());
194 assertFalse(ctp
.eof());
195 assertEquals(m644
.getBits(), ctp
.mode
);
196 assertEquals("foo", path());
197 assertEquals(hash_foo
, ctp
.getEntryObjectId());
200 assertFalse(ctp
.eof());
201 assertEquals(m644
.getBits(), ctp
.mode
);
202 assertEquals("a", path());
203 assertEquals(hash_a
, ctp
.getEntryObjectId());
206 public void testTwoEntries_BackwardsTwo() throws Exception
{
209 assertTrue(ctp
.eof());
212 assertFalse(ctp
.eof());
213 assertEquals(m644
.getBits(), ctp
.mode
);
214 assertEquals("a", path());
215 assertEquals(hash_a
, ctp
.getEntryObjectId());
218 assertFalse(ctp
.eof());
219 assertEquals(m644
.getBits(), ctp
.mode
);
220 assertEquals("foo", path());
221 assertEquals(hash_foo
, ctp
.getEntryObjectId());
224 assertTrue(ctp
.eof());
227 public void testThreeEntries_BackwardsTwo() throws Exception
{
230 assertTrue(ctp
.eof());
233 assertFalse(ctp
.eof());
234 assertEquals(mt
.getBits(), ctp
.mode
);
235 assertEquals("b_sometree", path());
236 assertEquals(hash_sometree
, ctp
.getEntryObjectId());
239 assertFalse(ctp
.eof());
240 assertEquals(m644
.getBits(), ctp
.mode
);
241 assertEquals("foo", path());
242 assertEquals(hash_foo
, ctp
.getEntryObjectId());
245 assertTrue(ctp
.eof());
248 public void testBackwards_ConfusingPathName() throws Exception
{
249 final String aVeryConfusingName
= "confusing 644 entry 755 and others";
250 ctp
.reset(mktree(entry(m644
, "a", hash_a
), entry(mt
, aVeryConfusingName
,
251 hash_sometree
), entry(m644
, "foo", hash_foo
)));
253 assertTrue(ctp
.eof());
256 assertFalse(ctp
.eof());
257 assertEquals(mt
.getBits(), ctp
.mode
);
258 assertEquals(aVeryConfusingName
, path());
259 assertEquals(hash_sometree
, ctp
.getEntryObjectId());
262 assertFalse(ctp
.eof());
263 assertEquals(m644
.getBits(), ctp
.mode
);
264 assertEquals("a", path());
265 assertEquals(hash_a
, ctp
.getEntryObjectId());
268 public void testBackwords_Prebuilts1() throws Exception
{
269 // What is interesting about this test is the ObjectId for the
270 // "darwin-x86" path entry ends in an octal digit (37 == '7').
271 // Thus when scanning backwards we could over scan and consume
272 // part of the SHA-1, and miss the path terminator.
274 final ObjectId common
= ObjectId
275 .fromString("af7bf97cb9bce3f60f1d651a0ef862e9447dd8bc");
276 final ObjectId darwinx86
= ObjectId
277 .fromString("e927f7398240f78face99e1a738dac54ef738e37");
278 final ObjectId linuxx86
= ObjectId
279 .fromString("ac08dd97120c7cb7d06e98cd5b152011183baf21");
280 final ObjectId windows
= ObjectId
281 .fromString("6c4c64c221a022bb973165192cca4812033479df");
283 ctp
.reset(mktree(entry(mt
, "common", common
), entry(mt
, "darwin-x86",
284 darwinx86
), entry(mt
, "linux-x86", linuxx86
), entry(mt
,
285 "windows", windows
)));
287 assertEquals("windows", ctp
.getEntryPathString());
288 assertSame(mt
, ctp
.getEntryFileMode());
289 assertEquals(windows
, ctp
.getEntryObjectId());
292 assertEquals("linux-x86", ctp
.getEntryPathString());
293 assertSame(mt
, ctp
.getEntryFileMode());
294 assertEquals(linuxx86
, ctp
.getEntryObjectId());
297 assertEquals("windows", ctp
.getEntryPathString());
298 assertSame(mt
, ctp
.getEntryFileMode());
299 assertEquals(windows
, ctp
.getEntryObjectId());
302 public void testBackwords_Prebuilts2() throws Exception
{
303 // What is interesting about this test is the ObjectId for the
304 // "darwin-x86" path entry ends in an octal digit (37 == '7').
305 // Thus when scanning backwards we could over scan and consume
306 // part of the SHA-1, and miss the path terminator.
308 final ObjectId common
= ObjectId
309 .fromString("af7bf97cb9bce3f60f1d651a0ef862e9447dd8bc");
310 final ObjectId darwinx86
= ObjectId
311 .fromString("0000000000000000000000000000000000000037");
312 final ObjectId linuxx86
= ObjectId
313 .fromString("ac08dd97120c7cb7d06e98cd5b152011183baf21");
314 final ObjectId windows
= ObjectId
315 .fromString("6c4c64c221a022bb973165192cca4812033479df");
317 ctp
.reset(mktree(entry(mt
, "common", common
), entry(mt
, "darwin-x86",
318 darwinx86
), entry(mt
, "linux-x86", linuxx86
), entry(mt
,
319 "windows", windows
)));
321 assertEquals("windows", ctp
.getEntryPathString());
322 assertSame(mt
, ctp
.getEntryFileMode());
323 assertEquals(windows
, ctp
.getEntryObjectId());
326 assertEquals("linux-x86", ctp
.getEntryPathString());
327 assertSame(mt
, ctp
.getEntryFileMode());
328 assertEquals(linuxx86
, ctp
.getEntryObjectId());
331 assertEquals("windows", ctp
.getEntryPathString());
332 assertSame(mt
, ctp
.getEntryFileMode());
333 assertEquals(windows
, ctp
.getEntryObjectId());
336 public void testFreakingHugePathName() throws Exception
{
337 final int n
= AbstractTreeIterator
.DEFAULT_PATH_SIZE
* 4;
338 final StringBuilder b
= new StringBuilder(n
);
339 for (int i
= 0; i
< n
; i
++)
341 final String name
= b
.toString();
342 ctp
.reset(entry(m644
, name
, hash_a
));
343 assertFalse(ctp
.eof());
344 assertEquals(name
, RawParseUtils
.decode(Constants
.CHARSET
, ctp
.path
,
345 ctp
.pathOffset
, ctp
.pathLen
));