public void TryUnregisterRepo_RemovesRegisteredRepos()
        {
            MockFileSystem     fileSystem = new MockFileSystem(new MockDirectory(Path.GetDirectoryName(this.registryFolderPath), null, null));
            ScalarRepoRegistry registry   = new ScalarRepoRegistry(
                new MockTracer(),
                fileSystem,
                this.registryFolderPath);

            List <ScalarRepoRegistration> registrationsPart1 = new List <ScalarRepoRegistration>
            {
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "Repo1"), "testUser"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "MoreRepos", "Repo1"), "user2"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos2", "Repo1"), "testUser")
            };

            List <ScalarRepoRegistration> registrationsPart2 = new List <ScalarRepoRegistration>
            {
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "Repo2"), "testUser"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "MoreRepos", "Repo2"), "user2"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos3", "Repo1"), "ThirdUser"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos3", "Repo2"), "ThirdUser")
            };

            this.RegisterRepos(registry, registrationsPart1.Concat(registrationsPart2));
            this.RegistryShouldContainRegistrations(registry, registrationsPart1.Concat(registrationsPart2));
            this.UnregisterRepos(registry, registrationsPart2);
            this.RegistryShouldContainRegistrations(registry, registrationsPart1);
        }
        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"));
        }
        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 TryUnregisterRepo_FailsIfRegistryDirectoryMissing()
        {
            MockFileSystem     fileSystem = new MockFileSystem(new MockDirectory(Path.GetDirectoryName(this.registryFolderPath), null, null));
            ScalarRepoRegistry registry   = new ScalarRepoRegistry(
                new MockTracer(),
                fileSystem,
                this.registryFolderPath);

            fileSystem.DirectoryExists(this.registryFolderPath).ShouldBeFalse();
            registry.TryUnregisterRepo(Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "Repo1"), out string errorMessage).ShouldBeFalse();
            errorMessage.ShouldNotBeNullOrEmpty();
            fileSystem.DirectoryExists(this.registryFolderPath).ShouldBeFalse();
        }
        public void TryUnregisterRepo_FailsForUnregisteredRepo()
        {
            MockFileSystem     fileSystem = new MockFileSystem(new MockDirectory(Path.GetDirectoryName(this.registryFolderPath), null, null));
            ScalarRepoRegistry registry   = new ScalarRepoRegistry(
                new MockTracer(),
                fileSystem,
                this.registryFolderPath);

            List <ScalarRepoRegistration> registrations = new List <ScalarRepoRegistration>
            {
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "Repo1"), "testUser")
            };

            this.RegisterRepos(registry, registrations);
            registry.TryUnregisterRepo(Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "Repo2"), out string errorMessage).ShouldBeFalse();
            errorMessage.ShouldNotBeNullOrEmpty();
            this.RegistryShouldContainRegistrations(registry, registrations);
        }
        public void TryRegisterRepo_CreatesMissingRegistryDirectory()
        {
            MockFileSystem     fileSystem = new MockFileSystem(new MockDirectory(Path.GetDirectoryName(this.registryFolderPath), null, null));
            ScalarRepoRegistry registry   = new ScalarRepoRegistry(
                new MockTracer(),
                fileSystem,
                this.registryFolderPath);

            List <ScalarRepoRegistration> registrations = new List <ScalarRepoRegistration>
            {
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "Repo1"), "testUser")
            };

            fileSystem.DirectoryExists(this.registryFolderPath).ShouldBeFalse();
            this.RegisterRepos(registry, registrations);
            fileSystem.DirectoryExists(this.registryFolderPath).ShouldBeTrue("Registering a repo should have created the missing registry directory");

            this.RegistryShouldContainRegistrations(registry, registrations);
        }
        public void TryRegisterRepo_FailsIfMissingRegistryDirectoryCantBeCreated()
        {
            Mock <PhysicalFileSystem> mockFileSystem = new Mock <PhysicalFileSystem>(MockBehavior.Strict);

            mockFileSystem.Setup(fileSystem => fileSystem.DirectoryExists(this.registryFolderPath)).Returns(false);
            mockFileSystem.Setup(fileSystem => fileSystem.CreateDirectory(this.registryFolderPath)).Throws(new UnauthorizedAccessException());

            ScalarRepoRegistry registry = new ScalarRepoRegistry(
                new MockTracer(),
                mockFileSystem.Object,
                this.registryFolderPath);

            string testRepoRoot = Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "Repo1");
            string testUserId   = "testUser";

            registry.TryRegisterRepo(testRepoRoot, testUserId, out string errorMessage).ShouldBeFalse();
            errorMessage.ShouldNotBeNullOrEmpty();

            mockFileSystem.VerifyAll();
        }
        public void TryUnregisterRepo_FailsIfDeleteFails()
        {
            string repoPath             = Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "Repo1");
            string registrationFilePath = Path.Combine(this.registryFolderPath, ScalarRepoRegistry.GetRepoRootSha(repoPath) + ".repo");

            Mock <PhysicalFileSystem> mockFileSystem = new Mock <PhysicalFileSystem>(MockBehavior.Strict);

            mockFileSystem.Setup(fileSystem => fileSystem.FileExists(registrationFilePath)).Returns(true);
            mockFileSystem.Setup(fileSystem => fileSystem.DeleteFile(registrationFilePath)).Throws(new UnauthorizedAccessException());

            ScalarRepoRegistry registry = new ScalarRepoRegistry(
                new MockTracer(),
                mockFileSystem.Object,
                this.registryFolderPath);

            registry.TryUnregisterRepo(repoPath, out string errorMessage).ShouldBeFalse();
            errorMessage.ShouldNotBeNullOrEmpty();

            mockFileSystem.VerifyAll();
        }
        public void TryRegisterRepo_UpdatesUsersForExistingRegistrations()
        {
            MockFileSystem     fileSystem = new MockFileSystem(new MockDirectory(Path.GetDirectoryName(this.registryFolderPath), null, null));
            ScalarRepoRegistry registry   = new ScalarRepoRegistry(
                new MockTracer(),
                fileSystem,
                this.registryFolderPath);

            List <ScalarRepoRegistration> registrationsPart1 = new List <ScalarRepoRegistration>
            {
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "Repo1"), "testUser"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "MoreRepos", "Repo1"), "user2"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos2", "Repo1"), "testUser")
            };

            List <ScalarRepoRegistration> registrationsPart2 = new List <ScalarRepoRegistration>
            {
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos", "Repo2"), "testUser"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "MoreRepos", "Repo2"), "user2"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos3", "Repo1"), "ThirdUser"),
                new ScalarRepoRegistration(Path.Combine(MockFileSystem.GetMockRoot(), "Repos3", "Repo2"), "ThirdUser")
            };

            this.RegisterRepos(registry, registrationsPart1.Concat(registrationsPart2));
            this.RegistryShouldContainRegistrations(registry, registrationsPart1.Concat(registrationsPart2));

            // Update the users on some registrations
            foreach (ScalarRepoRegistration registration in registrationsPart2)
            {
                registration.UserId = $"UPDATED_{registration.UserId}";
            }

            // Just register the updates
            this.RegisterRepos(registry, registrationsPart2);

            // The unchanged + updated entries should be present
            this.RegistryShouldContainRegistrations(registry, registrationsPart1.Concat(registrationsPart2));
        }
        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"));
        }