Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Migrating notification templates #2486

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/ApiService/ApiService/OneFuzzTypes/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,14 @@ private static readonly IReadOnlySet<NodeState> _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
tevoinea marked this conversation as resolved.
Show resolved Hide resolved
/// 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
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Microsoft.OneFuzz.Service;

public class JinjaTemplateAdapter {
tevoinea marked this conversation as resolved.
Show resolved Hide resolved
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("%}", "}}");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> 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 {
Expand Down
38 changes: 35 additions & 3 deletions src/ApiService/Tests/TemplateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class TemplateTests {
private static readonly string _defaultTemplate = "<a href='{{ input_url }}'>This input</a> caused the <a href='{{ target_url }}'>fuzz target</a> {{ report.executable }} to crash. The faulting input SHA256 hash is {{ report.input_sha256 }} <br>";

// 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: <ul> {% for item in report.call_stack %} <li> {{ item }} </li> {% endfor %} </ul>"
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: <ul> {% for item in report.call_stack %} <li> {{ item }} </li> {% endfor %} </ul>";
// Changes for dotnet:
// * Change "endfor" in python to "end"
// * Change "{% ... %}" in python to "{{ ... }}"
Expand All @@ -24,12 +25,14 @@ public class TemplateTests {
private static readonly string _testString2 = "The OneFuzz job {{ task.job_id }} found a crash in <a href='{{ target_url }}'>{{ report.executable }}</a> with input <a href='{{ input_url }}'>{{ report.input_sha256 }}</a>. ASan log:<br><br>{{ report.asan_log }}";

// Original python template: "The fuzzing target ({{ job.project }} {{ job.name }} {{ job.build }}) reported a crash. <br> {%if report.asan_log %} AddressSanitizer reported the following details: <br> <pre> {{ report.asan_log }} </pre> {% else %} Faulting call stack: <ul> {% for item in report.call_stack %} <li> {{ item }} </li> {% endfor %} </ul> <br> {% endif %} You can reproduce the issue remotely in OneFuzz by running the following command: <pre> {{ repro_cmd }} </pre>"
private static readonly string _jinjaComplex = "The fuzzing target ({{ job.project }} {{ job.name }} {{ job.build }}) reported a crash. <br> {% if report.asan_log %} AddressSanitizer reported the following details: <br> <pre> {{ report.asan_log }} </pre> {% else %} Faulting call stack: <ul> {% for item in report.call_stack %} <li> {{ item }} </li> {% endfor %} </ul> <br> {% endif %} You can reproduce the issue remotely in OneFuzz by running the following command: <pre> {{ repro_cmd }} </pre>";
// 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. <br> {{ if report.asan_log }} AddressSanitizer reported the following details: <br> <pre> {{ report.asan_log }} </pre> {{ else }} Faulting call stack: <ul> {{ for item in report.call_stack }} <li> {{ item }} </li> {{ end }} </ul> <br> {{ end }} You can reproduce the issue remotely in OneFuzz by running the following command: <pre> {{ repro_cmd }} </pre>";
private static readonly string _testString3 = "The fuzzing target ({{ job.project }} {{ job.name }} {{ job.build }}) reported a crash. <br> {{ if report.asan_log }} AddressSanitizer reported the following details: <br> <pre> {{ report.asan_log }} </pre> {{ else }} Faulting call stack: <ul> {{ for item in report.call_stack }} <li> {{ item }} </li> {{ end }} </ul> <br> {{ end }} You can reproduce the issue remotely in OneFuzz by running the following command: <pre> {{ repro_cmd }} </pre>";

private static readonly string _jinjaIfStatement = "{% if report.asan_log %} AddressSanitizer reported the following details: <br> <pre> {{ report.asan_log }} </pre> {% else %} Faulting call stack: <ul> {% endif %}";

[Fact]
public void CanFormatDefaultTemplate() {
Expand Down Expand Up @@ -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);
Expand All @@ -130,6 +133,35 @@ public void TemplatesShouldDeserializeAppropriately() {
g.Should().BeFalse();
}

[Fact]
public void CanConvertJinjaForLoop() {
_testString1.Should().BeEquivalentTo(
JinjaTemplateAdapter.AdaptForScriban(_jinjaForLoop)
);
}

[Fact]
public void CanConvertJinjaIfStatement() {
var migrated = JinjaTemplateAdapter.AdaptForScriban(_jinjaIfStatement);

migrated.Should().Contain("{{ if report.asan_log }}");
migrated.Should().Contain("{{ end }}");
}

[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",
Expand Down