6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 21:43:06 +01:00
firebird-qa/tests/bugs/core_2477_test.py

129 lines
5.1 KiB
Python
Raw Normal View History

2021-04-26 20:07:00 +02:00
#coding:utf-8
2022-01-21 18:49:26 +01:00
"""
ID: issue-2890
ISSUE: 2890
TITLE: mon$memory_usage: Sorting memory should be reported as owned by the statement
DESCRIPTION:
NOTES:
[16.11.2021] pcisar
This test is too complicated and fragile, and it's IMHO not worth to be implemented
[24.07.2022] pzotov
Test was totally re-implemented. No async call of ISQL, waiting/killing etc.
Checked on 3.0.8.33535, 4.0.1.2692, 5.0.0.591
2022-01-21 18:49:26 +01:00
JIRA: CORE-2477
FBTEST: bugs.core_2477
2022-01-21 18:49:26 +01:00
"""
import subprocess
from pathlib import Path
2022-01-21 18:49:26 +01:00
import pytest
from firebird.qa import *
import time
MIN_DIFF_THRESHOLD=60000000
2021-04-26 20:07:00 +02:00
2022-01-21 18:49:26 +01:00
init_script = """
2021-04-26 20:07:00 +02:00
create or alter view v_mon as
select *
from (
2021-11-16 19:44:53 +01:00
select
2021-04-26 20:07:00 +02:00
m.mon$stat_group as stat_gr
,rpad( decode(m.mon$stat_group, 0,'0:database', 1,'1:attachment', 2,'2:transaction', 3,'3:statement', 4,'4:call'), 15,' ') as stat_type
,m.mon$memory_used as memo_used
,m.mon$memory_allocated as memo_allo
,m.mon$max_memory_used as max_memo_used
,m.mon$max_memory_allocated as max_memo_allo
,m.mon$stat_id as stat_id
,coalesce( s.mon$attachment_id, t.mon$attachment_id, a.mon$attachment_id, -999 ) as att_id
,coalesce( s.mon$transaction_id, t.mon$transaction_id, -999 ) as trn_id
,coalesce( s.mon$statement_id, -999) as sttm_id
,coalesce( decode( s.mon$state, 0,'idle', 1,'running', 2,'stalled' ), 'n/a') as stm_state
,lower(right( coalesce(trim(coalesce(a.mon$remote_process, a.mon$user)), ''), 20 )) as att_process -- isql.exe or Garbage Collector or Cache Writer
,lower(left( coalesce(cast(s.mon$sql_text as varchar(8100)),''), 128 )) as sql_text
2021-11-16 19:44:53 +01:00
from mon$memory_usage m
2021-04-26 20:07:00 +02:00
left join mon$statements s on m.mon$stat_group = 3 and m.mon$stat_id = s.mon$stat_id
2021-11-16 19:44:53 +01:00
left join mon$transactions t on
2021-04-26 20:07:00 +02:00
m.mon$stat_group = 2 and m.mon$stat_id = t.mon$stat_id
or m.mon$stat_group = 3 and m.mon$stat_id = s.mon$stat_id and t.mon$transaction_id = s.mon$transaction_id
2021-11-16 19:44:53 +01:00
left join mon$attachments a on
m.mon$stat_group = 1 and m.mon$stat_id = a.mon$stat_id
2021-04-26 20:07:00 +02:00
or m.mon$stat_group=2 and m.mon$stat_id = t.mon$stat_id and a.mon$attachment_id = t.mon$attachment_id
or m.mon$stat_group=3 and m.mon$stat_id = s.mon$stat_id and a.mon$attachment_id = s.mon$attachment_id
) t
where t.stat_gr = 3 and sql_text containing 'HEAVY_SORT_TAG'
order by stat_type, stat_id
;
2021-04-26 20:07:00 +02:00
create or alter view v_gather_mon as
select
v.att_process
,replace(replace(replace(replace(v.sql_text, ascii_char(10),' '), ascii_char(13),' '),' ',' '),' ',' ') as sql_text
,v.stat_type
,v.stm_state
,v.att_id
,v.trn_id
,v.sttm_id
,v.memo_used
,v.memo_allo
from v_mon v
where v.att_id is distinct from current_connection
;
commit;
2021-12-22 20:23:11 +01:00
"""
2021-04-26 20:07:00 +02:00
2022-01-21 18:49:26 +01:00
db = db_factory(init=init_script)
2021-04-26 20:07:00 +02:00
act = python_act('db')
def result_msg(a_diff_value, a_min_threshold):
return ( ('OK, expected: increased significantly.') if a_diff_value > a_min_threshold else ('BAD! Did not increased as expected. Difference: ' + "{:d}".format(a_diff_value)+'.') )
@pytest.mark.version('>=3.0')
def test_1(act: Action, capsys):
heavy_sql_sttm = "select /* HEAVY_SORT_TAG */ distinct lpad('', 32500, uuid_to_char(gen_uuid())) s from (select 1 i from rdb$types rows 100) a, (select 1 i from rdb$types rows 100) b"
map_result = {}
with act.db.connect() as con_worker:
cur_worker = con_worker.cursor()
cur_wrk_ps = cur_worker.prepare(heavy_sql_sttm)
for m in ('beg','end'):
with act.db.connect() as con_monitor:
cur_monitor=con_monitor.cursor()
cur_monitor.execute('select * from v_gather_mon')
for r in cur_monitor:
map_result[m] = (r[3], r[7]) # ('idle' | 'stalled', memo_used)
if m == 'beg':
cur_worker.execute(cur_wrk_ps)
for i in range(0, 5000):
r = cur_worker.fetchone()
# After this loop statement with huge sort will remain in stalled state
# (its mon$statements.mon$state must be 2).
# We can now gather mon$ info second time (in a NEW connection)
# and then evaluate DIFFERENCE.
#------------------------------------------------------------------------------------------
assert map_result['beg'][0].strip() == 'idle' and map_result['end'][0].strip() == 'stalled'
expected_msg = 'DELTA of mon$memory_used increased significantly.'
diff = map_result['end'][1] - map_result['beg'][1]
if diff > MIN_DIFF_THRESHOLD:
print(expected_msg)
else:
print('### FAIL ### DELTA of mon$memory_used increased for less than MIN_DIFF_THRESHOLD = %d' % MIN_DIFF_THRESHOLD)
for k,v in sorted(map_result.items()):
print(k,':',v)
print('diff = %d' % diff)
act.expected_stdout = expected_msg
act.stdout = capsys.readouterr().out
assert act.clean_stdout == act.clean_expected_stdout