public void MaintenanceTask_Execute_SkipsRegisteredRepoIfVolumeDoesNotExist()
        {
            MaintenanceTasks.Task task = MaintenanceTasks.Task.PackFiles;

            UserAndSession testUser = new UserAndSession("testUserId", sessionId: 1);

            this.mockRegisteredUserStore.SetupGet(mrus => mrus.RegisteredUser).Returns(testUser);

            string repoPath = Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "repoRoot");

            this.mockRepoRegistry.Setup(reg => reg.GetRegisteredRepos()).Returns(
                new List <ScalarRepoRegistration>
            {
                new ScalarRepoRegistration(repoPath, testUser.UserId)
            });

            this.mockFileSystem.Setup(fs => fs.DirectoryExists(Path.GetPathRoot(repoPath))).Returns(false);

            MaintenanceTaskScheduler.MaintenanceTask maintenanceTask = new MaintenanceTaskScheduler.MaintenanceTask(
                this.mockTracer,
                this.mockFileSystem.Object,
                this.mockVerbRunner.Object,
                this.mockRepoRegistry.Object,
                this.mockRegisteredUserStore.Object,
                task);

            maintenanceTask.Execute();
            this.mockTracer.RelatedEvents.ShouldContain(entry => entry.Contains("SkippedRepoWithMissingVolume"));
        }
        public void MaintenanceTask_Execute_SkipsReposThatDoNotMatchRegisteredUser()
        {
            MaintenanceTasks.Task task = MaintenanceTasks.Task.PackFiles;

            UserAndSession testUser = new UserAndSession("testUserId", sessionId: 1);

            this.mockRegisteredUserStore.SetupGet(mrus => mrus.RegisteredUser).Returns(testUser);

            this.mockRepoRegistry.Setup(reg => reg.GetRegisteredRepos()).Returns(
                new List <ScalarRepoRegistration>
            {
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "repoRoot"), "nonMatchingUser"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "repoRoot2"), "nonMatchingUser2")
            });

            MaintenanceTaskScheduler.MaintenanceTask maintenanceTask = new MaintenanceTaskScheduler.MaintenanceTask(
                this.mockTracer,
                this.mockFileSystem.Object,
                this.mockVerbRunner.Object,
                this.mockRepoRegistry.Object,
                this.mockRegisteredUserStore.Object,
                task);

            maintenanceTask.Execute();
            this.mockTracer.RelatedEvents.ShouldContain(entry => entry.Contains("\"reposInRegistryForUser\":0"));
        }
        /// <summary>
        /// Calls the 'scalar maintenance' verb
        /// </summary>
        /// <param name="task">Maintenance task to run</param>
        /// <param name="repoRoot">Repo to maintain</param>
        /// <param name="sessionId">Ignored</param>
        /// <returns>
        /// true if the maintenance verb succeeded, and false otherwise
        /// </returns>
        /// <remarks>
        /// 'CallMaintenance' should only be called for repos that are owned by
        /// the owner of the current process.
        ///
        /// 'launchctl asuser' *could* be used to launch has an arbitrary user,
        /// however, it is not used because it does not pass back the output/errors
        /// of the maintenance verb correctly.
        ///
        /// On Mac this method:
        ///
        ///   - Is only called by Scalar.Service
        ///   - Is only called for repos owned by the same user that's running Scalar.Service
        ///
        /// And so there is no need to use 'launchctl'.
        /// </remarks>
        public bool CallMaintenance(MaintenanceTasks.Task task, string repoRoot, int sessionId)
        {
            string taskVerbName = MaintenanceTasks.GetVerbTaskName(task);
            string arguments    =
                $"run {taskVerbName} \"{repoRoot}\" --{ScalarConstants.VerbParameters.InternalUseOnly} {this.internalVerbJson}";

            ProcessResult result = this.processLauncher.LaunchProcess(this.scalarBinPath, arguments, repoRoot);

            if (result.ExitCode != 0)
            {
                EventMetadata metadata = new EventMetadata();
                metadata.Add("Area", "ScalarVerbRunner");
                metadata.Add(nameof(this.scalarBinPath), this.scalarBinPath);
                metadata.Add(nameof(arguments), arguments);
                metadata.Add(nameof(repoRoot), repoRoot);
                metadata.Add(nameof(result.ExitCode), result.ExitCode);
                metadata.Add(nameof(result.Output), result.Output);
                metadata.Add(nameof(result.Errors), result.Errors);

                this.tracer.RelatedError(metadata, $"{nameof(this.CallMaintenance)}: Maintenance verb failed");
                return(false);
            }

            return(true);
        }
