Beispiel #1
0
        private bool CreateFactories(
            FrontEndContext frontEndContext,
            TestEngineAbstraction engineAbstraction,
            FrontEndStatistics frontEndStatistics,
            ICommandLineConfiguration configuration,
            out AmbientTesting ambientTesting,
            out ModuleRegistry moduleRegistry,
            out FrontEndFactory frontEndFactory)
        {
            moduleRegistry = new ModuleRegistry(frontEndContext.SymbolTable);
            ambientTesting = new AmbientTesting(engineAbstraction, GetAllDiagnostics, moduleRegistry.PrimitiveTypes);
            ambientTesting.Initialize(moduleRegistry.GlobalLiteral);

            var ambientAssert = new AmbientAssert(moduleRegistry.PrimitiveTypes);

            ambientAssert.Initialize(moduleRegistry.GlobalLiteral);

            // Create the controller
            frontEndFactory = new FrontEndFactory();
            frontEndFactory.SetConfigurationProcessor(new TestConfigProcessor(configuration));
            frontEndFactory.AddFrontEnd(
                new DScriptFrontEnd(
                    frontEndStatistics,
                    logger: m_astLogger));

            if (!frontEndFactory.TrySeal(frontEndContext.LoggingContext))
            {
                HandleDiagnostics();
                return(false);
            }

            return(true);
        }
Beispiel #2
0
        private bool CreateFactories(
            FrontEndContext frontEndContext,
            TestEngineAbstraction engineAbstraction,
            FrontEndStatistics frontEndStatistics,
            ICommandLineConfiguration configuration,
            out AmbientTesting ambientTesting,
            out DScriptWorkspaceResolverFactory workspaceFactory,
            out FrontEndFactory frontEndFactory)
        {
            var globalConstants = new GlobalConstants(frontEndContext.SymbolTable);

            ambientTesting = new AmbientTesting(engineAbstraction, GetAllDiagnostics, globalConstants.KnownTypes);
            ambientTesting.Initialize(globalConstants.Global);

            var ambientAssert = new AmbientAssert(globalConstants.KnownTypes);

            ambientAssert.Initialize(globalConstants.Global);

            var sharedModuleRegistry = new ModuleRegistry();

            workspaceFactory = new DScriptWorkspaceResolverFactory();
            workspaceFactory.RegisterResolver(
                KnownResolverKind.DScriptResolverKind,
                () => new WorkspaceSourceModuleResolver(globalConstants, sharedModuleRegistry, frontEndStatistics));
            workspaceFactory.RegisterResolver(
                KnownResolverKind.SourceResolverKind,
                () => new WorkspaceSourceModuleResolver(globalConstants, sharedModuleRegistry, frontEndStatistics));
            workspaceFactory.RegisterResolver(
                KnownResolverKind.DefaultSourceResolverKind,
                () => new WorkspaceDefaultSourceModuleResolver(globalConstants, sharedModuleRegistry, frontEndStatistics));

            // Create the controller
            frontEndFactory = new FrontEndFactory();
            frontEndFactory.SetConfigurationProcessor(new TestConfigProcessor(configuration));
            frontEndFactory.AddFrontEnd(
                new DScriptFrontEnd(
                    globalConstants,
                    sharedModuleRegistry,
                    frontEndStatistics,
                    logger: m_astLogger));

            if (!frontEndFactory.TrySeal(frontEndContext.LoggingContext))
            {
                HandleDiagnostics();
                return(false);
            }

            return(true);
        }
