public TestEnv( string name, string rootPath, bool enableLazyOutputMaterialization = false, int maxRelativeOutputDirectoryLength = 260, List <IMount> mounts = null, PathTable pathTable = null) { Contract.Requires(name != null); Contract.Requires(!string.IsNullOrEmpty(rootPath)); LoggingContext = new LoggingContext("TestLogger." + name); PathTable = pathTable ?? new PathTable(); PipDataBuilderPool = new ObjectPool <PipDataBuilder>(() => new PipDataBuilder(PathTable.StringTable), _ => { }); // The tests that use TestEnv need to be modernized to take a filesystem var fileSystem = new PassThroughFileSystem(PathTable); Context = EngineContext.CreateNew(CancellationToken.None, PathTable, fileSystem); // Add some well-known paths with fixed casing to the Context.PathTable AbsolutePath.Create(Context.PathTable, rootPath.ToLowerInvariant()); var root = AbsolutePath.Create(Context.PathTable, rootPath); var configuration = ConfigHelpers.CreateDefaultForXml(Context.PathTable, root); configuration.Layout.SourceDirectory = root.Combine(PathTable, PathAtom.Create(PathTable.StringTable, "src")); // These tests have non-standard src folder configuration.Engine.MaxRelativeOutputDirectoryLength = maxRelativeOutputDirectoryLength; configuration.Schedule.EnableLazyOutputMaterialization = enableLazyOutputMaterialization; configuration.Schedule.UnsafeDisableGraphPostValidation = false; configuration.Schedule.ComputePipStaticFingerprints = true; configuration.Sandbox.FileAccessIgnoreCodeCoverage = true; BuildXLEngine.PopulateFileSystemCapabilities(configuration, configuration, Context.PathTable, LoggingContext); BuildXLEngine.PopulateLoggingAndLayoutConfiguration(configuration, Context.PathTable, bxlExeLocation: null, inTestMode: true); BuildXLEngine.PopulateAndValidateConfiguration(configuration, configuration, Context.PathTable, LoggingContext); Configuration = configuration; var mountsTable = MountsTable.CreateAndRegister(LoggingContext, Context, Configuration, null); if (mounts != null) { foreach (var mount in mounts) { mountsTable.AddResolvedMount(mount); } } AbsolutePath specFile = SourceRoot.CreateRelative(Context.PathTable, "TestSpecFile.dsc"); var graph = TestSchedulerFactory.CreateEmptyPipGraph(Context, configuration, mountsTable.MountPathExpander); PipTable = graph.PipTable; PipGraph = graph; var locationData = new LocationData(specFile, 0, 0); var modulePip = ModulePip.CreateForTesting(Context.StringTable, specFile); PipGraph.AddModule(modulePip); PipGraph.AddSpecFile(new SpecFilePip(FileArtifact.CreateSourceFile(specFile), locationData, modulePip.Module)); PipConstructionHelper = PipConstructionHelper.CreateForTesting( Context, ObjectRoot, redirectedRoot: Configuration.Layout.RedirectedDirectory, pipGraph: PipGraph, moduleName: modulePip.Identity.ToString(Context.StringTable), symbol: name, specPath: specFile); Paths = new Paths(PathTable); mountsTable.CompleteInitialization(); }
private bool ConstructAndEvaluateGraph( LoggingContext loggingContext, FrontEndEngineAbstraction frontEndEngineAbstration, CacheInitializationTask engineCacheTask, MountsTable mountsTable, EvaluationFilter evaluationFilter, [CanBeNull] GraphReuseResult reuseResult, out PipGraph pipGraph) { Contract.Requires(frontEndEngineAbstration != null); Contract.Requires(engineCacheTask != null); Contract.Requires(mountsTable != null); pipGraph = null; IPipGraphBuilder pipGraphBuilder = null; if (!AddConfigurationMountsAndCompleteInitialization(loggingContext, mountsTable)) { return(false); } IDictionary <ModuleId, MountsTable> moduleMountsTableMap; if (!mountsTable.PopulateModuleMounts(Configuration.ModulePolicies.Values, out moduleMountsTableMap)) { Contract.Assume(loggingContext.ErrorWasLogged, "An error should have been logged after MountTable.PopulateModuleMounts()"); return(false); } m_visualization?.MountsTable.MakeAvailable(mountsTable); if ((Configuration.Engine.Phase & EnginePhases.Schedule) != 0) { pipGraphBuilder = CreatePipGraphBuilder(loggingContext, mountsTable, reuseResult); } // Have to do some horrible magic here to get to a proper Task<T> with the BuildXL cache since // someone updated the engine cache to be an await style pattern, and there is no way to get to the EngineCache // If the cache was fast to startup, but perhaps blocked itself on first access we wouldn't have to do all these hoops. Func <Task <Possible <EngineCache> > > getBuildCacheTask = async() => { return((await engineCacheTask).Then(engineCache => engineCache.CreateCacheForContext())); }; if (!FrontEndController.PopulateGraph( getBuildCacheTask(), pipGraphBuilder, frontEndEngineAbstration, evaluationFilter, Configuration, m_initialCommandLineConfiguration.Startup)) { LogFrontEndStats(loggingContext); Contract.Assume(loggingContext.ErrorWasLogged, "An error should have been logged after FrontEndController.PopulateGraph()"); return(false); } LogFrontEndStats(loggingContext); // Pip graph must become immutable now that evaluation is done (required to construct a scheduler). return(pipGraphBuilder == null || (pipGraph = pipGraphBuilder.Build()) != null); }