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

Test with trace refactoring and more Python tests

This commit is contained in:
Pavel Císař 2021-12-07 20:09:36 +01:00
parent c13d40082f
commit 76b49666fa
32 changed files with 1338 additions and 1478 deletions

View File

@ -40,7 +40,6 @@
# qmid: None
import pytest
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 2.5
@ -264,41 +263,21 @@ test_script_1 = """
set term ;^
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' #include_filter',
' exclude_filter = %no_trace%',
' log_connections = true',
' log_transactions = true',
' log_statement_finish = true',
' print_plan = true',
' print_perf = true',
' time_threshold = 0',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
trace_1 = ['exclude_filter = %no_trace%',
'log_connections = true',
'log_transactions = true',
'log_statement_finish = true',
'print_plan = true',
'print_perf = true',
'time_threshold = 0'
]
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
def test_1(act_1: Action):
with act_1.trace(db_events=trace_1):
act_1.isql(switches=['-n'], input=test_script_1)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
act_1.trace_to_stdout()
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -16,7 +16,6 @@
# qmid: None
import pytest
from threading import Thread, Barrier
from difflib import unified_diff
from firebird.qa import db_factory, python_act, Action
@ -482,65 +481,34 @@ select '*Лев Николаевич Толстой *
' from rdb$database;
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' include_filter = %(SELECT|INSERT|UPDATE|DELETE)%',
' exclude_filter = %no_trace%',
' log_connections = true',
' log_transactions = true',
' log_statement_prepare = true',
' log_statement_free = true',
' log_statement_start = true',
' log_statement_finish = true',
' log_trigger_start = true',
' log_trigger_finish = true',
' log_context = true',
' print_plan = true',
' print_perf = true',
' time_threshold = 0',
' max_sql_length = 5000',
' max_blr_length = 500',
' max_dyn_length = 500',
' max_arg_length = 80',
' max_arg_count = 30',
'}',
'services {',
' enabled = false',
' log_services = false',
' log_service_query = false',
'}']
with act.connect_server() as srv:
srv.encoding = 'utf8'
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
pass # we are not interested in trace output
trace_1 = ['include_filter = %(SELECT|INSERT|UPDATE|DELETE)%',
'exclude_filter = %no_trace%',
'log_connections = true',
'log_transactions = true',
'log_statement_prepare = true',
'log_statement_free = true',
'log_statement_start = true',
'log_statement_finish = true',
'log_trigger_start = true',
'log_trigger_finish = true',
'log_context = true',
'print_plan = true',
'print_perf = true',
'time_threshold = 0',
'max_sql_length = 5000',
'max_blr_length = 500',
'max_dyn_length = 500',
'max_arg_length = 80',
'max_arg_count = 30',
]
@pytest.mark.version('>=2.5.1')
def test_1(act_1: Action):
b = Barrier(2)
# Get content of firebird.log BEFORE test
with act_1.connect_server() as srv:
srv.info.get_log()
log_before = srv.readlines()
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
# RUN QUERY WITH NON-ASCII CHARACTERS
log_before = act_1.get_firebird_log()
with act_1.trace(db_events=trace_1, keep_log=False, encoding='utf8'):
act_1.isql(switches=['-n', '-q'], input=test_script_1)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
# Get content of firebird.log AFTER test
with act_1.connect_server() as srv:
srv.info.get_log()
log_after = srv.readlines()
log_after = act_1.get_firebird_log()
assert '\n'.join(unified_diff(log_before, log_after)) == ''

View File

@ -20,7 +20,6 @@
# qmid: None
import pytest
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 2.5
@ -188,37 +187,17 @@ expected_stdout_1 = """
SYSDBA:NONE, ISO88591, TCP
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' log_connections = true',
' time_threshold = 0',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line.upper())
trace_1 = ['log_connections = true',
'time_threshold = 0',
]
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
# make two connections with different charset
def test_1(act_1: Action):
with act_1.trace(db_events=trace_1):
with act_1.db.connect(charset='utf8'):
pass
with act_1.db.connect(charset='iso8859_1'):
pass
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
act_1.trace_to_stdout(upper=True)
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -33,8 +33,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from io import BytesIO
from firebird.qa import db_factory, python_act, Action, temp_file
from firebird.driver import SrvStatFlag
@ -267,43 +265,20 @@ expected_stdout_1 = """
"BACKUP DATABASE"
"""
def trace_session(act: Action, barrier: Barrier):
cfg30 = ['services',
'{',
' enabled = true',
' log_services = true',
' exclude_filter = "Database Stats"',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
barrier.wait()
for line in srv:
print(line.upper())
trace_1 = ['log_services = true',
'exclude_filter = "Database Stats"',
]
temp_file_1 = temp_file('test-file')
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys, temp_file_1):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
with act_1.connect_server() as srv:
# Make some service requests
b.wait()
def test_1(act_1: Action, temp_file_1):
with act_1.trace(svc_events=trace_1), act_1.connect_server() as srv:
srv.database.set_sweep_interval(database=act_1.db.db_path, interval=1234321)
srv.database.get_statistics(database=act_1.db.db_path, flags=SrvStatFlag.HDR_PAGES)
srv.wait()
srv.database.backup(database=act_1.db.db_path, backup=temp_file_1)
srv.wait()
#
time.sleep(2)
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(2.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
act_1.trace_to_stdout(upper=True)
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -20,8 +20,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 2.5.1
@ -197,35 +195,14 @@ expected_stdout_1 = """
ELEMENT "LOG_STATEMENT_FINISH": "FOO" IS NOT A VALID
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_statement_finish = foo',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line.upper())
trace_1 = ['time_threshold = 0',
'log_statement_finish = foo'
]
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
def test_1(act_1: Action):
with act_1.trace(db_events=trace_1):
act_1.isql(switches=['-n'], input='select 1 as c from rdb$database;')
time.sleep(2)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
act_1.trace_to_stdout(upper=True)
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -41,8 +41,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
from firebird.driver import DbWriteMode
@ -451,23 +449,10 @@ expected_stdout_1 = """
Check ratio_marks_to_row_count_for_GTT_PRESERVE_ROWS: OK
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' log_transactions = true',
' print_perf = true',
#' log_connections = true',
#' log_procedure_start = true',
#' log_procedure_finish = true',
' log_initfini = false',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
trace_1 = ['log_transactions = true',
'print_perf = true',
'log_initfini = false',
]
@pytest.mark.version('>=2.5.2')
def test_1(act_1: Action, capsys):
@ -482,29 +467,15 @@ def test_1(act_1: Action, capsys):
c.call_procedure('sp_fill_fix_tab', [NUM_ROWS_TO_BE_ADDED])
con.commit()
#
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
#
with act_1.trace(db_events=trace_1):
with act_1.db.connect() as con1:
c = con1.cursor()
c.call_procedure('sp_fill_gtt_sav_rows', [NUM_ROWS_TO_BE_ADDED])
con1.rollback()
with act_1.db.connect() as con2:
c = con2.cursor()
c.call_procedure('sp_fill_gtt_del_rows', [NUM_ROWS_TO_BE_ADDED])
con2.rollback()
# Somehow sleep is necessary otherwise "sp_fill_gtt_del_rows" will not show up in trace log
time.sleep(3)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(3.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
trace_output = capsys.readouterr().out
# Obtain statistics for table T_FIX_TAB in order to estimate numberof data pages
dp_cnt = 0
act_1.gstat(switches=['-a','-t', 'T_FIX_TAB', '-u', act_1.db.user, '-p', act_1.db.password])
@ -519,7 +490,7 @@ def test_1(act_1: Action, capsys):
gtt_del_marks = -1
gtt_del_trace = ''
gtt_sav_trace = ''
for line in trace_output.splitlines():
for line in act_1.trace_log:
if 'fetch' in line:
# 2.5.7:
# ['370', 'ms,', '1100', 'read(s),', '1358', 'write(s),', '410489', 'fetch(es),', '93294', 'mark(s)']
@ -568,7 +539,7 @@ def test_1(act_1: Action, capsys):
if failed_flag:
print('Trace for GTT PRESERVE rows: ' + gtt_sav_trace)
print('Trace for GTT DELETE rows: ' + gtt_del_trace)
#
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -28,8 +28,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 3.0
@ -277,54 +275,26 @@ expected_stdout_1 = """
Statement statistics detected for ROLLBACK
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' log_transactions = true',
' print_perf = true',
#' log_connections = true',
#' log_procedure_start = true',
#' log_procedure_finish = true',
' log_initfini = false',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
trace_1 = ['log_transactions = true',
'print_perf = true',
'log_initfini = false',
]
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
#
with act_1.trace(db_events=trace_1):
act_1.isql(switches=[], input=test_script_1)
# do NOT remove this otherwise trace log can contain only message about its start before being closed!
time.sleep(3)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(3.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
trace_output = capsys.readouterr().out
# Output log of trace session, with filtering only interested info:
# Performance header text (all excessive spaces will be removed before comparison - see below):
perf_header='Table Natural Index Update Insert Delete Backout Purge Expunge'
checked_events= {') COMMIT_TRANSACTION': 'commit',
') ROLLBACK_TRANSACTION': 'rollback',
') EXECUTE_STATEMENT': 'execute_statement',
') START_TRANSACTION': 'start_transaction'
}
i, k = 0, 0
watched_event = ''
for line in trace_output.splitlines():
for line in act_1.trace_log:
k += 1
e = ''.join([v.upper() for x, v in checked_events.items() if x in line])
watched_event = e if e else watched_event
@ -336,6 +306,7 @@ def test_1(act_1: Action, capsys):
print('Found performance block header')
if line.startswith('TFIX') or line.startswith('GTT_SSN') or line.startswith('GTT_TRA'):
print(f'Found table statistics for {line.split()[0]}')
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -11,9 +11,7 @@
# qmid: None
import pytest
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
from firebird.driver import DatabaseError
# version: 2.5
# resources: None
@ -193,39 +191,17 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_statement_finish = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
pass # We are not interested in trace output
trace_1 = ['time_threshold = 0',
'log_statement_finish = true',
]
@pytest.mark.version('>=2.5')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
# empty query
def test_1(act_1: Action):
with act_1.trace(db_events=trace_1, keep_log=False):
with act_1.db.connect() as con:
c = con.cursor()
try:
c.execute('') # This may crash the server
except Exception as exc:
except Exception:
pass
#
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
# If we got here, the server lives so test passed

View File

@ -21,8 +21,6 @@
import pytest
import re
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 2.5.2
@ -303,54 +301,30 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
def trace_session(act: Action, b: Barrier, log_sweep: bool):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_connections = true',
f' log_sweep = {"true" if log_sweep else "false"}',
' log_initfini = false',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line.upper())
def sweep_present(text: str) -> bool:
def sweep_present(trace_log) -> bool:
pattern = re.compile('\\s+sweep_(start|progress|finish)(\\s+|$)', re.IGNORECASE)
present = False
for line in text.splitlines():
for line in trace_log:
if pattern.search(line):
present = True
break
return present
def check_sweep(act_1: Action, log_sweep: bool):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b, log_sweep])
trace_thread.start()
b.wait()
with act_1.connect_server() as srv:
# Run sweep
cfg = ['time_threshold = 0',
'log_connections = true',
f'log_sweep = {"true" if log_sweep else "false"}',
'log_initfini = false',
]
with act_1.trace(db_events=cfg), act_1.connect_server() as srv:
srv.database.sweep(database=act_1.db.db_path)
# Stop trace
time.sleep(2)
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
def test_1(act_1: Action):
# Case 1 - sweep logged
check_sweep(act_1, True)
trace_log = capsys.readouterr().out
assert sweep_present(trace_log)
assert sweep_present(act_1.trace_log)
# Case 2 - sweep not logged
act_1.trace_log.clear()
check_sweep(act_1, False)
trace_log = capsys.readouterr().out
assert not sweep_present(trace_log)
assert not sweep_present(act_1.trace_log)

View File

@ -33,8 +33,6 @@
import pytest
import re
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 2.5.3
@ -262,44 +260,24 @@ expected_stdout_1 = """
param3 = smallint, "4"
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_statement_start = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
trace_1 = ['time_threshold = 0',
'log_statement_start = true',
]
@pytest.mark.version('>=2.5.3')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
with act_1.trace(db_events=trace_1):
act_1.isql(switches=['-n', '-q'], input='execute procedure sp_test(1, 2, 3, 4);')
time.sleep(2)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
#
trace_log = capsys.readouterr().out
# process trace
spcall_pattern = re.compile("execute procedure ")
params_pattern = re.compile("param[0-9]{1} = ")
flag = False
for line in trace_log.splitlines():
for line in act_1.trace_log:
if spcall_pattern.match(line):
flag = True
if flag and params_pattern.match(line):
print(line)
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -55,7 +55,6 @@ import time
import re
import subprocess
from datetime import datetime
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
from firebird.driver import DbWriteMode, ShutdownMethod, ShutdownMode
@ -522,23 +521,13 @@ expected_stdout_1_b = """
Trace log parsing. Found triggers before sweep finish: EXPECTED (equals to planned).
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_statement_start = true',
' log_initfini = false',
' log_errors = true',
' log_sweep = true',
' log_trigger_finish = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
trace_1 = ['time_threshold = 0',
'log_statement_start = true',
'log_initfini = false',
'log_errors = true',
'log_sweep = true',
'log_trigger_finish = true',
]
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
@ -619,10 +608,7 @@ def test_1(act_1: Action, capsys):
with act_1.connect_server() as srv:
srv.database.set_write_mode(database=act_1.db.db_path, mode=DbWriteMode.SYNC)
# Trace
b_trace = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b_trace])
trace_thread.start()
b_trace.wait()
with act_1.trace(db_events=trace_1):
# Traced action
# Now we run SWEEP in child thread (asynchronous) and while it will work - try to establish several attachments.
sweeper = subprocess.Popen([act_1.vars['gfix'], '-sweep', '-user', act_1.db.user,
@ -661,15 +647,7 @@ def test_1(act_1: Action, capsys):
finally:
# Kill sweep
sweeper.terminate()
# stop trace
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
#
trace_log = capsys.readouterr().out
# Return database online in order to check number of attachments that were established
# while sweep was in work
with act_1.connect_server() as srv:
@ -716,7 +694,7 @@ def test_1(act_1: Action, capsys):
found_swp_finish = False
triggers_count_before_swp_start = 0
triggers_count_before_swp_finish = 0
for line in trace_log.splitlines():
for line in act_1.trace_log:
for p in allowed_patterns:
if result:= p.search(line):
what_found = result.group(0)
@ -728,9 +706,6 @@ def test_1(act_1: Action, capsys):
triggers_count_before_swp_start += (1 if not found_swp_start else 0)
triggers_count_before_swp_finish += (1 if found_swp_start and not found_swp_finish else 0)
#time.sleep(1)
#print('Trace log parsing. Found triggers before sweep start:', triggers_count_before_swp_start )
#print('Trace log parsing. Found triggers before sweep finish:', triggers_count_before_swp_finish )
print('Trace log parsing. Found triggers before sweep start:',
'EXPECTED (no triggers found).' if triggers_count_before_swp_start == 0
else f'UNEXPECTED: {triggers_count_before_swp_start} instead of 0.')

View File

@ -22,8 +22,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 2.5.3
@ -174,39 +172,17 @@ Command error: show database
Cannot get server version without database connection
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_errors = true',
' connection_id = 1234',
' log_connections = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line.upper())
trace_1 = ['time_threshold = 0',
'log_errors = true',
'connection_id = 1234',
'log_connections = true',
]
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
try:
def test_1(act_1: Action):
with act_1.trace(db_events=trace_1):
act_1.expected_stderr = expected_stderr_1
act_1.isql(switches=['-n'],
input="connect 'localhost:some_non_existent' user 'SYSDBA' password 'masterkey'; show database; show version;")
time.sleep(2)
finally:
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
# check that we are still kicking and got expected result from isql
# check that we are still kicking (via trace exit) and got expected result from isql
assert act_1.clean_stderr == act_1.clean_expected_stderr

View File

@ -50,7 +50,6 @@ import re
import time
import subprocess
from difflib import unified_diff
from threading import Thread, Barrier
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
from firebird.driver import DbWriteMode
@ -613,21 +612,11 @@ sweep_killer_out_1 = temp_file('killer.out')
sweep_killer_err_1 = temp_file('killer.err')
sweep_out_1 = temp_file('sweep.out')
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_errors = true',
' log_sweep = true',
' log_connections = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line.upper())
trace_1 = ['time_threshold = 0',
'log_errors = true',
'log_sweep = true',
'log_connections = true',
]
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys, sweep_killer_script_1: Path, sweep_killer_out_1: Path,
@ -681,11 +670,7 @@ def test_1(act_1: Action, capsys, sweep_killer_script_1: Path, sweep_killer_out_
# Change FW to ON (in order to make sweep life harder :))
srv.database.set_write_mode(database=act_1.db.db_path, mode=DbWriteMode.SYNC)
# Start trace
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
try:
with act_1.trace(db_events=trace_1):
# Launch (async.) ISQL which will make small delay and then kill GFIX attachment
with open(sweep_killer_out_1, 'w') as killer_out, \
open(sweep_killer_err_1, 'w') as killer_err:
@ -704,17 +689,7 @@ def test_1(act_1: Action, capsys, sweep_killer_script_1: Path, sweep_killer_out_
gfix_err = act_1.stderr
finally:
p_killer.terminate()
time.sleep(2)
finally:
# stop trace
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
#
trace_log = capsys.readouterr().out
# get firebird log after action
with act_1.connect_server() as srv:
srv.info.get_log()
@ -731,7 +706,7 @@ def test_1(act_1: Action, capsys, sweep_killer_script_1: Path, sweep_killer_out_
print('ISQL ERR:', line.upper())
# Trace log
found_sweep_failed = 0
for line in trace_log.splitlines():
for line in act_1.trace_log:
if 'SWEEP_FAILED' in line:
print('TRACE_LOG:' + (' '.join(line.split()).upper()))
found_sweep_failed = 1

View File

@ -23,9 +23,7 @@
# qmid: None
import pytest
import time
import re
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 3.0
@ -350,28 +348,16 @@ expected_stdout_1 = """
LOG_FUNC_ENABLED PARAM0 = BIGINT, "207936"
"""
def trace_session(act: Action, b: Barrier, logfunc: bool):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_errors = true',
' log_connections = true',
' log_transactions = true',
trace_1 = ['time_threshold = 0',
'log_errors = true',
'log_connections = true',
'log_transactions = true',
'log_function_start = true',
'log_function_finish = true'
]
if logfunc:
cfg30.append(' log_function_start = true')
cfg30.append(' log_function_finish = true')
cfg30.append('}')
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line.upper())
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
def test_1(act_1: Action):
output = []
trace_timestamp_prefix = '[.*\\s+]*20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3,4}\\s+\\(.+\\)'
func_start_ptn = re.compile(trace_timestamp_prefix + '\\s+(FAILED){0,1}\\s*EXECUTE_FUNCTION_START$', re.IGNORECASE)
@ -395,52 +381,27 @@ def test_1(act_1: Action, capsys):
commit;
"""
# Case 1: Trace functions enabled
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b, True])
trace_thread.start()
b.wait()
try:
with act_1.trace(db_events=trace_1):
act_1.isql(switches=['-n', '-q'], input=func_script % (123, 456))
time.sleep(2)
finally:
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
#
trace_log = capsys.readouterr().out
for line in trace_log.splitlines():
for line in act_1.trace_log:
if (func_start_ptn.search(line)
or func_finish_ptn.search(line)
or func_name_ptn.search(line)
or func_param_prn.search(line) ):
output.append('LOG_FUNC_ENABLED ' + line.upper())
# Case 1: Trace functions disabled
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b, False])
trace_thread.start()
b.wait()
try:
# Case 2: Trace functions disabled
act_1.trace_log.clear()
with act_1.trace(db_events=trace_1[:-2]):
act_1.isql(switches=['-n', '-q'], input=func_script % (789, 987))
time.sleep(2)
finally:
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
#
trace_log += capsys.readouterr().out
for line in trace_log.splitlines():
for line in act_1.trace_log:
if (func_start_ptn.search(line)
or func_finish_ptn.search(line)
or func_name_ptn.search(line)
or func_param_prn.search(line) ):
print('LOG_FUNC_DISABLED ' + line.upper())
# Test
output.append('LOG_FUNC_DISABLED ' + line.upper())
# Check
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.stdout = '\n'.join(output)

