Beispiel #1
0
 /**
  * @brief initialization WITHOUT Visual Studio services available.
  */
 public CTestAdapterPackage()
 {
     if (null != Instance)
     {
         /// @todo give some error here!
     }
     Instance = this;
     // main DTE object
     this._dte = (DTE)Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider.GetService(typeof(DTE));
     // basic solution events
     this._log = new CTestAdapterLog();
     this._sol = new SolutionEventListener(Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider);
     this._sol.SolutionLoaded   += this.SolutionLoaded;
     this._sol.SolutionUnloaded += this.SolutionUnloaded;
     // cmake cache & cmake test file
     this._config            = new CTestAdapterConfig();
     this._cmakeCache        = new CMakeCache(this._log);
     this._cMakeCacheWatcher = new CMakeCacheWatcher(this._log);
     this._cMakeCacheWatcher.CacheFileChanged += this.OnCMakeCacheChanged;
     // test container discovery and management
     this._containerManager                        = new TestContainerManager(this, this._log);
     this._activeConfigurationTimer                = new System.Timers.Timer(CTestAdapterPackage.ConfigurationTimerIntervalMs);
     this._activeConfigurationTimer.Elapsed       += this.UpdateActiveConfiguration;
     this._containerManager.TestContainersChanged += this.OnTestContainersChanged;
     this.SetValidRelease();
 }
        public static CTestTestCollection FindAllTestsWithCtest(CTestAdapterConfig cfg)
        {
            if (null == cfg)
            {
                return(null);
            }
            if (!Directory.Exists(cfg.CacheDir))
            {
                return(null);
            }
            if (!File.Exists(cfg.CTestExecutable))
            {
                return(null);
            }
            var collection = new CTestTestCollection();
            var collector  = new CTestTestCollector
            {
                CTestExecutable     = cfg.CTestExecutable,
                CTestWorkingDir     = cfg.CacheDir,
                CurrentActiveConfig = cfg.ActiveConfiguration
            };

            collector.CollectTestCases(collection);
            return(collection);
        }
Beispiel #3
0
        private void UpdateActiveConfiguration(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            if (!this._ctestAdapterEnabled)
            {
                return;
            }
            // set current active configuration
            var p = this._dte.Solution.SolutionBuild;

            if (null == p)
            {
                return;
            }
            var sc = p.ActiveConfiguration;

            if (null == sc)
            {
                return;
            }
            var name = sc.Name;

            if (this._config.ActiveConfiguration == name)
            {
                return;
            }
            this._config.ActiveConfiguration = name;
            CTestAdapterConfig.WriteToDisk(this._config);
            this._containerManager.FindTestContainers();
        }
Beispiel #4
0
        public static CTestAdapterConfig ReadFromDisk(string file)
        {
            if (!File.Exists(file))
            {
                return(null);
            }
            var ser = new XmlSerializer(typeof(CTestAdapterConfig));

            while (CTestAdapterConfig.IsFileLocked(file))
            {
                Thread.Sleep(50);
            }
            var str = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
            var cfg = (CTestAdapterConfig)ser.Deserialize(str);

            str.Close();
            if (null == cfg)
            {
                return(null);
            }
            if (cfg._configFileName != file)
            {
                // @todo give some message here?
            }
            return(cfg);
        }
Beispiel #5
0
        public static CTestAdapterConfig ReadFromCache(string dir)
        {
            if (!Directory.Exists(dir))
            {
                return(null);
            }
            ILog log = null;
            var  pkg = CTestAdapterPackage.Instance;

            if (null != pkg)
            {
                log = pkg.Logger;
            }
            var cache = new CMakeCache(log);

            cache.LoadCMakeCache(Path.Combine(dir, Constants.CMakeCacheFilename));
            if (!cache.IsLoaded)
            {
                return(null);
            }
            var cfg = new CTestAdapterConfig
            {
                // unfortunately we cannot set the active configuration here,
                // a fallback will be used when parsing
                CMakeConfigurationTypes = cache[Constants.CMakeCacheKey_CofigurationTypes],
                CTestExecutable         = cache[Constants.CMakeCacheKey_CTestCommand],
                CacheDir = cache[Constants.CMakeCacheKey_CacheFileDir]
            };

            return(cfg);
        }
Beispiel #6
0
        private bool SetupEnvironment(string source)
        {
            var cacheDir = TestContainerHelper.FindCMakeCacheDirectory(source);

            this._config = CTestAdapterConfig.ReadFromDisk(Path.Combine(cacheDir, Constants.CTestAdapterConfigFileName)) ??
                           CTestAdapterConfig.ReadFromCache(cacheDir);
            if (this._config == null)
            {
                this.Log(TestMessageLevel.Error, "could not initialize environment");
                return(false);
            }
            return(true);
        }
