6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-02-02 02:40:42 +01:00

Fixes for FB 4

This commit is contained in:
Pavel Císař 2021-11-09 11:01:26 +01:00
parent e754587c22
commit b458cecb1e
32 changed files with 2826 additions and 2617 deletions

View File

@ -74,6 +74,9 @@ def pytest_addoption(parser, pluginmanager):
def pytest_report_header(config):
return ["Firebird:",
f" root: {_vars_['root']}",
f" databases: {_vars_['databases']}",
f" backups: {_vars_['backups']}",
f" driver configuration: {_vars_['firebird-config']}",
f" server: {_vars_['server']}",
f" protocol: {_vars_['protocol']}",
@ -120,7 +123,6 @@ def pytest_configure(config):
path = config.rootpath / 'backups'
_vars_['backups'] = path if path.is_dir() else config.rootpath
_vars_['server'] = config.getoption('server')
_vars_['bin-dir'] = config.getoption('bin_dir')
_vars_['protocol'] = config.getoption('protocol')
_vars_['save-output'] = config.getoption('save_output')
srv_conf = driver_config.get_server(_vars_['server'])
@ -131,17 +133,25 @@ def pytest_configure(config):
password=_vars_['password']) as srv:
_vars_['version'] = parse(srv.info.version.replace('-dev', ''))
_vars_['home-dir'] = Path(srv.info.home_directory)
if bindir := config.getoption('bin_dir'):
_vars_['bin-dir'] = Path(bindir)
else:
bindir = _vars_['home-dir'] / 'bin'
if not bindir.exists():
bindir = _vars_['home-dir']
_vars_['bin-dir'] = bindir
_vars_['lock-dir'] = Path(srv.info.lock_directory)
_vars_['bin-dir'] = Path(bindir) if bindir else _vars_['home-dir']
_vars_['security-db'] = Path(srv.info.security_database)
_vars_['arch'] = srv.info.architecture
if _vars_['bin-dir'] is None:
path = _vars_['home-dir'] / 'bin'
if path.is_dir():
_vars_['bin-dir'] = path
else:
pytest.exit("Path to binary tools not determined")
else:
_vars_['bin-dir'] = Path(_vars_['bin-dir'])
#if _vars_['bin-dir'] is None:
#path = _vars_['home-dir'] / 'bin'
#if path.is_dir():
#_vars_['bin-dir'] = path
#else:
#pytest.exit("Path to binary tools not determined")
#else:
#_vars_['bin-dir'] = Path(_vars_['bin-dir'])
# tools
for tool in ['isql', 'gbak', 'nbackup', 'gstat', 'gfix', 'gsec']:
set_tool(tool)
@ -154,17 +164,17 @@ def pytest_collection_modifyitems(session, config, items):
for item in items:
if 'slow' in item.keywords and not _vars_['runslow']:
item.add_marker(skip_slow)
for platforms in [mark.args for mark in item.iter_markers(name="platform")]:
if _platform not in platforms:
item.add_marker(skip_platform)
# Deselect tests not applicable to tested engine version
# Deselect tests not applicable to tested engine version and platform
selected = []
deselected = []
for item in items:
platform_ok = True
for platforms in [mark.args for mark in item.iter_markers(name="platform")]:
platform_ok = _platform in platforms
versions = [mark.args for mark in item.iter_markers(name="version")]
if versions:
spec = SpecifierSet(','.join(list(versions[0])))
if _vars_['version'] in spec:
if platform_ok and _vars_['version'] in spec:
selected.append(item)
else:
deselected.append(item)
@ -189,12 +199,15 @@ class Database:
user: str=None, password: str=None):
self.db_path: Path = path / filename
self.dsn: str = None
self.io_enc = 'utf8'
if _vars_['host']:
self.dsn = f"{_vars_['host']}:{str(self.db_path)}"
else:
self.dsn = str(self.db_path)
self.subs = {'temp_directory': str(path / 'x')[:-1], 'database_location': str(path / 'x')[:-1],
'DATABASE_PATH': str(path / 'x')[:-1], 'DSN': self.dsn,
self.subs = {'temp_directory': str(path / 'x')[:-1],
'database_location': str(path / 'x')[:-1],
'DATABASE_PATH': str(path / 'x')[:-1],
'DSN': self.dsn,
'files_location': str(_vars_['root'] / 'files'),
'backup_location': str(_vars_['root'] / 'backups'),
'suite_database_location': str(_vars_['root'] / 'databases'),
@ -271,10 +284,11 @@ class Database:
charset = charset.upper()
else:
charset = 'NONE'
self.io_enc = CHARSET_MAP[charset]
result = run([_vars_['isql'], '-ch', charset, '-user', self.user,
'-password', self.password, str(self.dsn)],
input=substitute_macros(script, self.subs),
encoding=CHARSET_MAP[charset], capture_output=True)
encoding=self.io_enc, capture_output=True)
if result.returncode and raise_on_fail:
print(f"-- ISQL script stdout {'-' * 20}")
print(result.stdout)
@ -401,9 +415,9 @@ class Action:
# Store output
if _vars_['save-output']:
if self.stdout:
out_file.write_text(self.stdout)
out_file.write_text(self.stdout, encoding=self.db.io_enc)
if self.stderr:
err_file.write_text(self.stderr)
err_file.write_text(self.stderr, encoding=self.db.io_enc)
@property
def clean_stdout(self) -> str:
if self._clean_stdout is None:

View File

@ -1035,7 +1035,7 @@ Dynamic SQL Error
-Wrong number of parameters (expected 3, got 0)
"""
@pytest.mark.version('>=3.0')
@pytest.mark.version('>=3.0,<4')
def test_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.expected_stderr = expected_stderr_1
@ -1043,3 +1043,45 @@ def test_1(act_1: Action):
assert act_1.clean_expected_stderr == act_1.clean_stderr
assert act_1.clean_expected_stdout == act_1.clean_stdout
act_2 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stderr_2 = """
Statement failed, SQLSTATE = 42000
Dynamic SQL Error
-SQL error code = -104
-Invalid expression in the HAVING clause (neither an aggregate function nor a part of the GROUP BY clause)
Statement failed, SQLSTATE = 42000
Dynamic SQL Error
-SQL error code = -104
-Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)
Statement failed, SQLSTATE = 42000
Dynamic SQL Error
-SQL error code = -104
-Invalid expression in the HAVING clause (neither an aggregate function nor a part of the GROUP BY clause)
Statement failed, SQLSTATE = 23000
Operation violates CHECK constraint T1_N on view or table T1
-At trigger 'CHECK_1'
Statement failed, SQLSTATE = 23000
Operation violates CHECK constraint T1_CX on view or table T1
-At trigger 'CHECK_3'
Statement failed, SQLSTATE = 23000
validation error for column "T1"."DC1", value "10"
Statement failed, SQLSTATE = 23000
validation error for column "T1"."DC2", value "10"
Statement failed, SQLSTATE = 22012
arithmetic exception, numeric overflow, or string truncation
-Integer divide by zero. The code attempted to divide an integer value by an integer divisor of zero.
Statement failed, SQLSTATE = 07002
Dynamic SQL Error
-SQLDA error
-No SQLDA for input values provided
"""
@pytest.mark.version('>=4.0')
def test_2(act_2: Action):
act_2.expected_stdout = expected_stdout_1
act_2.expected_stderr = expected_stderr_2
act_2.execute()
assert act_2.clean_expected_stderr == act_2.clean_stderr
assert act_2.clean_expected_stdout == act_2.clean_stdout

View File

@ -24,10 +24,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
test_script_1 = """
-- [pcisar] 20.10.2021
-- For 3.0.7 on Linux (uses system ICU) or Windows (includes ICU 52) this
-- collation *SHOULD* be created w/o errors like in 4.0 version.
-- However this has to be verified (passes on Linux opensuse tumbleweed)
-- In case it would be confirmed, both test cases could be merged into one.
-- For 3.0.7 on Linux this PASS (uses system ICU) but on Windows (includes ICU 52)
-- it FAIL unless newer ICU (63) is installed.
set list on;
set count on;

