@@ -5,8 +5,13 @@ import (
5
5
"fmt"
6
6
"os"
7
7
"path/filepath"
8
+ "reflect"
8
9
"testing"
10
+ "time"
9
11
12
+ batchv1 "k8s.io/api/batch/v1"
13
+ corev1 "k8s.io/api/core/v1"
14
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10
15
"k8s.io/apimachinery/pkg/runtime"
11
16
"k8s.io/apimachinery/pkg/types"
12
17
"k8s.io/apimachinery/pkg/util/yaml"
@@ -16,6 +21,8 @@ import (
16
21
17
22
apiv1alpha1 "github.com/percona/percona-server-mysql-operator/api/v1alpha1"
18
23
"github.com/percona/percona-server-mysql-operator/pkg/platform"
24
+ "github.com/percona/percona-server-mysql-operator/pkg/secret"
25
+ "github.com/percona/percona-server-mysql-operator/pkg/xtrabackup"
19
26
)
20
27
21
28
func TestBackupStatusErrStateDesc (t * testing.T ) {
@@ -125,6 +132,168 @@ func TestBackupStatusErrStateDesc(t *testing.T) {
125
132
}
126
133
}
127
134
135
+ func TestCheckFinalizers (t * testing.T ) {
136
+ ctx := context .Background ()
137
+ scheme := runtime .NewScheme ()
138
+ if err := clientgoscheme .AddToScheme (scheme ); err != nil {
139
+ t .Fatal (err , "failed to add client-go scheme" )
140
+ }
141
+ if err := apiv1alpha1 .AddToScheme (scheme ); err != nil {
142
+ t .Fatal (err , "failed to add apis scheme" )
143
+ }
144
+ namespace := "some-namespace"
145
+ cr , err := readDefaultCRBackup ("some-name" , namespace )
146
+ if err != nil {
147
+ t .Fatal (err , "failed to read default backup" )
148
+ }
149
+
150
+ tests := []struct {
151
+ name string
152
+ cr * apiv1alpha1.PerconaServerMySQLBackup
153
+ expectedFinalizers []string
154
+ finalizerJobFail bool
155
+ }{
156
+ {
157
+ name : "without finalizers" ,
158
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
159
+ cr .Finalizers = []string {}
160
+ cr .Status .State = apiv1alpha1 .BackupError
161
+ }),
162
+ expectedFinalizers : nil ,
163
+ },
164
+ {
165
+ name : "with finalizer and starting state" ,
166
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
167
+ cr .Finalizers = []string {finalizerDeleteBackup }
168
+ cr .Status .State = apiv1alpha1 .BackupStarting
169
+ }),
170
+ expectedFinalizers : []string {finalizerDeleteBackup },
171
+ },
172
+ {
173
+ name : "with finalizer and running state" ,
174
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
175
+ cr .Finalizers = []string {finalizerDeleteBackup }
176
+ cr .Status .State = apiv1alpha1 .BackupRunning
177
+ }),
178
+ expectedFinalizers : []string {finalizerDeleteBackup },
179
+ },
180
+ {
181
+ name : "with finalizer and error state" ,
182
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
183
+ cr .Finalizers = []string {finalizerDeleteBackup }
184
+ cr .Status .State = apiv1alpha1 .BackupError
185
+ }),
186
+ expectedFinalizers : nil ,
187
+ },
188
+ {
189
+ name : "with finalizer and new state" ,
190
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
191
+ cr .Finalizers = []string {finalizerDeleteBackup }
192
+ cr .Status .State = apiv1alpha1 .BackupNew
193
+ }),
194
+ expectedFinalizers : nil ,
195
+ },
196
+ {
197
+ name : "with failing finalizer and succeeded state" ,
198
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
199
+ cr .Finalizers = []string {finalizerDeleteBackup }
200
+ cr .Status .State = apiv1alpha1 .BackupSucceeded
201
+ }),
202
+ finalizerJobFail : true ,
203
+ expectedFinalizers : []string {finalizerDeleteBackup },
204
+ },
205
+ {
206
+ name : "with successful finalizer and succeeded state" ,
207
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
208
+ cr .Finalizers = []string {finalizerDeleteBackup }
209
+ cr .Status .State = apiv1alpha1 .BackupSucceeded
210
+ }),
211
+ expectedFinalizers : []string {},
212
+ },
213
+ {
214
+ name : "with successful finalizer, unknown finalizer and succeeded state" ,
215
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
216
+ cr .Finalizers = []string {finalizerDeleteBackup , "unknown-finalizer" }
217
+ cr .Status .State = apiv1alpha1 .BackupSucceeded
218
+ }),
219
+ expectedFinalizers : []string {"unknown-finalizer" },
220
+ },
221
+ {
222
+ name : "with failing finalizer and failed state" ,
223
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
224
+ cr .Finalizers = []string {finalizerDeleteBackup }
225
+ cr .Status .State = apiv1alpha1 .BackupFailed
226
+ }),
227
+ finalizerJobFail : true ,
228
+ expectedFinalizers : []string {finalizerDeleteBackup },
229
+ },
230
+ {
231
+ name : "with successful finalizer and failed state" ,
232
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
233
+ cr .Finalizers = []string {finalizerDeleteBackup }
234
+ cr .Status .State = apiv1alpha1 .BackupFailed
235
+ }),
236
+ expectedFinalizers : []string {},
237
+ },
238
+ {
239
+ name : "with successful finalizer, unknown finalizer and failed state" ,
240
+ cr : updateResource (cr .DeepCopy (), func (cr * apiv1alpha1.PerconaServerMySQLBackup ) {
241
+ cr .Finalizers = []string {finalizerDeleteBackup , "unknown-finalizer" }
242
+ cr .Status .State = apiv1alpha1 .BackupFailed
243
+ }),
244
+ expectedFinalizers : []string {"unknown-finalizer" },
245
+ },
246
+ }
247
+
248
+ sec := & corev1.Secret {
249
+ ObjectMeta : metav1.ObjectMeta {
250
+ Name : "some-secret" ,
251
+ Namespace : namespace ,
252
+ },
253
+ Data : map [string ][]byte {
254
+ secret .CredentialsAWSAccessKey : []byte ("access-key" ),
255
+ secret .CredentialsAWSSecretKey : []byte ("secret-key" ),
256
+ },
257
+ }
258
+ storage := & apiv1alpha1.BackupStorageSpec {
259
+ Type : apiv1alpha1 .BackupStorageS3 ,
260
+ S3 : & apiv1alpha1.BackupStorageS3Spec {
261
+ Bucket : "some-bucket" ,
262
+ CredentialsSecret : "some-secret" ,
263
+ },
264
+ Labels : make (map [string ]string ),
265
+ }
266
+
267
+ for _ , tt := range tests {
268
+ t .Run (tt .name , func (t * testing.T ) {
269
+ tt .cr .DeletionTimestamp = & metav1.Time {Time : time .Now ()}
270
+ tt .cr .Status .Storage = storage
271
+
272
+ job := xtrabackup .GetDeleteJob (tt .cr , new (xtrabackup.BackupConfig ))
273
+ cond := batchv1.JobCondition {
274
+ Type : batchv1 .JobComplete ,
275
+ Status : corev1 .ConditionTrue ,
276
+ }
277
+ if tt .finalizerJobFail {
278
+ cond .Type = batchv1 .JobFailed
279
+ }
280
+ job .Status .Conditions = append (job .Status .Conditions , cond )
281
+
282
+ cb := fake .NewClientBuilder ().WithScheme (scheme ).WithObjects (tt .cr , sec , job )
283
+ r := PerconaServerMySQLBackupReconciler {
284
+ Client : cb .Build (),
285
+ Scheme : scheme ,
286
+ ServerVersion : & platform.ServerVersion {Platform : platform .PlatformKubernetes },
287
+ }
288
+
289
+ r .checkFinalizers (ctx , tt .cr )
290
+ if ! reflect .DeepEqual (tt .cr .Finalizers , tt .expectedFinalizers ) {
291
+ t .Fatalf ("expected finalizers %v, got %v" , tt .expectedFinalizers , tt .cr .Finalizers )
292
+ }
293
+ })
294
+ }
295
+ }
296
+
128
297
func readDefaultCR (name , namespace string ) (* apiv1alpha1.PerconaServerMySQL , error ) {
129
298
data , err := os .ReadFile (filepath .Join (".." , ".." , ".." , "deploy" , "cr.yaml" ))
130
299
if err != nil {
0 commit comments