From 9321711962f59e61990072d23df21539cc734ff2 Mon Sep 17 00:00:00 2001 From: KeiaiLab-PHIL Date: Sat, 1 Aug 2026 11:24:41 +0900 Subject: [PATCH 1/5] =?UTF-8?q?ci:=20=EC=9E=91=EC=84=B1=EB=8F=BC=20?= =?UTF-8?q?=EC=9E=88=EB=8D=98=20e2e=20=EC=8A=A4=EC=9C=84=ED=8A=B8=EB=A5=BC?= =?UTF-8?q?=20nightly=20=EB=A1=9C=20=EC=8B=A4=ED=96=89=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test/e2e 스위트가 존재하는데 어떤 워크플로도 호출하지 않아 한 번도 게이트가 되지 못했다 (make test-e2e 수동 실행 전용) — 가장 비싸게 만든 테스트가 죽어 있던 셈. PR 이 아니라 nightly 인 이유: kind 생성 + 이미지 빌드 + cert-manager 설치까지 도는 스위트라 PR 지연이 크다. 회귀는 하루 안에 잡히면 충분하고 급할 땐 dispatch 로 즉시 실행한다. 스위트가 BeforeSuite 에서 docker-build/kind load 를 자체 수행하므로 CI 는 kind 바이너리만 설치한다. Signed-off-by: 태환 박 Co-Authored-By: Claude Opus 5 --- .github/workflows/e2e-nightly.yml | 52 +++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/workflows/e2e-nightly.yml diff --git a/.github/workflows/e2e-nightly.yml b/.github/workflows/e2e-nightly.yml new file mode 100644 index 0000000..0bd5f13 --- /dev/null +++ b/.github/workflows/e2e-nightly.yml @@ -0,0 +1,52 @@ +name: e2e (nightly) + +# test/e2e 스위트는 작성돼 있는데 **어떤 워크플로도 호출하지 않아** 한 번도 +# 게이트 역할을 하지 못했다 (`make test-e2e` 수동 실행 전용). 가장 비싼 테스트가 +# 죽어 있던 셈이라 여기서 되살린다. +# +# PR 이 아니라 nightly 인 이유: kind 클러스터 생성 + 이미지 빌드 + cert-manager +# 설치까지 도는 스위트라 PR 지연이 크다. 회귀는 하루 안에 잡히면 충분하고, +# 급할 땐 workflow_dispatch 로 즉시 돌린다. + +on: + schedule: + - cron: "37 18 * * *" # 매일 03:37 KST + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: e2e-${{ github.repository }} + cancel-in-progress: false + +jobs: + e2e: + name: kind e2e + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-go@v6 + with: + go-version-file: go.mod + cache: true + - name: Install kind + run: | + set -euo pipefail + curl -fsSLo /tmp/kind https://kind.sigs.k8s.io/dl/v0.30.0/kind-linux-amd64 + chmod +x /tmp/kind + sudo install /tmp/kind /usr/local/bin/kind + kind version + # 스위트가 BeforeSuite 에서 make docker-build + kind load 를 직접 수행하므로 + # 여기서는 kind 바이너리만 깔면 된다. IMG 는 로컬 빌드·로드 전용이라 + # 레지스트리에 도달할 필요가 없다 — 사설 호스트명 기본값을 피해 중립 태그를 준다. + - name: make test-e2e + env: + IMG: localhost/keiailab/mongodb-operator:e2e-ci + run: make test-e2e + - name: Dump cluster state on failure + if: failure() + run: | + kubectl get pods -A -o wide || true + kubectl describe pods -A | tail -200 || true From fc92b54191f2f9908b45d632fd83487205493305 Mon Sep 17 00:00:00 2001 From: KeiaiLab-PHIL Date: Sat, 1 Aug 2026 11:25:28 +0900 Subject: [PATCH 2/5] =?UTF-8?q?ci:=20e2e=20=EC=9B=8C=ED=81=AC=ED=94=8C?= =?UTF-8?q?=EB=A1=9C=EA=B0=80=20=EC=9E=90=EA=B8=B0=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EC=8B=9C=20PR=20=EC=97=90=EC=84=9C=20=EC=9E=90=EC=B2=B4=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 태환 박 --- .github/workflows/e2e-nightly.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/e2e-nightly.yml b/.github/workflows/e2e-nightly.yml index 0bd5f13..fe7044a 100644 --- a/.github/workflows/e2e-nightly.yml +++ b/.github/workflows/e2e-nightly.yml @@ -12,6 +12,11 @@ on: schedule: - cron: "37 18 * * *" # 매일 03:37 KST workflow_dispatch: + # 이 워크플로 자신을 고칠 때는 PR 에서 실제로 돌려본다 — e2e 배선 변경을 + # 검증 없이 머지하면 nightly 가 조용히 죽는다 (게이트의 자기 감시). + pull_request: + paths: + - ".github/workflows/e2e-nightly.yml" permissions: contents: read From 7a73e7b46ddaa7e8cbc944ca7bbd61734da47cce Mon Sep 17 00:00:00 2001 From: KeiaiLab-PHIL Date: Sat, 1 Aug 2026 11:40:41 +0900 Subject: [PATCH 3/5] =?UTF-8?q?fix(make):=20test-e2e=20=EC=97=90=20-timeou?= =?UTF-8?q?t=20=EC=A7=80=EC=A0=95=20(=EA=B8=B0=EB=B3=B8=2010m=20=E2=86=92?= =?UTF-8?q?=20E2E=5FTIMEOUT=2045m)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit e2e 스위트를 nightly 로 붙여 처음 실행해보니 양 repo 모두 정확히 600.0s 에서 FAIL 했다 — go test 기본 타임아웃 10m. kind 생성 + 이미지 빌드 + cert-manager 설치 + StatefulSet 롤아웃까지 도는 스위트라 이 값으로는 구조적으로 통과가 불가능하다. 스위트가 작성돼 있으면서도 CI 에 한 번도 붙지 못한 실제 이유로 보인다. Signed-off-by: 태환 박 Co-Authored-By: Claude Opus 5 --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 28c4279..149390f 100644 --- a/Makefile +++ b/Makefile @@ -412,9 +412,14 @@ setup-test-e2e: ## Set up a Kind cluster for e2e tests if it does not exist. $(KIND) create cluster --name $(KIND_CLUSTER) --config test/e2e/kind-config.yaml ;; \ esac +# e2e 스위트 타임아웃. go test 기본값은 10m 인데 이 스위트는 kind 생성 + 이미지 빌드 + +# cert-manager 설치 + StatefulSet 롤아웃까지 도느라 항상 그 벽에 걸렸다 — 스위트가 작성돼 +# 있으면서도 CI 에 한 번도 붙지 못한 실제 이유다. +E2E_TIMEOUT ?= 45m + .PHONY: test-e2e test-e2e: setup-test-e2e manifests generate fmt vet ## Run e2e tests against the Kind cluster. - KIND=$(KIND) KIND_CLUSTER=$(KIND_CLUSTER) go test -tags=e2e ./test/e2e/ -v -ginkgo.v + KIND=$(KIND) KIND_CLUSTER=$(KIND_CLUSTER) go test -tags=e2e ./test/e2e/ -v -ginkgo.v -timeout $(E2E_TIMEOUT) $(MAKE) cleanup-test-e2e .PHONY: cleanup-test-e2e From 6d67cc2393b2d6cf96f49815bcf50646b9c7d1bf Mon Sep 17 00:00:00 2001 From: KeiaiLab-PHIL Date: Sat, 1 Aug 2026 11:41:09 +0900 Subject: [PATCH 4/5] =?UTF-8?q?ci:=20e2e=20=EC=9E=90=EA=B8=B0=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EB=8C=80=EC=83=81=EC=97=90=20Makefile=20=ED=8F=AC?= =?UTF-8?q?=ED=95=A8=20(test-e2e=20=EB=A0=88=EC=8B=9C=ED=94=BC=EA=B0=80=20?= =?UTF-8?q?=EA=B1=B0=EA=B8=B0=20=EC=9E=88=EB=8B=A4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 태환 박 --- .github/workflows/e2e-nightly.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e-nightly.yml b/.github/workflows/e2e-nightly.yml index fe7044a..d2876e6 100644 --- a/.github/workflows/e2e-nightly.yml +++ b/.github/workflows/e2e-nightly.yml @@ -17,6 +17,7 @@ on: pull_request: paths: - ".github/workflows/e2e-nightly.yml" + - "Makefile" # test-e2e 레시피(타임아웃·kind 변수)가 여기 산다 permissions: contents: read From 88f8118c42a168b1795ee566653ee3500c68c4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=83=9C=ED=99=98=20=EB=B0=95?= Date: Sat, 1 Aug 2026 12:41:18 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix(e2e):=20CRD+operator=20=EC=84=A4?= =?UTF-8?q?=EC=B9=98=EB=A5=BC=20BeforeSuite=20=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20(=EC=88=9C=EC=84=9C=20=EC=9D=98=EC=A1=B4=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit e2e 를 nightly 로 처음 CI 에 붙여 실행하니 19 Passed / 10 Failed 였고, 실패 10 건은 전부 같은 클래스였다 — `no matches for kind "MongoDB" in version "...v1alpha1"`, 즉 CRD 가 없는 클러스터에 CR 을 apply. 원인은 `make deploy` 가 search_test.go 의 BeforeAll 에만 있었다는 것("self-contained" 주석). Ginkgo 는 최상위 컨테이너 순서를 무작위화하므로, search 컨테이너보다 먼저 뽑힌 컨테이너는 CRD 없이 돌아 죽는다. 스위트가 통과하느냐가 난수에 달려 있던 셈이다. 설치를 BeforeSuite 로 올려 모든 spec 이 CRD+operator 를 전제할 수 있게 한다. search_test 의 중복 deploy 는 제거(설치는 이제 스위트 1회). verify: - go vet -tags=e2e ./test/e2e/ → exit 0 - gofmt -l test/e2e/ → 출력 없음 Signed-off-by: 태환 박 Co-Authored-By: Claude Opus 5 --- test/e2e/e2e_suite_test.go | 13 +++++++++++++ test/e2e/search_test.go | 10 +++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index 7289967..1f331e1 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -65,6 +65,19 @@ var _ = BeforeSuite(func() { configureKubectlKubeRC() setupCertManager() + + // CRD + operator 설치는 **모든 spec 보다 먼저** 일어나야 한다. + // 구 구조는 search_test.go 의 BeforeAll 에서만 `make deploy` 를 했는데, + // Ginkgo 는 최상위 컨테이너 순서를 무작위화하므로 그보다 먼저 뽑힌 컨테이너는 + // CRD 가 없는 클러스터에 CR 을 apply 하다 `no matches for kind "MongoDB"` 로 + // 죽었다 (첫 CI 실행: 19 Passed / 10 Failed — 전부 이 클래스). + By("deploying CRDs + operator (make deploy)") + _, err = utils.Run(exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", managerImage))) + ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to deploy CRDs + operator") + + By("waiting for controller-manager rollout (best-effort)") + _, _ = utils.Run(exec.Command("kubectl", "-n", "mongodb-operator-system", "rollout", "status", + "deploy/mongodb-operator-controller-manager", "--timeout=150s")) }) var _ = AfterSuite(func() { diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index c29ef61..552b1f5 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -53,12 +53,8 @@ const ( var _ = Describe("MongoDBSearch $vectorSearch Round-Trip (PR5)", Ordered, func() { BeforeAll(func() { - By("deploying operator (make deploy — self-contained)") - _, err := utils.Run(exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", managerImage))) - Expect(err).NotTo(HaveOccurred(), "make deploy") - By("waiting for operator controller-manager rollout (best-effort)") - _, _ = utils.Run(exec.Command("kubectl", "-n", "mongodb-operator-system", "rollout", "status", - "deploy/mongodb-operator-controller-manager", "--timeout=150s")) + // operator/CRD 설치는 BeforeSuite 로 이동했다 — 여기서만 하면 Ginkgo 의 + // 컨테이너 순서 무작위화 때문에 다른 spec 이 CRD 없이 돌 수 있다. By("pre-caching mongot image on the kind node (avoid slow Docker Hub pull inside the timed spec)") // mongot 이미지(~1.3GB)를 노드 containerd 에 미리 적재한다. 핀된 :0.69.1(IfNotPresent)가 이 @@ -109,7 +105,7 @@ spec: `, searchMongoName, searchNS, searchCRName, searchNS, searchMongoName) cmd := exec.Command("kubectl", "apply", "-f", "-") cmd.Stdin = strings.NewReader(manifest) - _, err = utils.Run(cmd) + _, err := utils.Run(cmd) Expect(err).NotTo(HaveOccurred(), "MongoDB + MongoDBSearch apply") })