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
2022-07-24 16:07:15 +02:00
[ 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
2022-02-02 15:46:19 +01:00
FBTEST : bugs . core_2477
2022-01-21 18:49:26 +01:00
"""
2022-07-24 16:07:15 +02:00
import subprocess
from pathlib import Path
2022-01-21 18:49:26 +01:00
import pytest
from firebird . qa import *
2022-07-24 16:07:15 +02:00
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
2022-07-24 16:07:15 +02:00
, 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
2022-07-24 16:07:15 +02:00
) 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
2022-07-24 16:07:15 +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
2022-02-02 15:46:19 +01:00
act = python_act ( ' db ' )
2022-07-24 16:07:15 +02:00
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 ) + ' . ' ) )
2022-02-02 15:46:19 +01:00
@pytest.mark.version ( ' >=3.0 ' )
2022-07-24 16:07:15 +02:00
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 )
2022-02-02 15:46:19 +01:00
2022-07-24 16:07:15 +02:00
act . expected_stdout = expected_msg
act . stdout = capsys . readouterr ( ) . out
assert act . clean_stdout == act . clean_expected_stdout