Пример #1
0
            public static ChangeTrackerSupport Initialize(FileContentTableWithTrackerTests test)
            {
                var loggingContext   = new LoggingContext("Dummy", "Dummy");
                var fileContentTable = FileContentTable.CreateNew();

                VolumeMap volumeMap = JournalUtils.TryCreateMapOfAllLocalVolumes(loggingContext);

                XAssert.IsNotNull(volumeMap);

                var maybeJournal = JournalUtils.TryGetJournalAccessorForTest(volumeMap);

                XAssert.IsTrue(maybeJournal.Succeeded, "Could not connect to journal");

                var fileChangeTracker = FileChangeTracker.StartTrackingChanges(loggingContext, volumeMap, maybeJournal.Result, null);

                return(new ChangeTrackerSupport(
                           loggingContext,
                           test.m_pathTable,
                           fileChangeTracker,
                           fileContentTable,
                           volumeMap,
                           maybeJournal.Result,
                           AbsolutePath.Create(test.m_pathTable, test.TemporaryDirectory),
                           null));
            }
Пример #2
0
        private FileChangeTracker(
            LoggingContext loggingContext,
            FileEnvelopeId fileEnvelopeId,
            FileChangeTrackingState initialState,
            VolumeMap volumeMap,
            IChangeJournalAccessor journal,
            FileChangeTrackingSet currentChangeTrackingSet,
            string buildEngineFingerprint)
        {
            Contract.Requires(loggingContext != null);
            Contract.Requires(fileEnvelopeId.IsValid);
            Contract.Requires(
                initialState == FileChangeTrackingState.BuildingInitialChangeTrackingSet || initialState == FileChangeTrackingState.TrackingChanges);
            Contract.Requires(volumeMap != null);
            Contract.Requires(journal != null);
            Contract.Requires(currentChangeTrackingSet != null);

            FileEnvelopeId           = fileEnvelopeId;
            m_loggingContext         = loggingContext;
            m_volumeMap              = volumeMap;
            m_journal                = journal;
            m_changeTrackingSet      = currentChangeTrackingSet;
            m_trackingStateValue     = (int)initialState;
            Counters                 = m_changeTrackingSet.Counters;
            m_buildEngineFingerprint = buildEngineFingerprint;
        }
Пример #3
0
        public void CanGetVolumePath()
        {
            VolumeMap map = CreateMapOfAllLocalVolumes();

            ulong          thisVolumeSerial;
            SafeFileHandle directoryHandle;

            FileUtilities.TryOpenDirectory(TemporaryDirectory, FileShare.ReadWrite | FileShare.Delete, out directoryHandle);
            using (directoryHandle)
            {
                XAssert.IsNotNull(directoryHandle, "Failed to open the TemporaryDirectory, which we just created");
                thisVolumeSerial = FileUtilities.GetVolumeSerialNumberByHandle(directoryHandle);
            }

            VolumeGuidPath volumePath = map.TryGetVolumePathBySerial(thisVolumeSerial);

            XAssert.IsTrue(volumePath.IsValid);

            var openResult = FileUtilities.TryOpenDirectory(volumePath.Path, FileShare.ReadWrite | FileShare.Delete, out directoryHandle);

            using (directoryHandle)
            {
                XAssert.IsTrue(openResult.Succeeded, "Failed to open the volume root (but we didn't ask for any access)");
                XAssert.IsTrue(openResult.OpenedOrTruncatedExistingFile);
                XAssert.IsNotNull(directoryHandle);
                XAssert.AreEqual(thisVolumeSerial, FileUtilities.GetVolumeSerialNumberByHandle(directoryHandle), "The volume root path has the wrong volume serial");
            }
        }
Пример #4
0
            public static ChangeTrackerSupport Initialize(FileContentTableWithTrackerTests test)
            {
                var loggingContext   = new LoggingContext("Dummy", "Dummy");
                var fileContentTable = FileContentTable.CreateNew();

                VolumeMap volumeMap = VolumeMap.TryCreateMapOfAllLocalVolumes(loggingContext);

                XAssert.IsNotNull(volumeMap);

                var journal = JournalAccessorGetter.TryGetJournalAccessor(loggingContext, volumeMap, AssemblyHelper.GetAssemblyLocation(Assembly.GetExecutingAssembly())).Value;

                XAssert.IsNotNull(journal);

                var fileChangeTracker = FileChangeTracker.StartTrackingChanges(loggingContext, volumeMap, journal, null);

                return(new ChangeTrackerSupport(
                           loggingContext,
                           test.m_pathTable,
                           fileChangeTracker,
                           fileContentTable,
                           volumeMap,
                           journal,
                           AbsolutePath.Create(test.m_pathTable, test.TemporaryDirectory),
                           null));
            }
