예제 #1
0
        public void EnsureClone_StateFileDoesntExistAndStateNotCloning_ClonesProject()
        {
            // Not a valid real-world scenario, but we test this anyway
            var lfProject  = LanguageForgeProject.Create(_projectCode);
            var projectDir = Path.Combine(_env.Settings.WebWorkDirectory, _projectCode);

            lfProject.State.SRState = ProcessingState.SendReceiveStates.HOLD;
            Assert.That(File.Exists(_env.Settings.GetStateFileName(_projectCode)), Is.False,
                        "State file shouldn't exist");
            Assert.AreNotEqual(lfProject.State.SRState, ProcessingState.SendReceiveStates.CLONING);
            Assert.That(Directory.Exists(Path.Combine(projectDir, ".hg")), Is.False,
                        "Clone of project shouldn't exist");

            // Execute
            new EnsureCloneActionDouble(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection).Run(lfProject);

            // Verify
            Assert.That(lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.CLONED),
                        "State should be CLONED");
            // TestDouble doesn't write state file
            Assert.That(File.Exists(_env.Settings.GetStateFileName(_projectCode)), Is.False,
                        "State file shouldn't exist yet");
            Assert.That(Directory.Exists(Path.Combine(projectDir, ".hg")), Is.True,
                        "Didn't clone project");
        }
예제 #2
0
        public void Setup()
        {
            if (SIL.PlatformUtilities.Platform.IsWindows)
            {
                const string tempPath = @"C:\Tmp";
                Environment.SetEnvironmentVariable("TMP", tempPath);
                Environment.SetEnvironmentVariable("TEMP", tempPath);

                Directory.CreateDirectory(tempPath);
            }

            _env = new TestEnvironment();
            _languageDepotFolder = new TemporaryFolder(TestContext.CurrentContext.Test.Name + Path.GetRandomFileName());
            _lDSettings          = new LfMergeSettingsDouble(_languageDepotFolder.Path);
            Directory.CreateDirectory(_lDSettings.WebWorkDirectory);
            LanguageDepotMock.ProjectFolderPath =
                Path.Combine(_lDSettings.WebWorkDirectory, TestContext.CurrentContext.Test.Name, TestLangProj);
            Directory.CreateDirectory(LanguageDepotMock.ProjectFolderPath);
            _lfProject = LanguageForgeProject.Create(TestLangProj);
            _mongoProjectRecordFactory = MainClass.Container.Resolve <LfMerge.Core.MongoConnector.MongoProjectRecordFactory>() as MongoProjectRecordFactoryDouble;
            // Even though the EnsureCloneActionWithoutMongo class has "WithoutMongo" in the name, the EnsureClone class which it inherits from
            // needs an IMongoConnection argument in the constructor, so we have to create a MongoConnectionDouble that we're not going to use here.
            var _mongoConnection = MainClass.Container.Resolve <IMongoConnection>();

            _EnsureCloneAction       = new EnsureCloneActionWithoutMongo(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection);
            LanguageDepotMock.Server = new MercurialServer(LanguageDepotMock.ProjectFolderPath);
        }
예제 #3
0
        public void Setup()
        {
            _env = new TestEnvironment();
            _env.Settings.CommitWhenDone = true;
            _counts    = MainClass.Container.Resolve <EntryCounts>();
            _lfProject = LanguageForgeProject.Create(testProjectCode);
            TestEnvironment.CopyFwProjectTo(testProjectCode, _env.Settings.WebWorkDirectory);

            // Guids are named for the diffs for the modified test project
            _testEntryGuid        = Guid.Parse(testEntryGuidStr);
            _testCreatedEntryGuid = Guid.Parse(testCreatedEntryGuidStr);
            _testDeletedEntryGuid = Guid.Parse(testDeletedEntryGuidStr);

            _languageDepotFolder = new TemporaryFolder("SyncTestLD" + Path.GetRandomFileName());
            _lDSettings          = new LfMergeSettingsDouble(_languageDepotFolder.Path);
            Directory.CreateDirectory(_lDSettings.WebWorkDirectory);
            LanguageDepotMock.ProjectFolderPath = Path.Combine(_lDSettings.WebWorkDirectory, testProjectCode);

            _mongoConnection = MainClass.Container.Resolve <IMongoConnection>() as MongoConnectionDouble;
            if (_mongoConnection == null)
            {
                throw new AssertionException("Sync tests need a mock MongoConnection that stores data in order to work.");
            }
            _recordFactory = MainClass.Container.Resolve <MongoProjectRecordFactory>() as MongoProjectRecordFactoryDouble;
            if (_recordFactory == null)
            {
                throw new AssertionException("Sync tests need a mock MongoProjectRecordFactory in order to work.");
            }

            _transferFdoToMongo = new TransferFdoToMongoAction(_env.Settings, _env.Logger, _mongoConnection, _recordFactory);
        }
