6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 13:33:07 +01:00
firebird-qa/tests/bugs/gh_7255_test.py

145 lines
5.4 KiB
Python
Raw Permalink Normal View History

#coding:utf-8
"""
ID: issue-7255
ISSUE: https://github.com/FirebirdSQL/firebird/issues/7255
TITLE: READ COMMITTED READ CONSISTENCY mode is broken in Classic / SuperClassic on Linux (the newly created users are not visible to execute statement)
DESCRIPTION:
Issue can be reproduced only if firebird.conf contains ReadConsistency = 1.
Problem will NOT appear if this parameter is set to 0 and we start transactions as 'READ COMMITTED READ CONSISTENCY'.
Because of that, it was decided to make copy of firebird.conf, read its content and remote any line with 'ReadConsistency'.
Then we add new line with ReadConsistency = 1 and OVERWRITE firebird.conf.
After this, we run ISQL with script similar to provided in the ticket.
Output must display name of new user and TIL of his transaction ('read committed read consistency') that is seen in procedure sp_main.
Finally, we revert changes in firebir.conf using its original copy.
All these actions are enclosed in the try/except/finally block.
NOTES:
### ACHTUNG ###
Test tries temporary to change content of firebird.conf. In any outcome, this content will be restored at final point.
Confirmed bug on 5.0.0.599, Classic. LINUX only.
Checked on 5.0.0.1397, 4.0.5.3098.
Command switch '--disable-db-cache' must be used if this test is running under 5.0.0.999 after some fresh FB with same ODS was tested.
Otherwise "internal Firebird consistency check (decompression overran buffer (179), file: sqz.cpp line: 293)" will raise.
Example:
/opt/distr/venv/bin/pytest --disable-db-cache -vv --tb=long --server qa_rundaily_FB50 tests/bugs/gh_7255_test.py
"""
import shutil
import pytest
import locale
import re
import time
import platform
from pathlib import Path
from firebird.qa import *
db = db_factory(async_write = True)
act = python_act('db', substitutions = [('[ \t]+', ' ')])
fbcfg_bak = temp_file('firebird.conf')
p_read_consist_param = re.compile('ReadConsistency\\s*=\\s*(0|1)', re.IGNORECASE)
TMP_USR_NAME = 'tmp$7255'
@pytest.mark.skipif(platform.system() == 'Windows', reason='Reproduced on Linux only.')
@pytest.mark.version('>=4.0.3')
def test_1(act: Action, fbcfg_bak: Path, capsys):
if act.vars['server-arch'].lower() != 'classic':
pytest.skip('Can be reproduced only for Servermode = Classic.')
fbcfg_file = act.vars['home-dir'] / 'firebird.conf'
shutil.copy2(fbcfg_file, fbcfg_bak)
try:
fbcfg_ini = fbcfg_file.read_text(encoding='utf-8').splitlines()
fbcfg_new = []
for x in fbcfg_ini:
if p_read_consist_param.search(x):
pass
else:
fbcfg_new.append(x)
fbcfg_new.append('ReadConsistency = 1')
fbcfg_file.write_text('\n'.join(fbcfg_new), encoding='utf-8' )
test_sql = f"""
set list on;
commit;
SET KEEP_TRAN_PARAMS ON;
SET TRANSACTION READ COMMITTED READ CONSISTENCY;
create or alter user {TMP_USR_NAME} password '123';
commit;
set term ^;
create or alter procedure sp_main(
a_usr varchar(31), a_pwd varchar(31)
) returns(
who varchar(50)
,til varchar(50)
) as
begin
for
execute statement
q'#select #'
|| q'# a.mon$user as who #'
|| q'# ,decode( #'
|| q'# t.mon$isolation_mode #'
|| q'# ,0, 'snapshot table stability' #'
|| q'# ,1, 'concurrency (snapshot)' #'
|| q'# ,2, 'read committed record version' #'
|| q'# ,3, 'read committed no record version' #'
|| q'# ,4, 'read committed read consistency' #'
|| q'# ) as til #'
|| q'#from mon$attachments a #'
|| q'#join mon$transactions t on a.mon$attachment_id = t.mon$attachment_id #'
|| q'#where a.mon$attachment_id = current_connection and t.mon$state = 1 #'
as user a_usr password a_pwd
into who, til
do
suspend;
end
^
set term ;^
commit;
grant execute on procedure sp_main to {TMP_USR_NAME};
commit;
-- wait 10 seconds and it will work
set term ^;
execute block returns(
who varchar(50)
,til varchar(50)
) as
begin
for
execute statement ('select who, til from sp_main(:u, :p)') ( u := '{TMP_USR_NAME}', p := '123' )
into who, til
do
suspend;
end
^
set term ;^
commit;
drop user {TMP_USR_NAME};
commit;
"""
act.isql(switches = ['-q'], input = test_sql, combine_output = True, io_enc = locale.getpreferredencoding())
except OSError as e:
print(e)
finally:
shutil.copy2(fbcfg_bak, act.vars['home-dir'] / 'firebird.conf')
act.expected_stdout = f"""
WHO {TMP_USR_NAME.upper()}
TIL read committed read consistency
"""
# act.stdout = capsys.readouterr().out
assert act.clean_stdout == act.clean_expected_stdout