예제 #1
0
        private void SaveAndReloadConfig(AnalysisConfig original, string outputFileName)
        {
            File.Exists(outputFileName).Should().BeFalse("Test error: file should not exist at the start of the test. File: {0}", outputFileName);
            original.Save(outputFileName);
            File.Exists(outputFileName).Should().BeTrue("Failed to create the output file. File: {0}", outputFileName);
            TestContext.AddResultFile(outputFileName);

            var reloaded = AnalysisConfig.Load(outputFileName);

            reloaded.Should().NotBeNull("Reloaded analysis config should not be null");

            AssertExpectedValues(original, reloaded);
        }
        private AnalysisConfig SaveAndReloadConfig(AnalysisConfig original, string outputFileName)
        {
            Assert.IsFalse(File.Exists(outputFileName), "Test error: file should not exist at the start of the test. File: {0}", outputFileName);
            original.Save(outputFileName);
            Assert.IsTrue(File.Exists(outputFileName), "Failed to create the output file. File: {0}", outputFileName);
            this.TestContext.AddResultFile(outputFileName);

            AnalysisConfig reloaded = AnalysisConfig.Load(outputFileName);

            Assert.IsNotNull(reloaded, "Reloaded analysis config should not be null");

            AssertExpectedValues(original, reloaded);
            return(reloaded);
        }
예제 #3
0
        [WorkItem(120)] // Regression test for http://jira.sonarsource.com/browse/SONARMSBRU-120
        public void AnalysisConfig_SharedReadAllowed()
        {
            // 0. Setup
            var testFolder = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext);
            var filePath   = Path.Combine(testFolder, "config.txt");

            var config = new AnalysisConfig();

            config.Save(filePath);

            using (var lockingStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                AnalysisConfig.Load(filePath);
            }
        }
        [WorkItem(120)] // Regression test for http://jira.sonarsource.com/browse/SONARMSBRU-120
        public void AnalysisConfig_SharedReadAllowed()
        {
            // 0. Setup
            string testFolder = TestUtils.CreateTestSpecificFolder(this.TestContext);
            string filePath   = Path.Combine(testFolder, "config.txt");

            AnalysisConfig config = new AnalysisConfig();

            config.Save(filePath);

            using (FileStream lockingStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                AnalysisConfig.Load(filePath);
            }
        }
        /// <summary>
        /// Attempts to load the config file, suppressing any IO errors that occur.
        /// This method is expected to be called inside a "retry"
        /// </summary>
        private bool DoLoadConfig(string filePath, out AnalysisConfig config)
        {
            Debug.Assert(File.Exists(filePath), "Expecting the config file to exist: " + filePath);
            config = null;

            try
            {
                config = AnalysisConfig.Load(filePath);
            }
            catch (IOException e)
            {
                // Log this as a message for info. We'll log an error if all of the re-tries failed
                this.Log.LogMessage(MessageImportance.Low, Resources.IsTest_ErrorReadingConfigFile, e.Message);
                return(false);
            }
            return(true);
        }
        /// <summary>
        /// Attempts to load the config file, suppressing any IO errors that occur.
        /// This method is expected to be called inside a "retry"
        /// </summary>
        private static bool DoLoadConfig(string filePath, ILogger logger, out AnalysisConfig config)
        {
            Debug.Assert(File.Exists(filePath), "Expecting the config file to exist: " + filePath);
            config = null;

            try
            {
                config = AnalysisConfig.Load(filePath);
            }
            catch (IOException e)
            {
                // Log this as a message for info. We'll log an error if all of the re-tries failed
                logger.LogDebug(Resources.Shared_ErrorReadingConfigFile, e.Message);
                return(false);
            }
            return(true);
        }
        public void PreProc_EmptySonarRunnerProperties()
        {
            // Checks the pre-processor creates a valid config file

            // Arrange
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            string propertiesFile = CreateEmptyPropertiesFile(testDir);

            MockPropertiesFetcher mockPropertiesFetcher = new MockPropertiesFetcher();
            MockRulesetGenerator  mockRulesetGenerator  = new MockRulesetGenerator();
            TestLogger            logger = new TestLogger();

            string expectedConfigFileName;

            using (PreprocessTestUtils.CreateValidLegacyTeamBuildScope("tfs uri", "http://builduri", testDir))
            {
                TeamBuildSettings settings = TeamBuildSettings.GetSettingsFromEnvironment(new ConsoleLogger());
                Assert.IsNotNull(settings, "Test setup error: TFS environment variables have not been set correctly");
                expectedConfigFileName = settings.AnalysisConfigFilePath;

                TeamBuildPreProcessor preProcessor = new TeamBuildPreProcessor(mockPropertiesFetcher, mockRulesetGenerator);

                // Act
                preProcessor.Execute(logger, "key", "name", "ver", propertiesFile);
            }

            // Assert
            Assert.IsTrue(File.Exists(expectedConfigFileName), "Config file does not exist: {0}", expectedConfigFileName);
            AnalysisConfig config = AnalysisConfig.Load(expectedConfigFileName);

            Assert.IsTrue(Directory.Exists(config.SonarOutputDir), "Output directory was not created: {0}", config.SonarOutputDir);
            Assert.IsTrue(Directory.Exists(config.SonarConfigDir), "Config directory was not created: {0}", config.SonarConfigDir);
            Assert.AreEqual("key", config.SonarProjectKey);
            Assert.AreEqual("name", config.SonarProjectName);
            Assert.AreEqual("ver", config.SonarProjectVersion);
            Assert.AreEqual("http://builduri", config.GetBuildUri());
            Assert.AreEqual("tfs uri", config.GetTfsUri());
            Assert.AreEqual(propertiesFile, config.SonarRunnerPropertiesPath);

            mockPropertiesFetcher.AssertFetchPropertiesCalled();
            mockPropertiesFetcher.CheckFetcherArguments("http://localhost:9000", "key");

            mockRulesetGenerator.AssertGenerateCalled();
            mockRulesetGenerator.CheckGeneratorArguments("http://localhost:9000", "key");
        }
예제 #8
0
        public static int Execute(string[] args, ILogger logger)
        {
            try
            {
                /* Expected Arguments :
                 * Method : 0
                 * SonarQubeAnalysisConfig.xml path : 1
                 * sonar-project.properties : 2
                 * ranToCompletion : 3
                 */
                if (args.Length < 1)
                {
                    logger.LogError("No argument found. Exiting...");
                    return(1);
                }

                CommandLineArgs commandLineArgs = new CommandLineArgs(logger);
                if (!commandLineArgs.ParseArguments(args))
                {
                    return(1);
                }

                var            teamBuildSettings      = TeamBuildSettings.GetSettingsFromEnvironment(logger);
                AnalysisConfig config                 = AnalysisConfig.Load(commandLineArgs.SonarQubeAnalysisConfigPath);
                var            legacyTeamBuildFactory = new LegacyTeamBuildFactory(logger, config);

                switch (commandLineArgs.ProcessToExecute)
                {
                case Method.ConvertCoverage:
                    ExecuteCoverageConverter(logger, config, legacyTeamBuildFactory, teamBuildSettings, commandLineArgs.SonarProjectPropertiesPath);
                    break;

                case Method.SummaryReportBuilder:
                    ExecuteReportBuilder(logger, config, legacyTeamBuildFactory, teamBuildSettings, commandLineArgs.RanToCompletion, commandLineArgs.SonarProjectPropertiesPath);
                    break;
                }
            }
            catch (Exception ex)
            {
                logger.LogError("An exception occured while executing the process : " + ex.Message);
                logger.LogError(ex.StackTrace);
            }

            return(0);
        }
        /// <summary>
        /// Attempts to load the analysis config file. The location of the file is
        /// calculated from TeamBuild-specific environment variables.
        /// Returns null if the required environment variables are not available.
        /// </summary>
        private AnalysisConfig GetAnalysisConfig(string configFilePath)
        {
            AnalysisConfig config = null;

            if (configFilePath != null)
            {
                Debug.Assert(!string.IsNullOrWhiteSpace(configFilePath), "Expecting the analysis config file path to be set");

                if (File.Exists(configFilePath))
                {
                    config = AnalysisConfig.Load(configFilePath);
                }
                else
                {
                    Logger.LogError(Resources.ERROR_ConfigFileNotFound, configFilePath);
                }
            }
            return(config);
        }