Beispiel #4
0
 public MaintenanceSchedule(MaintenanceTasks.Task task, TimeSpan dueTime, TimeSpan period, bool ignorePause = false)
 {
     this.Task        = task;
     this.DueTime     = dueTime;
     this.Period      = period;
     this.IgnorePause = ignorePause;
 }
        private bool CallScalarMaintenance(MaintenanceTasks.Task task, string repoRoot, CurrentUser currentUser)
        {
            string taskVerbName = MaintenanceTasks.GetVerbTaskName(task);

            return(currentUser.RunAs(
                       Configuration.Instance.ScalarLocation,
                       $"run {taskVerbName} \"{repoRoot}\" --{ScalarConstants.VerbParameters.InternalUseOnly} {this.internalVerbJson}"));
        }
        public bool CallMaintenance(MaintenanceTasks.Task task, string repoRoot, int sessionId)
        {
            using (CurrentUser currentUser = new CurrentUser(this.tracer, sessionId))
            {
                if (!this.CallScalarMaintenance(task, repoRoot, currentUser))
                {
                    this.tracer.RelatedError($"{nameof(this.CallMaintenance)}: Unable to start the Scalar.exe process.");
                    return(false);
                }
            }

            return(true);
        }
        public void MaintenanceTask_Execute_NoRegisteredUser()
        {
            MaintenanceTasks.Task task = MaintenanceTasks.Task.PackFiles;

            this.mockRegisteredUserStore.SetupGet(mrus => mrus.RegisteredUser).Returns((UserAndSession)null);

            MaintenanceTaskScheduler.MaintenanceTask maintenanceTask = new MaintenanceTaskScheduler.MaintenanceTask(
                this.mockTracer,
                this.mockFileSystem.Object,
                this.mockVerbRunner.Object,
                this.mockRepoRegistry.Object,
                this.mockRegisteredUserStore.Object,
                task);

            maintenanceTask.Execute();
            this.mockTracer.RelatedInfoEvents.ShouldContain(entry => entry.Contains($"Skipping '{task}', no registered user"));
        }