예제 #4
0
        public void GetSyncUri_NameWithSpace()
        {
            var proj         = LanguageForgeProject.Create("test project");
            var chorusHelper = MainClass.Container.Resolve <ChorusHelper>();

            Assert.That(chorusHelper.GetSyncUri(proj),
                        Is.EqualTo("https://*****:*****@hg-public.languagedepot.org/test+project"));
        }
예제 #5
0
 public void SetUpForFdoTests()
 {
     LanguageForgeFolder = new TemporaryFolder("FdoTestFixture");
     env = new TestEnvironment(
         resetLfProjectsDuringCleanup: false,
         languageForgeServerFolder: LanguageForgeFolder
         );
     Settings = new LfMergeSettingsDouble(LanguageForgeFolder.Path);
     TestEnvironment.CopyFwProjectTo(testProjectCode, Settings.FdoDirectorySettings.DefaultProjectsDirectory);
     lfProj = LanguageForgeProject.Create(testProjectCode);
 }
예제 #6
0
        public void State(ActionNames actionName, ProcessingState.SendReceiveStates expectedState)
        {
            // Setup
            var lfProj = LanguageForgeProject.Create("proja");
            var sut    = Action.GetAction(actionName);

            // Exercise
            sut.Run(lfProj);

            // Verify
            Assert.That(ProcessState.SavedStates, Is.EqualTo(new[] { expectedState }));
            Assert.That(lfProj.State.SRState, Is.EqualTo(expectedState));
        }
예제 #7
0
 public void Teardown()
 {
     if (_lfProject != null)
     {
         LanguageForgeProject.DisposeFwProject(_lfProject);
     }
     if (_lDProject != null)
     {
         LanguageDepotMock.DisposeFwProject(_lDProject);
     }
     _languageDepotFolder?.Dispose();
     _env.Dispose();
     _mongoConnection.Reset();
 }
예제 #8
0
 public void Setup()
 {
     MagicStrings.SetMinimalModelVersion(FdoCache.ModelVersion);
     _env = new TestEnvironment();
     _languageDepotFolder = new TemporaryFolder(TestContext.CurrentContext.Test.Name + Path.GetRandomFileName());
     _lDSettings          = new LfMergeSettingsDouble(_languageDepotFolder.Path);
     Directory.CreateDirectory(_lDSettings.WebWorkDirectory);
     LanguageDepotMock.ProjectFolderPath =
         Path.Combine(_lDSettings.WebWorkDirectory, TestLangProj);
     Directory.CreateDirectory(LanguageDepotMock.ProjectFolderPath);
     _lfProject               = LanguageForgeProject.Create(TestLangProj);
     _synchronizeAction       = new SynchronizeAction(_env.Settings, _env.Logger);
     _workDir                 = Directory.GetCurrentDirectory();
     LanguageDepotMock.Server = new MercurialServer(LanguageDepotMock.ProjectFolderPath);
 }
