Skip to content
This repository was archived by the owner on Apr 24, 2024. It is now read-only.

Commit 1b17c3a

Browse files
make: add an end-to-end test
Signed-off-by: Steve Kuznetsov <[email protected]>
1 parent b095739 commit 1b17c3a

File tree

2 files changed

+129
-48
lines changed

2 files changed

+129
-48
lines changed

Makefile

Lines changed: 113 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,41 @@
1+
##@ Build Dependencies
2+
3+
## Location to install dependencies to
4+
LOCALBIN ?= $(shell pwd)/bin
5+
$(LOCALBIN):
6+
mkdir -p $(LOCALBIN)
7+
8+
## Tool Binaries
9+
KUSTOMIZE ?= $(LOCALBIN)/kustomize
10+
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
11+
ENVTEST ?= $(LOCALBIN)/setup-envtest
12+
KCP ?= $(LOCALBIN)/kcp
13+
KUBECTL_KCP ?= $(LOCALBIN)/kubectl-kcp
14+
15+
## Tool Versions
16+
KUSTOMIZE_VERSION ?= v3.8.7
17+
CONTROLLER_TOOLS_VERSION ?= v0.8.0
18+
KCP_VERSION ?= 0.7.4
19+
20+
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
21+
$(KUSTOMIZE): $(LOCALBIN)
22+
curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN)
23+
24+
$(CONTROLLER_GEN): $(LOCALBIN)
25+
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
26+
27+
OS ?= $(shell go env GOOS )
28+
ARCH ?= $(shell go env GOARCH )
29+
30+
$(KCP): $(LOCALBIN) ## Download kcp locally if necessary.
31+
wget -qO- https://github.com/kcp-dev/kcp/releases/download/v$(KCP_VERSION)/kcp_$(KCP_VERSION)_$(OS)_$(ARCH).tar.gz | tar -xvzf - bin/kcp --directory $(LOCALBIN)/../
32+
33+
$(KUBECTL_KCP): $(LOCALBIN) ## Download kcp kubectl plugins locally if necessary.
34+
wget -qO- https://github.com/kcp-dev/kcp/releases/download/v$(KCP_VERSION)/kubectl-kcp-plugin_$(KCP_VERSION)_$(OS)_$(ARCH).tar.gz | tar -xvzf - bin --directory $(LOCALBIN)/../
35+
36+
$(ENVTEST): $(LOCALBIN)
37+
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
38+
139

240
# Image URL to use all building/pushing image targets
341
IMG ?= controller:latest
@@ -15,7 +53,7 @@ endif
1553
# This is a requirement for 'setup-envtest.sh' in the test target.
1654
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
1755
SHELL = /usr/bin/env bash -o pipefail
18-
.SHELLFLAGS = -ec
56+
.SHELLFLAGS = -ecx
1957

2058
.PHONY: all
2159
all: build
@@ -43,15 +81,15 @@ help: ## Display this help.
4381
##@ Development
4482

4583
.PHONY: manifests
46-
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
84+
manifests: $(CONTROLLER_GEN) ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
4785
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
4886

4987
.PHONY: apiresourceschemas
50-
apiresourceschemas: kustomize ## Convert CRDs from config/crds to APIResourceSchemas. Specify APIEXPORT_PREFIX as needed.
88+
apiresourceschemas: $(KUSTOMIZE) ## Convert CRDs from config/crds to APIResourceSchemas. Specify APIEXPORT_PREFIX as needed.
5189
$(KUSTOMIZE) build config/crd | kubectl kcp crd snapshot -f - --prefix $(APIEXPORT_PREFIX) > config/kcp/$(APIEXPORT_PREFIX).apiresourceschemas.yaml
5290

5391
.PHONY: generate
54-
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
92+
generate: $(CONTROLLER_GEN) ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
5593
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
5694

5795
.PHONY: fmt
@@ -63,9 +101,66 @@ vet: ## Run go vet against code.
63101
go vet ./...
64102

65103
.PHONY: test
66-
test: manifests generate fmt vet envtest ## Run tests.
104+
test: manifests generate fmt vet $(ENVTEST) ## Run tests.
67105
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -coverprofile cover.out
68106