View File

@ -15,8 +15,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 3.0
@ -205,46 +203,25 @@ expected_stdout_1 = """
-> Table "TEST" Full Scan
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_initfini = false',
' print_plan = true',
' explain_plan = true',
' log_statement_prepare = true',
' include_filter=%(from|join)[[:whitespace:]]test%',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
trace_1 = ['time_threshold = 0',
'log_initfini = false',
'print_plan = true',
'explain_plan = true',
'log_statement_prepare = true',
'include_filter=%(from|join)[[:whitespace:]]test%',
]
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
# Trace ready, run tests
with act_1.trace(db_events=trace_1):
act_1.isql(switches=[], input='select count(*) from test;')
# Stop trace
time.sleep(2)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
# Check
# Process trace
show_line = 0
for line in capsys.readouterr().out.splitlines():
for line in act_1.trace_log:
show_line = (show_line + 1 if ('^' * 79) in line or show_line>0 else show_line)
if show_line > 1:
print(line)
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -21,8 +21,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 3.0
@ -258,28 +256,15 @@ expected_stdout_1 = """
Records affected: 1
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_initfini = false',
' log_errors = true',
' log_statement_finish = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
trace_1 = ['time_threshold = 0',
'log_initfini = false',
'log_errors = true',
'log_statement_finish = true',
]
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
with act_1.trace(db_events=trace_1):
isq_script = """
set list on;
set count on;
@ -293,19 +278,10 @@ def test_1(act_1: Action, capsys):
commit;
"""
act_1.isql(switches=['-n', '-user', 'tmp$no$such$user$4889', str(act_1.db.db_path)],
connect_db=False, input=isq_script)
output = act_1.stdout
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
trace_log = capsys.readouterr().out
#
# Process logs
connect_db=False, credentials=False, input=isq_script)
# Process trace log
i = 0
for line in trace_log.splitlines():
for line in act_1.trace_log:
if ') EXECUTE_STATEMENT_FINISH' in line:
i = 1
if i == 1 and '1 records fetched' in line:
@ -313,8 +289,8 @@ def test_1(act_1: Action, capsys):
print("OK: found text in trace related to EMBEDDED connect.")
break
if not i == 2:
print("FAILED to found text in trace related to EMBEDDED connect.")
print(output if output else "FAILED to print log from EMBEDDED connect: log is EMPTY.")
print("FAILED to find text in trace related to EMBEDDED connect.")
print(act_1.stdout if act_1.stdout else "FAILED to print log from EMBEDDED connect: log is EMPTY.")
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out

View File

@ -34,8 +34,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 2.5.5
@ -280,39 +278,17 @@ expected_stdout_1 = """
DETAIL_2100
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_initfini = false',
' log_statement_finish = true',
' print_perf = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
trace_1 = ['time_threshold = 0',
'log_initfini = false',
'log_statement_finish = true',
'print_perf = true',
]
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
with act_1.trace(db_events=trace_1):
act_1.isql(switches=[], input='set list on; select result from sp_test;')
time.sleep(2)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
act_1.trace_to_stdout()
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -17,8 +17,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action, user_factory, User
# version: 4.0
@ -26,9 +24,9 @@ from firebird.qa import db_factory, python_act, Action, user_factory, User
substitutions_1 = [('\t+', ' '),
('^((?!ROLE_|PREPARE_STATEMENT|EXECUTE_STATEMENT_START|EXECUTE_STATEMENT_FINISH).)*$', ''),
('.*PREPARE_STATEMENT', 'TRACE_LOG: PREPARE_STATEMENT'),
('.*EXECUTE_STATEMENT_START', 'TRACE_LOG: EXECUTE_STATEMENT_START'),
('.*EXECUTE_STATEMENT_FINISH', 'TRACE_LOG: EXECUTE_STATEMENT_FINISH')]
('.*PREPARE_STATEMENT', 'PREPARE_STATEMENT'),
('.*EXECUTE_STATEMENT_START', 'EXECUTE_STATEMENT_START'),
('.*EXECUTE_STATEMENT_FINISH', 'EXECUTE_STATEMENT_FINISH')]
init_script_1 = """"""
@ -214,29 +212,18 @@ expected_stdout_1_a = """
"""
expected_stdout_1_b = """
TRACE LOG: 2016-08-06T11:51:38.9360 (2536:01FD0CC8) PREPARE_STATEMENT
TRACE LOG: 2016-08-06T11:51:38.9360 (2536:01FD0CC8) EXECUTE_STATEMENT_START
TRACE LOG: 2016-08-06T11:51:38.9360 (2536:01FD0CC8) EXECUTE_STATEMENT_FINISH
2016-08-06T11:51:38.9360 (2536:01FD0CC8) PREPARE_STATEMENT
2016-08-06T11:51:38.9360 (2536:01FD0CC8) EXECUTE_STATEMENT_START
2016-08-06T11:51:38.9360 (2536:01FD0CC8) EXECUTE_STATEMENT_FINISH
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_initfini = false',
' log_statement_start = true',
' log_statement_finish = true',
' max_sql_length = 5000',
' log_statement_prepare = true',
'}']
with act.connect_server(user='TMP$C5269_2', password='456',
role='role_for_trace_any_attachment') as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
trace_1 = ['time_threshold = 0',
'log_initfini = false',
'log_statement_start = true',
'log_statement_finish = true',
'max_sql_length = 5000',
'log_statement_prepare = true',
]
user_1_a = user_factory(name='TMP$C5269_1', password='123')
user_1_b = user_factory(name='TMP$C5269_2', password='456')
@ -250,7 +237,7 @@ where p.rdb$user = upper('TMP$C5269_2');
"""
@pytest.mark.version('>=4.0')
def test_1(act_1: Action, user_1_a: User, user_1_b: User, capsys):
def test_1(act_1: Action, user_1_a: User, user_1_b: User):
with act_1.test_role('role_for_trace_any_attachment'):
with act_1.db.connect() as con:
con.execute_immediate('alter role role_for_trace_any_attachment set system privileges to TRACE_ANY_ATTACHMENT')
@ -261,25 +248,11 @@ def test_1(act_1: Action, user_1_a: User, user_1_b: User, capsys):
act_1.isql(switches=[], input=test_script_1_a)
assert act_1.clean_stdout == act_1.clean_expected_stdout
# Run trace
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
# Test
with act_1.db.connect(user='TMP$C5269_1', password='123') as con:
with act_1.trace(db_events=trace_1), act_1.db.connect(user='TMP$C5269_1', password='123') as con:
c = con.cursor()
c.execute('select current_user from rdb$database')
time.sleep(2)
# End trace
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
# Check
act_1.reset()
act_1.expected_stdout = expected_stdout_1_b
act_1.stdout = capsys.readouterr().out
act_1.trace_to_stdout()
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -34,8 +34,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from difflib import unified_diff
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
@ -291,37 +289,20 @@ act_1 = python_act('db_1', substitutions=substitutions_1)
temp_db_1 = temp_file('tmp_5273.fdb')
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
'database=%[\\\\/]tmp_5273.fdb',
'{',
' enabled = true',
' time_threshold = 0',
' log_sweep = true',
' log_errors = true',
' log_connections = true',
' log_statement_prepare = true',
' log_statement_start = true',
' log_statement_finish = true',
' log_statement_free = true',
' log_trigger_start = true',
' log_trigger_finish = true',
' print_perf = true',
' max_sql_length = 16384',
' max_log_size = 5000000',
'}',
'services',
'{',
' enabled = false',
' log_services = true',
' log_service_query = true',
' log_errors = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
trace_1 = ['time_threshold = 0',
'log_sweep = true',
'log_errors = true',
'log_connections = true',
'log_statement_prepare = true',
'log_statement_start = true',
'log_statement_finish = true',
'log_statement_free = true',
'log_trigger_start = true',
'log_trigger_finish = true',
'print_perf = true',
'max_sql_length = 16384',
'max_log_size = 5000000',
]
@pytest.mark.version('>=4.0')
def test_1(act_1: Action, temp_db_1: Path):
@ -337,20 +318,8 @@ def test_1(act_1: Action, temp_db_1: Path):
# Get content of firebird.log BEFORE test
log_before = act_1.get_firebird_log()
# Start trace
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
# Test
with act_1.trace(db_events=trace_1, keep_log=False, database=temp_db_1.name):
act_1.isql(switches=[], input=sql_ddl)
# Stop trace
time.sleep(2)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
# Get content of firebird.log AFTER test
log_after = act_1.get_firebird_log()
# Check

View File

@ -16,8 +16,6 @@
# qmid: None
import pytest
import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 4.0
@ -266,38 +264,19 @@ expected_stdout_1 = """
Y 2
"""
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=',
trace_1 = ['database=',
'{',
' enabled = true',
'enabled = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
pass
@pytest.mark.version('>=4.0')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
# Trace ready, run tests
with act_1.trace(config=trace_1, keep_log=False):
for i in range(3, 0, -1):
act_1.reset()
act_1.isql(switches=[], input=test_script_1)
print(act_1.stdout)
# Stop trace
time.sleep(2)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
# Check
act_1.reset()
act_1.expected_stdout = expected_stdout_1

View File

@ -9,6 +9,9 @@
# Repeat retrieveing content - it also should not contain any characters except newline.
# Checked on 2.5.7.27030, 4.0.0.465
#
# [pcisar] 7.12.2021
# Test requires direct changes to firebird.log which could require elevated privileges
#
# tracker_id: CORE-5418
# min_versions: ['2.5.7']
# versions: 2.5.7
@ -135,8 +138,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
@pytest.mark.version('>=2.5.7')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
pytest.skip("Requires direct changes to firebird.log")

View File

@ -22,7 +22,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 4.0
# resources: None
@ -107,15 +107,14 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
OK
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
if act_1.get_server_architecture() in ['CS', 'SC']:
with act_1.db.connect() as con:
att1 = con.info.id
with act_1.db.connect() as con:
att2 = con.info.id
assert att2 - att1 == 1

View File

@ -20,12 +20,14 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
from firebird.driver import TraAccessMode, TPB
# version: 3.0.2
# resources: None
substitutions_1 = [('Deferred: fb_arch=.*', 'Acceptable')]
#substitutions_1 = [('Deferred: fb_arch=.*', 'Acceptable')]
substitutions_1 = []
init_script_1 = """"""
@ -127,15 +129,30 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
Acceptable
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=3.0.2')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
tpb = TPB(access_mode=TraAccessMode.READ).get_buffer()
sql = 'select mon$page_writes from mon$io_stats where mon$stat_group=0'
if act_1.get_server_architecture() == 'SS':
with act_1.db.connect() as con:
with act_1.db.connect() as con2:
cur = con.cursor()
page_writes_before_test = cur.execute(sql).fetchone()[0]
con.commit()
#
ta = []
for i in range(50):
tra = con2.transaction_manager(default_tpb=tpb)
tra.begin()
ta.append(tra)
for tra in ta:
tra.rollback()
#
cur = con.cursor()
page_writes_after_test = cur.execute(sql).fetchone()[0]
con.commit()
#
assert page_writes_after_test - page_writes_before_test == 1

View File

@ -28,7 +28,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0.2
# resources: None
@ -189,7 +189,7 @@ db_1 = db_factory(page_size=8192, sql_dialect=3, init=init_script_1)
# from (
# select *
# from test -- ############################################################################
# where f01 = 1 and f02=0 -- <<< ::: NB ::: we check here 'f01 = 1' rather than 'f01 is NULL' <<< !!! <<<
# where f01 = 1 and f02 = 0 -- <<< ::: NB ::: we check here 'f01 = 1' rather than 'f01 is NULL' <<< !!! <<<
# order by f01, id -- ############################################################################
# )
# ;
@ -281,16 +281,86 @@ db_1 = db_factory(page_size=8192, sql_dialect=3, init=init_script_1)
# cleanup( (f_trc_cfg, f_trc_lst, f_trc_log, f_trc_err, sql_log, sql_err, sql_cmd) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
FETCHES_THRESHOLD = 80
expected_stdout_1 = """
PLAN (TEST ORDER TEST_F01_ID)
Number of fetches: acceptable.
"""
"""
async_init_script_1 = """
recreate table test
(
id int not null,
f01 int,
f02 int
);
set term ^;
create or alter procedure sp_add_init_data(a_rows_to_add int)
as
declare n int;
declare i int = 0;
begin
n = a_rows_to_add;
while ( i < n ) do
begin
insert into test(id, f01, f02) values( :i, nullif(mod(:i, :n/20), 0), iif( mod(:i,3)<2, 0, 1) )
returning :i+1 into i;
end
end
^
set term ^;
commit;
execute procedure sp_add_init_data( 300000 );
commit;
create index test_f01_id on test(f01, id);
create index test_f02_only on test(f02);
commit;
"""
test_script_1 = """
set list on;
select count(*) cnt_check
from (
select *
from test -- ############################################################################
where f01 = 1 and f02 = 0 -- <<< ::: NB ::: we check here 'f01 = 1' rather than 'f01 is NULL' <<< !!! <<<
order by f01, id -- ############################################################################
);
"""
trace_1 = ['time_threshold = 0',
'log_initfini = false',
'print_plan = true',
'print_perf = true',
'log_statement_finish = true',
]
@pytest.mark.version('>=3.0.2')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.db.set_async_write()
act_1.isql(switches=[], input=async_init_script_1)
#
with act_1.trace(db_events=trace_1):
act_1.reset()
act_1.isql(switches=[], input=test_script_1)
# Process trace
run_with_plan = ''
num_of_fetches = -1
for line in act_1.trace_log:
if line.lower().startswith('plan ('):
run_with_plan = line.strip()
if 'fetch(es)' in line:
words = line.split()
for k in range(len(words)):
if words[k].startswith('fetch'):
num_of_fetches = int(words[k - 1])
break
# Check
assert run_with_plan == 'PLAN (TEST ORDER TEST_F01_ID)'
assert num_of_fetches < FETCHES_THRESHOLD

View File

@ -29,7 +29,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0.2
# resources: None
@ -61,7 +61,7 @@ init_script_1 = """
end^
set term ;^
commit;
"""
"""
db_1 = db_factory(page_size=8192, sql_dialect=3, init=init_script_1)
@ -228,16 +228,40 @@ db_1 = db_factory(page_size=8192, sql_dialect=3, init=init_script_1)
# cleanup( (f_trc_cfg, f_trc_lst, f_trc_log, f_trc_err) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
fetches=3 occured 9 times
fetches=4 occured 1 times
"""
"""
trace_1 = ['time_threshold = 0',
'log_initfini = false',
'log_statement_finish = true',
'include_filter = "%(select % from test where x = ?)%"',
]
@pytest.mark.version('>=3.0.2')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
with act_1.trace(db_events=trace_1), act_1.db.connect() as con:
c = con.cursor()
c.call_procedure('sp_test')
# Process trace
fetches_distinct_amounts = {}
for line in act_1.trace_log:
if 'fetch(es)' in line:
words = line.split()
for k in range(len(words)):
if words[k].startswith('fetch'):
amount = words[k - 1]
if not amount in fetches_distinct_amounts:
fetches_distinct_amounts[amount] = 1
else:
fetches_distinct_amounts[amount] += 1
for k, v in sorted(fetches_distinct_amounts.items()):
print(f'fetches={k} occured {v} times')
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -18,7 +18,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0.2
# resources: None
@ -88,18 +88,39 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# os.remove(f_sql_err)
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
OK: column is integer > 0
OK: column is integer > 0
OK: column is integer > 0
OK: all columns are the same
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
test_script_1 = """
set term ^;
execute block as
begin
execute statement '-- table ''test'' has no trigger, DROP TRIGGER is skipped.';
end
^
execute block as
begin
execute statement '-- table ''test'' has no trigger, DROP TRIGGER is skipped.';
end
^
execute block as
begin
execute statement '-- table ''test'' has no trigger, DROP TRIGGER is skipped.';
end
^
set term ;^
"""
@pytest.mark.version('>=3.0.2')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.expected_stderr = "We expect errors"
act_1.isql(switches=[], input=test_script_1)
col_set = set()
for line in act_1.stderr.splitlines():
if '-Unexpected end of command' in line:
# -Unexpected end of command - line 0, column -45949567
# 0 1 2 3 4 5 6 7 8
col_number = line.split()[8]
assert col_number.isdigit() and int(col_number) > 0, "column is ZERO, NEGATIVE or NaN"
col_set.add(col_number)
assert len(col_set) == 1, "columns differ or empty set()"

View File

@ -30,7 +30,10 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import time
import re
from difflib import unified_diff
from firebird.qa import db_factory, python_act, Action
# version: 3.0.2
# resources: None
@ -198,12 +201,62 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( (f_diff_txt,f_fblog_before,f_fblog_after) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=3.0.2')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
log_before = act_1.get_firebird_log()
#
with act_1.db.connect() as con:
sp_test_ddl = """
create procedure sp_calc_val(a_id int) returns(val int) as
begin
val = a_id * 10;
suspend;
end
"""
con.execute_immediate(sp_test_ddl)
con.commit()
test_table_ddl = """
create table test(
id int primary key,
txt varchar(80),
calc_val computed by ((select val from sp_calc_val(test.id)))
)
"""
con.execute_immediate(test_table_ddl)
con.commit()
#
c = con.cursor()
c.execute('insert into test select row_number()over(), ascii_char(96 + row_number()over()) from rdb$types rows 7')
con.commit()
#
c.execute('select count(*), sum(calc_val) from test').fetchall()
#
sp_alter_ddl = """
alter procedure sp_calc_val (a_id int) returns (val int) as
begin
val = a_id * 7;
suspend;
end
"""
con.execute_immediate(sp_alter_ddl)
c.execute('select count(*), sum(calc_val) from test').fetchall()
con.commit()
c.execute('select count(*), sum(calc_val) from test').fetchall()
#
time.sleep(1)
#
log_after = act_1.get_firebird_log()
unexpected_patterns = [re.compile('\\s+internal\\s+Firebird\\s+consistency\\s+check', re.IGNORECASE)]
for line in unified_diff(log_before, log_after):
if line.startswith('+'):
match2some = list(filter(None, [p.search(line) for p in unexpected_patterns]))
if match2some:
print(f'UNEXPECTED: {line}')
#
act_1.expected_stdout = ''
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -35,7 +35,7 @@ init_script_1 = """
п1
';
commit;
"""
"""
db_1 = db_factory(charset='WIN1251', sql_dialect=3, init=init_script_1)
@ -92,18 +92,36 @@ db_1 = db_factory(charset='WIN1251', sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
test_script_1 = """
set blob all;
set list on;
select c.rdb$character_set_name as connection_cset, r.rdb$character_set_name as db_default_cset
from mon$attachments a
join rdb$character_sets c on a.mon$character_set_id = c.rdb$character_set_id
cross join rdb$database r where a.mon$attachment_id=current_connection;
select rdb$field_name, rdb$system_flag, rdb$description
from rdb$fields where rdb$description is not null;
"""
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
CONNECTION_CSET WIN1250
DB_DEFAULT_CSET WIN1251
"""
expected_stderr_1 = """
Statement failed, SQLSTATE = 22018
Cannot transliterate character between character sets
"""
"""
@pytest.mark.version('>=3.0.2')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q'], input=test_script_1, charset='WIN1250')
assert act_1.clean_stderr == act_1.clean_expected_stderr
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -3,7 +3,7 @@
# id: bugs.core_5470
# title: Trace INCLUDE_FILTER with [[:WHITESPACE:]]+ does not work when statement contains newline is issued
# decription:
# We create a list of several DDLs which all contain NEWLINE character(s) between jeyword and name of DB object.
# We create a list of several DDLs which all contain NEWLINE character(s) between keyword and name of DB object.
# Then we launch trace session and execute all these DDLs.
# Finally we check whether trace log contains every DDL or not.
# Expected result: text of every DDL should be FOUND in the trace log.
@ -16,7 +16,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 2.5.7
# resources: None
@ -226,17 +226,56 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( (f_trc_cfg, f_trc_lst, f_trc_log, f_trc_err) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
FOUND
FOUND
FOUND
act_1 = python_act('db_1', substitutions=substitutions_1)
ddl_lst = ["""recreate
table
t_test(x int)
""",
"""comment on
table
t_test is
'foo
bar'
""",
"""
create
or
alter
view
v_rio
as
select *
from
rdb$database
"""]
trace_1 = ['time_threshold = 0',
'log_initfini = false',
'log_errors = true',
'log_statement_finish = true',
'include_filter = "%(recreate|create|alter|drop|comment on)[[:WHITESPACE:]]+(domain|generator|sequence|exception|procedure|function|table|index|view|trigger|role|filter|external function)%"',
]
@pytest.mark.version('>=2.5.7')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.trace(db_events=trace_1), act_1.db.connect() as con:
for cmd in ddl_lst:
con.execute_immediate(cmd)
con.commit()
# Check
act_1.trace_to_stdout()
for cmd in ddl_lst:
assert act_1.stdout.find(cmd) > 0

View File

@ -40,7 +40,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
from firebird.driver import DatabaseError, FirebirdWarning
# version: 3.0
# resources: None
@ -57,7 +58,7 @@ init_script_1 = """
commit;
insert into test(id, tiny_num, dts) values(1,32767, null);
commit;
"""
"""
db_1 = db_factory(sql_dialect=1, init=init_script_1)
@ -395,32 +396,34 @@ db_1 = db_factory(sql_dialect=1, init=init_script_1)
# cleanup( (f_trc_cfg, f_trc_lst, f_trc_log, f_trc_err) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
# Following gdscodes MUST BE found in the trace log:
MISSED_EXPECTED_TOKEN = 'ERROR: missed expected token which MUST be in the trace log'
EXPECTED_SET = {'335544321' : MISSED_EXPECTED_TOKEN,
'335544916' : MISSED_EXPECTED_TOKEN,
'335544665' : MISSED_EXPECTED_TOKEN,
'336068855' : MISSED_EXPECTED_TOKEN
}
# Following gdscodes must NOT present on trace log because we explicitly PROHIBIT them:
NOT_FOUND_EXPLICITLY_PROHIBITED = 'SUCCESS: no tokens which are explicitly prohibited in exclude_gds_codes list'
PROHIBIT_SET = {'335544772' : NOT_FOUND_EXPLICITLY_PROHIBITED,
'335544778' : NOT_FOUND_EXPLICITLY_PROHIBITED,
'335544808' : NOT_FOUND_EXPLICITLY_PROHIBITED,
'TRACE_INIT' : NOT_FOUND_EXPLICITLY_PROHIBITED,
'TRACE_FINI' : NOT_FOUND_EXPLICITLY_PROHIBITED
}
# Following gdscodes are UNEXPECTED, i.e. we did not prohibit them explicitly
# but none of them are in include_gds_codes ==> they should NOT appear in the trace:
NOT_FOUND_IMPLICITLY_PROHIBITED = 'SUCCESS: no tokens which are not in include_gds_codes list.'
UNEXPECT_SET = {'335544347' : NOT_FOUND_IMPLICITLY_PROHIBITED,
'335544913' : NOT_FOUND_IMPLICITLY_PROHIBITED
}
expected_stdout_1 = """
Error while executing SQL statement:
- SQLCODE: -802
- arithmetic exception, numeric overflow, or string truncation
- Integer divide by zero. The code attempted to divide an integer value by an integer divisor of zero.
Error while executing SQL statement:
- SQLCODE: -803
- violation of PRIMARY or UNIQUE KEY constraint "TEST_PK" on table "TEST"
- Problematic key value is ("ID" = 1)
Error while executing SQL statement:
- SQLCODE: -802
- arithmetic exception, numeric overflow, or string truncation
- numeric value is out of range
Error while executing SQL statement:
- SQLCODE: -833
- value exceeds the range for valid timestamps
Error while executing SQL statement:
- SQLCODE: -625
- validation error for column "TEST"."ID", value "*** null ***"
expected_token: 335544321 ; trace search result: SUCCESS: found expected token which MUST be in the trace log.
expected_token: 335544665 ; trace search result: SUCCESS: found expected token which MUST be in the trace log.
expected_token: 335544916 ; trace search result: SUCCESS: found expected token which MUST be in the trace log.
@ -432,11 +435,88 @@ expected_stdout_1 = """
prohibit_token: TRACE_INIT ; trace search result: SUCCESS: no tokens which are explicitly prohibited in exclude_gds_codes list
unexpect_token: 335544347 ; trace search result: SUCCESS: no tokens which are not in include_gds_codes list.
unexpect_token: 335544913 ; trace search result: SUCCESS: no tokens which are not in include_gds_codes list.
"""
"""
trace_1 = ['time_threshold = 0',
'log_initfini = false',
'log_connections = true',
'log_errors = true',
'log_warnings = true',
'log_statement_prepare = true',
'log_statement_finish = true',
# 1. We EXPLICITLY ALLOW to be logged (and EXPECT because of current test scenario):
# 1.1) any kind of "arithmetic exc, num ovf, or string trunc"
# 1.2) PK/UK violation
# 1.3) (warning) 336068855 : Warning: ALL on ALL is not granted to <...>.
'include_gds_codes = arith_except,unique_key_violation,336068855',
# We EXPLICITLY PREVENT from logging:
# 2.1 "FP divide by zero",
# 2.2 "Integer divide by zero" and
# 2.3 (warning) "DATE data type is now called TIMESTAMP" (warning)
'exclude_gds_codes = 335544772,335544778,335544808',
# We do not prevent (explicitly) but DO NOT expect see in trace following errors:
# 1) 335544347 : validation error for column ..., value "*** null ***"
# 2) 335544913 : value exceeds the range for valid timestamps
]
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
with act_1.trace(db_events=trace_1):
with act_1.db.connect(sql_dialect=1) as con:
c = con.cursor()
with pytest.raises(DatabaseError, match='.*Floating-point divide by zero.*'):
c.execute('insert into test(tiny_num) values(1/0)')
#
with act_1.db.connect(sql_dialect=1) as con:
c = con.cursor()
with pytest.raises(DatabaseError, match='.*violation of PRIMARY or UNIQUE KEY constraint "TEST_PK" on table "TEST".*'):
c.execute('insert into test(id,tiny_num) values(?, ?)', [1, 1])
#
with act_1.db.connect(sql_dialect=1) as con:
c = con.cursor()
with pytest.raises(DatabaseError, match='.*numeric value is out of range.*'):
c.execute('update test set tiny_num = tiny_num + 1')
#
with act_1.db.connect(sql_dialect=1) as con:
c = con.cursor()
with pytest.raises(DatabaseError, match='.*value exceeds the range for valid timestamps.*'):
c.execute("insert into test(dts) values('01.01.0000')" )
#
with act_1.db.connect(sql_dialect=1) as con:
c = con.cursor()
with pytest.warns(FirebirdWarning, match='.*DATE data type is now called TIMESTAMP.*'):
# Leads to WARNING in trace:
# 335544807 : SQL warning code = 301
# 335544808 : DATE data type is now called TIMESTAMP
c.execute("update test set dts = cast('now' as date)")
#
with act_1.db.connect(sql_dialect=1) as con:
c = con.cursor()
with pytest.raises(DatabaseError, match='.*validation error for column.*'):
c.execute('insert into test(id) values(null)')
#
with act_1.db.connect(sql_dialect=1) as con:
with pytest.warns(FirebirdWarning, match='.*ALL on ALL is not granted.*'):
# (warning) 336068855 : Warning: ALL on ALL is not granted to <...>.
con.execute_immediate('revoke all on all from tmp$c5475')
# Process trace
for line in act_1.trace_log:
if line.split():
starting_word = line.split()[0]
if starting_word in EXPECTED_SET:
EXPECTED_SET[starting_word] = 'SUCCESS: found expected token which MUST be in the trace log.'
elif starting_word in PROHIBIT_SET:
PROHIBIT_SET[starting_word] = 'ERROR: found token which is EXPLICITLY prohibited in exclude_gds_codes list.'
elif starting_word in UNEXPECT_SET:
UNEXPECT_SET[starting_word] = 'ERROR: found token NOT from include_gdscodes list (implicitly prohibited).'
#
for k,v in sorted(EXPECTED_SET.items()):
print(f'expected_token: {k} ; trace search result: {v}')
for k,v in sorted(PROHIBIT_SET.items()):
print(f'prohibit_token: {k} ; trace search result: {v}')
for k,v in sorted(UNEXPECT_SET.items()):
print(f'unexpect_token: {k} ; trace search result: {v}')
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -34,12 +34,15 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import os
import re
from firebird.qa import db_factory, python_act, Action
# version: 4.0
# resources: None
substitutions_1 = [('timeout .* second', 'timeout second'), ('.*After line [\\d]+.*', ''), ('.*shell.*', '')]
substitutions_1 = [('timeout .* second', 'timeout second'),
('.*After line [\\d]+.*', ''), ('.*shell.*', '')]
init_script_1 = """"""
@ -254,30 +257,79 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( (f_trc_cfg, f_trc_lst, f_trc_log, f_trc_err, f_sql_cmd, f_isql_log, f_isql_err ) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_trace_1 = """
ATTACH_DATABASE
START_TRANSACTION
EXECUTE_STATEMENT_FINISH
set session idle timeout second
EXECUTE_STATEMENT_FINISH
ROLLBACK_TRANSACTION
DETACH_DATABASE
"""
expected_stdout_1 = """
TRCLOG: ATTACH_DATABASE
TRCLOG: START_TRANSACTION
TRCLOG: EXECUTE_STATEMENT_FINISH
TRCLOG: set session idle timeout second
TRCLOG: EXECUTE_STATEMENT_FINISH
TRCLOG: ROLLBACK_TRANSACTION
TRCLOG: DETACH_DATABASE
set session idle timeout second;
select 1 as point_1 from rdb$database;
POINT_1 1
select 2 as point_2 from rdb$database;
"""
SQLLOG: set session idle timeout second;
SQLLOG: select 1 as point_1 from rdb$database;
SQLLOG: POINT_1 1
SQLLOG: select 2 as point_2 from rdb$database;
expected_stderr_1 = """
Statement failed, SQLSTATE = 08003
connection shutdown
-Idle timeout expired.
"""
SQLERR: Statement failed, SQLSTATE = 08003
SQLERR: connection shutdown
SQLERR: -Idle timeout expired.
"""
trace_1 = ['time_threshold = 0',
'log_initfini = false',
'log_errors = true',
'log_connections = true',
'log_transactions = true',
'log_statement_finish = true',
]
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
trace_dts_pattern = re.compile('.*(ATTACH_DATABASE|START_TRANSACTION|EXECUTE_STATEMENT_FINISH|ROLLBACK_TRANSACTION|DETACH_DATABASE)')
session_idle_timeout = 1
shell_sleep_sec = session_idle_timeout + 2
if os.name == 'nt':
shell_sleep_cmd = f'shell ping -n {shell_sleep_sec} 127.0.0.1 > {os.devnull}'
else:
shell_sleep_cmd = f'shell sleep {shell_sleep_sec} > {os.devnull}'
sql = f"""
set list on;
set bail on;
set echo on;
set session idle timeout {session_idle_timeout} second;
select 1 as point_1 from rdb$database;
{shell_sleep_cmd};
select 2 as point_2 from rdb$database;
quit;
"""
# Trace
with act_1.trace(db_events=trace_1):
act_1.expected_stderr = expected_stderr_1
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q', '-n'], input=sql)
# Check
for line in act_1.trace_log:
if trace_dts_pattern.match(line):
print(line.strip().split()[-1])
if 'set session idle' in line:
# Since fixed CORE-6469 ("Provide ability to see in the trace log actions related to session management"), 20.01.2021:
# https://github.com/FirebirdSQL/firebird/commit/a65f19f8b36384d59a55fbb6e0a43a6b84cf4978
print(line)
assert act_1.clean_stdout == act_1.clean_expected_stdout
assert act_1.clean_stderr == act_1.clean_expected_stderr
act_1.reset()
act_1.expected_stdout = expected_trace_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout