Skip to content

Commit 39aa89a

Browse files
committed
new tests for ptrack
1 parent 595982a commit 39aa89a

File tree

4 files changed

+122
-49
lines changed

4 files changed

+122
-49
lines changed

tests/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,13 @@ def load_tests(loader, tests, pattern):
3737
suite.addTests(loader.loadTestsFromModule(compression))
3838
suite.addTests(loader.loadTestsFromModule(page))
3939
suite.addTests(loader.loadTestsFromModule(archive))
40-
suite.addTests(loader.loadTestsFromModule(cfs_backup))
41-
suite.addTests(loader.loadTestsFromModule(cfs_restore))
42-
suite.addTests(loader.loadTestsFromModule(cfs_validate_backup))
40+
# suite.addTests(loader.loadTestsFromModule(cfs_backup))
41+
# suite.addTests(loader.loadTestsFromModule(cfs_restore))
42+
# suite.addTests(loader.loadTestsFromModule(cfs_validate_backup))
4343

4444
return suite
4545

46+
# test_pgpro434_2 unexpected success
4647
# ToDo:
4748
# archive:
4849
# discrepancy of instance`s SYSTEMID and node`s SYSTEMID should lead to archive-push refusal to work

tests/helpers/ptrack_helpers.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -255,32 +255,34 @@ def get_md5_per_page_for_fork(self, file, size_in_pages):
255255
return md5_per_page
256256

257257
def get_ptrack_bits_per_page_for_fork(self, node, file, size=[]):
258-
if len(size) > 1:
259-
if size[0] > size[1]:
260-
size = size[0]
261-
else:
262-
size = size[1]
263-
else:
264-
size = size[0]
265258

266259
if self.get_pgpro_edition(node) == 'enterprise':
267260
header_size = 48
268261
else:
269262
header_size = 24
270263
ptrack_bits_for_fork = []
264+
265+
page_body_size = 8192-header_size
271266
byte_size = os.path.getsize(file + '_ptrack')
272-
byte_size_minus_header = byte_size - header_size
267+
npages = byte_size/8192
268+
if byte_size%8192 != 0:
269+
print('Ptrack page is not 8k aligned')
270+
sys.exit(1)
271+
273272
file = os.open(file + '_ptrack', os.O_RDONLY)
274-
os.lseek(file, header_size, 0)
275-
lots_of_bytes = os.read(file, byte_size_minus_header)
276-
byte_list = [lots_of_bytes[i:i+1] for i in range(len(lots_of_bytes))]
277-
for byte in byte_list:
278-
#byte_inverted = bin(int(byte, base=16))[2:][::-1]
279-
#bits = (byte >> x) & 1 for x in range(7, -1, -1)
280-
byte_inverted = bin(ord(byte))[2:].rjust(8, '0')[::-1]
281-
for bit in byte_inverted:
282-
if len(ptrack_bits_for_fork) < size:
283-
ptrack_bits_for_fork.append(int(bit))
273+
274+
for page in range(npages):
275+
offset = 8192*page+header_size
276+
os.lseek(file, offset, 0)
277+
lots_of_bytes = os.read(file, page_body_size)
278+
byte_list = [lots_of_bytes[i:i+1] for i in range(len(lots_of_bytes))]
279+
for byte in byte_list:
280+
#byte_inverted = bin(int(byte, base=16))[2:][::-1]
281+
#bits = (byte >> x) & 1 for x in range(7, -1, -1)
282+
byte_inverted = bin(ord(byte))[2:].rjust(8, '0')[::-1]
283+
for bit in byte_inverted:
284+
# if len(ptrack_bits_for_fork) < size:
285+
ptrack_bits_for_fork.append(int(bit))
284286
os.close(file)
285287
return ptrack_bits_for_fork
286288

tests/page.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import unittest
33
from .helpers.ptrack_helpers import ProbackupTest, ProbackupException
44
from datetime import datetime, timedelta
5-
import subprocess
5+
import subprocess, time
66

77

88
module_name = 'page'
@@ -148,3 +148,69 @@ def test_page_archive(self):
148148

