Skip to content

Commit 2058081

Browse files
sergeyshevchKirill-Garbar
authored andcommitted
feat: Add initial e2e tests
1 parent df56b4d commit 2058081

File tree

8 files changed

+220
-69
lines changed

8 files changed

+220
-69
lines changed

Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ test: manifests generate fmt vet envtest ## Run tests.
8080

8181
# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
8282
.PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up.
83-
test-e2e:
84-
go test ./test/e2e/ -v -ginkgo.v
83+
test-e2e: ginkgo
84+
$(GINKGO) -v ./test/e2e/
8585

8686
.PHONY: lint
8787
lint: golangci-lint ## Run golangci-lint linter & yamllint
@@ -249,6 +249,7 @@ HELM ?= $(LOCALBIN)/helm
249249
HELM_DOCS ?= $(LOCALBIN)/helm-docs
250250
YQ = $(LOCALBIN)/yq
251251
CRD_REF_DOCS ?= $(LOCALBIN)/crd-ref-docs
252+
GINKGO ?= $(LOCALBIN)/ginkgo
252253

253254
## Tool Versions
254255
# renovate: datasource=github-tags depName=kubernetes-sigs/kustomize
@@ -268,6 +269,8 @@ HELM_SCHEMA_VERSION ?= v1.4.1
268269
HELM_DOCS_VERSION ?= v1.13.1
269270
# renovate: datasource=github-tags depName=mikefarah/yq
270271
YQ_VERSION ?= v4.44.1
272+
# renovate: datasource=github-tags depName=onsi/ginkgo
273+
GINKGO_VERSION ?= v2.17.3
271274

272275
## Tool install scripts
273276
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
@@ -298,6 +301,11 @@ golangci-lint: $(LOCALBIN)
298301
@test -x $(GOLANGCI_LINT) && $(GOLANGCI_LINT) version | grep -q $(GOLANGCI_LINT_VERSION) || \
299302
GOBIN=$(LOCALBIN) go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
300303

304+
.PHONY: ginkgo
305+
ginkgo: $(LOCALBIN)
306+
@test -x $(GINKGO) && $(GINKGO) version | grep -q $(GINKGO_VERSION) || \
307+
GOBIN=$(LOCALBIN) go install github.com/onsi/ginkgo/v2/ginkgo@$(GINKGO_VERSION)
308+
301309
.PHONY: nilaway
302310
nilaway: $(LOCALBIN)
303311
@test -x $(NILAWAY_LINT) || GOBIN=$(LOCALBIN) go install go.uber.org/nilaway/cmd/nilaway@latest

go.mod

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ require (
2828
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
2929
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
3030
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
31+
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
3132
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
3233
github.com/fsnotify/fsnotify v1.7.0 // indirect
3334
github.com/go-logr/zapr v1.3.0 // indirect
@@ -42,10 +43,6 @@ require (
4243
github.com/google/go-cmp v0.6.0 // indirect
4344
github.com/google/gofuzz v1.2.0 // indirect
4445
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect
45-
github.com/gorilla/websocket v1.5.0 // indirect
46-
github.com/hashicorp/hcl v1.0.0 // indirect
47-
github.com/imdario/mergo v0.3.6 // indirect
48-
github.com/inconshreveable/mousetrap v1.1.0 // indirect
4946
github.com/josharian/intern v1.0.0 // indirect
5047
github.com/json-iterator/go v1.1.12 // indirect
5148
github.com/magiconair/properties v1.8.7 // indirect
@@ -72,19 +69,6 @@ require (
7269
go.etcd.io/etcd/api/v3 v3.5.14 // indirect
7370
go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect
7471
go.uber.org/multierr v1.11.0 // indirect
75-
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
76-
golang.org/x/net v0.25.0 // indirect
77-
golang.org/x/oauth2 v0.18.0 // indirect
78-
golang.org/x/sys v0.20.0 // indirect
79-
golang.org/x/term v0.20.0 // indirect
80-
golang.org/x/text v0.15.0 // indirect
81-
golang.org/x/time v0.5.0 // indirect
82-
golang.org/x/tools v0.21.0 // indirect
83-
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
84-
google.golang.org/appengine v1.6.8 // indirect
85-
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect
86-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect
87-
google.golang.org/grpc v1.62.1 // indirect
8872
google.golang.org/protobuf v1.33.0 // indirect
8973
gopkg.in/inf.v0 v0.9.1 // indirect
9074
gopkg.in/ini.v1 v1.67.0 // indirect

go.sum

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
1414
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1515
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
1616
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
17-
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
18-
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
1917
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
2018
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
21-
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
22-
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
19+
github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI=
20+
github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
2321
github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=
2422
github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
2523
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
@@ -60,15 +58,6 @@ github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQN
6058
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
6159
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
6260
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
63-
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
64-
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
65-
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
66-
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
67-
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
68-
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
69-
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
70-
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
71-
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
7261
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
7362
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
7463
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -172,7 +161,6 @@ go.uber.org/zap/exp v0.2.0/go.mod h1:t0gqAIdh1MfKv9EwN/dLwfZnJxe9ITAZN78HEWPFWDQ
172161
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
173162
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
174163
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
175-
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
176164
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
177165
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
178166
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -182,10 +170,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
182170
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
183171
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
184172
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
185-
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
186-
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
187-
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
188-
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
189173
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
190174
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
191175
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -207,10 +191,6 @@ golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
207191
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
208192
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
209193
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
210-
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
211-
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
212-
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
213-
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
214194
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
215195
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
216196
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -226,16 +206,6 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
226206
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
227207
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
228208
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
229-
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
230-
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
231-
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ=
232-
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y=
233-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c h1:lfpJ/2rWPa/kJgxyyXM8PrNnfCzcmxJ265mADgwmvLI=
234-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
235-
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
236-
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
237-
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
238-
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
239209
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
240210
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
241211
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -249,6 +219,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
249219
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
250220
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
251221
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
222+
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
252223
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
253224
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
254225
k8s.io/api v0.30.2 h1:+ZhRj+28QT4UOH+BKznu4CBgPWgkXO7XAvMcMl0qKvI=

test/e2e/e2e_test.go

Lines changed: 154 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import (
2020
"fmt"
2121
"os"
2222
"os/exec"
23+
"strconv"
2324
"sync"
25+
"time"
2426

2527
. "github.com/onsi/ginkgo/v2"
2628
. "github.com/onsi/gomega"
@@ -31,6 +33,7 @@ import (
3133
)
3234

3335
var _ = Describe("etcd-operator", Ordered, func() {
36+
dir, _ := utils.GetProjectDir()
3437

3538
BeforeAll(func() {
3639
var err error
@@ -55,7 +58,7 @@ var _ = Describe("etcd-operator", Ordered, func() {
5558
By("wait while etcd-operator is ready", func() {
5659
cmd := exec.Command("kubectl", "wait", "--namespace",
5760
"etcd-operator-system", "deployment/etcd-operator-controller-manager",
58-
"--for", "jsonpath={.status.availableReplicas}=1", "--timeout=5m")
61+
"--for", "jsonpath={.status.readyReplicas}=1", "--timeout=5m")
5962
_, err = utils.Run(cmd)
6063
ExpectWithOffset(1, err).NotTo(HaveOccurred())
6164
})
@@ -73,17 +76,12 @@ var _ = Describe("etcd-operator", Ordered, func() {
7376

7477
Context("Simple", func() {
7578
It("should deploy etcd cluster", func() {
76-
var err error
7779
const namespace = "test-simple-etcd-cluster"
7880
var wg sync.WaitGroup
7981
wg.Add(1)
8082

81-
By("create namespace", func() {
82-
cmd := exec.Command("sh", "-c",
83-
fmt.Sprintf("kubectl create namespace %s --dry-run=client -o yaml | kubectl apply -f -", namespace)) // nolint:lll
84-
_, err = utils.Run(cmd)
85-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
86-
})
83+
CreateNamespace(namespace)
84+
DeferCleanup(DeleteNamespaceCB(namespace))
8785

8886
By("apply simple etcd cluster manifest", func() {
8987
dir, _ := utils.GetProjectDir()
@@ -95,16 +93,9 @@ var _ = Describe("etcd-operator", Ordered, func() {
9593
ExpectWithOffset(1, err).NotTo(HaveOccurred())
9694
})
9795

98-
By("wait for statefulset is ready", func() {
99-
cmd := exec.Command("kubectl", "wait",
100-
"statefulset/test",
101-
"--for", "jsonpath={.status.readyReplicas}=3",
102-
"--namespace", namespace,
103-
"--timeout", "5m",
104-
)
105-
_, err = utils.Run(cmd)
106-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
107-
})
96+
WaitSTSReady("statefulset/test", namespace)
97+
98+
// CheckEtcdClusterHealthy("service/test", namespace)
10899

109100
client, err := utils.GetEtcdClient(ctx, client.ObjectKey{Namespace: namespace, Name: "test"})
110101
Expect(err).NotTo(HaveOccurred())
@@ -187,4 +178,149 @@ var _ = Describe("etcd-operator", Ordered, func() {
187178
})
188179
})
189180

181+
DescribeTable("Upgrade",
182+
func(namespace string, fileName string, version string) {
183+
CreateNamespace(namespace)
184+
DeferCleanup(DeleteNamespaceCB(namespace))
185+
186+
By("apply upgrade etcd cluster manifest")
187+
188+
cmd := exec.Command("kubectl", "apply",
189+
"--filename", dir+fileName,
190+
"--namespace", namespace,
191+
)
192+
_, err := utils.Run(cmd)
193+
194+
ExpectWithOffset(1, err).NotTo(HaveOccurred())
195+
196+
WaitSTSReady("statefulset/test", namespace)
197+
CheckEtcdClusterHealthy("service/test", namespace)
198+
199+
By("upgrade etcd cluster to one patch version")
200+
cmd = exec.Command("kubectl", "patch",
201+
"etcdcluster/test",
202+
"--type", "json",
203+
// Strategic Merge Patch is not currently supported by the etcd-operator
204+
// "--patch",
205+
// fmt.Sprintf(
206+
// "{\"spec\":{\"podTemplate\":{\"containers\":[{\"name\":\"etcd\",\"image\":\"quay.io/coreos/etcd:%s\"}]}}}",
207+
// version,
208+
// ),
209+
"--patch",
210+
fmt.Sprintf(
211+
"[{\"op\": \"replace\", \"path\": \"/spec/podTemplate/spec/containers/0/image\", "+
212+
"\"value\":\"quay.io/coreos/etcd:%s\"}]",
213+
version,
214+
),
215+
"--namespace", namespace,
216+
)
217+
_, err = utils.Run(cmd)
218+
ExpectWithOffset(1, err).NotTo(HaveOccurred())
219+
220+
// Give the operator some time to update the sts
221+
time.Sleep(2 * time.Second)
222+
223+
WaitSTSReady("statefulset/test", namespace)
224+
CheckEtcdClusterHealthy("service/test", namespace)
225+
},
226+
Entry(
227+
"should upgrade etcd cluster patch version",
228+
"test-upgrade-3-5-11--3-5-12",
229+
"/test/e2e/testdata/etcdcluster-3.5.yaml",
230+
"v3.5.12",
231+
),
232+
Entry(
233+
"should downgrade etcd cluster patch version",
234+
"test-downgrade-3-5-11--3-5-10",
235+
"/test/e2e/testdata/etcdcluster-3.5.yaml",
236+
"v3.5.10",
237+
),
238+
Entry(
239+
"should upgrade etcd cluster to one minor version",
240+
"test-upgrade-3-4-32--3-5-10",
241+
"/test/e2e/testdata/etcdcluster-3.4.yaml",
242+
"v3.5.10",
243+
),
244+
Entry(
245+
"should downgrade etcd cluster to one minor version",
246+
"test-downgrade-3-5-11--3-4-32",
247+
"/test/e2e/testdata/etcdcluster-3.5.yaml",
248+
"v3.4.32",
249+
),
250+
Entry(
251+
"should upgrade etcd cluster to multiple minor version",
252+
"test-upgrade-3-3-27--3-5-11",
253+
"/test/e2e/testdata/etcdcluster-3.3.yaml",
254+
"v3.5.11",
255+
),
256+
Entry(
257+
"should downgrade etcd cluster to multiple minor version",
258+
"test-downgrade-3-5-11--3-3-27",
259+
"/test/e2e/testdata/etcdcluster-3.5.yaml",
260+
"v3.3.27",
261+
),
262+
)
263+
190264
})
265+
266+
func DeleteNamespaceCB(namespace string) func() error {
267+
return func() error {
268+
return DeleteNamespace(namespace)
269+
}
270+
}
271+
272+
func DeleteNamespace(namespace string) error {
273+
By("delete namespace")
274+
275+
cmd := exec.Command("kubectl", "delete", "namespace", namespace)
276+
_, err := utils.Run(cmd)
277+
278+
return err
279+
}
280+
281+
func CreateNamespace(namespace string) {
282+
By("create namespace")
283+
284+
cmd := exec.Command("kubectl", "create", "namespace", namespace)
285+
_, err := utils.Run(cmd)
286+
ExpectWithOffset(1, err).NotTo(HaveOccurred())
287+
}
288+
289+
func WaitSTSReady(stsName, namespace string) {
290+
By("wait for statefulset is ready")
291+
292+
cmd := exec.Command("kubectl", "wait",
293+
stsName,
294+
"--for", "jsonpath={.status.availableReplicas}=3",
295+
"--namespace", namespace,
296+
"--timeout", "5m",
297+
)
298+
_, err := utils.Run(cmd)
299+
300+
ExpectWithOffset(1, err).NotTo(HaveOccurred())
301+
}
302+
303+
func CheckEtcdClusterHealthy(serviceName, namespace string) {
304+
var wg sync.WaitGroup
305+
wg.Add(1)
306+
307+
By("port-forward service to localhost")
308+
port, _ := utils.GetFreePort()
309+
go func() {
310+
defer GinkgoRecover()
311+
defer wg.Done()
312+
313+
cmd := exec.Command("kubectl", "port-forward",
314+
serviceName, strconv.Itoa(port)+":2379",
315+
"--namespace", namespace,
316+
)
317+
_, err := utils.Run(cmd)
318+
ExpectWithOffset(1, err).NotTo(HaveOccurred())
319+
}()
320+
321+
By("check etcd cluster is healthy")
322+
endpoints := []string{"localhost:" + strconv.Itoa(port)}
323+
for i := 0; i < 3; i++ {
324+
Expect(utils.IsEtcdClusterHealthy(endpoints)).To(BeTrue())
325+
}
326+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
apiVersion: etcd.aenix.io/v1alpha1
3+
kind: EtcdCluster
4+
metadata:
5+
name: test
6+
spec:
7+
replicas: 3
8+
podTemplate:
9+
spec:
10+
containers:
11+
- name: etcd
12+
image: "quay.io/coreos/etcd:v3.3.27"
13+
# volumes: []
14+
# storage:
15+
# emptyDir: {}

0 commit comments

Comments
 (0)