public void AnalysisConfGen_Simple() { // Arrange string analysisDir = TestUtils.CreateTestSpecificFolder(this.TestContext); TestLogger logger = new TestLogger(); ListPropertiesProvider propertyProvider = new ListPropertiesProvider(); propertyProvider.AddProperty(SonarProperties.HostUrl, "http://foo"); ProcessedArgs args = new ProcessedArgs("valid.key", "valid.name", "1.0", false, EmptyPropertyProvider.Instance, propertyProvider); TeamBuildSettings tbSettings = TeamBuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir); Dictionary<string, string> serverSettings = new Dictionary<string, string>(); serverSettings.Add("server.key.1", "server.value.1"); AnalyzerSettings analyzerSettings = new AnalyzerSettings(); analyzerSettings.RuleSetFilePath = "c:\\xxx.ruleset"; analyzerSettings.AdditionalFilePaths = new List<string>(); analyzerSettings.AdditionalFilePaths.Add("f:\\additionalPath1.txt"); analyzerSettings.AnalyzerAssemblyPaths = new List<string>(); analyzerSettings.AnalyzerAssemblyPaths.Add("f:\\temp\\analyzer1.dll"); Directory.CreateDirectory(tbSettings.SonarConfigDirectory); // config directory needs to exist // Act AnalysisConfig actualConfig = AnalysisConfigGenerator.GenerateFile(args, tbSettings, serverSettings, analyzerSettings, logger); // Assert AssertConfigFileExists(actualConfig); logger.AssertErrorsLogged(0); logger.AssertWarningsLogged(0); Assert.AreEqual("valid.key", actualConfig.SonarProjectKey); Assert.AreEqual("valid.name", actualConfig.SonarProjectName); Assert.AreEqual("1.0", actualConfig.SonarProjectVersion); Assert.AreEqual("http://foo", actualConfig.SonarQubeHostUrl); Assert.AreEqual(tbSettings.SonarBinDirectory, actualConfig.SonarBinDir); Assert.AreEqual(tbSettings.SonarConfigDirectory, actualConfig.SonarConfigDir); Assert.AreEqual(tbSettings.SonarOutputDirectory, actualConfig.SonarOutputDir); Assert.AreEqual(tbSettings.SonarRunnerWorkingDirectory, actualConfig.SonarRunnerWorkingDirectory); Assert.AreEqual(tbSettings.BuildUri, actualConfig.GetBuildUri()); Assert.AreEqual(tbSettings.TfsUri, actualConfig.GetTfsUri()); Assert.IsNotNull(actualConfig.ServerSettings); Property serverProperty = actualConfig.ServerSettings.SingleOrDefault(s => string.Equals(s.Id, "server.key.1", System.StringComparison.Ordinal)); Assert.IsNotNull(serverProperty); Assert.AreEqual("server.value.1", serverProperty.Value); Assert.AreSame(analyzerSettings, actualConfig.AnalyzerSettings); }
private bool FetchArgumentsAndRulesets(ProcessedArgs args, TeamBuildSettings settings, out IDictionary<string, string> serverSettings, out AnalyzerSettings analyzerSettings) { string hostUrl = args.GetSetting(SonarProperties.HostUrl); serverSettings = null; analyzerSettings = null; ISonarQubeServer server = this.factory.CreateSonarQubeServer(args, this.logger); try { this.logger.LogInfo(Resources.MSG_FetchingAnalysisConfiguration); // Respect sonar.branch setting if set string projectBranch = null; args.TryGetSetting(SonarProperties.ProjectBranch, out projectBranch); // Fetch the SonarQube project properties serverSettings = server.GetProperties(args.ProjectKey, projectBranch); // Generate the FxCop rulesets this.logger.LogInfo(Resources.MSG_GeneratingRulesets); GenerateFxCopRuleset(server, args.ProjectKey, projectBranch, "csharp", "cs", "fxcop", Path.Combine(settings.SonarConfigDirectory, FxCopCSharpRuleset)); GenerateFxCopRuleset(server, args.ProjectKey, projectBranch, "vbnet", "vbnet", "fxcop-vbnet", Path.Combine(settings.SonarConfigDirectory, FxCopVBNetRuleset)); IAnalyzerProvider analyzerProvider = this.factory.CreateAnalyzerProvider(this.logger); Debug.Assert(analyzerProvider != null, "Factory should not return null"); analyzerSettings = analyzerProvider.SetupAnalyzers(server, settings, args.ProjectKey, projectBranch); } catch (WebException ex) { if (Utilities.HandleHostUrlWebException(ex, hostUrl, this.logger)) { return false; } throw; } finally { Utilities.SafeDispose(server); } return true; }
/// <summary> /// Combines the various configuration options into the AnalysisConfig file /// used by the build and post-processor. Saves the file and returns the config instance. /// </summary> /// <returns></returns> public static AnalysisConfig GenerateFile(ProcessedArgs args, TeamBuildSettings settings, IDictionary<string, string> serverProperties, AnalyzerSettings analyzerSettings, // could be null if the Rolsyn profile couldn't be retrieved ILogger logger) { if (args == null) { throw new ArgumentNullException("args"); } if (settings == null) { throw new ArgumentNullException("settings"); } if (serverProperties == null) { throw new ArgumentNullException("serverProperties"); } if (logger == null) { throw new ArgumentNullException("logger"); } AnalysisConfig config = new AnalysisConfig(); config.SonarProjectKey = args.ProjectKey; config.SonarProjectName = args.ProjectName; config.SonarProjectVersion = args.ProjectVersion; config.SonarQubeHostUrl = args.GetSetting(SonarProperties.HostUrl); config.SetBuildUri(settings.BuildUri); config.SetTfsUri(settings.TfsUri); config.SonarConfigDir = settings.SonarConfigDirectory; config.SonarOutputDir = settings.SonarOutputDirectory; config.SonarBinDir = settings.SonarBinDirectory; config.SonarRunnerWorkingDirectory = settings.SonarRunnerWorkingDirectory; // Add the server properties to the config config.ServerSettings = new AnalysisProperties(); foreach (var property in serverProperties) { if (!IsSecuredServerProperty(property.Key)) { AddSetting(config.ServerSettings, property.Key, property.Value); } } // Add command line arguments config.LocalSettings = new AnalysisProperties(); foreach (var property in args.LocalProperties.GetAllProperties()) { AddSetting(config.LocalSettings, property.Id, property.Value); } // Set the pointer to the properties file if (args.PropertiesFileName != null) { config.SetSettingsFilePath(args.PropertiesFileName); } config.AnalyzerSettings = analyzerSettings; config.Save(settings.AnalysisConfigFilePath); return config; }
private static void CheckExpectedAssemblies(AnalyzerSettings actualSettings, params string[] expected) { foreach(string expectedItem in expected) { Assert.IsTrue(actualSettings.AnalyzerAssemblyPaths.Contains(expectedItem, StringComparer.OrdinalIgnoreCase), "Expected assembly file path was not returned: {0}", expectedItem); } Assert.AreEqual(expected.Length, actualSettings.AnalyzerAssemblyPaths.Count(), "Too many assembly file paths returned"); }
private static void AssertAnalyzerSetupNotPerformed(AnalyzerSettings actualSettings, string rootTestDir) { Assert.IsNull(actualSettings, "Not expecting a config instance to have been returned"); string filePath = GetExpectedRulesetFilePath(rootTestDir); Assert.IsFalse(File.Exists(filePath), "Not expecting the ruleset file to exist: {0}", filePath); }
private void CheckExpectedAdditionalFileExists(string expectedFileName, string expectedContent, AnalyzerSettings actualSettings) { // Check one file of the expected name exists IEnumerable<string> matches = actualSettings.AdditionalFilePaths.Where(actual => string.Equals(expectedFileName, Path.GetFileName(actual), System.StringComparison.OrdinalIgnoreCase)); Assert.AreEqual(1, matches.Count(), "Unexpected number of files named \"{0}\". One and only one expected", expectedFileName); // Check the file exists and has the expected content string actualFilePath = matches.First(); Assert.IsTrue(File.Exists(actualFilePath), "AdditionalFile does not exist: {0}", actualFilePath); // Dump the contents to help with debugging this.TestContext.AddResultFile(actualFilePath); this.TestContext.WriteLine("File contents: {0}", actualFilePath); this.TestContext.WriteLine(File.ReadAllText(actualFilePath)); this.TestContext.WriteLine(""); if (expectedContent != null) // null expected means "don't check" { Assert.AreEqual(expectedContent, File.ReadAllText(actualFilePath), "Additional file does not have the expected content: {0}", expectedFileName); } }
private void CheckExpectedAdditionalFiles(WellKnownProfile expected, AnalyzerSettings actualSettings) { foreach (string expectedFileName in expected.AdditionalFiles.Keys) { string expectedContent = expected.AdditionalFiles[expectedFileName]; CheckExpectedAdditionalFileExists(expectedFileName, expectedContent, actualSettings); } }
private void CheckRuleset(AnalyzerSettings actualSettings, string rootTestDir) { Assert.IsFalse(string.IsNullOrWhiteSpace(actualSettings.RuleSetFilePath), "Ruleset file path should be set"); Assert.IsTrue(Path.IsPathRooted(actualSettings.RuleSetFilePath), "Ruleset file path should be absolute"); Assert.IsTrue(File.Exists(actualSettings.RuleSetFilePath), "Specified ruleset file does not exist: {0}", actualSettings.RuleSetFilePath); this.TestContext.AddResultFile(actualSettings.RuleSetFilePath); CheckFileIsXml(actualSettings.RuleSetFilePath); Assert.AreEqual(RoslynAnalyzerProvider.RoslynCSharpRulesetFileName, Path.GetFileName(actualSettings.RuleSetFilePath), "Ruleset file does not have the expected name"); string expectedFilePath = GetExpectedRulesetFilePath(rootTestDir); Assert.AreEqual(expectedFilePath, actualSettings.RuleSetFilePath, "Ruleset was not written to the expected location"); }
private static void CheckSettingsInvariants(AnalyzerSettings actualSettings) { Assert.IsNotNull(actualSettings, "Not expecting the config to be null"); Assert.IsNotNull(actualSettings.AdditionalFilePaths); Assert.IsNotNull(actualSettings.AnalyzerAssemblyPaths); Assert.IsFalse(string.IsNullOrEmpty(actualSettings.RuleSetFilePath)); // Any file paths returned in the config should exist foreach (string filePath in actualSettings.AdditionalFilePaths) { Assert.IsTrue(File.Exists(filePath), "Expected additional file does not exist: {0}", filePath); } Assert.IsTrue(File.Exists(actualSettings.RuleSetFilePath), "Specified ruleset does not exist: {0}", actualSettings.RuleSetFilePath); }
private AnalyzerSettings ProcessProfile(RoslynExportProfile profile) { Debug.Assert(profile != null, "Expecting a valid profile"); string rulesetFilePath = this.UnpackRuleset(profile); if (rulesetFilePath == null) { return null; } IEnumerable<string> additionalFiles = this.UnpackAdditionalFiles(profile); IEnumerable<string> analyzersAssemblies = this.FetchAnalyzerAssemblies(profile); AnalyzerSettings compilerConfig = new AnalyzerSettings(rulesetFilePath, analyzersAssemblies ?? Enumerable.Empty<string>(), additionalFiles ?? Enumerable.Empty<string>()); return compilerConfig; }
/// <summary> /// Combines the various configuration options into the AnalysisConfig file /// used by the build and post-processor. Saves the file and returns the config instance. /// </summary> /// <param name="args">Processed command line arguments supplied the user</param> /// <param name="buildSettings">Build environment settings</param> /// <param name="serverProperties">Analysis properties downloaded from the SonarQube server</param> /// <param name="analyzerSettings">Specifies the Roslyn analyzers to use</param> /// <param name="programmaticProperties">Any additional programmatically set analysis properties. Any user-specified values will take priority</param> public static AnalysisConfig GenerateFile(ProcessedArgs args, TeamBuildSettings buildSettings, IDictionary<string, string> serverProperties, AnalyzerSettings analyzerSettings, AnalysisProperties programmaticProperties, ILogger logger) { if (args == null) { throw new ArgumentNullException("args"); } if (buildSettings == null) { throw new ArgumentNullException("settings"); } if (serverProperties == null) { throw new ArgumentNullException("serverProperties"); } if (analyzerSettings == null) { throw new ArgumentNullException("analyzerSettings"); } if (programmaticProperties == null) { throw new ArgumentNullException("programmaticProperties"); } if (logger == null) { throw new ArgumentNullException("logger"); } AnalysisConfig config = new AnalysisConfig(); config.SonarProjectKey = args.ProjectKey; config.SonarProjectName = args.ProjectName; config.SonarProjectVersion = args.ProjectVersion; config.SonarQubeHostUrl = args.GetSetting(SonarProperties.HostUrl); config.SetBuildUri(buildSettings.BuildUri); config.SetTfsUri(buildSettings.TfsUri); config.SonarConfigDir = buildSettings.SonarConfigDirectory; config.SonarOutputDir = buildSettings.SonarOutputDirectory; config.SonarBinDir = buildSettings.SonarBinDirectory; config.SonarRunnerWorkingDirectory = buildSettings.SonarRunnerWorkingDirectory; config.SourcesDirectory = buildSettings.SourcesDirectory; // Add the server properties to the config config.ServerSettings = new AnalysisProperties(); foreach (var property in serverProperties) { if (!IsSecuredServerProperty(property.Key)) { AddSetting(config.ServerSettings, property.Key, property.Value); } } // Add command line arguments and programmatic properties. // Command line arguments take precedence AggregatePropertiesProvider aggProvider = new AggregatePropertiesProvider(args.LocalProperties, new ListPropertiesProvider(programmaticProperties)); config.LocalSettings = new AnalysisProperties(); foreach (var property in aggProvider.GetAllProperties()) { AddSetting(config.LocalSettings, property.Id, property.Value); } // Set the pointer to the properties file if (args.PropertiesFileName != null) { config.SetSettingsFilePath(args.PropertiesFileName); } config.AnalyzerSettings = analyzerSettings; config.Save(buildSettings.AnalysisConfigFilePath); return config; }
private static void AssertAnalyzerSetupNotPerformed(AnalyzerSettings actualSettings, string rootTestDir) { Assert.IsNotNull(actualSettings, "Not expecting the settings to be null"); string filePath = GetExpectedRulesetFilePath(rootTestDir); Assert.IsFalse(File.Exists(filePath), "Not expecting the ruleset file to exist: {0}", filePath); }
public void AnalysisConfGen_CommandLineAndProgrammaticProperties() { // Arrange TestLogger logger = new TestLogger(); string analysisDir = TestUtils.CreateTestSpecificFolder(this.TestContext); TeamBuildSettings tbSettings = TeamBuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir); Dictionary<string, string> emptyServerProperties = new Dictionary<string, string>(); AnalyzerSettings emptyAnalyzerSettings = new AnalyzerSettings(); Directory.CreateDirectory(tbSettings.SonarConfigDirectory); // config directory needs to exist // Define a set of user properties ListPropertiesProvider userProperties = new ListPropertiesProvider(); userProperties.AddProperty("sonar.host.url", "http://host"); // required userProperties.AddProperty("user1", "user value 1"); userProperties.AddProperty("shared.key.1", "user value for shared.key.1"); ProcessedArgs cmdLineArgs = new ProcessedArgs("key", "name", "version", false, userProperties, EmptyPropertyProvider.Instance); // Define a set of programmatic properties AnalysisProperties programmaticProperties = new AnalysisProperties(); programmaticProperties.Add(new Property() { Id = "prog1", Value = "prog value 1" }); programmaticProperties.Add(new Property() { Id = "shared.key.1", Value = "prog value for shared.key.1" }); // Act AnalysisConfig actualConfig = AnalysisConfigGenerator.GenerateFile(cmdLineArgs, tbSettings, emptyServerProperties, emptyAnalyzerSettings, programmaticProperties, logger); // Assert AssertConfigFileExists(actualConfig); logger.AssertErrorsLogged(0); logger.AssertWarningsLogged(0); // Check that user properties take precedence over the programmatic ones AssertExpectedLocalSetting("sonar.host.url", "http://host", actualConfig); AssertExpectedLocalSetting("user1", "user value 1", actualConfig); AssertExpectedLocalSetting("shared.key.1", "user value for shared.key.1", actualConfig); AssertExpectedLocalSetting("prog1", "prog value 1", actualConfig); }