149149
# Clean after yourself
150150
self.del_test_dir(module_name, fname)
151+
152+
# @unittest.skip("skip")
153+
def test_page_multiple_segments(self):
154+
"""Make node, create table with multiple segments, write some data to it, check page and data correctness"""
155+
fname = self.id().split('.')[3]
156+
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
157+
node = self.make_simple_node(base_dir="{0}/{1}/node".format(module_name, fname),
158+
set_replication=True,
159+
initdb_params=['--data-checksums'],
160+
pg_options={'wal_level': 'replica', 'max_wal_senders': '2',
161+
'ptrack_enable': 'on', 'fsync': 'off', 'shared_buffers': '1GB',
162+
'maintenance_work_mem': '1GB', 'autovacuum': 'off', 'full_page_writes': 'off'}
163+
)
164+
165+
self.init_pb(backup_dir)
166+
self.add_instance(backup_dir, 'node', node)
167+
self.set_archiving(backup_dir, 'node', node)
168+
node.start()
169+
170+
self.create_tblspace_in_node(node, 'somedata')
171+
172+
# CREATE TABLE
173+
node.pgbench_init(scale=100, options=['--tablespace=somedata'])
174+
# FULL BACKUP
175+
self.backup_node(backup_dir, 'node', node)
176+
177+
# PGBENCH STUFF
178+
pgbench = node.pgbench(options=['-T', '150', '-c', '2', '--no-vacuum'])
179+
pgbench.wait()
180+
node.safe_psql("postgres", "checkpoint")
181+
182+
# GET LOGICAL CONTENT FROM NODE
183+
result = node.safe_psql("postgres", "select * from pgbench_accounts")
184+
# PAGE BACKUP
185+
self.backup_node(backup_dir, 'node', node, backup_type='page', options=["-l", "--log-level=verbose"])
186+
# GET PHYSICAL CONTENT FROM NODE
187+
pgdata = self.pgdata_content(node.data_dir)
188+
189+
# RESTORE NODE
190+
restored_node = self.make_simple_node(base_dir="{0}/{1}/restored_node".format(module_name, fname))
191+
restored_node.cleanup()
192+
tblspc_path = self.get_tblspace_path(node, 'somedata')
193+
tblspc_path_new = self.get_tblspace_path(restored_node, 'somedata_restored')
194+
195+
self.restore_node(backup_dir, 'node', restored_node, options=[
196+
"-j", "4", "-T", "{0}={1}".format(tblspc_path, tblspc_path_new)])
197+
198+
# GET PHYSICAL CONTENT FROM NODE_RESTORED
199+
pgdata_restored = self.pgdata_content(restored_node.data_dir)
200+
201+
# START RESTORED NODE
202+
restored_node.append_conf("postgresql.auto.conf", "port = {0}".format(restored_node.port))
203+
restored_node.start()
204+
while restored_node.safe_psql("postgres", "select pg_is_in_recovery()") == 't\n':
205+
time.sleep(1)
206+
207+
result_new = restored_node.safe_psql("postgres", "select * from pgbench_accounts")
208+
209+
# COMPARE RESTORED FILES
210+
self.assertEqual(result, result_new, 'data is lost')
211+
212+
if self.paranoia:
213+
self.compare_pgdata(pgdata, pgdata_restored)
214+
215+
# Clean after yourself
216+
self.del_test_dir(module_name, fname)

tests/ptrack.py

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -391,14 +391,15 @@ def test_create_db(self):
391391
node.safe_psql("postgres",
392392
"create table t_heap as select i as id, md5(i::text) as text, md5(i::text)::tsvector as tsvector from generate_series(0,100) i")
393393
node.safe_psql("postgres", "SELECT * FROM t_heap")
394-
self.backup_node(backup_dir, 'node', node, options=["--stream"])
394+
self.backup_node(backup_dir, 'node', node, options=["--stream", "-l", "--log-level=verbose"])
395+
#sys.exit(1)
395396

396397
# CREATE DATABASE DB1
397398
node.safe_psql("postgres", "create database db1")
398399
node.safe_psql("db1", "create table t_heap as select i as id, md5(i::text) as text, md5(i::text)::tsvector as tsvector from generate_series(0,100) i")
399400

400401
# PTRACK BACKUP
401-
backup_id = self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream"])
402+
backup_id = self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream", "-l", "--log-level=verbose"])
402403
pgdata = self.pgdata_content(node.data_dir)
403404

404405
# RESTORE
@@ -475,12 +476,13 @@ def test_alter_table_set_tablespace_ptrack(self):
475476
node.safe_psql(
476477
"postgres", "alter table t_heap set tablespace somedata_new")
477478

