@@ -411,6 +411,100 @@ def test_validate_corrupted_intermediate_backups(self):
411
411
# Clean after yourself
412
412
self .del_test_dir (module_name , fname )
413
413
414
+ # @unittest.skip("skip")
415
+ def test_validate_error_intermediate_backups (self ):
416
+ """
417
+ make archive node, take FULL, PAGE1, PAGE2 backups,
418
+ change backup status of FULL and PAGE1 to ERROR,
419
+ run validate on PAGE1
420
+ purpouse of this test is to be sure that not only
421
+ CORRUPT backup descendants can be orphanized
422
+ """
423
+ fname = self .id ().split ('.' )[3 ]
424
+ node = self .make_simple_node (
425
+ base_dir = os .path .join (module_name , fname , 'node' ),
426
+ initdb_params = ['--data-checksums' ],
427
+ pg_options = {'wal_level' : 'replica' }
428
+ )
429
+ backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
430
+ self .init_pb (backup_dir )
431
+ self .add_instance (backup_dir , 'node' , node )
432
+ self .set_archiving (backup_dir , 'node' , node )
433
+ node .slow_start ()
434
+
435
+ # FULL
436
+ backup_id_1 = self .backup_node (backup_dir , 'node' , node )
437
+
438
+ # PAGE1
439
+ backup_id_2 = self .backup_node (
440
+ backup_dir , 'node' , node , backup_type = 'page' )
441
+
442
+ # PAGE2
443
+ backup_id_3 = self .backup_node (
444
+ backup_dir , 'node' , node , backup_type = 'page' )
445
+
446
+ # Change FULL backup status to ERROR
447
+ control_path = os .path .join (
448
+ backup_dir , 'backups' , 'node' , backup_id_1 , 'backup.control' )
449
+
450
+ with open (control_path , 'r' ) as f :
451
+ actual_control = f .read ()
452
+
453
+ print (actual_control )
454
+
455
+ new_control_file = ''
456
+ for line in actual_control .splitlines ():
457
+ new_control_file += line .replace (
458
+ 'status = OK' , 'status = ERROR' )
459
+ new_control_file += '\n '
460
+
461
+ with open (control_path , 'wt' ) as f :
462
+ f .write (new_control_file )
463
+ f .flush ()
464
+ f .close ()
465
+
466
+ print ('HELLO' )
467
+ print (new_control_file )
468
+
469
+ # Validate PAGE1
470
+ try :
471
+ self .validate_pb (
472
+ backup_dir , 'node' , backup_id = backup_id_2 )
473
+ self .assertEqual (
474
+ 1 , 0 ,
475
+ "Expecting Error because backup has status ERROR.\n "
476
+ "Output: {0} \n CMD: {1}" .format (
477
+ repr (self .output ), self .cmd ))
478
+ except ProbackupException as e :
479
+ self .assertTrue (
480
+ 'WARNING: Backup {0} is orphaned because '
481
+ 'his parent {1} has status: ERROR' .format (
482
+ backup_id_2 , backup_id_1 ) in e .message and
483
+ 'INFO: Validating parents for backup {0}' .format (
484
+ backup_id_2 ) in e .message and
485
+ 'WARNING: Backup {0} has status ERROR. Skip validation.' .format (
486
+ backup_id_1 ) and
487
+ 'ERROR: Backup {0} is orphan.' .format (backup_id_2 ) in e .message ,
488
+ '\n Unexpected Error Message: {0}\n '
489
+ 'CMD: {1}' .format (
490
+ repr (e .message ), self .cmd ))
491
+
492
+ self .assertEqual (
493
+ 'ERROR' ,
494
+ self .show_pb (backup_dir , 'node' , backup_id_1 )['status' ],
495
+ 'Backup STATUS should be "ERROR"' )
496
+ self .assertEqual (
497
+ 'ORPHAN' ,
498
+ self .show_pb (backup_dir , 'node' , backup_id_2 )['status' ],
499
+ 'Backup STATUS should be "ORPHAN"' )
500
+ self .assertEqual (
501
+ 'ORPHAN' ,
502
+ self .show_pb (backup_dir , 'node' , backup_id_3 )['status' ],
503
+ 'Backup STATUS should be "ORPHAN"' )
504
+
505
+ # Clean after yourself
506
+ self .del_test_dir (module_name , fname )
507
+
414
508
# @unittest.skip("skip")
415
509
def test_validate_corrupted_intermediate_backups_1 (self ):
416
510
"""
0 commit comments