public static string FindCTestExe(string basePath) { var file = new FileInfo(Path.Combine(basePath, Constants.CTestExecutableName)); if (file.Exists) { return(file.FullName); } var cdir = new DirectoryInfo(basePath); var subdirs = cdir.GetDirectories(); foreach (var dir in subdirs) { var res = TestContainerHelper.FindCTestExe(dir.FullName); if (res != string.Empty) { return(res); } } return(string.Empty); }
public void DiscoverTests(IEnumerable <string> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) { this._log = logger; this.Log(TestMessageLevel.Informational, "discovering ..."); var v = sources as IList <string> ?? sources.ToList(); // verify we have a CMakeCache.txt directory var cacheDir = TestContainerHelper.FindCMakeCacheDirectory(v.First()); if (!cacheDir.Any()) { this.Log(TestMessageLevel.Informational, "cmake cache not found"); return; } // read parameters var cfg = CTestAdapterConfig.ReadFromDisk(Path.Combine(cacheDir, Constants.CTestAdapterConfigFileName)) ?? CTestAdapterConfig.ReadFromCache(cacheDir); if (null == cfg) { this.Log(TestMessageLevel.Error, "could not create CTestAdapterConfig"); return; } // make sure a configuration is set if (!cfg.ActiveConfiguration.Any()) { if (cfg.TrySetActiveConfigFromConfigTypes()) { this.Log(TestMessageLevel.Warning, "Configuration fallback to: " + cfg.ActiveConfiguration); } else { this.Log(TestMessageLevel.Error, "could not set Configuration"); return; } } this.Log(TestMessageLevel.Informational, "using configuration: " + cfg.ActiveConfiguration); // make sure we have a ctest executable if (!File.Exists(cfg.CTestExecutable)) { cfg.CTestExecutable = TestContainerHelper.FindCTestExe(cfg.CacheDir); } if (!File.Exists(cfg.CTestExecutable)) { this.Log(TestMessageLevel.Error, "ctest not found, tried: \"" + cfg.CTestExecutable + "\""); return; } this.Log(TestMessageLevel.Informational, "using ctest binary: " + cfg.CTestExecutable); // collect all existing tests by executing ctest var collection = TestContainerHelper.FindAllTestsWithCtest(cfg); foreach (var source in v) { var cases = TestContainerHelper.ParseTestContainerFile(source, this._log, collection, cfg.ActiveConfiguration); foreach (var c in cases) { discoverySink.SendTestCase(c.Value); } } this.Log(TestMessageLevel.Informational, "discovering done"); }
public void RunTests(IEnumerable <TestCase> tests, IRunContext runContext, IFrameworkHandle frameworkHandle) { this._log = frameworkHandle; this.Log(TestMessageLevel.Informational, "running tests ..."); var testCases = tests as IList <TestCase> ?? tests.ToList(); if (!testCases.Any()) { return; } if (!this._runningFromSources) { if (!this.SetupEnvironment(testCases.First().Source)) { return; } } // make sure a configuration is set if (!this._config.ActiveConfiguration.Any()) { if (this._config.TrySetActiveConfigFromConfigTypes()) { this.Log(TestMessageLevel.Warning, "Configuration fallback to: " + this._config.ActiveConfiguration); } else { this.Log(TestMessageLevel.Error, "could not set Configuration"); return; } } // make sure we have a ctest executable if (!File.Exists(this._config.CTestExecutable)) { this._config.CTestExecutable = TestContainerHelper.FindCTestExe(this._config.CacheDir); } if (!File.Exists(this._config.CTestExecutable)) { this.Log(TestMessageLevel.Error, "ctest not found, tried: \"" + this._config.CTestExecutable + "\""); return; } if (!Directory.Exists(this._config.CacheDir)) { this.Log(TestMessageLevel.Error, "working directory not found: " + TestContainerHelper.ToLinkPath(this._config.CacheDir)); return; } this.Log(TestMessageLevel.Informational, "working directory is " + TestContainerHelper.ToLinkPath(this._config.CacheDir)); var logFileDir = this._config.CacheDir + "\\Testing\\Temporary"; if (!this._runningFromSources) { this.Log(TestMessageLevel.Informational, "ctest (" + this._config.CTestExecutable + ")"); this.Log(TestMessageLevel.Informational, "logs are written to (" + TestContainerHelper.ToLinkPath(logFileDir) + ")"); } this._parentProcess = Process.GetCurrentProcess(); this._ctestProcess = new Process(); if (this._procParam == null) { this._procParam = new ProcessStartInfo { CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, WindowStyle = ProcessWindowStyle.Hidden }; } // run test cases foreach (var test in testCases) { var testResult = new TestResult(test) { ComputerName = Environment.MachineName, Outcome = TestOutcome.Skipped }; // verify we have a run directory and a ctest executable var args = "-R \"^" + test.FullyQualifiedName + "$\""; if (this._config.ActiveConfiguration.Any()) { args += " -C \"" + this._config.ActiveConfiguration + "\""; } this._procParam.Arguments = args; this._procParam.FileName = this._config.CTestExecutable; this._procParam.WorkingDirectory = this._config.CacheDir; this._ctestProcess.StartInfo = this._procParam; var logFileName = logFileDir + "\\LastTest.log"; if (File.Exists(logFileName)) { File.Delete(logFileName); } var logMsg = "ctest " + test.FullyQualifiedName; if (this._config.ActiveConfiguration.Any()) { logMsg += " -C " + this._config.ActiveConfiguration; } this.Log(TestMessageLevel.Informational, logMsg); if (this._cancelled) { break; } if (runContext.IsBeingDebugged) { /// @todo check if child process debugging is available?!? this._ctestProcess.Start(); } else { this._ctestProcess.Start(); } this._ctestProcess.WaitForExit(); if (this._cancelled) { break; } var output = this._ctestProcess.StandardOutput.ReadToEnd(); if (!File.Exists(logFileName)) { this.Log(TestMessageLevel.Warning, "logfile not found: " + TestContainerHelper.ToLinkPath(logFileName)); } var content = File.ReadAllText(logFileName); var logFileBackup = test.FullyQualifiedName + ".log"; var invalidChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); foreach (char c in invalidChars) { logFileBackup = logFileBackup.Replace(c.ToString(), "_"); } logFileBackup = logFileDir + "\\" + logFileBackup; File.Copy(logFileName, logFileBackup, true); var matchesDuration = CTestExecutor.RegexDuration.Match(content); var timeSpan = new TimeSpan(); if (matchesDuration.Success) { timeSpan = TimeSpan.FromSeconds( double.Parse(matchesDuration.Groups[CTestExecutor.RegexFieldDuration].Value, System.Globalization.CultureInfo.InvariantCulture.NumberFormat)); } else { this.Log(TestMessageLevel.Warning, "could not get runtime of test " + test.FullyQualifiedName); } testResult.Duration = timeSpan; testResult.Outcome = this._ctestProcess.ExitCode == 0 ? TestOutcome.Passed : TestOutcome.Failed; if (this._ctestProcess.ExitCode != 0) { var matchesOutput = CTestExecutor.RegexOutput.Match(content); testResult.ErrorMessage = matchesOutput.Groups[CTestExecutor.RegexFieldOutput].Value; this.Log(TestMessageLevel.Error, "ERROR IN TEST " + test.FullyQualifiedName + ":"); this.Log(TestMessageLevel.Error, output); this.Log(TestMessageLevel.Error, "END OF TEST OUTPUT FROM " + test.FullyQualifiedName); } this.Log(TestMessageLevel.Informational, "Log saved to " + TestContainerHelper.ToLinkPath(logFileBackup)); frameworkHandle.RecordResult(testResult); } this._ctestProcess.Dispose(); this._ctestProcess = null; this._parentProcess = null; this.Log(TestMessageLevel.Informational, "running tests done"); }