From 4d8fa3c8a50dcb2e23e0e5fa6663c80906f6b4a3 Mon Sep 17 00:00:00 2001 From: Teo Voinea Date: Mon, 3 Oct 2022 20:03:39 +0000 Subject: [PATCH 1/3] Add jinja template migration --- src/ApiService/ApiService/OneFuzzTypes/Enums.cs | 6 ++++++ .../notifications/JinjaTemplateAdapter.cs | 14 ++++++++++++++ .../onefuzzlib/notifications/NotificationsBase.cs | 1 + 3 files changed, 21 insertions(+) create mode 100644 src/ApiService/ApiService/onefuzzlib/notifications/JinjaTemplateAdapter.cs diff --git a/src/ApiService/ApiService/OneFuzzTypes/Enums.cs b/src/ApiService/ApiService/OneFuzzTypes/Enums.cs index 0d05ba0150..7019d3e9cb 100644 --- a/src/ApiService/ApiService/OneFuzzTypes/Enums.cs +++ b/src/ApiService/ApiService/OneFuzzTypes/Enums.cs @@ -331,8 +331,14 @@ private static readonly IReadOnlySet _readyForReset } +/// Select how nodes should be disposed of after they complete a WorkSet public enum NodeDisposalStrategy { + /// Re-images the node (which resets its state), then either it can pick up more work + /// or auto scale will reap it if no work is queued ScaleIn, + + /// Skips re-imaging the node, the node will no longer pick up new work. It will only be + /// scaled in by auto scale. Decommission } diff --git a/src/ApiService/ApiService/onefuzzlib/notifications/JinjaTemplateAdapter.cs b/src/ApiService/ApiService/onefuzzlib/notifications/JinjaTemplateAdapter.cs new file mode 100644 index 0000000000..48ef27a446 --- /dev/null +++ b/src/ApiService/ApiService/onefuzzlib/notifications/JinjaTemplateAdapter.cs @@ -0,0 +1,14 @@ +namespace Microsoft.OneFuzz.Service; + +public class JinjaTemplateAdapter { + public static bool IsJinjaTemplate(string jinjaTemplate) { + return jinjaTemplate.Contains("{% endfor %}") + || jinjaTemplate.Contains("{% endif %}"); + } + public static string AdaptForScriban(string jinjaTemplate) { + return jinjaTemplate.Replace("endfor", "end") + .Replace("endif", "end") + .Replace("{%", "{{") + .Replace("%}", "}}"); + } +} diff --git a/src/ApiService/ApiService/onefuzzlib/notifications/NotificationsBase.cs b/src/ApiService/ApiService/onefuzzlib/notifications/NotificationsBase.cs index 5454513229..696cd2b57b 100644 --- a/src/ApiService/ApiService/onefuzzlib/notifications/NotificationsBase.cs +++ b/src/ApiService/ApiService/onefuzzlib/notifications/NotificationsBase.cs @@ -97,6 +97,7 @@ public Renderer( // implementation doesn't have that so I'm trying to match it. // We should probably propagate any errors up public async Async.Task Render(string templateString, Uri instanceUrl) { + templateString = JinjaTemplateAdapter.IsJinjaTemplate(templateString) ? JinjaTemplateAdapter.AdaptForScriban(templateString) : templateString; var template = Template.Parse(templateString); if (template != null) { return await template.RenderAsync(new { From f66ba590f8407b9fb0b423e8b828ce72f80c44c9 Mon Sep 17 00:00:00 2001 From: Teo Voinea <58236992+tevoinea@users.noreply.github.com> Date: Tue, 4 Oct 2022 14:47:58 +0000 Subject: [PATCH 2/3] Support migrating our most common jinja templates to scriban on the fly --- src/ApiService/Tests/TemplateTests.cs | 37 ++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/ApiService/Tests/TemplateTests.cs b/src/ApiService/Tests/TemplateTests.cs index d3b07e7d2c..f0e9b6699f 100644 --- a/src/ApiService/Tests/TemplateTests.cs +++ b/src/ApiService/Tests/TemplateTests.cs @@ -15,6 +15,7 @@ public class TemplateTests { private static readonly string _defaultTemplate = "This input caused the fuzz target {{ report.executable }} to crash. The faulting input SHA256 hash is {{ report.input_sha256 }}
"; // Original python template: "This is the call stack as determined by heuristics. You may wish to confirm this stack trace with a debugger via repro:
    {% for item in report.call_stack %}
  • {{ item }}
  • {% endfor %}
" + private static readonly string _jinjaForLoop = "This is the call stack as determined by heuristics. You may wish to confirm this stack trace with a debugger via repro:
    {% for item in report.call_stack %}
  • {{ item }}
  • {% endfor %}
"; // Changes for dotnet: // * Change "endfor" in python to "end" // * Change "{% ... %}" in python to "{{ ... }}" @@ -24,12 +25,14 @@ public class TemplateTests { private static readonly string _testString2 = "The OneFuzz job {{ task.job_id }} found a crash in {{ report.executable }} with input {{ report.input_sha256 }}. ASan log:

