mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-08-19 20:46:42 +00:00
* chore * perfromance improvements Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * perfromance improvements Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat(performance): removed duplicate client calls from all admission paths Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat(performance): removed duplicate client calls from all admission paths Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat(performance): removed duplicate client calls from all admission paths Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat(performance): removed duplicate client calls from all admission paths Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat(performance): removed duplicate client calls from all admission paths Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat(performance): removed duplicate client calls from all admission paths Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat(performance): removed duplicate client calls from all admission paths Signed-off-by: Oliver Baehler <oliver@sudo-i.net> --------- Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
130 lines
2.9 KiB
Go
130 lines
2.9 KiB
Go
// Copyright 2020-2026 Project Capsule Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package utils
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"testing"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
|
)
|
|
|
|
func TestRequestCachingReaderDeduplicatesAndIsolatesGets(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
scheme := runtime.NewScheme()
|
|
if err := corev1.AddToScheme(scheme); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
base := fake.NewClientBuilder().
|
|
WithScheme(scheme).
|
|
WithObjects(&corev1.Namespace{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "solar",
|
|
Labels: map[string]string{"original": "true"},
|
|
},
|
|
}).
|
|
Build()
|
|
counting := &countingReader{Reader: base}
|
|
reader := NewRequestCachingReader(counting)
|
|
|
|
first := &corev1.Namespace{}
|
|
if err := reader.Get(context.Background(), client.ObjectKey{Name: "solar"}, first); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
first.Labels["mutated"] = "true"
|
|
|
|
second := &corev1.Namespace{}
|
|
if err := reader.Get(context.Background(), client.ObjectKey{Name: "solar"}, second); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if counting.gets != 1 {
|
|
t.Fatalf("underlying gets = %d, want 1", counting.gets)
|
|
}
|
|
|
|
if second.Labels["original"] != "true" || second.Labels["mutated"] != "" {
|
|
t.Fatalf("cached object was not isolated: %#v", second.Labels)
|
|
}
|
|
}
|
|
|
|
func TestRequestCachingReaderSeparatesObjectTypes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
scheme := runtime.NewScheme()
|
|
if err := corev1.AddToScheme(scheme); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
base := fake.NewClientBuilder().WithScheme(scheme).Build()
|
|
counting := &countingReader{Reader: base}
|
|
reader := NewRequestCachingReader(counting)
|
|
key := client.ObjectKey{Name: "missing"}
|
|
|
|
_ = reader.Get(context.Background(), key, &corev1.Namespace{})
|
|
_ = reader.Get(context.Background(), key, &corev1.ConfigMap{})
|
|
|
|
if counting.gets != 2 {
|
|
t.Fatalf("underlying gets = %d, want 2 for different object types", counting.gets)
|
|
}
|
|
}
|
|
|
|
func TestRequestCachingReaderDeduplicatesConcurrentGets(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
scheme := runtime.NewScheme()
|
|
if err := corev1.AddToScheme(scheme); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
base := fake.NewClientBuilder().
|
|
WithScheme(scheme).
|
|
WithObjects(&corev1.Namespace{
|
|
ObjectMeta: metav1.ObjectMeta{Name: "solar"},
|
|
}).
|
|
Build()
|
|
counting := &countingReader{Reader: base}
|
|
reader := NewRequestCachingReader(counting)
|
|
|
|
start := make(chan struct{})
|
|
errors := make(chan error, 2)
|
|
|
|
var wg sync.WaitGroup
|
|
for range 2 {
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
defer wg.Done()
|
|
<-start
|
|
|
|
errors <- reader.Get(
|
|
context.Background(),
|
|
client.ObjectKey{Name: "solar"},
|
|
&corev1.Namespace{},
|
|
)
|
|
}()
|
|
}
|
|
|
|
close(start)
|
|
wg.Wait()
|
|
close(errors)
|
|
|
|
for err := range errors {
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
if counting.gets != 1 {
|
|
t.Fatalf("underlying gets = %d, want 1", counting.gets)
|
|
}
|
|
}
|