From 4888af583f6a992e46617cc154ff9787e4dc2a7b Mon Sep 17 00:00:00 2001
From: Daniel Lipovetsky <dlipovetsky@d2iq.com>
Date: Wed, 8 Feb 2023 11:30:06 -0800
Subject: [PATCH] :book: Document example VSCode envtest integration

* Add 'setup-envtest' make target to setup envtest on demand.
* Document how to configure VSCode.
---
 Makefile                                      |  4 +++
 .../settings.json                             |  3 ++
 dev/vscode-example-configuration/tasks.json   | 32 +++++++++++++++++++
 dev/vscode-example-configuration/test.env     |  0
 docs/book/src/developer/repository-layout.md  |  5 +++
 docs/book/src/developer/testing.md            | 28 ++++++++++++++++
 6 files changed, 72 insertions(+)
 create mode 100644 dev/vscode-example-configuration/settings.json
 create mode 100644 dev/vscode-example-configuration/tasks.json
 create mode 100644 dev/vscode-example-configuration/test.env

diff --git a/Makefile b/Makefile
index 4e67c526d676..9f2cf9350aa2 100644
--- a/Makefile
+++ b/Makefile
@@ -731,6 +731,10 @@ ARTIFACTS ?= ${ROOT_DIR}/_artifacts
 
 KUBEBUILDER_ASSETS ?= $(shell $(SETUP_ENVTEST) use --use-env -p path $(KUBEBUILDER_ENVTEST_KUBERNETES_VERSION))
 
+.PHONY: setup-envtest
+setup-envtest: $(SETUP_ENVTEST) ## Set up envtest (download kubebuilder assets)
+	@echo KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS)
+
 .PHONY: test
 test: $(SETUP_ENVTEST) ## Run unit and integration tests
 	KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" go test ./... $(TEST_ARGS)
diff --git a/dev/vscode-example-configuration/settings.json b/dev/vscode-example-configuration/settings.json
new file mode 100644
index 000000000000..bbade3fe7cd0
--- /dev/null
+++ b/dev/vscode-example-configuration/settings.json
@@ -0,0 +1,3 @@
+{
+    "go.testEnvFile": "${workspaceFolder}/.vscode/test.env"
+}
\ No newline at end of file
diff --git a/dev/vscode-example-configuration/tasks.json b/dev/vscode-example-configuration/tasks.json
new file mode 100644
index 000000000000..4629a886b51f
--- /dev/null
+++ b/dev/vscode-example-configuration/tasks.json
@@ -0,0 +1,32 @@
+{
+    // See https://go.microsoft.com/fwlink/?LinkId=733558
+    // for the documentation about the tasks.json format
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "type": "shell",
+            "label": "sigs.k8s.io/cluster-api: Prepare vscode to run envtest-based tests",
+            "detail": "Install envtest and configure the vscode-go test environment.",
+            "group": {
+                "kind": "test",
+                "isDefault": true
+            },
+            "command": [
+                "echo $(make setup-envtest) > ${workspaceFolder}/.vscode/test.env",
+            ],
+            "presentation": {
+                "echo": true,
+                "reveal": "silent",
+                "focus": true,
+                "panel": "shared",
+                "showReuseMessage": true,
+                "clear": false
+            },
+            "runOptions": {
+                "runOn": "folderOpen",
+                "instanceLimit": 1,
+            },
+            "promptOnClose": true,
+        }
+    ]
+}
\ No newline at end of file
diff --git a/dev/vscode-example-configuration/test.env b/dev/vscode-example-configuration/test.env
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/docs/book/src/developer/repository-layout.md b/docs/book/src/developer/repository-layout.md
index dc918cef3051..bc6936fd314c 100644
--- a/docs/book/src/developer/repository-layout.md
+++ b/docs/book/src/developer/repository-layout.md
@@ -12,6 +12,7 @@ cluster-api
 └───config
 └───controllers
 └───controlplane
+└───dev
 └───docs
 └───errors
 └───exp
@@ -115,6 +116,10 @@ This folder has scripts used for building, testing and developer workflow.
 
 This folder consists of CI scripts related to setup, build and e2e tests. These are mostly called by CI jobs.
 
+[~/dev](https://github.com/kubernetes-sigs/cluster-api/tree/main/dev)
+
+This folder has example configuration for integrating Cluster API development with tools like IDEs.
+
 ### Util, Feature and Errors
 
 [~/util](https://github.com/kubernetes-sigs/cluster-api/tree/main/util)
diff --git a/docs/book/src/developer/testing.md b/docs/book/src/developer/testing.md
index 91bc5673b2c0..1d60fec1cdf2 100644
--- a/docs/book/src/developer/testing.md
+++ b/docs/book/src/developer/testing.md
@@ -95,6 +95,8 @@ but in this case the distinctive value of the two layers of testing is determine
 
 Run `make test` to execute all unit and integration tests.
 
+Integration tests use the [envtest](https://github.com/kubernetes-sigs/controller-runtime/blob/master/pkg/envtest/doc.go) test framework. The tests need to know the location of the executables called by the framework. The `make test` target installs these executables, and passes this location to the tests as an environment variable.
+
 <aside class="note">
 
 <h1>Tips</h1>
@@ -113,6 +115,30 @@ To debug testenv unit tests it is possible to use:
 
 </aside>
 
+### Test execution via IDE
+
+Your IDE needs to know the location of the executables called by the framework, so that it can pass the location to the tests as an environment variable.
+
+<aside class="note warning">
+
+<h1>Warning</h1>
+
+If you see this error when running a test in your IDE, the test uses the envtest framework, and probably does not know the location of the envtest executables.
+
+```console
+E0210 16:11:04.222471  132945 server.go:329] controller-runtime/test-env "msg"="unable to start the controlplane" "error"="fork/exec /usr/local/kubebuilder/bin/etcd: no such file or directory" "tries"=0
+```
+
+</aside>
+
+#### VSCode
+
+The `dev/vscode-example-configuration` directory in the repository contains an example configuration that integrates VSCode with the envtest framework.
+
+To use the example configuration, copy the files to the `.vscode` directory in the repository, and restart VSCode.
+
+The configuration works as follows: Whenever the project is opened in VSCode, a VSCode task runs that installs the executables, and writes the location to a file. A setting tells [vscode-go] to initialize the environment from this file.
+
 ## End-to-end tests
 
 The end-to-end tests are meant to verify the proper functioning of a Cluster API management cluster
@@ -536,3 +562,5 @@ In Cluster API Unit and integration test MUST use [go test].
 [envtest]: https://github.com/kubernetes-sigs/controller-runtime/tree/master/pkg/envtest
 [fakeclient]: https://github.com/kubernetes-sigs/controller-runtime/tree/master/pkg/client/fake
 [test/helpers]: https://github.com/kubernetes-sigs/cluster-api/tree/main/test/helpers
+
+[vscode-go]: https://marketplace.visualstudio.com/items?itemName=golang.Go
\ No newline at end of file