Skip to content

Commit

Permalink
fix: configure ENVTEST binaries for IDE execution and project-specifi…
Browse files Browse the repository at this point in the history
…c setup

- Installs ENVTEST binaries in the project’s `./bin/envtest` directory for isolation.
- Configures `setup-envtest` binary to be downloaded based on the controller-runtime release version to ensure compatibility with the project’s dependencies.
- Updates `suite_test.go` to dynamically locate and set the binary assets directory for seamless IDE debugging.
- Introduces `getFirstFoundEnvTestBinaryDir` to detect ENVTEST binaries in the project directory when running tests outside the Makefile context.

1. **Ease of IDE Debugging**:
   - By setting the `BinaryAssetsDirectory` dynamically, contributors can debug tests in their preferred IDEs (e.g., GoLand, VSCode) without requiring additional environment configuration such as setting `KUBEBUILDER_ASSETS`.

2. **Project-Specific Binaries**:
   - Installing binaries inside the project avoids conflicts with other projects or system-wide installations, particularly useful for contributors with restricted environments (e.g., corporate laptops).

3. **Consistency**:
   - Using `setup-envtest` from the matching controller-runtime release avoids compatibility issues, such as those outlined in [#2744](kubernetes-sigs/controller-runtime#2744) and [#2646](kubernetes-sigs/controller-runtime#2646).

4. **Simplified Contributor Onboarding**:
   - New contributors often face a learning curve to:
     - Understand ENVTEST and its dependency on binaries.
     - Configure `KUBEBUILDER_ASSETS` manually.
     - Set up their IDE for debugging tests.
   - This setup minimizes friction and ensures tests can be run consistently across different environments.

While setting `KUBEBUILDER_ASSETS` is sufficient for experienced contributors, this change makes it easier for newcomers and supports debugging directly in IDEs without additional configuration.
  • Loading branch information
Camila M authored and Camila M committed Nov 17, 2024
1 parent 63ef902 commit ba71f8b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 99 deletions.
7 changes: 0 additions & 7 deletions .bingo/setup-envtest.mod

This file was deleted.

85 changes: 0 additions & 85 deletions .bingo/setup-envtest.sum

This file was deleted.

18 changes: 13 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export INSTALL_DEFAULT_CATALOGS := true
# By default setup-envtest will write to $XDG_DATA_HOME, or $HOME/.local/share if that is not defined.
# If $HOME is not set, we need to specify a binary directory to prevent an error in setup-envtest.
# Useful for some CI/CD environments that set neither $XDG_DATA_HOME nor $HOME.
SETUP_ENVTEST_BIN_DIR_OVERRIDE=
SETUP_ENVTEST_BIN_DIR_OVERRIDE := --bin-dir $(ROOT_DIR)/bin/envtest-binaries
ifeq ($(shell [[ $$HOME == "" || $$HOME == "/" ]] && [[ $$XDG_DATA_HOME == "" ]] && echo true ), true)
SETUP_ENVTEST_BIN_DIR_OVERRIDE += --bin-dir /tmp/envtest-binaries
endif
Expand Down Expand Up @@ -151,19 +151,27 @@ test-ext-dev-e2e: $(OPERATOR_SDK) $(KUSTOMIZE) $(KIND) #HELP Run extension creat
test/extension-developer-e2e/setup.sh $(OPERATOR_SDK) $(CONTAINER_RUNTIME) $(KUSTOMIZE) $(KIND) $(KIND_CLUSTER_NAME) $(E2E_REGISTRY_NAMESPACE)
go test -count=1 -v ./test/extension-developer-e2e/...

.PHONY: test-unit
ENVTEST_VERSION := $(shell go list -m k8s.io/client-go | cut -d" " -f2 | sed 's/^v0\.\([[:digit:]]\{1,\}\)\.[[:digit:]]\{1,\}$$/1.\1.x/')
CONTROLLER_RUNTIME_VERSION := release-$(shell go list -m sigs.k8s.io/controller-runtime | awk '{print $$2}' | sed -E 's/^v([0-9]+)\.([0-9]+)\..*/\1.\2/')
UNIT_TEST_DIRS := $(shell go list ./... | grep -v /test/)
COVERAGE_UNIT_DIR := $(ROOT_DIR)/coverage/unit
test-unit: $(SETUP_ENVTEST) #HELP Run the unit tests

.PHONY: setup-envtest #HELP Install setup-envtest binary in the bin directory.
setup-envtest:
mkdir -p $(ROOT_DIR)/bin
GOBIN=$(ROOT_DIR)/bin go install sigs.k8s.io/controller-runtime/tools/setup-envtest@$(CONTROLLER_RUNTIME_VERSION)
$(ROOT_DIR)/bin/setup-envtest use -p env $(ENVTEST_VERSION) $(SETUP_ENVTEST_BIN_DIR_OVERRIDE)

.PHONY: test-unit
test-unit: setup-envtest #HELP Run the unit tests
rm -rf $(COVERAGE_UNIT_DIR) && mkdir -p $(COVERAGE_UNIT_DIR)
eval $$($(SETUP_ENVTEST) use -p env $(ENVTEST_VERSION) $(SETUP_ENVTEST_BIN_DIR_OVERRIDE)) && \
KUBEBUILDER_ASSETS="$(shell $(ROOT_DIR)/bin/setup-envtest use -p path $(ENVTEST_VERSION) $(SETUP_ENVTEST_BIN_DIR_OVERRIDE))" \
CGO_ENABLED=1 go test \
-tags '$(GO_BUILD_TAGS)' \
-cover -coverprofile ${ROOT_DIR}/coverage/unit.out \
-count=1 -race -short \
$(UNIT_TEST_DIRS) \
-test.gocoverdir=$(ROOT_DIR)/coverage/unit
-test.gocoverdir=$(COVERAGE_UNIT_DIR)

.PHONY: image-registry
E2E_REGISTRY_IMAGE=localhost/e2e-test-registry:devel
Expand Down
25 changes: 23 additions & 2 deletions internal/controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (

"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
apimachineryruntime "k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -64,7 +64,7 @@ func (m *MockUnpacker) Cleanup(_ context.Context, _ *source.BundleSource) error
func newClient(t *testing.T) client.Client {
// TODO: this is a live client, which behaves differently than a cache client.
// We may want to use a caching client instead to get closer to real behavior.
sch := runtime.NewScheme()
sch := apimachineryruntime.NewScheme()
require.NoError(t, ocv1.AddToScheme(sch))
cl, err := client.New(config, client.Options{Scheme: sch})
require.NoError(t, err)
Expand Down Expand Up @@ -162,6 +162,15 @@ func TestMain(m *testing.M) {
ErrorIfCRDPathMissing: true,
}

// The BinaryAssetsDirectory is only necessary when we run tests directly
// without using the target. (e.g., when debugging tests in an IDE)
// If left unset, it will default to the path defined in controller-runtime (/usr/local/kubebuilder/).
// Ensure that required binaries are set up in the bin directory bin/k8s/envtest-binaries for direct testing.
// Run `make setup-envtest` to set up the binaries.
if getFirstFoundEnvTestBinaryDir() != "" {
testEnv.BinaryAssetsDirectory = getFirstFoundEnvTestBinaryDir()
}

var err error
config, err = testEnv.Start()
utilruntime.Must(err)
Expand All @@ -179,3 +188,15 @@ func TestMain(m *testing.M) {
utilruntime.Must(testEnv.Stop())
os.Exit(code)
}

// getFirstFoundEnvTestBinaryDir finds and returns the first directory under the given path.
func getFirstFoundEnvTestBinaryDir() string {
basePath := filepath.Join("..", "..", "bin", "envtest-binaries", "k8s")
entries, _ := os.ReadDir(basePath)
for _, entry := range entries {
if entry.IsDir() {
return filepath.Join(basePath, entry.Name())
}
}
return ""
}

0 comments on commit ba71f8b

Please sign in to comment.