public void ReportProcessor_CannotConvertFiles()
        {
            // Arrange
            MockReportUrlProvider urlProvider = new MockReportUrlProvider() { UrlsToReturn = new string[] { ValidUrl1 } };
            MockReportDownloader downloader = new MockReportDownloader();
            MockReportConverter converter = new MockReportConverter() { CanConvert = false };
            AnalysisConfig context = this.CreateValidContext();
            TeamBuildSettings settings = this.CreateValidSettings();
            TestLogger logger = new TestLogger();

            TfsLegacyCoverageReportProcessor processor = new TfsLegacyCoverageReportProcessor(urlProvider, downloader, converter);

            // Act
            bool initResult = processor.Initialise(context, settings, logger);

            // Assert
            Assert.IsFalse(initResult, "Expecting false: processor should not have been initialised successfully");

            urlProvider.AssertGetUrlsNotCalled();
            downloader.AssertDownloadNotCalled();
            converter.AssertConvertNotCalled();

            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        public void RoslynConfig_BranchMissingRuleset()
        {
            // This test is a regression scenario for SONARMSBRU-187:
            // We do not expect the project profile to be returned if we ask for a branch-specific profile

            // Arrange
            string rootDir = CreateTestFolders();
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings = CreateSettings(rootDir);

            WellKnownProfile testProfile = CreateValidCSharpProfile();
            MockSonarQubeServer mockServer = CreateServer("valid.project", null, "valid.profile", testProfile);

            MockAnalyzerInstaller mockInstaller = new MockAnalyzerInstaller();
            mockInstaller.AssemblyPathsToReturn = new HashSet<string>(new string[] { "c:\\assembly1.dll", "d:\\foo\\assembly2.dll" });

            RoslynAnalyzerProvider testSubject = new RoslynAnalyzerProvider(mockInstaller, logger);

            // Act
            AnalyzerSettings actualSettings = testSubject.SetupAnalyzers(mockServer, settings, "valid.project", "missingBranch");

            // Assert
            AssertAnalyzerSetupNotPerformed(actualSettings, rootDir);

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
        }
        public void FileGen_DuplicateProjectIds()
        {
            // ProjectInfo files with duplicate ids should be ignored

            // Arrange - three files, all with the same Guid, one of which is excluded
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            Guid duplicateGuid = Guid.NewGuid();
            CreateProjectInfoInSubDir(testDir, "duplicate1", duplicateGuid, ProjectType.Product, false, "c:\\abc\\duplicateProject1.proj"); // not excluded
            CreateProjectInfoInSubDir(testDir, "duplicate2", duplicateGuid, ProjectType.Test, false, "S:\\duplicateProject2.proj"); // not excluded
            CreateProjectInfoInSubDir(testDir, "excluded", duplicateGuid, ProjectType.Product, true, null); // excluded

            TestLogger logger = new TestLogger();
            AnalysisConfig config = CreateValidConfig(testDir);

            // Act
            ProjectInfoAnalysisResult result = null;
            using (new AssertIgnoreScope()) // expecting the properties writer to assert
            {
                result = PropertiesFileGenerator.GenerateFile(config, logger);
            }

            // Assert
            AssertExpectedStatus("duplicate1", ProjectInfoValidity.DuplicateGuid, result);
            AssertExpectedStatus("duplicate2", ProjectInfoValidity.DuplicateGuid, result);
            AssertExpectedStatus("excluded", ProjectInfoValidity.ExcludeFlagSet, result); // Expecting excluded rather than duplicate
            AssertExpectedProjectCount(3, result);

            // No valid project info files -> file not generated
            AssertFailedToCreatePropertiesFiles(result, logger);
            logger.AssertWarningsLogged(2); // should be a warning for each project with a duplicate id

            logger.AssertSingleWarningExists(duplicateGuid.ToString(), "c:\\abc\\duplicateProject1.proj");
            logger.AssertSingleWarningExists(duplicateGuid.ToString(), "S:\\duplicateProject2.proj");
        }
        public void AnalysisConfGen_AnalysisConfigDoesNotContainSensitiveData()
        {
            // Arrange
            string analysisDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            TestLogger logger = new TestLogger();

            ListPropertiesProvider cmdLineArgs = new ListPropertiesProvider();
            // Public args - should be written to the config file
            cmdLineArgs.AddProperty("sonar.host.url", "http://host");
            cmdLineArgs.AddProperty("public.key", "public value");

            // Sensitive values - should not be written to the config file
            cmdLineArgs.AddProperty(SonarProperties.DbPassword, "secret db password");
            cmdLineArgs.AddProperty(SonarProperties.DbUserName, "secret db user");

            // Create a settings file with public and sensitive data
            AnalysisProperties fileSettings = new AnalysisProperties();
            fileSettings.Add(new Property() { Id = "file.public.key", Value = "file public value" });
            fileSettings.Add(new Property() {Id = SonarProperties.DbUserName, Value = "secret db user"});
            fileSettings.Add(new Property() { Id = SonarProperties.DbPassword, Value = "secret db password"});
            string fileSettingsPath = Path.Combine(analysisDir, "fileSettings.txt");
            fileSettings.Save(fileSettingsPath);
            FilePropertyProvider fileProvider = FilePropertyProvider.Load(fileSettingsPath);

            ProcessedArgs args = new ProcessedArgs("key", "name", "1.0", false, cmdLineArgs, fileProvider);

            IDictionary<string, string> serverProperties = new Dictionary<string, string>();
            // Public server settings
            serverProperties.Add("server.key.1", "server value 1");
            // Sensitive server settings
            serverProperties.Add(SonarProperties.SonarUserName, "secret user");
            serverProperties.Add(SonarProperties.SonarPassword, "secret pwd");

            TeamBuildSettings settings = TeamBuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir);
            Directory.CreateDirectory(settings.SonarConfigDirectory); // config directory needs to exist

            // Act
            AnalysisConfig config = AnalysisConfigGenerator.GenerateFile(args, settings, serverProperties, logger);

            // Assert
            AssertConfigFileExists(config);
            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);

            // Check the config

            // "Public" arguments should be in the file
            Assert.AreEqual("key", config.SonarProjectKey, "Unexpected project key");
            Assert.AreEqual("name", config.SonarProjectName, "Unexpected project name");
            Assert.AreEqual("1.0", config.SonarProjectVersion, "Unexpected project version");

            AssertExpectedLocalSetting(SonarProperties.HostUrl, "http://host", config);
            AssertExpectedServerSetting("server.key.1", "server value 1", config);

            AssertFileDoesNotContainText(config.FileName, "file.public.key"); // file settings values should not be in the config

            // SONARMSBRU-136: TODO - uncomment the following code:
            AssertFileDoesNotContainText(config.FileName, "secret"); // sensitive data should not be in config
        }
        private static void CheckVerbosity(string errorMessage, LoggerVerbosity expectedVerbosity, string verbosity = null, string logLevel = null, int expectedNumberOfWarnings = 0)
        {
            var provider = CreatePropertiesProvider(verbosity, logLevel);
            TestLogger logger = new TestLogger();

            var actualVerbosity = VerbosityCalculator.ComputeVerbosity(provider, logger);

            Assert.AreEqual(expectedVerbosity, actualVerbosity, errorMessage);

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(expectedNumberOfWarnings);
        }
        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);
        }
        public void TrxReader_TestsResultsDirectoryMissing()
        {
            // Arrange
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            TestLogger logger = new TestLogger();

            // Act
            string coverageFilePath = TrxFileReader.LocateCodeCoverageFile(testDir, logger);

            // Assert
            Assert.AreEqual(null, coverageFilePath);

            // Not expecting errors or warnings: we assume it means that tests have not been executed
            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
        }
        [TestCategory("Task")] // Regression test for bug http://jira.codehaus.org/browse/SONARMSBRU-11
        public void TaskUtils_LoadConfig_RetryIfConfigLocked_ValueReturned()
        {
            // Arrange
            string testFolder = TestUtils.CreateTestSpecificFolder(this.TestContext);
            string configFile = CreateAnalysisConfig(testFolder);

            TestLogger logger = new TestLogger();

            AnalysisConfig result = null;
            PerformOpOnLockedFile(configFile, () => result = TaskUtilities.TryGetConfig(testFolder, logger), shouldTimeoutReadingConfig: false);

            Assert.IsNotNull(result, "Expecting the config to have been loaded");

            AssertRetryAttempted(logger);
            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        [TestCategory("Task")] // Regression test for bug http://jira.codehaus.org/browse/SONARMSBRU-11
        public void TaskUtils_LoadConfig_TimeoutIfConfigLocked_NullReturned()
        {
            // Arrange
            // We'll lock the file and sleep for long enough for the task to timeout
            string testFolder = TestUtils.CreateTestSpecificFolder(this.TestContext);
            string configFile = CreateAnalysisConfig(testFolder);

            TestLogger logger = new TestLogger();

            AnalysisConfig result = null;

            PerformOpOnLockedFile(configFile, () => result = TaskUtilities.TryGetConfig(testFolder, logger), shouldTimeoutReadingConfig: true);

            Assert.IsNull(result, "Not expecting the config to be retrieved");

            AssertRetryAttempted(logger);
            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(1);
        }
        public void RoslynConfig_ValidProfile()
        {
            // Arrange
            string rootDir = CreateTestFolders();
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings = CreateSettings(rootDir);

            WellKnownProfile testProfile = CreateValidCSharpProfile();
            MockSonarQubeServer mockServer = CreateServer("valid.project", null, "valid.profile", testProfile);

            MockAnalyzerInstaller mockInstaller = new MockAnalyzerInstaller();
            mockInstaller.AssemblyPathsToReturn = new HashSet<string>(new string[] { "c:\\assembly1.dll", "d:\\foo\\assembly2.dll" });

            RoslynAnalyzerProvider testSubject = new RoslynAnalyzerProvider(mockInstaller, logger);

            // Act
            AnalyzerSettings actualSettings = testSubject.SetupAnalyzers(mockServer, settings, "valid.project", null);

            // Assert
            CheckSettingsInvariants(actualSettings);
            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);

            CheckRuleset(actualSettings, rootDir);
            CheckExpectedAdditionalFiles(testProfile, actualSettings);

            mockInstaller.AssertExpectedPackagesRequested(testProfile.Packages);
            CheckExpectedAssemblies(actualSettings, "c:\\assembly1.dll", "d:\\foo\\assembly2.dll");
        }
        public void ReportProcessor_MultipleUrlsFound()
        {
            // Arrange
            MockReportUrlProvider urlProvider = new MockReportUrlProvider() { UrlsToReturn = new string[] { ValidUrl1, ValidUrl2 } };
            MockReportDownloader downloader = new MockReportDownloader();
            MockReportConverter converter = new MockReportConverter() { CanConvert = true };
            AnalysisConfig context = this.CreateValidContext();
            TeamBuildSettings settings = this.CreateValidSettings();
            TestLogger logger = new TestLogger();

            TfsLegacyCoverageReportProcessor processor = new TfsLegacyCoverageReportProcessor(urlProvider, downloader, converter);

            // Act
            bool initResult = processor.Initialise(context, settings, logger);
            Assert.IsTrue(initResult, "Expecting true: processor should have been initialised successfully");
            bool result = processor.ProcessCoverageReports();

            // Assert
            urlProvider.AssertGetUrlsCalled();
            downloader.AssertDownloadNotCalled(); // Multiple urls so should early out
            converter.AssertConvertNotCalled();
            Assert.IsFalse(result, "Expecting false: can't process multiple coverage reports");

            logger.AssertErrorsLogged(1);
            logger.AssertWarningsLogged(0);
        }
        public void TBSettings_LegacyTeamBuild()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings;

            using (EnvironmentVariableScope scope = new EnvironmentVariableScope())
            {
                scope.SetVariable(TeamBuildSettings.EnvironmentVariables.IsInTeamBuild, "TRUE");
                scope.SetVariable(TeamBuildSettings.EnvironmentVariables.BuildUri_Legacy, "http://legacybuilduri");
                scope.SetVariable(TeamBuildSettings.EnvironmentVariables.TfsCollectionUri_Legacy, "http://legacycollectionUri");
                scope.SetVariable(TeamBuildSettings.EnvironmentVariables.BuildDirectory_Legacy, "legacy build dir");

                // Act
                settings = TeamBuildSettings.GetSettingsFromEnvironment(logger);
            }

            // Assert
            Assert.IsNotNull(settings, "Failed to create the TeamBuildSettings");
            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);

            // Check the environment properties
            CheckExpectedSettings(settings, BuildEnvironment.LegacyTeamBuild, Directory.GetCurrentDirectory(), "http://legacybuilduri", "http://legacycollectionUri", "legacy build dir");
        }
        public void ReportProcessor_SingleUrlFound_DownloadedOk()
        {
            // Arrange
            MockReportUrlProvider urlProvider = new MockReportUrlProvider() { UrlsToReturn = new string[] { ValidUrl2 } };
            MockReportDownloader downloader = new MockReportDownloader();
            MockReportConverter converter = new MockReportConverter() { CanConvert = true };
            AnalysisConfig context = this.CreateValidContext();
            TeamBuildSettings settings = this.CreateValidSettings();
            TestLogger logger = new TestLogger();

            downloader.CreateFileOnDownloadRequest = true;

            TfsLegacyCoverageReportProcessor processor = new TfsLegacyCoverageReportProcessor(urlProvider, downloader, converter);

            // Act
            bool initResult = processor.Initialise(context, settings, logger);
            Assert.IsTrue(initResult, "Expecting true: processor should have been initialised successfully");
            bool result = processor.ProcessCoverageReports();

            // Assert
            urlProvider.AssertGetUrlsCalled();
            downloader.AssertExpectedDownloads(1);
            converter.AssertExpectedNumberOfConversions(1);

            downloader.AssertExpectedUrlsRequested(ValidUrl2);
            downloader.AssertExpectedTargetFileNamesSupplied(Path.Combine(context.SonarOutputDir, TfsLegacyCoverageReportProcessor.DownloadFileName));
            Assert.IsTrue(result, "Expecting true: happy path");

            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        public void ReportProcessor_NoUrlsFound()
        {
            // Arrange
            MockReportUrlProvider urlProvider = new MockReportUrlProvider() { UrlsToReturn = new string[] { } };
            MockReportDownloader downloader = new MockReportDownloader();
            MockReportConverter converter = new MockReportConverter() { CanConvert = true };
            AnalysisConfig context = this.CreateValidContext();
            TeamBuildSettings settings = this.CreateValidSettings();
            TestLogger logger = new TestLogger();

            TfsLegacyCoverageReportProcessor processor = new TfsLegacyCoverageReportProcessor(urlProvider, downloader, converter);

            // Act
            bool initResult = processor.Initialise(context, settings, logger);
            Assert.IsTrue(initResult, "Expecting true: processor should have been initialised successfully");
            bool result = processor.ProcessCoverageReports();

            // Assert
            urlProvider.AssertGetUrlsCalled();
            downloader.AssertDownloadNotCalled(); // no urls returned, so should go any further
            converter.AssertConvertNotCalled();
            Assert.IsTrue(result, "Expecting true: no coverage reports is a valid scenario");

            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        public void FileGen_VSBootstrapperIsDisabled()
        {
            // 0. Arrange
            TestLogger logger = new TestLogger();

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("disableBootstrapper", logger);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingExists(PropertiesFileGenerator.VSBootstrapperPropertyKey, "false");
            logger.AssertWarningsLogged(0);
        }
        public void RoslynConfig_DuplicateAdditionalFileName_DuplicateFileIgnored()
        {
            // Arrange
            string rootDir = CreateTestFolders();
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings = CreateSettings(rootDir);

            string expectedFileContent = "expected";
            string unexpectedFileContent = "not expected: file should already exist with the expected content";

            MockSonarQubeServer mockServer = CreateValidServer("valid.project", null, "valid.profile");
            QualityProfile csProfile = mockServer.Data.FindProfile("valid.profile", RoslynAnalyzerProvider.CSharpLanguage);
            csProfile.SetExport(RoslynAnalyzerProvider.RoslynCSharpFormatName, @"<?xml version=""1.0"" encoding=""utf-8""?>
<RoslynExportProfile Version=""1.0="">
  <Configuration>
    <RuleSet />
    <AdditionalFiles>
      <AdditionalFile FileName=""foo.txt"" >" + GetBase64EncodedString(expectedFileContent) + @"</AdditionalFile>
      <AdditionalFile FileName=""foo.txt"" >" + GetBase64EncodedString(unexpectedFileContent) + @"</AdditionalFile>
      <AdditionalFile FileName=""file2.txt""></AdditionalFile>
    </AdditionalFiles>
  </Configuration>
  <Deployment />
</RoslynExportProfile>");

            RoslynAnalyzerProvider testSubject = CreateTestSubject(logger);

            // Act
            AnalyzerSettings actualSettings = testSubject.SetupAnalyzers(mockServer, settings, "valid.project", null);

            // Assert
            CheckSettingsInvariants(actualSettings);
            CheckRuleset(actualSettings, rootDir);
            CheckExpectedAdditionalFileExists("foo.txt", expectedFileContent, actualSettings);
            CheckExpectedAdditionalFileExists("file2.txt", string.Empty, actualSettings);

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
        }
        public void ArgProc_BeginVerb_MatchesOnlyCompleteWord()
        {
            // Arrange
            TestLogger logger;
            string validUrl = "/d:sonar.host.url=http://foo";

            // 1. "beginx" -> valid, child argument "beginx"
            logger = new TestLogger();
            IBootstrapperSettings settings = CheckProcessingSucceeds(logger, validUrl, "beginX");
            AssertExpectedPhase(AnalysisPhase.PreProcessing, settings);
            logger.AssertWarningsLogged(1); // Expecting a warning because "beginX" should not be recognised as "begin"
            AssertExpectedChildArguments(settings, validUrl, "beginX");

            // 2. "begin", "beginx" should not be treated as duplicates
            logger = new TestLogger();
            settings = CheckProcessingSucceeds(logger, validUrl, "begin", "beginX");
            AssertExpectedPhase(AnalysisPhase.PreProcessing, settings);
            logger.AssertWarningsLogged(0);
            AssertExpectedChildArguments(settings, validUrl, "beginX");
        }
        public void AnalysisConfGen_FileProperties()
        {
            // File properties should not be copied to the file.
            // Instead, a pointer to the file should be created.

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

            TestLogger logger = new TestLogger();

            // The set of file properties to supply
            AnalysisProperties fileProperties = new AnalysisProperties();
            fileProperties.Add(new Property() { Id = SonarProperties.HostUrl, Value = "http://myserver" });
            fileProperties.Add(new Property() { Id = "file.only", Value = "file value" });
            string settingsFilePath = Path.Combine(analysisDir, "settings.txt");
            fileProperties.Save(settingsFilePath);

            FilePropertyProvider fileProvider = FilePropertyProvider.Load(settingsFilePath);

            ProcessedArgs args = new ProcessedArgs("key", "name", "version", false, EmptyPropertyProvider.Instance, fileProvider);

            TeamBuildSettings settings = TeamBuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir);
            Directory.CreateDirectory(settings.SonarConfigDirectory); // config directory needs to exist

            // Act
            AnalysisConfig actualConfig = AnalysisConfigGenerator.GenerateFile(args, settings, new Dictionary<string, string>(), logger);

            // Assert
            AssertConfigFileExists(actualConfig);
            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);

            string actualSettingsFilePath = actualConfig.GetSettingsFilePath();
            Assert.AreEqual(settingsFilePath, actualSettingsFilePath, "Unexpected settings file path");

            // Check the file setting value do not appear in the config file
            AssertFileDoesNotContainText(actualConfig.FileName, "file.only");

            Assert.AreEqual(settings.SonarRunnerWorkingDirectory, actualConfig.SonarRunnerWorkingDirectory);
        }
        public void RoslynConfig_MissingRuleset()
        {
            // Arrange
            string rootDir = CreateTestFolders();
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings = CreateSettings(rootDir);

            MockSonarQubeServer mockServer = CreateValidServer("valid.project", null, "valid.profile");
            QualityProfile csProfile = mockServer.Data.FindProfile("valid.profile", RoslynAnalyzerProvider.CSharpLanguage);
            csProfile.SetExport(RoslynAnalyzerProvider.RoslynCSharpFormatName, @"<?xml version=""1.0"" encoding=""utf-8""?>
<RoslynExportProfile Version=""1.0="">
  <Configuration>
    <!-- Missing ruleset -->
    <AdditionalFiles>
      <AdditionalFile FileName=""SonarLint.xml"" >
      </AdditionalFile>
    </AdditionalFiles>
  </Configuration>
  <Deployment>
    <NuGetPackages>
      <NuGetPackage Id=""SonarLint"" Version=""1.3.0""/>
    </NuGetPackages>
  </Deployment>
</RoslynExportProfile>");

            RoslynAnalyzerProvider testSubject = CreateTestSubject(logger);

            // Act
            AnalyzerSettings actualSettings = testSubject.SetupAnalyzers(mockServer, settings, "valid.project", null);

            // Assert
            AssertAnalyzerSetupNotPerformed(actualSettings, rootDir);

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
        }
        public void TBSettings_NonLegacyTeamBuild()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings;

            using (EnvironmentVariableScope scope = new EnvironmentVariableScope())
            {
                scope.SetVariable(TeamBuildSettings.EnvironmentVariables.IsInTeamBuild, "TRUE");
                scope.SetVariable(TeamBuildSettings.EnvironmentVariables.BuildUri_TFS2015, "http://builduri");
                scope.SetVariable(TeamBuildSettings.EnvironmentVariables.TfsCollectionUri_TFS2015, "http://collectionUri");
                scope.SetVariable(TeamBuildSettings.EnvironmentVariables.BuildDirectory_TFS2015, "non-legacy team build");
                scope.SetVariable(TeamBuildSettings.EnvironmentVariables.SourcesDirectory_TFS2015, @"c:\agent\_work\1"); ;

                // Act
                settings = TeamBuildSettings.GetSettingsFromEnvironment(logger);
            }

            // Assert
            Assert.IsNotNull(settings, "Failed to create the TeamBuildSettings");
            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);

            // Check the environment properties
            CheckExpectedSettings(
                settings,
                BuildEnvironment.TeamBuild,
                Directory.GetCurrentDirectory(),
                "http://builduri",
                "http://collectionUri",
                "non-legacy team build",
                @"c:\agent\_work\1");
        }
        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 FileGen_VSBootstrapperIsDisabled_OverrideUserSettings_SameValue()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            Property bootstrapperProperty = new Property() { Id = PropertiesFileGenerator.VSBootstrapperPropertyKey, Value = "false" };

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("disableBootstrapperSame", logger, bootstrapperProperty);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingExists(PropertiesFileGenerator.VSBootstrapperPropertyKey, "false");
            logger.AssertSingleDebugMessageExists(PropertiesFileGenerator.VSBootstrapperPropertyKey);
            logger.AssertWarningsLogged(0); // not expecting a warning if the user has supplied the value we want
        }
        public void RoslynConfig_ValidProfile_BranchSpecific()
        {
            // Arrange
            string rootDir = CreateTestFolders();
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings = CreateSettings(rootDir);

            // Differentiate the branch-specific and non-branch-specific profiles
            WellKnownProfile nonBranchSpecificProfile = CreateValidCSharpProfile();
            WellKnownProfile branchSpecificProfile = CreateValidCSharpProfile();
            branchSpecificProfile.AssemblyFilePaths.Add("e:\\assembly3.dll");

            MockSonarQubeServer mockServer = CreateServer("valid.project", null, "valid.profile", nonBranchSpecificProfile);
            AddWellKnownProfileToServer("valid.project", "aBranch", "valid.anotherProfile", branchSpecificProfile, mockServer);

            MockAnalyzerInstaller mockInstaller = new MockAnalyzerInstaller();
            mockInstaller.AssemblyPathsToReturn = new HashSet<string>(new string[] { "c:\\assembly1.dll", "d:\\foo\\assembly2.dll", "e:\\assembly3.dll" });

            RoslynAnalyzerProvider testSubject = new RoslynAnalyzerProvider(mockInstaller, logger);

            // Act
            AnalyzerSettings actualSettings = testSubject.SetupAnalyzers(mockServer, settings, "valid.project", "aBranch");

            // Assert
            CheckSettingsInvariants(actualSettings);
            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);

            CheckRuleset(actualSettings, rootDir);
            CheckExpectedAdditionalFiles(branchSpecificProfile, actualSettings);

            mockInstaller.AssertExpectedPackagesRequested(branchSpecificProfile.Packages);
            CheckExpectedAssemblies(actualSettings, "c:\\assembly1.dll", "d:\\foo\\assembly2.dll", "e:\\assembly3.dll");
        }
        public void ArgProc_EndVerb()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            string validUrl = "/d:sonar.host.url=http://foo";

            // 1. Minimal parameters -> valid
            IBootstrapperSettings settings = CheckProcessingSucceeds(logger, "end");
            AssertExpectedPhase(AnalysisPhase.PostProcessing, settings);
            AssertExpectedChildArguments(settings);

            // 2. With additional parameters -> valid
            logger = new TestLogger();
            settings = CheckProcessingSucceeds(logger, "end", "ignored", "/d:key=value");
            AssertExpectedPhase(AnalysisPhase.PostProcessing, settings);
            logger.AssertWarningsLogged(0);
            AssertExpectedChildArguments(settings, "ignored", "/d:key=value");

            // 3. Multiple occurrences -> invalid
            logger = CheckProcessingFails(validUrl, "end", "end");
            logger.AssertSingleErrorExists(ArgumentProcessor.EndVerb);

            // 4. Missing, no other arguments -> valid with warning
            logger = new TestLogger();
            settings = CheckProcessingSucceeds(logger);
            AssertExpectedPhase(AnalysisPhase.PostProcessing, settings);
            logger.AssertWarningsLogged(1);
            AssertExpectedChildArguments(settings);

            // 5. Incorrect case -> unrecognised -> treated as preprocessing -> fails (URL not supplied)
            logger = CheckProcessingFails("END");
            logger.AssertErrorsLogged();

            // 6. Partial match -> unrecognised -> treated as preprocessing -> fails (URL not supplied)
            logger = CheckProcessingFails("endX");
            logger.AssertErrorsLogged();
        }
        public void RoslynConfig_ValidRealSonarLintProfile()
        {
            // Arrange
            string rootDir = CreateTestFolders();
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings = CreateSettings(rootDir);

            WellKnownProfile testProfile = CreateRealSonarLintProfile();
            MockSonarQubeServer mockServer = CreateServer("valid.project", null, "valid.profile", testProfile);

            RoslynAnalyzerProvider testSubject = CreateTestSubject(logger);

            // Act
            AnalyzerSettings actualSettings = testSubject.SetupAnalyzers(mockServer, settings, "valid.project", null);

            // Assert
            CheckSettingsInvariants(actualSettings);
            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
            CheckRuleset(actualSettings, rootDir);
            CheckExpectedAdditionalFiles(testProfile, actualSettings);

            // Check the additional file is valid XML
            Assert.AreEqual(1, actualSettings.AdditionalFilePaths.Count(), "Test setup error: expecting only one additional file. Check the sample export XML has not changed");
            string filePath = actualSettings.AdditionalFilePaths.First();
            CheckFileIsXml(filePath);
        }
        public void ArgProc_EndVerb_MatchesOnlyCompleteWord()
        {
            // Arrange
            TestLogger logger;
            IBootstrapperSettings settings;
            logger = new TestLogger();

            // Act
            // "end", "endx" should not be treated as duplicates
            settings = CheckProcessingSucceeds(logger, "end", "endX", "endXXX");

            // Assert
            AssertExpectedPhase(AnalysisPhase.PostProcessing, settings);
            logger.AssertWarningsLogged(0);
            AssertExpectedChildArguments(settings, "endX", "endXXX");
        }
        public void RoslynConfig_NoAnalyzerAssemblies_Succeeds()
        {
            // Arrange
            string rootDir = CreateTestFolders();
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings = CreateSettings(rootDir);

            MockSonarQubeServer mockServer = CreateValidServer("valid.project", null, "valid.profile");
            QualityProfile csProfile = mockServer.Data.FindProfile("valid.profile", RoslynAnalyzerProvider.CSharpLanguage);
            csProfile.SetExport(RoslynAnalyzerProvider.RoslynCSharpFormatName, @"<?xml version=""1.0"" encoding=""utf-8""?>
<RoslynExportProfile Version=""1.0="">
  <Configuration>
    <RuleSet />
    <AdditionalFiles />
  </Configuration>
  <Deployment>
    <NuGetPackages /> <!-- empty -->
  </Deployment>
</RoslynExportProfile>");

            RoslynAnalyzerProvider testSubject = CreateTestSubject(logger);

            // Act
            AnalyzerSettings actualSettings = testSubject.SetupAnalyzers(mockServer, settings, "valid.project", null);

            // Assert
            CheckSettingsInvariants(actualSettings);

            CheckExpectedAssemblies(actualSettings /* none */ );

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
        }
        public void FileGen_ExcludedProjectsAreNotDuplicates()
        {
            // Excluded ProjectInfo files should be ignored when calculating duplicates

            // Arrange - two sub-directories, neither containing a ProjectInfo.xml
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            Guid duplicateGuid = Guid.NewGuid();
            CreateProjectInfoInSubDir(testDir, "excl1", duplicateGuid, ProjectType.Product, true, null); // excluded
            CreateProjectInfoInSubDir(testDir, "excl2", duplicateGuid, ProjectType.Test, true, null); // excluded
            CreateProjectInfoInSubDir(testDir, "notExcl", duplicateGuid, ProjectType.Product, false, null); // not excluded

            TestLogger logger = new TestLogger();
            AnalysisConfig config = CreateValidConfig(testDir);

            // Act
            ProjectInfoAnalysisResult result = PropertiesFileGenerator.GenerateFile(config, logger);

            // Assert
            AssertExpectedStatus("excl1", ProjectInfoValidity.ExcludeFlagSet, result);
            AssertExpectedStatus("excl2", ProjectInfoValidity.ExcludeFlagSet, result);
            AssertExpectedStatus("notExcl", ProjectInfoValidity.NoFilesToAnalyze, result); // not "duplicate" since the duplicate guids are excluded
            AssertExpectedProjectCount(3, result);

            // One valid project info file -> file
            AssertFailedToCreatePropertiesFiles(result, logger);
            logger.AssertWarningsLogged(0); // not expecting any warnings
        }
Exemplo n.º 29
0
        public void PreProc_EndToEnd_SuccessCase()
        {
            // Checks end-to-end happy path for the pre-processor i.e.
            // * arguments are parsed
            // * targets are installed
            // * build wrapper installer is called
            // * 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();
            MockBuildWrapperInstaller mockBuildWrapperInstaller = new MockBuildWrapperInstaller();

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

            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

            mockBuildWrapperInstaller.AssertExpectedCallCount(1);

            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 ArgProc_BeginVerb()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            string validUrl = "/d:sonar.host.url=http://foo";

            // 1. Minimal parameters -> valid
            IBootstrapperSettings settings = CheckProcessingSucceeds(logger, validUrl, "begin");
            AssertExpectedPhase(AnalysisPhase.PreProcessing, settings);
            logger.AssertWarningsLogged(0);
            AssertExpectedChildArguments(settings, validUrl);

            // 2. With additional parameters -> valid
            settings = CheckProcessingSucceeds(logger, validUrl, "begin", "ignored", "k=2");
            AssertExpectedPhase(AnalysisPhase.PreProcessing, settings);
            logger.AssertWarningsLogged(0);
            AssertExpectedChildArguments(settings, validUrl, "ignored", "k=2");

            // 3. Multiple occurrences -> error
            logger = CheckProcessingFails(validUrl, "begin", "begin");
            logger.AssertSingleErrorExists(ArgumentProcessor.BeginVerb);

            // 4. Missing -> valid with warning
            logger = new TestLogger();
            settings = CheckProcessingSucceeds(logger, validUrl);
            logger.AssertSingleWarningExists(ArgumentProcessor.BeginVerb);
            AssertExpectedChildArguments(settings, validUrl);

            // 5. Incorrect case -> treated as unrecognised argument
            // -> valid with 1 warning (no begin / end specified warning)
            logger = new TestLogger();
            settings = CheckProcessingSucceeds(logger, validUrl, "BEGIN"); // wrong case
            logger.AssertWarningsLogged(1);
            logger.AssertSingleWarningExists(ArgumentProcessor.BeginVerb);
            AssertExpectedChildArguments(settings, validUrl, "BEGIN");
        }