Skip to content

Commit 30c4431

Browse files
hhpatel14kaovilai
authored andcommitted
Two volume backup-restore E2E-test (openshift#864)
1 parent 772fb8b commit 30c4431

File tree

7 files changed

+374
-9
lines changed

7 files changed

+374
-9
lines changed

tests/e2e/backup_restore_suite_test.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"log"
8+
"strings"
89
"time"
910

1011
volsync "github.com/backube/volsync/api/v1alpha1"
@@ -48,11 +49,11 @@ func mongoready(preBackupState bool, backupRestoreType BackupRestoreType) Verifi
4849
if !exists {
4950
return errors.New("did not find Mongo scc")
5051
}
51-
err = VerifyBackupRestoreData(artifact_dir, namespace, "todolist-route", "todolist", preBackupState, backupRestoreType) // TODO: VERIFY PARKS APP DATA
52+
err = VerifyBackupRestoreData(artifact_dir, namespace, "todolist-route", "todolist", preBackupState, false, backupRestoreType) // TODO: VERIFY PARKS APP DATA
5253
return err
5354
})
5455
}
55-
func mysqlReady(preBackupState bool, backupRestoreType BackupRestoreType) VerificationFunction {
56+
func mysqlReady(preBackupState bool, twoVol bool, backupRestoreType BackupRestoreType) VerificationFunction {
5657
return VerificationFunction(func(ocClient client.Client, namespace string) error {
5758
fmt.Printf("checking for the NAMESPACE: %s\n ", namespace)
5859
// This test confirms that SCC restore logic in our plugin is working
@@ -65,7 +66,7 @@ func mysqlReady(preBackupState bool, backupRestoreType BackupRestoreType) Verifi
6566
if !exists {
6667
return errors.New("did not find MYSQL scc")
6768
}
68-
err = VerifyBackupRestoreData(artifact_dir, namespace, "todolist-route", "todolist", preBackupState, backupRestoreType)
69+
err = VerifyBackupRestoreData(artifact_dir, namespace, "todolist-route", "todolist", preBackupState, twoVol, backupRestoreType)
6970
return err
7071
})
7172
}
@@ -237,7 +238,12 @@ var _ = Describe("AWS backup restore tests", func() {
237238
dpaCR.Client.Create(context.Background(), &corev1.Namespace{ObjectMeta: v1.ObjectMeta{Name: brCase.ApplicationNamespace}}, &client.CreateOptions{})
238239
if brCase.BackupRestoreType == CSI || brCase.BackupRestoreType == CSIDataMover {
239240
log.Printf("Creating csi pvc for case %s", brCase.Name)
240-
pvcPath := fmt.Sprintf("./sample-applications/%s/pvc/%s.yaml", brCase.ApplicationNamespace, provider)
241+
var pvcPath string
242+
if strings.Contains(brCase.Name, "twovol") {
243+
pvcPath = fmt.Sprintf("./sample-applications/%s/pvc-twoVol/%s.yaml", brCase.ApplicationNamespace, provider)
244+
} else {
245+
pvcPath = fmt.Sprintf("./sample-applications/%s/pvc/%s.yaml", brCase.ApplicationNamespace, provider)
246+
}
241247
err = InstallApplication(dpaCR.Client, pvcPath)
242248
Expect(err).ToNot(HaveOccurred())
243249
}
@@ -335,8 +341,8 @@ var _ = Describe("AWS backup restore tests", func() {
335341
ApplicationNamespace: "mysql-persistent",
336342
Name: "mysql-csi-e2e",
337343
BackupRestoreType: CSI,
338-
PreBackupVerify: mysqlReady(true, CSI),
339-
PostRestoreVerify: mysqlReady(false, CSI),
344+
PreBackupVerify: mysqlReady(true, false, CSI),
345+
PostRestoreVerify: mysqlReady(false, false, CSI),
340346
}, nil),
341347
Entry("Mongo application CSI", Label("ibmcloud", "aws", "gcp", "azure"), BackupRestoreCase{
342348
ApplicationTemplate: "./sample-applications/mongo-persistent/mongo-persistent-csi.yaml",
@@ -346,6 +352,14 @@ var _ = Describe("AWS backup restore tests", func() {
346352
PreBackupVerify: mongoready(true, CSI),
347353
PostRestoreVerify: mongoready(false, CSI),
348354
}, nil),
355+
Entry("MySQL application two Vol CSI", Label("ibmcloud", "aws", "gcp", "azure"), BackupRestoreCase{
356+
ApplicationTemplate: fmt.Sprintf("./sample-applications/mysql-persistent/mysql-persistent-twovol-csi.yaml"),
357+
ApplicationNamespace: "mysql-persistent",
358+
Name: "mysql-twovol-csi-e2e",
359+
BackupRestoreType: CSI,
360+
PreBackupVerify: mysqlReady(true, true, CSI),
361+
PostRestoreVerify: mysqlReady(false, true, CSI),
362+
}, nil),
349363
Entry("Mongo application RESTIC", BackupRestoreCase{
350364
ApplicationTemplate: "./sample-applications/mongo-persistent/mongo-persistent.yaml",
351365
ApplicationNamespace: "mongo-persistent",
@@ -359,8 +373,8 @@ var _ = Describe("AWS backup restore tests", func() {
359373
ApplicationNamespace: "mysql-persistent",
360374
Name: "mysql-restic-e2e",
361375
BackupRestoreType: RESTIC,
362-
PreBackupVerify: mysqlReady(true, RESTIC),
363-
PostRestoreVerify: mysqlReady(false, RESTIC),
376+
PreBackupVerify: mysqlReady(true, false, RESTIC),
377+
PostRestoreVerify: mysqlReady(false, false, RESTIC),
364378
}, nil),
365379
Entry("Mongo application DATAMOVER", BackupRestoreCase{
366380
ApplicationTemplate: "./sample-applications/mongo-persistent/mongo-persistent-csi.yaml",

tests/e2e/lib/apps.go

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ func makeRequest(request string, api string, todo string) {
449449
}
450450

451451
// VerifyBackupRestoreData verifies if app ready before backup and after restore to compare data.
452-
func VerifyBackupRestoreData(artifact_dir string, namespace string, routeName string, app string, prebackupState bool, backupRestoretype BackupRestoreType) error {
452+
func VerifyBackupRestoreData(artifact_dir string, namespace string, routeName string, app string, prebackupState bool, twoVol bool, backupRestoretype BackupRestoreType) error {
453453
log.Printf("Verifying backup/restore data of %s", app)
454454
appRoute := &routev1.Route{}
455455
clientv1, err := client.New(config.GetConfigOrDie(), client.Options{})
@@ -489,6 +489,8 @@ func VerifyBackupRestoreData(artifact_dir string, namespace string, routeName st
489489
makeRequest("POST", appApi+"/todo", time.Now().Weekday().String())
490490
}
491491
}
492+
volumeApi := appApi + "/log"
493+
492494
switch app {
493495
case "todolist":
494496
appApi += "/todo-incomplete"
@@ -499,6 +501,7 @@ func VerifyBackupRestoreData(artifact_dir string, namespace string, routeName st
499501
if err != nil {
500502
return err
501503
}
504+
502505
//Verifying backup-restore data only for CSI as of now.
503506
if backupRestoretype == CSI || backupRestoretype == CSIDataMover || backupRestoretype == RESTIC {
504507
//check if backupfile exists. If true { compare data response with data from file} (post restore step)
@@ -537,6 +540,62 @@ func VerifyBackupRestoreData(artifact_dir string, namespace string, routeName st
537540
}
538541
}
539542

543+
if twoVol {
544+
volumeFile := artifact_dir + "/volume-data.txt"
545+
return verifyVolume(volumeFile, volumeApi, prebackupState, backupRestoretype)
546+
}
547+
548+
return nil
549+
}
550+
551+
//VerifyVolumeData for application with two volumes
552+
func verifyVolume(volumeFile string, volumeApi string, prebackupState bool, backupRestoretype BackupRestoreType) error {
553+
if prebackupState {
554+
// delete volumeFile if it exists
555+
if _, err := os.Stat(volumeFile); err == nil {
556+
os.Remove(volumeFile)
557+
}
558+
}
559+
//get response Data if response status is 200
560+
volData, err := getResponseData(volumeApi)
561+
if err != nil {
562+
return err
563+
}
564+
if backupRestoretype == CSI || backupRestoretype == RESTIC {
565+
if _, err := os.Stat(volumeFile); err == nil {
566+
volumeBackupData, err := os.ReadFile(volumeFile)
567+
if err != nil {
568+
return err
569+
}
570+
os.Remove(volumeFile)
571+
fmt.Printf("Data came from volume-file\n %s\n", volumeBackupData)
572+
fmt.Printf("Volume Data after restore\n %s\n", volData)
573+
dataIsEqual := false
574+
for i := 0; i < 5 && !dataIsEqual; i++ {
575+
volData, err = getResponseData(volumeApi)
576+
if err != nil {
577+
return err
578+
}
579+
dataIsEqual = bytes.Contains(volData, volumeBackupData)
580+
if dataIsEqual != true {
581+
fmt.Printf("Backup-volume and Restore-volume Data are not equal, retry %d\n", i)
582+
fmt.Printf("volume-Data from the response after restore\n %s\n", volData)
583+
time.Sleep(10 * time.Second)
584+
}
585+
}
586+
if dataIsEqual != true {
587+
return errors.New("Backup and Restore Data are not the same")
588+
}
589+
590+
} else if errors.Is(err, os.ErrNotExist) {
591+
fmt.Printf("Writing data to volumeFile (volume-data.txt): \n %s\n", volData)
592+
err := os.WriteFile(volumeFile, volData, 0644)
593+
if err != nil {
594+
return err
595+
}
596+
}
597+
}
598+
540599
return nil
541600
}
542601

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
apiVersion: v1
2+
kind: List
3+
items:
4+
- kind: Namespace
5+
apiVersion: v1
6+
metadata:
7+
name: mysql-persistent
8+
labels:
9+
app: mysql
10+
- apiVersion: v1
11+
kind: ServiceAccount
12+
metadata:
13+
name: mysql-persistent-sa
14+
namespace: mysql-persistent
15+
labels:
16+
component: mysql-persistent
17+
- kind: SecurityContextConstraints
18+
apiVersion: security.openshift.io/v1
19+
metadata:
20+
name: mysql-persistent-scc
21+
allowPrivilegeEscalation: true
22+
allowPrivilegedContainer: true
23+
runAsUser:
24+
type: RunAsAny
25+
seLinuxContext:
26+
type: RunAsAny
27+
fsGroup:
28+
type: RunAsAny
29+
supplementalGroups:
30+
type: RunAsAny
31+
volumes:
32+
- '*'
33+
users:
34+
- system:admin
35+
- system:serviceaccount:mysql-persistent:mysql-persistent-sa
36+
- apiVersion: v1
37+
kind: Service
38+
metadata:
39+
annotations:
40+
template.openshift.io/expose-uri: mariadb://{.spec.clusterIP}:{.spec.ports[?(.name=="mysql")].port}
41+
name: mysql
42+
namespace: mysql-persistent
43+
labels:
44+
app: mysql
45+
service: mysql
46+
spec:
47+
ports:
48+
- protocol: TCP
49+
name: mysql
50+
port: 3306
51+
selector:
52+
app: mysql
53+
- apiVersion: apps/v1
54+
kind: Deployment
55+
metadata:
56+
annotations:
57+
template.alpha.openshift.io/wait-for-ready: 'true'
58+
name: mysql
59+
namespace: mysql-persistent
60+
labels:
61+
e2e-app: "true"
62+
spec:
63+
selector:
64+
matchLabels:
65+
app: mysql
66+
strategy:
67+
type: Recreate
68+
template:
69+
metadata:
70+
labels:
71+
e2e-app: "true"
72+
app: mysql
73+
spec:
74+
serviceAccountName: mysql-persistent-sa
75+
containers:
76+
- image: registry.redhat.io/rhel8/mariadb-105:latest
77+
name: mysql
78+
securityContext:
79+
privileged: true
80+
env:
81+
- name: MYSQL_USER
82+
value: changeme
83+
- name: MYSQL_PASSWORD
84+
value: changeme
85+
- name: MYSQL_ROOT_PASSWORD
86+
value: root
87+
- name: MYSQL_DATABASE
88+
value: todolist
89+
ports:
90+
- containerPort: 3306
91+
name: mysql
92+
resources:
93+
limits:
94+
memory: 512Mi
95+
volumeMounts:
96+
- name: mysql-data
97+
mountPath: /var/lib/mysql
98+
volumes:
99+
- name: mysql-data
100+
persistentVolumeClaim:
101+
claimName: mysql
102+
- apiVersion: v1
103+
kind: Service
104+
metadata:
105+
name: todolist
106+
namespace: mysql-persistent
107+
labels:
108+
app: todolist
109+
service: todolist
110+
spec:
111+
ports:
112+
- name: web
113+
port: 8000
114+
targetPort: 8000
115+
selector:
116+
app: todolist
117+
service: todolist
118+
- apiVersion: apps.openshift.io/v1
119+
kind: DeploymentConfig
120+
metadata:
121+
name: todolist
122+
namespace: mysql-persistent
123+
labels:
124+
app: todolist
125+
service: todolist
126+
spec:
127+
replicas: 1
128+
selector:
129+
app: todolist
130+
service: todolist
131+
strategy:
132+
type: Recreate
133+
template:
134+
metadata:
135+
labels:
136+
app: todolist
137+
service: todolist
138+
spec:
139+
containers:
140+
- name: todolist
141+
image: quay.io/konveyor/todolist-mariadb-go:v2_4
142+
env:
143+
- name: foo
144+
value: bar
145+
ports:
146+
- containerPort: 8000
147+
protocol: TCP
148+
volumeMounts:
149+
- name: applog
150+
mountPath: /tmp/log/todoapp/
151+
volumes:
152+
- name: applog
153+
persistentVolumeClaim:
154+
claimName: applog
155+
initContainers:
156+
- name: init-myservice
157+
image: registry.access.redhat.com/ubi8/ubi:latest
158+
command: ['sh', '-c', 'sleep 10; until getent hosts mysql; do echo waiting for mysql; sleep 5; done;']
159+
- apiVersion: route.openshift.io/v1
160+
kind: Route
161+
metadata:
162+
name: todolist-route
163+
namespace: mysql-persistent
164+
spec:
165+
path: "/"
166+
to:
167+
kind: Service
168+
name: todolist
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
apiVersion: v1
2+
kind: List
3+
items:
4+
- apiVersion: v1
5+
kind: PersistentVolumeClaim
6+
metadata:
7+
name: mysql
8+
namespace: mysql-persistent
9+
labels:
10+
app: mysql
11+
spec:
12+
accessModes:
13+
- ReadWriteOnce
14+
storageClassName: gp2-csi
15+
resources:
16+
requests:
17+
storage: 1Gi
18+
- apiVersion: v1
19+
kind: PersistentVolumeClaim
20+
metadata:
21+
name: applog
22+
namespace: mysql-persistent
23+
labels:
24+
app: todolist
25+
spec:
26+
accessModes:
27+
- ReadWriteOnce
28+
storageClassName: gp2-csi
29+
resources:
30+
requests:
31+
storage: 1Gi

0 commit comments

Comments
 (0)