479+
# sys.exit(1)
478480
# PTRACK BACKUP
479481
result = node.safe_psql("postgres", "select * from t_heap")
480-
self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream"])
482+
self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream", "-l", "--log-level=verbose"])
481483
pgdata = self.pgdata_content(node.data_dir)
482-
node.stop()
483-
node.cleanup()
484+
#node.stop()
485+
#node.cleanup()
484486

485487
# RESTORE
486488
node_restored = self.make_simple_node(base_dir="{0}/{1}/node_restored".format(module_name, fname))
@@ -533,9 +535,10 @@ def test_alter_database_set_tablespace_ptrack(self):
533535
# ALTER DATABASE
534536
node.safe_psql("template1",
535537
"alter database postgres set tablespace somedata")
538+
#sys.exit(1)
536539

537540
# PTRACK BACKUP
538-
self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream"])
541+
self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream", "-l", '--log-level=verbose'])
539542
pgdata= self.pgdata_content(node.data_dir)
540543
node.stop()
541544

@@ -625,14 +628,17 @@ def test_ptrack_alter_tablespace(self):
625628
node = self.make_simple_node(base_dir="{0}/{1}/node".format(module_name, fname),
626629
set_replication=True,
627630
initdb_params=['--data-checksums'],
628-
pg_options={'wal_level': 'replica', 'max_wal_senders': '2', 'checkpoint_timeout': '30s', 'ptrack_enable': 'on'}
631+
pg_options={'wal_level': 'replica', 'max_wal_senders': '2',
632+
'checkpoint_timeout': '30s', 'ptrack_enable': 'on',
633+
'autovacuum': 'off'}
629634
)
630635

631636
self.init_pb(backup_dir)
632637
self.add_instance(backup_dir, 'node', node)
633638
node.start()
634639

635640
self.create_tblspace_in_node(node, 'somedata')
641+
tblspc_path = self.get_tblspace_path(node, 'somedata')
636642

