public void SetModelVersion() { ChorusHelper.SetModelVersion("123456"); var chorusHelper = MainClass.Container.Resolve <ChorusHelper>(); Assert.That(chorusHelper.ModelVersion, Is.EqualTo("123456")); }
/// <summary> /// Ensures a Send/Receive project from Language Depot is properly /// cloned into the WebWork directory for LfMerge.Core. /// A project will be cloned if: /// 1) The LfMerge state file doesn't exist OR /// 2) The current LfMerge state is ProcessingState.SendReceiveStates.CLONING OR /// 3) The project directory is empty /// </summary> /// <param name="project">LF Project.</param> protected override void DoRun(ILfProject project) { try { // Check if an initial clone needs to be performed if (File.Exists(Settings.GetStateFileName(project.ProjectCode)) && project.State.SRState != ProcessingState.SendReceiveStates.CLONING && File.Exists(project.FwDataPath)) { return; } var cloneLocation = project.ProjectDir; if (RepoAlreadyExists(cloneLocation)) { Logger.Notice("Repairing clone of project {0}", project.ProjectCode); } else { Logger.Notice("Initial clone for project {0}", project.ProjectCode); } project.State.SRState = ProcessingState.SendReceiveStates.CLONING; string cloneResult; if (!CloneRepo(project, cloneLocation, out cloneResult)) { Logger.Error(cloneResult); return; } if (CloneResultedInError(project, cloneResult, "clone is not a FLEx project", true, ProcessingState.ErrorCodes.NoFlexProject) || CloneResultedInError(project, cloneResult, "new repository with no commits", true, ProcessingState.ErrorCodes.EmptyProject) || CloneResultedInError(project, cloneResult, "clone has higher model", true, ProcessingState.ErrorCodes.ProjectTooNew) || CloneResultedInError(project, cloneResult, "LfMergeBridge starting S/R handler from directory", false, ProcessingState.ErrorCodes.Unspecified)) { return; } string line = LfMergeBridgeServices.GetLineContaining(cloneResult, "no such branch"); if (!string.IsNullOrEmpty(line)) { const string modelString = "Highest available model '"; var index = line.IndexOf(modelString, StringComparison.Ordinal); if (index < 0) { ReportNoSuchBranchFailure(project, cloneLocation, cloneResult, line, ProcessingState.ErrorCodes.UnspecifiedBranchError); return; } var cloneModelVersion = line.Substring(index + modelString.Length, 7); if (int.Parse(cloneModelVersion) < int.Parse(MagicStrings.MinimalModelVersion)) { ReportNoSuchBranchFailure(project, cloneLocation, cloneResult, line, ProcessingState.ErrorCodes.ProjectTooOld); Logger.Error("Error during initial clone of '{0}': " + "clone model version '{1}' less than minimal supported model version '{2}'.", project.ProjectCode, cloneModelVersion, MagicStrings.MinimalModelVersion); return; } Logger.Info(line); ChorusHelper.SetModelVersion(cloneModelVersion); } else { ChorusHelper.SetModelVersion(FdoCache.ModelVersion); line = LfMergeBridgeServices.GetLineContaining(cloneResult, "new clone created on branch"); Require.That(!string.IsNullOrEmpty(line), "Looks like the clone was not successful, but we didn't get an understandable error"); // verify clone path GetActualClonePath(cloneLocation, line); if (MongoProjectHasUserDataOrHasBeenSynced()) { // If the local Mercurial repo was deleted but the Mongo database is still there, // then there might be data in Mongo that we still need, in which case we should NOT // skip the syncing step. So do nothing, so that we'll fall through to the SYNCING state. } else { InitialTransferToMongoAfterClone(project); Logger.Notice("Initial clone completed; setting state to CLONED"); project.State.SRState = ProcessingState.SendReceiveStates.CLONED; } } } catch (Exception e) { switch (e.GetType().Name) { case "ArgumentOutOfRangeException": if (e.Message == "Cannot update to any branch.") { project.State.SetErrorState(ProcessingState.SendReceiveStates.ERROR, ProcessingState.ErrorCodes.UnspecifiedBranchError, "Error during initial clone of {0}: {1}", project.ProjectCode, e); return; } break; case "RepositoryAuthorizationException": Logger.Error("Initial clone of {0}: authorization exception", project.ProjectCode); project.State.SetErrorState(ProcessingState.SendReceiveStates.ERROR, ProcessingState.ErrorCodes.Unauthorized, "Error during initial clone of {0}: authorization exception from remote repository", project.ProjectCode); return; } Logger.Error("Got {0} exception trying to clone {1}: {2}", e.GetType(), project.ProjectCode, e.Message); throw; } }
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); } }
public void RemoteDataIsForDifferentModelVersion_DifferentVersion() { ChorusHelper.SetModelVersion("7000060"); Assert.That(ChorusHelper.RemoteDataIsForDifferentModelVersion, Is.True); }
public void RemoteDataIsForDifferentModelVersion_SameVersion() { ChorusHelper.SetModelVersion(FdoCache.ModelVersion); Assert.That(ChorusHelper.RemoteDataIsForDifferentModelVersion, Is.False); }