public async Task BindingWorkflow_DownloadQualityProfile_WithNoRules_Fails()
        {
            // Arrange
            const string    QualityProfileName        = "SQQualityProfileName";
            const string    ProjectName               = "SQProjectName";
            BindingWorkflow testSubject               = this.CreateTestSubject("key", ProjectName);
            ConfigurableProgressController controller = new ConfigurableProgressController();
            var notifications = new ConfigurableProgressStepExecutionEvents();

            RuleSet ruleSet         = TestRuleSetHelper.CreateTestRuleSetWithRuleIds(Enumerable.Empty <string>());
            var     nugetPackages   = new[] { new PackageName("myPackageId", new SemanticVersion("1.0.0")) };
            var     additionalFiles = new[] { new AdditionalFileResponse {
                                                  FileName = "abc.xml", Content = new byte[] { 1, 2, 3 }
                                              } };
            RoslynExportProfileResponse export = RoslynExportProfileHelper.CreateExport(ruleSet, nugetPackages, additionalFiles);

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureProfileExport(export, language, QualityProfileName);

            // Act
            await testSubject.DownloadQualityProfileAsync(controller, notifications, new[] { language }, CancellationToken.None);

            // Assert
            testSubject.Rulesets.Should().NotContainKey(Language.VBNET, "Not expecting any rules for this language");
            testSubject.Rulesets.Should().NotContainKey(language, "Not expecting any rules");
            controller.NumberOfAbortRequests.Should().Be(1);

            notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage);

            this.outputWindowPane.AssertOutputStrings(1);
            var expectedOutput = string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.NoSonarAnalyzerActiveRulesForQualityProfile, QualityProfileName, language.Name));

            this.outputWindowPane.AssertOutputStrings(expectedOutput);
        }
        public void TestInitialize()
        {
            emptyRules = Array.Empty <SonarQubeRule>();

            validRules = new List <SonarQubeRule>
            {
                new SonarQubeRule("key", "repoKey", true, SonarQubeIssueSeverity.Blocker, null, SonarQubeIssueType.Bug)
            };

            anyProperties = Array.Empty <SonarQubeProperty>();

            validQualityProfile = new SonarQubeQualityProfile("qpkey1", "qp name", "any", false, DateTime.UtcNow);

            validNugetPackages = new List <NuGetPackageInfo> {
                new NuGetPackageInfo("package.id", "1.2")
            };

            validRuleSet = new CoreRuleSet
            {
                Description  = OriginalValidRuleSetDescription,
                ToolsVersion = "12.0",
                Rules        = new List <Core.CSharpVB.Rules>
                {
                    new Core.CSharpVB.Rules
                    {
                        AnalyzerId = "my analyzer", RuleNamespace = "my namespace"
                    }
                }
            };
        }
        public async Task DownloadQualityProfile_WhenBindingConfigIsNull_Fails()
        {
            // Arrange
            const string QualityProfileName = "SQQualityProfileName";
            const string ProjectName        = "SQProjectName";

            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();

            var notifications   = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(notifications);

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureQualityProfile(language, QualityProfileName);

            var configProviderMock = new Mock <IBindingConfigProvider>();
            var testSubject        = this.CreateTestSubject("key", ProjectName, nuGetOpMock.Object, configProviderMock.Object);

            ConfigureSupportedBindingProject(testSubject.InternalState, language);

            // Act
            var result = await testSubject.DownloadQualityProfileAsync(progressAdapter, CancellationToken.None);

            // Assert
            result.Should().BeFalse();
            testSubject.InternalState.QualityProfiles[language].Should().Be(profile);

            notifications.AssertProgress(0.0);
            notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage);

            this.outputWindowPane.AssertOutputStrings(1);
            var expectedOutput = string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.FailedToCreateBindingConfigForLanguage, language.Name));

            this.outputWindowPane.AssertOutputStrings(expectedOutput);
        }
        private FilePathAndContent <RuleSet> GetRulesetFile(SonarQubeQualityProfile qualityProfile, Language language, BindingConfiguration bindingConfiguration, IEnumerable <SonarQubeRule> activeRules, IEnumerable <SonarQubeRule> inactiveRules, Dictionary <string, string> sonarProperties)
        {
            var RuleSet = CreateRuleset(qualityProfile, language, bindingConfiguration, activeRules.Union(inactiveRules), sonarProperties);

            var ruleSetFilePath = GetSolutionRuleSetFilePath(language, bindingConfiguration);

            return(new FilePathAndContent <RuleSet>(ruleSetFilePath, RuleSet));
        }
        public Task <IBindingConfig> GetConfigurationAsync(SonarQubeQualityProfile qualityProfile, Language language, BindingConfiguration bindingConfiguration, CancellationToken cancellationToken)
        {
            if (!IsLanguageSupported(language))
            {
                throw new ArgumentOutOfRangeException(nameof(language));
            }

            return(DoGetConfigurationAsync(qualityProfile, language, bindingConfiguration, cancellationToken));
        }
        private SonarQubeQualityProfile ConfigureQualityProfile(Language language, string profileName)
        {
            var profile = new SonarQubeQualityProfile("", profileName, "", false, DateTime.Now);

            this.sonarQubeServiceMock
            .Setup(x => x.GetQualityProfileAsync(It.IsAny <string>(), It.IsAny <string>(), language.ServerLanguage, It.IsAny <CancellationToken>()))
            .ReturnsAsync(profile);

            return(profile);
        }
        private RuleSet CreateRuleset(SonarQubeQualityProfile qualityProfile, Language language, BindingConfiguration bindingConfiguration, IEnumerable <SonarQubeRule> rules, Dictionary <string, string> sonarProperties)
        {
            var coreRuleset = ruleSetGenerator.Generate(language.ServerLanguage.Key, rules, sonarProperties);

            // Set the name and description
            coreRuleset.Name = string.Format(Strings.SonarQubeRuleSetNameFormat, bindingConfiguration.Project.ProjectName, qualityProfile.Name);
            var descriptionSuffix = string.Format(Strings.SonarQubeQualityProfilePageUrlFormat, bindingConfiguration.Project.ServerUri, qualityProfile.Key);

            coreRuleset.Description = $"{coreRuleset.Description} {descriptionSuffix}";
            return(coreRuleset);
        }
        private void UpdateDownloadedSonarQubeQualityProfile(RuleSet ruleSet, SonarQubeQualityProfile qualityProfile)
        {
            ruleSet.NonLocalizedDisplayName = string.Format(Strings.SonarQubeRuleSetNameFormat, this.project.Name, qualityProfile.Name);

            var ruleSetDescriptionBuilder = new StringBuilder();

            ruleSetDescriptionBuilder.AppendLine(ruleSet.Description);
            ruleSetDescriptionBuilder.AppendFormat(Strings.SonarQubeQualityProfilePageUrlFormat, this.connectionInformation.ServerUri, qualityProfile.Key);
            ruleSet.NonLocalizedDescription = ruleSetDescriptionBuilder.ToString();

            ruleSet.WriteToFile(ruleSet.FilePath);
        }
        public async Task BindingWorkflow_DownloadQualityProfile_Success()
        {
            // Arrange
            const string QualityProfileName = "SQQualityProfileName";
            const string ProjectName        = "SQProjectName";

            // Record all of the calls to NuGetBindingOperation.ProcessExport
            var actualProfiles = new List <Tuple <Language, RoslynExportProfileResponse> >();
            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();

            nuGetOpMock.Setup(x => x.ProcessExport(It.IsAny <Language>(), It.IsAny <RoslynExportProfileResponse>()))
            .Callback <Language, RoslynExportProfileResponse>((l, r) => actualProfiles.Add(new Tuple <Language, RoslynExportProfileResponse>(l, r)))
            .Returns(true);

            BindingWorkflow testSubject = this.CreateTestSubject("key", ProjectName, nuGetOpMock.Object);


            ConfigurableProgressController controller = new ConfigurableProgressController();
            var notifications = new ConfigurableProgressStepExecutionEvents();

            RuleSet ruleSet         = TestRuleSetHelper.CreateTestRuleSetWithRuleIds(new[] { "Key1", "Key2" });
            var     expectedRuleSet = new RuleSet(ruleSet)
            {
                NonLocalizedDisplayName = string.Format(Strings.SonarQubeRuleSetNameFormat, ProjectName, QualityProfileName),
                NonLocalizedDescription = "\r\nhttp://connected/profiles/show?key="
            };
            var nugetPackages   = new[] { new PackageName("myPackageId", new SemanticVersion("1.0.0")) };
            var additionalFiles = new[] { new AdditionalFileResponse {
                                              FileName = "abc.xml", Content = new byte[] { 1, 2, 3 }
                                          } };
            RoslynExportProfileResponse export = RoslynExportProfileHelper.CreateExport(ruleSet, nugetPackages, additionalFiles);

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureProfileExport(export, language, QualityProfileName);

            // Act
            await testSubject.DownloadQualityProfileAsync(controller, notifications, new[] { language }, CancellationToken.None);

            // Assert
            RuleSetAssert.AreEqual(expectedRuleSet, testSubject.Rulesets[language], "Unexpected rule set");
            testSubject.QualityProfiles[language].Should().Be(profile);
            VerifyNuGetPackgesDownloaded(nugetPackages, language, actualProfiles);

            controller.NumberOfAbortRequests.Should().Be(0);
            notifications.AssertProgress(0.0, 1.0);
            notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage, string.Empty);

            this.outputWindowPane.AssertOutputStrings(1);
            var expectedOutput = string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.QualityProfileDownloadSuccessfulMessageFormat, QualityProfileName, string.Empty, language.Name));

            this.outputWindowPane.AssertOutputStrings(expectedOutput);
        }
            public TestEnvironmentBuilder(SonarQubeQualityProfile profile, Language language,
                                          string projectName = "any", string serverUrl = "http://any")
            {
                this.profile     = profile;
                this.language    = language;
                this.projectName = projectName;
                this.serverUrl   = serverUrl;

                Logger = new TestLogger();
                SonarLintConfigurationResponse = new SonarLintConfiguration();
                PropertiesResponse             = new List <SonarQubeProperty>();
            }