예제 #9
0
        public void Setup()
        {
            _env    = new TestEnvironment(resetLfProjectsDuringCleanup: false);
            _conn   = MainClass.Container.Resolve <IMongoConnection>() as MongoConnectionDouble;
            _counts = MainClass.Container.Resolve <EntryCounts>();
            if (_conn == null)
            {
                throw new AssertionException("LCM tests need a mock MongoConnection that stores data in order to work.");
            }
            _recordFactory = MainClass.Container.Resolve <MongoProjectRecordFactory>() as MongoProjectRecordFactoryDouble;
            if (_recordFactory == null)
            {
                throw new AssertionException("Mongo->Lcm roundtrip tests need a mock MongoProjectRecordFactory in order to work.");
            }

            _lfProj = LcmTestFixture.lfProj;
            _cache  = _lfProj.FieldWorksProject.Cache;
            Assert.That(_cache, Is.Not.Null);
            _servLoc             = new FwServiceLocatorCache(_cache.ServiceLocator);
            _wsEn                = _cache.WritingSystemFactory.GetWsFromStr("en");
            _undoHelper          = new UndoableUnitOfWorkHelper(_cache.ActionHandlerAccessor, "undo", "redo");
            _undoHelper.RollBack = true;

            SutMongoToLcm = new TransferMongoToLcmAction(
                _env.Settings,
                _env.Logger,
                _conn,
                _recordFactory,
                _counts
                );

            SutLcmToMongo = new TransferLcmToMongoAction(
                _env.Settings,
                _env.Logger,
                _conn,
                _recordFactory
                );

            var convertCustomField = new ConvertLcmToMongoCustomField(_cache, _servLoc, _env.Logger);

            _listConverters = new Dictionary <string, ConvertLcmToMongoOptionList>();
            foreach (KeyValuePair <string, ICmPossibilityList> pair in convertCustomField.GetCustomFieldParentLists())
            {
                string             listCode   = pair.Key;
                ICmPossibilityList parentList = pair.Value;
                _listConverters[listCode] = ConvertOptionListFromLcm(_lfProj, listCode, parentList);
            }
        }
예제 #10
0
        public void EnsureClone_OtherException_SetsStateOnHold()
        {
            // for this test we don't want the test double for InternetCloneSettingsModel
            _env.Dispose();
            _env = new TestEnvironment(registerSettingsModelDouble: false);

            // Setup
            var nonExistingProjectCode = Path.GetRandomFileName().ToLowerInvariant();
            var lfProject = LanguageForgeProject.Create(nonExistingProjectCode);

            // Execute/Verify
            Assert.That(() => new EnsureCloneActionDouble(_env.Settings, _env.Logger,
                                                          _mongoProjectRecordFactory, _mongoConnection, false, false).Run(lfProject),
                        Throws.Exception);

            // In the real app the exception gets caught and the status set in Program.cs
        }
예제 #11
0
        public void State_SkipsHoldState(ActionNames actionName)
        {
            // Setup
            var lfProj = LanguageForgeProject.Create("proja");
            var state  = Factory.Deserialize("proja") as ProcessingStateDouble;

            state.SRState = ProcessingState.SendReceiveStates.HOLD;
            state.ResetSavedStates();
            Factory.State = state;
            var sut = Action.GetAction(actionName);

            // Exercise
            sut.Run(lfProj);

            // Verify
            Assert.That(ProcessState.SavedStates, Is.Empty);
        }
예제 #12
0
        public void EnsureClone_ProjectThatHasNeverBeenCloned_RunsInitialClone()
        {
            // Setup
            var projectDir = Path.Combine(_env.Settings.WebWorkDirectory, _projectCode);

            Directory.CreateDirectory(projectDir);
            var lfProject = LanguageForgeProject.Create(_projectCode);
            var action    = new EnsureCloneActionDoubleMockingInitialTransfer(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection);

            Assert.That(action.InitialCloneWasRun, Is.False);

            // Execute
            action.Run(lfProject);

            // Verify
            Assert.That(action.InitialCloneWasRun, Is.True);
        }
예제 #13
0
        public void EnsureClone_NonExistingProject_SetsStateOnError()
        {
            // for this test we don't want the test double for InternetCloneSettingsModel
            _env.Dispose();
            _env = new TestEnvironment(registerSettingsModelDouble: false);

            // Setup
            var nonExistingProjectCode = Path.GetRandomFileName().ToLowerInvariant();
            var lfProject = LanguageForgeProject.Create(nonExistingProjectCode);

            // Execute
            Assert.That(() => new EnsureCloneActionDouble(_env.Settings, _env.Logger,
                                                          _mongoProjectRecordFactory, _mongoConnection, false).Run(lfProject),
                        Throws.Nothing);

            // Verify
            Assert.That(lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.ERROR));
        }
예제 #14
0
        public void EnsureClone_ProjectThatHasAPreviouslyClonedDate_DoesNotRunInitialClone()
        {
            // Setup
            var projectDir = Path.Combine(_env.Settings.WebWorkDirectory, _projectCode);

            Directory.CreateDirectory(projectDir);
            var lfProject = LanguageForgeProject.Create(_projectCode);

            _mongoConnection.SetLastSyncedDate(lfProject, DateTime.UtcNow);
            var action = new EnsureCloneActionDoubleMockingInitialTransfer(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection);

            Assert.That(action.InitialCloneWasRun, Is.False);

            // Execute
            action.Run(lfProject);

            // Verify
            Assert.That(action.InitialCloneWasRun, Is.False);
        }
예제 #15
0
        public void EnsureClone_NotFlexProject_SetsRecoverableError()
        {
            // Setup
            var projectDir = Path.Combine(_env.Settings.WebWorkDirectory, _projectCode);

            Directory.CreateDirectory(projectDir);
            var lfProject = LanguageForgeProject.Create(_projectCode);
            var action    = new EnsureCloneActionDoubleMockErrorCondition(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection,
                                                                          "Clone failure: clone is not a FLEx project: Clone deleted.");

            // Execute
            action.Run(lfProject);

            // Verify
            Assert.That(lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.ERROR));
            Assert.That(lfProject.State.ErrorCode, Is.EqualTo((int)ProcessingState.ErrorCodes.NoFlexProject));
            Assert.That(lfProject.State.ErrorMessage,
                        Is.EqualTo(string.Format("Recoverable error during initial clone of {0}: Clone failure: clone is not a FLEx project: Clone deleted.", _projectCode)));
        }
        public void Teardown()
        {
            // Reset workdir, otherwise NUnit will get confused when it tries to reset the
            // workdir after running the test but the current dir got deleted in the teardown.
            Directory.SetCurrentDirectory(_workDir);

            LanguageForgeProject.DisposeFwProject(_lfProject);

            if (_languageDepotFolder != null)
            {
                _languageDepotFolder.Dispose();
            }
            _env.Dispose();

            if (LanguageDepotMock.Server != null)
            {
                LanguageDepotMock.Server.Stop();
                LanguageDepotMock.Server = null;
            }
        }
예제 #17
0
        public void EnsureClone_ProjectDirExistHgDoesntExist_ClonesProject()
        {
            // Setup
            var projectDir = Path.Combine(_env.Settings.WebWorkDirectory, _projectCode);

            Directory.CreateDirectory(projectDir);
            var lfProject = LanguageForgeProject.Create(_projectCode);

            Assert.That(Directory.Exists(projectDir), Is.True,
                        "Didn't create webwork directory: " + projectDir);
            Assert.That(Directory.Exists(Path.Combine(projectDir, ".hg")), Is.False,
                        "Clone of project shouldn't exist yet");

            // Execute
            new EnsureCloneActionDouble(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection).Run(lfProject);

            // Verify
            Assert.That(Directory.Exists(Path.Combine(projectDir, ".hg")), Is.True,
                        "Didn't clone project");
        }
예제 #18
0
        public void EnsureClone_CloneEmptyRepo_SetsRecoverableError()
        {
            // Setup
            var projectDir = Path.Combine(_env.Settings.WebWorkDirectory, _projectCode);

            Directory.CreateDirectory(projectDir);
            var lfProject = LanguageForgeProject.Create(_projectCode);
            var action    = new EnsureCloneActionDoubleMockErrorCondition(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection,
                                                                          "Clone failure: new repository with no commits. Clone deleted.");

            // Execute
            action.Run(lfProject);

            // Verify
            Assert.That(lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.ERROR));
            Assert.That(lfProject.State.ErrorCode, Is.EqualTo((int)ProcessingState.ErrorCodes.EmptyProject));
            Assert.That(lfProject.State.ErrorMessage,
                        Is.EqualTo(
                            $"Recoverable error during initial clone of {_projectCode}: Clone failure: new repository with no commits. Clone deleted."));
        }