107+
.PHONY: require-%
108+
require-%:
109+
@if ! command -v $* 1> /dev/null 2>&1; then echo "$* not found in \$$PATH"; exit 1; fi
110+
111+
ARTIFACT_DIR ?= .test
112+
113+
.PHONY: test-e2e
114+
test-e2e: $(ARTIFACT_DIR)/kind.kubeconfig kcp-synctarget ready-deployment
115+
go test ./test/e2e/...
116+
117+
.PHONY: ready-deployment
118+
ready-deployment: KUBECONFIG = $(ARTIFACT_DIR)/kcp.kubeconfig
119+
ready-deployment: kind-image install deploy
120+
$(KCP_KUBECTL) --namespace "controller-runtime-example-system" rollout status deployment/controller-runtime-example-controller-manager
121+
122+
.PHONY: kind-image
123+
kind-image: docker-build
124+
kind load docker-image $(IMG) --name controller-runtime-example
125+
126+
$(ARTIFACT_DIR)/kind.kubeconfig: $(ARTIFACT_DIR) require-kind
127+
@if ! kind get clusters --quiet | grep --quiet controller-runtime-example; then kind create cluster --name controller-runtime-example; fi
128+
kind get kubeconfig --name controller-runtime-example > $(ARTIFACT_DIR)/kind.kubeconfig
129+
130+
$(ARTIFACT_DIR):
131+
mkdir -p $(ARTIFACT_DIR)
132+
133+
KCP_KUBECTL ?= PATH=$(LOCALBIN):$(PATH) KUBECONFIG=$(ARTIFACT_DIR)/kcp.kubeconfig kubectl
134+
KIND_KUBECTL ?= kubectl --kubeconfig $(ARTIFACT_DIR)/kind.kubeconfig
135+
136+
.PHONY: kcp-synctarget
137+
kcp-synctarget: require-yq kcp-workspace $(ARTIFACT_DIR)/syncer.yaml
138+
$(KIND_KUBECTL) apply -f $(ARTIFACT_DIR)/syncer.yaml
139+
$(eval DEPLOYMENT_NAME = $(shell yq 'select(.kind=="Deployment") | .metadata.name' --raw-output < $(ARTIFACT_DIR)/syncer.yaml ))
140+
$(eval DEPLOYMENT_NAMESPACE = $(shell yq 'select(.kind=="Deployment") | .metadata.namespace' --raw-output < $(ARTIFACT_DIR)/syncer.yaml ))
141+
$(KIND_KUBECTL) --namespace $(DEPLOYMENT_NAMESPACE) rollout status deployment/$(DEPLOYMENT_NAME)
142+
@if [[ ! -s $(ARTIFACT_DIR)/syncer.log ]]; then ( $(KIND_KUBECTL) --namespace $(DEPLOYMENT_NAMESPACE) logs deployment/$(DEPLOYMENT_NAME) -f >$(ARTIFACT_DIR)/syncer.log 2>&1 & ); fi
143+
$(KCP_KUBECTL) wait --for=condition=Ready synctarget/controller-runtime
144+
145+
$(ARTIFACT_DIR)/syncer.yaml:
146+
$(KCP_KUBECTL) kcp workload sync controller-runtime --resources services --syncer-image ghcr.io/kcp-dev/kcp/syncer:v$(KCP_VERSION) --output-file $(ARTIFACT_DIR)/syncer.yaml
147+
148+
.PHONY: kcp-workspace
149+
kcp-workspace: $(KUBECTL_KCP) require-kubectl
150+
kcp-workspace: kcp-server
151+
$(KCP_KUBECTL) kcp workspace use '~'
152+
@if ! $(KCP_KUBECTL) kcp workspace use controller-runtime-example; then $(KCP_KUBECTL) kcp workspace create controller-runtime-example --type universal --enter; fi
153+
154+
.PHONY: kcp-server
155+
kcp-server: $(KCP)
156+
kcp-server: $(ARTIFACT_DIR)/kcp
157+
@if [[ ! -s $(ARTIFACT_DIR)/kcp.log ]]; then ( $(KCP) start --root-directory $(ARTIFACT_DIR)/kcp --kubeconfig-path $(ARTIFACT_DIR)/kcp.kubeconfig >$(ARTIFACT_DIR)/kcp.log 2>&1 & ); fi
158+
@while true; do if [[ ! -s $(ARTIFACT_DIR)/kcp.kubeconfig ]]; then sleep 0.2; else break; fi; done
159+
@while true; do if ! kubectl --kubeconfig $(ARTIFACT_DIR)/kcp.kubeconfig get --raw /readyz >$(ARTIFACT_DIR)/kcp.probe.log 2>&1; then sleep 0.2; else break; fi; done
160+
161+
$(ARTIFACT_DIR)/kcp:
162+
mkdir -p $(ARTIFACT_DIR)/kcp
163+
69164
##@ Build
70165

71166
.PHONY: build
@@ -80,11 +175,11 @@ run: manifests generate fmt vet ## Run a controller from your host.
80175
go run ./main.go --api-export-name $(NAME_PREFIX)$(APIEXPORT_NAME)
81176

82177
.PHONY: docker-build
83-
docker-build: build ## Build docker image with the manager.
178+
docker-build: require-docker build ## Build docker image with the manager.
84179
docker build -t ${IMG} .
85180

86181
.PHONY: docker-push
87-
docker-push: ## Push docker image with the manager.
182+
docker-push: require-docker ## Push docker image with the manager.
88183
docker push ${IMG}
89184

90185
##@ Deployment
@@ -93,56 +188,26 @@ ifndef ignore-not-found
93188
ignore-not-found = false
94189
endif
95190

191+
KUBECONFIG ?= $(shell realpath ~/.kube/config )
192+
96193
.PHONY: install
97-
install: manifests kustomize ## Install APIResourceSchemas and APIExport into kcp (using $KUBECONFIG or ~/.kube/config).
98-
$(KUSTOMIZE) build config/kcp | kubectl apply -f -
194+
install: manifests $(KUSTOMIZE) ## Install APIResourceSchemas and APIExport into kcp (using $KUBECONFIG or ~/.kube/config).
195+
$(KUSTOMIZE) build config/kcp | kubectl --kubeconfig $(KUBECONFIG) apply -f -
99196

100197
.PHONY: uninstall
101-
uninstall: manifests kustomize ## Uninstall APIResourceSchemas and APIExport from kcp (using $KUBECONFIG or ~/.kube/config). Call with ignore-not-found=true to ignore resource not found errors during deletion.
102-
$(KUSTOMIZE) build config/kcp | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
198+
uninstall: manifests $(KUSTOMIZE) ## Uninstall APIResourceSchemas and APIExport from kcp (using $KUBECONFIG or ~/.kube/config). Call with ignore-not-found=true to ignore resource not found errors during deletion.
199+
$(KUSTOMIZE) build config/kcp | kubectl --kubeconfig $(KUBECONFIG) delete --ignore-not-found=$(ignore-not-found) -f -
103200

104201
.PHONY: deploy-crd
105-
deploy-crd: manifests kustomize ## Deploy controller
202+
deploy-crd: manifests $(KUSTOMIZE) ## Deploy controller
106203
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
107-
$(KUSTOMIZE) build config/default-crd | kubectl apply -f - || true
204+
$(KUSTOMIZE) build config/default-crd | kubectl --kubeconfig $(KUBECONFIG) apply -f - || true
108205

109206
.PHONY: deploy
110-
deploy: manifests kustomize ## Deploy controller
207+
deploy: manifests $(KUSTOMIZE) ## Deploy controller
111208
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
112-
$(KUSTOMIZE) build config/default | kubectl apply -f -
209+
$(KUSTOMIZE) build config/default | kubectl --kubeconfig $(KUBECONFIG) apply -f -
113210

114211
.PHONY: undeploy
115212
undeploy: ## Undeploy controller. Call with ignore-not-found=true to ignore resource not found errors during deletion.
116-
$(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
117-
118-
##@ Build Dependencies
119-
120-
## Location to install dependencies to
121-
LOCALBIN ?= $(shell pwd)/bin
122-
$(LOCALBIN):
123-
mkdir -p $(LOCALBIN)
124-
125-
## Tool Binaries
126-
KUSTOMIZE ?= $(LOCALBIN)/kustomize
127-
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
128-
ENVTEST ?= $(LOCALBIN)/setup-envtest
129-
130-
## Tool Versions
131-
KUSTOMIZE_VERSION ?= v3.8.7
132-
CONTROLLER_TOOLS_VERSION ?= v0.8.0
133-
134-
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
135-
.PHONY: kustomize
136-
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
137-
$(KUSTOMIZE): $(LOCALBIN)
138-
curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN)
139-
140-
.PHONY: controller-gen
141-
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
142-
$(CONTROLLER_GEN): $(LOCALBIN)
143-
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
144-
145-
.PHONY: envtest
146-
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
147-
$(ENVTEST): $(LOCALBIN)
148-
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
213+
$(KUSTOMIZE) build config/default | kubectl --kubeconfig $(KUBECONFIG) delete --ignore-not-found=$(ignore-not-found) -f -

test/e2e/controller_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package e2e
2+
3+
import "testing"
4+
5+
// TestControllers is called when:
6+
// - kcp is running
7+
// - a kind cluster is up and running
8+
// - it is hosting a syncer, and the SyncTarget is ready to go
9+
// - the controller-manager from this repo is deployed to kcp
10+
// - that deployment is synced to the kind cluster
11+
// - the deployment is rolled out & ready
12+
//
13+
// We can then check that the controllers defined here are working as expected.
14+
func TestControllers(t *testing.T) {
15+
16+
}

0 commit comments

Comments
 (0)