Skip to content

Commit b278a2f

Browse files
committed
tests: minor fixes
1 parent f270d38 commit b278a2f

File tree

1 file changed

+200
-134
lines changed

1 file changed

+200
-134
lines changed

tests/restore.py

Lines changed: 200 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -2930,140 +2930,6 @@ def test_partial_restore_backward_compatibility_merge(self):
29302930

29312931
self.compare_pgdata(pgdata_restored, pgdata_restored_1)
29322932

2933-
def test_missing_database_map(self):
2934-
"""
2935-
"""
2936-
fname = self.id().split('.')[3]
2937-
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
2938-
node = self.make_simple_node(
2939-
base_dir=os.path.join(module_name, fname, 'node'),
2940-
set_replication=True,
2941-
initdb_params=['--data-checksums'])
2942-
2943-
self.init_pb(backup_dir)
2944-
self.add_instance(backup_dir, 'node', node)
2945-
2946-
node.slow_start()
2947-
2948-
# create databases
2949-
for i in range(1, 10, 1):
2950-
node.safe_psql(
2951-
'postgres',
2952-
'CREATE database db{0}'.format(i))
2953-
2954-
node.safe_psql(
2955-
"postgres",
2956-
"CREATE DATABASE backupdb")
2957-
2958-
if self.get_version(node) > self.version_to_num('10.0'):
2959-
# bootstrap for 10/11
2960-
node.safe_psql(
2961-
"backupdb",
2962-
"REVOKE ALL on SCHEMA public from public; "
2963-
"REVOKE ALL on SCHEMA pg_catalog from public; "
2964-
"REVOKE ALL ON ALL TABLES IN SCHEMA pg_catalog FROM public; "
2965-
"REVOKE ALL ON ALL TABLES IN SCHEMA public FROM public; "
2966-
"CREATE ROLE backup WITH LOGIN REPLICATION; "
2967-
"GRANT CONNECT ON DATABASE postgres to backup; "
2968-
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
2969-
"GRANT SELECT ON TABLE pg_catalog.pg_proc TO backup; "
2970-
# we use it for partial restore and checkdb
2971-
# "GRANT SELECT ON TABLE pg_catalog.pg_database TO backup; "
2972-
"GRANT EXECUTE ON FUNCTION pg_catalog.current_setting(text) TO backup; "
2973-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_is_in_recovery() TO backup; "
2974-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_start_backup(text, boolean, boolean) TO backup; "
2975-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_stop_backup(boolean, boolean) TO backup; "
2976-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_create_restore_point(text) TO backup; "
2977-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_switch_wal() TO backup; "
2978-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_last_wal_replay_lsn() TO backup; "
2979-
"GRANT EXECUTE ON FUNCTION pg_catalog.txid_current_snapshot() TO backup; "
2980-
"GRANT EXECUTE ON FUNCTION pg_catalog.txid_snapshot_xmax(txid_snapshot) TO backup; "
2981-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_ptrack_clear() TO backup; "
2982-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_ptrack_get_and_clear(oid, oid) TO backup; "
2983-
# "GRANT EXECUTE ON FUNCTION pg_catalog.pg_ptrack_get_block_2(oid, oid, oid, oid) TO backup;"
2984-
)
2985-
else:
2986-
# bootstrap for 9.5/9.6
2987-
node.safe_psql(
2988-
"backupdb",
2989-
"REVOKE ALL on SCHEMA public from public; "
2990-
"REVOKE ALL on SCHEMA pg_catalog from public; "
2991-
"REVOKE ALL ON ALL TABLES IN SCHEMA pg_catalog FROM public; "
2992-
"REVOKE ALL ON ALL TABLES IN SCHEMA public FROM public; "
2993-
"CREATE ROLE backup WITH LOGIN REPLICATION; "
2994-
"GRANT CONNECT ON DATABASE postgres to backup; "
2995-
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
2996-
# we use it for ptrack
2997-
"GRANT SELECT ON TABLE pg_catalog.pg_proc TO backup; "
2998-
# we use it for partial restore and checkdb
2999-
# "GRANT SELECT ON TABLE pg_catalog.pg_database TO backup; "
3000-
"GRANT EXECUTE ON FUNCTION pg_catalog.current_setting(text) TO backup; "
3001-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_is_in_recovery() TO backup; "
3002-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_start_backup(text, boolean, boolean) TO backup; "
3003-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_stop_backup() TO backup; "
3004-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_stop_backup(boolean) TO backup; "
3005-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_create_restore_point(text) TO backup; "
3006-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_switch_xlog() TO backup; "
3007-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_last_xlog_replay_location() TO backup; "
3008-
"GRANT EXECUTE ON FUNCTION pg_catalog.txid_current_snapshot() TO backup; "
3009-
"GRANT EXECUTE ON FUNCTION pg_catalog.txid_snapshot_xmax(txid_snapshot) TO backup; "
3010-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_ptrack_clear() TO backup; "
3011-
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_ptrack_get_and_clear(oid, oid) TO backup; "
3012-
# "GRANT EXECUTE ON FUNCTION pg_catalog.pg_ptrack_get_block_2(oid, oid, oid, oid) TO backup;"
3013-
)
3014-
3015-
# FULL backup without database_map
3016-
backup_id = self.backup_node(
3017-
backup_dir, 'node', node, datname='backupdb',
3018-
options=['--stream', "-U", "backup"])
3019-
3020-
pgdata = self.pgdata_content(node.data_dir)
3021-
3022-
node_restored = self.make_simple_node(
3023-
base_dir=os.path.join(module_name, fname, 'node_restored'))
3024-
node_restored.cleanup()
3025-
3026-
# backup has missing database_map and that is legal
3027-
try:
3028-
self.restore_node(
3029-
backup_dir, 'node', node_restored,
3030-
options=["--db-exclude=db5", "--db-exclude=db9"])
3031-
self.assertEqual(
3032-
1, 0,
3033-
"Expecting Error because user do not have pg_database access.\n "
3034-
"Output: {0} \n CMD: {1}".format(
3035-
self.output, self.cmd))
3036-
except ProbackupException as e:
3037-
self.assertIn(
3038-
"ERROR: Backup {0} has missing database_map, "
3039-
"partial restore is impossible.".format(
3040-
backup_id), e.message,
3041-
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
3042-
repr(e.message), self.cmd))
3043-
3044-
try:
3045-
self.restore_node(
3046-
backup_dir, 'node', node_restored,
3047-
options=["--db-include=db1"])
3048-
self.assertEqual(
3049-
1, 0,
3050-
"Expecting Error because user do not have pg_database access.\n "
3051-
"Output: {0} \n CMD: {1}".format(
3052-
self.output, self.cmd))
3053-
except ProbackupException as e:
3054-
self.assertIn(
3055-
"ERROR: Backup {0} has missing database_map, "
3056-
"partial restore is impossible.".format(
3057-
backup_id), e.message,
3058-
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
3059-
repr(e.message), self.cmd))
3060-
3061-
# check that simple restore is still possible
3062-
self.restore_node(backup_dir, 'node', node_restored)
3063-
3064-
pgdata_restored = self.pgdata_content(node_restored.data_dir)
3065-
self.compare_pgdata(pgdata, pgdata_restored)
3066-
30672933
def test_empty_and_mangled_database_map(self):
30682934
"""
30692935
"""
@@ -3176,3 +3042,203 @@ def test_empty_and_mangled_database_map(self):
31763042