{{ report.asan_log }}"; // Original python template: "The fuzzing target ({{ job.project }} {{ job.name }} {{ job.build }}) reported a crash.
{%if report.asan_log %} AddressSanitizer reported the following details:
 {{ report.asan_log }} 
{% else %} Faulting call stack:
    {% for item in report.call_stack %}
  • {{ item }}
  • {% endfor %}

{% endif %} You can reproduce the issue remotely in OneFuzz by running the following command:
 {{ repro_cmd }} 
" + private static readonly string _jinjaComplex = "The fuzzing target ({{ job.project }} {{ job.name }} {{ job.build }}) reported a crash.
{% if report.asan_log %} AddressSanitizer reported the following details:
 {{ report.asan_log }} 
{% else %} Faulting call stack:
    {% for item in report.call_stack %}
  • {{ item }}
  • {% endfor %}

{% endif %} You can reproduce the issue remotely in OneFuzz by running the following command:
 {{ repro_cmd }} 
"; // Changes for dotnet: // * Change "endfor" in python to "end" // * Change "endif" in python for "end" // * Change "{% ... %}" in python to "{{ ... }}" - // * Change job.project -> job.config.project (same for job.name, job.build). This is actually a bug, it shouldn't work in python either - private static readonly string _testString3 = "The fuzzing target ({{ job.config.project }} {{ job.config.name }} {{ job.config.build }}) reported a crash.
{{ if report.asan_log }} AddressSanitizer reported the following details:
 {{ report.asan_log }} 
{{ else }} Faulting call stack:
    {{ for item in report.call_stack }}
  • {{ item }}
  • {{ end }}

{{ end }} You can reproduce the issue remotely in OneFuzz by running the following command:
 {{ repro_cmd }} 
"; + private static readonly string _testString3 = "The fuzzing target ({{ job.project }} {{ job.name }} {{ job.build }}) reported a crash.
{{ if report.asan_log }} AddressSanitizer reported the following details:
 {{ report.asan_log }} 
{{ else }} Faulting call stack:
    {{ for item in report.call_stack }}
  • {{ item }}
  • {{ end }}

{{ end }} You can reproduce the issue remotely in OneFuzz by running the following command:
 {{ repro_cmd }} 
"; + + private static readonly string _jinjaIfStatement = "{% if report.asan_log %} AddressSanitizer reported the following details:
 {{ report.asan_log }} 
{% else %} Faulting call stack:
    {% endif %}"; [Fact] public void CanFormatDefaultTemplate() { @@ -104,7 +107,7 @@ public void CanFormatWithIfStatement() { var output = template.Render(new { ReproCmd = reproCmd, Report = report, - Job = job + Job = job.Config }); output.Should().Contain(job.Config.Project); @@ -130,6 +133,34 @@ public void TemplatesShouldDeserializeAppropriately() { g.Should().BeFalse(); } + [Fact] + public void CanConvertJinjaForLoop() { + _testString1.Should().BeEquivalentTo( + JinjaTemplateAdapter.AdaptForScriban(_jinjaForLoop) + ); + } + + [Fact] + public void CanConvertJinjaIfStatement() { + _testString3.Should().Contain( + JinjaTemplateAdapter.AdaptForScriban(_jinjaIfStatement) + ); + } + + [Fact] + public void CanConvertJinjaComplex() { + _testString3.Should().BeEquivalentTo( + JinjaTemplateAdapter.AdaptForScriban(_jinjaComplex) + ); + } + + [Fact] + public void CanDetectJinja() { + JinjaTemplateAdapter.IsJinjaTemplate(_jinjaIfStatement).Should().BeTrue(); + JinjaTemplateAdapter.IsJinjaTemplate(_jinjaComplex).Should().BeTrue(); + JinjaTemplateAdapter.IsJinjaTemplate(_jinjaForLoop).Should().BeTrue(); + } + private static Report GetReport() { return new Report( "https://example.com", From 06829b7f38ad1f548515119f454bd60f5d1ce17b Mon Sep 17 00:00:00 2001 From: Teo Voinea <58236992+tevoinea@users.noreply.github.com> Date: Tue, 4 Oct 2022 15:09:53 +0000 Subject: [PATCH 3/3] Fix tests --- src/ApiService/Tests/TemplateTests.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ApiService/Tests/TemplateTests.cs b/src/ApiService/Tests/TemplateTests.cs index f0e9b6699f..0eb43efe72 100644 --- a/src/ApiService/Tests/TemplateTests.cs +++ b/src/ApiService/Tests/TemplateTests.cs @@ -142,9 +142,10 @@ public void CanConvertJinjaForLoop() { [Fact] public void CanConvertJinjaIfStatement() { - _testString3.Should().Contain( - JinjaTemplateAdapter.AdaptForScriban(_jinjaIfStatement) - ); + var migrated = JinjaTemplateAdapter.AdaptForScriban(_jinjaIfStatement); + + migrated.Should().Contain("{{ if report.asan_log }}"); + migrated.Should().Contain("{{ end }}"); } [Fact]