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); }
[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"); }
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); }
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); }
/// <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); }
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); }
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"); }
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); }
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); }