1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.kuali.student.svn.model;
16
17 import java.io.IOException;
18 import java.util.Arrays;
19 import java.util.Map;
20
21 import org.eclipse.jgit.errors.CorruptObjectException;
22 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
23 import org.eclipse.jgit.errors.MissingObjectException;
24 import org.eclipse.jgit.lib.AnyObjectId;
25 import org.eclipse.jgit.lib.FileMode;
26 import org.eclipse.jgit.lib.ObjectId;
27 import org.eclipse.jgit.lib.ObjectInserter;
28 import org.eclipse.jgit.lib.ObjectReader;
29 import org.eclipse.jgit.lib.RefUpdate.Result;
30 import org.eclipse.jgit.revwalk.RevCommit;
31 import org.eclipse.jgit.revwalk.RevWalk;
32 import org.eclipse.jgit.treewalk.TreeWalk;
33 import org.eclipse.jgit.treewalk.filter.PathFilter;
34 import org.junit.Assert;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.junit.runners.BlockJUnit4ClassRunner;
38 import org.kuali.student.git.model.DummyGitTreeNodeInitializer;
39 import org.kuali.student.git.model.ExternalModuleUtils;
40 import org.kuali.student.git.model.ref.utils.GitRefUtils;
41 import org.kuali.student.git.model.tree.GitTreeData;
42 import org.kuali.student.git.model.tree.utils.GitTreeProcessor;
43 import org.kuali.student.git.model.utils.GitTestUtils;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47
48
49
50
51 @RunWith(BlockJUnit4ClassRunner.class)
52 public class TestExternalsFusion extends AbstractGitRespositoryTestCase {
53
54 private static Logger log = LoggerFactory.getLogger(TestExternalsFusion.class);
55
56
57
58
59 public TestExternalsFusion() {
60 super ("externals-fusion");
61 }
62
63 @Test
64 public void testInverseFusion() throws IOException {
65
66
67
68
69 ObjectInserter inserter = repo.newObjectInserter();
70
71
72 GitTreeData branch1 = new GitTreeData(new DummyGitTreeNodeInitializer());
73
74 String branch1FilePath = "src/main/java/org/kuali/student/enrollment/test.txt";
75 storeFile (inserter, branch1, branch1FilePath, "test");
76
77 ObjectId b1Id = commit (inserter, branch1, "created branch1");
78
79 Result result = createBranch(b1Id, "branch1");
80
81 Assert.assertEquals(Result.NEW, result);
82
83 inserter.flush();
84
85
86 GitTreeData branch2 = new GitTreeData(new DummyGitTreeNodeInitializer());
87
88 String branch2FilePath = branch1FilePath;
89
90 storeFile (inserter, branch2, branch2FilePath, "test");
91
92 ObjectId b2Id = commit (inserter, branch2, "created branch2");
93
94 result = createBranch(b2Id, "branch2");
95
96 Assert.assertEquals(Result.NEW, result);
97
98 inserter.flush();
99
100
101 GitTreeData aggregate = new GitTreeData(new DummyGitTreeNodeInitializer());
102
103 String aggregate_file_path = "src/main/java/org/kuali/student/enrollment/pom.xml";
104 storeFile (inserter, aggregate, aggregate_file_path, "pom test");
105
106 ObjectId aggregateId = commit (inserter, aggregate, "created aggregate");
107
108 result = createBranch(aggregateId, "aggregate");
109
110 Assert.assertEquals(Result.NEW, result);
111
112 inserter.flush();
113
114
115 GitTreeProcessor treeProcessor = new GitTreeProcessor(repo);
116
117 GitTreeData fusedAggregate = treeProcessor.extractExistingTreeDataFromCommit(aggregateId);
118
119 fusedAggregate.resetDirtyFlag();
120
121 String fusedAPath = "branch1/src/main/resources/fusedA.txt";
122 storeFile(inserter, fusedAggregate, fusedAPath, "fusedA content");
123
124 String fusedBPath = "branch2/src/main/resources/fusedB.txt";
125 storeFile(inserter, fusedAggregate, fusedBPath, "fusedB content");
126
127
128
129 ObjectId originalAggregateId = aggregateId;
130
131 aggregateId = commit (inserter, fusedAggregate, "fusion commit to the aggregate");
132
133
134
135
136 checkTrees (originalAggregateId, aggregateId);
137
138 result = createBranch(aggregateId, "aggregate");
139
140 Assert.assertEquals(Result.FORCED, result);
141
142
143 ObjectReader objectReader = repo.newObjectReader();
144 RevWalk rw = new RevWalk(objectReader);
145
146 TreeWalk tw = new TreeWalk (objectReader);
147
148 tw.setRecursive(true);
149
150 ExternalModuleInfo branch1Externals = new ExternalModuleInfo("branch1", "branch1");
151 ExternalModuleInfo branch2Externals = new ExternalModuleInfo("branch2", "branch2");
152
153 Map<String, ObjectId>results = ExternalModuleUtils.splitFusedTree(objectReader, inserter, rw, aggregateId, Arrays.asList(new ExternalModuleInfo[] {branch1Externals, branch2Externals}));
154
155 Assert.assertEquals(true, results.containsKey("branch1"));
156
157 tw.addTree(results.get("branch1"));
158
159 Assert.assertEquals(true, findPath(tw, fusedAPath.substring("branch1/".length())));
160 Assert.assertEquals(false, findPath(tw, fusedBPath.substring("branch1/".length())));
161
162 Assert.assertEquals(true, results.containsKey("branch2"));
163
164 tw.reset(results.get("branch2"));
165
166 Assert.assertEquals(true, findPath(tw, fusedBPath.substring("branch2/".length())));
167 Assert.assertEquals(false, findPath(tw, fusedAPath.substring("branch2/".length())));
168
169 tw.reset(results.get("remainder"));
170
171 Assert.assertEquals(true, findPath(tw, "src/main/java/org/kuali/student/enrollment/pom.xml"));
172 Assert.assertEquals(false, findPath(tw, "branch1"));
173 Assert.assertEquals(false, findPath(tw, "branch2"));
174
175 rw.release();
176
177 objectReader.release();
178
179 inserter.release();
180
181 }
182
183
184
185
186 private void checkTrees(ObjectId originalAggregateId, ObjectId aggregateId) throws MissingObjectException, IncorrectObjectTypeException, IOException {
187
188 RevWalk rw = new RevWalk(repo);
189
190 RevCommit originalAggregateCommit = rw.parseCommit(originalAggregateId);
191
192 RevCommit aggregateCommit = rw.parseCommit(aggregateId);
193
194 TreeWalk tw = new TreeWalk(repo);
195
196 tw.addTree(originalAggregateCommit.getTree().getId());
197 tw.addTree(aggregateCommit.getTree().getId());
198
199 tw.setRecursive(false);
200
201 while (tw.next()) {
202
203 FileMode originalMode = tw.getFileMode(0);
204
205 FileMode fileMode = tw.getFileMode(1);
206
207 if (originalMode.equals(FileMode.TYPE_MISSING) || fileMode.equals(FileMode.TYPE_MISSING))
208 continue;
209
210 String name = tw.getNameString();
211
212 ObjectId originalObjectId = tw.getObjectId(0);
213 ObjectId currentObjectId = tw.getObjectId(1);
214
215 Assert.assertTrue(originalObjectId + " is not equals to " + currentObjectId + " for " + name, originalObjectId.equals(currentObjectId));
216
217 }
218
219 tw.release();
220
221 rw.release();
222 }
223
224 @Test
225 public void testFusion() throws IOException {
226
227 ObjectInserter inserter = repo.newObjectInserter();
228
229
230 GitTreeData branch1 = new GitTreeData(new DummyGitTreeNodeInitializer());
231
232 String branch1FilePath = "src/main/java/org/kuali/student/enrollment/test.txt";
233 storeFile (inserter, branch1, branch1FilePath, "test");
234
235 ObjectId b1Id = commit (inserter, branch1, "created branch1");
236
237 Result result = createBranch(b1Id, "branch1");
238
239 Assert.assertEquals(Result.NEW, result);
240
241 inserter.flush();
242
243
244 GitTreeData branch2 = new GitTreeData(new DummyGitTreeNodeInitializer());
245
246 String branch2FilePath = branch1FilePath;
247
248 storeFile (inserter, branch2, branch2FilePath, "test");
249
250 ObjectId b2Id = commit (inserter, branch2, "created branch2");
251
252 result = createBranch(b2Id, "branch2");
253
254 Assert.assertEquals(Result.NEW, result);
255
256 inserter.flush();
257
258
259 GitTreeData aggregate = new GitTreeData(new DummyGitTreeNodeInitializer());
260
261 String aggregate_file_path = "src/main/java/org/kuali/student/enrollment/pom.xml";
262 storeFile (inserter, aggregate, aggregate_file_path, "pom test");
263
264 ObjectId aggregateId = commit (inserter, aggregate, "created aggregate");
265
266 result = createBranch(aggregateId, "aggregate");
267
268 Assert.assertEquals(Result.NEW, result);
269
270 inserter.flush();
271
272 ExternalModuleInfo branch1Externals = new ExternalModuleInfo("branch1", "branch1", b1Id);
273 ExternalModuleInfo branch2Externals = new ExternalModuleInfo("branch2", "branch2", b2Id);
274
275
276 ObjectReader objectReader = repo.newObjectReader();
277 RevWalk rw = new RevWalk(objectReader);
278
279 RevCommit aggregateCommit = rw.parseCommit(aggregateId);
280
281 AnyObjectId fusedTreeId = ExternalModuleUtils.createFusedTree(objectReader, inserter, rw, aggregateCommit, Arrays.asList(new ExternalModuleInfo[] {branch1Externals, branch2Externals}));
282
283 TreeWalk tw = new TreeWalk (objectReader);
284
285 tw.setRecursive(true);
286
287 tw.addTree(fusedTreeId);
288
289 Assert.assertEquals(true, findPath (tw, "branch1/" + branch1FilePath));
290
291 tw.reset(fusedTreeId);
292
293 Assert.assertEquals(true, findPath (tw, "branch2/" + branch1FilePath));
294
295 tw.reset(fusedTreeId);
296
297 tw.setFilter(PathFilter.create(aggregate_file_path));
298
299 Assert.assertEquals(true, findPath (tw, aggregate_file_path));
300
301 tw.release();
302
303 rw.release();
304
305 objectReader.release();
306
307 }
308
309 private boolean findPath(TreeWalk tw, String targetPath) throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException, IOException {
310
311 while (tw.next()) {
312
313 String candidatePath = tw.getPathString();
314
315 if (candidatePath.equals(targetPath))
316 return true;
317 }
318 return false;
319 }
320 }