Пример #5
0
        /// <summary>
        /// Creates a new change tracker in the <see cref="FileChangeTrackingState.BuildingInitialChangeTrackingSet"/> state.
        /// The caller may then add tracking for full set of files of interest, for later re-use by
        /// <see cref="ResumeTrackingChanges(LoggingContext,BuildXL.Utilities.FileEnvelopeId,VolumeMap,IChangeJournalAccessor,FileChangeTrackingSet,string)"/>.
        /// </summary>
        public static FileChangeTracker StartTrackingChanges(
            LoggingContext loggingContext,
            VolumeMap volumeMap,
            IChangeJournalAccessor journal,
            string buildEngineFingerprint,
            FileEnvelopeId?correlatedId = default)
        {
            Contract.Requires(loggingContext != null);
            Contract.Requires(volumeMap != null);
            Contract.Requires(journal != null);
            Contract.Ensures(Contract.Result <FileChangeTracker>().TrackingState == FileChangeTrackingState.BuildingInitialChangeTrackingSet);

            var tracker = new FileChangeTracker(
                loggingContext,
                correlatedId ?? FileEnvelopeId.Create(),
                FileChangeTrackingState.BuildingInitialChangeTrackingSet,
                volumeMap,
                journal,
                FileChangeTrackingSet.CreateForAllCapableVolumes(loggingContext, volumeMap, journal),
                buildEngineFingerprint);

            foreach (var gvfsProjectionFile in volumeMap.GvfsProjections)
            {
                var maybeTracking = tracker.TryProbeAndTrackPath(gvfsProjectionFile);
                if (!maybeTracking.Succeeded)
                {
                    Logger.Log.TrackChangesToGvfsProjectionFailed(loggingContext, gvfsProjectionFile, maybeTracking.Failure.DescribeIncludingInnerFailures());
                }
            }

            return(tracker);
        }
Пример #6
0
        /// <summary>
        /// Loads <see cref="FileChangeTracker"/>, and if successful, the <see cref="FileChangeTracker"/> is a disabled one.
        /// </summary>
        public static LoadingTrackerResult LoadTrackingChanges(
            LoggingContext loggingContext,
            VolumeMap volumeMap,
            IChangeJournalAccessor journal,
            string path,
            string buildEngineFingerprint,
            out FileChangeTracker tracker,
            bool loadForAllCapableVolumes = true)
        {
            Contract.Requires(!loadForAllCapableVolumes || volumeMap != null);
            Contract.Requires(!loadForAllCapableVolumes || journal != null);
            Contract.Requires(path != null);

            tracker = null;

            using (var pm = BuildXL.Tracing.PerformanceMeasurement.StartWithoutStatistic(
                       loggingContext,
                       loggingContext1 => Logger.Log.StartLoadingChangeTracker(loggingContext1, path),
                       loggingContext1 => Logger.Log.EndLoadingChangeTracker(loggingContext1)))
            {
                // Note that TryLoad may throw in the event of spooky I/O errors.
                var loadingTrackerResult = TryLoad(
                    pm.LoggingContext,
                    path,
                    volumeMap,
                    journal,
                    buildEngineFingerprint,
                    loadForAllCapableVolumes: loadForAllCapableVolumes);

                if (loadingTrackerResult.Succeeded)
                {
                    Contract.Assert(loadingTrackerResult.ChangeTrackingSet != null);

                    tracker = new FileChangeTracker(
                        pm.LoggingContext,
                        loadingTrackerResult.FileId,
                        FileChangeTrackingState.TrackingChanges,
                        loadingTrackerResult.ChangeTrackingSet.VolumeMap,
                        journal ?? new InProcChangeJournalAccessor(),
                        loadingTrackerResult.ChangeTrackingSet,
                        buildEngineFingerprint);
                }
                else
                {
                    Contract.Assert(loadingTrackerResult.ChangeTrackingSet == null);
                }

                Logger.Log.LoadingChangeTracker(
                    pm.LoggingContext,
                    path,
                    loadingTrackerResult.FileId.ToString(),
                    loadingTrackerResult.Status.ToString(),
                    loadingTrackerResult.StatusAsString,
                    loadingTrackerResult.TrackedVolumesCount,
                    (long)loadingTrackerResult.TrackedJournalsSizeBytes,
                    loadingTrackerResult.DurationMs);

                return(loadingTrackerResult);
            }
        }
Пример #7
0
        private static VolumeMap CreateMapOfAllLocalVolumes()
        {
            VolumeMap map = JournalUtils.TryCreateMapOfAllLocalVolumes(new LoggingContext("Dummy", "Dummy"));

            XAssert.IsNotNull(map);
            return(map);
        }
        /// <summary>
        /// Creates an instance of <see cref="FileContentTableAccessorWin"/>
        /// </summary>
        /// <param name="volumeMap">Volume map.</param>
        public FileContentTableAccessorWin(VolumeMap volumeMap)
        {
            Contract.Requires(volumeMap != null);

            m_volumeMap    = volumeMap;
            m_fileAccessor = m_volumeMap.CreateFileAccessor();
        }