예제 #10
0
        private void AssertAnalysisConfig(string filePath, int noAnalyzers, TestLogger logger)
        {
            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
            logger.AssertVerbosity(LoggerVerbosity.Debug);

            AssertConfigFileExists(filePath);
            AnalysisConfig actualConfig = AnalysisConfig.Load(filePath);

            Assert.AreEqual("key", actualConfig.SonarProjectKey, "Unexpected project key");
            Assert.AreEqual("name", actualConfig.SonarProjectName, "Unexpected project name");
            Assert.AreEqual("1.0", actualConfig.SonarProjectVersion, "Unexpected project version");

            Assert.IsNotNull(actualConfig.AnalyzersSettings, "Analyzer settings should not be null");
            Assert.AreEqual(actualConfig.AnalyzersSettings.Count, noAnalyzers);

            AssertExpectedLocalSetting(SonarProperties.HostUrl, "http://host", actualConfig);
            AssertExpectedLocalSetting("cmd.line1", "cmdline.value.1", actualConfig);
            AssertExpectedServerSetting("server.key", "server value 1", actualConfig);
        }
예제 #11
0
        /// <summary>
        /// Attempts to load the analysis config file. The location of the file is
        /// calculated from TeamBuild-specific environment variables.
        /// Returns null if the required environment variables are not available.
        /// </summary>
        private static AnalysisConfig GetAnalysisConfig(TeamBuildSettings teamBuildSettings, ILogger logger)
        {
            AnalysisConfig config = null;

            if (teamBuildSettings != null)
            {
                var configFilePath = teamBuildSettings.AnalysisConfigFilePath;
                Debug.Assert(!string.IsNullOrWhiteSpace(configFilePath), "Expecting the analysis config file path to be set");

                if (File.Exists(configFilePath))
                {
                    config = AnalysisConfig.Load(teamBuildSettings.AnalysisConfigFilePath);
                }
                else
                {
                    logger.LogError(Resources.ERROR_ConfigFileNotFound, configFilePath);
                }
            }
            return(config);
        }
예제 #12
0
        private AnalysisConfig AssertAnalysisConfig(string filePath, int noAnalyzers, TestLogger logger)
        {
            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
            logger.AssertVerbosity(LoggerVerbosity.Debug);

            AssertConfigFileExists(filePath);
            var actualConfig = AnalysisConfig.Load(filePath);

            actualConfig.SonarProjectKey.Should().Be("key", "Unexpected project key");
            actualConfig.SonarProjectName.Should().Be("name", "Unexpected project name");
            actualConfig.SonarProjectVersion.Should().Be("1.0", "Unexpected project version");

            actualConfig.AnalyzersSettings.Should().NotBeNull("Analyzer settings should not be null");
            actualConfig.AnalyzersSettings.Should().HaveCount(noAnalyzers);

            AssertExpectedLocalSetting(SonarProperties.HostUrl, "http://host", actualConfig);
            AssertExpectedLocalSetting("cmd.line1", "cmdline.value.1", actualConfig);
            AssertExpectedServerSetting("server.key", "server value 1", actualConfig);

            return(actualConfig);
        }