Beispiel #7
0
        private void OnCMakeCacheChanged()
        {
            var cacheFileName =
                Path.Combine(this._cMakeCacheWatcher.CMakeCacheDirectory, this._cMakeCacheWatcher.CMakeCacheFile);
            var testFileName =
                Path.Combine(this._cMakeCacheWatcher.CMakeCacheDirectory, Constants.CTestTestFileName);

            this._cmakeCache.LoadCMakeCache(cacheFileName);
            var enabled = true;

            if (!this._cmakeCache.IsLoaded)
            {
                this.Log(LogLevel.Warning, "OnCMakeCacheChanged (cache not loaded)");
                enabled = false;
            }
            if (!File.Exists(testFileName))
            {
                this.Log(LogLevel.Warning, "OnCMakeCacheChanged file not found: " + testFileName);
                enabled = false;
            }
            if (this._cmakeCache[Constants.CMakeCacheKey_CTestCommand] == string.Empty)
            {
                this.Log(LogLevel.Warning, "OnCMakeCacheChanged ctest not found in cache");
                enabled = false;
            }
            var ctest = this._cmakeCache[Constants.CMakeCacheKey_CTestCommand];

            if (!File.Exists(ctest))
            {
                this.Log(LogLevel.Warning, "OnCMakeCacheChanged ctest executable not found: " + ctest);
                enabled = false;
            }
            this._config.CTestExecutable         = ctest;
            this._config.CMakeConfigurationTypes = this._cmakeCache[Constants.CMakeCacheKey_CofigurationTypes];
            CTestAdapterConfig.WriteToDisk(this._config);
            if (this._ctestAdapterEnabled != enabled)
            {
                this.CTestAdapterEnabled = enabled;
            }
            this._containerManager.FindTestContainers();
        }
Beispiel #8
0
        public static void WriteToDisk(CTestAdapterConfig cfg)
        {
            if (!cfg._dirty)
            {
                return;
            }
            if (!Directory.Exists(cfg.CacheDir))
            {
                return;
            }
            var ser = new XmlSerializer(typeof(CTestAdapterConfig));

            while (CTestAdapterConfig.IsFileLocked(cfg._configFileName))
            {
                Thread.Sleep(50);
            }
            var str = new StreamWriter(cfg._configFileName);

            ser.Serialize(str, cfg);
            str.Close();
            cfg._dirty = false;
        }
Beispiel #9
0
        public void LoadCMakeCache(string fileName)
        {
            this._cmakeCacheFile = fileName;
            if (null == this._cmakeCacheFile || !File.Exists(this._cmakeCacheFile))
            {
                this.Log(LogLevel.Debug, "LoadCMakeCache: clearing cmake CMakeCache");
                this._cacheEntries.Clear();
                return;
            }
            var newInfo = new FileInfo(this._cmakeCacheFile);

            if (this._cmakeCacheInfo != null)
            {
                this.Log(LogLevel.Debug, "LoadCMakeCache: comparing already loaded CMakeCache");
                if (this._cmakeCacheInfo.FullName == newInfo.FullName &&
                    this._cmakeCacheInfo.LastWriteTime == newInfo.LastWriteTime &&
                    newInfo.Exists)
                {
                    this.Log(LogLevel.Debug, "LoadCMakeCache: CMakeCache did not change, not reloading");
                    return;
                }
            }
            this.Log(LogLevel.Debug, "LoadCMakeCache: loading CMakeCache from \"" + this._cmakeCacheFile + "\"");
            this._cmakeCacheInfo = newInfo;
            this._cacheEntries.Clear();
            if (!File.Exists(this._cmakeCacheFile))
            {
                this.Log(LogLevel.Error, "LoadCMakeCache: CMakeCache not found at:\"" + this._cmakeCacheFile + "\"");
                return;
            }
            while (CTestAdapterConfig.IsFileLocked(this._cmakeCacheFile))
            {
                Thread.Sleep(50);
            }
            var stream = new FileStream(this._cmakeCacheFile, FileMode.Open,
                                        FileAccess.Read, FileShare.ReadWrite);
            var r = new StreamReader(stream);

            while (!r.EndOfStream)
            {
                var line = r.ReadLine();
                if (null == line)
                {
                    continue;
                }
                line = line.TrimStart(' ');
                if (line.Length == 0 || line.StartsWith("#") || line.StartsWith("//"))
                {
                    continue;
                }
                var c = CMakeCache.CacheEntryRegex.Split(line);
                if (c.Length != 5)
                {
                    this.Log(LogLevel.Warning, "LoadCMakeCache: CMakeCache load: element count != 5: (" + c.Length + ")" + line);
                    var count = 0;
                    foreach (var asdf in c)
                    {
                        this.Log(LogLevel.Warning, "v" + count + ": " + asdf);
                        count++;
                    }
                    continue;
                }
                CMakeCacheEntryType myType;
                if (!Enum.TryParse(c[2], out myType))
                {
                    this.Log(LogLevel.Error, "LoadCMakeCache: cache load: error parsing enum Type: " + c[2]);
                    continue;
                }
                var entry = new CMakeCacheEntry()
                {
                    Name  = c[1],
                    Value = c[3]
                };
                if (entry.Name.StartsWith("\"") && entry.Name.Length > 2)
                {
                    entry.Name = entry.Name.Substring(1, entry.Name.Length - 2);
                }
                this._cacheEntries.Add(entry.Name, entry);
            }
            r.Close();
            stream.Close();
            r.Dispose();
            stream.Dispose();
        }
Beispiel #10
0
        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");
        }