public void MergeSamePropertyConflict(IObjectRepositoryLoader loader, ObjectRepository sut, Page page, Signature signature, string message, Func <RepositoryDescription, IComputeTreeChanges> computeTreeChangesFactory)
        {
            // master:    A---C---D
            //             \     /
            // newBranch:   B---'

            // Arrange
            var repositoryDescription = RepositoryFixture.GetRepositoryDescription();

            sut.SaveInNewRepository(signature, message, repositoryDescription); // A

            // Act
            sut.Branch("newBranch");
            var updateName = page.With(p => p.Name == "modified name");

            sut.Commit(updateName.Repository, signature, message); // B
            sut.Checkout("master");
            var updateNameOther = page.With(p => p.Name == "yet again modified name");
            var commitC         = sut.Commit(updateNameOther.Repository, signature, message); // C
            var loaded          = loader.LoadFrom <ObjectRepository>(RepositoryFixture.GetRepositoryDescription());
            var merge           = loaded.Merge("newBranch");
            var chunk           = merge.ModifiedChunks.Single();

            chunk.Resolve(JToken.FromObject("merged name"));
            var mergeCommit = merge.Apply(signature); // D

            // Assert
            var changes = computeTreeChangesFactory(RepositoryFixture.GetRepositoryDescription())
                          .Compare(commitC, mergeCommit);

            Assert.That(changes, Has.Count.EqualTo(1));
            Assert.That(changes[0].Status, Is.EqualTo(ChangeKind.Modified));
            Assert.That(changes[0].Old.Name, Is.EqualTo("yet again modified name"));
            Assert.That(changes[0].New.Name, Is.EqualTo("merged name"));
        }
        public void MergeFileDeletionChange(IObjectRepositoryLoader loader, ObjectRepository sut, Page page, Signature signature, string message, Func <RepositoryDescription, IComputeTreeChanges> computeTreeChangesFactory)
        {
            // master:    A---C---D
            //             \     /
            // newBranch:   B---'

            // Arrange
            var repositoryDescription = RepositoryFixture.GetRepositoryDescription();

            sut.SaveInNewRepository(signature, message, repositoryDescription); // A

            // Act
            sut.Branch("newBranch");
            var updateName = page.With(p => p.Fields.Delete(page.Fields[1]));

            sut.Commit(updateName.Repository, signature, message); // B
            sut.Checkout("master");
            var updateDescription = page.With(p => p.Description == "modified description");
            var commitC           = sut.Commit(updateDescription.Repository, signature, message); // C
            var loaded            = loader.LoadFrom <ObjectRepository>(RepositoryFixture.GetRepositoryDescription());
            var mergeCommit       = loaded.Merge("newBranch").Apply(signature);                   // D

            // Assert
            var changes = computeTreeChangesFactory(RepositoryFixture.GetRepositoryDescription())
                          .Compare(commitC, mergeCommit);

            Assert.That(changes, Has.Count.EqualTo(1));
            Assert.That(changes[0].Status, Is.EqualTo(ChangeKind.Deleted));
            Assert.That(changes[0].Old.Id, Is.EqualTo(page.Fields[1].Id));
        }
Beispiel #3
0
        public void CloneRepository(IObjectRepositoryLoader loader)
        {
            // Act
            var loaded = loader.Clone <ObjectRepository>(RepositoryFixture.SmallRepositoryPath, RepositoryFixture.GetRepositoryDescription());

            // Assert
            Assert.That(loaded.Applications, Has.Count.EqualTo(2));
        }
Beispiel #4
0
        public void LoadLinkField(IObjectRepositoryLoader loader, ObjectRepository sut, LinkField linkField, Signature signature, string message, InMemoryBackend inMemoryBackend)
        {
            // Act
            sut.SaveInNewRepository(signature, message, RepositoryFixture.GetRepositoryDescription(inMemoryBackend));
            var loaded          = loader.LoadFrom <ObjectRepository>(RepositoryFixture.GetRepositoryDescription(inMemoryBackend));
            var loadedLinkField = (LinkField)loaded.GetFromGitPath(linkField.GetFolderPath());

            // Assert
            Assert.That(loadedLinkField.PageLink.Link.Id, Is.EqualTo(linkField.PageLink.Link.Id));
        }
Beispiel #5
0
        public ComputeTreeChanges(IObjectRepositoryContainer container, RepositoryDescription repositoryDescription,
                                  IModelDataAccessorProvider modelDataProvider, IObjectRepositoryLoader objectRepositoryLoader,
                                  IRepositoryProvider repositoryProvider, ILogger <ComputeTreeChanges> logger)
        {
            _container             = container ?? throw new ArgumentNullException(nameof(container));
            _repositoryDescription = repositoryDescription ?? throw new ArgumentNullException(nameof(repositoryDescription));

            _modelDataProvider      = modelDataProvider ?? throw new ArgumentNullException(nameof(modelDataProvider));
            _objectRepositoryLoader = objectRepositoryLoader ?? throw new ArgumentNullException(nameof(objectRepositoryLoader));
            _repositoryProvider     = repositoryProvider ?? throw new ArgumentNullException(nameof(repositoryProvider));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }
Beispiel #6
0
        public void LoadLargeRepository(IObjectRepositoryLoader loader)
        {
            // Arrange
            var stopwatch = Stopwatch.StartNew();

            // Act
            loader.LoadFrom <ObjectRepository>(RepositoryFixture.BenchmarkRepositoryDescription);

            // Assert
            // Child loading is lazy so root load time should be really short
            Assert.That(stopwatch.Elapsed, Is.LessThan(TimeSpan.FromMilliseconds(300)));
        }
Beispiel #7
0
        public void CreateAndLoadRepository(IObjectRepositoryLoader loader, ObjectRepository sut, Signature signature, string message, InMemoryBackend inMemoryBackend)
        {
            // Act
            sut.SaveInNewRepository(signature, message, RepositoryFixture.GetRepositoryDescription(inMemoryBackend));
            var loaded = loader.LoadFrom <ObjectRepository>(RepositoryFixture.GetRepositoryDescription(inMemoryBackend));

            // Assert
            PAssert.IsTrue(AreFunctionnally.Equivalent <ObjectRepository>(() => sut == loaded));
            foreach (var apps in sut.Applications.OrderBy(v => v.Id).Zip(loaded.Applications.OrderBy(v => v.Id), (a, b) => new { source = a, desctination = b }))
            {
                PAssert.IsTrue(AreFunctionnally.Equivalent <Application>(() => apps.source == apps.desctination));
            }
        }
Beispiel #8
0
        public void SearchInLargeRepository(IObjectRepositoryLoader loader)
        {
            // Arrange
            var sut       = loader.LoadFrom <ObjectRepository>(RepositoryFixture.BenchmarkRepositoryDescription);
            var stopwatch = Stopwatch.StartNew();

            // Act
            sut.Flatten().LastOrDefault(o => o.Children.Any()); // Dummy search

            // Assert
            // Child loading is lazy so root load time should be really short
            Assert.That(stopwatch.Elapsed, Is.LessThan(TimeSpan.FromMinutes(1)));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ComputeTreeChanges"/> class.
        /// </summary>
        /// <param name="serviceProvider">The service provider.</param>
        /// <param name="repositoryDescription">The repository description.</param>
        /// <exception cref="ArgumentNullException">serviceProvider</exception>
        public ComputeTreeChanges(IServiceProvider serviceProvider, RepositoryDescription repositoryDescription)
        {
            if (serviceProvider == null)
            {
                throw new ArgumentNullException(nameof(serviceProvider));
            }

            _modelDataProvider = serviceProvider.GetRequiredService<IModelDataAccessorProvider>();
            _objectRepositoryLoader = serviceProvider.GetRequiredService<IObjectRepositoryLoader>();
            _repositoryProvider = serviceProvider.GetRequiredService<IRepositoryProvider>();

            _repositoryDescription = repositoryDescription ?? throw new ArgumentNullException(nameof(repositoryDescription));
        }
        public ObjectRepositoryRebase(IObjectRepository repository, ObjectId rebaseCommitId, string branchName,
                                      IObjectRepositoryLoader repositoryLoader, MigrationScaffolderFactory migrationScaffolderFactory,
                                      RebaseProcessor.Factory rebaseProcessorFactory)
        {
            Repository     = repository ?? throw new ArgumentNullException(nameof(repository));
            HeadCommitId   = repository.CommitId ?? throw new GitObjectDbException("Repository instance is not linked to any commit.");
            RebaseCommitId = rebaseCommitId ?? throw new ArgumentNullException(nameof(rebaseCommitId));
            BranchName     = branchName ?? throw new ArgumentNullException(nameof(branchName));

            _repositoryLoader           = repositoryLoader ?? throw new ArgumentNullException(nameof(repositoryLoader));
            _migrationScaffolderFactory = migrationScaffolderFactory ?? throw new ArgumentNullException(nameof(migrationScaffolderFactory));
            _rebaseProcessorFactory     = rebaseProcessorFactory ?? throw new ArgumentNullException(nameof(rebaseProcessorFactory));

            Initialize();
        }
Beispiel #11
0
        public void ComputeChangesInLargeRepository(IObjectRepositoryLoader loader, Func <RepositoryDescription, IComputeTreeChanges> computeTreeChangesFactory)
        {
            // Arrange
            var sut           = loader.LoadFrom <ObjectRepository>(RepositoryFixture.BenchmarkRepositoryDescription);
            var fieldToModify = sut
                                .Applications.PickRandom()
                                .Pages.PickRandom()
                                .Fields.PickRandom();
            var computeTreeChanges = computeTreeChangesFactory(RepositoryFixture.BenchmarkRepositoryDescription);
            var stopwatch          = Stopwatch.StartNew();

            // Act
            var modifiedField = fieldToModify.With(f => f.Name == "modified");

            computeTreeChanges.Compare(sut, modifiedField.Repository);

            // Assert
            // Child loading is lazy so root load time should be really short
            Assert.That(stopwatch.Elapsed, Is.LessThan(TimeSpan.FromMilliseconds(300)));
        }
        public void MergeSamePropertyDetectsConflicts(IObjectRepositoryLoader loader, ObjectRepository sut, Page page, Signature signature, string message)
        {
            // master:    A---C---D
            //             \     /
            // newBranch:   B---'

            // Arrange
            var repositoryDescription = RepositoryFixture.GetRepositoryDescription();

            sut.SaveInNewRepository(signature, message, repositoryDescription); // A

            // Act
            sut.Branch("newBranch");
            var updateName = page.With(p => p.Name == "modified name");

            sut.Commit(updateName.Repository, signature, message); // B
            sut.Checkout("master");
            var updateNameOther = page.With(p => p.Name == "yet again modified name");

            sut.Commit(updateNameOther.Repository, signature, message); // C
            var loaded = loader.LoadFrom <ObjectRepository>(RepositoryFixture.GetRepositoryDescription());

            Assert.Throws <RemainingConflictsException>(() => loaded.Merge("newBranch").Apply(signature));
        }
Beispiel #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ObjectRepositoryContainer{TRepository}"/> class.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="repositoryLoader">The repository loader.</param>
        /// <param name="computeTreeChangesFactory">The <see cref="IComputeTreeChanges"/> factory.</param>
        /// <param name="objectRepositoryMergeFactory">The <see cref="IObjectRepositoryMerge"/> factory.</param>
        /// <param name="objectRepositoryRebaseFactory">The <see cref="IObjectRepositoryRebase"/> factory.</param>
        /// <param name="objectRepositoryCherryPickFactory">The <see cref="IObjectRepositoryCherryPick"/> factory.</param>
        /// <param name="repositoryProvider">The repository provider.</param>
        /// <param name="hooks">The hooks.</param>
        /// <param name="serializerFactory">The <see cref="IObjectRepositorySerializer"/> factory.</param>
        /// <param name="logger">The logger.</param>
        public ObjectRepositoryContainer(string path,
                                         IObjectRepositoryLoader repositoryLoader, ComputeTreeChangesFactory computeTreeChangesFactory,
                                         ObjectRepositoryMergeFactory objectRepositoryMergeFactory, ObjectRepositoryRebaseFactory objectRepositoryRebaseFactory,
                                         ObjectRepositoryCherryPickFactory objectRepositoryCherryPickFactory,
                                         IRepositoryProvider repositoryProvider, GitHooks hooks,
                                         ObjectRepositorySerializerFactory serializerFactory, ILogger <ObjectRepositoryContainer> logger)
        {
            _repositoryLoader                  = repositoryLoader ?? throw new ArgumentNullException(nameof(repositoryLoader));
            _computeTreeChangesFactory         = computeTreeChangesFactory ?? throw new ArgumentNullException(nameof(computeTreeChangesFactory));
            _objectRepositoryMergeFactory      = objectRepositoryMergeFactory ?? throw new ArgumentNullException(nameof(objectRepositoryMergeFactory));
            _objectRepositoryRebaseFactory     = objectRepositoryRebaseFactory ?? throw new ArgumentNullException(nameof(objectRepositoryRebaseFactory));
            _objectRepositoryCherryPickFactory = objectRepositoryCherryPickFactory ?? throw new ArgumentNullException(nameof(objectRepositoryCherryPickFactory));
            _repositoryProvider                = repositoryProvider ?? throw new ArgumentNullException(nameof(repositoryProvider));
            _hooks             = hooks ?? throw new ArgumentNullException(nameof(hooks));
            _serializerFactory = serializerFactory ?? throw new ArgumentNullException(nameof(serializerFactory));
            _logger            = logger ?? throw new ArgumentNullException(nameof(logger));

            Path = path ?? throw new ArgumentNullException(nameof(path));
            Directory.CreateDirectory(path);

            Repositories = LoadRepositories();

            _logger.ContainerCreated(path);
        }
Beispiel #14
0
        public void ComputeChangesInLargeRepository(IObjectRepositoryContainer <ObjectRepository> container, IObjectRepositoryLoader loader, ComputeTreeChangesFactory computeTreeChangesFactory)
        {
            // Arrange
            var sut           = loader.LoadFrom(container, RepositoryFixture.BenchmarkRepositoryDescription);
            var fieldToModify = sut.Flatten().OfType <Field>().First(
                f => f.Content.MatchOrDefault(matchLink: l => true));
            var computeTreeChanges = computeTreeChangesFactory(container, RepositoryFixture.BenchmarkRepositoryDescription);
            var stopwatch          = Stopwatch.StartNew();

            // Act
            var modifiedField = sut.With(fieldToModify, f => f.Name, "modified");

            computeTreeChanges.Compare(sut, modifiedField.Repository);

            // Assert
            // Child loading is lazy so root load time should be really short
            Assert.That(stopwatch.Elapsed, Is.LessThan(TimeSpan.FromMilliseconds(300)));
        }
        public void MergeTwoDifferentPropertiesWithMigrationChanged(IFixture fixture, IObjectRepositoryLoader loader, ObjectRepository sut, Page page, Signature signature, string message)
        {
            // master:    A-----D-----E---F
            //             \         /   /
            //              \   ,---'   /
            //               \ /   x   /
            // newBranch:     B---C---' (B contains a non-idempotent migration)

            // Arrange
            var repositoryDescription = RepositoryFixture.GetRepositoryDescription();

            sut.SaveInNewRepository(signature, message, repositoryDescription); // A

            // B, C
            sut.Branch("newBranch");
            var updatedInstance = sut.With(i => i.Migrations.Add(fixture.Create <Migration>()));

            sut.Commit(updatedInstance.Repository, signature, message); // B
            var loaded     = loader.LoadFrom <ObjectRepository>(RepositoryFixture.GetRepositoryDescription());
            var updateName = loaded.Applications[1].Pages[1].With(p => p.Name == "modified name");

            loaded.Commit(updateName.Repository, signature, message); // C

            // D
            sut.Checkout("master");
            var updateDescription = page.With(p => p.Description == "modified description");

            sut.Commit(updateDescription.Repository, signature, message); // D
            loaded = loader.LoadFrom <ObjectRepository>(RepositoryFixture.GetRepositoryDescription());

            // E
            var mergeStep1 = loaded.Merge("newBranch");

            Assert.That(mergeStep1.IsPartialMerge, Is.True);
            mergeStep1.Apply(signature); // E

            // F
            loaded = loader.LoadFrom <ObjectRepository>(RepositoryFixture.GetRepositoryDescription());
            var mergeStep2 = loaded.Merge("newBranch");

            Assert.That(mergeStep2.IsPartialMerge, Is.False);
            mergeStep2.Apply(signature); // F
        }
Beispiel #16
0
        public void FullLoadInLargeRepository(IObjectRepositoryContainer <ObjectRepository> container, IObjectRepositoryLoader loader)
        {
            // Arrange
            var sut       = loader.LoadFrom(container, RepositoryFixture.BenchmarkRepositoryDescription);
            var stopwatch = Stopwatch.StartNew();

            // Act
            var result = sut.Flatten().Last();

            stopwatch.Stop();
            Console.WriteLine($"Full load total duration: {stopwatch.Elapsed}");

            // Assert
            Assert.That(result, Is.Not.Null);
            Assert.That(stopwatch.Elapsed, Is.LessThan(TimeSpan.FromSeconds(30)));
        }
Beispiel #17
0
        public void SearchInLargeRepository(IObjectRepositorySearch search, IObjectRepositoryContainer <ObjectRepository> container, IObjectRepositoryLoader loader)
        {
            // Arrange
            var sut       = loader.LoadFrom(container, RepositoryFixture.BenchmarkRepositoryDescription);
            var page      = sut.Applications.PickRandom().Pages.PickRandom();
            var stopwatch = Stopwatch.StartNew();

            // Act
            var result = search.Grep(sut, page.Id.ToString());

            stopwatch.Stop();
            Console.WriteLine($"Grep total duration: {stopwatch.Elapsed}");

            // Assert
            Assert.That(result, Is.Not.Empty);
            Assert.That(stopwatch.Elapsed, Is.LessThan(TimeSpan.FromSeconds(2)));
        }
Beispiel #18
0
        public void SearchInLargeRepositoryUsingIndex(IObjectRepositoryContainer <ObjectRepository> container, IObjectRepositoryLoader loader)
        {
            // Arrange
            var sut            = loader.LoadFrom(container, RepositoryFixture.BenchmarkRepositoryDescription);
            var referencedPage = File.ReadAllText("Assets\\Benchmark.ReferencedPage.txt").Trim();
            var index          = sut.Indexes.Single(i => i is LinkFieldReferrerIndex);
            var stopwatch      = Stopwatch.StartNew();

            // Act
            var result = index[referencedPage].ToList();

            stopwatch.Stop();
            Console.WriteLine($"Grep total duration: {stopwatch.Elapsed}");

            // Assert
            Assert.That(result, Is.Not.Empty);
            Assert.That(stopwatch.Elapsed, Is.LessThan(TimeSpan.FromMilliseconds(300)));
        }
Beispiel #19
0
        public void SearchInLargeRepositoryUsingLightDbBackend(IObjectRepositorySearch search, IObjectRepositoryContainer <ObjectRepository> container, IObjectRepositoryLoader loader)
        {
            // Arrange
            var           dbFile  = Path.Combine(RepositoryFixture.BenchmarkRepositoryDescription.Path, "lite.db");
            LiteDbBackend backend = default;
            var           repositoryDescription = RepositoryFixture.BenchmarkRepositoryDescription
                                                  .WithBackend(() => backend = new LiteDbBackend($"filename={dbFile}; journal=false"));
            var sut = loader.LoadFrom(container, repositoryDescription);

            sut.Execute(r => r.ObjectDatabase.CopyAllBlobs(backend));
            var page      = sut.Applications.PickRandom().Pages.PickRandom();
            var stopwatch = Stopwatch.StartNew();

            // Act
            var result = search.Grep(sut, page.Id.ToString());

            stopwatch.Stop();
            Console.WriteLine($"Grep total duration: {stopwatch.Elapsed}");

            // Assert
            Assert.That(result, Is.Not.Empty);
            Assert.That(stopwatch.Elapsed, Is.LessThan(TimeSpan.FromSeconds(5)));
        }