예제 #13
0
        private static AnalysisConfig TryGetAnalysisConfig(string suppliedPath, ILogger logger)
        {
            suppliedPath = Path.GetFullPath(suppliedPath); // turn relative into absolute paths

            if (!File.Exists(suppliedPath))
            {
                logger.LogError(Resources.ERR_InvalidAnalysisConfigFilePath, suppliedPath);
                return(null);
            }

            AnalysisConfig config = null;

            try
            {
                config = AnalysisConfig.Load(suppliedPath);
            }
            catch (InvalidOperationException ex)
            {
                logger.LogError(Resources.ERR_ErrorLoadingConfigFile, ex.Message);
            }
            return(config);
        }
        public void PreProc_EndToEnd_SuccessCase()
        {
            // Checks end-to-end happy path for the pre-processor i.e.
            // * arguments are parsed
            // * targets are installed
            // * server properties are fetched
            // * rulesets are generated
            // * config file is created

            // Arrange
            string     workingDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            TestLogger logger     = new TestLogger();

            // Configure the server
            MockSonarQubeServer mockServer = new MockSonarQubeServer();

            ServerDataModel data = mockServer.Data;

            data.ServerProperties.Add("server.key", "server value 1");

            data.InstalledPlugins.Add("csharp");
            data.InstalledPlugins.Add("vbnet");

            data.AddRepository("fxcop", "cs")
            .AddRule("cs.rule1", "cs.rule1.internal")
            .AddRule("cs.rule2", "cs.rule2.internal");

            data.AddRepository("fxcop-vbnet", "vbnet")
            .AddRule("vb.rule1", "vb.rule1.internal")
            .AddRule("vb.rule2", "vb.rule2.internal");

            data.AddQualityProfile("test.profile", "cs")
            .AddProject("key");
            data.AddRuleToProfile("cs.rule1", "test.profile");

            data.AddQualityProfile("test.profile", "vbnet")
            .AddProject("key");
            data.AddRuleToProfile("vb.rule2", "test.profile");

            MockRoslynAnalyzerProvider mockAnalyzerProvider = new MockRoslynAnalyzerProvider();

            mockAnalyzerProvider.SettingsToReturn = new AnalyzerSettings();
            mockAnalyzerProvider.SettingsToReturn.RuleSetFilePath = "c:\\xxx.ruleset";

            MockTargetsInstaller mockTargetsInstaller = new MockTargetsInstaller();

            MockObjectFactory mockFactory = new MockObjectFactory(mockServer, mockTargetsInstaller, mockAnalyzerProvider);


            string[] validArgs = new string[] {
                "/k:key", "/n:name", "/v:1.0",
                "/d:cmd.line1=cmdline.value.1",
                "/d:sonar.host.url=http://host",
                "/d:sonar.log.level=INFO|DEBUG"
            };

            TeamBuildSettings settings;

            using (PreprocessTestUtils.CreateValidNonTeamBuildScope())
                using (new WorkingDirectoryScope(workingDir))
                {
                    settings = TeamBuildSettings.GetSettingsFromEnvironment(new TestLogger());
                    Assert.IsNotNull(settings, "Test setup error: TFS environment variables have not been set correctly");
                    Assert.AreEqual(BuildEnvironment.NotTeamBuild, settings.BuildEnvironment, "Test setup error: build environment was not set correctly");

                    TeamBuildPreProcessor preProcessor = new TeamBuildPreProcessor(mockFactory, logger);

                    // Act
                    bool success = preProcessor.Execute(validArgs);
                    Assert.IsTrue(success, "Expecting the pre-processing to complete successfully");
                }

            // Assert
            AssertDirectoryExists(settings.AnalysisBaseDirectory);
            AssertDirectoryExists(settings.SonarConfigDirectory);
            AssertDirectoryExists(settings.SonarOutputDirectory);
            // The bootstrapper is responsible for creating the bin directory

            mockTargetsInstaller.AssertsTargetsCopied();
            mockServer.AssertMethodCalled("GetProperties", 1);
            mockServer.AssertMethodCalled("GetInternalKeys", 2); // C# and VB

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
            logger.AssertVerbosity(LoggerVerbosity.Debug);

            AssertConfigFileExists(settings.AnalysisConfigFilePath);
            AnalysisConfig actualConfig = AnalysisConfig.Load(settings.AnalysisConfigFilePath);

            Assert.AreEqual("key", actualConfig.SonarProjectKey, "Unexpected project key");
            Assert.AreEqual("name", actualConfig.SonarProjectName, "Unexpected project name");
            Assert.AreEqual("1.0", actualConfig.SonarProjectVersion, "Unexpected project version");

            Assert.IsNotNull(actualConfig.AnalyzerSettings, "Analyzer settings should not be null");
            Assert.AreEqual("c:\\xxx.ruleset", actualConfig.AnalyzerSettings.RuleSetFilePath, "Unexpected ruleset path");

            AssertExpectedLocalSetting(SonarProperties.HostUrl, "http://host", actualConfig);
            AssertExpectedLocalSetting("cmd.line1", "cmdline.value.1", actualConfig);
            AssertExpectedServerSetting("server.key", "server value 1", actualConfig);

            string fxCopFilePath = AssertFileExists(settings.SonarConfigDirectory, TeamBuildPreProcessor.FxCopCSharpRuleset);

            PreProcessAsserts.AssertRuleSetContainsRules(fxCopFilePath, "cs.rule1");

            fxCopFilePath = AssertFileExists(settings.SonarConfigDirectory, TeamBuildPreProcessor.FxCopVBNetRuleset);
            PreProcessAsserts.AssertRuleSetContainsRules(fxCopFilePath, "vb.rule2");
        }
