Skip to content

Commit a21288a

Browse files
author
Mateus Oliveira
authored
fix: must-gather e2e test (#1723)
* fix: must-gather e2e test Signed-off-by: Mateus Oliveira <[email protected]> * fixup! fix: must-gather e2e test Signed-off-by: Mateus Oliveira <[email protected]> * fixup! fixup! fix: must-gather e2e test Signed-off-by: Mateus Oliveira <[email protected]> * fixup! fix: must-gather e2e test Signed-off-by: Mateus Oliveira <[email protected]> * fixup! fix: must-gather e2e test Signed-off-by: Mateus Oliveira <[email protected]> * fixup! fix: must-gather e2e test Signed-off-by: Mateus Oliveira <[email protected]> * fixup! fix: must-gather e2e test Signed-off-by: Mateus Oliveira <[email protected]> --------- Signed-off-by: Mateus Oliveira <[email protected]>
1 parent 2c748ec commit a21288a

File tree

10 files changed

+102
-41
lines changed

10 files changed

+102
-41
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@ debug.test*
4444
must-gather/oadp-must-gather
4545
must-gather/must-gather/
4646
must-gather/must-gather.local.*/
47+
tests/e2e/must-gather/

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ OADP_BUCKET ?= $(shell cat $(OADP_BUCKET_FILE))
539539
SETTINGS_TMP=/tmp/test-settings
540540

541541
.PHONY: test-e2e-setup
542-
test-e2e-setup: login-required
542+
test-e2e-setup: login-required build-must-gather
543543
mkdir -p $(SETTINGS_TMP)
544544
TMP_DIR=$(SETTINGS_TMP) \
545545
OPENSHIFT_CI="$(OPENSHIFT_CI)" \
@@ -590,7 +590,6 @@ test-e2e: test-e2e-setup install-ginkgo ## Run E2E tests against OADP operator i
590590
-velero_namespace=$(OADP_TEST_NAMESPACE) \
591591
-velero_instance_name=$(VELERO_INSTANCE_NAME) \
592592
-artifact_dir=$(ARTIFACT_DIR) \
593-
-oc_cli=$(OC_CLI) \
594593
-kvm_emulation=$(KVM_EMULATION) \
595594
-hco_upstream=$(HCO_UPSTREAM) \
596595
--ginkgo.vv \
@@ -635,3 +634,7 @@ endif
635634
grep -q "\- $$file_name" $(shell pwd)/config/samples/kustomization.yaml || \
636635
$(SED) -i "s%resources:%resources:\n- $$file_name%" $(shell pwd)/config/samples/kustomization.yaml;done
637636
@make bundle
637+
638+
.PHONY: build-must-gather
639+
build-must-gather: ## Build OADP Must-gather binary must-gather/oadp-must-gather
640+
cd must-gather && go build -mod=mod -a -o oadp-must-gather cmd/main.go

must-gather/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ podman push <this-image>
1313
oc adm must-gather --image=<this-image> -- /usr/bin/gather -h
1414
oc adm must-gather --image=<this-image>
1515
```
16-
TODO mention e2e tests!
16+
OADP Must-gather is also tested through OADP E2E tests, being run after test cases and checking if summary does not contain errors and all required objects were collected.
1717

1818
To test omg tool, create `omg.Dockerfile` file
1919
```Dockerfile

must-gather/pkg/cli.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ For more information, check OADP must-gather documentation: https://docs.redhat.
250250
// OADP dev, community and prod operators have same spec.displayName
251251
if csv.Spec.DisplayName == "OADP Operator" {
252252
oadpOperatorsText += fmt.Sprintf("Found **%v** version **%v** installed in **%v** namespace\n\n", csv.Spec.DisplayName, csv.Spec.Version, csv.Namespace)
253-
if (csv.Spec.Version.Major < 1 || csv.Spec.Version.Minor < 5) && major >= 4 && minor >= 19 {
253+
if (csv.Spec.Version.Major < 1 || (csv.Spec.Version.Major == 1 && csv.Spec.Version.Minor < 5)) && major >= 4 && minor >= 19 {
254254
oldOADPError += "❌ OADP 1.4 and lower is not supported in OpenShift 4.19 and higher\n\n"
255255
}
256256
foundOADP = true

must-gather/pkg/templates/summary.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,16 @@ func ReplaceDataProtectionApplicationsSection(outputPath string, dataProtectionA
340340

341341
unsupportedOverridesText := "false"
342342
if dataProtectionApplication.Spec.UnsupportedOverrides != nil {
343-
summaryTemplateReplaces["ERRORS"] += fmt.Sprintf(
344-
"⚠️ DataProtectionApplication **%v** in **%v** namespace is using **unsupportedOverrides**\n\n",
345-
dataProtectionApplication.Name, namespace,
346-
)
347-
unsupportedOverridesText = "⚠️ true"
343+
for _, value := range dataProtectionApplication.Spec.UnsupportedOverrides {
344+
if value != "" {
345+
summaryTemplateReplaces["ERRORS"] += fmt.Sprintf(
346+
"⚠️ DataProtectionApplication **%v** in **%v** namespace is using **unsupportedOverrides**\n\n",
347+
dataProtectionApplication.Name, namespace,
348+
)
349+
unsupportedOverridesText = "⚠️ true"
350+
break
351+
}
352+
}
348353
}
349354

350355
dpaStatus := ""

tests/e2e/backup_restore_suite_test.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,8 @@ func todoListReady(preBackupState bool, twoVol bool, database string) Verificati
4949
})
5050
}
5151

52-
func prepareBackupAndRestore(brCase BackupRestoreCase, updateLastInstallTime func()) (string, string) {
53-
updateLastInstallTime()
54-
55-
err := dpaCR.CreateOrUpdate(dpaCR.Build(brCase.BackupRestoreType))
52+
func waitOADPReadiness(backupRestoreType lib.BackupRestoreType) {
53+
err := dpaCR.CreateOrUpdate(dpaCR.Build(backupRestoreType))
5654
gomega.Expect(err).NotTo(gomega.HaveOccurred())
5755

5856
log.Print("Checking if DPA is reconciled")
@@ -61,7 +59,7 @@ func prepareBackupAndRestore(brCase BackupRestoreCase, updateLastInstallTime fun
6159
log.Printf("Waiting for Velero Pod to be running")
6260
gomega.Eventually(lib.VeleroPodIsRunning(kubernetesClientForSuiteRun, namespace), time.Minute*3, time.Second*5).Should(gomega.BeTrue())
6361

64-
if brCase.BackupRestoreType == lib.RESTIC || brCase.BackupRestoreType == lib.KOPIA || brCase.BackupRestoreType == lib.CSIDataMover {
62+
if backupRestoreType == lib.RESTIC || backupRestoreType == lib.KOPIA || backupRestoreType == lib.CSIDataMover {
6563
log.Printf("Waiting for Node Agent pods to be running")
6664
gomega.Eventually(lib.AreNodeAgentPodsRunning(kubernetesClientForSuiteRun, namespace), time.Minute*3, time.Second*5).Should(gomega.BeTrue())
6765
}
@@ -70,12 +68,18 @@ func prepareBackupAndRestore(brCase BackupRestoreCase, updateLastInstallTime fun
7068

7169
log.Print("Checking if BSL is available")
7270
gomega.Eventually(dpaCR.BSLsAreAvailable(), time.Minute*3, time.Second*5).Should(gomega.BeTrue())
71+
}
72+
73+
func prepareBackupAndRestore(brCase BackupRestoreCase, updateLastInstallTime func()) (string, string) {
74+
updateLastInstallTime()
75+
76+
waitOADPReadiness(brCase.BackupRestoreType)
7377

7478
if brCase.BackupRestoreType == lib.CSI || brCase.BackupRestoreType == lib.CSIDataMover {
7579
if provider == "aws" || provider == "ibmcloud" || provider == "gcp" || provider == "azure" || provider == "openstack" {
7680
log.Printf("Creating VolumeSnapshotClass for CSI backuprestore of %s", brCase.Name)
7781
snapshotClassPath := fmt.Sprintf("./sample-applications/snapclass-csi/%s.yaml", provider)
78-
err = lib.InstallApplication(dpaCR.Client, snapshotClassPath)
82+
err := lib.InstallApplication(dpaCR.Client, snapshotClassPath)
7983
gomega.Expect(err).ToNot(gomega.HaveOccurred())
8084
}
8185
}
@@ -272,7 +276,7 @@ func tearDownBackupAndRestore(brCase BackupRestoreCase, installTime time.Time, r
272276
gomega.Eventually(lib.IsNamespaceDeleted(kubernetesClientForSuiteRun, brCase.Namespace), time.Minute*5, time.Second*5).Should(gomega.BeTrue())
273277
}
274278

275-
var _ = ginkgo.Describe("Backup and restore tests", func() {
279+
var _ = ginkgo.Describe("Backup and restore tests", ginkgo.Ordered, func() {
276280
var lastBRCase ApplicationBackupRestoreCase
277281
var lastInstallTime time.Time
278282
updateLastBRcase := func(brCase ApplicationBackupRestoreCase) {
@@ -286,6 +290,19 @@ var _ = ginkgo.Describe("Backup and restore tests", func() {
286290
tearDownBackupAndRestore(lastBRCase.BackupRestoreCase, lastInstallTime, ctx.SpecReport())
287291
})
288292

293+
var _ = ginkgo.AfterAll(func() {
294+
// DPA just needs to have BSL so gathering of backups/restores logs/describe work
295+
// using kopia to collect more info (DaemonSet)
296+
waitOADPReadiness(lib.KOPIA)
297+
298+
log.Printf("Running OADP must-gather")
299+
err := lib.RunMustGather(artifact_dir, dpaCR.Client)
300+
gomega.Expect(err).ToNot(gomega.HaveOccurred())
301+
302+
err = dpaCR.Delete()
303+
gomega.Expect(err).ToNot(gomega.HaveOccurred())
304+
})
305+
289306
ginkgo.DescribeTable("Backup and restore applications",
290307
func(brCase ApplicationBackupRestoreCase, expectedErr error) {
291308
if ginkgo.CurrentSpecReport().NumAttempts > 1 && !knownFlake {

tests/e2e/e2e_suite_test.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import (
2424

2525
var (
2626
// Common vars obtained from flags passed in ginkgo.
27-
bslCredFile, namespace, instanceName, provider, vslCredFile, settings, artifact_dir, oc_cli string
28-
flakeAttempts int64
27+
bslCredFile, namespace, instanceName, provider, vslCredFile, settings, artifact_dir string
28+
flakeAttempts int64
2929

3030
kubernetesClientForSuiteRun *kubernetes.Clientset
3131
runTimeClientForSuiteRun client.Client
@@ -54,7 +54,6 @@ func init() {
5454
flag.StringVar(&instanceName, "velero_instance_name", "example-velero", "Velero Instance Name")
5555
flag.StringVar(&provider, "provider", "aws", "Cloud provider")
5656
flag.StringVar(&artifact_dir, "artifact_dir", "/tmp", "Directory for storing must gather")
57-
flag.StringVar(&oc_cli, "oc_cli", "oc", "OC CLI Client")
5857
flag.Int64Var(&flakeAttempts, "flakeAttempts", 3, "Customize the number of flake retries (3)")
5958
flag.BoolVar(&kvmEmulation, "kvm_emulation", true, "Enable or disable KVM emulation for virtualization testing")
6059
flag.BoolVar(&useUpstreamHco, "hco_upstream", false, "Force use of upstream virtualization operator")
@@ -84,9 +83,6 @@ func init() {
8483
if os.Getenv("ARTIFACT_DIR") != "" {
8584
artifact_dir = os.Getenv("ARTIFACT_DIR")
8685
}
87-
if os.Getenv("OC_CLI") != "" {
88-
oc_cli = os.Getenv("OC_CLI")
89-
}
9086
if envValue := os.Getenv("FLAKE_ATTEMPTS"); envValue != "" {
9187
// Parse the environment variable as int64
9288
parsedValue, err := strconv.ParseInt(envValue, 10, 64)
@@ -188,12 +184,6 @@ var _ = ginkgo.BeforeSuite(func() {
188184
})
189185

190186
var _ = ginkgo.AfterSuite(func() {
191-
// TODO run OADP must-gather
192-
// log.Printf("Running OADP must-gather")
193-
// err := lib.RunMustGather(oc_cli, artifact_dir)
194-
// gomega.Expect(err).ToNot(gomega.HaveOccurred())
195-
// TODO validate that everything was collected?
196-
197187
log.Printf("Deleting Secrets")
198188
err := lib.DeleteSecret(kubernetesClientForSuiteRun, namespace, vslSecretName)
199189
gomega.Expect(err).ToNot(gomega.HaveOccurred())

tests/e2e/lib/apps.go

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@ import (
88
"log"
99
"os"
1010
"os/exec"
11+
"path/filepath"
1112
"reflect"
1213
"sort"
14+
"strings"
1315
"time"
1416

1517
"github.com/google/go-cmp/cmp"
1618
volumesnapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
1719
"github.com/onsi/ginkgo/v2"
1820
"github.com/onsi/gomega"
1921
ocpappsv1 "github.com/openshift/api/apps/v1"
22+
openshiftconfigv1 "github.com/openshift/api/config/v1"
2023
security "github.com/openshift/api/security/v1"
2124
templatev1 "github.com/openshift/api/template/v1"
2225
"github.com/vmware-tanzu/velero/pkg/label"
@@ -373,18 +376,47 @@ func PrintNamespaceEventsAfterTime(c *kubernetes.Clientset, namespace string, st
373376
}
374377
}
375378

376-
func RunMustGather(oc_cli string, artifact_dir string) error {
377-
ocClient := oc_cli
378-
ocAdmin := "adm"
379-
mustGatherCmd := "must-gather"
380-
// TODO update image
381-
// need to reopen https://github.com/openshift/release/pull/55587
382-
mustGatherImg := "--image=quay.io/konveyor/oadp-must-gather:latest"
383-
destDir := "--dest-dir=" + artifact_dir
384-
385-
cmd := exec.Command(ocClient, ocAdmin, mustGatherCmd, mustGatherImg, destDir)
386-
_, err := cmd.Output()
387-
return err
379+
func RunMustGather(artifact_dir string, clusterClient client.Client) error {
380+
executablePath, err := os.Executable()
381+
if err != nil {
382+
return err
383+
}
384+
385+
_, err = exec.Command(filepath.Dir(filepath.Dir(filepath.Dir(executablePath))) + "/must-gather/oadp-must-gather").Output()
386+
if err != nil {
387+
return err
388+
}
389+
390+
_, err = exec.Command("mv", filepath.Dir(executablePath)+"/must-gather", artifact_dir).Output()
391+
if err != nil {
392+
return err
393+
}
394+
395+
clusterVersionList := &openshiftconfigv1.ClusterVersionList{}
396+
err = clusterClient.List(context.Background(), clusterVersionList)
397+
if err != nil {
398+
return err
399+
}
400+
if len(clusterVersionList.Items) == 0 {
401+
return errors.New("no ClusterVersion found in cluster")
402+
}
403+
clusterVersion := &clusterVersionList.Items[0]
404+
mustGatherPath := fmt.Sprintf("%s/must-gather/clusters/%s/", artifact_dir, string(clusterVersion.Spec.ClusterID[:8]))
405+
406+
mustGatherSummaryContent, err := os.ReadFile(mustGatherPath + "oadp-must-gather-summary.md")
407+
if err != nil {
408+
return err
409+
}
410+
411+
mustGatherSummaryText := string(mustGatherSummaryContent)
412+
413+
if !strings.Contains(mustGatherSummaryText, "No errors happened or were found while running OADP must-gather") {
414+
return errors.New("expected no errors in must-gather Errors section")
415+
}
416+
417+
// TODO validate that everything was collected
418+
419+
return nil
388420
}
389421

390422
// VerifyBackupRestoreData verifies if app ready before backup and after restore to compare data.

tests/e2e/lib/scheme.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
volumesnapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
55
openshiftappsv1 "github.com/openshift/api/apps/v1"
66
openshiftbuildv1 "github.com/openshift/api/build/v1"
7+
openshiftconfigv1 "github.com/openshift/api/config/v1"
78
openshiftroutev1 "github.com/openshift/api/route/v1"
89
openshiftsecurityv1 "github.com/openshift/api/security/v1"
910
openshifttemplatev1 "github.com/openshift/api/template/v1"
@@ -36,4 +37,5 @@ func init() {
3637
_ = operatorsv1.AddToScheme(Scheme)
3738
_ = hypershiftv1.AddToScheme(Scheme)
3839
_ = appsv1.AddToScheme(Scheme)
40+
_ = openshiftconfigv1.AddToScheme(Scheme)
3941
}

tests/e2e/virt_backup_restore_suite_test.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,17 @@ var _ = ginkgo.Describe("VM backup and restore tests", ginkgo.Ordered, func() {
214214
})
215215

216216
var _ = ginkgo.AfterAll(func() {
217+
// DPA just needs to have BSL so gathering of backups/restores logs/describe work
218+
// using kopia to collect more info (DaemonSet)
219+
waitOADPReadiness(lib.KOPIA)
220+
221+
log.Printf("Running OADP must-gather")
222+
err := lib.RunMustGather(artifact_dir, dpaCR.Client)
223+
gomega.Expect(err).ToNot(gomega.HaveOccurred())
224+
225+
err = dpaCR.Delete()
226+
gomega.Expect(err).ToNot(gomega.HaveOccurred())
227+
217228
if v != nil && cirrosDownloadedFromTest {
218229
v.RemoveDataSource(bootImageNamespace, "cirros")
219230
v.RemoveDataVolume(bootImageNamespace, "cirros", 2*time.Minute)
@@ -223,7 +234,7 @@ var _ = ginkgo.Describe("VM backup and restore tests", ginkgo.Ordered, func() {
223234
v.EnsureVirtRemoval()
224235
}
225236

226-
err := v.RemoveStorageClass("test-sc-immediate")
237+
err = v.RemoveStorageClass("test-sc-immediate")
227238
gomega.Expect(err).To(gomega.BeNil())
228239
err = v.RemoveStorageClass("test-sc-wffc")
229240
gomega.Expect(err).To(gomega.BeNil())

0 commit comments

Comments
 (0)