Beispiel #3
0
        /// <summary>
        /// Run the test
        /// </summary>
        public bool Run(string testFolder, string specFile, string fullIdentifier, string shortName, string lkgFile, params string[] sdksToResolve)
        {
            Contract.Requires(!string.IsNullOrEmpty(testFolder));
            Contract.Requires(!string.IsNullOrEmpty(specFile));
            Contract.Requires(sdksToResolve != null);

            // Sadly the frontend doesn't use the engine abstractions file api's so we have to materialize stuff on disk for now...
            // TODO: Fix this code once the frontend supports a proper virtual FileSystem.
            // TODO: Change the package semantics to implicit when we expose a way to evaluate a single value
            var testFileName = Path.GetFileName(specFile);
            var mainFileName = "testMain.bp";
            var testMainFile = Path.Combine(testFolder, mainFileName);

            Directory.CreateDirectory(testFolder);
            File.WriteAllText(Path.Combine(testFolder, Names.ModuleConfigBm), I($@"module(
{{
    name: 'TestPackage',
    nameResolutionSemantics: NameResolutionSemantics.implicitProjectReferences, 
    projects: [
        f`{mainFileName}`,
        f`{testFileName}`,
    ],
}});"));
            File.WriteAllText(testMainFile, I($@"
export const testFolder = d`{Path.GetDirectoryName(specFile).Replace('\\', '/')}`;

@@public
export const main = {fullIdentifier}();"));
            File.Copy(specFile, Path.Combine(testFolder, testFileName));

            // Create a fake package for Sdk.TestRunner so that you can safely test packages that have the tests embedded in them.
            var testRunnerFolder = Path.Combine(testFolder, "Sdk.TestRunner");

            Directory.CreateDirectory(testRunnerFolder);
            File.WriteAllText(Path.Combine(testRunnerFolder, Names.ModuleConfigBm), I($"module({{\n\tname: 'Sdk.TestRunner',\n}});"));
            File.WriteAllText(Path.Combine(testRunnerFolder, "package" + Names.DotDscExtension), I($@"
export interface TestArguments {{
    testFiles: File[];
    sdkFolders?: (Directory|StaticDirectory)[];
    autoFixLkgs?: boolean;
}}
export interface TestResult {{
    xmlResults: File;
}}
export function test(args: TestArguments): TestResult {{
    Contract.fail(""Can't run a DScript UnitTest inside of a DScript UnitTest"");
}}"));

            // Setup Context and configuration
            var frontEndContext = FrontEndContext.CreateInstanceForTesting();
            var pipContext      = new SchedulerContext(CancellationToken.None, frontEndContext.StringTable, frontEndContext.PathTable, frontEndContext.SymbolTable, frontEndContext.QualifierTable);
            var pathTable       = frontEndContext.PathTable;
            var testFolderPath  = AbsolutePath.Create(pathTable, testFolder);

            var configuration = CreateConfiguration(sdksToResolve.Union(new[] { testRunnerFolder }), pathTable, testFolderPath);

            var engineAbstraction = new TestEngineAbstraction(pathTable, frontEndContext.StringTable, testFolderPath, new PassThroughFileSystem(pathTable));

            var frontEndStatistics = new FrontEndStatistics();

            if (!CreateFactories(
                    frontEndContext,
                    engineAbstraction,
                    frontEndStatistics,
                    configuration,
                    out var ambientTesting,
                    out var moduleRegistry,
                    out var frontEndFactory))
            {
                return(false);
            }

            // Set the timeout to a large number to avoid useless performance collections in tests.
            using (var performanceCollector = new PerformanceCollector(TimeSpan.FromHours(1)))
                using (var frontEndHostController = new FrontEndHostController(
                           frontEndFactory,
                           new EvaluationScheduler(1),
                           moduleRegistry,
                           frontEndStatistics,
                           m_tracingLogger,
                           performanceCollector,
                           collectMemoryAsSoonAsPossible: true))
                {
                    var frontEndController = (IFrontEndController)frontEndHostController;
                    frontEndController.InitializeHost(frontEndContext, configuration);
                    frontEndController.ParseConfig(configuration);

                    // Populate the graph
                    using (var pipTable = new PipTable(
                               pipContext.PathTable,
                               pipContext.SymbolTable,
                               initialBufferSize: 16384,
                               maxDegreeOfParallelism: 1,
                               debug: true))
                    {
                        var mountPathExpander = new MountPathExpander(pathTable);
                        mountPathExpander.Add(pathTable, new SemanticPathInfo(PathAtom.Create(frontEndContext.StringTable, "testFolder"), testFolderPath, allowHashing: true, readable: true, writable: false));
                        mountPathExpander.Add(pathTable, new SemanticPathInfo(PathAtom.Create(frontEndContext.StringTable, "src"), testFolderPath.Combine(pathTable, "src"), allowHashing: true, readable: true, writable: true));
                        mountPathExpander.Add(pathTable, new SemanticPathInfo(PathAtom.Create(frontEndContext.StringTable, "out"), testFolderPath.Combine(pathTable, "out"), allowHashing: true, readable: true, writable: true));
                        mountPathExpander.Add(pathTable, new SemanticPathInfo(PathAtom.Create(frontEndContext.StringTable, "noRead"), testFolderPath.Combine(pathTable, "noRead"), allowHashing: true, readable: false, writable: true));
                        mountPathExpander.Add(pathTable, new SemanticPathInfo(PathAtom.Create(frontEndContext.StringTable, "temp"), engineAbstraction.Layout.TempDirectory, allowHashing: true, readable: true, writable: true));
                        mountPathExpander.Add(pathTable, new SemanticPathInfo(PathAtom.Create(frontEndContext.StringTable, "obj"), engineAbstraction.Layout.ObjectDirectory, allowHashing: true, readable: true, writable: true));

                        var graph = new PipGraph.Builder(
                            pipTable,
                            pipContext,
                            m_pipLogger,
                            frontEndContext.LoggingContext,
                            configuration,
                            mountPathExpander);

                        using (var cacheLayer = new EngineCache(
                                   new InMemoryArtifactContentCache(),
                                   new InMemoryTwoPhaseFingerprintStore()))
                        {
                            var cache = Task.FromResult(Possible.Create(cacheLayer));
                            try
                            {
                                var evaluationFilter = new EvaluationFilter(
                                    pipContext.SymbolTable,
                                    pipContext.PathTable,
                                    new FullSymbol[0],
                                    new[]
                                {
                                    AbsolutePath.Create(frontEndContext.PathTable, testMainFile),
                                },
                                    CollectionUtilities.EmptyArray <StringId>());
                                if (!frontEndController.PopulateGraph(cache, graph, engineAbstraction, evaluationFilter, configuration, configuration.Startup))
                                {
                                    HandleDiagnostics();
                                    return(false);
                                }
                            }
                            catch (AggregateException e)
                            {
                                var baseException = e.GetBaseException();
                                if (baseException is XunitException)
                                {
                                    // If it is an XUnit assert, then unwrap the exception and throw that because XUnit other doesn't display the error nicely.
                                    ExceptionDispatchInfo.Capture(baseException).Throw();
                                }

                                throw;
                            }
                        }

                        if (!ValidatePips(frontEndContext, graph, testFolderPath, specFile, shortName, lkgFile, ambientTesting.DontValidatePipsEnabled))
                        {
                            return(false);
                        }
                    }
                }

            HandleDiagnostics();
            return(true);
        }