From 2950a016401076e7358f25687e02e7ae7058e37a Mon Sep 17 00:00:00 2001 From: Chris Randles Date: Sun, 15 Sep 2024 20:53:56 -0400 Subject: [PATCH] feat: add benchmark and skipping features example --- examples/benchmark_tests/README.md | 42 +++++++++++++++ examples/benchmark_tests/benchmark_test.go | 35 ++++++++++++ examples/benchmark_tests/main_test.go | 63 ++++++++++++++++++++++ go.mod | 2 + 4 files changed, 142 insertions(+) create mode 100644 examples/benchmark_tests/README.md create mode 100644 examples/benchmark_tests/benchmark_test.go create mode 100644 examples/benchmark_tests/main_test.go diff --git a/examples/benchmark_tests/README.md b/examples/benchmark_tests/README.md new file mode 100644 index 00000000..ae1f4103 --- /dev/null +++ b/examples/benchmark_tests/README.md @@ -0,0 +1,42 @@ +# Benchmark tests and skipping features + +This directory contains the example of: +- how to run **without test features**, and use your preferred `testing` package (standard library and testify included in example) + * When skipping features, you will not receive any benefit from the `features` related setup or teardown `envfuncs`, but you will still be able to access a kubernetes config (`envconfig`) to create a client that has access to the expected test cluster. +- how to run Go **Test Benchmarks**, e.g. via `go test -bench=.` + +# Skipping features + +```go +func BenchmarkListPods(b *testing.B) { + client, err := testenv.EnvConf().NewClient() + // ...your client is ready you use -- or use the `*rest.Config` to create your preferred client +} + +func TestExample(t *testing.T) { + client, err := testenv.EnvConf().NewClient() + // ... +} +``` + + +# Run Tests with flags + +These test cases can be executed using the normal `go test -bench=-` command by passing the right arguments + +```bash +go test -bench=. -v . +``` + +With the output generated as following. + +```bash +goos: +goarch: +pkg: sigs.k8s.io/e2e-framework/examples/benchmark_tests +cpu: +BenchmarkListPods +BenchmarkListPods-12 100 180148936 ns/op +PASS +ok sigs.k8s.io/e2e-framework/examples/benchmark_tests 47.880s +``` diff --git a/examples/benchmark_tests/benchmark_test.go b/examples/benchmark_tests/benchmark_test.go new file mode 100644 index 00000000..defc1fae --- /dev/null +++ b/examples/benchmark_tests/benchmark_test.go @@ -0,0 +1,35 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package benchmark_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" +) + +func BenchmarkListPods(b *testing.B) { + client, err := testenv.EnvConf().NewClient() + require.NoError(b, err) + var pods corev1.PodList + for n := 0; n < b.N; n++ { + err = client.Resources("kube-system").List(context.TODO(), &pods) + require.NoError(b, err) + } +} diff --git a/examples/benchmark_tests/main_test.go b/examples/benchmark_tests/main_test.go new file mode 100644 index 00000000..e49999ee --- /dev/null +++ b/examples/benchmark_tests/main_test.go @@ -0,0 +1,63 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package benchmark_test + +import ( + "context" + "os" + "testing" + "time" + + "sigs.k8s.io/e2e-framework/pkg/env" + "sigs.k8s.io/e2e-framework/pkg/envconf" + "sigs.k8s.io/e2e-framework/support/kind" +) + +var testenv env.Environment + +func TestMain(m *testing.M) { + testenv = env.New() + testenv.Setup( + // Step: creates kind cluster, propagate kind cluster object + func(ctx context.Context, cfg *envconf.Config) (context.Context, error) { + name := envconf.RandomName("my-cluster", 16) + cluster := kind.NewCluster(name) + kubeconfig, err := cluster.Create(ctx) + if err != nil { + return ctx, err + } + // stall a bit to allow most pods to come up + time.Sleep(time.Second * 10) + + // update environment with kubecofig file + cfg.WithKubeconfigFile(kubeconfig) + // propagate cluster value + return context.WithValue(ctx, 1, cluster), nil + }, + ).Finish( + // Teardown func: delete kind cluster + func(ctx context.Context, cfg *envconf.Config) (context.Context, error) { + cluster := ctx.Value(1).(*kind.Cluster) // nil should be tested + if err := cluster.Destroy(ctx); err != nil { + return ctx, err + } + return ctx, nil + }, + ) + + os.Exit(testenv.Run(m)) +} diff --git a/go.mod b/go.mod index 80a54ed6..59f30ac1 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module sigs.k8s.io/e2e-framework go 1.22.3 require ( + github.com/stretchr/testify v1.9.0 github.com/vladimirvivien/gexe v0.3.0 k8s.io/api v0.31.1 k8s.io/apimachinery v0.31.1 @@ -41,6 +42,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect