Skip to content

Commit

Permalink
fix: escape the .net filter subsitution for shells (#57)
Browse files Browse the repository at this point in the history
Co-authored-by: Jonathan Dickinson <jdickinson@cmgx.io>
  • Loading branch information
michaelglass and jcdickinson committed Sep 1, 2023
1 parent 1577598 commit d009006
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
14 changes: 13 additions & 1 deletion internal/targetedretries/dot_net_xunit_substitution.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package targetedretries

import (
"fmt"
"regexp"
"strings"

"github.com/rwx-research/captain-cli/internal/errors"
Expand Down Expand Up @@ -39,6 +40,13 @@ func (s DotNetxUnitSubstitution) ValidateTemplate(compiledTemplate templating.Co
return nil
}

// https://github.com/microsoft/vstest/blob/main/docs/filter.md
var testFilterSpecialCharacters = regexp.MustCompile(`[()\\&|=!~]`)

func escapeTestFilterCharacter(value string) string {
return fmt.Sprintf(`\%v`, value)
}

func (s DotNetxUnitSubstitution) SubstitutionsFor(
_ templating.CompiledTemplate,
testResults v1.TestResults,
Expand All @@ -57,7 +65,11 @@ func (s DotNetxUnitSubstitution) SubstitutionsFor(

testType := test.Attempt.Meta["type"].(*string)
testMethod := test.Attempt.Meta["method"].(*string)
formattedTest := fmt.Sprintf("FullyQualifiedName=%v.%v", *testType, *testMethod)
fullyQualifiedName := testFilterSpecialCharacters.ReplaceAllStringFunc(
fmt.Sprintf("%v.%v", *testType, *testMethod),
escapeTestFilterCharacter,
)
formattedTest := templating.ShellEscape(fmt.Sprintf("FullyQualifiedName=%v", fullyQualifiedName))
if _, ok := testsSeen[formattedTest]; ok {
continue
}
Expand Down
42 changes: 42 additions & 0 deletions internal/targetedretries/dot_net_xunit_substitution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,5 +253,47 @@ var _ = Describe("DotNetxUnitSubstitution", func() {
},
))
})

It("correctly escapes the filter substitution", func() {
compiledTemplate, compileErr := templating.CompileTemplate("dotnet test --filter '{{ filter }}'")
Expect(compileErr).NotTo(HaveOccurred())

type1 := "type1"
method1 := `method1(val1: 100, val2: "test")`
type2 := "type2"
method2 := `!method2=|&\`
testResults := v1.TestResults{
Tests: []v1.Test{
{
Attempt: v1.TestAttempt{
Meta: map[string]any{"type": &type1, "method": &method1},
Status: v1.NewFailedTestStatus(nil, nil, nil),
},
},
{
Attempt: v1.TestAttempt{
Meta: map[string]any{"type": &type2, "method": &method2},
Status: v1.NewFailedTestStatus(nil, nil, nil),
},
},
},
}

substitution := targetedretries.DotNetxUnitSubstitution{}
substitutions, err := substitution.SubstitutionsFor(
compiledTemplate,
testResults,
func(test v1.Test) bool { return test.Attempt.Status.Kind == v1.TestStatusFailed },
)
Expect(err).NotTo(HaveOccurred())
Expect(substitutions).To(Equal(
[]map[string]string{
{
"filter": `FullyQualifiedName=type1.method1\(val1: 100, val2: "test"\) | ` +
`FullyQualifiedName=type2.\!method2\=\|\&\\`,
},
},
))
})
})
})

0 comments on commit d009006

Please sign in to comment.