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:
parent
c13d40082f
commit
76b49666fa
@ -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%',
|
||||
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',
|
||||
'}']
|
||||
with act.connect_server() as srv:
|
||||
srv.trace.start(config='\n'.join(cfg30))
|
||||
b.wait()
|
||||
for line in srv:
|
||||
print(line)
|
||||
'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
|
||||
|
||||
|
||||
|
@ -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,12 +481,8 @@ 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)%',
|
||||
|
||||
trace_1 = ['include_filter = %(SELECT|INSERT|UPDATE|DELETE)%',
|
||||
'exclude_filter = %no_trace%',
|
||||
'log_connections = true',
|
||||
'log_transactions = true',
|
||||
@ -506,41 +501,14 @@ def trace_session(act: Action, b: Barrier):
|
||||
'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
|
||||
]
|
||||
|
||||
@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)) == ''
|
||||
|
||||
|
||||
|
@ -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',
|
||||
trace_1 = ['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())
|
||||
]
|
||||
|
||||
@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
|
||||
|
@ -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',
|
||||
trace_1 = ['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())
|
||||
]
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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',
|
||||
trace_1 = ['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)
|
||||
]
|
||||
|
||||
@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
|
||||
|
@ -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',
|
||||
trace_1 = ['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)
|
||||
]
|
||||
|
||||
@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
|
||||
|
@ -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',
|
||||
trace_1 = ['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
|
||||
]
|
||||
|
||||
@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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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',
|
||||
trace_1 = ['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)
|
||||
]
|
||||
|
||||
@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
|
||||
|
@ -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',
|
||||
trace_1 = ['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)
|
||||
]
|
||||
|
||||
@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.')
|
||||
|
@ -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',
|
||||
trace_1 = ['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())
|
||||
]
|
||||
|
||||
@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
|
||||
|
@ -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',
|
||||
trace_1 = ['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())
|
||||
]
|
||||
|
||||
@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
|
||||
|
@ -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',
|
||||
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)
|
||||
|
@ -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',
|
||||
trace_1 = ['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)
|
||||
]
|
||||
|
||||
@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
|
||||
|
@ -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',
|
||||
trace_1 = ['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)
|
||||
]
|
||||
|
||||
@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
|
||||
|
@ -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',
|
||||
trace_1 = ['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)
|
||||
]
|
||||
|
||||
@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
|
||||
|
||||
|
||||
|
@ -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',
|
||||
trace_1 = ['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)
|
||||
]
|
||||
|
||||
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
|
||||
|
||||
|
@ -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,12 +289,7 @@ 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',
|
||||
trace_1 = ['time_threshold = 0',
|
||||
'log_sweep = true',
|
||||
'log_errors = true',
|
||||
'log_connections = true',
|
||||
@ -309,19 +302,7 @@ def trace_session(act: Action, b: Barrier):
|
||||
'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)
|
||||
]
|
||||
|
||||
@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
|
||||
|
@ -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',
|
||||
'}']
|
||||
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
|
||||
|
@ -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")
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -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
|
||||
|
@ -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
|
||||
@ -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
|
||||
|
@ -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()"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -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.
|
||||
@ -434,9 +437,86 @@ expected_stdout_1 = """
|
||||
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
|
||||
|
@ -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)
|
||||
|
||||
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
|
||||
act_1 = python_act('db_1', substitutions=substitutions_1)
|
||||
|
||||
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;
|
||||
|
||||
SQLERR: Statement failed, SQLSTATE = 08003
|
||||
SQLERR: connection shutdown
|
||||
SQLERR: -Idle timeout expired.
|
||||
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 = """
|
||||
set session idle timeout second;
|
||||
select 1 as point_1 from rdb$database;
|
||||
POINT_1 1
|
||||
select 2 as point_2 from rdb$database;
|
||||
"""
|
||||
|
||||
expected_stderr_1 = """
|
||||
Statement failed, SQLSTATE = 08003
|
||||
connection shutdown
|
||||
-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
|
||||
|
Loading…
Reference in New Issue
Block a user