Пример #9
0
            private ChangeTrackerSupport(
                LoggingContext loggingContext,
                PathTable pathTable,
                FileChangeTracker fileChangeTracker,
                FileContentTable fileContentTable,
                VolumeMap volumeMap,
                IChangeJournalAccessor journal,
                AbsolutePath temporaryDirectory,
                string buildEngineFingerprint)
            {
                Contract.Requires(loggingContext != null);
                Contract.Requires(pathTable != null);
                Contract.Requires(fileChangeTracker != null);
                Contract.Requires(fileContentTable != null);
                Contract.Requires(temporaryDirectory.IsValid);

                m_loggingContext         = loggingContext;
                m_pathTable              = pathTable;
                m_fileChangeTracker      = fileChangeTracker;
                m_fileContentTable       = fileContentTable;
                m_volumeMap              = volumeMap;
                m_journal                = journal;
                m_fileContentTablePath   = temporaryDirectory.Combine(m_pathTable, FileContentTableName);
                m_fileChangeTrackerPath  = temporaryDirectory.Combine(m_pathTable, FileChangeTrackerName);
                m_buildEngineFingerprint = buildEngineFingerprint;
            }
Пример #10
0
        public void CannotAccessDeletedFile()
        {
            ulong  volumeSerial;
            FileId fileId;
            string path = GetFullPath("F");

            using (FileStream fs = File.Create(path))
            {
                volumeSerial = FileUtilities.GetVolumeSerialNumberByHandle(fs.SafeFileHandle);
                fileId       = FileUtilities.ReadFileUsnByHandle(fs.SafeFileHandle).Value.FileId;
            }

            File.Delete(path);

            VolumeMap map = CreateMapOfAllLocalVolumes();

            using (FileAccessor accessor = map.CreateFileAccessor())
            {
                SafeFileHandle handle;
                FileAccessor.OpenFileByIdResult openResult = accessor.TryOpenFileById(
                    volumeSerial,
                    fileId,
                    FileDesiredAccess.GenericRead,
                    FileShare.ReadWrite,
                    FileFlagsAndAttributes.None,
                    out handle);
                using (handle)
                {
                    XAssert.AreEqual(FileAccessor.OpenFileByIdResult.FailedToFindFile, openResult);
                    XAssert.IsNull(handle);
                }
            }
        }
Пример #11
0
 public void OverlappingJunctionRoots()
 {
     List <string> junctionRoots = new List <string>()
     {
         @"c:\windows", @"c:\windows"
     };
     VolumeMap map = JournalUtils.TryCreateMapOfAllLocalVolumes(new LoggingContext("Dummy", "Dummy"), junctionRoots);
 }
Пример #12
0
        /// <summary>
        /// Creates a map of local volumes.
        /// </summary>
        public static VolumeMap TryCreateMapOfAllLocalVolumes(LoggingContext loggingContext, IReadOnlyList <string> junctionRoots = null)
        {
            var volumeMap = VolumeMap.CreateMapOfAllLocalVolumes(loggingContext, junctionRoots);

            // We want to skip volumes that are not local to VM.
            volumeMap.SkipTrackingJournalIncapableVolume = HasRelocatedTempInVm;

            return(volumeMap);
        }
Пример #13
0
        /// <summary>
        /// Tries to load a <see cref="FileChangeTrackingSet"/> and resume tracking changes.
        /// If loading is successful (including matching the provided atomic save token), the returned tracker begins in the <see cref="FileChangeTrackingState.TrackingChanges"/> state.
        /// The caller may then query for new changes since the tracking set was last checkpointed and persisted, and may track additional files.
        /// Otherwise, a tracker with a new and empty change tracking set is created, initially in the <see cref="FileChangeTrackingState.BuildingInitialChangeTrackingSet"/> state.
        /// In that case, attempting to query changes will fail (the caller should fall back to doing complete rather than incremental work, thus populating the new change tracking set).
        /// </summary>
        /// <exception cref="BuildXLException">Thrown in the event of an I/O error other than the given path being absent.</exception>
        public static LoadingTrackerResult ResumeOrRestartTrackingChanges(
            LoggingContext loggingContext,
            VolumeMap volumeMap,
            IChangeJournalAccessor journal,
            string path,
            string buildEngineFingerprint,
            out FileChangeTracker tracker)
        {
            Contract.Requires(volumeMap != null);
            Contract.Requires(journal != null);
            Contract.Requires(path != null);

            using (var pm = BuildXL.Tracing.PerformanceMeasurement.StartWithoutStatistic(
                       loggingContext,
                       loggingContext1 => Logger.Log.StartLoadingChangeTracker(loggingContext1, path),
                       loggingContext1 => Logger.Log.EndLoadingChangeTracker(loggingContext1)))
            {
                // Note that TryLoad may throw in the event of spooky I/O errors.
                var loadingTrackerResult = TryLoad(pm.LoggingContext, path, volumeMap, journal, buildEngineFingerprint);

                if (loadingTrackerResult.Succeeded)
                {
                    Contract.Assert(loadingTrackerResult.ChangeTrackingSet != null);

                    // Ideally, we reload prior state so that the caller can query changes and do incremental work.
                    // In this case, we already validated the correlating atomic save token, and so the state is safe to reuse.
                    tracker = ResumeTrackingChanges(
                        pm.LoggingContext,
                        loadingTrackerResult.FileId,
                        volumeMap,
                        journal,
                        loadingTrackerResult.ChangeTrackingSet,
                        buildEngineFingerprint);
                }
                else
                {
                    Contract.Assert(loadingTrackerResult.ChangeTrackingSet == null);

                    // Or, we might be unable to re-use the persisted state. In that case we start over. Note that there's nothing to do with the correlating save token here;
                    // on save, a new or existing token will be provided as appropriate.
                    // The reason of the failure is already logged in the TryLoad() method above.
                    tracker = StartTrackingChanges(pm.LoggingContext, volumeMap, journal, buildEngineFingerprint);
                }

                Logger.Log.LoadingChangeTracker(
                    pm.LoggingContext,
                    path,
                    loadingTrackerResult.FileId.ToString(),
                    loadingTrackerResult.Status.ToString(),
                    loadingTrackerResult.StatusAsString,
                    loadingTrackerResult.TrackedVolumesCount,
                    (long)loadingTrackerResult.TrackedJournalsSizeBytes,
                    loadingTrackerResult.DurationMs);

                return(loadingTrackerResult);
            }
        }
Пример #14
0
        /// <summary>
        /// Gets an instance of <see cref="IChangeJournalAccessor"/> for tests.
        /// </summary>
        /// <param name="volumeMap">Volume map.</param>
        /// <returns>An instance of <see cref="IChangeJournalAccessor"/>.</returns>
        public static Possible <IChangeJournalAccessor> TryGetJournalAccessorForTest(VolumeMap volumeMap)
        {
            string path = FileUtilities.GetTempFileName();

            var maybeJournal = JournalAccessorGetter.TryGetJournalAccessor(volumeMap, path);

            FileUtilities.DeleteFile(path);

            return(maybeJournal);
        }
Пример #15
0
        private FileChangeTracker(LoggingContext loggingContext)
        {
            Contract.Requires(loggingContext != null);

            m_loggingContext         = loggingContext;
            m_volumeMap              = null;
            m_journal                = null;
            m_changeTrackingSet      = null;
            m_trackingStateValue     = (int)FileChangeTrackingState.DisabledSinceTrackingIsIncomplete;
            Counters                 = new CounterCollection <FileChangeTrackingCounter>();
            m_buildEngineFingerprint = null;
        }
Пример #16
0
        public void CannotGetVolumePathForSerialThatDoesNotExist()
        {
            var   serials      = new HashSet <ulong>(FileUtilities.ListVolumeGuidPathsAndSerials().Select(t => t.Item2));
            ulong uniqueSerial = serials.First();

            do
            {
                uniqueSerial++;
            }while (serials.Contains(uniqueSerial));

            VolumeMap map = CreateMapOfAllLocalVolumes();

            XAssert.IsFalse(map.TryGetVolumePathBySerial(uniqueSerial).IsValid, "Found a path for a serial that seemed to not exist");
        }
Пример #17
0
        public void CanAccessMultipleFilesById()
        {
            var fileIdAndVolumeSerialPairs = new List <Tuple <FileId, ulong> >();

            for (int i = 0; i < 3; i++)
            {
                string path = GetFullPath("F" + i);
                using (FileStream fs = File.Create(path))
                {
                    fs.WriteByte((byte)i);

                    ulong  volumeSerial = FileUtilities.GetVolumeSerialNumberByHandle(fs.SafeFileHandle);
                    FileId fileId       = FileUtilities.ReadFileUsnByHandle(fs.SafeFileHandle).Value.FileId;
                    fileIdAndVolumeSerialPairs.Add(Tuple.Create(fileId, volumeSerial));
                }
            }

            VolumeMap map = CreateMapOfAllLocalVolumes();

            using (FileAccessor accessor = map.CreateFileAccessor())
            {
                for (int i = 0; i < fileIdAndVolumeSerialPairs.Count; i++)
                {
                    Tuple <FileId, ulong> fileIdAndVolumeSerial = fileIdAndVolumeSerialPairs[i];

                    SafeFileHandle handle;
                    FileAccessor.OpenFileByIdResult openResult = accessor.TryOpenFileById(
                        fileIdAndVolumeSerial.Item2,
                        fileIdAndVolumeSerial.Item1,
                        FileDesiredAccess.GenericRead,
                        FileShare.ReadWrite,
                        FileFlagsAndAttributes.None,
                        out handle);
                    using (handle)
                    {
                        XAssert.AreEqual(openResult, FileAccessor.OpenFileByIdResult.Succeeded);
                        XAssert.IsNotNull(handle);

                        using (var fileStream = new FileStream(handle, FileAccess.Read))
                        {
                            XAssert.AreEqual(i, fileStream.ReadByte());
                        }
                    }
                }
            }
        }
Пример #18
0
        public void StartTracking()
        {
            var loggingContext = new LoggingContext("JournalTesting", "Dummy");

            VolumeMap volumeMap = JournalUtils.TryCreateMapOfAllLocalVolumes(loggingContext);

            XAssert.IsNotNull(volumeMap);

            var maybeJournal = JournalUtils.TryGetJournalAccessorForTest(volumeMap);

            XAssert.IsTrue(maybeJournal.Succeeded);
            m_journal = maybeJournal.Result;

            m_changeTracker = FileChangeTrackingSet.CreateForAllCapableVolumes(
                loggingContext,
                volumeMap,
                m_journal);
        }
Пример #19
0
        /// <summary>
        /// Creates a new change tracker in the <see cref="FileChangeTrackingState.BuildingInitialChangeTrackingSet"/> state.
        /// The caller may then add tracking for full set of files of interest, for later re-use by
        /// <see cref="ResumeTrackingChanges(LoggingContext,BuildXL.Utilities.FileEnvelopeId,VolumeMap,IChangeJournalAccessor,FileChangeTrackingSet,string)"/>.
        /// </summary>
        public static FileChangeTracker StartTrackingChanges(
            LoggingContext loggingContext,
            VolumeMap volumeMap,
            IChangeJournalAccessor journal,
            string buildEngineFingerprint,
            FileEnvelopeId?correlatedId = default)
        {
            Contract.Requires(loggingContext != null);
            Contract.Requires(volumeMap != null);
            Contract.Requires(journal != null);
            Contract.Ensures(Contract.Result <FileChangeTracker>().TrackingState == FileChangeTrackingState.BuildingInitialChangeTrackingSet);

            return(new FileChangeTracker(
                       loggingContext,
                       correlatedId ?? FileEnvelopeId.Create(),
                       FileChangeTrackingState.BuildingInitialChangeTrackingSet,
                       volumeMap,
                       journal,
                       FileChangeTrackingSet.CreateForAllCapableVolumes(loggingContext, volumeMap, journal),
                       buildEngineFingerprint));
        }
Пример #20
0
        /// <summary>
        /// Creates an instance of <see cref="IFileContentTableAccessor"/> based on the current OS.
        /// </summary>
        /// <param name="accessor">Output file content table accessor.</param>
        /// <param name="error">Error message for failed creation.</param>
        /// <returns>True if successful; otherwise false.</returns>
        public static bool TryCreate(out IFileContentTableAccessor accessor, out string error)
        {
            accessor = null;
            error    = null;

            if (OperatingSystemHelper.IsUnixOS)
            {
                accessor = new FileContentTableAccessorUnix();
                return(true);
            }

            VolumeMap volumeMap = VolumeMap.TryCreateMapOfAllLocalVolumes(new LoggingContext(nameof(IFileContentTableAccessor)));

            if (volumeMap == null)
            {
                error = "Failed to create volume map";
                return(false);
            }

            accessor = new FileContentTableAccessorWin(volumeMap);
            return(true);
        }
Пример #21
0
        /// <summary>
        /// Creates a new change tracker in the <see cref="FileChangeTrackingState.TrackingChanges"/> state.
        /// The caller may query for new changes since the tracking set was last checkpointed and persisted, and may track additional files.
        /// </summary>
        private static FileChangeTracker ResumeTrackingChanges(
            LoggingContext loggingContext,
            FileEnvelopeId fileEnvelopeId,
            VolumeMap volumeMap,
            IChangeJournalAccessor journal,
            FileChangeTrackingSet previousChangeTrackingSet,
            string buildEngineFingerprint)
        {
            Contract.Requires(loggingContext != null);
            Contract.Requires(volumeMap != null);
            Contract.Requires(journal != null);
            Contract.Requires(previousChangeTrackingSet != null);
            Contract.Requires(fileEnvelopeId.IsValid);

            return(new FileChangeTracker(
                       loggingContext,
                       fileEnvelopeId,
                       FileChangeTrackingState.TrackingChanges,
                       volumeMap,
                       journal,
                       previousChangeTrackingSet,
                       buildEngineFingerprint));
        }
