コード例 #1
0
        public Possible <FileChangeTrackingSet.EnumerationResult> TryEnumerateDirectoryAndTrackMembership(
            string path,
            Action <string, FileAttributes> handleEntry)
        {
            Contract.Requires(path != null);
            Contract.Requires(handleEntry != null);

            var possibleFingerprintResult = DirectoryMembershipTrackingFingerprinter.ComputeFingerprint(path, handleEntry);

            if (!possibleFingerprintResult.Succeeded)
            {
                return(possibleFingerprintResult.Failure);
            }

            PathExistence existence = possibleFingerprintResult.Result.PathExistence;
            Possible <FileChangeTrackingSet.ConditionalTrackingResult> trackingResult = new Failure <string>("Tracking membership failed");

            lock (m_lock)
            {
                if (existence == PathExistence.ExistsAsDirectory)
                {
                    trackingResult = FileChangeTrackingSet.ConditionalTrackingResult.Tracked;
                    PathsWithTrackedMembership.Add(Path.GetFullPath(path));
                }

                PathsWithTrackedExistence.Add(Path.GetFullPath(path));
            }

            return(new FileChangeTrackingSet.EnumerationResult(
                       possibleFingerprintResult.Result.Fingerprint,
                       possibleFingerprintResult.Result.PathExistence,
                       trackingResult));
        }
コード例 #2
0
 /// <summary>
 /// Creates an instance of <see cref="DirectoryMembershipFingerprintResult"/>.
 /// </summary>
 public DirectoryMembershipFingerprintResult(
     DirectoryMembershipTrackingFingerprint fingerprint,
     PathExistence pathExistence,
     int memberCount)
 {
     Fingerprint   = fingerprint;
     PathExistence = pathExistence;
     MemberCount   = memberCount;
 }
コード例 #3
0
            public void VerifyExistence(string fullPath, FileSystemViewMode mode, PathExistence existence, bool shouldBeProbed)
            {
                ProbePaths.Clear();
                var path            = GetPath(fullPath);
                var actualExistence = FileSystemView.GetExistence(path, mode);

                Assert.Equal(existence, actualExistence.Result);
                Assert.Equal(shouldBeProbed, ProbePaths.Contains(path));
            }
コード例 #4
0
        public static ProvingContext ToProvingContext(this Application application)
        {
            var paths = new PathExistence(
                (from @this in application.PropertiesOf <Paths>() select @this.Content).SelectMany(p => p));
            var hosts = new HostAvailability(
                (from @this in application.PropertiesOf <Hosts>() select @this.Content).SelectMany(p => p));

            return(new ProvingContext(paths, hosts));
        }
コード例 #5
0
    public async void Should_not_prove_directory_existence_if_does_not_exists()
    {
        const string fakePath = "/var/tests";
        var          mock     = ArbitraryIO.Directories(ArbitraryIO.DirectoryPaths(samples: Maybe.Nothing <ushort>()));
        var          sut      = new PathExistence(mock, new Paths().AddDirectory(fakePath).Content);

        var outcome = await sut.VerifyAsync();

        outcome.Should().NotBeNull()
        .And.BeOfType <Bad <Evidence, string> >()
        .Which.FailedWith().Single().Should().Be($"{fakePath} directory is not found.");
    }
コード例 #6
0
        public Possible <PathExistence> TryProbeAndTrackPath(string path, bool?isReadOnly = default)
        {
            Contract.Requires(path != null);

            PathExistence existence = GetExistence(path);

            lock (m_lock)
            {
                PathsWithTrackedExistence.Add(Path.GetFullPath(path));
            }

            return(existence);
        }
コード例 #7
0
    public async void Should_prove_directory_existence_if_exists()
    {
        const string fakePath = "/var/tests";
        var          mock     = ArbitraryIO.Directories(ArbitraryIO.DirectoryPaths(
                                                            samples: Maybe.Nothing <ushort>(), fakePath));
        var sut = new PathExistence(mock, new Paths().AddDirectory(fakePath).Content);

        var outcome = await sut.VerifyAsync();

        outcome.Should().NotBeNull()
        .And.BeOfType <Ok <Evidence, string> >()
        .Which.SucceededWith().Should().BeEquivalentTo(new Evidence(typeof(PathExistence),
                                                                    new Paths().AddDirectory(fakePath).Content));
    }
