Consolidate Distributor template parsing
This commit is contained in:
@@ -1725,43 +1725,59 @@ func TestDistributorBatchTemplateRendering(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDistributorBatchTemplateRejectsUnknownAndMalformedVariables(t *testing.T) {
|
||||
func TestDistributorTemplateRejectsUnknownVariables(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
template string
|
||||
render func(string) error
|
||||
}{
|
||||
{name: "Unknown", template: "{report_id}"},
|
||||
{name: "Unclosed", template: "{batch"},
|
||||
{name: "Unopened", template: "batch}"},
|
||||
{name: "Empty", template: "{}"},
|
||||
{
|
||||
name: "SingleReport",
|
||||
template: "{unknown}",
|
||||
render: func(template string) error {
|
||||
_, err := RenderDistributorBundleID(template, DistributorTemplateValues{})
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Batch",
|
||||
template: "{report_id}",
|
||||
render: func(template string) error {
|
||||
_, err := RenderDistributorBatchBundleID(template, DistributorBatchTemplateValues{})
|
||||
return err
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := RenderDistributorBatchBundleID(tt.template, DistributorBatchTemplateValues{})
|
||||
err := tt.render(tt.template)
|
||||
if err == nil {
|
||||
t.Fatal("RenderDistributorBatchBundleID() error = nil, want error")
|
||||
t.Fatal("rendering error = nil, want error")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDistributorTemplateRejectsUnknownAndMalformedVariables(t *testing.T) {
|
||||
func TestDistributorTemplateParserRejectsMalformedVariables(t *testing.T) {
|
||||
const name = "notify.distributor.bundle_id_template"
|
||||
tests := []struct {
|
||||
name string
|
||||
template string
|
||||
wantErr string
|
||||
}{
|
||||
{name: "Unknown", template: "{unknown}"},
|
||||
{name: "Unclosed", template: "{location_id"},
|
||||
{name: "Unopened", template: "location_id}"},
|
||||
{name: "Empty", template: "{}"},
|
||||
{name: "Unclosed", template: "{location_id", wantErr: name + " contains an unclosed template variable"},
|
||||
{name: "Unopened", template: "location_id}", wantErr: name + " contains an unopened template variable"},
|
||||
{name: "Empty", template: "{}", wantErr: name + " contains an empty template variable"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := RenderDistributorBundleID(tt.template, DistributorTemplateValues{})
|
||||
if err == nil {
|
||||
t.Fatal("RenderDistributorBundleID() error = nil, want error")
|
||||
_, err := renderDistributorTemplate(name, tt.template, func(variable string) (string, bool) {
|
||||
return "value", variable == "location_id"
|
||||
})
|
||||
if err == nil || err.Error() != tt.wantErr {
|
||||
t.Fatalf("error = %v, want %q", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ var distributorBatchIdempotencyTemplateVariables = map[string]struct{}{
|
||||
var distributorBatchPipelineTemplateVariables = distributorBatchTemplateVariables
|
||||
|
||||
func RenderDistributorBundleID(template string, values DistributorTemplateValues) (string, error) {
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.bundle_id_template", template, values, distributorTemplateVariables)
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.bundle_id_template", template, newDistributorTemplateResolver(values, distributorTemplateVariables))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -89,7 +89,7 @@ func RenderDistributorBundleID(template string, values DistributorTemplateValues
|
||||
}
|
||||
|
||||
func RenderDistributorPipelineID(template string, values DistributorTemplateValues) (string, error) {
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.pipeline_id_template", template, values, distributorPipelineTemplateVariables)
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.pipeline_id_template", template, newDistributorTemplateResolver(values, distributorPipelineTemplateVariables))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -100,7 +100,7 @@ func RenderDistributorPipelineID(template string, values DistributorTemplateValu
|
||||
}
|
||||
|
||||
func RenderDistributorIdempotencyKey(template string, values DistributorTemplateValues) (string, error) {
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.idempotency_key_template", template, values, distributorIdempotencyTemplateVariables)
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.idempotency_key_template", template, newDistributorTemplateResolver(values, distributorIdempotencyTemplateVariables))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -111,7 +111,7 @@ func RenderDistributorIdempotencyKey(template string, values DistributorTemplate
|
||||
}
|
||||
|
||||
func RenderDistributorBatchBundleID(template string, values DistributorBatchTemplateValues) (string, error) {
|
||||
rendered, err := renderDistributorBatchTemplate("notify.distributor.batch.bundle_id_template", template, values, distributorBatchTemplateVariables)
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.batch.bundle_id_template", template, newDistributorBatchTemplateResolver(values, distributorBatchTemplateVariables))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -122,7 +122,7 @@ func RenderDistributorBatchBundleID(template string, values DistributorBatchTemp
|
||||
}
|
||||
|
||||
func RenderDistributorBatchPipelineID(template string, values DistributorBatchTemplateValues) (string, error) {
|
||||
rendered, err := renderDistributorBatchTemplate("notify.distributor.batch.pipeline_id_template", template, values, distributorBatchPipelineTemplateVariables)
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.batch.pipeline_id_template", template, newDistributorBatchTemplateResolver(values, distributorBatchPipelineTemplateVariables))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -133,7 +133,7 @@ func RenderDistributorBatchPipelineID(template string, values DistributorBatchTe
|
||||
}
|
||||
|
||||
func RenderDistributorBatchIdempotencyKey(template string, values DistributorBatchTemplateValues) (string, error) {
|
||||
rendered, err := renderDistributorBatchTemplate("notify.distributor.batch.idempotency_key_template", template, values, distributorBatchIdempotencyTemplateVariables)
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.batch.idempotency_key_template", template, newDistributorBatchTemplateResolver(values, distributorBatchIdempotencyTemplateVariables))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -151,7 +151,7 @@ func RenderDistributorReportPaths(name string, templates []string, values Distri
|
||||
seen := make(map[string]struct{}, len(templates))
|
||||
for i, template := range templates {
|
||||
itemName := fmt.Sprintf("%s[%d]", name, i)
|
||||
rendered, err := renderDistributorTemplate(itemName, template, values, distributorTemplateVariables)
|
||||
rendered, err := renderDistributorTemplate(itemName, template, newDistributorTemplateResolver(values, distributorTemplateVariables))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -168,16 +168,18 @@ func RenderDistributorReportPaths(name string, templates []string, values Distri
|
||||
}
|
||||
|
||||
func validateDistributorTemplate(name, template string, allowed map[string]struct{}) error {
|
||||
_, err := renderDistributorTemplate(name, template, DistributorTemplateValues{}, allowed)
|
||||
_, err := renderDistributorTemplate(name, template, newDistributorTemplateResolver(DistributorTemplateValues{}, allowed))
|
||||
return err
|
||||
}
|
||||
|
||||
func validateDistributorBatchTemplate(name, template string, allowed map[string]struct{}) error {
|
||||
_, err := renderDistributorBatchTemplate(name, template, DistributorBatchTemplateValues{}, allowed)
|
||||
_, err := renderDistributorTemplate(name, template, newDistributorBatchTemplateResolver(DistributorBatchTemplateValues{}, allowed))
|
||||
return err
|
||||
}
|
||||
|
||||
func renderDistributorTemplate(name, template string, values DistributorTemplateValues, allowed map[string]struct{}) (string, error) {
|
||||
type distributorTemplateResolver func(string) (string, bool)
|
||||
|
||||
func renderDistributorTemplate(name, template string, resolve distributorTemplateResolver) (string, error) {
|
||||
var rendered strings.Builder
|
||||
for i := 0; i < len(template); {
|
||||
switch template[i] {
|
||||
@@ -190,10 +192,11 @@ func renderDistributorTemplate(name, template string, values DistributorTemplate
|
||||
if variable == "" {
|
||||
return "", fmt.Errorf("%s contains an empty template variable", name)
|
||||
}
|
||||
if _, ok := allowed[variable]; !ok {
|
||||
value, ok := resolve(variable)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%s contains unknown template variable %q", name, variable)
|
||||
}
|
||||
rendered.WriteString(distributorTemplateValue(variable, values))
|
||||
rendered.WriteString(value)
|
||||
i += end + 2
|
||||
case '}':
|
||||
return "", fmt.Errorf("%s contains an unopened template variable", name)
|
||||
@@ -205,32 +208,22 @@ func renderDistributorTemplate(name, template string, values DistributorTemplate
|
||||
return rendered.String(), nil
|
||||
}
|
||||
|
||||
func renderDistributorBatchTemplate(name, template string, values DistributorBatchTemplateValues, allowed map[string]struct{}) (string, error) {
|
||||
var rendered strings.Builder
|
||||
for i := 0; i < len(template); {
|
||||
switch template[i] {
|
||||
case '{':
|
||||
end := strings.IndexByte(template[i+1:], '}')
|
||||
if end < 0 {
|
||||
return "", fmt.Errorf("%s contains an unclosed template variable", name)
|
||||
}
|
||||
variable := template[i+1 : i+1+end]
|
||||
if variable == "" {
|
||||
return "", fmt.Errorf("%s contains an empty template variable", name)
|
||||
}
|
||||
if _, ok := allowed[variable]; !ok {
|
||||
return "", fmt.Errorf("%s contains unknown template variable %q", name, variable)
|
||||
}
|
||||
rendered.WriteString(distributorBatchTemplateValue(variable, values))
|
||||
i += end + 2
|
||||
case '}':
|
||||
return "", fmt.Errorf("%s contains an unopened template variable", name)
|
||||
default:
|
||||
rendered.WriteByte(template[i])
|
||||
i++
|
||||
func newDistributorTemplateResolver(values DistributorTemplateValues, allowed map[string]struct{}) distributorTemplateResolver {
|
||||
return func(variable string) (string, bool) {
|
||||
if _, ok := allowed[variable]; !ok {
|
||||
return "", false
|
||||
}
|
||||
return distributorTemplateValue(variable, values), true
|
||||
}
|
||||
}
|
||||
|
||||
func newDistributorBatchTemplateResolver(values DistributorBatchTemplateValues, allowed map[string]struct{}) distributorTemplateResolver {
|
||||
return func(variable string) (string, bool) {
|
||||
if _, ok := allowed[variable]; !ok {
|
||||
return "", false
|
||||
}
|
||||
return distributorBatchTemplateValue(variable, values), true
|
||||
}
|
||||
return rendered.String(), nil
|
||||
}
|
||||
|
||||
func distributorTemplateValue(variable string, values DistributorTemplateValues) string {
|
||||
|
||||
Reference in New Issue
Block a user