using System; using System.Collections; using System.Collections.Generic; using System.Text; using NUnit.Framework; using Codice.Test; namespace cmtest { internal class RepositoryChecker { internal RepositoryChecker(string plasticWkPath, string gitWkPath, string wkserverName) { mPlasticWkPath = plasticWkPath; mGitWkPath = gitWkPath; mServerName = wkserverName; } public void CheckFullRepository() { CheckBranches(); CheckTags(); CheckChangesets(); CheckMergeLinks(); } public void CheckMergeLinks() { List plasticMergeLinks = MetadataChecker.GetListOfMergeLinks(mPlasticWkPath); Dictionary> mergeLinks = new Dictionary>(); foreach (Merge plasticMergeLink in plasticMergeLinks) { IList ids; if (!mergeLinks.TryGetValue(plasticMergeLink.dstId, out ids)) { ids = new List(); mergeLinks[plasticMergeLink.dstId] = ids; } ids.Add(GitHelper.GetGitEquivalentChangeset(plasticMergeLink.srcId, mPlasticWkPath)); } CheckParentsFromDstMergeLink(mergeLinks); } public void CheckChangesets() { List plasticChangesets = MetadataChecker.GetListOfChangesets(mPlasticWkPath); foreach (Cs plasticChangeset in plasticChangesets) { CheckData(plasticChangeset.Id); MetadataChecker.Check(plasticChangeset, mPlasticWkPath, mGitWkPath); } } public void CheckBranches() { List branches = MetadataChecker.GetListOfBranches(mPlasticWkPath); // check branch heads for (int i = branches.Count - 1; i >= 0; i--) { string attribute = GitHelper.GetGitAttribute(branches[i].Id, mPlasticWkPath); string[] fields = attribute.Split(':'); string refName = fields[0]; long csetId = long.Parse(fields[1]); if (csetId == -1 && branches[i].Name.StartsWith("/tag-")) { // it's a tag branch, skippe it! branches.RemoveAt(i); continue; } Assert.AreEqual(branches[i].Changeset, csetId, "The branch is out of sync"); string foreignRev = GitHelper.GetGitEquivalentChangeset(csetId, mPlasticWkPath); string gitSha = GitHelper.GetHeadCommit(refName, mGitWkPath); Assert.AreEqual(gitSha, foreignRev, "The branch is out of sync"); } // check all branches are sync Assert.AreEqual(branches.Count, GitHelper.GetBranches(mGitWkPath).Count, "There are branches that are not synchronized."); } private void CheckBranchHeads() { List branches = MetadataChecker.GetListOfBranches(mPlasticWkPath); foreach (Branch branch in branches) { string attribute = GitHelper.GetGitAttribute(branch.Id, mPlasticWkPath); string[] fields = attribute.Split(':'); string refName = fields[0]; long csetId = long.Parse(fields[1]); Assert.AreEqual(branch.Changeset, csetId, "The branch is out of sync"); string foreignRev = GitHelper.GetGitEquivalentChangeset(csetId, mPlasticWkPath); string gitSha = GitHelper.GetReferenceCommit(refName, mGitWkPath); Assert.AreEqual(gitSha, foreignRev, "The branch is out of sync"); } } private void CheckParentsFromDstMergeLink(Dictionary> mergeLinks) { string sha = null; IList gitMergeLinks = null; foreach (long dstId in mergeLinks.Keys) { sha = GitHelper.GetGitEquivalentChangeset(dstId, mPlasticWkPath); gitMergeLinks = GitHelper.GetMergeLinks(sha, mGitWkPath); CollectionAssert.AreEquivalent(mergeLinks[dstId], gitMergeLinks); } } public void CheckFullRepositoryFromDate(DateTime dateTime) { List plasticChangesets = MetadataChecker.GetListOfChangesetsFromDate(mPlasticWkPath, dateTime); foreach (Cs plasticChangeset in plasticChangesets) { CheckData(plasticChangeset.Id); MetadataChecker.Check(plasticChangeset, mPlasticWkPath, mGitWkPath); } } private void CheckData(long plasticChangeset) { string sha = GitHelper.GetGitEquivalentChangeset(plasticChangeset, mPlasticWkPath); if (sha == null) NUnit.Framework.Assert.Fail("The changeset cs:{0} has not a git mapping", plasticChangeset); // update plastic changeset CmdRunner.ExecuteCommand( string.Format("cm update . --changeset={0} -wks={1}", plasticChangeset, mServerName), mPlasticWkPath); // update git changeset GitHelper.Switch(sha, mGitWkPath); // compare workspace contents CompareWks(mPlasticWkPath, mGitWkPath); } private IList GetBranches() { string cmdres = CmdRunner.ExecuteCommandWithStringResult(string.Format( "cm find branches on repository '{0}' --format={{name}} --nototal -wks={1}", "imported", mServerName), mPlasticWkPath); return ResultParser.GetListResults(cmdres, false); } internal static void CompareWks(string plasticwk, string gitWk) { FolderComparator comparator = new FolderComparator( plasticwk, gitWk, new string[] { Config.PLASTIC_WK_DIR, ".git" }, new string[] { ".private." }); IList result = comparator.Compare(); if (result != null && result.Count > 0) { StringBuilder builder = new StringBuilder(); builder.AppendLine("Differences comparing Plastic and Git workspaces!!!!!!"); foreach (FolderComparationResult folderDiff in result) { builder.AppendLine( string.Format("{0} ({1})-> {2}", folderDiff.ItemName, folderDiff.Type.ToString(), folderDiff.DifferenceMsg)); } throw new Exception(builder.ToString()); } } string mPlasticWkPath; string mGitWkPath; string mServerName; } }