plugin-barman-cloud/test/e2e/internal/tests/backup/backup_restore.go
Marco Nenciarini db6b1818c5
fix(e2e): use runtime Skip for GCS tests instead of removing them
Deleting the GCS Entry() calls dropped e2e coverage permanently and
left the GCS factory types and fakegcsserver.go referenced nowhere.
Ginkgo's --fail-on-pending forbids Pending/XEntry, but a runtime
Skip() inside the shared spec body avoids that check while keeping
the factories wired up, making it easier to notice and re-enable the
tests once EnterpriseDB/barman#1218 is fixed.

Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
2026-09-02 11:05:27 +02:00

219 lines
6.9 KiB
Go

/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package backup
import (
"fmt"
"time"
v1 "github.com/cloudnative-pg/api/pkg/api/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
internalClient "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/client"
internalCluster "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/cluster"
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/command"
nmsp "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/namespace"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Backup and restore", func() {
var namespace *corev1.Namespace
var cl client.Client
BeforeEach(func(ctx SpecContext) {
var err error
cl, _, err = internalClient.NewClient()
Expect(err).NotTo(HaveOccurred())
namespace, err = nmsp.CreateUniqueNamespace(ctx, cl, "backup-restore")
Expect(err).NotTo(HaveOccurred())
})
AfterEach(func(ctx SpecContext) {
Expect(cl.Delete(ctx, namespace)).To(Succeed())
})
DescribeTable("should backup and restore a cluster",
func(
ctx SpecContext,
factory testCaseFactory,
) {
switch factory.(type) {
case *gcsBackupPluginBackupPluginRestore, *gcsBackupPluginBackupInTreeRestore,
*gcsBackupPluginInTreeBackupPluginRestore:
Skip("GCS e2e tests are disabled until https://github.com/EnterpriseDB/barman/issues/1218 is fixed")
}
testResources := factory.createBackupRestoreTestResources(namespace.Name)
By("starting the ObjectStore deployment")
Expect(testResources.ObjectStoreResources.Create(ctx, cl)).To(Succeed())
By("creating the ObjectStore")
Expect(cl.Create(ctx, testResources.ObjectStore)).To(Succeed())
By("Creating a CloudNativePG cluster")
src := testResources.SrcCluster
Expect(cl.Create(ctx, testResources.SrcCluster)).To(Succeed())
By("Having the Cluster ready")
Eventually(func(g Gomega) {
g.Expect(cl.Get(
ctx,
types.NamespacedName{
Name: src.Name,
Namespace: src.Namespace,
},
src)).To(Succeed())
g.Expect(internalCluster.IsReady(*src)).To(BeTrue())
}).WithTimeout(10 * time.Minute).WithPolling(10 * time.Second).Should(Succeed())
By("Adding data to PostgreSQL")
clientSet, cfg, err := internalClient.NewClientSet()
Expect(err).NotTo(HaveOccurred())
_, _, err = command.ExecuteInContainer(ctx,
*clientSet,
cfg,
command.ContainerLocator{
NamespaceName: src.Namespace,
PodName: fmt.Sprintf("%v-1", src.Name),
ContainerName: "postgres",
},
nil,
[]string{"psql", "-tAc", "CREATE TABLE test (i int); INSERT INTO test VALUES (1);"})
Expect(err).NotTo(HaveOccurred())
By("Creating a backup")
backup := testResources.SrcBackup
Expect(cl.Create(ctx, backup)).To(Succeed())
By("Waiting for the backup to complete")
Eventually(func(g Gomega) {
g.Expect(cl.Get(ctx, types.NamespacedName{Name: backup.Name, Namespace: backup.Namespace},
backup)).To(Succeed())
g.Expect(backup.Status.Phase).To(BeEquivalentTo(v1.BackupPhaseCompleted))
}).Within(2 * time.Minute).WithPolling(5 * time.Second).Should(Succeed())
By("Adding data after the backup")
_, _, err = command.ExecuteInContainer(ctx,
*clientSet,
cfg,
command.ContainerLocator{
NamespaceName: src.Namespace,
PodName: fmt.Sprintf("%v-1", src.Name),
ContainerName: "postgres",
},
nil,
[]string{
"psql", "-tAc",
"SELECT pg_switch_wal()" +
"; INSERT INTO test VALUES (2)",
})
Expect(err).NotTo(HaveOccurred())
_, _, err = command.ExecuteInContainer(ctx,
*clientSet,
cfg,
command.ContainerLocator{
NamespaceName: src.Namespace,
PodName: fmt.Sprintf("%v-1", src.Name),
ContainerName: "postgres",
},
nil,
[]string{
"psql", "-tAc",
"SELECT pg_switch_wal()",
})
Expect(err).NotTo(HaveOccurred())
By("Restoring the backup")
dst := testResources.DstCluster
Expect(cl.Create(ctx, dst)).To(Succeed())
By("Having the Cluster ready")
Eventually(func(g Gomega) {
g.Expect(cl.Get(ctx,
types.NamespacedName{Name: dst.Name, Namespace: dst.Namespace},
dst)).To(Succeed())
g.Expect(internalCluster.IsReady(*dst)).To(BeTrue())
}).WithTimeout(10 * time.Minute).WithPolling(10 * time.Second).Should(Succeed())
By("Verifying the data exists in the restored instance")
output, _, err := command.ExecuteInContainer(ctx,
*clientSet,
cfg,
command.ContainerLocator{
NamespaceName: dst.Namespace,
PodName: fmt.Sprintf("%v-1", dst.Name),
ContainerName: "postgres",
},
nil,
[]string{"psql", "-tAc", "SELECT count(*) FROM test;"})
Expect(err).NotTo(HaveOccurred())
Expect(output).To(BeEquivalentTo("2\n"))
By("taking a backup from the restored cluster")
backup = testResources.DstBackup
Expect(cl.Create(ctx, backup)).To(Succeed())
By("Waiting for the backup to complete")
Eventually(func(g Gomega) {
g.Expect(cl.Get(ctx, types.NamespacedName{Name: backup.Name, Namespace: backup.Namespace},
backup)).To(Succeed())
g.Expect(backup.Status.Phase).To(BeEquivalentTo(v1.BackupPhaseCompleted))
}).Within(3 * time.Minute).WithPolling(5 * time.Second).Should(Succeed())
},
Entry(
"using the plugin for backup and restore on S3",
&s3BackupPluginBackupPluginRestore{},
),
Entry(
"using the plugin for backup and in-tree for restore on S3",
&s3BackupPluginBackupInTreeRestore{},
),
Entry(
"using in-tree for backup and the plugin for restore on S3",
&s3BackupPluginInTreeBackupPluginRestore{},
),
Entry(
"using the plugin for backup and restore on Azure",
&azureBackupPluginBackupPluginRestore{},
),
Entry(
"using the plugin for backup and in-tree for restore on Azure",
&azureBackupPluginBackupInTreeRestore{},
),
Entry(
"using in-tree for backup and the plugin for restore on Azure",
&azureBackupPluginInTreeBackupPluginRestore{},
),
Entry("using the plugin for backup and restore on GCS",
&gcsBackupPluginBackupPluginRestore{},
),
Entry("using the plugin for backup and in-tree for restore on GCS",
&gcsBackupPluginBackupInTreeRestore{},
),
Entry(
"using in-tree for backup and the plugin for restore on GCS",
&gcsBackupPluginInTreeBackupPluginRestore{},
),
)
})