예제 #1
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))
                    {
                        MountPathExpander mountPathExpander = null;
                        var frontEndNonScrubbablePaths      = CollectionUtilities.EmptyArray <string>();
                        var nonScrubbablePaths = EngineSchedule.GetNonScrubbablePaths(Context.PathTable, config, frontEndNonScrubbablePaths, tempCleaner);
                        EngineSchedule.ScrubExtraneousFilesAndDirectories(mountPathExpander, testScheduler, LoggingContext, config, nonScrubbablePaths, tempCleaner);

                        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();

                        if (ShouldLogSchedulerStats)
                        {
                            // Logs are not written out normally during these tests, but LogStats depends on the existence of the logs directory
                            // to write out the stats perf JSON file
                            var logsDir = config.Logging.LogsDirectory.ToString(Context.PathTable);
                            Directory.CreateDirectory(logsDir);
                            testScheduler.LogStats(LoggingContext);
                        }

                        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)
                        });
                    }
        }