Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SLVS-1597 Store SLCore issue id in AnalysisIssue #5823

Merged
9 changes: 7 additions & 2 deletions src/Core/Analysis/AnalysisIssue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class AnalysisIssue : IAnalysisIssue
private static readonly IReadOnlyList<IQuickFix> EmptyFixes = [];

public AnalysisIssue(
Guid id,
string ruleKey,
AnalysisIssueSeverity severity,
AnalysisIssueType type,
Expand All @@ -36,6 +37,7 @@ public AnalysisIssue(
string context = null
)
{
Id = id;
RuleKey = ruleKey;
Severity = severity;
HighestSoftwareQualitySeverity = highestSoftwareQualitySeverity;
Expand All @@ -46,6 +48,8 @@ public AnalysisIssue(
RuleDescriptionContextKey = context;
}

public Guid Id { get; }

public string RuleKey { get; }

public AnalysisIssueSeverity Severity { get; }
Expand All @@ -65,7 +69,8 @@ public AnalysisIssue(

public class AnalysisHotspotIssue : AnalysisIssue, IAnalysisHotspotIssue
{
public AnalysisHotspotIssue(string ruleKey,
public AnalysisHotspotIssue(Guid id,
string ruleKey,
AnalysisIssueSeverity severity,
AnalysisIssueType type,
SoftwareQualitySeverity? highestSoftwareQualitySeverity,
Expand All @@ -74,7 +79,7 @@ public AnalysisHotspotIssue(string ruleKey,
IReadOnlyList<IQuickFix> fixes = null,
string context = null,
HotspotPriority? hotspotPriority = null) :
base(ruleKey, severity, type, highestSoftwareQualitySeverity, primaryLocation, flows, fixes, context)
base(id, ruleKey, severity, type, highestSoftwareQualitySeverity, primaryLocation, flows, fixes, context)
{
HotspotPriority = hotspotPriority;
}
Expand Down
2 changes: 2 additions & 0 deletions src/Core/Analysis/IAnalysisIssue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ namespace SonarLint.VisualStudio.Core.Analysis
{
public interface IAnalysisIssue : IAnalysisIssueBase
{
Guid Id { get; }

AnalysisIssueSeverity Severity { get; }

SoftwareQualitySeverity? HighestSoftwareQualitySeverity { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,11 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Utilities;
using Moq;
using SonarLint.VisualStudio.CFamily.Rules;
using SonarLint.VisualStudio.CFamily.SubProcess;
using SonarLint.VisualStudio.Core;
using SonarLint.VisualStudio.Core.Analysis;
using SonarLint.VisualStudio.Core.Configuration;
using SonarLint.VisualStudio.Core.UserRuleSettings;
Expand Down Expand Up @@ -444,6 +437,7 @@ public void Convert_SeverityAndTypeLookup(string ruleKey, AnalysisIssueSeverity
var testSubject = CreateTestSubject();
var issue = Convert(testSubject, message);

issue.Id.Should().BeEmpty();
issue.RuleKey.Should().Be($"lang1:{ruleKey}");
issue.Severity.Should().Be(severity);
issue.Type.Should().Be(type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ private IAnalysisIssue ToAnalysisIssue(Message cFamilyIssue,
{
return new AnalysisIssue
(
id: Guid.Empty,
ruleKey: sqLanguage + ":" + cFamilyIssue.RuleKey,
severity: Convert(defaultSeverity),
type: Convert(defaultType),
Expand Down
125 changes: 69 additions & 56 deletions src/IssueViz.Security.UnitTests/Taint/Models/TaintIssueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,74 +18,87 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using System;
using System.Collections.Generic;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SonarLint.VisualStudio.Core.Analysis;
using SonarLint.VisualStudio.IssueVisualization.Security.Taint;
using SonarLint.VisualStudio.IssueVisualization.Security.Taint.Models;

namespace SonarLint.VisualStudio.IssueVisualization.Security.UnitTests.Taint.Models
namespace SonarLint.VisualStudio.IssueVisualization.Security.UnitTests.Taint.Models;

[TestClass]
public class TaintIssueTests
{
[TestClass]
public class TaintIssueTests
[TestMethod]
public void Ctor_NullLocation_ArgumentNullException()
{
[TestMethod]
public void Ctor_NullLocation_ArgumentNullException()
{
Action act = () => new TaintIssue("issue key", "rule key",
null,
AnalysisIssueSeverity.Major, SoftwareQualitySeverity.High, DateTimeOffset.MinValue, DateTimeOffset.MinValue, null, null);
Action act = () => new TaintIssue( Guid.Empty,"issue key", "rule key",
null,
AnalysisIssueSeverity.Major, SoftwareQualitySeverity.High, DateTimeOffset.MinValue, null, null);

act.Should().Throw<ArgumentNullException>().And.ParamName.Should().Be("primaryLocation");
}
act.Should().Throw<ArgumentNullException>().And.ParamName.Should().Be("primaryLocation");
}

[TestMethod]
public void Ctor_PropertiesSet()
{
var created = DateTimeOffset.Parse("2001-01-31T01:02:03+0200");
var lastUpdated = DateTimeOffset.UtcNow;
var issue = new TaintIssue("issue key", "rule key",
new AnalysisIssueLocation("message", "local-path.cpp", new TextRange(1, 2, 3, 4, "hash")),
AnalysisIssueSeverity.Major, SoftwareQualitySeverity.High, created, lastUpdated, null, "contextKey");
[TestMethod]
public void Ctor_PropertiesSet()
{
var created = DateTimeOffset.Parse("2001-01-31T01:02:03+0200");
var id = Guid.NewGuid();
var issue = new TaintIssue(id, "issue key", "rule key",
new AnalysisIssueLocation("message", "local-path.cpp", new TextRange(1, 2, 3, 4, "hash")),
AnalysisIssueSeverity.Major, SoftwareQualitySeverity.High, created, null, "contextKey");

issue.IssueKey.Should().Be("issue key");
issue.RuleKey.Should().Be("rule key");
issue.Severity.Should().Be(AnalysisIssueSeverity.Major);
issue.CreationTimestamp.Should().Be(created);
issue.LastUpdateTimestamp.Should().Be(lastUpdated);
issue.RuleDescriptionContextKey.Should().Be("contextKey");
issue.Id.Should().Be(id);
issue.IssueKey.Should().Be("issue key");
issue.RuleKey.Should().Be("rule key");
issue.Severity.Should().Be(AnalysisIssueSeverity.Major);
issue.CreationTimestamp.Should().Be(created);
issue.RuleDescriptionContextKey.Should().Be("contextKey");

issue.PrimaryLocation.FilePath.Should().Be("local-path.cpp");
issue.PrimaryLocation.Message.Should().Be("message");
issue.PrimaryLocation.TextRange.StartLine.Should().Be(1);
issue.PrimaryLocation.TextRange.EndLine.Should().Be(2);
issue.PrimaryLocation.TextRange.StartLineOffset.Should().Be(3);
issue.PrimaryLocation.TextRange.EndLineOffset.Should().Be(4);
issue.PrimaryLocation.TextRange.LineHash.Should().Be("hash");
}
issue.PrimaryLocation.FilePath.Should().Be("local-path.cpp");
issue.PrimaryLocation.Message.Should().Be("message");
issue.PrimaryLocation.TextRange.StartLine.Should().Be(1);
issue.PrimaryLocation.TextRange.EndLine.Should().Be(2);
issue.PrimaryLocation.TextRange.StartLineOffset.Should().Be(3);
issue.PrimaryLocation.TextRange.EndLineOffset.Should().Be(4);
issue.PrimaryLocation.TextRange.LineHash.Should().Be("hash");
}

[TestMethod]
public void Ctor_NoFlows_EmptyFlows()
{
IReadOnlyList<IAnalysisIssueFlow> flows = null;
var issue = new TaintIssue("issue key", "rule key",
new AnalysisIssueLocation("message", "local-path.cpp", new TextRange(1, 2, 3, 4, "hash")),
AnalysisIssueSeverity.Major, SoftwareQualitySeverity.High, DateTimeOffset.MinValue, DateTimeOffset.MaxValue, flows, null);
[TestMethod]
public void Ctor_NoFlows_EmptyFlows()
{
IReadOnlyList<IAnalysisIssueFlow> flows = null;
var issue = new TaintIssue(Guid.NewGuid(), "issue key", "rule key",
new AnalysisIssueLocation("message", "local-path.cpp", new TextRange(1, 2, 3, 4, "hash")),
AnalysisIssueSeverity.Major, SoftwareQualitySeverity.High, DateTimeOffset.MinValue, flows, null);

issue.Flows.Should().BeEmpty();
}
issue.Flows.Should().BeEmpty();
}

[TestMethod]
public void Ctor_HasFlows_CorrectFlows()
{
var flows = new[] { Mock.Of<IAnalysisIssueFlow>(), Mock.Of<IAnalysisIssueFlow>() };
var issue = new TaintIssue("issue key", "rule key",
new AnalysisIssueLocation("message", "local-path.cpp", new TextRange(1, 2, 3, 4, "hash")),
AnalysisIssueSeverity.Major, SoftwareQualitySeverity.High, DateTimeOffset.MinValue, DateTimeOffset.MaxValue, flows, null);
[TestMethod]
public void Ctor_HasFlows_CorrectFlows()
{
var flows = new[] { Substitute.For<IAnalysisIssueFlow>(), Substitute.For<IAnalysisIssueFlow>() };
var issue = new TaintIssue(Guid.NewGuid(), "issue key", "rule key",
new AnalysisIssueLocation("message", "local-path.cpp", new TextRange(1, 2, 3, 4, "hash")),
AnalysisIssueSeverity.Major, SoftwareQualitySeverity.High, DateTimeOffset.MinValue, flows, null);

issue.Flows.Should().BeEquivalentTo(flows);
}

[TestMethod]
public void Ctor_HasNoStandardAndNoCCTSeverity_Throws()
{
AnalysisIssueSeverity? analysisIssueSeverity = null;
SoftwareQualitySeverity? highestSoftwareQualitySeverity = null;
var act = () => new TaintIssue(Guid.NewGuid(),
"issue key",
"rule key",
new AnalysisIssueLocation("msg", "local-path.cpp", new TextRange(1, 2, 3, 4, "hash")),
analysisIssueSeverity,
highestSoftwareQualitySeverity,
DateTimeOffset.Now,
[],
null);

issue.Flows.Should().BeEquivalentTo(flows);
}
act.Should().Throw<ArgumentException>().WithMessage(string.Format(TaintResources.TaintIssue_SeverityUndefined, "issue key"));
}
}
Loading