View File

@ -462,6 +462,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -14,7 +14,7 @@ from firebird.qa import db_factory, isql_act, Action
# version: 2.5.0
# resources: None
substitutions_1 = []
substitutions_1 = [('=.*', '=')]
init_script_1 = """create table t (col varchar(32000));
commit;

View File

@ -17,7 +17,7 @@ from firebird.qa import db_factory, isql_act, Action
# version: 2.5
# resources: None
substitutions_1 = []
substitutions_1 = [('01-JAN-', ' 1-JAN-')]
init_script_1 = """"""
@ -41,13 +41,6 @@ test_script_1 = """
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
# [pcisar] 20.10.2011
# This test FAIL on my system because the isql output is:
# ID 1
# OPDATE 31-DEC-2000
# ID 2
# OPDATE 1-JAN-2001
expected_stdout_1 = """
ID 1
OPDATE 31-DEC-2000

View File

@ -28,9 +28,10 @@ test_script_1 = """
-- -Data type unknown
-- -COLLATION WIN_PTBR for CHARACTER SET UTF8 is not defined
-- (See ticket issue: "WIN_PTBR is tried to be resolved agains database charset instead of client charset: incorrect")
-- [pcisar] 20.10.2021
-- It fails as well in 3.0.7 on Linux (opensuse tumbleweed)
-- In 3.0.0.31827 (WI- and LI-) works fine:
-- [pcisar] 20.10.2021
-- It fails as well in 3.0.7 and 4.0 on Linux (opensuse tumbleweed) and Windows (8.1)
-- It appears that this test is bogus from the beginning
set term ^;
execute block returns (c varchar(10) collate win_ptbr) as
begin

