Skip to content

Commit d4505e7

Browse files
Merge pull request #943 from njhale/catalog-benchmarks
Add simple benchmark for namespaced subscription resolution
2 parents 4ed2a7e + f41dccb commit d4505e7

File tree

4 files changed

+186
-26
lines changed

4 files changed

+186
-26
lines changed

pkg/controller/operators/catalog/operator_test.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
appsv1 "k8s.io/api/apps/v1"
1616
corev1 "k8s.io/api/core/v1"
1717
rbacv1 "k8s.io/api/rbac/v1"
18-
"k8s.io/client-go/rest"
1918
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
2019
apiextensionsfake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
2120
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -24,6 +23,7 @@ import (
2423
utilclock "k8s.io/apimachinery/pkg/util/clock"
2524
"k8s.io/client-go/informers"
2625
k8sfake "k8s.io/client-go/kubernetes/fake"
26+
"k8s.io/client-go/rest"
2727
"k8s.io/client-go/tools/cache"
2828
"k8s.io/client-go/util/workqueue"
2929
apiregistrationfake "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake"
@@ -569,11 +569,25 @@ type fakeOperatorConfig struct {
569569
regObjs []runtime.Object
570570
clientOptions []clientfake.Option
571571
logger *logrus.Logger
572+
resolver resolver.Resolver
573+
reconciler reconciler.RegistryReconcilerFactory
572574
}
573575

574576
// fakeOperatorOption applies an option to the given fake operator configuration.
575577
type fakeOperatorOption func(*fakeOperatorConfig)
576578

579+
func withResolver(res resolver.Resolver) fakeOperatorOption {
580+
return func(config *fakeOperatorConfig) {
581+
config.resolver = res
582+
}
583+
}
584+
585+
func withReconciler(rec reconciler.RegistryReconcilerFactory) fakeOperatorOption {
586+
return func(config *fakeOperatorConfig) {
587+
config.reconciler = rec
588+
}
589+
}
590+
577591
func withClock(clock utilclock.Clock) fakeOperatorOption {
578592
return func(config *fakeOperatorConfig) {
579593
config.clock = clock
@@ -608,8 +622,9 @@ func withFakeClientOptions(options ...clientfake.Option) fakeOperatorOption {
608622
func NewFakeOperator(ctx context.Context, namespace string, watchedNamespaces []string, fakeOptions ...fakeOperatorOption) (*Operator, error) {
609623
// Apply options to default config
610624
config := &fakeOperatorConfig{
611-
logger: logrus.New(),
612-
clock: utilclock.RealClock{},
625+
logger: logrus.New(),
626+
clock: utilclock.RealClock{},
627+
resolver: &fakes.FakeResolver{},
613628
}
614629
for _, option := range fakeOptions {
615630
option(config)
@@ -689,12 +704,15 @@ func NewFakeOperator(ctx context.Context, namespace string, watchedNamespaces []
689704
// 1 qps, 100 bucket size. This is only for retry speed and its only the overall factor (not per item)
690705
&workqueue.BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(1), 100)},
691706
), "resolver"),
692-
sources: make(map[resolver.CatalogKey]resolver.SourceRef),
693-
resolver: &fakes.FakeResolver{},
694-
clientAttenuator: scoped.NewClientAttenuator(logger, &rest.Config{}, opClientFake, clientFake),
695-
serviceAccountQuerier: scoped.NewUserDefinedServiceAccountQuerier(logger, clientFake),
707+
sources: make(map[resolver.CatalogKey]resolver.SourceRef),
708+
resolver: config.resolver,
709+
reconciler: config.reconciler,
710+
clientAttenuator: scoped.NewClientAttenuator(logger, &rest.Config{}, opClientFake, clientFake),
711+
serviceAccountQuerier: scoped.NewUserDefinedServiceAccountQuerier(logger, clientFake),
712+
}
713+
if op.reconciler == nil {
714+
op.reconciler = reconciler.NewRegistryReconcilerFactory(lister, op.opClient, "test:pod", op.now)
696715
}
697-
op.reconciler = reconciler.NewRegistryReconcilerFactory(lister, op.opClient, "test:pod", op.now)
698716

699717
op.RunInformers(ctx)
700718

pkg/controller/operators/catalog/subscriptions_test.go

Lines changed: 148 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"time"
88

99
"github.com/stretchr/testify/require"
10-
v1 "k8s.io/api/core/v1"
10+
corev1 "k8s.io/api/core/v1"
1111
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1212
"k8s.io/apimachinery/pkg/runtime"
1313
utilclock "k8s.io/apimachinery/pkg/util/clock"
@@ -139,7 +139,7 @@ func TestSyncSubscriptions(t *testing.T) {
139139
Kind: v1alpha1.InstallPlanKind,
140140
APIVersion: v1alpha1.InstallPlanAPIVersion,
141141
},
142-
InstallPlanRef: &v1.ObjectReference{
142+
InstallPlanRef: &corev1.ObjectReference{
143143
Namespace: testNamespace,
144144
Kind: v1alpha1.InstallPlanKind,
145145
APIVersion: v1alpha1.InstallPlanAPIVersion,
@@ -270,7 +270,7 @@ func TestSyncSubscriptions(t *testing.T) {
270270
Kind: v1alpha1.InstallPlanKind,
271271
APIVersion: v1alpha1.InstallPlanAPIVersion,
272272
},
273-
InstallPlanRef: &v1.ObjectReference{
273+
InstallPlanRef: &corev1.ObjectReference{
274274
Namespace: testNamespace,
275275
Kind: v1alpha1.InstallPlanKind,
276276
APIVersion: v1alpha1.InstallPlanAPIVersion,
@@ -410,7 +410,7 @@ func TestSyncSubscriptions(t *testing.T) {
410410
Kind: v1alpha1.InstallPlanKind,
411411
APIVersion: v1alpha1.InstallPlanAPIVersion,
412412
},
413-
InstallPlanRef: &v1.ObjectReference{
413+
InstallPlanRef: &corev1.ObjectReference{
414414
Namespace: testNamespace,
415415
Kind: v1alpha1.InstallPlanKind,
416416
APIVersion: v1alpha1.InstallPlanAPIVersion,
@@ -574,7 +574,7 @@ func TestSyncSubscriptions(t *testing.T) {
574574
Kind: v1alpha1.InstallPlanKind,
575575
APIVersion: v1alpha1.InstallPlanAPIVersion,
576576
},
577-
InstallPlanRef: &v1.ObjectReference{
577+
InstallPlanRef: &corev1.ObjectReference{
578578
Namespace: testNamespace,
579579
Kind: v1alpha1.InstallPlanKind,
580580
APIVersion: v1alpha1.InstallPlanAPIVersion,
@@ -665,7 +665,7 @@ func TestSyncSubscriptions(t *testing.T) {
665665
},
666666
}
667667

668-
namespace := &v1.Namespace{
668+
namespace := &corev1.Namespace{
669669
ObjectMeta: metav1.ObjectMeta{
670670
Name: testNamespace,
671671
},
@@ -692,3 +692,145 @@ func TestSyncSubscriptions(t *testing.T) {
692692
})
693693
}
694694
}
695+
696+
type operatorBuilder interface {
697+
operator(ctx context.Context) (*Operator, error)
698+
}
699+
700+
type objs struct {
701+
clientObjs []runtime.Object
702+
k8sObjs []runtime.Object
703+
}
704+
705+
type srnFields struct {
706+
clientOptions []clientfake.Option
707+
existingObjs objs
708+
resolver resolver.Resolver
709+
reconciler reconciler.RegistryReconcilerFactory
710+
}
711+
712+
type srnArgs struct {
713+
namespace string
714+
}
715+
716+
type srnTest struct {
717+
fields srnFields
718+
args srnArgs
719+
}
720+
721+
func (t srnTest) operator(ctx context.Context) (*Operator, error) {
722+
return NewFakeOperator(
723+
ctx,
724+
t.args.namespace,
725+
[]string{t.args.namespace},
726+
withClientObjs(t.fields.existingObjs.clientObjs...),
727+
withK8sObjs(t.fields.existingObjs.k8sObjs...),
728+
withFakeClientOptions(t.fields.clientOptions...),
729+
withResolver(t.fields.resolver),
730+
)
731+
}
732+
733+
func benchOperator(ctx context.Context, test operatorBuilder, b *testing.B) (*Operator, error) {
734+
b.StartTimer()
735+
defer b.StopTimer()
736+
737+
return test.operator(ctx)
738+
}
739+
740+
func benchmarkSyncResolvingNamespace(test srnTest, b *testing.B) {
741+
b.ResetTimer()
742+
for n := 0; n < b.N; n++ {
743+
ctx, cancel := context.WithCancel(context.TODO())
744+
defer cancel()
745+
746+
o, err := benchOperator(ctx, test, b)
747+
require.NoError(b, err)
748+
749+
namespace := &corev1.Namespace{
750+
ObjectMeta: metav1.ObjectMeta{
751+
Name: test.args.namespace,
752+
},
753+
}
754+
require.NoError(b, o.syncResolvingNamespace(namespace))
755+
}
756+
}
757+
758+
func BenchmarkSyncResolvingNamespace(b *testing.B) {
759+
ns := "default"
760+
name := "sub"
761+
benchmarkSyncResolvingNamespace(srnTest{
762+
fields: srnFields{
763+
clientOptions: []clientfake.Option{clientfake.WithSelfLinks(b)},
764+
existingObjs: objs{
765+
clientObjs: []runtime.Object{
766+
&v1alpha1.Subscription{
767+
ObjectMeta: metav1.ObjectMeta{
768+
Name: name,
769+
Namespace: ns,
770+
},
771+
Spec: &v1alpha1.SubscriptionSpec{
772+
CatalogSource: "src",
773+
CatalogSourceNamespace: ns,
774+
},
775+
Status: v1alpha1.SubscriptionStatus{
776+
CurrentCSV: "",
777+
State: "",
778+
},
779+
},
780+
},
781+
},
782+
reconciler: &fakes.FakeRegistryReconcilerFactory{
783+
ReconcilerForSourceStub: func(*v1alpha1.CatalogSource) reconciler.RegistryReconciler {
784+
return &fakes.FakeRegistryReconciler{
785+
CheckRegistryServerStub: func(*v1alpha1.CatalogSource) (bool, error) {
786+
return true, nil
787+
},
788+
}
789+
},
790+
},
791+
resolver: &fakes.FakeResolver{
792+
ResolveStepsStub: func(string, resolver.SourceQuerier) ([]*v1alpha1.Step, []*v1alpha1.Subscription, error) {
793+
steps := []*v1alpha1.Step{
794+
{
795+
Resolving: "csv.v.2",
796+
Resource: v1alpha1.StepResource{
797+
CatalogSource: "src",
798+
CatalogSourceNamespace: ns,
799+
Group: v1alpha1.GroupName,
800+
Version: v1alpha1.GroupVersion,
801+
Kind: v1alpha1.ClusterServiceVersionKind,
802+
Name: "csv.v.2",
803+
Manifest: "{}",
804+
},
805+
},
806+
}
807+
subs := []*v1alpha1.Subscription{
808+
{
809+
TypeMeta: metav1.TypeMeta{
810+
Kind: v1alpha1.SubscriptionKind,
811+
APIVersion: v1alpha1.SubscriptionCRDAPIVersion,
812+
},
813+
ObjectMeta: metav1.ObjectMeta{
814+
Name: name,
815+
Namespace: ns,
816+
},
817+
Spec: &v1alpha1.SubscriptionSpec{
818+
CatalogSource: "src",
819+
CatalogSourceNamespace: ns,
820+
},
821+
Status: v1alpha1.SubscriptionStatus{
822+
CurrentCSV: "csv.v.2",
823+
State: "SubscriptionStateAtLatest",
824+
},
825+
},
826+
}
827+
828+
return steps, subs, nil
829+
},
830+
},
831+
},
832+
args: srnArgs{
833+
namespace: ns,
834+
},
835+
}, b)
836+
}

pkg/controller/operators/olm/operator_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ import (
3636
"k8s.io/apimachinery/pkg/util/intstr"
3737
"k8s.io/apimachinery/pkg/util/wait"
3838
k8sfake "k8s.io/client-go/kubernetes/fake"
39+
k8sscheme "k8s.io/client-go/kubernetes/scheme"
3940
"k8s.io/client-go/pkg/version"
41+
"k8s.io/client-go/rest"
4042
"k8s.io/client-go/tools/cache"
4143
"k8s.io/client-go/tools/record"
42-
k8sscheme "k8s.io/client-go/kubernetes/scheme"
43-
"k8s.io/client-go/rest"
4444
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
4545
apiregistrationfake "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake"
4646

@@ -54,13 +54,13 @@ import (
5454
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver"
5555
"github.com/operator-framework/operator-lifecycle-manager/pkg/fakes"
5656
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/clientfake"
57+
csvutility "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/csv"
5758
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/labeler"
5859
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
5960
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
6061
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
61-
"github.com/operator-framework/operator-registry/pkg/registry"
6262
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/scoped"
63-
csvutility "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/csv"
63+
"github.com/operator-framework/operator-registry/pkg/registry"
6464
)
6565

6666
type TestStrategy struct{}
@@ -261,7 +261,7 @@ func NewFakeOperator(ctx context.Context, options ...fakeOperatorOption) (*Opera
261261
strategyResolver: &install.StrategyResolver{},
262262
apiReconciler: resolver.APIIntersectionReconcileFunc(resolver.ReconcileAPIIntersection),
263263
apiLabeler: labeler.Func(resolver.LabelSetsFor),
264-
restConfig: &rest.Config{},
264+
restConfig: &rest.Config{},
265265
},
266266
recorder: &record.FakeRecorder{},
267267
// default expected namespaces
@@ -3318,7 +3318,7 @@ func TestUpdates(t *testing.T) {
33183318

33193319
// If we expect a change, wait for listers to sync the change so that the next sync reflects the changes
33203320
if expectedCurrent != expectedPrevious {
3321-
err = wait.PollImmediate(1*time.Millisecond, 5*time.Second, func() (bool, error) {
3321+
err = wait.PollImmediate(1*time.Millisecond, 10*time.Second, func() (bool, error) {
33223322
updated, err := op.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(namespace).Get(csv.GetName())
33233323
if k8serrors.IsNotFound(err) {
33243324
return false, nil
@@ -4278,7 +4278,7 @@ func TestSyncOperatorGroups(t *testing.T) {
42784278
}
42794279

42804280
if i == 0 {
4281-
err = wait.PollImmediate(1*time.Millisecond, 5*time.Second, func() (bool, error) {
4281+
err = wait.PollImmediate(1*time.Millisecond, 10*time.Second, func() (bool, error) {
42824282
for namespace, objects := range tt.final.objects {
42834283
if err := RequireObjectsInCache(t, op.lister, namespace, objects, false); err != nil {
42844284
return false, nil
@@ -4290,7 +4290,7 @@ func TestSyncOperatorGroups(t *testing.T) {
42904290
}
42914291

42924292
if i == 8 {
4293-
err = wait.PollImmediate(1*time.Millisecond, 5*time.Second, func() (bool, error) {
4293+
err = wait.PollImmediate(1*time.Millisecond, 10*time.Second, func() (bool, error) {
42944294
for namespace, objects := range tt.final.objects {
42954295
if err := RequireObjectsInCache(t, op.lister, namespace, objects, true); err != nil {
42964296
return false, nil

pkg/lib/clientfake/client_options.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ import (
1212
type Option func(ClientsetDecorator)
1313

1414
// WithSelfLinks returns a fakeClientOption that configures a ClientsetDecorator to write selfLinks to all OLM types on create.
15-
func WithSelfLinks(t *testing.T) Option {
15+
func WithSelfLinks(tb testing.TB) Option {
1616
return func(c ClientsetDecorator) {
1717
c.PrependReactor("create", "*", func(a clitesting.Action) (bool, runtime.Object, error) {
1818
ca, ok := a.(clitesting.CreateAction)
1919
if !ok {
20-
t.Fatalf("expected CreateAction")
20+
tb.Fatalf("expected CreateAction")
2121
}
2222

2323
obj := ca.GetObject()
@@ -39,12 +39,12 @@ func WithSelfLinks(t *testing.T) Option {
3939
}
4040

4141
// WithNameGeneration returns a fakeK8sClientOption that configures a Clientset to write generated names to all types on create.
42-
func WithNameGeneration(t *testing.T) Option {
42+
func WithNameGeneration(tb testing.TB) Option {
4343
return func(c ClientsetDecorator) {
4444
c.PrependReactor("create", "*", func(a clitesting.Action) (bool, runtime.Object, error) {
4545
ca, ok := a.(clitesting.CreateAction)
4646
if !ok {
47-
t.Fatalf("expected CreateAction")
47+
tb.Fatalf("expected CreateAction")
4848
}
4949

5050
return false, AddSimpleGeneratedName(ca.GetObject()), nil

0 commit comments

Comments
 (0)