31773043
pgdata_restored = self.pgdata_content(node_restored.data_dir)
31783044
self.compare_pgdata(pgdata, pgdata_restored)
3045+
3046+
def test_missing_database_map(self):
3047+
"""
3048+
"""
3049+
fname = self.id().split('.')[3]
3050+
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
3051+
node = self.make_simple_node(
3052+
base_dir=os.path.join(module_name, fname, 'node'),
3053+
set_replication=True,
3054+
initdb_params=['--data-checksums'],
3055+
pg_options={'autovacuum': 'off'})
3056+
3057+
self.init_pb(backup_dir)
3058+
self.add_instance(backup_dir, 'node', node)
3059+
3060+
node.slow_start()
3061+
3062+
# create databases
3063+
for i in range(1, 10, 1):
3064+
node.safe_psql(
3065+
'postgres',
3066+
'CREATE database db{0}'.format(i))
3067+
3068+
node.safe_psql(
3069+
"postgres",
3070+
"CREATE DATABASE backupdb")
3071+
3072+
# PG 9.5
3073+
if self.get_version(node) < 90600:
3074+
node.safe_psql(
3075+
'backupdb',
3076+
"REVOKE ALL ON DATABASE backupdb from PUBLIC; "
3077+
"REVOKE ALL ON SCHEMA public from PUBLIC; "
3078+
"REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC; "
3079+
"REVOKE ALL ON ALL FUNCTIONS IN SCHEMA public FROM PUBLIC; "
3080+
"REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM PUBLIC; "
3081+
"REVOKE ALL ON SCHEMA pg_catalog from PUBLIC; "
3082+
"REVOKE ALL ON ALL TABLES IN SCHEMA pg_catalog FROM PUBLIC; "
3083+
"REVOKE ALL ON ALL FUNCTIONS IN SCHEMA pg_catalog FROM PUBLIC; "
3084+
"REVOKE ALL ON ALL SEQUENCES IN SCHEMA pg_catalog FROM PUBLIC; "
3085+
"REVOKE ALL ON SCHEMA information_schema from PUBLIC; "
3086+
"REVOKE ALL ON ALL TABLES IN SCHEMA information_schema FROM PUBLIC; "
3087+
"REVOKE ALL ON ALL FUNCTIONS IN SCHEMA information_schema FROM PUBLIC; "
3088+
"REVOKE ALL ON ALL SEQUENCES IN SCHEMA information_schema FROM PUBLIC; "
3089+
"CREATE ROLE backup WITH LOGIN REPLICATION; "
3090+
"GRANT CONNECT ON DATABASE backupdb to backup; "
3091+
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
3092+
"GRANT SELECT ON TABLE pg_catalog.pg_proc TO backup; "
3093+
"GRANT SELECT ON TABLE pg_catalog.pg_database TO backup; " # for partial restore, checkdb and ptrack
3094+
"GRANT EXECUTE ON FUNCTION pg_catalog.nameeq(name, name) TO backup; "
3095+
"GRANT EXECUTE ON FUNCTION pg_catalog.textout(text) TO backup; "
3096+
"GRANT EXECUTE ON FUNCTION pg_catalog.timestamptz(timestamp with time zone, integer) TO backup; "
3097+
"GRANT EXECUTE ON FUNCTION pg_catalog.current_setting(text) TO backup; "
3098+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_is_in_recovery() TO backup; "
3099+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_start_backup(text, boolean) TO backup; "
3100+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_stop_backup() TO backup; "
3101+
"GRANT EXECUTE ON FUNCTION pg_catalog.txid_current_snapshot() TO backup; "
3102+
"GRANT EXECUTE ON FUNCTION pg_catalog.txid_snapshot_xmax(txid_snapshot) TO backup;"
3103+
)
3104+
# PG 9.6
3105+
elif self.get_version(node) > 90600 and self.get_version(node) < 100000:
3106+
node.safe_psql(
3107+
'backupdb',
3108+
"REVOKE ALL ON DATABASE backupdb from PUBLIC; "
3109+
"REVOKE ALL ON SCHEMA public from PUBLIC; "
3110+
"REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC; "
3111+
"REVOKE ALL ON ALL FUNCTIONS IN SCHEMA public FROM PUBLIC; "
3112+
"REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM PUBLIC; "
3113+
"REVOKE ALL ON SCHEMA pg_catalog from PUBLIC; "
3114+
"REVOKE ALL ON ALL TABLES IN SCHEMA pg_catalog FROM PUBLIC; "
3115+
"REVOKE ALL ON ALL FUNCTIONS IN SCHEMA pg_catalog FROM PUBLIC; "
3116+
"REVOKE ALL ON ALL SEQUENCES IN SCHEMA pg_catalog FROM PUBLIC; "
3117+
"REVOKE ALL ON SCHEMA information_schema from PUBLIC; "
3118+
"REVOKE ALL ON ALL TABLES IN SCHEMA information_schema FROM PUBLIC; "
3119+
"REVOKE ALL ON ALL FUNCTIONS IN SCHEMA information_schema FROM PUBLIC; "
3120+
"REVOKE ALL ON ALL SEQUENCES IN SCHEMA information_schema FROM PUBLIC; "
3121+
"CREATE ROLE backup WITH LOGIN REPLICATION; "
3122+
"GRANT CONNECT ON DATABASE backupdb to backup; "
3123+
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
3124+
"GRANT SELECT ON TABLE pg_catalog.pg_proc TO backup; "
3125+
"GRANT SELECT ON TABLE pg_catalog.pg_database TO backup; " # for partial restore, checkdb and ptrack
3126+
"GRANT EXECUTE ON FUNCTION pg_catalog.nameeq(name, name) TO backup; "
3127+
"GRANT EXECUTE ON FUNCTION pg_catalog.textout(text) TO backup; "
3128+
"GRANT EXECUTE ON FUNCTION pg_catalog.timestamptz(timestamp with time zone, integer) TO backup; "
3129+
"GRANT EXECUTE ON FUNCTION pg_catalog.current_setting(text) TO backup; "
3130+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_is_in_recovery() TO backup; "
3131+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_control_system() TO backup; "
3132+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_start_backup(text, boolean, boolean) TO backup; "
3133+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_stop_backup(boolean) TO backup; "
3134+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_create_restore_point(text) TO backup; "
3135+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_switch_xlog() TO backup; "
3136+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_last_xlog_replay_location() TO backup; "
3137+
"GRANT EXECUTE ON FUNCTION pg_catalog.txid_current_snapshot() TO backup; "
3138+
"GRANT EXECUTE ON FUNCTION pg_catalog.txid_snapshot_xmax(txid_snapshot) TO backup;"
3139+
)
3140+
# >= 10
3141+
else:
3142+
node.safe_psql(
3143+
'backupdb',
3144+
"REVOKE ALL ON DATABASE backupdb from PUBLIC; "
3145+
"REVOKE ALL ON SCHEMA public from PUBLIC; "
3146+
"REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC; "
3147+
"REVOKE ALL ON ALL FUNCTIONS IN SCHEMA public FROM PUBLIC; "
3148+
"REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM PUBLIC; "
3149+
"REVOKE ALL ON SCHEMA pg_catalog from PUBLIC; "
3150+
"REVOKE ALL ON ALL TABLES IN SCHEMA pg_catalog FROM PUBLIC; "
3151+
"REVOKE ALL ON ALL FUNCTIONS IN SCHEMA pg_catalog FROM PUBLIC; "
3152+
"REVOKE ALL ON ALL SEQUENCES IN SCHEMA pg_catalog FROM PUBLIC; "
3153+
"REVOKE ALL ON SCHEMA information_schema from PUBLIC; "
3154+
"REVOKE ALL ON ALL TABLES IN SCHEMA information_schema FROM PUBLIC; "
3155+
"REVOKE ALL ON ALL FUNCTIONS IN SCHEMA information_schema FROM PUBLIC; "
3156+
"REVOKE ALL ON ALL SEQUENCES IN SCHEMA information_schema FROM PUBLIC; "
3157+
"CREATE ROLE backup WITH LOGIN REPLICATION; "
3158+
"GRANT CONNECT ON DATABASE backupdb to backup; "
3159+
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
3160+
"GRANT SELECT ON TABLE pg_catalog.pg_proc TO backup; "
3161+
"GRANT SELECT ON TABLE pg_catalog.pg_database TO backup; " # for partial restore, checkdb and ptrack
3162+
"GRANT EXECUTE ON FUNCTION pg_catalog.nameeq(name, name) TO backup; "
3163+
"GRANT EXECUTE ON FUNCTION pg_catalog.current_setting(text) TO backup; "
3164+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_is_in_recovery() TO backup; "
3165+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_control_system() TO backup; "
3166+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_start_backup(text, boolean, boolean) TO backup; "
3167+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_stop_backup(boolean, boolean) TO backup; "
3168+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_create_restore_point(text) TO backup; "
3169+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_switch_wal() TO backup; "
3170+
"GRANT EXECUTE ON FUNCTION pg_catalog.pg_last_wal_replay_lsn() TO backup; "
3171+
"GRANT EXECUTE ON FUNCTION pg_catalog.txid_current_snapshot() TO backup; "
3172+
"GRANT EXECUTE ON FUNCTION pg_catalog.txid_snapshot_xmax(txid_snapshot) TO backup;"
3173+
)
3174+
3175+
if self.ptrack:
3176+
for fname in [
3177+
'pg_catalog.oideq(oid, oid)',
3178+
'pg_catalog.ptrack_version()',
3179+
'pg_catalog.pg_ptrack_clear()',
3180+
'pg_catalog.pg_ptrack_control_lsn()',
3181+
'pg_catalog.pg_ptrack_get_and_clear_db(oid, oid)',
3182+
'pg_catalog.pg_ptrack_get_and_clear(oid, oid)',
3183+
'pg_catalog.pg_ptrack_get_block_2(oid, oid, oid, bigint)',
3184+
'pg_catalog.pg_stop_backup()']:
3185+
3186+
node.safe_psql(
3187+
"backupdb",
3188+
"GRANT EXECUTE ON FUNCTION {0} "
3189+
"TO backup".format(fname))
3190+
3191+
# FULL backup without database_map
3192+
backup_id = self.backup_node(
3193+
backup_dir, 'node', node, datname='backupdb',
3194+
options=['--stream', "-U", "backup", '--log-level-file=verbose'])
3195+
3196+
pgdata = self.pgdata_content(node.data_dir)
3197+
3198+
node_restored = self.make_simple_node(
3199+
base_dir=os.path.join(module_name, fname, 'node_restored'))
3200+
node_restored.cleanup()
3201+
3202+
# backup has missing database_map and that is legal
3203+
try:
3204+
self.restore_node(
3205+
backup_dir, 'node', node_restored,
3206+
options=["--db-exclude=db5", "--db-exclude=db9"])
3207+
self.assertEqual(
3208+
1, 0,
3209+
"Expecting Error because user do not have pg_database access.\n "
3210+
"Output: {0} \n CMD: {1}".format(
3211+
self.output, self.cmd))
3212+
except ProbackupException as e:
3213+
self.assertIn(
3214+
"ERROR: Backup {0} doesn't contain a database_map, "
3215+
"partial restore is impossible.".format(
3216+
backup_id), e.message,
3217+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
3218+
repr(e.message), self.cmd))
3219+
3220+
try:
3221+
self.restore_node(
3222+
backup_dir, 'node', node_restored,
3223+
options=["--db-include=db1"])
3224+
self.assertEqual(
3225+
1, 0,
3226+
"Expecting Error because user do not have pg_database access.\n "
3227+
"Output: {0} \n CMD: {1}".format(
3228+
self.output, self.cmd))
3229+
except ProbackupException as e:
3230+
self.assertIn(
3231+
"ERROR: Backup {0} doesn't contain a database_map, "
3232+
"partial restore is impossible.".format(
3233+
backup_id), e.message,
3234+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
3235+
repr(e.message), self.cmd))
3236+
3237+
# check that simple restore is still possible
3238+
self.restore_node(backup_dir, 'node', node_restored)
3239+
3240+
pgdata_restored = self.pgdata_content(node_restored.data_dir)
3241+
self.compare_pgdata(pgdata, pgdata_restored)
3242+
3243+
# Clean after yourself
3244+
self.del_test_dir(module_name, fname)

0 commit comments

Comments
 (0)