637643
# CREATE TABLE
638644
node.safe_psql(
@@ -645,19 +651,23 @@ def test_ptrack_alter_tablespace(self):
645651
# Move table to separate tablespace
646652
node.safe_psql(
647653
"postgres", "alter table t_heap set tablespace somedata")
654+
# GET LOGICAL CONTENT FROM NODE
655+
result = node.safe_psql("postgres", "select * from t_heap")
656+
648657
# FIRTS PTRACK BACKUP
649-
self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream"])
658+
self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream", "-l", "--log-level=verbose"])
659+
660+
# GET PHYSICAL CONTENT FROM NODE
650661
pgdata = self.pgdata_content(node.data_dir)
651662

652-
# Restore ptrack backup and check table consistency
663+
# Restore ptrack backup
653664
restored_node = self.make_simple_node(base_dir="{0}/{1}/restored_node".format(module_name, fname))
654665
restored_node.cleanup()
655-
tblspc_path = self.get_tblspace_path(node, 'somedata')
656666
tblspc_path_new = self.get_tblspace_path(restored_node, 'somedata_restored')
657667
self.restore_node(backup_dir, 'node', restored_node, options=[
658668
"-j", "4", "-T", "{0}={1}".format(tblspc_path, tblspc_path_new)])
659-
result = node.safe_psql("postgres", "select * from t_heap")
660669

670+
# GET PHYSICAL CONTENT FROM RESTORED NODE
661671
pgdata_restored = self.pgdata_content(restored_node.data_dir)
662672

663673
# START RESTORED NODE
@@ -666,6 +676,7 @@ def test_ptrack_alter_tablespace(self):
666676
while restored_node.safe_psql("postgres", "select pg_is_in_recovery()") == 't\n':
667677
time.sleep(1)
668678

679+
# COMPARE LOGICAL CONTENT
669680
result_new = restored_node.safe_psql("postgres", "select * from t_heap")
670681
self.assertEqual(result, result_new)
671682

@@ -680,18 +691,18 @@ def test_ptrack_alter_tablespace(self):
680691
node.safe_psql(
681692
"postgres", "alter table t_heap set tablespace pg_default")
682693
# SECOND PTRACK BACKUP
683-
self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream"])
694+
self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream", "-l", "--log-level=verbose"])
684695
pgdata = self.pgdata_content(node.data_dir)
685696

686697
# Restore second ptrack backup and check table consistency
687698
self.restore_node(backup_dir, 'node', restored_node, options=[
688699
"-j", "4", "-T", "{0}={1}".format(tblspc_path, tblspc_path_new)])
689-
restored_node.append_conf("postgresql.auto.conf", "port = {0}".format(restored_node.port))
690700

691-
# GET PHYSICAL CONTENT
701+
# GET PHYSICAL CONTENT FROM RESTORED NODE
692702
pgdata_restored = self.pgdata_content(restored_node.data_dir)
693703

694704
# START RESTORED NODE
705+
restored_node.append_conf("postgresql.auto.conf", "port = {0}".format(restored_node.port))
695706
restored_node.start()
696707
while restored_node.safe_psql("postgres", "select pg_is_in_recovery()") == 't\n':
697708
time.sleep(1)
@@ -707,7 +718,7 @@ def test_ptrack_alter_tablespace(self):
707718
self.del_test_dir(module_name, fname)
708719

709720
# @unittest.skip("skip")
710-
def test_relation_with_multiple_segments(self):
721+
def test_ptrack_multiple_segments(self):
711722
"""Make node, create table, alter table tablespace, take ptrack backup, move table from tablespace, take ptrack backup"""
712723
fname = self.id().split('.')[3]
713724
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
@@ -729,38 +740,31 @@ def test_relation_with_multiple_segments(self):
729740
# CREATE TABLE
730741
node.pgbench_init(scale=100, options=['--tablespace=somedata'])
731742
# FULL BACKUP
732-
#self.backup_node(backup_dir, 'node', node, options=["--stream"])
733743
self.backup_node(backup_dir, 'node', node)
734744

735745
# PTRACK STUFF
736746
idx_ptrack = {'type': 'heap'}
737-
738747
idx_ptrack['path'] = self.get_fork_path(node, 'pgbench_accounts')
739748
idx_ptrack['old_size'] = self.get_fork_size(node, 'pgbench_accounts')
740749
idx_ptrack['old_pages'] = self.get_md5_per_page_for_fork(
741750
idx_ptrack['path'], idx_ptrack['old_size'])
742751

743-
pgbench = node.pgbench(options=['-T', '50', '-c', '2', '--no-vacuum'])
752+
pgbench = node.pgbench(options=['-T', '150', '-c', '2', '--no-vacuum'])
744753
pgbench.wait()
745-
#node.safe_psql("postgres", "update pgbench_accounts set bid = bid +1")
746754
node.safe_psql("postgres", "checkpoint")
747755

748756
idx_ptrack['new_size'] = self.get_fork_size(node, 'pgbench_accounts')
749757
idx_ptrack['new_pages'] = self.get_md5_per_page_for_fork(idx_ptrack['path'], idx_ptrack['new_size'])
750-
idx_ptrack['ptrack'] = self.get_ptrack_bits_per_page_for_fork(
751-
node, idx_ptrack['path'], [idx_ptrack['old_size'], idx_ptrack['new_size']])
752-
758+
idx_ptrack['ptrack'] = self.get_ptrack_bits_per_page_for_fork(node, idx_ptrack['path'])
753759
self.check_ptrack_sanity(idx_ptrack)
754-
## PTRACK STUFF
760+
755761

756762
# GET LOGICAL CONTENT FROM NODE
757763
result = node.safe_psql("postgres", "select * from pgbench_accounts")
758764
# FIRTS PTRACK BACKUP
759-
#self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["--stream"])
760-
self.backup_node(backup_dir, 'node', node, backup_type='ptrack')
765+
self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=["-l", "--log-level=verbose"])
761766
# GET PHYSICAL CONTENT FROM NODE
762767
pgdata = self.pgdata_content(node.data_dir)
763-
#get_md5_per_page_for_fork
764768

765769
# RESTORE NODE
766770
restored_node = self.make_simple_node(base_dir="{0}/{1}/restored_node".format(module_name, fname))
@@ -789,4 +793,4 @@ def test_relation_with_multiple_segments(self):
789793
self.compare_pgdata(pgdata, pgdata_restored)
790794

791795
# Clean after yourself
792-
# self.del_test_dir(module_name, fname)
796+
self.del_test_dir(module_name, fname)

0 commit comments

Comments
 (0)