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