Пример #22
0
        private void WithVolumeHandle(Action <SafeFileHandle> action)
        {
            VolumeMap map = JournalUtils.TryCreateMapOfAllLocalVolumes(new LoggingContext("Dummy", "Dummy"));

            XAssert.IsNotNull(map, "Failed to create a volume map");

            using (VolumeAccessor volumeAccessor = map.CreateVolumeAccessor())
            {
                SafeFileHandle directoryHandle;
                var            directoryOpenResult = FileUtilities.TryOpenDirectory(
                    TemporaryDirectory,
                    FileShare.ReadWrite | FileShare.Delete,
                    out directoryHandle);
                using (directoryHandle)
                {
                    XAssert.IsTrue(directoryOpenResult.Succeeded, "Failed to open the temporary directory to query its volume membership");

                    SafeFileHandle volumeHandle = volumeAccessor.TryGetVolumeHandle(directoryHandle);
                    XAssert.IsNotNull(volumeHandle, "Failed to open a volume handle");

                    action(volumeHandle);
                }
            }
        }
Пример #23
0
        public static LoadingTrackerResult TryLoad(
            LoggingContext loggingContext,
            string path,
            VolumeMap volumeMap,
            IChangeJournalAccessor journal,
            string buildEngineFingerprint,
            bool loadForAllCapableVolumes = true)
        {
            Contract.Requires(loggingContext != null);
            Contract.Requires(!loadForAllCapableVolumes || volumeMap != null);
            Contract.Requires(!loadForAllCapableVolumes || journal != null);

            Stopwatch stopwatch = Stopwatch.StartNew();

            SafeFileHandle handle;
            OpenFileResult result = FileUtilities.TryCreateOrOpenFile(
                path,
                FileDesiredAccess.GenericRead,
                FileShare.Read | FileShare.Delete,
                FileMode.Open,
                // Ok to evict the file from standby since the file will be overwritten and never reread from disk after this point.
                FileFlagsAndAttributes.FileFlagSequentialScan,
                out handle);

            if (result.Succeeded)
            {
                Contract.Assume(handle != null);
                Contract.Assume(!handle.IsInvalid);

                using (handle)
                {
                    using (var stream = new FileStream(handle, FileAccess.Read))
                    {
                        FileEnvelopeId fileEnvelopeId;

                        try
                        {
                            fileEnvelopeId = FileEnvelope.ReadHeader(stream);
                        }
                        catch (BuildXLException e)
                        {
                            return(LoadingTrackerResult.FailBadFormatMarker(e.Message));
                        }

                        try
                        {
                            return(ExceptionUtilities.HandleRecoverableIOException(
                                       () =>
                            {
                                using (var reader = new BuildXLReader(debug: false, stream: stream, leaveOpen: true))
                                {
                                    bool wasTrackerDisabled = reader.ReadBoolean();

                                    if (wasTrackerDisabled)
                                    {
                                        return LoadingTrackerResult.FailPriorTrackerDisabled();
                                    }

                                    var previousFingerprint = reader.ReadNullable(r => r.ReadString());
                                    // only check for fingerprints match if the supplied fingerprint is valid
                                    // this is to support special cases where we might want to load ChangeTracker
                                    // regardless of the previously stored fingerprint value
                                    if (buildEngineFingerprint != null && !string.Equals(previousFingerprint, buildEngineFingerprint, StringComparison.Ordinal))
                                    {
                                        return LoadingTrackerResult.FailBuildEngineFingerprintMismatch();
                                    }

                                    return FileChangeTrackingSet.TryLoad(
                                        loggingContext,
                                        fileEnvelopeId,
                                        reader,
                                        volumeMap,
                                        journal,
                                        stopwatch,
                                        loadForAllCapableVolumes);
                                }
                            },
                                       ex =>
                            {
                                throw new BuildXLException(ex.Message);
                            }));
                        }
                        catch (Exception e)
                        {
                            // Catch any exception. Failure in loading FileChangeTracker should not
                            // cause build break, or worse, make people stuck on erroneous state.
                            // In such a case, BuildXL simply has to start tracking from scratch.
                            return(LoadingTrackerResult.FailLoadException(e.GetLogEventMessage()));
                        }
                    }
                }
            }

            Contract.Assume(handle == null);
            return(LoadingTrackerResult.FailTrackingSetCannotBeOpened(result.CreateFailureForError().DescribeIncludingInnerFailures()));
        }
Пример #24
0
        /// <nodoc/>
        public FactIfSupportedAttribute(
            bool requiresAdmin                       = false,
            bool requiresJournalScan                 = false,
            bool requiresSymlinkPermission           = false,
            bool requiresWindowsBasedOperatingSystem = false,
            bool requiresUnixBasedOperatingSystem    = false,
            bool requiresHeliumDriversAvailable      = false,
            bool requiresHeliumDriversNotAvailable   = false)
        {
            RequiresAdmin             = requiresAdmin;
            RequiresJournalScan       = requiresJournalScan;
            RequiresSymlinkPermission = requiresSymlinkPermission;

            if (Skip != null)
            {
                // If skip is specified, do nothing because the test will be skipped anyway.
                return;
            }

            if (requiresAdmin)
            {
                if (!s_isElevated.HasValue)
                {
                    s_isElevated = CurrentProcess.IsElevated;
                }

                if (!s_isElevated.Value)
                {
                    Skip = "Test must be run elevated!";
                    return;
                }
            }

            if (requiresSymlinkPermission)
            {
                if (!s_canCreateSymlink.HasValue)
                {
                    string tempFile    = Path.GetTempFileName();
                    string symlinkPath = Path.GetTempFileName();
                    FileUtilities.DeleteFile(symlinkPath);

                    // For reliable tests, we ensure that the symlink is created.
                    s_canCreateSymlink = FileUtilities.TryCreateSymbolicLink(symlinkPath, tempFile, true).Succeeded&& FileUtilities.FileExistsNoFollow(symlinkPath);
                    FileUtilities.DeleteFile(symlinkPath);
                    FileUtilities.DeleteFile(tempFile);
                }

                if (!s_canCreateSymlink.Value)
                {
                    Skip = "Test must be run with symbolic link creation privileged";
                    return;
                }
            }

            if (requiresJournalScan)
            {
                if (!s_canScanJournal.HasValue)
                {
                    var loggingContext = new LoggingContext("Dummy", "Dummy");
                    var map            = VolumeMap.TryCreateMapOfAllLocalVolumes(loggingContext);
                    var accessor       = JournalAccessorGetter.TryGetJournalAccessor(loggingContext, map, AssemblyHelper.GetAssemblyLocation(Assembly.GetExecutingAssembly()));
                    s_canScanJournal = accessor.IsValid && accessor.Value != null;
                }

                if (!s_canScanJournal.Value)
                {
                    Skip = "Test requires access to the in process change journal scan. Either run elevated on install RS2.";
                    return;
                }
            }

            if (requiresWindowsBasedOperatingSystem)
            {
                if (OperatingSystemHelper.IsUnixOS)
                {
                    Skip = "Test must be run on the CLR on Windows based operating systems!";
                    return;
                }
            }

            if (requiresUnixBasedOperatingSystem)
            {
                if (!OperatingSystemHelper.IsUnixOS)
                {
                    Skip = "Test must be run on the CoreCLR on Unix based operating systems!";
                    return;
                }
            }

            if (requiresHeliumDriversAvailable)
            {
                if (!s_isHeliumFiltersAvailable.HasValue)
                {
                    s_isHeliumFiltersAvailable = ProcessUtilities.IsWciAndBindFiltersAvailable();
                }

                if (!s_isHeliumFiltersAvailable.Value)
                {
                    Skip = "Test must be run elevated on a machine with WCI and Bind filters available.";
                    return;
                }
            }

            if (requiresHeliumDriversNotAvailable)
            {
                if (!s_isHeliumFiltersAvailable.HasValue)
                {
                    s_isHeliumFiltersAvailable = ProcessUtilities.IsWciAndBindFiltersAvailable();
                }
                if (s_isHeliumFiltersAvailable.Value)
                {
                    Skip = "Test must be run on a machine where WCI and Bind filters are NOT available.";
                    return;
                }
            }
        }
Пример #25
0
 public VolumePluginController(VolumeMap volumeMappings, StatelessServiceContext context)
 {
     this.volumeMap      = volumeMappings;
     this.serviceContext = context;
 }
Пример #26
0
    private static void Init()
    {
        GameObject gameObject = Resources.Load("Audio/VolumeMap") as GameObject;

        VolumeMap._instance = gameObject.GetComponent <VolumeMap>();
    }
