Skip to content

Commit b6c8d53

Browse files
authored
Merge pull request #87 from sp-yduck/refactor/testing
Support integration test and e2e test
2 parents 291a3e2 + ddb4db5 commit b6c8d53

File tree

27 files changed

+1466
-253
lines changed

27 files changed

+1466
-253
lines changed

.github/workflows/cover.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ jobs:
88
runs-on: ubuntu-latest
99
steps:
1010
- uses: actions/checkout@master
11-
- run: "make test-cover"
11+
- run: "make unit-test-cover"
1212
- uses: codecov/codecov-action@v2

.gitignore

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,11 @@ coverage.*
2727
*~
2828

2929
# release
30-
out
30+
out
31+
32+
# test artifact
33+
ginkgo-log.txt
34+
internal/test/e2e/clusters
35+
internal/test/e2e/kind
36+
internal/test/e2e/repository
37+
internal/test/e2e/data/infrastructure-proxmox/*/cluster-template.yaml

Makefile

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11

22
# Image URL to use all building/pushing image targets
3-
IMG ?= controller:latest
3+
REGISTRY := ghcr.io
4+
PROJECT := sp-yduck/cluster-api-provider-proxmox
5+
RELEASE_TAG := latest
6+
IMG ?= $(REGISTRY)/$(PROJECT):$(RELEASE_TAG)
47
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
58
ENVTEST_K8S_VERSION = 1.26.1
69

10+
# add localbin to PATH
11+
LOCALBIN ?= $(shell pwd)/bin
12+
export PATH := $(abspath $(LOCALBIN)):$(PATH)
13+
714
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
815
ifeq (,$(shell go env GOBIN))
916
GOBIN=$(shell go env GOPATH)/bin
@@ -58,7 +65,7 @@ vet: ## Run go vet against code.
5865
go vet ./...
5966

6067
.PHONY: lint
61-
lint: ## Run golangci-lint
68+
lint: golangci-lint ## Run golangci-lint
6269
$(GOLANGCI_LINT) run
6370

6471
CLUSTER_NAME := cappx-test
@@ -75,17 +82,51 @@ delete-workload-cluster: $(KUBECTL)
7582

7683
SETUP_ENVTEST_VER := v0.0.0-20211110210527-619e6b92dab9
7784
SETUP_ENVTEST := $(LOCALBIN)/setup-envtest
85+
GINKGO_TIMEOUT ?= 30m
7886

7987
.PHONY: test
80-
test: manifests generate fmt $(SETUP_ENVTEST)
81-
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... $(TEST_ARGS)
88+
test: generate manifests fmt $(SETUP_ENVTEST) ## Run unit and integration test
89+
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./api/... ./cloud/... ./controllers/... $(TEST_ARGS)
90+
91+
.PHONY: unit-test ## Run unit tests
92+
unit-test: generate manifests fmt $(SETUP_ENVTEST)
93+
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./api/... ./cloud/... ./controllers/... --ginkgo.label-filter=unit $(TEST_ARGS)
8294

8395
.PHONY: test-cover
8496
test-cover: ## Run unit and integration tests and generate coverage report
8597
$(MAKE) test TEST_ARGS="$(TEST_ARGS) -coverprofile=coverage.out"
8698
go tool cover -func=coverage.out -o coverage.txt
8799
go tool cover -html=coverage.out -o coverage.html
88100

101+
.PHONY: unit-test-cover
102+
unit-test-cover: ## Run unit tests and generate coverage report
103+
$(MAKE) unit-test TEST_ARGS="$(TEST_ARGS) -coverprofile=coverage.out"
104+
go tool cover -func=coverage.out -o coverage.txt
105+
go tool cover -html=coverage.out -o coverage.html
106+
107+
E2E_DIR = $(shell pwd)/internal/test/e2e
108+
E2E_IMG := ghcr.io/sp-yduck/cluster-api-provider-proxmox:e2e
109+
.PHONY: generate-e2e-templates
110+
generate-e2e-templates: $(KUSTOMIZE) ## Generate cluster-templates for e2e
111+
cp templates/cluster-template* $(E2E_DIR)/data/infrastructure-proxmox/templates
112+
$(KUSTOMIZE) build $(E2E_DIR)/data/infrastructure-proxmox/templates > $(E2E_DIR)/data/infrastructure-proxmox/main/cluster-template.yaml
113+
114+
.PHONY: build-e2e-image
115+
build-e2e-image: ## Build cappx image to be used for e2e test
116+
IMG=${E2E_IMG} $(MAKE) docker-build
117+
118+
.PHONY: e2e
119+
e2e: generate-e2e-templates build-e2e-image cleanup-e2e-artifacts ## Run e2e test
120+
go test $(E2E_DIR)/... -v \
121+
-timeout=$(GINKGO_TIMEOUT) \
122+
--e2e.artifacts-folder=$(E2E_DIR) \
123+
--e2e.use-existing-cluster="$(USE_EXISTING_CLUSTER)"
124+
125+
.PHONY: cleanup-e2e-artifacts
126+
cleanup-e2e-artifacts: ## delete some e2e artifacts
127+
rm -rf $(E2E_DIR)/clusters
128+
rm -rf $(E2E_DIR)/kind
129+
89130
##@ Build
90131

91132
.PHONY: build
@@ -140,7 +181,6 @@ uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified
140181

141182
.PHONY: deploy
142183
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
143-
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
144184
$(KUSTOMIZE) build config/default | kubectl apply -f -
145185

146186
.PHONY: undeploy
@@ -150,16 +190,20 @@ undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/confi
150190
##@ Release
151191

152192
## Location to output for release
153-
RELEASE_DIR := out
193+
RELEASE_DIR := $(shell pwd)/out
154194
$(RELEASE_DIR):
155195
mkdir -p $(RELEASE_DIR)
156196

157-
# RELEASE_TAG := $(shell git describe --abbrev=0 2>/dev/null)
197+
RELEASE_TAG := $(shell git describe --abbrev=0 2>/dev/null)
158198

159-
# .PHONY: release
199+
.PHONY: release ## Builds all the manifests/config files to publish with a release
200+
$(MAKE) release-manifests
201+
$(MAKE) release-metadata
202+
$(MAKE) release-templates
160203

161204
.PHONY: release-manifests
162205
release-manifests: $(KUSTOMIZE) $(RELEASE_DIR) ## Builds the manifests to publish with a release
206+
cd config/manager && $(KUSTOMIZE) edit set image controller=${REGISTRY}/${PROJECT}:${RELEASE_TAG}
163207
$(KUSTOMIZE) build config/default > $(RELEASE_DIR)/infrastructure-components.yaml
164208

165209
.PHONY: release-metadata
@@ -174,7 +218,6 @@ release-templates: $(RELEASE_DIR)
174218
##@ Build Dependencies
175219

176220
## Location to install dependencies to
177-
LOCALBIN ?= $(shell pwd)/bin
178221
$(LOCALBIN):
179222
mkdir -p $(LOCALBIN)
180223

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,33 @@ Because Proxmox-VE does not provide LBaaS solution, CAPPX does not follow the [t
102102

103103
ProxmoxMachine controller follows the [typical infra-machine logic](https://cluster-api.sigs.k8s.io/developer/providers/machine-infrastructure.html#behavior). To bootstrap your machine, CAPPX supports only `cloud-config` type bootstrap data secret. CAPPX is mainly tested with [KubeadmControlPlane](https://github.com/kubernetes-sigs/cluster-api/tree/main/controlplane/kubeadm) and [KubeadmBootstrap](https://github.com/kubernetes-sigs/cluster-api/tree/main/bootstrap/kubeadm).
104104

105+
## Development
106+
107+
### Testing
108+
#### Unit Testing
109+
```
110+
make unit-test
111+
```
112+
113+
#### Unit and Integration Testing
114+
```
115+
export PROXMOX_URL=https://X.X.X.X:8006/api2/json
116+
export PROXMOX_PASSWORD=password
117+
export PROXMOX_USER=user@pam
118+
119+
make test
120+
```
121+
122+
### E2E Testing
123+
```
124+
export CONTROLPLANE_HOST=X.X.X.X
125+
export PROXMOX_URL=https://X.X.X.X:8006/api2/json
126+
export PROXMOX_PASSWORD=password
127+
export PROXMOX_USER=user@pam
128+
129+
make e2e
130+
```
131+
105132
## Contributing
106133

107134
Are you interested in contributing to cluster-api-provider-proxmox? Do not hesitate to open GitHub issues.

cloud/cloudinit/user_test.go

Lines changed: 64 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
package cloudinit_test
22

33
import (
4-
"reflect"
54
"testing"
65

6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
79
infrav1 "github.com/sp-yduck/cluster-api-provider-proxmox/api/v1beta1"
810
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/cloudinit"
911
)
1012

11-
func TestParseUser(t *testing.T) {
12-
testYaml := `
13+
func TestCloudInit(t *testing.T) {
14+
RegisterFailHandler(Fail)
15+
RunSpecs(t, "CloudInit Suite")
16+
}
17+
18+
var _ = Describe("ParseUserDatas", Label("unit", "cloudinit"), func() {
19+
BeforeEach(func() {})
20+
AfterEach(func() {})
21+
22+
Context("correct format", func() {
23+
It("should no error", func() {
24+
testYaml := `
1325
write_files:
1426
- path: /run/kubeadm/kubeadm.yaml
1527
owner: root:root
@@ -22,69 +34,64 @@ runcmd:
2234
- "chmod +x /usr/local/bin/kubectl"
2335
- "reboot now"
2436
`
25-
_, err := cloudinit.ParseUserData(testYaml)
26-
if err != nil {
27-
t.Errorf("failed to parse user: %v", err)
28-
}
37+
userData, err := cloudinit.ParseUserData(testYaml)
38+
Expect(err).NotTo(HaveOccurred())
39+
Expect(userData).NotTo(BeNil())
40+
})
41+
})
2942

30-
testYaml = `
43+
Context("incorrect format", func() {
44+
It("should error", func() {
45+
testYaml := `
3146
write_files:
3247
- path: /run/kubeadm/kubeadm.yaml
3348
owner: root:root
3449
permissions: '0640'
3550
content: |
3651
asdfasdfasdf
3752
`
38-
user, err := cloudinit.ParseUserData(testYaml)
39-
if err == nil {
40-
t.Errorf("should returns an error. user=%v", *user)
41-
}
42-
}
53+
userData, err := cloudinit.ParseUserData(testYaml)
54+
Expect(err).To(HaveOccurred())
55+
Expect(userData).To(BeNil())
56+
})
57+
})
58+
})
4359

44-
func TestGenerateUserYaml(t *testing.T) {
45-
testYaml := `
46-
write_files:
47-
- path: /run/kubeadm/kubeadm.yaml
48-
owner: root:root
49-
permissions: '0640'
50-
content: |
51-
asdfasdfasdf
52-
runcmd:
53-
- 'kubeadm init --config /run/kubeadm/kubeadm.yaml && echo success > /run/cluster-api/bootstrap-success.complete'
54-
- "curl -L https://dl.k8s.io/release/v1.27.3/bin/linux/amd64/kubectl -o /usr/local/bin/kubectl"
55-
- "chmod +x /usr/local/bin/kubectl"
56-
- "reboot now"
57-
`
60+
var _ = Describe("GenerateUserDataYaml", Label("unit", "cloudinit"), func() {
61+
BeforeEach(func() {})
62+
AfterEach(func() {})
5863

59-
uc, err := cloudinit.ParseUserData(testYaml)
60-
if err != nil {
61-
t.Fatalf("failed to parse user: %v", err)
62-
}
64+
Context("generate user-data yaml string", func() {
65+
It("should no error", func() {
66+
userData := infrav1.UserData{
67+
RunCmd: []string{"echo", "pwd"},
68+
}
69+
yaml, err := cloudinit.GenerateUserDataYaml(userData)
70+
Expect(err).NotTo(HaveOccurred())
71+
Expect(yaml).NotTo(BeNil())
72+
})
73+
})
74+
})
6375

64-
_, err = cloudinit.GenerateUserDataYaml(*uc)
65-
if err != nil {
66-
t.Fatalf("generate : %v", err)
67-
}
68-
}
76+
var _ = Describe("MergeUserDatas", Label("unit", "cloudinit"), func() {
77+
var _ = Context("merge 2 user datas", func() {
78+
var _ = It("should no error", func() {
79+
a := infrav1.UserData{
80+
User: "override-user",
81+
RunCmd: []string{"command A", "command B"},
82+
}
83+
b := infrav1.UserData{
84+
User: "test-user",
85+
RunCmd: []string{"command C"},
86+
}
87+
expected := infrav1.UserData{
88+
User: "override-user",
89+
RunCmd: []string{"command A", "command B", "command C"},
90+
}
6991

70-
func TestMergeUsers(t *testing.T) {
71-
a := infrav1.UserData{
72-
User: "override-user",
73-
RunCmd: []string{"command A", "command B"},
74-
}
75-
b := infrav1.UserData{
76-
User: "test-user",
77-
RunCmd: []string{"command C"},
78-
}
79-
expected := infrav1.UserData{
80-
User: "override-user",
81-
RunCmd: []string{"command A", "command B", "command C"},
82-
}
83-
c, err := cloudinit.MergeUserDatas(&a, &b)
84-
if err != nil {
85-
t.Errorf("failed to merge cloud init user data: %v", err)
86-
}
87-
if !reflect.DeepEqual(*c, expected) {
88-
t.Errorf("%v is expected to same as %v", *c, expected)
89-
}
90-
}
92+
c, err := cloudinit.MergeUserDatas(&a, &b)
93+
Expect(err).NotTo(HaveOccurred())
94+
Expect(*c).To(Equal(expected))
95+
})
96+
})
97+
})

0 commit comments

Comments
 (0)