コード例 #8
0
        public void ThrowExceptionIfColumnNumberIsOutOfRange(int expectedColumnNumber)
        {
            const string csvPath   = @"D:\a\review-case-s21b11\review-case-s21b11\sample-review\review-report.csv";
            var          checkPath = PathExistence.CheckFileExistOrNot(csvPath);

            if (checkPath)
            {
                var lines = System.IO.File.ReadAllLines(csvPath);
                Assert.Throws <System.IndexOutOfRangeException>(() => ColumnFilter.PrintCsvColumn(lines, expectedColumnNumber));
            }
            else
            {
                Assert.True(false);
            }
        }
コード例 #9
0
    public async void Should_prove_files_and_dirs_existence_if_exist()
    {
        const string fakeFilePath      = "/var/tests/fake.txt";
        const string fakeDirectoryPath = "/var/tests";
        var          mock = ArbitraryIO.Files(ArbitraryIO.FilePaths(
                                                  samples: Maybe.Nothing <ushort>(), fakeFilePath));

        ArbitraryIO.AddDirectories((MockFileSystem)mock, fakeDirectoryPath);
        var paths = new Paths().AddFile(fakeFilePath).AddDirectory(fakeDirectoryPath).Content;
        var sut   = new PathExistence(mock, paths);

        var outcome = await sut.VerifyAsync();

        outcome.Should().NotBeNull()
        .And.BeOfType <Ok <Evidence, string> >()
        .Which.SucceededWith().Should().BeEquivalentTo(new Evidence(typeof(PathExistence),
                                                                    paths));
    }
コード例 #10
0
        /// <summary>
        /// Checks if the given path is an output under a shared opaque by verifying whether <see cref="WellKnownTimestamps.OutputInSharedOpaqueTimestamp"/> is the creation time of the file
        /// </summary>
        /// <remarks>
        /// If the given path is a directory, it is always considered part of a shared opaque
        /// </remarks>
        public static bool IsSharedOpaqueOutput(string expandedPath, out PathExistence pathExistence)
        {
            // On Windows: FOLLOW symlinks
            //   - directory symlinks are not fully supported (e.g., producing directory symlinks)
            //   - other reparse points are at play (e.g., junctions, Helium containers) which necessitate
            //     that we transparently follow those reparse points
            // On non-Windows: NO_FOLLOW symlinks
            //   - directory symlinks are supported
            //   - all symlinks are treated uniformly as files
            //   - if 'expandedPath' is a symlink pointing to a non-existent file, 'expandedPath' should hence
            //     still be treated as an existent file
            //   - similarly, if 'expandedPath' is a symlink pointing to a directory, it should still be treated as a file
            bool followSymlink = !OperatingSystemHelper.IsUnixOS;

            // If the file is not there (the check may be happening against a reported write that later got deleted)
            // then there is nothing to do
            var maybeResult = FileUtilities.TryProbePathExistence(expandedPath, followSymlink);

            if (maybeResult.Succeeded && maybeResult.Result == PathExistence.Nonexistent)
            {
                pathExistence = PathExistence.Nonexistent;
                return(true);
            }

            // We don't really track directories as part of shared opaques.
            // So we consider them all potential members and return true.
            // It is important to track directory symlinks, because they are considered files for sake of shared opaque scrubbing.
            if (maybeResult.Succeeded && maybeResult.Result == PathExistence.ExistsAsDirectory)
            {
                pathExistence = PathExistence.ExistsAsDirectory;
                return(true);
            }

            pathExistence = PathExistence.ExistsAsFile;

            return(OperatingSystemHelper.IsMacOS
                ? XattrBased.IsSharedOpaqueOutput(expandedPath)
                : TimestampBased.IsSharedOpaqueOutput(expandedPath));
        }
コード例 #11
0
            public void AddRealPath(string fullPath, PathExistence existence)
            {
                if (existence == PathExistence.Nonexistent)
                {
                    return;
                }

                var path = AbsolutePath.Create(m_pathTable, fullPath);

                FileOrDirectoryArtifact member = FileOrDirectoryArtifact.Invalid;

                while (path.IsValid)
                {
                    if (existence == PathExistence.ExistsAsFile)
                    {
                        m_files.Add(path);
                        member = new FileArtifact(path);
                    }
                    else
                    {
                        var members = m_directories.GetOrAdd(path, p => new HashSet <FileOrDirectoryArtifact>());
                        if (member.IsValid)
                        {
                            if (!members.Add(member))
                            {
                                return;
                            }
                        }

                        member = DirectoryArtifact.CreateWithZeroPartialSealId(path);
                    }

                    existence = PathExistence.ExistsAsDirectory;
                    path      = path.GetParent(m_pathTable);
                }
            }
