Skip to content

Commit

Permalink
Configure ENVTEST Binaries for IDE Debugging
Browse files Browse the repository at this point in the history
This change introduces downloading the specific binaries required to run ENVTEST-based tests into the project/bin directory. This setup makes it easier to configure tests for debugging directly in an IDE.

Furthermore, no longer install binaries required for ENVTEST based tests on the project/bin instead of global path.
  • Loading branch information
camilamacedo86 committed Dec 17, 2024
1 parent 7ad65d6 commit 450d120
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
26 changes: 26 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,32 @@ you can follow the steps below to test your changes:
make kind-load kind-deploy
```

## How to debug controller tests using ENVTEST

[ENVTEST](https://book.kubebuilder.io/reference/envtest) requires k8s binaries to be downloaded to run the tests.
To download the necessary binaries, follow the steps below:

```sh
make envtest-k8s-bins
```

Note that the binaries are downloaded to the `bin/envtest-binaries` directory.

```sh
$ tree
.
├── envtest-binaries
│   └── k8s
│   └── 1.31.0-darwin-arm64
│   ├── etcd
│   ├── kube-apiserver
│   └── kubectl
```

Now, you can debug them with your IDE:

![Screenshot IDE example](https://github.com/user-attachments/assets/3096d524-0686-48ca-911c-5b843093ad1f)

### Communication Channels

- Email: [operator-framework-olm-dev](mailto:[email protected])
Expand Down
18 changes: 12 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ export WAIT_TIMEOUT := 60s
# Install default ClusterCatalogs
export INSTALL_DEFAULT_CATALOGS := true

# By default setup-envtest will write to $XDG_DATA_HOME, or $HOME/.local/share if that is not defined.
# By default setup-envtest binary 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 @@ -158,19 +158,25 @@ 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/')
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: envtest-k8s-bins #HELP Uses setup-envtest to download and install the binaries required to run ENVTEST-test based locally at the project/bin directory.
envtest-k8s-bins: $(SETUP_ENVTEST)
mkdir -p $(ROOT_DIR)/bin
$(SETUP_ENVTEST) use -p env $(ENVTEST_VERSION) $(SETUP_ENVTEST_BIN_DIR_OVERRIDE)

.PHONY: test-unit
test-unit: $(SETUP_ENVTEST) envtest-k8s-bins #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 $(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
31 changes: 29 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,21 @@ func TestMain(m *testing.M) {
ErrorIfCRDPathMissing: true,
}

// ENVTEST-based tests require specific binaries. By default, these binaries are located
// in paths defined by controller-runtime. However, the `BinaryAssetsDirectory` needs
// to be explicitly set when running tests directly (e.g., debugging tests in an IDE)
// without using the Makefile targets.
//
// This is equivalent to configuring your IDE to export the `KUBEBUILDER_ASSETS` environment
// variable before each test execution. The following function simplifies this process
// by handling the configuration for you.
//
// To ensure the binaries are in the expected path without manual configuration, run:
// `make envtest-k8s-bins`
if getFirstFoundEnvTestBinaryDir() != "" {
testEnv.BinaryAssetsDirectory = getFirstFoundEnvTestBinaryDir()
}

var err error
config, err = testEnv.Start()
utilruntime.Must(err)
Expand All @@ -179,3 +194,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 450d120

Please sign in to comment.