110 lines
3.1 KiB
Go
110 lines
3.1 KiB
Go
package validation
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// benchmarkExclusionIndex is an assessment-only alternative, not production logic.
|
|
func benchmarkExclusionIndex(exclusions []string) map[string]struct{} {
|
|
index := make(map[string]struct{}, len(exclusions))
|
|
for _, exclusion := range normalizedExclusions(exclusions) {
|
|
index[exclusion] = struct{}{}
|
|
}
|
|
return index
|
|
}
|
|
|
|
func benchmarkExcluded(filePath string, index map[string]struct{}) bool {
|
|
if _, ok := index["."]; ok {
|
|
return true
|
|
}
|
|
if _, ok := index[filePath]; ok {
|
|
return true
|
|
}
|
|
for pos := 0; pos < len(filePath); pos++ {
|
|
if filePath[pos] == '/' {
|
|
if _, ok := index[filePath[:pos]]; ok {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
var benchmarkExclusionMatches int
|
|
|
|
func BenchmarkFileSizeExclusions(b *testing.B) {
|
|
for _, pathCount := range []int{1000, 10000} {
|
|
for _, exclusionCount := range []int{1, 10, 100, 1000} {
|
|
for _, depth := range []string{"shallow", "deep"} {
|
|
for _, match := range []bool{true, false} {
|
|
exclusions := make([]string, exclusionCount)
|
|
for i := range exclusions {
|
|
exclusions[i] = fmt.Sprintf("excluded-%04d", i)
|
|
}
|
|
paths := make([]string, pathCount)
|
|
prefix := "other"
|
|
if match {
|
|
prefix = exclusions[0]
|
|
}
|
|
if depth == "deep" {
|
|
prefix += "/nested/one/two/three/four"
|
|
}
|
|
for i := range paths {
|
|
paths[i] = fmt.Sprintf("%s/file-%05d", prefix, i)
|
|
}
|
|
name := fmt.Sprintf("paths=%d/exclusions=%d/%s/match=%t", pathCount, exclusionCount, depth, match)
|
|
for _, indexed := range []bool{false, true} {
|
|
method := "scan"
|
|
if indexed {
|
|
method = "index"
|
|
}
|
|
b.Run(name+"/"+method, func(b *testing.B) {
|
|
normalized := normalizedExclusions(exclusions)
|
|
index := benchmarkExclusionIndex(exclusions)
|
|
for _, filePath := range paths {
|
|
if excludedByPath(filePath, normalized) != benchmarkExcluded(filePath, index) {
|
|
b.Fatalf("index disagrees for %q", filePath)
|
|
}
|
|
}
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
count := 0
|
|
if indexed {
|
|
index := benchmarkExclusionIndex(exclusions)
|
|
for _, filePath := range paths {
|
|
if benchmarkExcluded(filePath, index) {
|
|
count++
|
|
}
|
|
}
|
|
} else {
|
|
normalized := normalizedExclusions(exclusions)
|
|
for _, filePath := range paths {
|
|
if excludedByPath(filePath, normalized) {
|
|
count++
|
|
}
|
|
}
|
|
}
|
|
benchmarkExclusionMatches = count
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBenchmarkExclusionIndexPreservesLiteralMatching(t *testing.T) {
|
|
for _, exclusions := range [][]string{{"."}, {"/"}, {"a//b", "../x", "", "a/b"}, {"a", "a/b"}} {
|
|
index := benchmarkExclusionIndex(exclusions)
|
|
for _, filePath := range []string{"a", "a/b", "a/b/c", "ab/c", "/", "//file", "../x/file", "other"} {
|
|
if got, want := benchmarkExcluded(filePath, index), excludedByPath(filePath, normalizedExclusions(exclusions)); got != want {
|
|
t.Errorf("path %q exclusions %s: indexed %t, scan %t", filePath, strings.Join(exclusions, ","), got, want)
|
|
}
|
|
}
|
|
}
|
|
}
|