コード例 #12
0
            public Possible <Unit, Failure> TryDelete()
            {
                Contract.Requires(IsValid);

                var           maybeExistence = FileUtilities.TryProbePathExistence(Path, followSymlink: false);
                PathExistence pathExistence  = PathExistence.Nonexistent;

                if (maybeExistence.Succeeded)
                {
                    pathExistence = maybeExistence.Result;
                }
                else
                {
                    if (File.Exists(Path))
                    {
                        pathExistence = PathExistence.ExistsAsFile;
                    }
                    else if (Directory.Exists(Path))
                    {
                        pathExistence = PathExistence.ExistsAsDirectory;
                    }

                    BuildXL.Storage.Tracing.Logger.Log.FileMaterializationMismatchFileExistenceResult(
                        Events.StaticContext,
                        Path,
                        maybeExistence.Failure.Describe(),
                        pathExistence.ToString());
                }

                if (pathExistence == PathExistence.ExistsAsFile)
                {
                    m_fileInfoPriorDeletion = new FileInfo(Path);
                }

                m_deletionTime = DateTime.UtcNow;

                switch (pathExistence)
                {
                case PathExistence.ExistsAsFile:
                {
                    var deleteFileResult = FileUtilities.TryDeleteFile(Path);

                    if (!deleteFileResult.Succeeded)
                    {
                        return(deleteFileResult.Failure.Annotate(I($"Failed to delete file '{Path}'")));
                    }

                    break;
                }

                case PathExistence.ExistsAsDirectory:
                {
                    FileUtilities.DeleteDirectoryContents(Path, deleteRootDirectory: true);
                    break;
                }

                default:
                    break;
                }

                return(Unit.Void);
            }
コード例 #13
0
 public void TestingForTheNonExistenceOfCsvFile(string csvPath)
 {
     //const string csvPath = @"E:\Philips\Review-case-s21b11-master\sample-review\Review-report.csv";
     PathExistence.CheckFileExistOrNot(csvPath);
     Assert.False(PathExistence.CheckFileExistOrNot(csvPath));
 }
コード例 #14
0
        public void TestingForTheExistenceOfCsvFile()
        {
            const string csvPath = @"D:\a\review-case-s21b11\review-case-s21b11\sample-review\review-report.csv";

            Assert.True(PathExistence.CheckFileExistOrNot(csvPath));
        }
コード例 #15
0
            public void VerifyGraphExistence(string fullPath, FileSystemViewMode mode, PathExistence existence)
            {
                Contract.Assert(mode != FileSystemViewMode.Real);

                // Graph queries should never probe the file system
                VerifyExistence(fullPath, mode, existence, shouldBeProbed: false);

                var path = GetPath(fullPath);

                if (existence == PathExistence.ExistsAsFile)
                {
                    // File should be queried from underlying pip graph file system
                    Assert.True(TryGetLatestFileArtifactPaths.Contains(path) && m_latestWriteCountByPath.ContainsKey(path));
                }
                else
                {
                    // Directory and non-existent paths will query underlying pip graph file system but will not be found
                    Assert.True(TryGetLatestFileArtifactPaths.Contains(path));
                    if (mode == FileSystemViewMode.FullGraph)
                    {
                        Assert.False(m_latestWriteCountByPath.ContainsKey(path));
                    }
                    else
                    {
                        Assert.True(!m_latestWriteCountByPath.ContainsKey(path) || m_latestWriteCountByPath[path] == 0);
                    }
                }
            }