示例#11
0
        public async Task <IBindingConfigFile> GetConfigurationAsync(SonarQubeQualityProfile qualityProfile, string organizationKey, Language language, CancellationToken cancellationToken)
        {
            if (!IsLanguageSupported(language))
            {
                throw new ArgumentOutOfRangeException(nameof(language));
            }

            var serverLanguage = language.ServerLanguage;

            Debug.Assert(serverLanguage != null,
                         $"Server language should not be null for supported language: {language.Id}");

            // Generate the rules configuration file for the language
            var roslynProfileExporter = await WebServiceHelper.SafeServiceCallAsync(() =>
                                                                                    this.sonarQubeService.GetRoslynExportProfileAsync(qualityProfile.Name,
                                                                                                                                      organizationKey, serverLanguage, cancellationToken),
                                                                                    this.logger);

            if (roslynProfileExporter == null)
            {
                this.logger.WriteLine(string.Format(Strings.SubTextPaddingFormat,
                                                    string.Format(Strings.QualityProfileDownloadFailedMessageFormat, qualityProfile.Name,
                                                                  qualityProfile.Key, language.Name)));
                return(null);
            }

            var tempRuleSetFilePath = Path.GetTempFileName();

            File.WriteAllText(tempRuleSetFilePath, roslynProfileExporter.Configuration.RuleSet.OuterXml);
            RuleSet ruleSet = RuleSet.LoadFromFile(tempRuleSetFilePath);

            // Give up if the quality profile is empty
            if (ruleSet == null ||
                ruleSet.Rules.Count == 0 ||
                ruleSet.Rules.All(rule => rule.Action == RuleAction.None))
            {
                this.logger.WriteLine(string.Format(Strings.SubTextPaddingFormat,
                                                    string.Format(Strings.NoSonarAnalyzerActiveRulesForQualityProfile, qualityProfile.Name, language.Name)));
                return(null);
            }

            // Add the NuGet reference, if appropriate (only in legacy connected mode, and only C#/VB)
            if (!this.nuGetBindingOperation.ProcessExport(language, roslynProfileExporter))
            {
                return(null);
            }

            // Remove/Move/Refactor code when XML ruleset file is no longer downloaded but the proper API is used to retrieve rules
            UpdateDownloadedSonarQubeQualityProfile(ruleSet, qualityProfile, this.projectName, this.serverUrl);

            return(new DotNetBindingConfigFile(ruleSet));
        }
        private SonarQubeQualityProfile ConfigureProfileExport(RoslynExportProfileResponse export, Language language, string profileName)
        {
            var profile = new SonarQubeQualityProfile("", profileName, "", false, DateTime.Now);

            this.sonarQubeServiceMock
            .Setup(x => x.GetQualityProfileAsync(It.IsAny <string>(), It.IsAny <string>(), language.ToServerLanguage(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(profile);
            this.sonarQubeServiceMock
            .Setup(x => x.GetRoslynExportProfileAsync(profileName, It.IsAny <string>(), It.IsAny <SonarQubeLanguage>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(export);

            return(profile);
        }
示例#13
0
        public void GetConfiguration_NoMatchingProvider_Throws()
        {
            // Arrange
            var otherProvider = new DummyProvider(Language.VBNET);
            var qp            = new SonarQubeQualityProfile("key", "name", "language", false, DateTime.UtcNow);

            var testSubject = new CompositeBindingConfigProvider(otherProvider);

            // 1. Multiple matching providers -> config from the first matching provider returned
            Action act = () => testSubject.GetConfigurationAsync(qp, "org", Language.Cpp, CancellationToken.None).Wait();

            act.Should().ThrowExactly <AggregateException>().And.InnerException.Should().BeOfType <ArgumentOutOfRangeException>();
        }
示例#14
0
        public void SolutionBindingOperation_CommitSolutionBinding()
        {
            // Arrange
            this.serviceProvider.RegisterService(typeof(Persistence.ISolutionBindingSerializer), this.solutionBinding);
            var csProject = this.solutionMock.AddOrGetProject("CS.csproj");

            csProject.SetCSProjectKind();
            var projects = new[] { csProject };

            var connectionInformation            = new ConnectionInformation(new Uri("http://xyz"));
            SolutionBindingOperation testSubject = this.CreateTestSubject("key", connectionInformation);

            var ruleSetMap = new Dictionary <Language, RuleSet>();

            ruleSetMap[Language.CSharp] = new RuleSet("cs");
            testSubject.RegisterKnownRuleSets(ruleSetMap);
            var profiles = GetQualityProfiles();

            profiles[Language.CSharp] = new SonarQubeQualityProfile("C# Profile", "", "", false, DateTime.Now);
            testSubject.Initialize(projects, profiles);
            testSubject.Binders.Clear(); // Ignore the real binders, not part of this test scope
            bool commitCalledForBinder = false;

            testSubject.Binders.Add(new ConfigurableBindingOperation {
                CommitAction = () => commitCalledForBinder = true
            });
            testSubject.Prepare(CancellationToken.None);
            this.solutionBinding.WriteSolutionBindingAction = bindingInfo =>
            {
                bindingInfo.ServerUri.Should().Be(connectionInformation.ServerUri);
                bindingInfo.Profiles.Should().HaveCount(1);

                SonarQubeQualityProfile csProfile = profiles[Language.CSharp];
                bindingInfo.Profiles[Language.CSharp].ProfileKey.Should().Be(csProfile.Key);
                bindingInfo.Profiles[Language.CSharp].ProfileTimestamp.Should().Be(csProfile.TimeStamp);

                return("Doesn't matter");
            };

            // Sanity
            this.solutionBinding.WrittenFilesCount.Should().Be(0);

            // Act
            var commitResult = testSubject.CommitSolutionBinding();

            // Assert
            commitResult.Should().BeTrue();
            commitCalledForBinder.Should().BeTrue();
            this.solutionItemsProject.Files.ContainsKey(@"c:\solution\SonarQube\keyCSharp.ruleset").Should().BeTrue("Ruleset was expected to be added to solution items");
            this.solutionBinding.WrittenFilesCount.Should().Be(1);
        }
        public async Task DownloadQualityProfile_Success()
        {
            var configPersister = new ConfigurableConfigurationProvider();

            this.serviceProvider.RegisterService(typeof(IConfigurationPersister), configPersister);

            // Arrange
            const string QualityProfileName = "SQQualityProfileName";
            const string ProjectName        = "SQProjectName";

            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();

            var notifications   = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(notifications);

            var bindingConfig = new Mock <IBindingConfig>().Object;

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureQualityProfile(language, QualityProfileName);

            var configProviderMock = new Mock <IBindingConfigProvider>();

            configProviderMock.Setup(x => x.GetConfigurationAsync(profile, language, BindingConfiguration.Standalone, CancellationToken.None))
            .ReturnsAsync(bindingConfig);

            var bindingArgs = new BindCommandArgs("key", ProjectName, new ConnectionInformation(new Uri("http://connected")));
            var testSubject = this.CreateTestSubject(bindingArgs, nuGetOpMock.Object, configProviderMock.Object);

            ConfigureSupportedBindingProject(testSubject.InternalState, language);

            // Act
            var result = await testSubject.DownloadQualityProfileAsync(progressAdapter, CancellationToken.None);

            // Assert
            result.Should().BeTrue();
            testSubject.InternalState.BindingConfigs.Should().ContainKey(language);
            testSubject.InternalState.BindingConfigs[language].Should().Be(bindingConfig);
            testSubject.InternalState.BindingConfigs.Count().Should().Be(1);

            testSubject.InternalState.QualityProfiles[language].Should().Be(profile);

            notifications.AssertProgress(0.0, 1.0);
            notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage, string.Empty);

            this.outputWindowPane.AssertOutputStrings(1);
            var expectedOutput = string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.QualityProfileDownloadSuccessfulMessageFormat, QualityProfileName, string.Empty, language.Name));

            this.outputWindowPane.AssertOutputStrings(expectedOutput);
        }
        public void GetRules_UnsupportedLanguage_Throws()
        {
            // Arrange
            CancellationTokenSource       cts         = new CancellationTokenSource();
            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();
            var qualityProfile = new SonarQubeQualityProfile("key", "name", "language", false, DateTime.UtcNow);

            var testSubject = this.CreateTestSubject("key", "anyProject", nuGetOpMock.Object);

            // Act
            Action act = () => testSubject.GetConfigurationAsync(qualityProfile, null, Language.Cpp, cts.Token).Wait();

            // Assert
            act.Should().ThrowExactly <AggregateException>().And.InnerException.Should().BeOfType <ArgumentOutOfRangeException>();
        }
示例#17
0
        public async Task GetConfiguration_WithMatchingProvider_ExpectedConfigReturned()
        {
            // Arrange
            var otherProvider = new DummyProvider(Language.VBNET);
            var cppProvider1  = new DummyProvider(Language.Cpp);
            var cppProvider2  = new DummyProvider(Language.Cpp);

            var qp = new SonarQubeQualityProfile("key", "name", "language", false, DateTime.UtcNow);

            var testSubject = new CompositeBindingConfigProvider(otherProvider, cppProvider1, cppProvider2);

            // Act. Multiple matching providers -> config from the first matching provider returned
            var actualConfig = await testSubject.GetConfigurationAsync(qp, "org", Language.Cpp, CancellationToken.None);

            actualConfig.Should().Be(cppProvider1.ConfigToReturn);
        }
            private bool HasProfileChanged(SonarQubeQualityProfile newProfileInfo, ApplicableQualityProfile oldProfileInfo)
            {
                if (!SonarQubeQualityProfile.KeyComparer.Equals(oldProfileInfo.ProfileKey, newProfileInfo.Key))
                {
                    this.host.Logger.WriteLine(Strings.SonarLintProfileCheckDifferentProfile);
                    return(true); // The profile change to a different one
                }

                if (oldProfileInfo.ProfileTimestamp != newProfileInfo.TimeStamp)
                {
                    this.host.Logger.WriteLine(Strings.SonarLintProfileCheckProfileUpdated);
                    return(true); // The profile was updated
                }

                return(false);
            }
示例#19
0
        public async Task <IBindingConfig> GetConfigurationAsync(SonarQubeQualityProfile qualityProfile, Language language, BindingConfiguration bindingConfiguration, CancellationToken cancellationToken)
        {
            var provider = Providers.FirstOrDefault(p => p.IsLanguageSupported(language));

            if (provider == null)
            {
                throw new ArgumentOutOfRangeException(nameof(language));
            }
            IBindingConfig config = null;

            if (provider != null)
            {
                config = await provider?.GetConfigurationAsync(qualityProfile, language, bindingConfiguration, cancellationToken);
            }

            return(config);
        }
        public async Task DownloadQualityProfile_Success()
        {
            // Arrange
            const string QualityProfileName = "SQQualityProfileName";
            const string ProjectName        = "SQProjectName";

            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();

            var notifications   = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(notifications);

            RuleSet expectedRuleSet = TestRuleSetHelper.CreateTestRuleSetWithRuleIds(new[] { "Key1", "Key2" });
            var     configFile      = new Mock <IBindingConfigFile>().Object;

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureQualityProfile(language, QualityProfileName);

            var configProviderMock = new Mock <IBindingConfigProvider>();

            configProviderMock.Setup(x => x.GetConfigurationAsync(profile, null, language, CancellationToken.None))
            .ReturnsAsync(configFile);

            var testSubject = this.CreateTestSubject("key", ProjectName, nuGetOpMock.Object, configProviderMock.Object);

            ConfigureSupportedBindingProject(testSubject.InternalState, language);

            // Act
            var result = await testSubject.DownloadQualityProfileAsync(progressAdapter, CancellationToken.None);

            // Assert
            result.Should().BeTrue();
            testSubject.InternalState.BindingConfigFiles.Should().ContainKey(language);
            testSubject.InternalState.BindingConfigFiles[language].Should().Be(configFile);
            testSubject.InternalState.BindingConfigFiles.Count().Should().Be(1);

            testSubject.InternalState.QualityProfiles[language].Should().Be(profile);

            notifications.AssertProgress(0.0, 1.0);
            notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage, string.Empty);

            this.outputWindowPane.AssertOutputStrings(1);
            var expectedOutput = string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.QualityProfileDownloadSuccessfulMessageFormat, QualityProfileName, string.Empty, language.Name));

            this.outputWindowPane.AssertOutputStrings(expectedOutput);
        }
