package de.hub.srcrepo;
import static de.hub.srcrepo.RepositoryModelUtil.getImportMetaData;
import static de.hub.srcrepo.RepositoryModelUtil.getMetaData;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.gmt.modisco.java.emf.JavaPackage;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import org.eclipse.jgit.treewalk.EmptyTreeIterator;
import org.eclipse.jgit.util.io.DisabledOutputStream;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.google.common.collect.Lists;
import de.hub.srcrepo.ISourceControlSystem.SourceControlException;
import de.hub.srcrepo.repositorymodel.RepositoryMetaData;
import de.hub.srcrepo.repositorymodel.RepositoryModel;
import de.hub.srcrepo.repositorymodel.RepositoryModelFactory;
import de.hub.srcrepo.repositorymodel.RepositoryModelPackage;
import de.hub.srcrepo.repositorymodel.Rev;
public class MoDiscoGitImportTest {
public enum TestModelKind { GIT, JAVA };
public final static URI testJavaModelURI = URI.createURI("testdata/models/example.java.xmi");
public final static URI testGitModelURI = URI.createURI("testdata/models/example.git.xmi");
public final static File workingCopy = new File(SrcRepoTestSuite.workingCopiesPrefix + "srcrepo.example.git");
private static boolean isStandalone = false;
protected URI getTestModelURI(TestModelKind kind) {
if (kind == TestModelKind.GIT) {
return testGitModelURI;
} else {
return testJavaModelURI;
}
}
protected File getWorkingCopy() {
return workingCopy;
}
protected boolean onlyCloneIfNecessary() {
return true;
}
protected String getCloneURL() {
return "git://github.com/markus1978/srcrepo.example.git";
}
@BeforeClass
public static void standaloneSrcRepo() {
if (SrcRepoActivator.INSTANCE == null) {
SrcRepoActivator.standalone();
isStandalone = true;
}
}
@Before
public void initialize() {
EPackage.Registry.INSTANCE.put(RepositoryModelPackage.eINSTANCE.getNsURI(), RepositoryModelPackage.eINSTANCE);
EPackage.Registry.INSTANCE.put(EcorePackage.eINSTANCE.getNsURI(), EcorePackage.eINSTANCE);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("gitmodel", new XMIResourceFactoryImpl());
}
@Test
public void testClone() {
try {
GitSourceControlSystem scs = new GitSourceControlSystem();
scs.createWorkingCopy(getWorkingCopy(), getCloneURL(), onlyCloneIfNecessary());
scs.close();
} catch (SourceControlException e) {
e.printStackTrace();
Assert.fail("Exception " + e.getClass() + ": " + e.getMessage());
}
}
protected RepositoryModel openRepositoryModel(TestModelKind kind, boolean dropExisting) {
ResourceSet rs = new ResourceSetImpl();
Resource resource = null;
if (new File(getTestModelURI(kind).toFileString()).exists()) {
resource = rs.getResource(getTestModelURI(kind), true);
if (dropExisting) {
resource.getContents().clear();
RepositoryModel repositoryModel = RepositoryModelFactory.eINSTANCE.createRepositoryModel();
resource.getContents().add(repositoryModel);
}
} else {
resource = rs.createResource(getTestModelURI(kind));
RepositoryModel repositoryModel = RepositoryModelFactory.eINSTANCE.createRepositoryModel();
resource.getContents().add(repositoryModel);
}
return (RepositoryModel)resource.getContents().get(0);
}
protected void closeRepositoryModel(TestModelKind kind, RepositoryModel model) {
try {
model.eResource().save(null);
} catch (IOException e) {
e.printStackTrace();
Assert.fail("Exception " + e.getClass() + ": " + e.getMessage());
}
}
protected GitSourceControlSystem openGitSrouceControlSystem() {
GitSourceControlSystem scs = new GitSourceControlSystem();
try {
scs.createWorkingCopy(getWorkingCopy(), getCloneURL(), true);
} catch (SourceControlException e) {
e.printStackTrace();
Assert.fail("Exception " + e.getClass() + ": " + e.getMessage());
}
return scs;
}
protected void importRepositoryModelFromGit(RepositoryModel repositoryModel) {
try {
GitSourceControlSystem scs = openGitSrouceControlSystem();
scs.importRevisions(repositoryModel);
scs.close();
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Exception " + e.getClass() + ": " + e.getMessage());
}
}
protected void importJavaFromModisco(RepositoryModel repositoryModel) {
if (!isStandalone) {
try {
importRepositoryModelFromGit(repositoryModel);
GitSourceControlSystem scs = openGitSrouceControlSystem();
IRepositoryModelVisitor visitor = createModiscoRepositoryModelImportVisitor(scs, repositoryModel);
RepositoryModelTraversal.traverse(repositoryModel, visitor);
visitor.close(repositoryModel);
scs.close();
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Exception " + e.getClass() + ": " + e.getMessage());
}
}
}
protected void assertMetaData(RepositoryModel repositoryModel) {
RepositoryMetaData metaData = getMetaData(repositoryModel);
Assert.assertNotNull(metaData.getOrigin());
Assert.assertNotNull(metaData.getNewestRev());
Assert.assertNotNull(metaData.getOldestRev());
Assert.assertTrue(metaData.getNewestRev().getTime() > metaData.getOldestRev().getTime());
Assert.assertNotNull(getImportMetaData(repositoryModel));
Assert.assertNotNull(getImportMetaData(repositoryModel).getStatsAsJSON());
Assert.assertEquals(16, metaData.getRevCount());
Assert.assertEquals(19, metaData.getCuCount());
Assert.assertEquals(1, metaData.getCusWithErrors());
}
@Test
public void gitImportTest() {
RepositoryModel repositoryModel = openRepositoryModel(TestModelKind.GIT, true);
importRepositoryModelFromGit(repositoryModel);
assertRepositoryModel(repositoryModel, 0);
closeRepositoryModel(TestModelKind.GIT, repositoryModel);
}
@Test
public void modiscoImportTest() {
// run import
RepositoryModel repositoryModel = openRepositoryModel(TestModelKind.JAVA, true);
importJavaFromModisco(repositoryModel);
closeRepositoryModel(TestModelKind.JAVA, repositoryModel);
// assert results
repositoryModel = openRepositoryModel(TestModelKind.JAVA, false);
assertMetaData(repositoryModel);
assertRepositoryModel(repositoryModel, 0);
closeRepositoryModel(TestModelKind.JAVA, repositoryModel);
}
protected Collection<String> assertRepositoryModel(RepositoryModel repositoryModel, int minimumNumberOfRevs) {
Assert.assertNotNull(repositoryModel);
// revs are unique
Collection<String> revNames = new HashSet<String>();
Collection<Rev> revs = new HashSet<Rev>();
for(Rev rev: repositoryModel.getAllRevs()) {
Assert.assertTrue(revNames.add(rev.getName()));
Assert.assertTrue(revs.add(rev));
}
// all refs point to stored revs
for(de.hub.srcrepo.repositorymodel.Ref ref: repositoryModel.getAllRefs()) {
Assert.assertTrue(revNames.contains(ref.getReferencedCommit().getName()));
Assert.assertTrue(revs.contains(ref.getReferencedCommit()));
}
Assert.assertTrue(repositoryModel.getAllRevs().size() >= minimumNumberOfRevs);
int count = 0;
TreeIterator<EObject> iterator = repositoryModel.eAllContents();
while(iterator.hasNext()) {
iterator.next();
count++;
}
Assert.assertTrue(count > minimumNumberOfRevs*2);
// assert example branch and merge
RepositoryModelTraversal.traverse(repositoryModel, new EmptyRepositoryModelVisitor() {
@Override
public void onMerge(Rev commonMergedRev, Rev lastBranchRev) {
super.onMerge(commonMergedRev, lastBranchRev);
List<String> merges = Lists.newArrayList(
"879076c35867e58b2a95e17139729315acbc65fa",
"693dcde1333e7b3d537d529190ffde523642ca72"
);
Assert.assertTrue(merges.contains(lastBranchRev.getName()));
}
@Override
public void onBranch(Rev commonPreviousRev, Rev newBranchRev) {
super.onBranch(commonPreviousRev, newBranchRev);
if (commonPreviousRev != null) {
List<String> branches = Lists.newArrayList(
"879076c35867e58b2a95e17139729315acbc65fa",
"98f56da6e548af6d5660f0c42726a5cde17f23e3"
);
Assert.assertTrue(branches.contains(newBranchRev.getName()));
}
}
});
return revNames;
}
protected IRepositoryModelVisitor createModiscoRepositoryModelImportVisitor(
GitSourceControlSystem scs, RepositoryModel repositoryModel) {
MoDiscoRepositoryModelImportVisitor visitor = new MoDiscoRepositoryModelImportVisitor(scs, repositoryModel, JavaPackage.eINSTANCE);
return visitor;
}
@Test
public void logTest() throws Exception {
File file = new File("example.git");
Git git = Git.init().setDirectory(file).call();
RevWalk rw = new RevWalk(git.getRepository());
DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);
df.setRepository(git.getRepository());
df.setDiffComparator(RawTextComparator.DEFAULT);
df.setDetectRenames(true);
for (Ref ref: git.getRepository().getAllRefs().values()) {
try {
System.out.println("# " + ref.getName() + " peeled:" + ref.isPeeled() + " symbolic:" + ref.isSymbolic() + " id:" + rw.parseAny(ref.getObjectId()).getName());
} catch (Exception e) {
e.printStackTrace();
}
if (!ref.isSymbolic()) {
RevObject object = null;
try {
object = rw.parseAny(ref.getObjectId());
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Exception " + e.getClass() + ": " + e.getMessage());
}
if (object.getType() == Constants.OBJ_COMMIT) {
RevCommit commit = (RevCommit)object;
System.out.println("# " + commit.getFullMessage() + " id:" + commit.getName());
List<DiffEntry> diffs = null;
if (commit.getParentCount() > 0) {
RevCommit parent = commit.getParent(0);
try {
diffs = df.scan(parent.getTree(), commit.getTree());
} catch (IOException e) {
e.printStackTrace();
Assert.fail("Exception " + e.getClass() + ": " + e.getMessage());
}
} else {
try {
diffs = df.scan(new EmptyTreeIterator(), new CanonicalTreeParser(null, rw.getObjectReader(), commit.getTree()));
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Exception " + e.getClass() + ": " + e.getMessage());
}
}
for (DiffEntry diff : diffs) {
System.out.println(
"changeType=" + diff.getChangeType().name() +
" newMode=" + diff.getNewMode().getBits() +
" newPath=" + diff.getNewPath() +
" id=" + commit.getName());
}
}
}
}
df.close();
rw.close();
}
}