View File

@ -123,13 +123,14 @@ expected_stdout_1 = """
CTX_NAME point_3
CTX_VALUE #null# #null# 100003 #null#
"""
expected_stderr_1 = """
Statement failed, SQLSTATE = 22000
no current record for fetch operation
-At procedure 'SP_TEST1A'
"""
@pytest.mark.version('>=3.0.1')
@pytest.mark.version('>=3.0.1,<4')
def test_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.expected_stderr = expected_stderr_1
@ -137,3 +138,119 @@ def test_1(act_1: Action):
assert act_1.clean_expected_stderr == act_1.clean_stderr
assert act_1.clean_expected_stdout == act_1.clean_stdout
# version: 4.0
# resources: None
substitutions_2 = [('[ \\t]+', ' '), ('line: [\\d]+[,]{0,1} col: [\\d]+', '') ]
test_script_2 = """
-- see also:
-- https://www.sql.ru/forum/1319017/obnovlenie-zapisi-po-kursoru
-- Discussed 13.11.2019 with hvlad and dimitr (related to CORE-5794)
recreate table test (
id int not null
,data1 int
,data2 int
,data3 int
,data4 int
);
set term ^;
create or alter procedure sp_set_ctx(a_point varchar(20), a_data1 int, a_data2 int, a_data3 int, a_data4 int) as
begin
-- Store values of cursor fields in the context variable which name is passed here as 'a_point'.
rdb$set_context(
'USER_SESSION',
a_point,
coalesce(cast( a_data1 as char(6)),'#null#')
|| ' ' || coalesce(cast( a_data2 as char(6)),'#null#')
|| ' ' || coalesce(cast( a_data3 as char(6)),'#null#')
|| ' ' || coalesce(cast( a_data4 as char(6)),'#null#')
);
end
^
create or alter procedure sp_test1a as
begin
-- ::: NOTE :::
-- Only IMPLICIT cursors are stable in 3.0+.
-- #############
-- Do _NOT_ try to check following statements using explicit cursor
-- (i.e. OPEN <C>; FETCH ...; CLOSE <C>)
for
select t.id, t.data1, t.data2, t.data3, t.data4 from test t where t.id = 1
as cursor c
do begin
execute procedure sp_set_ctx('point_0', c.data1, c.data2, c.data3, c.data4 );
update test t set t.data1 = 100001 where current of c;
-- make "photo" of all cursor fields:
execute procedure sp_set_ctx('point_1', c.data1, c.data2, c.data3, c.data4 );
-- at this point value of c.data1 remains NULL from cursor POV because
-- "UPDATE WHERE CURRENT OF C" sees record as it was no changes at all:
update test t set t.data2 = 100002 where current of c;
-- make "photo" of all cursor fields:
execute procedure sp_set_ctx('point_2', c.data1, c.data2, c.data3, c.data4 );
-- at this point value of c.data1 and c.data2 remain NULL from cursor POV because
-- "UPDATE WHERE CURRENT OF C" sees record as it was no changes at all:
update test t set t.data3 = 100003 where current of c;
-- make "photo" of all cursor fields:
execute procedure sp_set_ctx('point_3', c.data1, c.data2, c.data3, c.data4 );
delete from test t where current of c;
execute procedure sp_set_ctx('point_4', c.data1, c.data2, c.data3, c.data4 );
-- 02.05.2021: on FB 3.x following UPDATE statement raises exception
-- "SQLSTATE = 22000 / no current record for fetch operation"
-- But on FB 4.x this was fixed since build 4.0.0.2448 and no exception will be here
-- See also: https://github.com/FirebirdSQL/firebird/issues/6778
-- This means that deletion of record in the table TEST will not be undone
-- and we must NOT see its data in expected_stdout section!
update test t set t.data4 = 100004 where current of c;
execute procedure sp_set_ctx('point_5', c.data1, c.data2, c.data3, c.data4 );
end
end
^
set term ;^
commit;
insert into test (id) values (1);
commit;
set bail off;
set list on;
execute procedure sp_test1a;
select * from test;
select mon$variable_name as ctx_name, mon$variable_value ctx_value from mon$context_variables where mon$attachment_id = current_connection;
"""
act_2 = isql_act('db_1', test_script_2, substitutions=substitutions_2)
expected_stdout_2 = """
CTX_NAME point_0
CTX_VALUE #null# #null# #null# #null#
CTX_NAME point_1
CTX_VALUE 100001 #null# #null# #null#
CTX_NAME point_2
CTX_VALUE #null# 100002 #null# #null#
CTX_NAME point_3
CTX_VALUE #null# #null# 100003 #null#
CTX_NAME point_4
CTX_VALUE #null# #null# #null# #null#
CTX_NAME point_5
CTX_VALUE #null# #null# #null# #null#
"""
@pytest.mark.version('>=4')
def test_2(act_2: Action):
act_2.expected_stdout = expected_stdout_2
act_2.execute()
assert act_2.clean_expected_stdout == act_2.clean_stdout