示例#21
0
        private void SetupServiceResponses(SonarQubeQualityProfile qualityProfileResponse,
                                           RoslynExportProfileResponse exportResponse)
        {
            serviceMock.Setup(x => x.GetQualityProfileAsync(
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <SonarQubeLanguage>(),
                                  It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult <SonarQubeQualityProfile>(qualityProfileResponse));

            serviceMock.Setup(x => x.GetRoslynExportProfileAsync(
                                  It.IsAny <string>(),
                                  It.IsAny <string>(),
                                  It.IsAny <SonarQubeLanguage>(),
                                  It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult <RoslynExportProfileResponse>(exportResponse));
        }
        public async Task GetConfig_Success()
        {
            // Arrange
            const string QualityProfileName = "SQQualityProfileName";
            const string ProjectName        = "SQProjectName";

            // Record all of the calls to NuGetBindingOperation.ProcessExport
            var actualProfiles = new List <Tuple <Language, RoslynExportProfileResponse> >();
            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();

            nuGetOpMock.Setup(x => x.ProcessExport(It.IsAny <Language>(), It.IsAny <RoslynExportProfileResponse>()))
            .Callback <Language, RoslynExportProfileResponse>((l, r) => actualProfiles.Add(new Tuple <Language, RoslynExportProfileResponse>(l, r)))
            .Returns(true);

            var testSubject = this.CreateTestSubject(ProjectName, "http://connected/", nuGetOpMock.Object);

            RuleSet ruleSet         = TestRuleSetHelper.CreateTestRuleSetWithRuleIds(new[] { "Key1", "Key2" });
            var     expectedRuleSet = new RuleSet(ruleSet)
            {
                NonLocalizedDisplayName = string.Format(Strings.SonarQubeRuleSetNameFormat, ProjectName, QualityProfileName),
                NonLocalizedDescription = "\r\nhttp://connected/profiles/show?key="
            };
            var nugetPackages   = new[] { new PackageName("myPackageId", new SemanticVersion("1.0.0")) };
            var additionalFiles = new[] { new AdditionalFileResponse {
                                              FileName = "abc.xml", Content = new byte[] { 1, 2, 3 }
                                          } };
            RoslynExportProfileResponse export = RoslynExportProfileHelper.CreateExport(ruleSet, nugetPackages, additionalFiles);

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureProfileExport(export, language, QualityProfileName);

            // Act
            var result = await testSubject.GetConfigurationAsync(profile, "TODO", language, CancellationToken.None)
                         .ConfigureAwait(false);

            // Assert
            result.Should().NotBeNull();
            var dotNetResult = result as DotNetBindingConfigFile;

            dotNetResult.Should().NotBeNull();

            RuleSetAssert.AreEqual(expectedRuleSet, dotNetResult.RuleSet, "Unexpected rule set");
            VerifyNuGetPackgesDownloaded(nugetPackages, language, actualProfiles);

            this.logger.AssertOutputStrings(0); // not expecting anything in the case of success
        }
        public async Task DownloadQualityProfile_SavesConfiguration()
        {
            var configPersister = new ConfigurableConfigurationProvider();

            this.serviceProvider.RegisterService(typeof(IConfigurationPersister), configPersister);

            // Arrange
            const string QualityProfileName = "SQQualityProfileName";
            const string ProjectName        = "SQProjectName";

            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();

            var notifications   = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(notifications);

            var bindingConfig = new Mock <IBindingConfig>().Object;

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureQualityProfile(language, QualityProfileName);

            var configProviderMock = new Mock <IBindingConfigProvider>();

            configProviderMock.Setup(x => x.GetConfigurationAsync(profile, language, It.IsAny <BindingConfiguration>(), CancellationToken.None))
            .ReturnsAsync(bindingConfig);

            var bindingArgs = new BindCommandArgs("key", ProjectName, new ConnectionInformation(new Uri("http://connected")));
            var testSubject = this.CreateTestSubject(bindingArgs, nuGetOpMock.Object, configProviderMock.Object);

            ConfigureSupportedBindingProject(testSubject.InternalState, language);

            // Act
            await testSubject.DownloadQualityProfileAsync(progressAdapter, CancellationToken.None);

            // Assert
            configPersister.SavedProject.Should().NotBeNull();
            configPersister.SavedMode.Should().Be(SonarLintMode.Connected);

            var savedProject = configPersister.SavedProject;

            savedProject.ServerUri.Should().Be(bindingArgs.Connection.ServerUri);
            savedProject.Profiles.Should().HaveCount(1);
            savedProject.Profiles[Language.VBNET].ProfileKey.Should().Be(profile.Key);
            savedProject.Profiles[Language.VBNET].ProfileTimestamp.Should().Be(profile.TimeStamp);
        }
            private bool IsUpdateRequired(BoundSonarQubeProject binding, IEnumerable <Language> projectLanguages,
                                          CancellationToken token)
            {
                Debug.Assert(binding != null);

                IDictionary <Language, SonarQubeQualityProfile> newProfiles = null;

                try
                {
                    newProfiles = TryGetLatestProfilesAsync(binding, projectLanguages, token).GetAwaiter().GetResult();
                }
                catch (Exception)
                {
                    this.host.Logger.WriteLine(Strings.SonarLintProfileCheckFailed);
                    return(false); // Error, can't proceed
                }

                if (!newProfiles.Keys.All(binding.Profiles.ContainsKey))
                {
                    this.host.Logger.WriteLine(Strings.SonarLintProfileCheckSolutionRequiresMoreProfiles);
                    return(true); // Missing profile, refresh
                }

                foreach (var keyValue in binding.Profiles)
                {
                    Language language = keyValue.Key;
                    ApplicableQualityProfile oldProfileInfo = keyValue.Value;

                    if (!newProfiles.ContainsKey(language))
                    {
                        // Not a relevant profile, we should just ignore it.
                        continue;
                    }

                    SonarQubeQualityProfile newProfileInfo = newProfiles[language];
                    if (this.HasProfileChanged(newProfileInfo, oldProfileInfo))
                    {
                        return(true);
                    }
                }

                this.host.Logger.WriteLine(Strings.SonarLintProfileCheckQualityProfileIsUpToDate);
                return(false); // Up-to-date
            }
        public async Task BindingWorkflow_DownloadQualityProfile_LegacyMode_WithNoNugetPackage_Fails()
        {
            // Arrange
            const string    QualityProfileName        = "SQQualityProfileName";
            const string    ProjectName               = "SQProjectName";
            var             legacyNuGetBinding        = new NuGetBindingOperation(this.host, this.host.Logger);
            BindingWorkflow testSubject               = this.CreateTestSubject("key", ProjectName, legacyNuGetBinding);
            ConfigurableProgressController controller = new ConfigurableProgressController();
            var notifications = new ConfigurableProgressStepExecutionEvents();

            RuleSet ruleSet         = TestRuleSetHelper.CreateTestRuleSetWithRuleIds(new[] { "Key1", "Key2" });
            var     expectedRuleSet = new RuleSet(ruleSet)
            {
                NonLocalizedDisplayName = string.Format(Strings.SonarQubeRuleSetNameFormat, ProjectName, QualityProfileName),
                NonLocalizedDescription = "\r\nhttp://connected/profiles/show?key="
            };
            var additionalFiles = new[] { new AdditionalFileResponse {
                                              FileName = "abc.xml", Content = new byte[] { 1, 2, 3 }
                                          } };
            RoslynExportProfileResponse export = RoslynExportProfileHelper.CreateExport(ruleSet, Enumerable.Empty <PackageName>(), additionalFiles);

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureProfileExport(export, language, QualityProfileName);

            // Act
            await testSubject.DownloadQualityProfileAsync(controller, notifications, new[] { language }, CancellationToken.None);

            // Assert
            testSubject.Rulesets.Should().NotContainKey(Language.VBNET, "Not expecting any rules for this language");
            testSubject.Rulesets.Should().NotContainKey(language, "Not expecting any rules");
            controller.NumberOfAbortRequests.Should().Be(1);

            notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage);

            this.outputWindowPane.AssertOutputStrings(1);
            var expectedOutput = string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.NoNuGetPackageForQualityProfile, language.Name));

            this.outputWindowPane.AssertOutputStrings(expectedOutput);
        }
        public async Task <SonarQubeQualityProfile> GetQualityProfileAsync(string projectKey, string organizationKey,
                                                                           SonarQubeLanguage language, CancellationToken token)
        {
            EnsureIsConnected();

            var qualityProfileRequest = new QualityProfileRequest {
                ProjectKey = projectKey, OrganizationKey = organizationKey
            };
            var qualityProfilesResult = await this.sonarqubeClient.GetQualityProfilesAsync(qualityProfileRequest, token);

            // Special handling for the case when a project was not analyzed yet, in which case a 404 is returned
            if (qualityProfilesResult.StatusCode == HttpStatusCode.NotFound)
            {
                qualityProfileRequest = new QualityProfileRequest {
                    ProjectKey = null, OrganizationKey = organizationKey
                };
                qualityProfilesResult = await this.sonarqubeClient.GetQualityProfilesAsync(qualityProfileRequest, token);
            }

            qualityProfilesResult.EnsureSuccess();

            var profilesWithGivenLanguage = qualityProfilesResult.Value.Where(x => x.Language == language.Key).ToList();

            var qualityProfile = profilesWithGivenLanguage.Count > 1
                ? profilesWithGivenLanguage.Single(x => x.IsDefault)
                : profilesWithGivenLanguage.Single();

            var qualityProfileChangeLogRequest = new QualityProfileChangeLogRequest
            {
                PageSize          = 1,
                QualityProfileKey = qualityProfile.Key
            };
            var changeLog = await this.sonarqubeClient.GetQualityProfileChangeLogAsync(qualityProfileChangeLogRequest, token);

            changeLog.EnsureSuccess();

            return(SonarQubeQualityProfile.FromResponse(qualityProfile, changeLog.Value.Events.Single().Date));
        }
        public async Task <IBindingConfigFile> GetConfigurationAsync(SonarQubeQualityProfile qualityProfile, string organizationKey,
                                                                     Language language, CancellationToken cancellationToken)
        {
            if (!IsLanguageSupported(language))
            {
                throw new ArgumentOutOfRangeException(nameof(language));
            }

            var result = await WebServiceHelper.SafeServiceCallAsync(
                () => sonarQubeService.GetAllRulesAsync(qualityProfile.Key, cancellationToken), logger);

            if (result == null)
            {
                return(null);
            }

            cancellationToken.ThrowIfCancellationRequested();

            var config     = CreateUserSettingsFromQPRules(result);
            var configFile = new CFamilyBindingConfigFile(config);

            return(configFile);
        }
        private async Task <IBindingConfig> DoGetConfigurationAsync(SonarQubeQualityProfile qualityProfile, Language language, BindingConfiguration bindingConfiguration, CancellationToken cancellationToken)
        {
            var serverLanguage = language.ServerLanguage;

            Debug.Assert(serverLanguage != null,
                         $"Server language should not be null for supported language: {language.Id}");

            // First, fetch the active rules
            var activeRules = await FetchSupportedRulesAsync(true, qualityProfile.Key, cancellationToken);

            // Give up if the quality profile is empty - no point in fetching anything else
            if (!activeRules.Any())
            {
                logger.WriteLine(string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.NoSonarAnalyzerActiveRulesForQualityProfile, qualityProfile.Name, language.Name)));
                return(null);
            }

            // Now fetch the data required for the NuGet configuration
            var sonarProperties = await FetchPropertiesAsync(bindingConfiguration.Project.ProjectKey, cancellationToken);

            // Get the NuGet package info and process it if appropriate (only in legacy connected mode, and only C#/VB)
            var nugetInfo = nuGetPackageInfoGenerator.GetNuGetPackageInfos(activeRules, sonarProperties);

            if (!nuGetBindingOperation.ProcessExport(language, nugetInfo))
            {
                return(null);
            }

            // Finally, fetch the remaining data needed to build the ruleset
            var inactiveRules = await FetchSupportedRulesAsync(false, qualityProfile.Key, cancellationToken);

            var ruleset        = GetRulesetFile(qualityProfile, language, bindingConfiguration, activeRules, inactiveRules, sonarProperties);
            var additionalFile = GetAdditionalFile(language, bindingConfiguration, activeRules, sonarProperties);

            return(new CSharpVBBindingConfig(ruleset, additionalFile));
        }
        public async Task <IBindingConfig> GetConfigurationAsync(SonarQubeQualityProfile qualityProfile, Language language, BindingConfiguration bindingConfiguration, CancellationToken cancellationToken)
        {
            if (!IsLanguageSupported(language))
            {
                throw new ArgumentOutOfRangeException(nameof(language));
            }

            var result = await WebServiceHelper.SafeServiceCallAsync(
                () => sonarQubeService.GetAllRulesAsync(qualityProfile.Key, cancellationToken), logger);

            if (result == null)
            {
                return(null);
            }

            cancellationToken.ThrowIfCancellationRequested();

            var settings         = CreateRulesSettingsFromQPRules(result);
            var settingsFilePath = bindingConfiguration.BuildPathUnderConfigDirectory(language.FileSuffixAndExtension);

            var configFile = new CFamilyBindingConfig(settings, settingsFilePath);

            return(configFile);
        }
示例#30
0
 public Task <IBindingConfigFile> GetConfigurationAsync(SonarQubeQualityProfile qualityProfile, string organizationKey, Language language, CancellationToken cancellationToken)
 {
     return(Task.FromResult <IBindingConfigFile>(ConfigToReturn));
 }