コード例 #16
0
        /// <summary>
        /// Adds the existence state of the path if not present or returns the current cached existence state of the path
        /// </summary>
        /// <remarks>
        /// If flags are provided, those are added to potentially existing flags
        /// </remarks>
        private PathExistence GetOrAddExistence(AbsolutePath path, FileSystemViewMode mode, PathExistence existence, out bool added, bool updateParents = true, FileSystemEntryFlags flags = FileSystemEntryFlags.None)
        {
            PathExistence result       = existence;
            var           originalPath = path;

            while (path.IsValid)
            {
                var getOrAddResult = PathExistenceCache.GetOrAdd(path, FileSystemEntry.Create(mode, existence).SetFlag(flags));
                if (getOrAddResult.IsFound)
                {
                    var currentExistence = getOrAddResult.Item.Value.GetExistence(mode);
                    var currentFlags     = getOrAddResult.Item.Value.Flags;
                    if (currentExistence != null && currentFlags.HasFlag(flags))
                    {
                        if (originalPath != path)
                        {
                            // Parent entry with existence already exists, just return the result
                            added = true;
                            return(result);
                        }
                        else
                        {
                            // Entry with existence already exists, just return the value
                            added = false;
                            return(currentExistence.Value);
                        }
                    }

                    // found entry for the 'path', but it does not contain existence for the specified 'mode'
                    var updateResult = PathExistenceCache.AddOrUpdate(path, (mode, existence),
                                                                      (key, data) => FileSystemEntry.Create(data.mode, data.existence).SetFlag(flags),
                                                                      (key, data, oldValue) => oldValue.TryUpdate(data.mode, data.existence).SetFlag(flags));

                    // the same entry might be updated concurrently; check whether we lost the race, and if we did, stop further processing
                    currentExistence = updateResult.OldItem.Value.GetExistence(mode);
                    currentFlags     = updateResult.OldItem.Value.Flags;
                    if (currentExistence != null && currentFlags.HasFlag(flags))
                    {
                        if (originalPath != path)
                        {
                            // Parent entry with existence already exists, just return the result
                            added = true;
                            return(result);
                        }
                        else
                        {
                            // Entry with existence already exists, just return the value
                            added = false;
                            return(currentExistence.Value);
                        }
                    }
                }

                // Only register parents as directories if path exists AND updateParents=true
                if (existence == PathExistence.Nonexistent || !updateParents)
                {
                    break;
                }

                // Set ancestor paths existence to directory existent for existent paths
                existence = PathExistence.ExistsAsDirectory;
                path      = path.GetParent(PathTable);
            }

            added = true;
            return(result);
        }
コード例 #17
0
 /// <summary>
 /// Adds the existence state of the path if not present or returns the current cached existence state of the path
 /// </summary>
 private PathExistence GetOrAddExistence(AbsolutePath path, FileSystemViewMode mode, PathExistence existence, bool updateParents = true, FileSystemEntryFlags flags = FileSystemEntryFlags.None)
 {
     return(GetOrAddExistence(path, mode, existence, out var added, updateParents, flags));
 }
コード例 #18
0
        /// <summary>
        /// Gets the existence of a path for the given file system view mode if set
        /// </summary>
        private bool TryGetKnownPathExistence(AbsolutePath path, FileSystemViewMode mode, out PathExistence existence)
        {
            if (mode == FileSystemViewMode.FullGraph || mode == FileSystemViewMode.Output)
            {
                if (ExistsInGraphFileSystem(PipGraph.TryGetLatestFileArtifactForPath(path), mode))
                {
                    existence = PathExistence.ExistsAsFile;
                    return(true);
                }
            }

            // For graph file systems, we query the path existence cache for existence of directories. Files are tracked
            // by the pip graph. For dynamic files, we need to check PathExistenceCache.
            existence = PathExistence.Nonexistent;
            FileSystemEntry entry;

            return(PathExistenceCache.TryGetValue(path, out entry) && entry.TryGetExistence(mode, out existence));
        }
コード例 #19
0
 /// <summary>
 /// Adds the existence state of the path if not present or returns the current cached existence state of the path
 /// </summary>
 private PathExistence GetOrAddExistence(AbsolutePath path, FileSystemViewMode mode, PathExistence existence, bool updateParents = true)
 {
     return(GetOrAddExistence(path, mode, existence, out var added, updateParents));
 }
コード例 #20
0
 private void AssertPathExistence(PathExistence expected, Possible <PathExistence, NativeFailure> maybeFileExistence)
 {
     XAssert.IsTrue(maybeFileExistence.Succeeded);
     XAssert.AreEqual(expected, maybeFileExistence.Result);
 }