111 lines
3.7 KiB
Go
111 lines
3.7 KiB
Go
package engine
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/ConfigKit/internal/document"
|
|
)
|
|
|
|
func BenchmarkInheritanceExpansion(b *testing.B) {
|
|
for _, shape := range []string{"chain", "wide", "nested", "replacement"} {
|
|
for _, size := range []int{16, 32, 64} {
|
|
b.Run(shape+"/"+strconv.Itoa(size), func(b *testing.B) {
|
|
input := inheritanceBenchmarkInput(shape, size)
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for range b.N {
|
|
if _, diagnostics := expandInheritanceWithOrigins(input, nil, defaultProjectionLimits()); len(diagnostics) != 0 {
|
|
b.Fatal(diagnostics)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkInheritanceInspectedLoad(b *testing.B) {
|
|
type entry struct {
|
|
Value string `yaml:"value"`
|
|
}
|
|
type configuration struct {
|
|
Entries map[string]entry `yaml:"entries"`
|
|
}
|
|
for _, size := range []int{16, 32, 64} {
|
|
b.Run(strconv.Itoa(size), func(b *testing.B) {
|
|
var input strings.Builder
|
|
input.WriteString("entries:\n item-0: {value: base}\n")
|
|
for index := 1; index <= size; index++ {
|
|
input.WriteString(" item-")
|
|
input.WriteString(strconv.Itoa(index))
|
|
input.WriteString(": {extends: item-0}\n")
|
|
}
|
|
source := Bytes("inheritance-benchmark", []byte(input.String()))
|
|
query := Keys("entries", "item-"+strconv.Itoa(size), "value")
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for range b.N {
|
|
loaded, err := Load[configuration](source, testSecretBinding())
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
if _, found := loaded.Inspection.Explain(query); !found {
|
|
b.Fatal("inherited value is not explainable")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Each scope has constant-sized output and evidence. This distinguishes budget
|
|
// accounting overhead from legitimate growth in expanded parent payloads.
|
|
func BenchmarkInheritanceIndependentScopes(b *testing.B) {
|
|
for _, size := range []int{256, 512, 1024} {
|
|
b.Run(strconv.Itoa(size), func(b *testing.B) {
|
|
input := &document.Node{Kind: document.Mapping}
|
|
for index := 0; index < size; index++ {
|
|
input.Mapping = append(input.Mapping, document.Entry{
|
|
Key: strconv.Itoa(index), Value: inheritanceBenchmarkInput("wide", 1),
|
|
})
|
|
}
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for range b.N {
|
|
if _, diagnostics := expandInheritanceTree(input, defaultProjectionLimits()); len(diagnostics) != 0 {
|
|
b.Fatal(diagnostics)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func inheritanceBenchmarkInput(shape string, size int) *document.Node {
|
|
value := func(text string) *document.Node { return &document.Node{Kind: document.String, Text: text} }
|
|
mapping := func(entries ...document.Entry) *document.Node {
|
|
return &document.Node{Kind: document.Mapping, Mapping: entries}
|
|
}
|
|
entry := func(key string, node *document.Node) document.Entry { return document.Entry{Key: key, Value: node} }
|
|
base := mapping(entry("value", value("base")), entry("settings", mapping(entry("enabled", &document.Node{Kind: document.Boolean, Text: "false"}))))
|
|
if shape == "nested" {
|
|
base = mapping(entry("settings", mapping(entry("first", mapping(entry("value", value("base")))), entry("second", mapping(entry("extends", value("first")))))))
|
|
}
|
|
definitions := make([]document.Entry, 0, size+1)
|
|
definitions = append(definitions, entry("item-0", base))
|
|
for index := 1; index <= size; index++ {
|
|
parent := "item-0"
|
|
if shape == "chain" {
|
|
parent = "item-" + strconv.Itoa(index-1)
|
|
}
|
|
payload := []document.Entry{entry("extends", value(parent))}
|
|
if shape == "nested" {
|
|
payload = append(payload, entry("settings", mapping(entry("first", mapping(entry("value", value("custom")))))))
|
|
}
|
|
if shape == "replacement" {
|
|
payload = append(payload, entry("value", value("replacement")))
|
|
}
|
|
definitions = append(definitions, entry("item-"+strconv.Itoa(index), mapping(payload...)))
|
|
}
|
|
return mapping(entry("entries", mapping(definitions...)))
|
|
}
|