Skip to content

Commit f75fbbf

Browse files
committed
Added/Updated tests\bugs\gh_6413_test.py: Confirmed on 6.0.0.799.
1 parent d23df8e commit f75fbbf

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

tests/bugs/gh_6413_test.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#coding:utf-8
2+
3+
"""
4+
ID: n/a
5+
ISSUE: https://github.com/FirebirdSQL/firebird/issues/6413
6+
TITLE: Data pages of newly gbak restored databases should be marked as "swept"
7+
DESCRIPTION:
8+
NOTES:
9+
[17.07.2025] pzotov
10+
Test adds a table and fill it with some data.
11+
Then we make b/r and obtain statistics using 'gstat -d ...'
12+
Output will contain lines like: "Primary pages: 1, secondary pages: 1, swept pages: 1"
13+
We have to check that in every such line value of primary pages is equal to swept pages
14+
or it can be greater but NO MORE than for <MAX_NUM_OF_EMPTY_PAGES> because of pages
15+
allocation algorithm.
16+
17+
Explained by Vlad, 17.07.2025 16:34.
18+
Confirmed on 6.0.0.799
19+
Checked on 6.0.0.1020 ; 5.0.3.1683
20+
"""
21+
import string
22+
import locale
23+
import re
24+
from io import BytesIO
25+
from firebird.driver import SrvRestoreFlag
26+
import pytest
27+
from firebird.qa import *
28+
29+
init_sql = """
30+
set bail on;
31+
recreate table test(id int generated by default as identity, s varchar(32760));
32+
set term ^;
33+
execute block as
34+
declare n int = 1000;
35+
declare i int = 0;
36+
begin
37+
while (i < n) do
38+
begin
39+
insert into test(s) values(lpad('', rand()*32760, uuid_to_char(gen_uuid())));
40+
i = i + 1;
41+
end
42+
end^
43+
set term ;^
44+
commit;
45+
"""
46+
db = db_factory(init = init_sql, charset = 'win1251', page_size = 8192)
47+
48+
act = python_act('db')
49+
50+
#-----------------------------------------------------------
51+
52+
REMOVE_PUNCT = str.maketrans('', '', string.punctuation)
53+
MAX_NUM_OF_EMPTY_PAGES = 7
54+
EXPECTED_MSG = f'Expected: no lines with difference between primary and swept pages GREATER than {MAX_NUM_OF_EMPTY_PAGES}'
55+
56+
@pytest.mark.version('>=5.0.3')
57+
def test_1(act: Action, capsys):
58+
backup = BytesIO()
59+
with act.connect_server() as srv:
60+
srv.database.local_backup(database = act.db.db_path, backup_stream = backup)
61+
backup.seek(0)
62+
srv.database.local_restore(backup_stream = backup, database = act.db.db_path, flags = SrvRestoreFlag.REPLACE)
63+
64+
act.gstat(switches=['-d' ], io_enc = locale.getpreferredencoding())
65+
# Primary pages: 1, secondary pages: 1, swept pages: 1
66+
# 0 1 2 3 4 5 6 7 8
67+
p_swept_pages = re.compile(r'Primary pages(:)?\s+\d+.*swept pages(:)?\s+\d+', re.IGNORECASE)
68+
non_swept_line_indices = []
69+
for idx, line in enumerate(act.stdout.splitlines()):
70+
if p_swept_pages.search(line):
71+
tokens = line.split()
72+
if len(tokens) >= 9:
73+
try:
74+
primary_pages_count = int(tokens[2].translate(REMOVE_PUNCT))
75+
swept_pages_count = int(tokens[8].translate(REMOVE_PUNCT))
76+
if primary_pages_count - swept_pages_count > MAX_NUM_OF_EMPTY_PAGES:
77+
non_swept_line_indices.append( (idx, line) )
78+
except ValueError as e:
79+
print(e.__str__())
80+
else:
81+
print('Line does not contain all expected tokens: "{line=}"')
82+
83+
if non_swept_line_indices:
84+
print(f'At least one line contains difference between primary and swept pages GREATER than {MAX_NUM_OF_EMPTY_PAGES}:')
85+
for p in non_swept_line_indices:
86+
print(f'Line #{p[0]}, text: {p[1].strip()}')
87+
else:
88+
print(EXPECTED_MSG)
89+
90+
act.expected_stdout = EXPECTED_MSG
91+
act.stdout = capsys.readouterr().out
92+
assert act.clean_stdout == act.clean_expected_stdout

0 commit comments

Comments
 (0)