Skip to content

Commit b9ac702

Browse files
committed
Added/Updated tests\bugs\core_4964_test.py: Expected ISQL output must be compared with filtered capsys.readouterr().out rather than with act.stdout. Noted by Dimitry Sibiryakov, #27
1 parent d44c33b commit b9ac702

File tree

1 file changed

+186
-140
lines changed

1 file changed

+186
-140
lines changed

tests/bugs/core_4964_test.py

+186-140
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,186 @@
1-
#coding:utf-8
2-
3-
"""
4-
ID: issue-5255
5-
ISSUE: 5255
6-
JIRA: CORE-4964
7-
FBTEST: bugs.core_4964
8-
TITLE: Real errors during connect to security database are hidden by Srp user manager. Errors should be logged no matter what AuthServer is used
9-
DESCRIPTION:
10-
Test does following:
11-
1) creates temporary user using plugin Srp (in order to avoid occasional connect as SYSDBA using Legacy plugin);
12-
2) makes copy of test DB to file which is specified n databases.conf as database for alias defined by variable with name REQUIRED_ALIAS
13-
(its value: 'tmp_4964_alias'; test will try to connect to this file via ALIAS from pre-created databases.conf);
14-
3) uses pre-created databases.conf which has alias and SecurityDatabase parameter in its details.
15-
This parameter that points to existing file that for sure can NOT be a Firebird database
16-
(file $(dir_conf)/firebird.msg is used for this purpose).
17-
18-
Then we:
19-
1) obtain content of server firebird.log;
20-
2) try to make connect to alias <tmp_alias> and (as expected) get error;
21-
3) obtain again content of server firebird.log and compare to origin one.
22-
23-
NOTES:
24-
[02.08.2022] pzotov
25-
1. One need to be sure that firebird.conf does NOT contain DatabaseAccess = None.
26-
2. Value of REQUIRED_ALIAS must be EXACTLY the same as alias specified in the pre-created databases.conf
27-
(for LINUX this equality is case-sensitive, even when aliases are compared!)
28-
3. Make sure that firebird was launched by user who is currently runs this test.
29-
Otherwise shutil.copy2() failes with "[Errno 13] Permission denied".
30-
4. Content of databases.conf must be taken from $QA_ROOT/files/qa-databases.conf (one need to replace it before every test session).
31-
Discussed with pcisar, letters since 30-may-2022 13:48, subject:
32-
"new qa, core_4964_test.py: strange outcome when use... shutil.copy() // comparing to shutil.copy2()"
33-
34-
Checked on 5.0.0.591, 4.0.1.2692, 3.0.8.33535 - both on Windows and Linux.
35-
"""
36-
37-
import re
38-
import time
39-
from pathlib import Path
40-
from difflib import unified_diff
41-
42-
import pytest
43-
from firebird.qa import *
44-
45-
substitutions = [('[ \t]+', ' '), ('file .* is not a valid database', 'file is not a valid database'), ]
46-
47-
REQUIRED_ALIAS = 'tmp_core_4964_alias'
48-
49-
db = db_factory()
50-
act = python_act('db', substitutions=substitutions)
51-
tmp_user = user_factory('db', name='tmp$c4964', password='123', plugin = 'Srp')
52-
53-
expected_stdout_isql = """
54-
Statement failed, SQLSTATE = 08006
55-
Error occurred during login, please check server firebird.log for details
56-
"""
57-
58-
expected_stdout_log_diff = """
59-
Authentication error
60-
file is not a valid database
61-
"""
62-
63-
@pytest.mark.version('>=3.0')
64-
def test_1(act: Action, tmp_user: User, capsys):
65-
66-
fblog_1 = act.get_firebird_log()
67-
68-
# Scan line-by-line through databases.conf, find line starting with REQUIRED_ALIAS and extract name of file that
69-
# must be created in the $(dir_sampleDb)/qa/ folder. This name will be used further as target database (tmp_fdb).
70-
# NOTE: we have to SKIP lines which are commented out, i.e. if they starts with '#':
71-
p_required_alias_ptn = re.compile( '^(?!#)((^|\\s+)' + REQUIRED_ALIAS + ')\\s*=\\s*\\$\\(dir_sampleDb\\)/qa/', re.IGNORECASE )
72-
fname_in_dbconf = None
73-
74-
with open(act.home_dir/'databases.conf', 'r') as f:
75-
for line in f:
76-
if p_required_alias_ptn.search(line):
77-
# If databases.conf contains line like this:
78-
# tmp_4964_alias = $(dir_sampleDb)/qa/tmp_qa_4964.fdb
79-
# - then we extract filename: 'tmp_qa_4964.fdb' (see below):
80-
fname_in_dbconf = Path(line.split('=')[1].strip()).name
81-
break
82-
83-
# if 'fname_in_dbconf' remains undefined here then propably REQUIRED_ALIAS not equals to specified in the databases.conf!
84-
#
85-
assert fname_in_dbconf
86-
87-
# Full path + filename of database to which we will try to connect:
88-
#
89-
tmp_fdb = Path( act.vars['sample_dir'], 'qa', fname_in_dbconf )
90-
91-
# PermissionError: [Errno 13] Permission denied --> probably because
92-
# Firebird was started by root rather than current (non-privileged) user.
93-
#
94-
tmp_fdb.write_bytes(act.db.db_path.read_bytes())
95-
96-
check_sql = f'''
97-
set bail on;
98-
set list on;
99-
connect '{act.host+":" if act.host else ""}{tmp_fdb}' user {tmp_user.name} password {tmp_user.password};
100-
-- This can occus only if we databases.conf contains {REQUIRED_ALIAS}
101-
-- but without reference to invalid security DB (e.g., alias without curly braces at all):
102-
select mon$database_name as "UNEXPECTED CONNECTION:" from mon$database;
103-
quit;
104-
'''
105-
106-
###############################################################################################################
107-
# POINT-1: check that ISQL raises:
108-
# "SQLSTATE = 08006 / Error occurred during login, please check server firebird.log ..."
109-
#
110-
act.expected_stdout = expected_stdout_isql
111-
try:
112-
act.isql(switches = ['-q'], input = check_sql, connect_db=False, credentials = False, combine_output = True)
113-
finally:
114-
tmp_fdb.unlink()
115-
116-
assert act.clean_stdout == act.clean_expected_stdout
117-
act.reset()
118-
119-
time.sleep(1) # Allow content of firebird log be fully flushed on disk.
120-
fblog_2 = act.get_firebird_log()
121-
122-
diff_patterns = [
123-
"\\+\\s+Authentication error",
124-
"\\+\\s+file .* is not a valid database",
125-
]
126-
diff_patterns = [re.compile(s) for s in diff_patterns]
127-
128-
for line in unified_diff(fblog_1, fblog_2):
129-
if line.startswith('+'):
130-
if act.match_any(line, diff_patterns):
131-
print(line.split('+')[-1])
132-
133-
###############################################################################################################
134-
# POINT-2: check that diff between firebird.log initial and current content has phrases
135-
# 'Authentication error' and '... file is not a valid database':
136-
#
137-
act.expected_stdout = expected_stdout_log_diff
138-
act.stdout = capsys.readouterr().out
139-
assert act.clean_stdout == act.clean_expected_stdout
140-
act.reset()
1+
#coding:utf-8
2+
3+
"""
4+
ID: issue-5255
5+
ISSUE: 5255
6+
JIRA: CORE-4964
7+
FBTEST: bugs.core_4964
8+
TITLE: Real errors during connect to security database are hidden by Srp user manager. Errors should be logged no matter what AuthServer is used
9+
DESCRIPTION:
10+
Test does following:
11+
1) creates temporary user using plugin Srp (in order to avoid occasional connect as SYSDBA using Legacy plugin);
12+
2) makes copy of test DB to file which is specified n databases.conf as database for alias defined by variable with name REQUIRED_ALIAS
13+
(its value: 'tmp_4964_alias'; test will try to connect to this file via ALIAS from pre-created databases.conf);
14+
3) uses pre-created databases.conf which has alias and SecurityDatabase parameter in its details.
15+
This parameter that points to existing file that for sure can NOT be a Firebird database
16+
(file $(dir_conf)/firebird.msg is used for this purpose).
17+
18+
Then we:
19+
1) obtain content of server firebird.log;
20+
2) try to make connect to alias <tmp_alias> and (as expected) get error;
21+
3) obtain again content of server firebird.log and compare to origin one.
22+
23+
NOTES:
24+
[02.08.2022] pzotov
25+
1. One need to be sure that firebird.conf does NOT contain DatabaseAccess = None.
26+
2. Value of REQUIRED_ALIAS must be EXACTLY the same as alias specified in the pre-created databases.conf
27+
(for LINUX this equality is case-sensitive, even when aliases are compared!)
28+
3. Make sure that firebird was launched by user who is currently runs this test.
29+
Otherwise shutil.copy2() failes with "[Errno 13] Permission denied".
30+
4. Content of databases.conf must be taken from $QA_ROOT/files/qa-databases.conf (one need to replace it before every test session).
31+
Discussed with pcisar, letters since 30-may-2022 13:48, subject:
32+
"new qa, core_4964_test.py: strange outcome when use... shutil.copy() // comparing to shutil.copy2()"
33+
34+
[31.07.2024] pzotov
35+
Replaced assert for ISQL output: added diff_patterns that must filter STDERR because we have to suppress message with text
36+
"file ... is not a valid database" as it can be seen only in dev-builds.
37+
Expected ISQL output must be compared with filtered capsys.readouterr().out rather than with act.stdout
38+
Noted by Dimitry Sibiryakov, https://github.com/FirebirdSQL/firebird-qa/issues/27
39+
40+
Checked on 5.0.0.591, 4.0.1.2692, 3.0.8.33535 - both on Windows and Linux.
41+
"""
42+
43+
import re
44+
import time
45+
from pathlib import Path
46+
from difflib import unified_diff
47+
48+
import pytest
49+
from firebird.qa import *
50+
51+
substitutions = [
52+
('[ \t]+', ' ')
53+
,('(-)?file .* is not a valid database', 'file is not a valid database')
54+
]
55+
56+
REQUIRED_ALIAS = 'tmp_core_4964_alias'
57+
58+
db = db_factory()
59+
act = python_act('db', substitutions = substitutions)
60+
tmp_user = user_factory('db', name='tmp$c4964', password='123', plugin = 'Srp')
61+
62+
expected_stdout_isql = """
63+
Statement failed, SQLSTATE = 08006
64+
Error occurred during login, please check server firebird.log for details
65+
"""
66+
67+
expected_stdout_log_diff = """
68+
Authentication error
69+
file is not a valid database
70+
"""
71+
72+
@pytest.mark.version('>=3.0')
73+
def test_1(act: Action, tmp_user: User, capsys):
74+
75+
fblog_1 = act.get_firebird_log()
76+
77+
# Scan line-by-line through databases.conf, find line starting with REQUIRED_ALIAS and extract name of file that
78+
# must be created in the $(dir_sampleDb)/qa/ folder. This name will be used further as target database (tmp_fdb).
79+
# NOTE: we have to SKIP lines which are commented out, i.e. if they starts with '#':
80+
p_required_alias_ptn = re.compile( '^(?!#)((^|\\s+)' + REQUIRED_ALIAS + ')\\s*=\\s*\\$\\(dir_sampleDb\\)/qa/', re.IGNORECASE )
81+
fname_in_dbconf = None
82+
83+
with open(act.home_dir/'databases.conf', 'r') as f:
84+
for line in f:
85+
if p_required_alias_ptn.search(line):
86+
# If databases.conf contains line like this:
87+
# tmp_4964_alias = $(dir_sampleDb)/qa/tmp_qa_4964.fdb
88+
# - then we extract filename: 'tmp_qa_4964.fdb' (see below):
89+
fname_in_dbconf = Path(line.split('=')[1].strip()).name
90+
break
91+
92+
# if 'fname_in_dbconf' remains undefined here then propably REQUIRED_ALIAS not equals to specified in the databases.conf!
93+
#
94+
assert fname_in_dbconf
95+
96+
# Full path + filename of database to which we will try to connect:
97+
#
98+
tmp_fdb = Path( act.vars['sample_dir'], 'qa', fname_in_dbconf )
99+
100+
# PermissionError: [Errno 13] Permission denied --> probably because
101+
# Firebird was started by root rather than current (non-privileged) user.
102+
#
103+
tmp_fdb.write_bytes(act.db.db_path.read_bytes())
104+
105+
check_sql = f'''
106+
set bail on;
107+
set list on;
108+
connect '{act.host+":" if act.host else ""}{tmp_fdb}' user {tmp_user.name} password {tmp_user.password};
109+
-- This can occus only if we databases.conf contains {REQUIRED_ALIAS}
110+
-- but without reference to invalid security DB (e.g., alias without curly braces at all):
111+
select mon$database_name as "UNEXPECTED CONNECTION:" from mon$database;
112+
quit;
113+
'''
114+
115+
###############################################################################################################
116+
# POINT-1: check that ISQL raises:
117+
# "SQLSTATE = 08006 / Error occurred during login, please check server firebird.log ..."
118+
#
119+
120+
# release build:
121+
# ==================================
122+
# Statement failed, SQLSTATE = 08006
123+
# Error occurred during login, please check server firebird.log for details
124+
# ==================================
125+
126+
# dev-build:
127+
# ==================================
128+
# Statement failed, SQLSTATE = 08006
129+
# Error occurred during login, please check server firebird.log for details
130+
# -file ... is not a valid database
131+
# ==================================
132+
# Last line ("file ... is not a valid database") will be suppressed by substitutions set:
133+
#
134+
135+
isql_err_diff_patterns = [
136+
"Statement failed, SQLSTATE = 08006"
137+
,"Error occurred during login, please check server firebird.log for details"
138+
]
139+
isql_err_diff_patterns = [re.compile(s) for s in isql_err_diff_patterns]
140+
141+
act.expected_stdout = expected_stdout_isql
142+
try:
143+
act.isql(switches = ['-q'], input = check_sql, connect_db=False, credentials = False, combine_output = True)
144+
finally:
145+
tmp_fdb.unlink()
146+
147+
# ::: NB :::
148+
# Expected ISQL output must be compared with filtered capsys.readouterr().out rather than with act.stdout
149+
for line in act.stdout.splitlines():
150+
if act.match_any(line, isql_err_diff_patterns):
151+
print(line)
152+
153+
act.stdout = capsys.readouterr().out
154+
assert act.clean_stdout == act.clean_expected_stdout
155+
act.reset()
156+
157+
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
158+
159+
time.sleep(1) # Allow content of firebird log be fully flushed on disk.
160+
fblog_2 = act.get_firebird_log()
161+
162+
fb_log_diff_patterns = [
163+
"\\+\\s+Authentication error"
164+
,"\\+\\s+file .* is not a valid database"
165+
]
166+
fb_log_diff_patterns = [re.compile(s) for s in fb_log_diff_patterns]
167+
168+
# BOTH release and dev build will print in firebird.log:
169+
# <hostname> <timestamp>
170+
# Authentication error
171+
# file .* is not a valid database
172+
#
173+
for line in unified_diff(fblog_1, fblog_2):
174+
if line.startswith('+'):
175+
if act.match_any(line, fb_log_diff_patterns):
176+
print(line.split('+')[-1])
177+
178+
###############################################################################################################
179+
# POINT-2: check that diff between firebird.log initial and current content has phrases
180+
# 'Authentication error' and '... file is not a valid database':
181+
#
182+
act.expected_stdout = expected_stdout_log_diff
183+
act.stdout = capsys.readouterr().out
184+
assert act.clean_stdout == act.clean_expected_stdout
185+
act.reset()
186+

0 commit comments

Comments
 (0)