Skip to content

Commit 5da6350

Browse files
committed
Added/Updated tests\bugs\gh_7979_test.py: Bug could NOT be reproduced on Windows. Bug can be reproduced only when appropriate code runs OUTSIDE current firebird-QA framework, i.e. directly from OS. Checked on 6.0.0.244.
1 parent 9965726 commit 5da6350

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

tests/bugs/gh_7979_test.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#coding:utf-8
2+
3+
"""
4+
ID: issue-7979
5+
ISSUE: Hang when database with disconnect trigger using MON$ tables is shutting down
6+
TITLE:
7+
DESCRIPTION:
8+
NOTES:
9+
[02.02.2024] pzotov
10+
### ACHTUNG ###
11+
Bug could NOT be reproduced on Windows.
12+
Bug can be reproduced only when appropriate code runs OUTSIDE current firebird-QA framework, i.e. directly from OS.
13+
Because of that, this test creates temporary .py script which is launched further using subprocess.run( [ sys.executable ...] )
14+
Confirmed problem on 6.0.0.219: 'gfix -shut full -force 0' hangs.
15+
Checked on 6.0.0.244.
16+
"""
17+
import sys
18+
import subprocess
19+
from pathlib import Path
20+
import pytest
21+
from firebird.qa import *
22+
23+
init_sql = f"""
24+
create table logger (dts timestamp default 'now', att_cnt int);
25+
set term ^;
26+
execute block as
27+
begin
28+
rdb$set_context('USER_SESSION', 'INITIAL_DDL', 1);
29+
end
30+
^
31+
create trigger logger active on disconnect as
32+
declare c int;
33+
begin
34+
if ( rdb$get_context('USER_SESSION', 'INITIAL_DDL') is null ) then
35+
begin
36+
select count(*) from mon$attachments where mon$attachment_id = current_connection into :c;
37+
insert into logger(att_cnt) values(:c);
38+
end
39+
end
40+
^
41+
set term ;^
42+
commit;
43+
"""
44+
45+
db = db_factory(init = init_sql)
46+
act = python_act('db', substitutions = [ ('^((?!(Attributes|ATT_CNT|Records affected)).)*$', ''), ('[ \t]+', ' ') ])
47+
tmp_run_py = temp_file('tmp_7979_run_external.py')
48+
tmp_log_py = temp_file('tmp_7979_run_external.log')
49+
tmp_sql_py = temp_file('tmp_7979_check_result.sql')
50+
51+
@pytest.mark.version('>=6.0')
52+
def test_1(act: Action, tmp_run_py: Path, tmp_log_py: Path, tmp_sql_py: Path, capsys):
53+
if act.platform == 'Windows':
54+
pytest.skip('Could not reproduce bug on Windows')
55+
if act.get_server_architecture() != 'SuperServer':
56+
pytest.skip('Applies only to SuperServer')
57+
58+
py_run_ext = ' '.join( [ sys.executable, '-u', f'{str(tmp_run_py)}'] )
59+
py_source = f"""# -*- coding: utf-8 -*-
60+
# {py_run_ext}
61+
import os
62+
import sys
63+
import argparse as ap
64+
from pathlib import Path
65+
import subprocess
66+
import datetime as py_dt
67+
68+
import firebird.driver
69+
from firebird.driver import *
70+
71+
os.environ["ISC_USER"] = '{act.db.user}'
72+
os.environ["ISC_PASSWORD"] = '{act.db.password}'
73+
driver_config.fb_client_library.value = "{act.vars['fbclient']}"
74+
75+
with connect_server('localhost:service_mgr') as srv:
76+
bin_isql="{act.vars['isql']}"
77+
bin_gfix="{act.vars['gfix']}"
78+
bin_gstat="{act.vars['gstat']}"
79+
80+
with connect('{act.db.dsn}') as con:
81+
#print(f"Trying to run gfix -shut full -force 0 '{act.db.dsn}'")
82+
subprocess.run( [bin_gfix, '-shut', 'full', '-force', '0', '{act.db.dsn}'] )
83+
subprocess.run( [bin_gstat, '-h', '{act.db.db_path}'] )
84+
#print(f"Trying to run gfix -online '{act.db.dsn}'")
85+
subprocess.run( [bin_gfix, '-online', '{act.db.dsn}'] )
86+
subprocess.run( [bin_gstat, '-h', '{act.db.db_path}'] )
87+
88+
chk_sql='''
89+
set list on;
90+
set count on;
91+
select att_cnt from logger;
92+
'''
93+
with open('{str(tmp_sql_py)}', 'w') as f:
94+
f.write(chk_sql)
95+
96+
#subprocess.run( [bin_isql, '-q', '-i', '{str(tmp_sql_py)}', '-user', os.environ["ISC_USER"], '-pas', os.environ["ISC_PASSWORD"], '{act.db.dsn}'] )
97+
subprocess.run( [bin_isql, '-q', '-i', '{str(tmp_sql_py)}', '{act.db.dsn}'] )
98+
"""
99+
100+
tmp_run_py.write_text(py_source)
101+
with open(tmp_log_py, 'w') as f:
102+
subprocess.run( [ sys.executable, '-u', f'{str(tmp_run_py)}'], stdout = f, stderr = subprocess.STDOUT )
103+
104+
with open(tmp_log_py, 'r') as f:
105+
print(f.read())
106+
act.expected_stdout = """
107+
Attributes full shutdown
108+
Attributes
109+
ATT_CNT 1
110+
Records affected: 1
111+
"""
112+
act.stdout = capsys.readouterr().out
113+
assert act.clean_stdout == act.clean_expected_stdout
114+
act.reset()

0 commit comments

Comments
 (0)