View File

@ -68,7 +68,7 @@ expected_stderr_1 = """
-Problematic key value is ("COL" = 0.0000000000000000)
"""
@pytest.mark.version('>=2.5.1,<2.5.1')
@pytest.mark.version('>=2.5.1')
@pytest.mark.platform('Windows')
def test_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1

View File

@ -114,6 +114,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -43,22 +43,30 @@ Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-CREATE USER U01 failed
-Password must be specified when creating user
Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-CREATE USER U01 failed
-Password must be specified when creating user
Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-CREATE USER U01 failed
-Password must be specified when creating user
Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-CREATE USER U01 failed
-Password must be specified when creating user
Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-CREATE USER U01 failed
-Password must be specified when creating user
Statement failed, SQLSTATE = HY000
Password must be specified when creating user
Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-CREATE USER PASSWORD failed

View File

@ -11,6 +11,7 @@
# Statement failed, SQLSTATE = 42000
# Execute statement error at attach :
# 335544472 : Your user name and password are not defined <...>
# [pcisar] 03.11.2021 The same error raised by 4.0 on Windows and Linux
#
# Works fine on:
# fb30Cs, build 3.0.4.32947: OK, 2.907s.

View File

@ -60,6 +60,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -13,6 +13,9 @@
# UserManager = Srp, Legacy_UserManager
# Checked on WI-T4.0.0.549 - works fine.
#
# [pcisar] 3.11.2021 This test fails with 4.0, even with specified config
# Although user is created, the connect as user tmp$c5495 fails (unknown user)
#
# tracker_id: CORE-5495
# min_versions: ['4.0']
# versions: 4.0
@ -33,6 +36,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
test_script_1 = """
set list on;
set bail on;
set echo on;
create user tmp$c5495 password '123' using plugin Legacy_UserManager;
commit;
connect '$(DSN)' user tmp$c5495 password '123';

View File

@ -138,6 +138,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -7,6 +7,8 @@
# Checked on:
# FB30SS, build 3.0.4.33021: OK, 2.312s.
#
# [pcisar] 3.11.2021 This test fails for 4.0 (returns tmp$ user names instead mapped ones)
#
# tracker_id: CORE-5884
# min_versions: ['3.0.4']
# versions: 3.0.4

View File

@ -40,6 +40,8 @@
#
# Checked on 4.0.0.2164
#
# [pcisar] 3.11.2021 This test fails for v4.0.0.2496 (4.0 final)
#
# tracker_id: CORE-5953
# min_versions: ['4.0']
# versions: 4.0

View File

@ -1370,7 +1370,7 @@ expected_stdout_1 = """
02: sqltype: 448 VARYING scale: 0 subtype: 0 len: 255 charset: 1 OCTETS
: name: ENCRYPT alias: E_CHAR
: table: owner:
03: sqltype: 448 VARYING scale: 0 subtype: 0 len: 6 charset: 0 NONE
03: sqltype: 448 VARYING scale: 0 subtype: 0 len: 6 charset: 1 OCTETS
: name: DECRYPT alias: D_BIN
: table: owner:
@ -1391,6 +1391,7 @@ expected_stderr_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.expected_stderr = expected_stderr_1
act_1.execute()