예제 #15
0
        public void PreProc_EndToEnd_SuccessCase()
        {
            // Checks end-to-end happy path for the pre-processor i.e.
            // * arguments are parsed
            // * targets are installed
            // * server properties are fetched
            // * rulesets are generated
            // * config file is created

            // Arrange
            string workingDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            MockRulesetGenerator mockRulesetGenerator = new MockRulesetGenerator();
            TestLogger           logger = new TestLogger();

            MockPropertiesFetcher mockPropertiesFetcher = new MockPropertiesFetcher();

            mockPropertiesFetcher.PropertiesToReturn = new Dictionary <string, string>();

            MockTargetsInstaller mockTargetsInstaller = new MockTargetsInstaller();

            // The set of server properties to return
            mockPropertiesFetcher.PropertiesToReturn.Add("server.key", "server value 1");

            string[] validArgs = new string[] {
                "/k:key", "/n:name", "/v:1.0",
                "/d:cmd.line1=cmdline.value.1",
                "/d:sonar.host.url=http://host",
                "/d:sonar.log.level=INFO|DEBUG"
            };

            TeamBuildSettings settings;

            using (PreprocessTestUtils.CreateValidNonTeamBuildScope())
                using (new WorkingDirectoryScope(workingDir))
                {
                    settings = TeamBuildSettings.GetSettingsFromEnvironment(new TestLogger());
                    Assert.IsNotNull(settings, "Test setup error: TFS environment variables have not been set correctly");
                    Assert.AreEqual(BuildEnvironment.NotTeamBuild, settings.BuildEnvironment, "Test setup error: build environment was not set correctly");

                    TeamBuildPreProcessor preProcessor = new TeamBuildPreProcessor(mockPropertiesFetcher, mockRulesetGenerator, mockTargetsInstaller);

                    // Act
                    bool success = preProcessor.Execute(validArgs, logger);
                    Assert.IsTrue(success, "Expecting the pre-processing to complete successfully");
                }

            // Assert
            AssertDirectoryExists(settings.AnalysisBaseDirectory);
            AssertDirectoryExists(settings.SonarConfigDirectory);
            AssertDirectoryExists(settings.SonarOutputDirectory);
            // The bootstrapper is responsible for creating the bin directory

            mockTargetsInstaller.AssertsTargetsCopied();
            mockPropertiesFetcher.AssertFetchPropertiesCalled();
            mockRulesetGenerator.AssertGenerateCalled(2); // C# and VB

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
            logger.AssertVerbosity(LoggerVerbosity.Debug);

            AssertConfigFileExists(settings.AnalysisConfigFilePath);
            AnalysisConfig actualConfig = AnalysisConfig.Load(settings.AnalysisConfigFilePath);

            Assert.AreEqual("key", actualConfig.SonarProjectKey, "Unexpected project key");
            Assert.AreEqual("name", actualConfig.SonarProjectName, "Unexpected project name");
            Assert.AreEqual("1.0", actualConfig.SonarProjectVersion, "Unexpected project version");

            AssertExpectedLocalSetting(SonarProperties.HostUrl, "http://host", actualConfig);
            AssertExpectedLocalSetting("cmd.line1", "cmdline.value.1", actualConfig);
            AssertExpectedServerSetting("server.key", "server value 1", actualConfig);
        }