예제 #19
0
        public void EnsureClone_ProjectThatHasPreviousUserData_DoesNotRunInitialClone()
        {
            // Setup
            var projectDir = Path.Combine(_env.Settings.WebWorkDirectory, _projectCode);

            Directory.CreateDirectory(projectDir);
            var lfProject = LanguageForgeProject.Create(_projectCode);
            var data      = new SampleData();

            _mongoConnection.UpdateMockLfLexEntry(data.bsonTestData);
            var action = new EnsureCloneActionDoubleMockingInitialTransfer(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection);

            Assert.That(action.InitialCloneWasRun, Is.False);

            // Execute
            action.Run(lfProject);

            // Verify
            Assert.That(action.InitialCloneWasRun, Is.False);
        }
예제 #20
0
        public void EnsureClone_StateFileExistsStateCloning_CloneProject()
        {
            // Setup
            var lfProject  = LanguageForgeProject.Create(_projectCode);
            var projectDir = Path.Combine(_env.Settings.WebWorkDirectory, _projectCode);

            File.Create(_env.Settings.GetStateFileName(_projectCode));
            lfProject.State.SRState = ProcessingState.SendReceiveStates.CLONING;
            Assert.That(File.Exists(_env.Settings.GetStateFileName(_projectCode)), Is.True,
                        "State file should exist");
            Assert.AreEqual(lfProject.State.SRState, ProcessingState.SendReceiveStates.CLONING);
            Assert.That(Directory.Exists(Path.Combine(projectDir, ".hg")), Is.False,
                        "Clone of project shouldn't exist");

            // Execute
            new EnsureCloneActionDouble(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection).Run(lfProject);

            // Verify
            Assert.That(Directory.Exists(Path.Combine(projectDir, ".hg")), Is.True,
                        "Didn't clone project");
        }
예제 #21
0
        public void Setup()
        {
            _env = new TestEnvironment(resetLfProjectsDuringCleanup: false);
            _conn = MainClass.Container.Resolve<IMongoConnection>() as MongoConnectionDouble;
            if (_conn == null)
                throw new AssertionException("FDO tests need a mock MongoConnection that stores data in order to work.");
            _recordFactory = MainClass.Container.Resolve<MongoProjectRecordFactory>() as MongoProjectRecordFactoryDouble;
            if (_recordFactory == null)
                throw new AssertionException("Mongo->Fdo roundtrip tests need a mock MongoProjectRecordFactory in order to work.");

            _lfProj = FdoTestFixture.lfProj;
            _cache = _lfProj.FieldWorksProject.Cache;
            _wsEn = _cache.WritingSystemFactory.GetWsFromStr("en");
            _undoHelper = new UndoableUnitOfWorkHelper(_cache.ActionHandlerAccessor, "undo", "redo");
            _undoHelper.RollBack = true;

            sutMongoToFdo = new TransferMongoToFdoAction(
                _env.Settings,
                _env.Logger,
                _conn,
                _recordFactory
            );

            sutFdoToMongo = new TransferFdoToMongoAction(
                _env.Settings,
                _env.Logger,
                _conn
            );

            var convertCustomField = new ConvertFdoToMongoCustomField(_cache, _env.Logger);
            _listConverters = new Dictionary<string, ConvertFdoToMongoOptionList>();
            foreach (KeyValuePair<string, ICmPossibilityList> pair in convertCustomField.GetCustomFieldParentLists())
            {
                string listCode = pair.Key;
                ICmPossibilityList parentList = pair.Value;
                _listConverters[listCode] = ConvertOptionListFromFdo(_lfProj, listCode, parentList);
            }
        }
