Skip to content

Commit 85dfd70

Browse files
committed
Scaffolding for e2e tests
1 parent 7e061ed commit 85dfd70

7 files changed

Lines changed: 392 additions & 4 deletions

File tree

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
REPO?=quay.io/quay/dba-operator
2+
TAG?=$(shell git rev-parse --short HEAD)
13

24
# Image URL to use all building/pushing image targets
35
IMG ?= ${REPO}:${TAG}
4-
DB_IMG ?= mysql/mysqlserver:latest
6+
DB_IMG ?= mysql/mysql-server:latest
57

68
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
79
CRD_OPTIONS ?= "crd:trivialVersions=true"

scripts/minikube.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ export MINIKUBE_VERSION=${MINIKUBE_VERSION:-v1.2.0}
88
export KUBERNETES_VERSION=${KUBERNETES_VERSION:-v1.15.2}
99
export KUBECONFIG=${KUBECONFIG:-$HOME/.kube/config}
1010

11+
export REPO=${REPO:-quay.io/quay/dba-operator}
12+
export TAG=${TAG:-$(git rev-parse --short HEAD)}
13+
1114

1215
kubectl > /dev/null || { curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/$KUBERNETES_VERSION/bin/linux/amd64/kubectl && \
1316
chmod +x kubectl && \
@@ -18,6 +21,7 @@ minikube > /dev/null || { curl -Lo minikube https://storage.googleapis.com/minik
1821
sudo mv minikube /usr/local/bin/ ;}
1922

2023

24+
# Create a minikube instance
2125
minikube_create() {
2226
minikube version | awk '{ print $3 }' | grep -q "$MINIKUBE_VERSION" || { echo "Wrong minikube version"; exit 1; }
2327

@@ -29,14 +33,16 @@ minikube_create() {
2933
kubectl config use-context minikube
3034
}
3135

36+
# Delete the minikube instance
3237
minikube_delete() {
3338
minikube delete
3439
}
3540

41+
# Build the operator image in the minikube's docker context
3642
build_image() {
3743
eval "$(minikube docker-env)" || { echo 'Cannot switch to minikube docker'; exit 1; }
38-
make manager
39-
docker build -f Dockerfile.e2e -t quay.io/quay/dba-operator:local .
44+
GOOS=linux GOARCH=amd64 make manager
45+
docker build -f Dockerfile.e2e -t $REPO:$TAG .
4046
}
4147

4248

scripts/run-e2e-local.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ SCRIPTS_DIR=$(dirname "${BASH_SOURCE[0]}")
1515

1616
"${SCRIPTS_DIR}"/minikube.sh build-image
1717

18-
make install # Install the genereated CRDs manifest in the cluster
18+
make install || true # Install the genereated CRDs manifest in the cluster
1919
make test-e2e-local # Run the tests
2020

2121
"${SCRIPTS_DIR}"/minikube.sh delete-minikube

test/e2e/framework_test.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package e2e
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strconv"
7+
"strings"
8+
"testing"
9+
"time"
10+
11+
"golang.org/x/sync/errgroup"
12+
13+
"sigs.k8s.io/controller-runtime/pkg/client"
14+
"sigs.k8s.io/controller-runtime/pkg/client/config"
15+
16+
"github.com/app-sre/dba-operator/pkg/dbadmin"
17+
)
18+
19+
var ()
20+
21+
type finalizerFn func() error
22+
23+
type TestFramework struct {
24+
client.Client
25+
admin dbadmin.DbAdmin
26+
}
27+
28+
func New(operatorImage string) (*TestFramework, error) {
29+
c, err := client.New(config.GetConfigOrDie(), client.Options{})
30+
if err != nil {
31+
return nil, nil
32+
}
33+
34+
return &TestFramework{
35+
Client: c,
36+
}, nil
37+
}
38+
39+
// Create a new test context with the test's name and the current time as its ID.
40+
// The ID will be used for creating objects, such as creating a namespace for the test.
41+
func (tf *TestFramework) NewTestCtx(t *testing.T) TestCtx {
42+
prefix := strings.TrimPrefix(
43+
strings.ReplaceAll(
44+
strings.ToLower(t.Name()),
45+
"/",
46+
"-",
47+
),
48+
"test",
49+
)
50+
51+
id := prefix + "-" + strconv.FormatInt(time.Now().Unix(), 36)
52+
return TestCtx{
53+
ID: id,
54+
}
55+
}
56+
57+
type TestCtx struct {
58+
ID string
59+
cleanupFns []finalizerFn
60+
ctx context.Context
61+
}
62+
63+
func (tctx *TestCtx) Cleanup(t *testing.T) {
64+
var eg errgroup.Group
65+
66+
for i := len(tctx.cleanupFns) - 1; i >= 0; i-- {
67+
eg.Go(tctx.cleanupFns[i])
68+
}
69+
70+
if err := eg.Wait(); err != nil {
71+
t.Fatal(err)
72+
}
73+
}
74+
75+
func (tctx *TestCtx) AddFinalizerFn(fn finalizerFn) {
76+
tctx.cleanupFns = append(tctx.cleanupFns, fn)
77+
}
78+
79+
func (tctx *TestCtx) CreateNamespace(t *testing.T, c client.Client) string {
80+
name := tctx.ID
81+
if err := CreateNamespace(tctx.ctx, c, name); err != nil {
82+
t.Fatal(err)
83+
}
84+
85+
namespaceCleanupFn := func() error {
86+
return DeleteNamespace(tctx.ctx, c, name)
87+
}
88+
89+
tctx.AddFinalizerFn(namespaceCleanupFn)
90+
91+
return name
92+
}
93+
94+
func (tctx *TestCtx) CreateDbaOperator(c client.Client, operatorImage string) error {
95+
deployment, err := MakeDeployment("../../deploy/dba-operator.yaml")
96+
if err != nil {
97+
return err
98+
}
99+
100+
if operatorImage != "" {
101+
repoTag := strings.Split(operatorImage, ":")
102+
if len(repoTag) != 2 {
103+
return fmt.Errorf("invalid operator image '%s'", operatorImage)
104+
}
105+
106+
deployment.Spec.Template.Spec.Containers[0].Image = operatorImage
107+
}
108+
109+
err = CreateDeployment(tctx.ctx, c, tctx.ID, deployment)
110+
if err != nil {
111+
return err
112+
}
113+
114+
return nil
115+
}
116+
117+
func (tctx *TestCtx) CreateDB(c client.Client, image string) error {
118+
deployment, err := MakeDeployment("../../deploy/debug.yaml")
119+
if err != nil {
120+
return err
121+
}
122+
123+
if image != "" {
124+
repoTag := strings.Split(image, ":")
125+
if len(repoTag) != 2 {
126+
return fmt.Errorf("invalid operator image '%s'", image)
127+
}
128+
129+
deployment.Spec.Template.Spec.Containers[0].Image = image
130+
}
131+
132+
err = CreateDeployment(tctx.ctx, c, tctx.ID, deployment)
133+
if err != nil {
134+
return err
135+
}
136+
137+
return nil
138+
}

test/e2e/migration_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package e2e
2+
3+
import "testing"
4+
5+
func TestBasicMigration(t *testing.T) {
6+
ctx := testFramework.NewTestCtx(t)
7+
// defer ctx.Cleanup(t)
8+
9+
ctx.CreateNamespace(t, testFramework.Client)
10+
11+
err := ctx.CreateDB(testFramework.Client, *dbImage)
12+
if err != nil {
13+
t.Fatal(err)
14+
}
15+
16+
err = ctx.CreateDbaOperator(testFramework.Client, *operatorImage)
17+
if err != nil {
18+
t.Fatal(err)
19+
}
20+
21+
// TODO
22+
}

test/e2e/setup_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package e2e
2+
3+
import (
4+
"flag"
5+
"log"
6+
"os"
7+
"testing"
8+
)
9+
10+
var (
11+
testFramework *TestFramework
12+
operatorImage *string
13+
dbImage *string
14+
)
15+
16+
func TestMain(m *testing.M) {
17+
operatorImage = flag.String(
18+
"operator-image",
19+
"",
20+
"operator image, e.g. quay.io/quay/dba-operator:v1.0.0",
21+
)
22+
dbImage = flag.String(
23+
"db-image",
24+
"",
25+
"db image, e.g. mysql/mysql-server:latest",
26+
)
27+
flag.Parse()
28+
29+
var err error
30+
if testFramework, err = New(*operatorImage); err != nil {
31+
log.Printf("failed to setup testFramework: %s", err)
32+
os.Exit(1)
33+
}
34+
35+
exitCode := m.Run()
36+
os.Exit(exitCode)
37+
}

0 commit comments

Comments
 (0)