Skip to content

Commit d8050e5

Browse files
committed
[Issue #385] improve test coverage
1 parent 0e4b3a9 commit d8050e5

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-0
lines changed

tests/backup.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3459,3 +3459,115 @@ def test_basic_backup_default_transaction_read_only(self):
34593459

34603460
# Clean after yourself
34613461
self.del_test_dir(module_name, fname)
3462+
3463+
# @unittest.skip("skip")
3464+
def test_backup_atexit(self):
3465+
""""""
3466+
fname = self.id().split('.')[3]
3467+
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
3468+
node = self.make_simple_node(
3469+
base_dir=os.path.join(module_name, fname, 'node'),
3470+
set_replication=True,
3471+
ptrack_enable=self.ptrack,
3472+
initdb_params=['--data-checksums'])
3473+
3474+
self.init_pb(backup_dir)
3475+
self.add_instance(backup_dir, 'node', node)
3476+
self.set_archiving(backup_dir, 'node', node)
3477+
node.slow_start()
3478+
3479+
node.pgbench_init(scale=5)
3480+
3481+
# Full backup in streaming mode
3482+
gdb = self.backup_node(
3483+
backup_dir, 'node', node,
3484+
options=['--stream', '--log-level-file=VERBOSE'], gdb=True)
3485+
3486+
# break at streaming start
3487+
gdb.set_breakpoint('backup_data_file')
3488+
gdb.run_until_break()
3489+
3490+
gdb.remove_all_breakpoints()
3491+
gdb._execute('signal SIGINT')
3492+
sleep(1)
3493+
3494+
self.assertEqual(
3495+
self.show_pb(
3496+
backup_dir, 'node')[0]['status'], 'ERROR')
3497+
3498+
with open(os.path.join(backup_dir, 'log', 'pg_probackup.log')) as f:
3499+
log_content = f.read()
3500+
#print(log_content)
3501+
self.assertIn(
3502+
'WARNING: backup in progress, stop backup',
3503+
log_content)
3504+
3505+
self.assertIn(
3506+
'FROM pg_catalog.pg_stop_backup',
3507+
log_content)
3508+
3509+
self.assertIn(
3510+
'setting its status to ERROR',
3511+
log_content)
3512+
3513+
# Clean after yourself
3514+
self.del_test_dir(module_name, fname)
3515+
3516+
# @unittest.skip("skip")
3517+
def test_pg_stop_backup_missing_permissions(self):
3518+
""""""
3519+
fname = self.id().split('.')[3]
3520+
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
3521+
node = self.make_simple_node(
3522+
base_dir=os.path.join(module_name, fname, 'node'),
3523+
set_replication=True,
3524+
ptrack_enable=self.ptrack,
3525+
initdb_params=['--data-checksums'])
3526+
3527+
self.init_pb(backup_dir)
3528+
self.add_instance(backup_dir, 'node', node)
3529+
self.set_archiving(backup_dir, 'node', node)
3530+
node.slow_start()
3531+
3532+
node.pgbench_init(scale=5)
3533+
3534+
self.simple_bootstrap(node, 'backup')
3535+
3536+
if self.get_version(node) < 90600:
3537+
node.safe_psql(
3538+
'postgres',
3539+
'REVOKE EXECUTE ON FUNCTION pg_catalog.pg_stop_backup() FROM backup')
3540+
elif self.get_version(node) > 90600 and self.get_version(node) < 100000:
3541+
node.safe_psql(
3542+
'postgres',
3543+
'REVOKE EXECUTE ON FUNCTION pg_catalog.pg_stop_backup(boolean) FROM backup')
3544+
else:
3545+
node.safe_psql(
3546+
'postgres',
3547+
'REVOKE EXECUTE ON FUNCTION pg_catalog.pg_stop_backup(boolean, boolean) FROM backup')
3548+
3549+
# Full backup in streaming mode
3550+
try:
3551+
self.backup_node(
3552+
backup_dir, 'node', node,
3553+
options=['--stream', '-U', 'backup'])
3554+
# we should die here because exception is what we expect to happen
3555+
self.assertEqual(
3556+
1, 0,
3557+
"Expecting Error because of missing permissions on pg_stop_backup "
3558+
"\n Output: {0} \n CMD: {1}".format(
3559+
repr(self.output), self.cmd))
3560+
except ProbackupException as e:
3561+
self.assertIn(
3562+
"ERROR: permission denied for function pg_stop_backup",
3563+
e.message,
3564+
"\n Unexpected Error Message: {0}\n CMD: {1}".format(
3565+
repr(e.message), self.cmd))
3566+
self.assertIn(
3567+
"query was: SELECT pg_catalog.txid_snapshot_xmax",
3568+
e.message,
3569+
"\n Unexpected Error Message: {0}\n CMD: {1}".format(
3570+
repr(e.message), self.cmd))
3571+
3572+
# Clean after yourself
3573+
self.del_test_dir(module_name, fname)

tests/helpers/ptrack_helpers.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,59 @@ def make_simple_node(
405405
self.set_auto_conf(
406406
node, {}, 'postgresql.conf', ['wal_keep_segments'])
407407
return node
408+
409+
def simple_bootstrap(self, node, role) -> None:
410+
411+
node.safe_psql(
412+
'postgres',
413+
'CREATE ROLE {0} WITH LOGIN REPLICATION'.format(role))
414+
415+
# PG 9.5
416+
if self.get_version(node) < 90600:
417+
node.safe_psql(
418+
'postgres',
419+
'GRANT USAGE ON SCHEMA pg_catalog TO {0}; '
420+
'GRANT EXECUTE ON FUNCTION pg_catalog.current_setting(text) TO {0}; '
421+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_is_in_recovery() TO {0}; '
422+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_start_backup(text, boolean) TO {0}; '
423+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_stop_backup() TO {0}; '
424+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_create_restore_point(text) TO {0}; '
425+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_switch_xlog() TO {0}; '
426+
'GRANT EXECUTE ON FUNCTION pg_catalog.txid_current() TO {0}; '
427+
'GRANT EXECUTE ON FUNCTION pg_catalog.txid_current_snapshot() TO {0}; '
428+
'GRANT EXECUTE ON FUNCTION pg_catalog.txid_snapshot_xmax(txid_snapshot) TO {0};'.format(role))
429+
# PG 9.6
430+
elif self.get_version(node) > 90600 and self.get_version(node) < 100000:
431+
node.safe_psql(
432+
'postgres',
433+
'GRANT USAGE ON SCHEMA pg_catalog TO {0}; '
434+
'GRANT EXECUTE ON FUNCTION pg_catalog.current_setting(text) TO {0}; '
435+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_is_in_recovery() TO {0}; '
436+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_start_backup(text, boolean, boolean) TO {0}; '
437+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_stop_backup(boolean) TO {0}; '
438+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_create_restore_point(text) TO {0}; '
439+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_switch_xlog() TO {0}; '
440+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_last_xlog_replay_location() TO {0}; '
441+
'GRANT EXECUTE ON FUNCTION pg_catalog.txid_current() TO {0}; '
442+
'GRANT EXECUTE ON FUNCTION pg_catalog.txid_current_snapshot() TO {0}; '
443+
'GRANT EXECUTE ON FUNCTION pg_catalog.txid_snapshot_xmax(txid_snapshot) TO {0}; '
444+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_control_checkpoint() TO {0};'.format(role))
445+
# >= 10
446+
else:
447+
node.safe_psql(
448+
'postgres',
449+
'GRANT USAGE ON SCHEMA pg_catalog TO {0}; '
450+
'GRANT EXECUTE ON FUNCTION pg_catalog.current_setting(text) TO {0}; '
451+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_is_in_recovery() TO {0}; '
452+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_start_backup(text, boolean, boolean) TO {0}; '
453+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_stop_backup(boolean, boolean) TO {0}; '
454+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_create_restore_point(text) TO {0}; '
455+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_switch_wal() TO {0}; '
456+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_last_wal_replay_lsn() TO {0}; '
457+
'GRANT EXECUTE ON FUNCTION pg_catalog.txid_current() TO {0}; '
458+
'GRANT EXECUTE ON FUNCTION pg_catalog.txid_current_snapshot() TO {0}; '
459+
'GRANT EXECUTE ON FUNCTION pg_catalog.txid_snapshot_xmax(txid_snapshot) TO {0}; '
460+
'GRANT EXECUTE ON FUNCTION pg_catalog.pg_control_checkpoint() TO {0};'.format(role))
408461

409462
def create_tblspace_in_node(self, node, tblspc_name, tblspc_path=None, cfs=False):
410463
res = node.execute(

0 commit comments

Comments
 (0)