Пример #27
0
        /// <summary>
        /// Runs the scheduler allowing various options to be specifically set
        /// </summary>
        public ScheduleRunResult RunSchedulerSpecific(
            PipGraph graph,
            SchedulerTestHooks testHooks  = null,
            SchedulerState schedulerState = null,
            RootFilter filter             = null,
            TempCleaner tempCleaner       = null)
        {
            var config = new CommandLineConfiguration(Configuration);

            // Populating the configuration may modify the configuration, so it should occur first.
            BuildXLEngine.PopulateLoggingAndLayoutConfiguration(config, Context.PathTable, bxlExeLocation: null, inTestMode: true);
            BuildXLEngine.PopulateAndValidateConfiguration(config, config, Context.PathTable, LoggingContext);

            FileAccessWhitelist whitelist = new FileAccessWhitelist(Context);

            whitelist.Initialize(config);

            IReadOnlyList <string> junctionRoots = Configuration.Engine.DirectoriesToTranslate?.Select(a => a.ToPath.ToString(Context.PathTable)).ToList();

            var map = VolumeMap.TryCreateMapOfAllLocalVolumes(LoggingContext, junctionRoots);
            var optionalAccessor = TryGetJournalAccessor(map);

            // Although scan change journal is enabled, but if we cannot create an enabled journal accessor, then create a disabled one.
            m_journalState = map == null || !optionalAccessor.IsValid
                ? JournalState.DisabledJournal
                : JournalState.CreateEnabledJournal(map, optionalAccessor.Value);

            if (config.Schedule.IncrementalScheduling)
            {
                // Ensure that we can scan the journal when incremental scheduling is enabled.
                XAssert.IsTrue(m_journalState.IsEnabled, "Incremental scheduling requires that journal is enabled");
            }

            // Seal the translator if not sealed
            DirectoryTranslator.Seal();

            // .....................................................................................
            // some dummy setup in order to get a PreserveOutputsSalt.txt file and an actual salt
            // .....................................................................................
            string dummyCacheDir = Path.Combine(TemporaryDirectory, "Out", "Cache");

            Directory.CreateDirectory(dummyCacheDir); // EngineSchedule tries to put the PreserveOutputsSalt.txt here
            ContentHash?previousOutputsSalt =
                EngineSchedule.PreparePreviousOutputsSalt(LoggingContext, Context.PathTable, config);

            Contract.Assert(previousOutputsSalt.HasValue);
            // .....................................................................................

            testHooks = testHooks ?? new SchedulerTestHooks();
            Contract.Assert(!(config.Engine.CleanTempDirectories && tempCleaner == null));

            using (var queue = new PipQueue(config.Schedule))
                using (var testQueue = new TestPipQueue(queue, LoggingContext, initiallyPaused: false))
                    using (var testScheduler = new TestScheduler(
                               graph: graph,
                               pipQueue: testQueue,
                               context: Context,
                               fileContentTable: FileContentTable,
                               loggingContext: LoggingContext,
                               cache: Cache,
                               configuration: config,
                               journalState: m_journalState,
                               fileAccessWhitelist: whitelist,
                               fingerprintSalt: Configuration.Cache.CacheSalt,
                               directoryMembershipFingerprinterRules: new DirectoryMembershipFingerprinterRuleSet(Configuration, Context.StringTable),
                               tempCleaner: tempCleaner,
                               previousInputsSalt: previousOutputsSalt.Value,
                               successfulPips: null,
                               failedPips: null,
                               ipcProvider: null,
                               directoryTranslator: DirectoryTranslator,
                               testHooks: testHooks))
                    {
                        if (filter == null)
                        {
                            EngineSchedule.TryGetPipFilter(LoggingContext, Context, config, config, Expander.TryGetRootByMountName, out filter);
                        }

                        XAssert.IsTrue(testScheduler.InitForMaster(LoggingContext, filter, schedulerState), "Failed to initialized test scheduler");

                        testScheduler.Start(LoggingContext);

                        bool success = testScheduler.WhenDone().GetAwaiter().GetResult();
                        testScheduler.SaveFileChangeTrackerAsync(LoggingContext).Wait();

                        return(new ScheduleRunResult
                        {
                            Graph = graph,
                            Config = config,
                            Success = success,
                            PipResults = testScheduler.PipResults,
                            PipExecutorCounters = testScheduler.PipExecutionCounters,
                            PathSets = testScheduler.PathSets,
                            ProcessPipCountersByFilter = testScheduler.ProcessPipCountersByFilter,
                            ProcessPipCountersByTelemetryTag = testScheduler.ProcessPipCountersByTelemetryTag,
                            SchedulerState = new SchedulerState(testScheduler)
                        });
                    }
        }
Пример #28
0
 private Optional <global::BuildXL.Storage.ChangeJournalService.IChangeJournalAccessor> TryGetJournalAccessor(VolumeMap map)
 {
     return(map.Volumes.Any()
         ? JournalAccessorGetter.TryGetJournalAccessor(LoggingContext, map, AssemblyHelper.GetAssemblyLocation(Assembly.GetExecutingAssembly()))
         : Optional <global::BuildXL.Storage.ChangeJournalService.IChangeJournalAccessor> .Invalid);
 }