|
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