public void Action_WithOneDeletedEntry_ShouldNotCountThatDeletedEntryOnSecondRun() { // Setup var lfProj = _lfProj; sutFdoToMongo.Run(lfProj); Guid entryGuid = Guid.Parse(TestEntryGuidStr); LfLexEntry entry = _conn.GetLfLexEntryByGuid(entryGuid); entry.IsDeleted = true; _conn.UpdateMockLfLexEntry(entry); // Exercise sutMongoToFdo.Run(lfProj); // Verify Assert.That(_counts.Added, Is.EqualTo(0)); Assert.That(_counts.Modified, Is.EqualTo(0)); Assert.That(_counts.Deleted, Is.EqualTo(1)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge: 1 entry deleted")); // Exercise again sutMongoToFdo.Run(lfProj); // Verify zero on second run Assert.That(_counts.Added, Is.EqualTo(0)); Assert.That(_counts.Modified, Is.EqualTo(0)); Assert.That(_counts.Deleted, Is.EqualTo(0)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge S/R")); }
public void Action_WithTwoDeletedEntries_ShouldCountTwoDeleted() { // Setup var lfProj = _lfProj; sutFdoToMongo.Run(lfProj); Guid entryGuid = Guid.Parse(TestEntryGuidStr); LfLexEntry entry = _conn.GetLfLexEntryByGuid(entryGuid); entry.IsDeleted = true; _conn.UpdateMockLfLexEntry(entry); Guid kenGuid = Guid.Parse(KenEntryGuidStr); entry = _conn.GetLfLexEntryByGuid(kenGuid); entry.IsDeleted = true; _conn.UpdateMockLfLexEntry(entry); // Exercise sutMongoToFdo.Run(lfProj); // Verify Assert.That(_counts.Added, Is.EqualTo(0)); Assert.That(_counts.Modified, Is.EqualTo(0)); Assert.That(_counts.Deleted, Is.EqualTo(2)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge: 2 entries deleted")); }
public void Action_WithOneModifiedEntry_ShouldCountOneModified() { // Setup var lfProj = _lfProj; sutFdoToMongo.Run(lfProj); Guid entryGuid = Guid.Parse(TestEntryGuidStr); LfLexEntry entry = _conn.GetLfLexEntryByGuid(entryGuid); FdoCache cache = lfProj.FieldWorksProject.Cache; string vernacularWS = cache.LanguageProject.DefaultVernacularWritingSystem.Id; string changedLexeme = "modified lexeme for this test"; entry.Lexeme = LfMultiText.FromSingleStringMapping(vernacularWS, changedLexeme); entry.AuthorInfo = new LfAuthorInfo(); entry.AuthorInfo.ModifiedDate = DateTime.UtcNow; _conn.UpdateMockLfLexEntry(entry); // Exercise sutMongoToFdo.Run(lfProj); // Verify Assert.That(_counts.Added, Is.EqualTo(0)); Assert.That(_counts.Modified, Is.EqualTo(1)); Assert.That(_counts.Deleted, Is.EqualTo(0)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge: 1 entry modified")); }
public void Action_WithOneNewEntry_ShouldCountOneAdded() { // Setup var lfProj = _lfProj; LfLexEntry newEntry = new LfLexEntry(); newEntry.Guid = Guid.NewGuid(); FdoCache cache = lfProj.FieldWorksProject.Cache; string vernacularWS = cache.LanguageProject.DefaultVernacularWritingSystem.Id; string newLexeme = "new lexeme for this test"; newEntry.Lexeme = LfMultiText.FromSingleStringMapping(vernacularWS, newLexeme); newEntry.AuthorInfo = new LfAuthorInfo(); newEntry.AuthorInfo.CreatedDate = DateTime.UtcNow; newEntry.AuthorInfo.ModifiedDate = newEntry.AuthorInfo.CreatedDate; _conn.UpdateMockLfLexEntry(newEntry); // Exercise sutMongoToFdo.Run(lfProj); // Verify Assert.That(_counts.Added, Is.EqualTo(1)); Assert.That(_counts.Modified, Is.EqualTo(0)); Assert.That(_counts.Deleted, Is.EqualTo(0)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge: 1 entry added")); }
public void Action_RunTwiceWithOneNewEntryEachTime_ShouldCountTwoAddedInTotal() { // Setup var lfProj = _lfProj; LfLexEntry newEntry = new LfLexEntry(); newEntry.Guid = Guid.NewGuid(); LcmCache cache = lfProj.FieldWorksProject.Cache; string vernacularWS = cache.LanguageProject.DefaultVernacularWritingSystem.Id; string newLexeme = "new lexeme for this test"; newEntry.Lexeme = LfMultiText.FromSingleStringMapping(vernacularWS, newLexeme); newEntry.AuthorInfo = new LfAuthorInfo(); newEntry.AuthorInfo.CreatedDate = DateTime.UtcNow; newEntry.AuthorInfo.ModifiedDate = newEntry.AuthorInfo.CreatedDate; _conn.UpdateMockLfLexEntry(newEntry); // Exercise SutMongoToLcm.Run(lfProj); // Verify Assert.That(_counts.Added, Is.EqualTo(1)); Assert.That(_counts.Modified, Is.EqualTo(0)); Assert.That(_counts.Deleted, Is.EqualTo(0)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge: 1 entry added")); // Setup second run newEntry = new LfLexEntry(); newEntry.Guid = Guid.NewGuid(); newLexeme = "second new lexeme for this test"; newEntry.Lexeme = LfMultiText.FromSingleStringMapping(vernacularWS, newLexeme); newEntry.AuthorInfo = new LfAuthorInfo(); newEntry.AuthorInfo.CreatedDate = DateTime.UtcNow; newEntry.AuthorInfo.ModifiedDate = newEntry.AuthorInfo.CreatedDate; _conn.UpdateMockLfLexEntry(newEntry); // Exercise SutMongoToLcm.Run(lfProj); // Verify Assert.That(_counts.Added, Is.EqualTo(1)); // Modified and Deleted shouldn't have changed, but check Added first // since that's the main point of this test Assert.That(_counts.Modified, Is.EqualTo(0)); Assert.That(_counts.Deleted, Is.EqualTo(0)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge: 1 entry added")); }
public void Action_RunTwiceWithTheSameEntryModifiedEachTime_ShouldCountTwoModifiedInTotal() { // Setup var lfProj = _lfProj; sutFdoToMongo.Run(lfProj); Guid entryGuid = Guid.Parse(TestEntryGuidStr); LfLexEntry entry = _conn.GetLfLexEntryByGuid(entryGuid); FdoCache cache = lfProj.FieldWorksProject.Cache; string vernacularWS = cache.LanguageProject.DefaultVernacularWritingSystem.Id; string changedLexeme = "modified lexeme for this test"; entry.Lexeme = LfMultiText.FromSingleStringMapping(vernacularWS, changedLexeme); entry.AuthorInfo = new LfAuthorInfo(); entry.AuthorInfo.ModifiedDate = DateTime.UtcNow; _conn.UpdateMockLfLexEntry(entry); // Exercise sutMongoToFdo.Run(lfProj); // Verify Assert.That(_counts.Added, Is.EqualTo(0)); Assert.That(_counts.Modified, Is.EqualTo(1)); Assert.That(_counts.Deleted, Is.EqualTo(0)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge: 1 entry modified")); // Setup second run string changedLexeme2 = "second modified lexeme for this test"; entry.Lexeme = LfMultiText.FromSingleStringMapping(vernacularWS, changedLexeme2); entry.AuthorInfo = new LfAuthorInfo(); entry.AuthorInfo.ModifiedDate = DateTime.UtcNow; _conn.UpdateMockLfLexEntry(entry); // Exercise second run sutMongoToFdo.Run(lfProj); // Verify second run Assert.That(_counts.Modified, Is.EqualTo(1)); // Added and Deleted shouldn't have changed, but check Modified first // since that's the main point of this test Assert.That(_counts.Added, Is.EqualTo(0)); Assert.That(_counts.Deleted, Is.EqualTo(0)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge: 1 entry modified")); }
public void Action_WithNoChangesFromMongo_ShouldCountZeroChanges() { // Setup var lfProj = _lfProj; FdoCache cache = lfProj.FieldWorksProject.Cache; // Exercise sutMongoToFdo.Run(lfProj); // Verify Assert.That(_counts.Added, Is.EqualTo(0)); Assert.That(_counts.Modified, Is.EqualTo(0)); Assert.That(_counts.Deleted, Is.EqualTo(0)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge S/R")); }
public void Action_RunTwiceWithTheSameEntryDeletedEachTime_ShouldCountJustOneDeletedInTotal() { // Setup var lfProj = _lfProj; sutFdoToMongo.Run(lfProj); Guid entryGuid = Guid.Parse(TestEntryGuidStr); LfLexEntry entry = _conn.GetLfLexEntryByGuid(entryGuid); entry.IsDeleted = true; _conn.UpdateMockLfLexEntry(entry); // Exercise sutMongoToFdo.Run(lfProj); // Verify Assert.That(_counts.Added, Is.EqualTo(0)); Assert.That(_counts.Modified, Is.EqualTo(0)); Assert.That(_counts.Deleted, Is.EqualTo(1)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge: 1 entry deleted")); entry = _conn.GetLfLexEntryByGuid(entryGuid); entry.IsDeleted = true; _conn.UpdateMockLfLexEntry(entry); // Exercise second run sutMongoToFdo.Run(lfProj); // Verify second run Assert.That(_counts.Deleted, Is.EqualTo(0)); // Added and Modified shouldn't have changed either, but check Deleted first // since that's the main point of this test Assert.That(_counts.Added, Is.EqualTo(0)); Assert.That(_counts.Modified, Is.EqualTo(0)); Assert.That(LfMergeBridgeServices.FormatCommitMessageForLfMerge(_counts.Added, _counts.Modified, _counts.Deleted), Is.EqualTo("Language Forge S/R")); }
protected override void DoRun(ILfProject project) { using (MainClass.Container.BeginLifetimeScope()) { var transferAction = GetAction(ActionNames.TransferMongoToLcm); transferAction.Run(project); int entriesAdded = 0, entriesModified = 0, entriesDeleted = 0; // Need to (safely) cast to TransferMongoToLcmAction to get the entry counts var transferMongoToLcmAction = transferAction as TransferMongoToLcmAction; if (transferMongoToLcmAction != null) { entriesAdded = transferMongoToLcmAction.EntryCounts.Added; entriesModified = transferMongoToLcmAction.EntryCounts.Modified; entriesDeleted = transferMongoToLcmAction.EntryCounts.Deleted; } Logger.Debug("About to dispose FW project {0}", project.ProjectCode); LanguageForgeProject.DisposeFwProject(project); Logger.Debug("Successfully disposed FW project {0}", project.ProjectCode); Logger.Notice("Syncing"); string commitMessage = LfMergeBridgeServices.FormatCommitMessageForLfMerge(entriesAdded, entriesModified, entriesDeleted); if (commitMessage == null) // Shouldn't happen, but be careful anyway { commitMessage = "Language Forge Send/Receive"; // Desperate fallback } var chorusHelper = MainClass.Container.Resolve <ChorusHelper>(); // Call into LF Bridge to do the work. string syncResult; var options = new Dictionary <string, string> { { "fullPathToProject", project.ProjectDir }, { "fwdataFilename", project.FwDataPath }, { "fdoDataModelVersion", LcmCache.ModelVersion.ToString() }, { "languageDepotRepoName", "Language Depot" }, { "languageDepotRepoUri", chorusHelper.GetSyncUri(project) }, { "commitMessage", commitMessage } }; try { if (!LfMergeBridge.LfMergeBridge.Execute("Language_Forge_Send_Receive", Progress, options, out syncResult)) { Logger.Error(syncResult); return; } } catch (System.FormatException e) { if (e.StackTrace.Contains("System.Int32.Parse")) { ChorusHelper.SetModelVersion(MagicStrings.MinimalModelVersionForNewBranchFormat); return; } else { throw; } } const string cannotCommitCurrentBranch = "Cannot commit to current branch '"; var line = LfMergeBridgeServices.GetLineContaining(syncResult, cannotCommitCurrentBranch); if (!string.IsNullOrEmpty(line)) { var index = line.IndexOf(cannotCommitCurrentBranch, StringComparison.Ordinal); Require.That(index >= 0); var modelVersion = int.Parse(line.Substring(index + cannotCommitCurrentBranch.Length, 7)); if (modelVersion > MagicStrings.MaximalModelVersion) { // Chorus changed model versions to 75#####.xxxxxxx where xxxxxxx is the old-style model version modelVersion = int.Parse(line.Substring(index + cannotCommitCurrentBranch.Length + 8, 7)); } if (modelVersion < MagicStrings.MinimalModelVersion) { SyncResultedInError(project, syncResult, cannotCommitCurrentBranch, ProcessingState.SendReceiveStates.HOLD); Logger.Error("Error during sync of '{0}': " + "clone model version '{1}' less than minimal supported model version '{2}'.", project.ProjectCode, modelVersion, MagicStrings.MinimalModelVersion); return; } ChorusHelper.SetModelVersion(modelVersion); return; } const string pulledHigherModel = "pulled a higher model '"; line = LfMergeBridgeServices.GetLineContaining(syncResult, pulledHigherModel); if (!string.IsNullOrEmpty(line)) { var index = line.IndexOf(pulledHigherModel, StringComparison.Ordinal); Require.That(index >= 0); var modelVersion = int.Parse(line.Substring(index + pulledHigherModel.Length, 7)); ChorusHelper.SetModelVersion(modelVersion); // The .hg branch has a higher model version than the .fwdata file. We allow // data migrations and try again. Logger.Notice("Allow data migration for project '{0}' to migrate to model version '{1}'", project.ProjectCode, modelVersion); FwProject.AllowDataMigration = true; return; } if (SyncResultedInError(project, syncResult, "Cannot create a repository at this point in LF development.", ProcessingState.SendReceiveStates.HOLD) || // REVIEW: should we set the state to HOLD if we don't have previous commits? SyncResultedInError(project, syncResult, "Cannot do first commit.", ProcessingState.SendReceiveStates.HOLD) || SyncResultedInError(project, syncResult, "Sync failure:")) { return; } line = LfMergeBridgeServices.GetLineContaining(syncResult, "No changes from others"); if (!string.IsNullOrEmpty(line)) { Logger.Notice(line); // We still need to transfer back to Mongo to delete any entries marked for deletion } else { // LfMergeBridge has code to detect when we got changes from others. However, // that code never executes because it does a pull before calling synchronizer.SyncNow() // so that syncResults.DidGetChangesFromOthers never gets set. It doesn't // matter to us because we always do a transfer to mongodb. line = LfMergeBridgeServices.GetLineContaining(syncResult, "Received changes from others"); if (string.IsNullOrEmpty(line)) { // Hmm. Bad news. Must have been some kind of problem down there. Logger.Error("Unhandled sync failure. Result we got was: {0}", syncResult); return; } Logger.Notice(line); } IAction transferLcmToMongoAction = GetAction(ActionNames.TransferLcmToMongo); if (transferLcmToMongoAction == null) { Logger.Error("Failed to run TransferLcmToMongo action: GetAction returned null"); return; } transferLcmToMongoAction.Run(project); } }