Beispiel #8
0
 public MaintenanceTask(
     ITracer tracer,
     PhysicalFileSystem fileSystem,
     IScalarVerbRunner scalarVerb,
     IScalarRepoRegistry repoRegistry,
     IRegisteredUserStore registeredUserStore,
     MaintenanceTasks.Task task,
     bool ignorePause = true)
 {
     this.tracer              = tracer;
     this.fileSystem          = fileSystem;
     this.scalarVerb          = scalarVerb;
     this.repoRegistry        = repoRegistry;
     this.registeredUserStore = registeredUserStore;
     this.task        = task;
     this.ignorePause = ignorePause;
 }
        public void CallMaintenance_LaunchesVerbUsingCorrectArgs()
        {
            MaintenanceTasks.Task task = MaintenanceTasks.Task.FetchCommitsAndTrees;
            string taskVerbName        = MaintenanceTasks.GetVerbTaskName(task);
            string scalarBinPath       = Path.Combine(this.scalarPlatform.Constants.ScalarBinDirectoryPath, this.scalarPlatform.Constants.ScalarExecutableName);
            string expectedArgs        =
                $"run {taskVerbName} \"{ExpectedActiveRepoPath}\" --{ScalarConstants.VerbParameters.InternalUseOnly} {new InternalVerbParameters(startedByService: true).ToJson()}";

            Mock <MacScalarVerbRunner.ScalarProcessLauncher> procLauncherMock = new Mock <MacScalarVerbRunner.ScalarProcessLauncher>(MockBehavior.Strict, this.tracer);

            procLauncherMock.Setup(mp => mp.LaunchProcess(
                                       scalarBinPath,
                                       expectedArgs,
                                       ExpectedActiveRepoPath))
            .Returns(new ProcessResult(output: string.Empty, errors: string.Empty, exitCode: 0));

            MacScalarVerbRunner verbProcess = new MacScalarVerbRunner(this.tracer, procLauncherMock.Object);

            verbProcess.CallMaintenance(task, ExpectedActiveRepoPath, ExpectedActiveUserId);

            procLauncherMock.VerifyAll();
        }
        public void MaintenanceTask_Execute_CallsRunVerbOnlyForRegisteredRepos()
        {
            MaintenanceTasks.Task task = MaintenanceTasks.Task.PackFiles;

            UserAndSession testUser            = new UserAndSession("testUserId", sessionId: 1);
            UserAndSession secondUser          = new UserAndSession("testUserId2", sessionId: 1);
            string         repoPath1           = Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "repoRoot");
            string         repoPath2           = Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "repoRoot2");
            string         secondUsersRepoPath = Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "secondUsersRepo");

            this.mockRegisteredUserStore.SetupGet(mrus => mrus.RegisteredUser).Returns(testUser);

            this.mockRepoRegistry.Setup(reg => reg.GetRegisteredRepos()).Returns(
                new List <ScalarRepoRegistration>
            {
                new ScalarRepoRegistration(repoPath1, testUser.UserId),
                new ScalarRepoRegistration(secondUsersRepoPath, secondUser.UserId),
                new ScalarRepoRegistration(repoPath2, testUser.UserId)
            });

            // The root volume and repos exist
            this.mockFileSystem.Setup(fs => fs.DirectoryExists(Path.GetPathRoot(repoPath1))).Returns(true);
            this.mockFileSystem.Setup(fs => fs.DirectoryExists(repoPath1)).Returns(true);
            this.mockFileSystem.Setup(fs => fs.DirectoryExists(repoPath2)).Returns(true);

            this.mockVerbRunner.Setup(vr => vr.CallMaintenance(task, repoPath1, testUser.SessionId)).Returns(true);
            this.mockVerbRunner.Setup(vr => vr.CallMaintenance(task, repoPath2, testUser.SessionId)).Returns(true);

            MaintenanceTaskScheduler.MaintenanceTask maintenanceTask = new MaintenanceTaskScheduler.MaintenanceTask(
                this.mockTracer,
                this.mockFileSystem.Object,
                this.mockVerbRunner.Object,
                this.mockRepoRegistry.Object,
                this.mockRegisteredUserStore.Object,
                task);

            maintenanceTask.Execute();
        }
        public void MaintenanceTask_Execute_UnregistersRepoIfMissing()
        {
            MaintenanceTasks.Task task = MaintenanceTasks.Task.PackFiles;

            UserAndSession testUser = new UserAndSession("testUserId", sessionId: 1);

            this.mockRegisteredUserStore.SetupGet(mrus => mrus.RegisteredUser).Returns(testUser);

            string repoPath = Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "repoRoot");

            this.mockRepoRegistry.Setup(reg => reg.GetRegisteredRepos()).Returns(
                new List <ScalarRepoRegistration>
            {
                new ScalarRepoRegistration(repoPath, testUser.UserId)
            });

            // Validate that TryUnregisterRepo will be called for repoPath
            string emptyString = string.Empty;

            this.mockRepoRegistry.Setup(reg => reg.TryUnregisterRepo(repoPath, out emptyString)).Returns(true);

            // The root volume should exist
            this.mockFileSystem.Setup(fs => fs.DirectoryExists(Path.GetPathRoot(repoPath))).Returns(true);

            // The repo itself does not exist
            this.mockFileSystem.Setup(fs => fs.DirectoryExists(repoPath)).Returns(false);

            MaintenanceTaskScheduler.MaintenanceTask maintenanceTask = new MaintenanceTaskScheduler.MaintenanceTask(
                this.mockTracer,
                this.mockFileSystem.Object,
                this.mockVerbRunner.Object,
                this.mockRepoRegistry.Object,
                this.mockRegisteredUserStore.Object,
                task);

            maintenanceTask.Execute();
            this.mockTracer.RelatedEvents.ShouldContain(entry => entry.Contains("RemovedMissingRepo"));
        }