Skip to content

Commit e4d375c

Browse files
armrulitaocdl
authored andcommitted
test(e2e): cover parallel WAL restore via the plugin
Recreate the parallel WAL-restore coverage in the plugin repo: a 2-instance cluster archiving to minio with wal.maxParallel=3, forged WAL segments on the object store, and assertions on the plugin's prefetch/spool/end-of-wal-stream state machine driven through `/controller/manager wal-restore` on the standby. Part of cloudnative-pg/cloudnative-pg#10954. Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
1 parent bb53820 commit e4d375c

4 files changed

Lines changed: 513 additions & 0 deletions

File tree

test/e2e/e2e_suite_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
_ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/backup"
4040
_ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/credentialrotation"
4141
_ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/replicacluster"
42+
_ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/walrestore"
4243

4344
. "github.com/onsi/ginkgo/v2"
4445
. "github.com/onsi/gomega"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright © contributors to CloudNativePG, established as
3+
CloudNativePG a Series of LF Projects, LLC.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
SPDX-License-Identifier: Apache-2.0
18+
*/
19+
20+
// Package walrestore contains the end-to-end test for the parallel WAL restore
21+
// behaviour of the Barman Cloud Plugin: prefetching upcoming segments into the
22+
// spool directory, serving later requests from the spool, and tracking the
23+
// end-of-wal-stream sentinel.
24+
package walrestore
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
Copyright © contributors to CloudNativePG, established as
3+
CloudNativePG a Series of LF Projects, LLC.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
SPDX-License-Identifier: Apache-2.0
18+
*/
19+
20+
package walrestore
21+
22+
import (
23+
cloudnativepgv1 "github.com/cloudnative-pg/api/pkg/api/v1"
24+
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
25+
appsv1 "k8s.io/api/apps/v1"
26+
corev1 "k8s.io/api/core/v1"
27+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
"k8s.io/utils/ptr"
29+
30+
pluginBarmanCloudV1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
31+
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/objectstore"
32+
)
33+
34+
const (
35+
minioName = "minio"
36+
objectStoreName = "source"
37+
clusterName = "source"
38+
s3ClientName = "s3-client"
39+
storageSize = "1Gi"
40+
// walMaxParallel is the prefetch parallelism under test: for a regular WAL
41+
// request the plugin restores the requested segment and prefetches the next
42+
// ones, up to this many segments in total.
43+
walMaxParallel = 3
44+
)
45+
46+
// newObjectStoreResources returns the minio server Deployment/Service/Secret/PVC.
47+
func newObjectStoreResources(namespace string) *objectstore.Resources {
48+
return objectstore.NewMinioObjectStoreResources(namespace, minioName)
49+
}
50+
51+
// newObjectStore returns a minio-backed ObjectStore configured with the WAL
52+
// prefetch parallelism (maxParallel) under test. Archiving with gzip makes the
53+
// archived segments carry the ".gz" suffix that forged segments are copied from.
54+
func newObjectStore(namespace string) *pluginBarmanCloudV1.ObjectStore {
55+
store := objectstore.NewMinioObjectStore(namespace, objectStoreName, minioName)
56+
store.Spec.Configuration.Wal = &barmanapi.WalBackupConfiguration{
57+
MaxParallel: walMaxParallel,
58+
Compression: barmanapi.CompressionTypeGzip,
59+
}
60+
return store
61+
}
62+
63+
// newCluster returns a 2-instance cluster that uses the plugin as its WAL
64+
// archiver, so the standby drives WAL restore (and its prefetch/spool/
65+
// end-of-wal-stream state machine) through the plugin.
66+
func newCluster(namespace string) *cloudnativepgv1.Cluster {
67+
return &cloudnativepgv1.Cluster{
68+
TypeMeta: metav1.TypeMeta{
69+
Kind: "Cluster",
70+
APIVersion: "postgresql.cnpg.io/v1",
71+
},
72+
ObjectMeta: metav1.ObjectMeta{
73+
Name: clusterName,
74+
Namespace: namespace,
75+
},
76+
Spec: cloudnativepgv1.ClusterSpec{
77+
Instances: 2,
78+
ImagePullPolicy: corev1.PullAlways,
79+
Plugins: []cloudnativepgv1.PluginConfiguration{
80+
{
81+
Name: "barman-cloud.cloudnative-pg.io",
82+
Parameters: map[string]string{
83+
"barmanObjectName": objectStoreName,
84+
},
85+
IsWALArchiver: ptr.To(true),
86+
},
87+
},
88+
PostgresConfiguration: cloudnativepgv1.PostgresConfiguration{
89+
Parameters: map[string]string{
90+
"log_min_messages": "DEBUG4",
91+
},
92+
},
93+
StorageConfiguration: cloudnativepgv1.StorageConfiguration{
94+
Size: storageSize,
95+
},
96+
},
97+
}
98+
}
99+
100+
// newS3ClientDeployment returns a deployment running the AWS CLI configured to
101+
// talk to the in-namespace minio service. The test execs `aws s3` commands in
102+
// it to forge WAL segments on the object store and to check their presence.
103+
func newS3ClientDeployment(namespace string) *appsv1.Deployment {
104+
labels := map[string]string{"app": s3ClientName}
105+
return &appsv1.Deployment{
106+
TypeMeta: metav1.TypeMeta{
107+
Kind: "Deployment",
108+
APIVersion: "apps/v1",
109+
},
110+
ObjectMeta: metav1.ObjectMeta{
111+
Name: s3ClientName,
112+
Namespace: namespace,
113+
},
114+
Spec: appsv1.DeploymentSpec{
115+
Replicas: ptr.To(int32(1)),
116+
Selector: &metav1.LabelSelector{MatchLabels: labels},
117+
Template: corev1.PodTemplateSpec{
118+
ObjectMeta: metav1.ObjectMeta{Labels: labels},
119+
Spec: corev1.PodSpec{
120+
Containers: []corev1.Container{
121+
{
122+
Name: s3ClientName,
123+
// renovate: datasource=docker depName=amazon/aws-cli versioning=docker
124+
Image: "docker.io/amazon/aws-cli:2.35.4",
125+
Command: []string{"sleep", "infinity"},
126+
Env: []corev1.EnvVar{
127+
{
128+
Name: "AWS_ENDPOINT_URL",
129+
Value: "http://" + minioName + ":9000",
130+
},
131+
{
132+
Name: "AWS_ACCESS_KEY_ID",
133+
ValueFrom: &corev1.EnvVarSource{
134+
SecretKeyRef: &corev1.SecretKeySelector{
135+
LocalObjectReference: corev1.LocalObjectReference{Name: minioName},
136+
Key: "ACCESS_KEY_ID",
137+
},
138+
},
139+
},
140+
{
141+
Name: "AWS_SECRET_ACCESS_KEY",
142+
ValueFrom: &corev1.EnvVarSource{
143+
SecretKeyRef: &corev1.SecretKeySelector{
144+
LocalObjectReference: corev1.LocalObjectReference{Name: minioName},
145+
Key: "ACCESS_SECRET_KEY",
146+
},
147+
},
148+
},
149+
{
150+
Name: "AWS_DEFAULT_REGION",
151+
Value: "us-east-1",
152+
},
153+
// The CRC-based default checksums introduced in AWS
154+
// CLI 2.23 are not supported by every S3-compatible
155+
// object store, minio included.
156+
{
157+
Name: "AWS_REQUEST_CHECKSUM_CALCULATION",
158+
Value: "when_required",
159+
},
160+
{
161+
Name: "AWS_RESPONSE_CHECKSUM_VALIDATION",
162+
Value: "when_required",
163+
},
164+
},
165+
SecurityContext: &corev1.SecurityContext{
166+
AllowPrivilegeEscalation: ptr.To(false),
167+
SeccompProfile: &corev1.SeccompProfile{
168+
Type: corev1.SeccompProfileTypeRuntimeDefault,
169+
},
170+
},
171+
},
172+
},
173+
},
174+
},
175+
},
176+
}
177+
}

0 commit comments

Comments
 (0)