View File

@ -25,7 +25,7 @@ from firebird.qa import db_factory, isql_act, Action
# version: 4.0
# resources: None
substitutions_1 = [('current value.*', 'current value')]
substitutions_1 = [('current value.*', 'current value'), ('COLL-VERSION=153\\.14', 'COLL-VERSION=153.88')]
init_script_1 = """"""

View File

@ -91,6 +91,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -14,6 +14,8 @@
# Discussion about this with Alex was in 23-sep-2019, and his solution not yet known.
# For this reason it was decided to comment code that relates tgo ROLE mapping in this test.
#
# [pcisar] 3.11.2021 This test fails for 4.0, WHO_AM_I = TMP$C6143_FOO
#
# tracker_id: CORE-6143
# min_versions: ['3.0.5']
# versions: 3.0.5

View File

@ -43,6 +43,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -76,6 +76,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -58,6 +58,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -50,6 +50,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -125,9 +125,23 @@ expected_stdout_1 = """PLAN JOIN (T1 NATURAL, T1K INDEX (PK_TABLE_1K), T2K INDEX
1
"""
@pytest.mark.version('>=2.0')
@pytest.mark.version('>=2.0,<4')
def test_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout
expected_stdout_2 = """PLAN JOIN (T1 NATURAL, T1K INDEX (PK_TABLE_1K), T2K INDEX (PK_TABLE_2K), T3K INDEX (PK_TABLE_3K), T4K INDEX (PK_TABLE_4K), T5K INDEX (PK_TABLE_5K), T6K INDEX (PK_TABLE_6K), T8K INDEX (PK_TABLE_8K), T10K INDEX (PK_TABLE_10K))
COUNT
=====================
1
"""
@pytest.mark.version('>=4')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_2
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

File diff suppressed because it is too large Load Diff

View File

@ -126,6 +126,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -476,6 +476,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -319,6 +319,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=4.0')
def test_1(act_1: Action):
act_1.charset = 'NONE'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout