Skip to content

Commit

Permalink
ci, test/e2e: multik8s: parallelize tests on CI
Browse files Browse the repository at this point in the history
Signed-off-by: Ryotaro Banno <[email protected]>
  • Loading branch information
ushitora-anqou committed Jan 8, 2025
1 parent ae30150 commit 3c479d6
Show file tree
Hide file tree
Showing 15 changed files with 1,289 additions and 1,184 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/e2e-multiple-k8s-clusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ concurrency:

jobs:
build:
strategy:
matrix:
package:
- replication
- changetostandalone
- changetoprimary
- changetosecondary
#runs-on: "ubuntu-22.04"
runs-on: mantle_large_runner_16core
steps:
Expand All @@ -29,4 +36,4 @@ jobs:
- run: sudo apt-get update
- uses: ./.github/actions/set-up-kvm-for-e2e-tests
- run: make -C test/e2e setup
- run: make -C test/e2e test-multiple-k8s-clusters
- run: make -C test/e2e test-multiple-k8s-clusters TEST_MULTIK8S_PACKAGES=${{ matrix.package }}
3 changes: 2 additions & 1 deletion test/e2e/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ LOOP_DEV2 := /dev/loop1
MINIKUBE_PROFILE_PRIMARY=profile1
MINIKUBE_PROFILE_SECONDARY=profile2
TMPDIR := tmp
TEST_MULTIK8S_PACKAGES := replication changetostandalone changetoprimary changetosecondary

export MINIKUBE_HOME

Expand Down Expand Up @@ -240,4 +241,4 @@ do-test-multik8s: $(GINKGO)
E2ETEST=1 \
KUBECTL_PRIMARY="$(MINIKUBE) -p $(MINIKUBE_PROFILE_PRIMARY) kubectl -- " \
KUBECTL_SECONDARY="$(MINIKUBE) -p $(MINIKUBE_PROFILE_SECONDARY) kubectl -- " \
$(GINKGO) --fail-fast -v $(GINKGO_FLAGS) multik8s
$(GINKGO) --fail-fast -v $(GINKGO_FLAGS) $(addprefix multik8s/, $(TEST_MULTIK8S_PACKAGES))
122 changes: 122 additions & 0 deletions test/e2e/multik8s/changetoprimary/suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package changetoprimary

import (
"context"
"os"
"testing"
"time"

"github.com/cybozu-go/mantle/internal/controller"
. "github.com/cybozu-go/mantle/test/e2e/multik8s/testutil"
"github.com/cybozu-go/mantle/test/util"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestMtest(t *testing.T) {
if os.Getenv("E2ETEST") == "" {
t.Skip("Run under e2e/")
}

RegisterFailHandler(Fail)

SetDefaultEventuallyPollingInterval(time.Second)
SetDefaultEventuallyTimeout(3 * time.Minute)
EnforceDefaultTimeoutsWhenUsingContexts()

RunSpecs(t, "replication test with multiple k8s clusters")
}

var _ = Describe("Mantle", func() {
Context("wait controller to be ready", WaitControllerToBeReady)
Context("change to primary", changeToPrimary)
})

func changeToPrimary() {
Describe("change to primary", func() {
var (
namespace string
pvcName0, backupName00, backupName01, writtenDataHash00, writtenDataHash01 string
pvcName1, backupName10, writtenDataHash10 string
)

/*
Overview of the test:
primary k8s cluster | secondary k8s cluster
============================|==========================
role=primary | role=secondary
PVC0, MB00 (created) |
| PVC0, MB00 (synced)
role=standalone (changed) |
MB01, PVC1, MB10 (created)|
role=primary (changed) |
| MB01, PVC1, MB10 (synced)
*/

It("should replicate a MantleBackup resource", func(ctx context.Context) {
namespace = util.GetUniqueName("ns-")
pvcName0 = util.GetUniqueName("pvc-")
backupName00 = util.GetUniqueName("mb-")

SetupEnvironment(namespace)
CreatePVC(ctx, PrimaryK8sCluster, namespace, pvcName0)
writtenDataHash00 = WriteRandomDataToPV(ctx, PrimaryK8sCluster, namespace, pvcName0)
CreateMantleBackup(PrimaryK8sCluster, namespace, pvcName0, backupName00)
WaitMantleBackupSynced(namespace, backupName00)
})

It("should change the role from primary to standalone", func() {
By("changing the primary mantle to standalone")
err := ChangeClusterRole(PrimaryK8sCluster, controller.RoleStandalone)
Expect(err).NotTo(HaveOccurred())
})

It("should restore the synced MantleBackup in the both clusters", func(ctx context.Context) {
restoreName00 := util.GetUniqueName("mr-")
EnsureCorrectRestoration(PrimaryK8sCluster, ctx, namespace, backupName00, restoreName00, writtenDataHash00)
EnsureCorrectRestoration(SecondaryK8sCluster, ctx, namespace, backupName00, restoreName00, writtenDataHash00)
})

It("should create a MantleBackup resource", func(ctx SpecContext) {
backupName01 = util.GetUniqueName("mb-")
writtenDataHash01 = WriteRandomDataToPV(ctx, PrimaryK8sCluster, namespace, pvcName0)

CreateMantleBackup(PrimaryK8sCluster, namespace, pvcName0, backupName01)

pvcName1 = util.GetUniqueName("pvc-")
backupName10 = util.GetUniqueName("mb-")

Eventually(func() error {
return ApplyPVCTemplate(PrimaryK8sCluster, namespace, pvcName1)
}).Should(Succeed())
writtenDataHash10 = WriteRandomDataToPV(ctx, PrimaryK8sCluster, namespace, pvcName1)
CreateMantleBackup(PrimaryK8sCluster, namespace, pvcName1, backupName10)
})

It("should change the role from standalone to primary", func() {
By("changing the standalone mantle to primary")
err := ChangeClusterRole(PrimaryK8sCluster, controller.RolePrimary)
Expect(err).NotTo(HaveOccurred())
})

It("should synchronize MantleBackups correctly", func() {
WaitMantleBackupSynced(namespace, backupName01)
WaitMantleBackupSynced(namespace, backupName10)
})

It("should restore MantleBackups correctly", func(ctx SpecContext) {
restoreName00 := util.GetUniqueName("mr-")
EnsureCorrectRestoration(PrimaryK8sCluster, ctx, namespace, backupName00, restoreName00, writtenDataHash00)
EnsureCorrectRestoration(SecondaryK8sCluster, ctx, namespace, backupName00, restoreName00, writtenDataHash00)

restoreName01 := util.GetUniqueName("mr-")
EnsureCorrectRestoration(PrimaryK8sCluster, ctx, namespace, backupName01, restoreName01, writtenDataHash01)
EnsureCorrectRestoration(SecondaryK8sCluster, ctx, namespace, backupName01, restoreName01, writtenDataHash01)

restoreName10 := util.GetUniqueName("mr-")
EnsureCorrectRestoration(PrimaryK8sCluster, ctx, namespace, backupName10, restoreName10, writtenDataHash10)
EnsureCorrectRestoration(SecondaryK8sCluster, ctx, namespace, backupName10, restoreName10, writtenDataHash10)
})
})
}
152 changes: 152 additions & 0 deletions test/e2e/multik8s/changetosecondary/suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package changetosecondary

import (
"context"
"os"
"testing"
"time"

"github.com/cybozu-go/mantle/internal/controller"
. "github.com/cybozu-go/mantle/test/e2e/multik8s/testutil"
"github.com/cybozu-go/mantle/test/util"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestMtest(t *testing.T) {
if os.Getenv("E2ETEST") == "" {
t.Skip("Run under e2e/")
}

RegisterFailHandler(Fail)

SetDefaultEventuallyPollingInterval(time.Second)
SetDefaultEventuallyTimeout(3 * time.Minute)
EnforceDefaultTimeoutsWhenUsingContexts()

RunSpecs(t, "replication test with multiple k8s clusters")
}

var _ = Describe("Mantle", func() {
Context("wait controller to be ready", WaitControllerToBeReady)
Context("change to secondary", changeToSecondary)
})

func changeToSecondary() {
Describe("change to secondary", func() {
var (
namespace string
pvcName0, backupName00, writtenDataHash00 string
pvcName1, backupName10, writtenDataHash10 string
pvcName2, backupName20, backupName21, writtenDataHash20, writtenDataHash21 string
)

/*
Overview of the test:
primary k8s cluster | secondary k8s cluster
===========================|==========================
role=primary | role=secondary
PVC0, MB00 (created) |
| PVC0, MB00 (synced)
| role=standalone (changed)
| PVC1, MB10 (created)
(MB10 don't exist) |
| role=secondary (changed)
PVC2, MB20 (created) |
| PVC2, MB20 (synced)
MB21 (created) |
| MB21 (synced)
(MB10 don't exist) |
*/

It("should set up the environment", func(ctx context.Context) {
namespace = util.GetUniqueName("ns-")
pvcName0 = util.GetUniqueName("pvc-")
backupName00 = util.GetUniqueName("mb-")
pvcName1 = util.GetUniqueName("pvc-")
backupName10 = util.GetUniqueName("mb-")
pvcName2 = util.GetUniqueName("pvc-")
backupName20 = util.GetUniqueName("mb-")
backupName21 = util.GetUniqueName("mb-")

SetupEnvironment(namespace)
})

It("should create and restore a MantleBackup resource", func(ctx context.Context) {
CreatePVC(ctx, PrimaryK8sCluster, namespace, pvcName0)

writtenDataHash00 = WriteRandomDataToPV(ctx, PrimaryK8sCluster, namespace, pvcName0)
CreateMantleBackup(PrimaryK8sCluster, namespace, pvcName0, backupName00)
WaitMantleBackupSynced(namespace, backupName00)

restoreName00 := util.GetUniqueName("mr-")
EnsureCorrectRestoration(PrimaryK8sCluster, ctx, namespace, backupName00, restoreName00, writtenDataHash00)
EnsureCorrectRestoration(SecondaryK8sCluster, ctx, namespace, backupName00, restoreName00, writtenDataHash00)
})

It("should change the role from secondary to standalone", func() {
By("changing the secondary mantle to standalone")
err := ChangeClusterRole(SecondaryK8sCluster, controller.RoleStandalone)
Expect(err).NotTo(HaveOccurred())
})

It("should restore the synced MantleBackup in the both clusters", func(ctx context.Context) {
restoreName00 := util.GetUniqueName("mr-")
EnsureCorrectRestoration(PrimaryK8sCluster, ctx, namespace, backupName00, restoreName00, writtenDataHash00)
EnsureCorrectRestoration(SecondaryK8sCluster, ctx, namespace, backupName00, restoreName00, writtenDataHash00)
})

It("should create a MantleBackup resource in the secondary k8s cluster", func(ctx context.Context) {
CreatePVC(ctx, SecondaryK8sCluster, namespace, pvcName1)
writtenDataHash10 = WriteRandomDataToPV(ctx, SecondaryK8sCluster, namespace, pvcName1)
CreateMantleBackup(SecondaryK8sCluster, namespace, pvcName1, backupName10)
WaitMantleBackupReadyToUse(SecondaryK8sCluster, namespace, backupName10)
})

It("should ensure the MantleBackup created by standalone mantle doesn't exist in the primary k8s cluster",
func(ctx context.Context) {
EnsureMantleBackupNotExist(ctx, PrimaryK8sCluster, namespace, backupName10)
})

It("should change the role from standalone to secondary", func() {
By("changing the standalone mantle to secondary")
err := ChangeClusterRole(SecondaryK8sCluster, controller.RoleSecondary)
Expect(err).NotTo(HaveOccurred())
})

It("should create and synchronize new MantleBackup resources", func(ctx SpecContext) {
CreatePVC(ctx, PrimaryK8sCluster, namespace, pvcName2)

writtenDataHash20 = WriteRandomDataToPV(ctx, PrimaryK8sCluster, namespace, pvcName2)
CreateMantleBackup(PrimaryK8sCluster, namespace, pvcName2, backupName20)
WaitMantleBackupSynced(namespace, backupName20)

writtenDataHash21 = WriteRandomDataToPV(ctx, PrimaryK8sCluster, namespace, pvcName2)
CreateMantleBackup(PrimaryK8sCluster, namespace, pvcName2, backupName21)
WaitMantleBackupSynced(namespace, backupName21)
})

It("should restore MantleBackups correctly", func(ctx SpecContext) {
restoreName00 := util.GetUniqueName("mr-")
EnsureCorrectRestoration(PrimaryK8sCluster, ctx, namespace, backupName00, restoreName00, writtenDataHash00)
EnsureCorrectRestoration(SecondaryK8sCluster, ctx, namespace, backupName00, restoreName00, writtenDataHash00)

restoreName10 := util.GetUniqueName("mr-")
EnsureCorrectRestoration(SecondaryK8sCluster, ctx, namespace, backupName10, restoreName10, writtenDataHash10)

restoreName20 := util.GetUniqueName("mr-")
EnsureCorrectRestoration(PrimaryK8sCluster, ctx, namespace, backupName20, restoreName20, writtenDataHash20)
EnsureCorrectRestoration(SecondaryK8sCluster, ctx, namespace, backupName20, restoreName20, writtenDataHash20)

restoreName21 := util.GetUniqueName("mr-")
EnsureCorrectRestoration(PrimaryK8sCluster, ctx, namespace, backupName21, restoreName21, writtenDataHash21)
EnsureCorrectRestoration(SecondaryK8sCluster, ctx, namespace, backupName21, restoreName21, writtenDataHash21)
})

It("should ensure the MantleBackup created by standalone mantle doesn't exist in the primary k8s cluster",
func(ctx context.Context) {
EnsureMantleBackupNotExist(ctx, PrimaryK8sCluster, namespace, backupName10)
})
})
}
Loading

0 comments on commit 3c479d6

Please sign in to comment.