Skip to content

Commit e7f7225

Browse files
committed
benchmark recurseKustomizationFiles()
Add benchmark for recurseKustomizationFiles() to measure the performance of recursively loading kustomization files with certain percentage of symlinks in the kustomizations. Signed-off-by: Sunny <darkowlzz@protonmail.com>
1 parent 2f41b20 commit e7f7225

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

controllers/kustomization_decryptor_test.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"encoding/base64"
2323
"fmt"
2424
"io/fs"
25+
"math"
26+
"math/rand"
2527
"os"
2628
"os/exec"
2729
"path/filepath"
@@ -55,6 +57,11 @@ import (
5557
"github.com/fluxcd/pkg/apis/meta"
5658
)
5759

60+
const (
61+
percent10 = 10.0
62+
percent80 = 80.0
63+
)
64+
5865
func TestKustomizationReconciler_Decryptor(t *testing.T) {
5966
g := NewWithT(t)
6067

@@ -1573,6 +1580,92 @@ func Test_recurseKustomizationFiles(t *testing.T) {
15731580
}
15741581
}
15751582

1583+
// benchmarkRecKustFiles runs benchmark for recurseKustomizationFiles().
1584+
func benchmarkRecKustFiles(numKusNodes int, percentSymlinks float64, b *testing.B) {
1585+
b.StopTimer()
1586+
1587+
numSymlinksFloat := (percentSymlinks / 100.0) * float64(numKusNodes)
1588+
numSymlinks := int(math.Round(numSymlinksFloat))
1589+
1590+
g := NewWithT(b)
1591+
tmpDir := b.TempDir()
1592+
1593+
// Create manifest directories. Write all the symlinked manifests in bar.
1594+
// /tmp/test-dir/
1595+
// ├── bar
1596+
// │   └── 1
1597+
// │  └── kustomization.yaml
1598+
// │
1599+
// └── foo
1600+
// ├── 0
1601+
// │ └── kustomization.yaml
1602+
// └── 1 -> ../bar/1
1603+
os.MkdirAll(filepath.Join(tmpDir, "foo"), 0o700)
1604+
os.MkdirAll(filepath.Join(tmpDir, "bar"), 0o700)
1605+
1606+
// Generate index of kustomizations that'll be symlinked.
1607+
rand.Seed(42) // Reproducible.
1608+
randKusNodes := rand.Perm(numKusNodes)[0:numSymlinks]
1609+
symlinkKusNodes := map[int]struct{}{}
1610+
for _, n := range randKusNodes {
1611+
symlinkKusNodes[n] = struct{}{}
1612+
}
1613+
1614+
// Create kustomization nodes.
1615+
// The kustomizations are chained to one another. The first kustomization
1616+
// refers to the second, the second refers to the third, and so on.
1617+
for kn := 0; kn < numKusNodes; kn++ {
1618+
// /tmp/test-dir/foo/0
1619+
kPath := filepath.Join(tmpDir, "foo", fmt.Sprint(kn))
1620+
kus := kustypes.Kustomization{
1621+
TypeMeta: kustypes.TypeMeta{
1622+
APIVersion: kustypes.KustomizationVersion,
1623+
Kind: kustypes.KustomizationKind,
1624+
},
1625+
Resources: []string{},
1626+
}
1627+
// Append next node reference, except for when it is the last node.
1628+
if kn != numKusNodes-1 {
1629+
kus.Resources = append(kus.Resources, filepath.Join("..", fmt.Sprint(kn+1)))
1630+
}
1631+
b, err := yaml.Marshal(kus)
1632+
g.Expect(err).ToNot(HaveOccurred())
1633+
1634+
// If this node is a symlink, create a symlink and write to the
1635+
// respective source file. Else, write to the actual file.
1636+
if _, ok := symlinkKusNodes[kn]; ok {
1637+
srcPath := filepath.Join(tmpDir, "bar", fmt.Sprint(kn))
1638+
g.Expect(os.MkdirAll(srcPath, 0o700)).ToNot(HaveOccurred())
1639+
// Relative path from foo/0 to bar/0 is ../bar/0.
1640+
g.Expect(os.Symlink(filepath.Join("..", "bar", fmt.Sprint(kn)), kPath)).ToNot(HaveOccurred())
1641+
g.Expect(os.WriteFile(filepath.Join(srcPath, "kustomization.yaml"), b, 0o644)).ToNot(HaveOccurred())
1642+
} else {
1643+
g.Expect(os.MkdirAll(kPath, 0o700)).ToNot(HaveOccurred())
1644+
g.Expect(os.WriteFile(filepath.Join(kPath, "kustomization.yaml"), b, 0o644)).ToNot(HaveOccurred())
1645+
}
1646+
}
1647+
1648+
// no-op visit.
1649+
visit := func(root, path string, kus *kustypes.Kustomization) error {
1650+
return nil
1651+
}
1652+
1653+
b.StartTimer()
1654+
for n := 0; n < b.N; n++ {
1655+
visited := make(map[string]struct{})
1656+
recurseKustomizationFiles(tmpDir, filepath.Join(tmpDir, "foo", "0"), visit, visited)
1657+
}
1658+
}
1659+
1660+
func BenchmarkRecKust10Nodes10pcSymlink(b *testing.B) { benchmarkRecKustFiles(10, percent10, b) }
1661+
func BenchmarkRecKust10Nodes80pcSymlink(b *testing.B) { benchmarkRecKustFiles(10, percent80, b) }
1662+
func BenchmarkRecKust100Nodes10pcSymlink(b *testing.B) { benchmarkRecKustFiles(100, percent10, b) }
1663+
func BenchmarkRecKust100Nodes80pcSymlink(b *testing.B) { benchmarkRecKustFiles(100, percent80, b) }
1664+
func BenchmarkRecKust1000Nodes10pcSymlink(b *testing.B) { benchmarkRecKustFiles(1000, percent10, b) }
1665+
func BenchmarkRecKust1000Nodes80pcSymlink(b *testing.B) { benchmarkRecKustFiles(1000, percent80, b) }
1666+
func BenchmarkRecKust10000Nodes10pcSymlink(b *testing.B) { benchmarkRecKustFiles(10000, percent10, b) }
1667+
func BenchmarkRecKust10000Nodes80pcSymlink(b *testing.B) { benchmarkRecKustFiles(10000, percent80, b) }
1668+
15761669
func Test_isSOPSEncryptedResource(t *testing.T) {
15771670
g := NewWithT(t)
15781671

0 commit comments

Comments
 (0)