예제 #16
0
        public void AnalysisConfig_ExpectedXmlFormat()
        {
            // Arrange
            var xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<AnalysisConfig xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""http://www.sonarsource.com/msbuild/integration/2015/1"">
  <SonarConfigDir>c:\config</SonarConfigDir>
  <SonarOutputDir>c:\output</SonarOutputDir>
  <SonarProjectKey>key.1.2</SonarProjectKey>
  <SonarProjectVersion>1.0</SonarProjectVersion>
  <SonarProjectName>My project</SonarProjectName>
  <ServerSettings>
    <Property Name=""server.key"">server.value</Property>
  </ServerSettings>

  <!-- Unexpected additional elements should be silently ignored -->
  <UnexpectedElement1 />

  <LocalSettings>
    <Property Name=""local.key"">local.value</Property>
  </LocalSettings>
  <AnalyzersSettings>
    <AnalyzerSettings>
      <RuleSetFilePath>d:\ruleset path.ruleset</RuleSetFilePath>
      <AnalyzerPlugins>
        <AnalyzerPlugin Key='csharp' Version='7.10.0.7896' StaticResourceName='SonarAnalyzer-7.10.0.7896.zip'>
          <AssemblyPaths>
            <Path>c:\assembly1.dll</Path>
            <Path>C:\assembly2.dll</Path>
          </AssemblyPaths>
        </AnalyzerPlugin>
        <AnalyzerPlugin Key='pluginkey2' Version='1.2.3' StaticResourceName='staticresource.zip'>
          <AssemblyPaths>
            <Path>C:\assembly3.dll</Path>
          </AssemblyPaths>
        </AnalyzerPlugin>
      </AnalyzerPlugins>
      <AdditionalFilePaths>

        <MoreUnexpectedData><Foo /></MoreUnexpectedData>

        <Path>c:\additional1.txt</Path>
      </AdditionalFilePaths>
    </AnalyzerSettings>
  </AnalyzersSettings>
</AnalysisConfig>";

            var testDir  = TestUtils.CreateTestSpecificFolder(TestContext);
            var fullPath = TestUtils.CreateTextFile(testDir, "input.txt", xml);

            // Act
            var actual = AnalysisConfig.Load(fullPath);

            // Assert
            var expected = new AnalysisConfig
            {
                SonarConfigDir      = "c:\\config",
                SonarOutputDir      = "c:\\output",
                SonarProjectKey     = "key.1.2",
                SonarProjectVersion = "1.0",
                SonarProjectName    = "My project",
                ServerSettings      = new AnalysisProperties()
            };

            expected.ServerSettings.Add(new Property()
            {
                Id = "server.key", Value = "server.value"
            });
            expected.LocalSettings = new AnalysisProperties
            {
                new Property()
                {
                    Id = "local.key", Value = "local.value"
                }
            };

            var settings = new AnalyzerSettings
            {
                RuleSetFilePath     = "d:\\ruleset path.ruleset",
                AdditionalFilePaths = new List <string>()
            };

            settings.AdditionalFilePaths.Add("c:\\additional1.txt");
            settings.AnalyzerPlugins = new List <AnalyzerPlugin>
            {
                new AnalyzerPlugin("csharp", "7.10.0.7896", "SonarAnalyzer-7.10.0.7896.zip", new List <string> {
                    "c:\\assembly1.dll", "C:\\assembly2.dll"
                }),
                new AnalyzerPlugin("pluginkey2", "1.2.3", "staticresource.zip", new List <string> {
                    "C:\\assembly3.dll"
                })
            };

            expected.AnalyzersSettings = new List <AnalyzerSettings>
            {
                settings
            };

            AssertExpectedValues(expected, actual);
        }
        public void AnalysisConfig_ExpectedXmlFormat()
        {
            // Arrange
            string xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<AnalysisConfig xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""http://www.sonarsource.com/msbuild/integration/2015/1"">
  <SonarConfigDir>c:\config</SonarConfigDir>
  <SonarOutputDir>c:\output</SonarOutputDir>
  <SonarProjectKey>key.1.2</SonarProjectKey>
  <SonarProjectVersion>1.0</SonarProjectVersion>
  <SonarProjectName>My project</SonarProjectName>
  <ServerSettings>
    <Property Name=""server.key"">server.value</Property>
  </ServerSettings>

  <!-- Unexpected additional elements should be silently ignored -->
  <UnexpectedElement1 />

  <LocalSettings>
    <Property Name=""local.key"">local.value</Property>
  </LocalSettings>
  <AnalyzersSettings>
    <AnalyzerSettings>
      <RuleSetFilePath>d:\ruleset path.ruleset</RuleSetFilePath>
      <AnalyzerAssemblyPaths>
        <Path>c:\analyzer1.dll</Path>
      </AnalyzerAssemblyPaths>
      <AdditionalFilePaths>

        <MoreUnexpectedData><Foo /></MoreUnexpectedData>

        <Path>c:\additional1.txt</Path>
      </AdditionalFilePaths>
    </AnalyzerSettings>
  </AnalyzersSettings>
</AnalysisConfig>";

            string testDir  = TestUtils.CreateTestSpecificFolder(this.TestContext);
            string fullPath = TestUtils.CreateTextFile(testDir, "input.txt", xml);

            // Act
            AnalysisConfig actual = AnalysisConfig.Load(fullPath);

            // Assert
            AnalysisConfig expected = new AnalysisConfig();

            expected.SonarConfigDir      = "c:\\config";
            expected.SonarOutputDir      = "c:\\output";
            expected.SonarProjectKey     = "key.1.2";
            expected.SonarProjectVersion = "1.0";
            expected.SonarProjectName    = "My project";
            expected.ServerSettings      = new AnalysisProperties();
            expected.ServerSettings.Add(new Property()
            {
                Id = "server.key", Value = "server.value"
            });
            expected.LocalSettings = new AnalysisProperties();
            expected.LocalSettings.Add(new Property()
            {
                Id = "local.key", Value = "local.value"
            });

            AnalyzerSettings settings = new AnalyzerSettings();

            settings = new AnalyzerSettings();
            settings.RuleSetFilePath     = "d:\\ruleset path.ruleset";
            settings.AdditionalFilePaths = new List <string>();
            settings.AdditionalFilePaths.Add("c:\\additional1.txt");
            settings.AnalyzerAssemblyPaths = new List <string>();
            settings.AnalyzerAssemblyPaths.Add("c:\\analyzer1.dll");

            expected.AnalyzersSettings = new List <AnalyzerSettings>();
            expected.AnalyzersSettings.Add(settings);

            AssertExpectedValues(expected, actual);
        }