예제 #22
0
        public void EnsureClone_StateFileDoesntExistAndStateCloning_CloneProject()
        {
            // Setup
            var projectCode = TestContext.CurrentContext.Test.Name.ToLowerInvariant();
            var lfProject   = LanguageForgeProject.Create(projectCode);
            var projectDir  = Path.Combine(_env.Settings.WebWorkDirectory, projectCode);

            lfProject.State.SRState = ProcessingState.SendReceiveStates.CLONING;
            Assert.That(File.Exists(_env.Settings.GetStateFileName(_projectCode)), Is.False,
                        "State file shouldn't exist");
            Assert.That(lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.CLONING));
            Assert.That(Directory.Exists(Path.Combine(projectDir, ".hg")), Is.False,
                        "Clone of project shouldn't exist");

            // Execute
            new EnsureCloneActionDouble(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection).Run(lfProject);

            // Verify
            Assert.That(lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.CLONED),
                        "State should be CLONED");
            Assert.That(Directory.Exists(Path.Combine(projectDir, ".hg")), Is.True,
                        "Didn't clone project");
        }
예제 #23
0
        public void EnsureClone_StateFileExistsStateNotCloning_DoesntCloneProject()
        {
            // Setup
            var lfProject  = LanguageForgeProject.Create(_projectCode);
            var projectDir = Path.Combine(_env.Settings.WebWorkDirectory, _projectCode);

            lfProject.State.SRState = ProcessingState.SendReceiveStates.HOLD;
            File.Create(_env.Settings.GetStateFileName(_projectCode));
            Assert.That(File.Exists(_env.Settings.GetStateFileName(_projectCode)), Is.True,
                        "State file should exist");
            Assert.That(lfProject.State.SRState, !Is.EqualTo(ProcessingState.SendReceiveStates.CLONING));
            Assert.That(Directory.Exists(Path.Combine(projectDir, ".hg")), Is.False,
                        "Clone of project shouldn't exist");
            var me = Directory.GetFiles(projectDir, "*.*", SearchOption.AllDirectories).Length == 0;

            Console.WriteLine("{0}", me);

            // Execute
            new EnsureCloneActionDouble(_env.Settings, _env.Logger, _mongoProjectRecordFactory, _mongoConnection).Run(lfProject);

            // Verify
            Assert.That(Directory.Exists(Path.Combine(projectDir, ".hg")), Is.False,
                        "Clone of project shouldn't exist");
        }
예제 #24
0
 public void SetUpForFdoTests()
 {
     LanguageForgeFolder = new TemporaryFolder("FdoTestFixture");
     env = new TestEnvironment(
         resetLfProjectsDuringCleanup: false,
         languageForgeServerFolder: LanguageForgeFolder
     );
     Settings = new LfMergeSettingsDouble(LanguageForgeFolder.Path);
     TestEnvironment.CopyFwProjectTo(testProjectCode, Settings.DefaultProjectsDirectory);
     lfProj = LanguageForgeProject.Create(Settings, testProjectCode);
 }
 public void Setup()
 {
     _env = new TestEnvironment();
     _languageDepotFolder = new TemporaryFolder(TestContext.CurrentContext.Test.Name);
     _lDSettings = new LfMergeSettingsDouble(_languageDepotFolder.Path);
     Directory.CreateDirectory(_lDSettings.WebWorkDirectory);
     SynchronizeActionTests.LDProjectFolderPath =
         Path.Combine(_lDSettings.WebWorkDirectory, TestLangProj);
     Directory.CreateDirectory(SynchronizeActionTests.LDProjectFolderPath);
     _lfProject = LanguageForgeProject.Create(_env.Settings, TestLangProj);
     _synchronizeAction = new SynchronizeAction(_env.Settings, _env.Logger);
     _workDir = Directory.GetCurrentDirectory();
     SynchronizeActionTests.LDServer = new MercurialServer(SynchronizeActionTests.LDProjectFolderPath);
 }
예제 #26
0
        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);
            }
        }
예제 #27
0
 public static void Reset()
 {
     LanguageForgeProject.DisposeProjectCache();
 }
예제 #28
0
파일: Program.cs 프로젝트: sillsdev/LfMerge
 /// <summary>
 /// Clean up anything needed before quitting, e.g. disposing of IDisposable objects.
 /// </summary>
 private static void Cleanup()
 {
     LanguageForgeProject.DisposeProjectCache();
 }
