Skip to content

Commit

Permalink
bundle/file_bench_test: Add basic tarball/directory loader benchmarks.
Browse files Browse the repository at this point in the history
Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
  • Loading branch information
philipaconrad committed Jun 18, 2024
1 parent bb22028 commit 99d6181
Showing 1 changed file with 134 additions and 0 deletions.
134 changes: 134 additions & 0 deletions bundle/file_bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package bundle

import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"testing"

"github.com/open-policy-agent/opa/internal/file/archive"
"github.com/open-policy-agent/opa/util"

"github.com/open-policy-agent/opa/util/test"
)

var benchTestArchiveFiles = map[string]string{
"/a.json": `"a"`,
"/a/b.json": `"b"`,
"/a/b/c.json": `"c"`,
"/a/b/d/data.json": `"hello"`,
"/a/c/data.yaml": "12",
"/some.txt": "text",
"/policy.rego": "package foo\n p = 1",
"/roles/policy.rego": "package bar\n p = 1",
"/deeper/dir/path/than/others/foo": "bar",
}

func BenchmarkTarballLoader(b *testing.B) {
files := map[string]string{
"/archive.tar.gz": "",
}
sizes := []int{1000, 10000, 100000, 250000}

for _, n := range sizes {
expectedFiles := make(map[string]string, len(benchTestArchiveFiles)+1)
for k, v := range benchTestArchiveFiles {
expectedFiles[k] = v
}
expectedFiles["/x/data.json"] = benchTestGetFlatDataJSON(n)

// We generate the tarball once in the tempfs, and then reuse it many
// times in the benchmark.
test.WithTempFS(files, func(rootDir string) {
tarballFile := filepath.Join(rootDir, "archive.tar.gz")
benchTestCreateTarballFile(b, rootDir, expectedFiles)

b.ResetTimer()

f, err := os.Open(tarballFile)
if err != nil {
b.Fatalf("Unexpected error: %s", err)
}
defer f.Close()

b.Run(fmt.Sprint(n), func(b *testing.B) {
// Reset the file reader.
if _, err := f.Seek(0, 0); err != nil {
b.Fatalf("Unexpected error: %s", err)
}
loader := NewTarballLoaderWithBaseURL(f, tarballFile)
benchTestLoader(b, loader)
})
})
}
}

func BenchmarkDirectoryLoader(b *testing.B) {
sizes := []int{10000, 100000, 250000, 500000}

for _, n := range sizes {
expectedFiles := make(map[string]string, len(benchTestArchiveFiles)+1)
for k, v := range benchTestArchiveFiles {
expectedFiles[k] = v
}
expectedFiles["/x/data.json"] = benchTestGetFlatDataJSON(n)

test.WithTempFS(expectedFiles, func(rootDir string) {
b.ResetTimer()

b.Run(fmt.Sprint(n), func(b *testing.B) {
loader := NewDirectoryLoader(rootDir)
benchTestLoader(b, loader)
})
})
}
}

// Creates a flat JSON object of configurable size.
func benchTestGetFlatDataJSON(numKeys int) string {
largeFile := make(map[string]string, numKeys)
for i := 0; i < numKeys; i++ {
largeFile[strconv.FormatInt(int64(i), 10)] = strings.Repeat("A", 1024)
}
return string(util.MustMarshalJSON(largeFile))
}

// Generates a tarball with a data.json of variable size.
func benchTestCreateTarballFile(b *testing.B, root string, filesToWrite map[string]string) {
b.Helper()

tarballFile := filepath.Join(root, "archive.tar.gz")
f, err := os.Create(tarballFile)
if err != nil {
b.Fatalf("Unexpected error: %s", err)
}

gzFiles := make([][2]string, 0, len(filesToWrite))
for name, content := range filesToWrite {
gzFiles = append(gzFiles, [2]string{name, content})
}

_, err = f.Write(archive.MustWriteTarGz(gzFiles).Bytes())
if err != nil {
b.Fatalf("Unexpected error: %s", err)
}
f.Close()
}

// We specifically invoke the loader through the bundle reader to mimic
// real-world usage.
func benchTestLoader(b *testing.B, loader DirectoryLoader) {
b.Helper()

br := NewCustomReader(loader).WithLazyLoadingMode(true)
bundle, err := br.Read()
if err != nil {
b.Fatal(err)
}

if len(bundle.Raw) == 0 {
b.Fatal("bundle.Raw is unexpectedly empty")
}
}

0 comments on commit 99d6181

Please sign in to comment.