1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.internal.storage.dfs;
12
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertFalse;
15 import static org.junit.Assert.assertSame;
16 import static org.junit.Assert.assertTrue;
17
18 import java.io.IOException;
19 import java.nio.ByteBuffer;
20 import java.util.Arrays;
21 import java.util.Collection;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Set;
25 import java.util.zip.Deflater;
26
27 import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
28 import org.eclipse.jgit.internal.storage.pack.PackExt;
29 import org.eclipse.jgit.junit.JGitTestUtil;
30 import org.eclipse.jgit.junit.TestRng;
31 import org.eclipse.jgit.lib.AbbreviatedObjectId;
32 import org.eclipse.jgit.lib.Constants;
33 import org.eclipse.jgit.lib.ObjectId;
34 import org.eclipse.jgit.lib.ObjectInserter;
35 import org.eclipse.jgit.lib.ObjectLoader;
36 import org.eclipse.jgit.lib.ObjectReader;
37 import org.eclipse.jgit.util.IO;
38 import org.eclipse.jgit.util.RawParseUtils;
39 import org.junit.Before;
40 import org.junit.Test;
41
42 public class DfsInserterTest {
43 InMemoryRepository db;
44
45 @Before
46 public void setUp() {
47 db = new InMemoryRepository(new DfsRepositoryDescription("test"));
48 }
49
50 @Test
51 public void testInserterDiscardsPack() throws IOException {
52 try (ObjectInserter ins = db.newObjectInserter()) {
53 ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
54 ins.insert(Constants.OBJ_BLOB, Constants.encode("bar"));
55 assertEquals(0, db.getObjectDatabase().listPacks().size());
56 }
57 assertEquals(0, db.getObjectDatabase().listPacks().size());
58 }
59
60 @Test
61 public void testReadFromInserterSmallObjects() throws IOException {
62 try (ObjectInserter ins = db.newObjectInserter()) {
63 ObjectId id1 = ins.insert(Constants.OBJ_BLOB,
64 Constants.encode("foo"));
65 ObjectId id2 = ins.insert(Constants.OBJ_BLOB,
66 Constants.encode("bar"));
67 assertEquals(0, db.getObjectDatabase().listPacks().size());
68
69 try (ObjectReader reader = ins.newReader()) {
70 assertSame(ins, reader.getCreatedFromInserter());
71 assertEquals("foo", readString(reader.open(id1)));
72 assertEquals("bar", readString(reader.open(id2)));
73 assertEquals(0, db.getObjectDatabase().listPacks().size());
74 ins.flush();
75 assertEquals(1, db.getObjectDatabase().listPacks().size());
76 }
77 }
78 }
79
80 @Test
81 public void testReadFromInserterLargerObjects() throws IOException {
82 db.getObjectDatabase().getReaderOptions().setStreamFileThreshold(512);
83 DfsBlockCache.reconfigure(new DfsBlockCacheConfig()
84 .setBlockSize(512)
85 .setBlockLimit(2048));
86
87 byte[] data = new TestRng(JGitTestUtil.getName()).nextBytes(8192);
88 try (DfsInserter ins = (DfsInserter) db.newObjectInserter()) {
89 ins.setCompressionLevel(Deflater.NO_COMPRESSION);
90 ObjectId id1 = ins.insert(Constants.OBJ_BLOB, data);
91 assertEquals(0, db.getObjectDatabase().listPacks().size());
92
93 try (ObjectReader reader = ins.newReader()) {
94 assertSame(ins, reader.getCreatedFromInserter());
95 assertTrue(Arrays.equals(data, readStream(reader.open(id1))));
96 assertEquals(0, db.getObjectDatabase().listPacks().size());
97 }
98 ins.flush();
99
100 }
101 List<DfsPackDescription> packs = db.getObjectDatabase().listPacks();
102 assertEquals(1, packs.size());
103 assertTrue(packs.get(0).getFileSize(PackExt.PACK) > 2048);
104 }
105
106 @Test
107 public void testReadFromFallback() throws IOException {
108 try (ObjectInserter ins = db.newObjectInserter()) {
109 ObjectId id1 = ins.insert(Constants.OBJ_BLOB,
110 Constants.encode("foo"));
111 ins.flush();
112 ObjectId id2 = ins.insert(Constants.OBJ_BLOB,
113 Constants.encode("bar"));
114 assertEquals(1, db.getObjectDatabase().listPacks().size());
115
116 try (ObjectReader reader = ins.newReader()) {
117 assertSame(ins, reader.getCreatedFromInserter());
118 assertEquals("foo", readString(reader.open(id1)));
119 assertEquals("bar", readString(reader.open(id2)));
120 assertEquals(1, db.getObjectDatabase().listPacks().size());
121 }
122 ins.flush();
123 assertEquals(2, db.getObjectDatabase().listPacks().size());
124 }
125 }
126
127 @Test
128 public void testReaderResolve() throws IOException {
129 try (ObjectInserter ins = db.newObjectInserter()) {
130 ObjectId id1 = ins.insert(Constants.OBJ_BLOB,
131 Constants.encode("foo"));
132 ins.flush();
133 ObjectId id2 = ins.insert(Constants.OBJ_BLOB,
134 Constants.encode("bar"));
135 String abbr1 = ObjectId.toString(id1).substring(0, 4);
136 String abbr2 = ObjectId.toString(id2).substring(0, 4);
137 assertFalse(abbr1.equals(abbr2));
138
139 try (ObjectReader reader = ins.newReader()) {
140 assertSame(ins, reader.getCreatedFromInserter());
141 Collection<ObjectId> objs;
142 objs = reader.resolve(AbbreviatedObjectId.fromString(abbr1));
143 assertEquals(1, objs.size());
144 assertEquals(id1, objs.iterator().next());
145
146 objs = reader.resolve(AbbreviatedObjectId.fromString(abbr2));
147 assertEquals(1, objs.size());
148 assertEquals(id2, objs.iterator().next());
149 }
150 }
151 }
152
153 @Test
154 public void testGarbageSelectivelyVisible() throws IOException {
155 ObjectId fooId;
156 try (ObjectInserter ins = db.newObjectInserter()) {
157 fooId = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
158 ins.flush();
159 }
160 assertEquals(1, db.getObjectDatabase().listPacks().size());
161
162
163 db.getObjectDatabase().listPacks().get(0).setPackSource(PackSource.UNREACHABLE_GARBAGE);
164
165
166 assertTrue(db.getObjectDatabase().has(fooId));
167
168 assertFalse(db.getObjectDatabase().has(fooId, true));
169 }
170
171 @Test
172 public void testInserterIgnoresUnreachable() throws IOException {
173 ObjectId fooId;
174 try (ObjectInserter ins = db.newObjectInserter()) {
175 fooId = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
176 ins.flush();
177 assertEquals(1, db.getObjectDatabase().listPacks().size());
178
179
180 db.getObjectDatabase().listPacks().get(0)
181 .setPackSource(PackSource.UNREACHABLE_GARBAGE);
182
183
184 assertFalse(db.getObjectDatabase().has(fooId, true));
185
186
187 ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
188 ins.flush();
189 }
190 assertTrue(db.getObjectDatabase().has(fooId, true));
191
192
193 try (DfsReader reader = new DfsReader(db.getObjectDatabase())) {
194 DfsPackFile packs[] = db.getObjectDatabase().getPacks();
195 Set<PackSource> pack_sources = new HashSet<>();
196
197 assertEquals(2, packs.length);
198
199 pack_sources.add(packs[0].getPackDescription().getPackSource());
200 pack_sources.add(packs[1].getPackDescription().getPackSource());
201
202 assertTrue(packs[0].hasObject(reader, fooId));
203 assertTrue(packs[1].hasObject(reader, fooId));
204 assertTrue(pack_sources.contains(PackSource.UNREACHABLE_GARBAGE));
205 assertTrue(pack_sources.contains(PackSource.INSERT));
206 }
207 }
208
209 @Test
210 public void testNoCheckExisting() throws IOException {
211 byte[] contents = Constants.encode("foo");
212 ObjectId fooId;
213 try (ObjectInserter ins = db.newObjectInserter()) {
214 fooId = ins.insert(Constants.OBJ_BLOB, contents);
215 ins.flush();
216 }
217 assertEquals(1, db.getObjectDatabase().listPacks().size());
218
219 try (ObjectInserter ins = db.newObjectInserter()) {
220 ((DfsInserter) ins).checkExisting(false);
221 assertEquals(fooId, ins.insert(Constants.OBJ_BLOB, contents));
222 ins.flush();
223 }
224 assertEquals(2, db.getObjectDatabase().listPacks().size());
225
226
227 try (DfsReader reader = new DfsReader(db.getObjectDatabase())) {
228 DfsPackFile packs[] = db.getObjectDatabase().getPacks();
229
230 assertEquals(2, packs.length);
231 DfsPackFile p1 = packs[0];
232 assertEquals(PackSource.INSERT,
233 p1.getPackDescription().getPackSource());
234 assertTrue(p1.hasObject(reader, fooId));
235
236 DfsPackFile p2 = packs[1];
237 assertEquals(PackSource.INSERT,
238 p2.getPackDescription().getPackSource());
239 assertTrue(p2.hasObject(reader, fooId));
240 }
241 }
242
243 private static String readString(ObjectLoader loader) throws IOException {
244 return RawParseUtils.decode(readStream(loader));
245 }
246
247 private static byte[] readStream(ObjectLoader loader) throws IOException {
248 ByteBuffer bb = IO.readWholeStream(loader.openStream(), 64);
249 byte[] buf = new byte[bb.remaining()];
250 bb.get(buf);
251 return buf;
252 }
253 }