public void Clear()
        {
            SortedFolderEntries sfe = SetupDefaultEntries();

            sfe.Clear();
            sfe.Count.ShouldEqual(0);
        }
        public void EntryNotFound()
        {
            SortedFolderEntries sfe      = SetupDefaultEntries();
            LazyUTF8String      findName = ConstructLazyUTF8String("Anything");

            sfe.TryGetValue(findName, out FolderEntryData folderEntryData).ShouldBeFalse();
            folderEntryData.ShouldBeNull();
        }
Ejemplo n.º 3
0
        public void AddItemAtEnd()
        {
            SortedFolderEntries sfe  = SetupDefaultEntries();
            LazyUTF8String      name = ConstructLazyUTF8String("{{shouldbeattheend");

            sfe.AddFolder(name);
            sfe[defaultFiles.Length + defaultFolders.Length].Name.ShouldEqual(name, "Item added at incorrect index.");
        }
        public void EntryFoundDifferentCase()
        {
            SortedFolderEntries sfe      = SetupDefaultEntries();
            LazyUTF8String      findName = ConstructLazyUTF8String("Folder");

            sfe.TryGetValue(findName, out FolderEntryData folderEntryData).ShouldBeTrue();
            folderEntryData.ShouldNotBeNull();
        }
        public void FoldersShouldBeIncludedWhenSparseFolderDataIsEmpty()
        {
            SortedFolderEntries sfe  = SetupDefaultEntries();
            LazyUTF8String      name = ConstructLazyUTF8String("IsIncludedFalse");

            sfe.GetOrAddFolder(new[] { name }, partIndex: 0, parentIsIncluded: false, rootSparseFolderData: new SparseFolderData());
            ValidateFolder(sfe, name, isIncludedValue: true);
        }
        public void AddItemAtTheBeginning()
        {
            SortedFolderEntries sfe  = SetupDefaultEntries();
            LazyUTF8String      name = ConstructLazyUTF8String("((shouldbeatthestart");

            sfe.AddFile(name, new byte[20]);
            sfe[0].Name.ShouldEqual(name, "Item added at incorrect index.");
        }
        public void AddItemAtEnd()
        {
            SortedFolderEntries sfe  = SetupDefaultEntries();
            LazyUTF8String      name = ConstructLazyUTF8String("{{shouldbeattheend");

            sfe.AddFile(name, new byte[20]);
            sfe[GetDefaultEntriesLength()].Name.ShouldEqual(name, "Item added at incorrect index.");
        }
Ejemplo n.º 8
0
 private static void AddFolders(SortedFolderEntries entries, params string[] names)
 {
     for (int i = 0; i < names.Length; i++)
     {
         LazyUTF8String entryString = ConstructLazyUTF8String(names[i]);
         entries.AddFolder(entryString);
     }
 }
 private static void AddFolders(SortedFolderEntries entries, params string[] names)
 {
     for (int i = 0; i < names.Length; i++)
     {
         LazyUTF8String entryString = ConstructLazyUTF8String(names[i]);
         entries.GetOrAddFolder(new[] { entryString }, partIndex: 0, parentIsIncluded: true, rootSparseFolderData: new SparseFolderData());
         ValidateFolder(entries, entryString, isIncludedValue: true);
     }
 }
        private static SortedFolderEntries SetupDefaultEntries()
        {
            SortedFolderEntries sfe = new SortedFolderEntries();

            AddFiles(sfe, defaultFiles);
            AddFolders(sfe, defaultFolders);
            sfe.Count.ShouldEqual(defaultFiles.Length + defaultFolders.Length);
            return(sfe);
        }
        public void AddFolderWhereParentIncludedIsTrueAndChildIsNotIncluded()
        {
            SortedFolderEntries sfe              = SetupDefaultEntries();
            LazyUTF8String      name             = ConstructLazyUTF8String("ChildNotIncluded");
            SparseFolderData    sparseFolderData = new SparseFolderData();

            sparseFolderData.Children.Add("Child", new SparseFolderData());
            sfe.GetOrAddFolder(new[] { name }, partIndex: 0, parentIsIncluded: true, rootSparseFolderData: sparseFolderData);
            ValidateFolder(sfe, name, isIncludedValue: false);
        }
 private static void AddFiles(SortedFolderEntries entries, params string[] names)
 {
     for (int i = 0; i < names.Length; i++)
     {
         LazyUTF8String entryString = ConstructLazyUTF8String(names[i]);
         entries.AddFile(entryString, new byte[20]);
         entries.TryGetValue(entryString, out FolderEntryData folderEntryData).ShouldBeTrue();
         folderEntryData.ShouldNotBeNull();
         folderEntryData.IsFolder.ShouldBeFalse();
     }
 }
        public void AddFolderBelowTopLevelNotIncluded()
        {
            SortedFolderEntries sfe              = SetupDefaultEntries();
            LazyUTF8String      name             = ConstructLazyUTF8String("Child");
            LazyUTF8String      name2            = ConstructLazyUTF8String("GrandChild");
            SparseFolderData    sparseFolderData = new SparseFolderData();

            sparseFolderData.Children.Add("Child", new SparseFolderData());
            sfe.GetOrAddFolder(new[] { name, name2 }, partIndex: 1, parentIsIncluded: true, rootSparseFolderData: sparseFolderData);
            ValidateFolder(sfe, name2, isIncludedValue: false);
        }
        private static void ValidateFolder(SortedFolderEntries entries, LazyUTF8String entryToValidate, bool isIncludedValue)
        {
            entries.TryGetValue(entryToValidate, out FolderEntryData folderEntryData).ShouldBeTrue();
            folderEntryData.ShouldNotBeNull();
            folderEntryData.IsFolder.ShouldBeTrue();

            FolderData folderData = folderEntryData as FolderData;

            folderData.ShouldNotBeNull();
            folderData.IsIncluded.ShouldEqual(isIncludedValue, "IsIncluded does not match expected value.");
        }
        public void SmallEntries()
        {
            SortedFolderEntries.FreePool();

            SortedFolderEntries.InitializePools(new MockTracer(), indexEntryCount: 0);
            SortedFolderEntries.FilePoolSize().ShouldBeAtLeast(1);
            SortedFolderEntries.FolderPoolSize().ShouldBeAtLeast(1);

            SortedFolderEntries.ResetPool(new MockTracer(), indexEntryCount: 0);
            SortedFolderEntries.FilePoolSize().ShouldBeAtLeast(1);
            SortedFolderEntries.FolderPoolSize().ShouldBeAtLeast(1);
        }
        public void ValidateCaseInsensitiveOrderOfDefaultEntries()
        {
            List <string> allEntries = new List <string>(defaultFiles);

            allEntries.AddRange(defaultFolders);
            allEntries.Sort(CaseInsensitiveStringCompare);
            SortedFolderEntries sfe = SetupDefaultEntries();

            sfe.Count.ShouldEqual(14);
            for (int i = 0; i < allEntries.Count; i++)
            {
                sfe[i].Name.GetString().ShouldEqual(allEntries[i]);
            }
        }
        private static SortedFolderEntries SetupDefaultEntries()
        {
            SortedFolderEntries sfe = new SortedFolderEntries();

            AddFiles(sfe, defaultFiles);
            AddFolders(sfe, defaultFolders);
            if (GVFSPlatform.Instance.Constants.CaseSensitiveFileSystem)
            {
                AddFiles(sfe, caseDifferingFiles);
                AddFolders(sfe, caseDifferingFolders);
            }

            sfe.Count.ShouldEqual(GetDefaultEntriesLength());
            return(sfe);
        }
            /// <summary>
            /// Takes an action on a GitIndexEntry using the index in indexStream
            /// </summary>
            /// <param name="indexStream">Stream for reading a git index file</param>
            /// <param name="entryAction">Action to take on each GitIndexEntry from the index</param>
            /// <returns>
            /// FileSystemTaskResult indicating success or failure of the specified action
            /// </returns>
            /// <remarks>
            /// Only the AddToModifiedFiles method because it updates the modified paths file can result
            /// in TryIndexAction returning a FileSystemTaskResult other than Success.  All other actions result in success (or an exception in the
            /// case of a corrupt index)
            /// </remarks>
            private FileSystemTaskResult ParseIndex(
                ITracer tracer,
                Stream indexStream,
                GitIndexEntry resuableParsedIndexEntry,
                Func <GitIndexEntry, FileSystemTaskResult> entryAction)
            {
                this.indexStream          = indexStream;
                this.indexStream.Position = 0;
                this.ReadNextPage();

                if (this.page[0] != 'D' ||
                    this.page[1] != 'I' ||
                    this.page[2] != 'R' ||
                    this.page[3] != 'C')
                {
                    throw new InvalidDataException("Incorrect magic signature for index: " + string.Join(string.Empty, this.page.Take(4).Select(c => (char)c)));
                }

                this.Skip(4);
                uint indexVersion = this.ReadFromIndexHeader();

                if (indexVersion != 4)
                {
                    throw new InvalidDataException("Unsupported index version: " + indexVersion);
                }

                uint entryCount = this.ReadFromIndexHeader();

                // Don't want to flood the logs on large indexes so only log every 500ms
                const int LoggingTicksThreshold = 5000000;
                long      nextLogTicks          = DateTime.UtcNow.Ticks + LoggingTicksThreshold;

                SortedFolderEntries.InitializePools(tracer, entryCount);
                LazyUTF8String.InitializePools(tracer, entryCount);

                resuableParsedIndexEntry.ClearLastParent();
                int previousPathLength = 0;

                bool parseMode = GVFSPlatform.Instance.FileSystem.SupportsFileMode;
                FileSystemTaskResult result = FileSystemTaskResult.Success;

                for (int i = 0; i < entryCount; i++)
                {
                    if (parseMode)
                    {
                        this.Skip(26);

                        // 4-bit object type
                        //     valid values in binary are 1000(regular file), 1010(symbolic link) and 1110(gitlink)
                        // 3-bit unused
                        // 9-bit unix permission. Only 0755 and 0644 are valid for regular files. (Legacy repos can also contain 664)
                        //     Symbolic links and gitlinks have value 0 in this field.
                        ushort indexFormatTypeAndMode = this.ReadUInt16();

                        FileTypeAndMode typeAndMode = new FileTypeAndMode(indexFormatTypeAndMode);

                        switch (typeAndMode.Type)
                        {
                        case FileType.Regular:
                            if (typeAndMode.Mode != FileMode755 &&
                                typeAndMode.Mode != FileMode644 &&
                                typeAndMode.Mode != FileMode664)
                            {
                                throw new InvalidDataException($"Invalid file mode {typeAndMode.GetModeAsOctalString()} found for regular file in index");
                            }

                            break;

                        case FileType.SymLink:
                        case FileType.GitLink:
                            if (typeAndMode.Mode != 0)
                            {
                                throw new InvalidDataException($"Invalid file mode {typeAndMode.GetModeAsOctalString()} found for link file({typeAndMode.Type:X}) in index");
                            }

                            break;

                        default:
                            throw new InvalidDataException($"Invalid file type {typeAndMode.Type:X} found in index");
                        }

                        resuableParsedIndexEntry.TypeAndMode = typeAndMode;

                        this.Skip(12);
                    }
                    else
                    {
                        this.Skip(40);
                    }

                    this.ReadSha(resuableParsedIndexEntry);

                    ushort flags = this.ReadUInt16();
                    if (flags == 0)
                    {
                        throw new InvalidDataException("Invalid flags found in index");
                    }

                    resuableParsedIndexEntry.MergeState = (MergeStage)((flags >> 12) & 3);
                    bool isExtended = (flags & ExtendedBit) == ExtendedBit;
                    resuableParsedIndexEntry.PathLength = (ushort)(flags & 0xFFF);

                    resuableParsedIndexEntry.SkipWorktree = false;
                    if (isExtended)
                    {
                        ushort extendedFlags = this.ReadUInt16();
                        resuableParsedIndexEntry.SkipWorktree = (extendedFlags & SkipWorktreeBit) == SkipWorktreeBit;
                    }

                    int replaceLength = this.ReadReplaceLength();
                    resuableParsedIndexEntry.ReplaceIndex = previousPathLength - replaceLength;
                    int bytesToRead = resuableParsedIndexEntry.PathLength - resuableParsedIndexEntry.ReplaceIndex + 1;
                    this.ReadPath(resuableParsedIndexEntry, resuableParsedIndexEntry.ReplaceIndex, bytesToRead);
                    previousPathLength = resuableParsedIndexEntry.PathLength;

                    result = entryAction.Invoke(resuableParsedIndexEntry);
                    if (result != FileSystemTaskResult.Success)
                    {
                        return(result);
                    }

                    if (DateTime.UtcNow.Ticks > nextLogTicks)
                    {
                        tracer.RelatedInfo($"{i}/{entryCount} index entries parsed.");
                        nextLogTicks = DateTime.UtcNow.Ticks + LoggingTicksThreshold;
                    }
                }

                tracer.RelatedInfo($"Finished parsing {entryCount} index entries.");
                return(result);
            }
 public void TestSetup()
 {
     LazyUTF8String.ResetPool(new MockTracer(), DefaultIndexEntryCount);
     SortedFolderEntries.ResetPool(new MockTracer(), DefaultIndexEntryCount);
 }
 public void Setup()
 {
     LazyUTF8String.InitializePools(new MockTracer(), DefaultIndexEntryCount);
     SortedFolderEntries.InitializePools(new MockTracer(), DefaultIndexEntryCount);
 }