Esempio n. 1
0
        /// <summary>
        /// After a project is loaded or unloaded either add or remove from the file watcher
        /// all test potential items inside that project
        /// </summary>
        private void UpdateTestContainersAndFileWatchers(IEnumerable <TestFileCandidate> files, bool isAdd)
        {
            ChutzpahTracer.TraceInformation("Begin UpdateTestContainersAndFileWatchers");
            Parallel.ForEach(files, file =>
            {
                try
                {
                    if (isAdd)
                    {
                        ChutzpahTracer.TraceInformation("Adding watch on {0}", file.Path);
                        testFilesUpdateWatcher.AddWatch(file.Path);
                        AddTestContainerIfTestFile(file);
                    }
                    else
                    {
                        ChutzpahTracer.TraceInformation("Removing watch on {0}", file.Path);
                        testFilesUpdateWatcher.RemoveWatch(file.Path);
                        RemoveTestContainer(file);
                    }
                }
                catch (Exception e)
                {
                    ChutzpahTracer.TraceError(e, "Failed in UpdateTestContainersAndFileWatchers");
                }
            });

            ChutzpahTracer.TraceInformation("End UpdateTestContainersAndFileWatchers");
        }
        private string GetOutputPath(string filePath, BatchCompileConfiguration compileConfiguration)
        {
            foreach (var pathMap in compileConfiguration.Paths)
            {
                if (filePath.IndexOf(pathMap.SourcePath, StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    // If the configured sourcePath is a full file path we just assume the fileName is the relative name
                    // Otherwise we calculate the relative path from the configured sourcePath to the current file
                    var relativePath = pathMap.SourcePathIsFile ? Path.GetFileName(pathMap.SourcePath) : FileProbe.GetRelativePath(pathMap.SourcePath, filePath);

                    string outputPath = pathMap.OutputPath;
                    if (!pathMap.OutputPathIsFile)
                    {
                        // If output path is not a file we calculate the file path using the input filePath's relative location compared
                        // to the output directory
                        outputPath = Path.Combine(outputPath, relativePath);
                        outputPath = Path.ChangeExtension(outputPath, ".js");
                    }

                    return(outputPath);
                }
            }

            ChutzpahTracer.TraceError("Can't find location for generated path on {0}", filePath);

            return(null);
        }
Esempio n. 3
0
        private ChutzpahWebServerHost BuildHost(string rootPath, int defaultPort, string builtInDependencyFolder)
        {
            var attemptLimit = Constants.WebServerCreationAttemptLimit;
            var success      = false;

            do
            {
                // We can try multiple times to build the webserver. The reason is there is a possible race condition where
                // between when we find a free port and when we start the server that port may have been taken. To mitigate this we
                // can retry to hopefully avoid this issue.
                attemptLimit--;
                var port = FindFreePort(defaultPort);

                try
                {
                    ChutzpahTracer.TraceInformation("Creating Web Server Host at path {0} and port {1}", rootPath, port);
                    var host = new WebHostBuilder()
                               .UseUrls($"http://localhost:{port}")
                               .UseContentRoot(rootPath)
                               .UseWebRoot("")
                               .UseKestrel()
                               .Configure((app) =>
                    {
                        var env = (IHostingEnvironment)app.ApplicationServices.GetService(typeof(IHostingEnvironment));
                        app.UseStaticFiles(new StaticFileOptions
                        {
                            OnPrepareResponse     = AddFileCacheHeaders,
                            ServeUnknownFileTypes = true,
                            FileProvider          = new ChutzpahServerFileProvider(env.ContentRootPath, builtInDependencyFolder)
                        });
                        app.Run(async(context) =>
                        {
                            if (context.Request.Path == "/")
                            {
                                await context.Response.WriteAsync($"Chutzpah Web Server (Version { Assembly.GetEntryAssembly().GetName().Version})");
                            }
                            else
                            {
                                context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                            }
                        });
                    })
                               .Build();

                    host.Start();
                    success = true;

                    return(ChutzpahWebServerHost.Create(host, rootPath, port));
                }
                catch (Exception ex) when(attemptLimit > 0)
                {
                    ChutzpahTracer.TraceError(ex, "Unable to create web server host at path {0} and port {1}. Trying again...", rootPath, port);
                }
            }while (!success && attemptLimit > 0);


            throw new ChutzpahException("Failed to create web server. This should never be hit!");
        }
Esempio n. 4
0
 public void Dispose()
 {
     try
     {
         ChutzpahTracer.TraceInformation("Tearing down Web Server Host at path {0} and port {1}", RootPath, Port);
         IsRunning = false;
         WebHost.Dispose();
     }
     catch (Exception e)
     {
         ChutzpahTracer.TraceError(e, "Error tearing down Web Server Host at path {0} and port {1}", RootPath, Port);
     }
 }
Esempio n. 5
0
        private bool IsTestFile(string path)
        {
            try
            {
                return(HasTestFileExtension(path) && testRunner.IsTestFile(path, settingsMapper.Settings.ChutzpahSettingsFileEnvironmentsWrapper));
            }
            catch (Exception e)
            {
                ChutzpahTracer.TraceError(e, "ChutzpahTestContainerDiscoverer::Error when detecting a test file");
                logger.Log("Error when detecting a test file", "ChutzpahTestContainerDiscoverer", e);
            }

            return(false);
        }
Esempio n. 6
0
 private void SerializeObject(string name, ConcurrentDictionary <string, Tuple <DateTime, string> > objectToSerialize)
 {
     try
     {
         using (var stream = filesystem.Open(name, FileMode.Create, FileAccess.Write))
         {
             binarySerializer.Serialize(stream, objectToSerialize);
         }
     }
     catch (IOException e)
     {
         ChutzpahTracer.TraceError(e, "Failed to save compiler cache");
     }
 }
Esempio n. 7
0
 private void RunBatchCompile(ChutzpahTestSettingsFile testSettings)
 {
     try
     {
         var result = processHelper.RunBatchCompileProcess(testSettings.Compile);
         if (result.ExitCode > 0)
         {
             throw new ChutzpahCompilationFailedException(result.StandardError, testSettings.SettingsFileName);
         }
     }
     catch (Exception e)
     {
         ChutzpahTracer.TraceError(e, "Error during batch compile of {0}", testSettings.SettingsFileName);
         throw new ChutzpahCompilationFailedException(e.Message, testSettings.SettingsFileName, e);
     }
 }
Esempio n. 8
0
 public void Dispose()
 {
     try
     {
         ChutzpahTracer.TraceInformation("Tearing down Web Server Host at path {0} and port {1}", RootPath, Port);
         NancyHost.Dispose();
     }
     catch (Exception e)
     {
         ChutzpahTracer.TraceError(e, "Error tearing down Web Server Host at path {0} and port {1}", RootPath, Port);
     }
     finally
     {
         // Set active server to null
         Interlocked.Exchange(ref activeWebServer, null);
     }
 }
Esempio n. 9
0
        public static string GetBrowserPath(string browserName)
        {
            var browserPath = string.Empty;

            try
            {
                if (!string.IsNullOrEmpty(browserName))
                {
                    browserPath = GetBrowserPathFromRegistry(browserName);
                }

                if (string.IsNullOrEmpty(browserPath))
                {
                    browserPath = GetSystemDefaultBrowser();
                }
            }
            catch (Exception e)
            {
                ChutzpahTracer.TraceError(e, "Unable to read browser path from registry");
            }

            return(browserPath);
        }
Esempio n. 10
0
        public void Compile(IEnumerable <TestContext> testContexts)
        {
            // Group the test contexts by test settings to run batch aware settings like compile
            // For each test settings file that defines a compile step we will run it and update
            // testContexts reference files accordingly.
            var groupedTestContexts = testContexts.GroupBy(x => x.TestFileSettings);

            foreach (var contextGroup in groupedTestContexts)
            {
                var testSettings = contextGroup.Key;

                // If there is no compile setting then nothing to do here
                if (testSettings.Compile == null)
                {
                    continue;
                }

                // Build the mapping from source to output files and gather properties about them
                var filePropeties = (
                    from file in contextGroup.SelectMany(x => x.ReferencedFiles).Distinct()
                    where testSettings.Compile.Extensions.Any(x => file.Path.EndsWith(x, StringComparison.OrdinalIgnoreCase))
                    let sourceProperties = GetFileProperties(file.Path)
                                           let sourceHasOutput = !testSettings.Compile.ExtensionsWithNoOutput.Any(x => file.Path.EndsWith(x, StringComparison.OrdinalIgnoreCase))
                                                                 let outputPath = GetOutputPath(file.Path, testSettings.Compile)
                                                                                  let outputProperties = sourceHasOutput ? GetFileProperties(outputPath) : null
                                                                                                         select new SourceCompileInfo {
                    SourceProperties = sourceProperties, OutputProperties = outputProperties, SourceHasOutput = sourceHasOutput
                }).ToList();

                var outputPathMap = filePropeties
                                    .Where(x => x.SourceHasOutput)
                                    .ToDictionary(x => x.SourceProperties.Path, x => x.OutputProperties.Path, StringComparer.OrdinalIgnoreCase);

                // Check if the batch compile is needed
                var shouldCompile = CheckIfCompileIsNeeded(testSettings, filePropeties);

                // Run the batch compile if necessary
                if (shouldCompile)
                {
                    if (testSettings.Compile.Mode == BatchCompileMode.Executable)
                    {
                        RunBatchCompile(testSettings);
                    }
                    else if (testSettings.Compile.Mode == BatchCompileMode.External)
                    {
                        ChutzpahTracer.TraceError("Chutzpah determined generated .js files are missing but the compile mode is External so Chutzpah can't compile them. Test results may be wrong.");
                    }
                }
                else
                {
                    ChutzpahTracer.TraceInformation("Skipping batch compile since all files are supdate to date for {0}", testSettings.SettingsFileName);
                }

                // Now that compile finished set generated path on  all files who match the compiled extensions
                var filesToUpdate = contextGroup.SelectMany(x => x.ReferencedFiles)
                                    .Where(x => outputPathMap.ContainsKey(x.Path));

                foreach (var file in filesToUpdate)
                {
                    var outputPath = outputPathMap[file.Path];
                    if (outputPath != null && fileSystem.FileExists(outputPath))
                    {
                        file.GeneratedFilePath = outputPath;
                        ChutzpahTracer.TraceInformation("Found generated path for {0} at {1}", file.Path, outputPath);
                    }
                    else
                    {
                        ChutzpahTracer.TraceWarning("Couldn't find generated path for {0} at {1}", file.Path, outputPath);
                    }

                    if (!string.IsNullOrWhiteSpace(file.GeneratedFilePath))
                    {
                        file.SourceMapFilePath = testSettings.Compile.UseSourceMaps ? sourceMapDiscoverer.FindSourceMap(file.GeneratedFilePath) : null;
                    }
                }
            }
        }
        public void Compile(IEnumerable <TestContext> testContexts, ITestMethodRunnerCallback callback = null)
        {
            // Group the test contexts by test settings to run batch aware settings like compile
            // For each test settings file that defines a compile step we will run it and update
            // testContexts reference files accordingly.
            var groupedTestContexts = testContexts.GroupBy(x => x.TestFileSettings);

            foreach (var contextGroup in groupedTestContexts)
            {
                var testSettings = contextGroup.Key;

                // If there is no compile setting then nothing to do here
                if (testSettings.Compile == null)
                {
                    continue;
                }

                // Build the mapping from source to output files and gather properties about them
                var filePropeties = (
                    from file in contextGroup.SelectMany(x => x.ReferencedFiles).Where(x => !x.IsBuiltInDependency).Distinct()
                    where testSettings.Compile.Extensions.Any(x => file.Path.EndsWith(x, StringComparison.OrdinalIgnoreCase))
                    let sourceProperties = GetFileProperties(file.Path)
                                           let sourceHasOutput = !testSettings.Compile.ExtensionsWithNoOutput.Any(x => file.Path.EndsWith(x, StringComparison.OrdinalIgnoreCase))
                                                                 let outputPath = GetOutputPath(file.Path, testSettings.Compile)
                                                                                  let outputProperties = sourceHasOutput ? GetFileProperties(outputPath) : null
                                                                                                         select new SourceCompileInfo {
                    SourceProperties = sourceProperties, OutputProperties = outputProperties, SourceHasOutput = sourceHasOutput
                }).ToList();

                var outputPathMap = filePropeties
                                    .Where(x => x.SourceHasOutput)
                                    .ToDictionary(x => x.SourceProperties.Path, x => x.OutputProperties.Path, StringComparer.OrdinalIgnoreCase);

                // Check if the batch compile is needed
                var shouldCompile = CheckIfCompileIsNeeded(testSettings, filePropeties);

                // Run the batch compile if necessary
                if (shouldCompile)
                {
                    if (testSettings.Compile.Mode == BatchCompileMode.Executable)
                    {
                        RunBatchCompile(testSettings);
                    }
                    else
                    {
                        ChutzpahTracer.TraceWarning("Chutzpah determined generated .js files are missing but the compile mode is External so Chutzpah can't compile them. Test results may be wrong.");
                    }
                }
                else
                {
                    ChutzpahTracer.TraceInformation("Skipping batch compile since all files are update to date for {0}", testSettings.SettingsFileName);
                }

                // Now that compile finished set generated path on  all files who match the compiled extensions
                var filesToUpdate = contextGroup.SelectMany(x => x.ReferencedFiles)
                                    .Where(x => outputPathMap.ContainsKey(x.Path));

                foreach (var file in filesToUpdate)
                {
                    var outputPath = outputPathMap[file.Path];
                    if (outputPath != null && fileSystem.FileExists(outputPath))
                    {
                        file.GeneratedFilePath = outputPath;
                        ChutzpahTracer.TraceInformation("Found generated path for {0} at {1}", file.Path, outputPath);
                    }
                    else
                    {
                        // If we could not find the file at the configured path attempt to see if it co-located
                        ChutzpahTracer.TraceInformation("Unable to find generated path at configured location so attempting to see if generated file is co-located.");
                        var coLocatedOutputPath = Path.ChangeExtension(file.Path, ".js");
                        if (fileSystem.FileExists(coLocatedOutputPath))
                        {
                            file.GeneratedFilePath = coLocatedOutputPath;
                            ChutzpahTracer.TraceInformation("Found generated path for {0} at {1}", file.Path, coLocatedOutputPath);
                        }
                        else
                        {
                            var error = string.Format("Couldn't find generated path for {0} at {1} or at {2}", file.Path, outputPath, coLocatedOutputPath);
                            ChutzpahTracer.TraceError(error);

                            if (!testSettings.Compile.IgnoreMissingFiles.GetValueOrDefault())
                            {
                                // Throw and fail here since if we cant find the file we cannot be sure anything will run
                                var exception = new FileNotFoundException(error, outputPath);
                                callback.ExceptionThrown(exception, outputPath);
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(file.GeneratedFilePath))
                    {
                        file.SourceMapFilePath = testSettings.Compile.UseSourceMaps.GetValueOrDefault() ? sourceMapDiscoverer.FindSourceMap(file.GeneratedFilePath) : null;
                    }
                }
            }
        }