예제 #29
0
파일: Program.cs 프로젝트: sillsdev/LfMerge
        private static string RunAction(string projectCode, ActionNames currentAction)
        {
            LanguageForgeProject project = null;
            var stopwatch = new Stopwatch();

            try
            {
                MainClass.Logger.Notice("ProjectCode {0}", projectCode);
                project = LanguageForgeProject.Create(projectCode);

                project.State.StartTimestamp = CurrentUnixTimestamp();
                stopwatch.Start();

                if (Options.Current.CloneProject)
                {
                    var cloneLocation = project.ProjectDir;
                    if (Directory.Exists(cloneLocation) && !File.Exists(project.FwDataPath))
                    {
                        // If we a .hg directory but no project file it means the previous clone
                        // was not finished, so remove and start over
                        MainClass.Logger.Notice("Cleaning out previous failed clone at {0}", cloneLocation);
                        Directory.Delete(cloneLocation, true);
                        project.State.SRState = ProcessingState.SendReceiveStates.CLONING;
                    }
                }

                var ensureClone = LfMerge.Core.Actions.Action.GetAction(ActionNames.EnsureClone);
                ensureClone.Run(project);

                if (ChorusHelper.RemoteDataIsForDifferentModelVersion)
                {
                    // The repo is for an older model version
                    var chorusHelper = MainClass.Container.Resolve <ChorusHelper>();
                    return(chorusHelper.ModelVersion.ToString());
                }

                if (project.State.SRState != ProcessingState.SendReceiveStates.HOLD &&
                    project.State.SRState != ProcessingState.SendReceiveStates.ERROR &&
                    project.State.SRState != ProcessingState.SendReceiveStates.CLONED)
                {
                    LfMerge.Core.Actions.Action.GetAction(currentAction).Run(project);

                    if (ChorusHelper.RemoteDataIsForDifferentModelVersion)
                    {
                        // The repo is for an older model version
                        var chorusHelper = MainClass.Container.Resolve <ChorusHelper>();
                        return(chorusHelper.ModelVersion.ToString());
                    }
                }
            }
            catch (Exception e)
            {
                MainClass.Logger.Error("Got exception {0}", e.ToString());
                ExceptionLogging.Client.Notify(e);
                if (projectCode == null)
                {
                    MainClass.Logger.Error("Project code was null");
                }

                if (project.State.SRState != ProcessingState.SendReceiveStates.ERROR)
                {
                    MainClass.Logger.Error(string.Format(
                                               "Putting project '{0}' on hold due to unhandled exception: \n{1}",
                                               projectCode, e));
                    if (project != null)
                    {
                        project.State.SetErrorState(ProcessingState.SendReceiveStates.HOLD,
                                                    ProcessingState.ErrorCodes.UnhandledException, string.Format(
                                                        "Putting project '{0}' on hold due to unhandled exception: \n{1}",
                                                        projectCode, e));
                    }
                }
            }
            finally
            {
                stopwatch.Stop();
                if (project != null && project.State != null)
                {
                    project.State.PreviousRunTotalMilliseconds = stopwatch.ElapsedMilliseconds;
                }
                if (project != null && project.State.SRState != ProcessingState.SendReceiveStates.HOLD &&
                    project.State.SRState != ProcessingState.SendReceiveStates.ERROR &&
                    !ChorusHelper.RemoteDataIsForDifferentModelVersion)
                {
                    project.State.SRState = ProcessingState.SendReceiveStates.IDLE;
                }

                // Dispose FDO cache to free memory
                LanguageForgeProject.DisposeFwProject(project);
            }
            return(null);
        }
 public void Setup()
 {
     _env = new TestEnvironment();
     _languageDepotFolder = new TemporaryFolder(TestContext.CurrentContext.Test.Name);
     _lDSettings = new LfMergeSettingsDouble(_languageDepotFolder.Path);
     Directory.CreateDirectory(_lDSettings.WebWorkDirectory);
     SynchronizeActionTests.LDProjectFolderPath =
         Path.Combine(_lDSettings.WebWorkDirectory, TestContext.CurrentContext.Test.Name);
     Directory.CreateDirectory(SynchronizeActionTests.LDProjectFolderPath);
     _lfProject = LanguageForgeProject.Create(_env.Settings,
         TestContext.CurrentContext.Test.Name);
     _EnsureCloneAction = new EnsureCloneActionWithoutMongo(_env.Settings, _env.Logger);
 }