Skip to content

Commit

Permalink
Merge branch 'feature/hardening-202311' into ue/fix-regex
Browse files Browse the repository at this point in the history
  • Loading branch information
ugras-ergun-sonarsource committed Nov 3, 2023
2 parents 14be8f9 + 8613ded commit 562e1e7
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 68 deletions.
132 changes: 132 additions & 0 deletions src/Education.UnitTests/XamlGenerator/RuleXamlBuilderSmokeTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* SonarLint for Visual Studio
* Copyright (C) 2016-2023 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Documents;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SonarLint.VisualStudio.Education.Layout.Logical;
using SonarLint.VisualStudio.Education.XamlGenerator;
using SonarLint.VisualStudio.Rules;
using SonarLint.VisualStudio.TestInfrastructure;

namespace SonarLint.VisualStudio.Education.UnitTests.XamlGenerator;

[TestClass]
public class RuleXamlBuilderSmokeTest
{
private static readonly Assembly ResourceAssembly = typeof(LocalRuleMetadataProvider).Assembly;

[TestMethod]
public void Create_CheckAllEmbedded()
{
// Performance: this test is loading nearly 2000 files and creating
// XAML document for them, but it still only takes a around 3 seconds
// to run.
var resourceNames = ResourceAssembly.GetManifestResourceNames()
.Where(x => x.EndsWith(".json"));

// Sanity check - should have checked at least 1500 rules
resourceNames.Count().Should().BeGreaterThan(1500);

Console.WriteLine("Checking xaml creation. Count = " + resourceNames.Count());

string[] failures;
using(new AssertIgnoreScope()) // the product code can assert if it encounters an unrecognised tag
{
failures = resourceNames.Where(x => !ProcessResource(x))
.ToArray();
}

failures.Should().BeEquivalentTo(new[]
{
// introduced in sonar-cpp 6.48
"SonarLint.VisualStudio.Rules.Embedded.cpp.S1232.json",
// introduced in dotnet analyzer 9.5
"SonarLint.VisualStudio.Rules.Embedded.csharpsquid.S4433.json",
// possible issues with EnsureHtmlIsXml regexp in rich rule description, need to investigate (same issue for all 5332 rules)
"SonarLint.VisualStudio.Rules.Embedded.cpp.S5332.json",
"SonarLint.VisualStudio.Rules.Embedded.c.S5332.json",
"SonarLint.VisualStudio.Rules.Embedded.csharpsquid.S5332.json",
"SonarLint.VisualStudio.Rules.Embedded.javascript.S5332.json",
"SonarLint.VisualStudio.Rules.Embedded.typescript.S5332.json",
// some issue with diff highlighting
"SonarLint.VisualStudio.Rules.Embedded.csharpsquid.S6640.json",
});
}

private static bool ProcessResource(string fullResourceName)
{
var xamlWriterFactory = new XamlWriterFactory();
var ruleHelpXamlTranslatorFactory = new RuleHelpXamlTranslatorFactory(xamlWriterFactory, new DiffTranslator(xamlWriterFactory));
var xamlGeneratorHelperFactory = new XamlGeneratorHelperFactory(ruleHelpXamlTranslatorFactory);
var ruleInfoTranslator = new RuleInfoTranslator(ruleHelpXamlTranslatorFactory, new TestLogger());
var staticXamlStorage = new StaticXamlStorage(ruleHelpXamlTranslatorFactory);

var simpleXamlBuilder = new SimpleRuleHelpXamlBuilder(ruleHelpXamlTranslatorFactory, xamlGeneratorHelperFactory, xamlWriterFactory);
var richXamlBuilder = new RichRuleHelpXamlBuilder(ruleInfoTranslator, xamlGeneratorHelperFactory, staticXamlStorage, xamlWriterFactory);

try
{
bool res = false;

var data = ReadResource(fullResourceName);
var jsonRuleInfo = LocalRuleMetadataProvider.RuleInfoJsonDeserializer.Deserialize(data);

if (!string.IsNullOrWhiteSpace(jsonRuleInfo.Description))
{
Res(simpleXamlBuilder.Create(jsonRuleInfo));
res = true;
}

if (jsonRuleInfo.DescriptionSections.Any())
{
Res(richXamlBuilder.Create(jsonRuleInfo, null));
res = true;
}

return res; // simple || rich should be true
}
catch (Exception ex)
{
Console.WriteLine("Failed: " + fullResourceName);
Console.WriteLine(" " + ex.Message);
return false;
}
}

private static void Res(FlowDocument doc)
{
// Quick sanity check that something was produced
// Note: this is a quick way of getting the size of the document. Serializing the doc to a string
// and checking the length takes much longer (around 25 seconds)
var docLength = doc.ContentStart.DocumentStart.GetOffsetToPosition(doc.ContentEnd.DocumentEnd);
docLength.Should().BeGreaterThan(30);
}

private static string ReadResource(string fullResourceName)
{
using var stream = new StreamReader(ResourceAssembly.GetManifestResourceStream(fullResourceName));
return stream.ReadToEnd();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
Expand Down Expand Up @@ -102,71 +100,5 @@ public void Create_FormsCorrectStructure()

flowDocument.Blocks.Single().Should().BeOfType<Paragraph>().Which.Inlines.Single().Should().BeOfType<Run>().Which.Text.Should().Be("Hi");
}

[TestMethod]
public void Create_CheckAllEmbedded()
{
// Performance: this test is loading nearly 2000 files and creating
// XAML document for them, but it still only takes a around 3 seconds
// to run.
var resourceNames = ResourceAssembly.GetManifestResourceNames()
.Where(x => x.EndsWith(".json"));

// Sanity check - should have checked at least 1500 rules
resourceNames.Count().Should().BeGreaterThan(1500);

Console.WriteLine("Checking xaml creation. Count = " + resourceNames.Count());

string[] failures;
using(new AssertIgnoreScope()) // the product code can assert if it encounters an unrecognised tag
{
failures = resourceNames.Where(x => !ProcessResource(x))
.ToArray();
}

// see https://github.com/SonarSource/sonarlint-visualstudio/issues/4471
failures.Should().BeEquivalentTo(new[]
{
// introduced in sonar-cpp 6.48
"SonarLint.VisualStudio.Rules.Embedded.cpp.S1232.json",
// introduced in dotnet analyzer 9.5
"SonarLint.VisualStudio.Rules.Embedded.csharpsquid.S4433.json",
});
}

private static bool ProcessResource(string fullResourceName)
{
var testSubject = new SimpleRuleHelpXamlBuilder(new RuleHelpXamlTranslatorFactory(new XamlWriterFactory(), new DiffTranslator(new XamlWriterFactory())), new XamlGeneratorHelperFactory(new RuleHelpXamlTranslatorFactory(new XamlWriterFactory(), new DiffTranslator(new XamlWriterFactory()))), new XamlWriterFactory());

try
{
var data = ReadResource(fullResourceName);
var jsonRuleInfo = LocalRuleMetadataProvider.RuleInfoJsonDeserializer.Deserialize(data);

if (!string.IsNullOrWhiteSpace(jsonRuleInfo.Description))
{
var doc = testSubject.Create(jsonRuleInfo);

// Quick sanity check that something was produced
// Note: this is a quick way of getting the size of the document. Serializing the doc to a string
// and checking the length takes much longer (around 25 seconds)
var docLength = doc.ContentStart.DocumentStart.GetOffsetToPosition(doc.ContentEnd.DocumentEnd);
docLength.Should().BeGreaterThan(30);
}
return true;
}
catch (Exception ex)
{
Console.WriteLine("Failed: " + fullResourceName);
Console.WriteLine(" " + ex.Message);
return false;
}
}

private static string ReadResource(string fullResourceName)
{
using var stream = new StreamReader(ResourceAssembly.GetManifestResourceStream(fullResourceName));
return stream.ReadToEnd();
}
}
}

0 comments on commit 562e1e7

Please sign in to comment.