mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 13:33:07 +01:00
Update tests
This commit is contained in:
parent
3102893439
commit
3081aa0974
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_86
|
||||
# id: bugs.core_0086
|
||||
# title: Index bug
|
||||
# decription: Can not fetch the data when Index is use
|
||||
# tracker_id: CORE-86
|
||||
@ -38,7 +38,7 @@ expected_stdout_1 = """ID_YLK PH HPBH CD
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.1')
|
||||
def test_core_86_1(act_1: Action):
|
||||
def test_core_0086_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_91
|
||||
# id: bugs.core_0091
|
||||
# title: Recreate and self-referencing indexes
|
||||
# decription:
|
||||
# tracker_id: CORE-91
|
||||
@ -45,6 +45,6 @@ act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
|
||||
@pytest.mark.version('>=2.1')
|
||||
def test_core_91_1(act_1: Action):
|
||||
def test_core_0091_1(act_1: Action):
|
||||
act_1.execute()
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_99
|
||||
# id: bugs.core_0099
|
||||
# title: Strange/Inconsistent query results
|
||||
# decription:
|
||||
# tracker_id: CORE-99
|
||||
@ -46,7 +46,7 @@ F1 F2
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.1')
|
||||
def test_core_99_1(act_1: Action):
|
||||
def test_core_0099_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_655
|
||||
# id: bugs.core_0655
|
||||
# title: Blob Type 1 compatibility with VarChar
|
||||
# decription: Blob Sub-Type 1 (text) column treated in the same manner as a VarChar column
|
||||
# for assignments, conversions, cast, lower, upper, trim, concatenate and substring
|
||||
@ -38,7 +38,7 @@ firebird FIREBIRD Firebird2.1 Firebird 2.1
|
||||
SQL>"""
|
||||
|
||||
@pytest.mark.version('>=2.1')
|
||||
def test_core_655_1(act_1: Action):
|
||||
def test_core_0655_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_805
|
||||
# id: bugs.core_0805
|
||||
# title: Privileges of dynamic statements in SP
|
||||
# decription:
|
||||
# Checked on:
|
||||
@ -165,7 +165,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5')
|
||||
def test_core_805_1(act_1: Action):
|
||||
def test_core_0805_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_842
|
||||
# id: bugs.core_0842
|
||||
# title: Specific query crashing server
|
||||
# decription: Run the query below twice and the server will crash:
|
||||
#
|
||||
@ -42,7 +42,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.1')
|
||||
def test_core_842_1(act_1: Action):
|
||||
def test_core_0842_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_852
|
||||
# id: bugs.core_0852
|
||||
# title: substring(current_user from 4) fails
|
||||
# decription: select substring( current_user from 4) from rdb$database;
|
||||
# fails on string truncation
|
||||
@ -33,7 +33,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_core_852_1(act_1: Action):
|
||||
def test_core_0852_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_857
|
||||
# id: bugs.core_0857
|
||||
# title: Containing not working correctly
|
||||
# decription:
|
||||
# Could not find build 2.0 RC3.
|
||||
@ -88,7 +88,7 @@ expected_stdout_1 = """
|
||||
|
||||
@pytest.mark.version('>=2.5')
|
||||
@pytest.mark.xfail
|
||||
def test_core_857_1(db_1):
|
||||
def test_core_0857_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_858
|
||||
# id: bugs.core_0858
|
||||
# title: Server crash when using UDF
|
||||
# decription:
|
||||
# Checked on:
|
||||
@ -76,7 +76,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_core_858_1(act_1: Action):
|
||||
def test_core_0858_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -102,6 +102,6 @@ act_2 = isql_act('db_2', test_script_2, substitutions=substitutions_2)
|
||||
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_core_858_2(act_2: Action):
|
||||
def test_core_0858_2(act_2: Action):
|
||||
act_2.execute()
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_866
|
||||
# id: bugs.core_0866
|
||||
# title: Removing a NOT NULL constraint is not visible until reconnect
|
||||
# decription:
|
||||
# tracker_id: CORE-866
|
||||
@ -46,7 +46,7 @@ expected_stderr_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_core_866_1(act_1: Action):
|
||||
def test_core_0866_1(act_1: Action):
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_871
|
||||
# id: bugs.core_0871
|
||||
# title: Incorrect handling of null within view - returns 0
|
||||
# decription:
|
||||
# tracker_id: CORE-871
|
||||
@ -43,7 +43,7 @@ expected_stdout_1 = """A B
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.1')
|
||||
def test_core_871_1(act_1: Action):
|
||||
def test_core_0871_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_878
|
||||
# id: bugs.core_0878
|
||||
# title: problem when dropping column that is a primary key
|
||||
# decription:
|
||||
# tracker_id: CORE-878
|
||||
@ -67,7 +67,7 @@ I2 INTEGER Nullable
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.1')
|
||||
def test_core_878_1(act_1: Action):
|
||||
def test_core_0878_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_879
|
||||
# id: bugs.core_0879
|
||||
# title: Dependencies are not cleared when creation of expression index fails
|
||||
# decription:
|
||||
# tracker_id: CORE-879
|
||||
@ -39,7 +39,7 @@ expected_stderr_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5')
|
||||
def test_core_879_1(act_1: Action):
|
||||
def test_core_0879_1(act_1: Action):
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_881
|
||||
# id: bugs.core_0881
|
||||
# title: Singleton isn't respected in COMPUTED BY expressions
|
||||
# decription:
|
||||
# tracker_id: CORE-881
|
||||
@ -40,7 +40,7 @@ multiple rows in singleton select
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5.0')
|
||||
def test_core_881_1(act_1: Action):
|
||||
def test_core_0881_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_883
|
||||
# id: bugs.core_0883
|
||||
# title: The built-in BLR printer doesn't support all FB2 features
|
||||
# decription:
|
||||
# tracker_id: CORE-883
|
||||
@ -134,7 +134,7 @@ RDB$PROCEDURE_BLR 1a:f1
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_core_883_1(act_1: Action):
|
||||
def test_core_0883_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_888
|
||||
# id: bugs.core_0888
|
||||
# title: DDL - object in use
|
||||
# decription:
|
||||
# tracker_id: CORE-888
|
||||
@ -37,6 +37,6 @@ act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
|
||||
@pytest.mark.version('>=2.0.1')
|
||||
def test_core_888_1(act_1: Action):
|
||||
def test_core_0888_1(act_1: Action):
|
||||
act_1.execute()
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_896
|
||||
# id: bugs.core_0896
|
||||
# title: SUBSTRING with NULL offset or length don't return NULL
|
||||
# decription:
|
||||
# tracker_id: CORE-896
|
||||
@ -37,7 +37,7 @@ SUBSTRING
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.1')
|
||||
def test_core_896_1(act_1: Action):
|
||||
def test_core_0896_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_899
|
||||
# id: bugs.core_0899
|
||||
# title: Problems with explicit cursors in unwanted states
|
||||
# decription:
|
||||
# tracker_id: CORE-899
|
||||
@ -133,7 +133,7 @@ no current record for fetch operation
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5.0')
|
||||
def test_core_899_1(act_1: Action):
|
||||
def test_core_0899_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_907
|
||||
# id: bugs.core_0907
|
||||
# title: Server crash on violation of NOT NULL constraint
|
||||
# decription:
|
||||
# tracker_id: CORE-907
|
||||
@ -78,7 +78,7 @@ expected_stderr_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_core_907_1(act_1: Action):
|
||||
def test_core_0907_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_925
|
||||
# id: bugs.core_0925
|
||||
# title: ALL predicate works incorrectly for some subqueries
|
||||
# decription:
|
||||
# tracker_id: CORE-925
|
||||
@ -63,6 +63,6 @@ act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
|
||||
@pytest.mark.version('>=2.1')
|
||||
def test_core_925_1(act_1: Action):
|
||||
def test_core_0925_1(act_1: Action):
|
||||
act_1.execute()
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_952
|
||||
# id: bugs.core_0952
|
||||
# title: AV when blob is used in expression index
|
||||
# decription:
|
||||
# tracker_id: CORE-952
|
||||
@ -48,7 +48,7 @@ expected_stdout_1 = """ID N2
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.0.1')
|
||||
def test_core_952_1(act_1: Action):
|
||||
def test_core_0952_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_965
|
||||
# id: bugs.core_0965
|
||||
# title: Many aggregate functions within a single select list may cause a server crash
|
||||
# decription: This test may crash the server.
|
||||
# tracker_id: CORE-965
|
||||
@ -40,7 +40,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_core_965_1(act_1: Action):
|
||||
def test_core_0965_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_972
|
||||
# id: bugs.core_0972
|
||||
# title: Case insensitive collation for UTF-8
|
||||
# decription: Basic test for case-insensitive comparison of char and blob fields with text literals. Use non-ascii text here.
|
||||
# tracker_id: CORE-972
|
||||
@ -59,7 +59,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5')
|
||||
def test_core_972_1(act_1: Action):
|
||||
def test_core_0972_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_979
|
||||
# id: bugs.core_0979
|
||||
# title: Make RDB$DB_KEY in outer joins return NULL when appropriate
|
||||
# decription: ----------------------------------------------------------------------------------------------
|
||||
# -- test de la fonctionalité
|
||||
@ -43,7 +43,7 @@ expected_stdout_1 = """DB_KEY
|
||||
<null>"""
|
||||
|
||||
@pytest.mark.version('>=2.1')
|
||||
def test_core_979_1(act_1: Action):
|
||||
def test_core_0979_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_995
|
||||
# id: bugs.core_0995
|
||||
# title: select with FIRST and LEFT JOIN needs excess SORT in plan
|
||||
# decription:
|
||||
# tracker_id: CORE-995
|
||||
@ -81,7 +81,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_core_995_1(act_1: Action):
|
||||
def test_core_0995_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_996
|
||||
# id: bugs.core_0996
|
||||
# title: Keyword AS not recognized in clause FROM
|
||||
# decription: The sentence SELECT * FROM <table> AS <alias> is not recognized correct.
|
||||
# tracker_id: CORE-996
|
||||
@ -34,7 +34,7 @@ expected_stdout_1 = """ ID1
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_core_996_1(act_1: Action):
|
||||
def test_core_0996_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
170
tests/bugs/test_core_3511.py
Normal file
170
tests/bugs/test_core_3511.py
Normal file
@ -0,0 +1,170 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_3511
|
||||
# title: Unquoted role names with non-ASCII characters passed in DPB are upper-cased wrongly
|
||||
# decription:
|
||||
# Test creates role with non-ascii characters and grants it to common user.
|
||||
# Then we try to connect to database using this role and specify it WITHOUT double quotes.
|
||||
#
|
||||
# ::: NB ::: DIFFERENT CODE FOR LINUX vs WINDOWS :::
|
||||
#
|
||||
# Attribute 'test_type' can be 'ISQL' only under LINUX.
|
||||
#
|
||||
# As of Windows, only system code page can be used when ISQL passes user/role containing non-ascii characters
|
||||
# (see letter from dimitr, 12-mar-2016, 19:14).
|
||||
#
|
||||
# Because of this, it was decided to use Pytthon FDB for connect with DPB that contains non-ascii data.
|
||||
# FDB method connect() of class Connection has parameter 'utf8params' with possible values True | False.
|
||||
# When this parameter is True, all info passed to DPB in UTF-8. Test uses this to form proper DPB and connect
|
||||
# to database with non-ascii role. This role must be specified WITHOUT double quotes.
|
||||
#
|
||||
# Checked on Linux: 3.0.8.33445, 4.0.0.2437
|
||||
# Checked on Windows 3.0.8.33452, 4.0.0.2436
|
||||
#
|
||||
# tracker_id:
|
||||
# min_versions: ['3.0']
|
||||
# versions: 3.0, 3.0
|
||||
# qmid: None
|
||||
|
||||
import pytest
|
||||
from firebird.qa import db_factory, isql_act, Action
|
||||
|
||||
# version: 3.0
|
||||
# resources: None
|
||||
|
||||
substitutions_1 = []
|
||||
|
||||
init_script_1 = """"""
|
||||
|
||||
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
|
||||
test_script_1 = """
|
||||
set wng off;
|
||||
set bail on;
|
||||
create or alter user tmp$c3511 password '123' using plugin Srp;
|
||||
create or alter view v_whoami as
|
||||
select current_user as cur_user,mon$role as mon_role,current_role as cur_role
|
||||
from mon$attachments
|
||||
where mon$attachment_id=current_connection;
|
||||
|
||||
revoke all on all from tmp$c3511;
|
||||
commit;
|
||||
|
||||
create table test(id int);
|
||||
|
||||
create role "Gros";
|
||||
create role "Groß";
|
||||
create role "αβγδε";
|
||||
|
||||
grant "Gros" to tmp$c3511;
|
||||
grant "Groß" to tmp$c3511;
|
||||
grant "αβγδε" to tmp$c3511;
|
||||
commit;
|
||||
|
||||
grant select on v_whoami to tmp$c3511;
|
||||
grant select on test to role "Gros";
|
||||
grant select on test to role "Groß";
|
||||
grant select on test to role "αβγδε";
|
||||
commit;
|
||||
|
||||
set list on;
|
||||
|
||||
set bail off;
|
||||
-- NB: do NOT enclose role name into double quotes here:
|
||||
connect '$(DSN)' user tmp$c3511 password '123' role αβγδε;
|
||||
select * from v_whoami;
|
||||
set plan on;
|
||||
select * from test;
|
||||
set plan off;
|
||||
commit;
|
||||
|
||||
-- NB: do NOT enclose role name into double quotes here:
|
||||
connect '$(DSN)' user tmp$c3511 password '123' role Groß;
|
||||
select * from v_whoami;
|
||||
set plan on;
|
||||
select * from test;
|
||||
set plan off;
|
||||
commit;
|
||||
"""
|
||||
|
||||
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
expected_stdout_1 = """
|
||||
CUR_USER TMP$C3511
|
||||
MON_ROLE αβγδε
|
||||
CUR_ROLE αβγδε
|
||||
PLAN (TEST NATURAL)
|
||||
|
||||
CUR_USER TMP$C3511
|
||||
MON_ROLE Groß
|
||||
CUR_ROLE Groß
|
||||
PLAN (TEST NATURAL)
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<3.0')
|
||||
@pytest.mark.platform('Linux')
|
||||
def test_core_3511_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
||||
# version: 3.0
|
||||
# resources: None
|
||||
|
||||
substitutions_2 = []
|
||||
|
||||
init_script_2 = """"""
|
||||
|
||||
db_2 = db_factory(sql_dialect=3, init=init_script_2)
|
||||
|
||||
# test_script_2
|
||||
#---
|
||||
#
|
||||
# import os
|
||||
#
|
||||
# os.environ["ISC_USER"] = 'SYSDBA'
|
||||
# os.environ["ISC_PASSWORD"] = 'masterkey'
|
||||
#
|
||||
# cur = db_conn.cursor()
|
||||
# cur.execute("create or alter user tmp$c3511 password '123' using plugin Srp")
|
||||
# cur.execute('create table test(id int)')
|
||||
# cur.execute('create role "Groß"')
|
||||
# db_conn.commit()
|
||||
#
|
||||
# cur.execute('grant "Groß" to tmp$c3511')
|
||||
# cur.execute('grant select on test to "Groß"')
|
||||
# db_conn.commit()
|
||||
#
|
||||
# # NB: do NOT enclose rolename Groß in double quotes here
|
||||
# # (this was needed in FB 2.5.x only; should NOT be necessarry in FB 3.x+):
|
||||
# con=fdb.connect(dsn = dsn, charset = 'utf8', utf8params = True, user = 'tmp$c3511', password = '123', role='Groß')
|
||||
#
|
||||
# cur=con.cursor()
|
||||
# cur.execute("select * from test");
|
||||
# for r in cur:
|
||||
# pass
|
||||
#
|
||||
# print('Done.')
|
||||
# cur.close()
|
||||
# con.close()
|
||||
#
|
||||
# con=fdb.connect(dsn = dsn)
|
||||
# con.execute_immediate('drop user tmp$c3511 using plugin Srp')
|
||||
# con.commit()
|
||||
# con.close()
|
||||
#
|
||||
#
|
||||
#---
|
||||
#act_2 = python_act('db_2', test_script_2, substitutions=substitutions_2)
|
||||
|
||||
expected_stdout_2 = """
|
||||
Done.
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_3511_2(db_2):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
||||
|
@ -10,6 +10,10 @@
|
||||
# 4.0.0.1685 CS: 12.078s.
|
||||
# 3.0.5.33206 SS: 10.827s.
|
||||
# 3.0.5.33206 CS: 11.793s.
|
||||
#
|
||||
# 13.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 3.0.8.33445, 4.0.0.2416
|
||||
# Linux: 3.0.8.33426, 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-4889
|
||||
# min_versions: ['3.0']
|
||||
@ -38,11 +42,48 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# fdb_file='$(DATABASE_LOCATION)bugs.core_4889.fdb'
|
||||
#
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
#
|
||||
# db_conn.close()
|
||||
#
|
||||
# #####################################################################
|
||||
# # Prepare config for trace session that will be launched by call of FBSVCMGR:
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
#
|
||||
# # Prepare config for trace session that will be launched by call of FBSVCMGR:
|
||||
# ################
|
||||
# txt = '''database= %[\\\\\\\\/]bugs.core_4889.fdb
|
||||
# {
|
||||
# enabled = true
|
||||
@ -53,19 +94,17 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# '''
|
||||
# trc_cfg=open( os.path.join(context['temp_directory'],'tmp_trace_4889.cfg'), 'w')
|
||||
# trc_cfg.write(txt)
|
||||
# trc_cfg.close()
|
||||
# trc_log=open( os.path.join(context['temp_directory'],'tmp_trace_4889.log'), 'w')
|
||||
# trc_log.close()
|
||||
# trc_lst=open( os.path.join(context['temp_directory'],'tmp_trace_4889.lst'), 'w')
|
||||
# trc_lst.close()
|
||||
#
|
||||
# flush_and_close( trc_cfg )
|
||||
#
|
||||
# #####################################################################
|
||||
# # Async. launch of trace session using FBSVCMGR action_trace_start:
|
||||
#
|
||||
# trc_log=open(trc_log.name, "w")
|
||||
# trc_log = open( os.path.join(context['temp_directory'],'tmp_trace_4889.log'), 'w')
|
||||
#
|
||||
# # Execute a child program in a new process, redirecting STDERR to the same target as of STDOUT:
|
||||
# p_svcmgr = Popen( ["fbsvcmgr", "localhost:service_mgr", "user" , "SYSDBA" , "password" , "masterkey", "action_trace_start","trc_cfg", trc_cfg.name], stdout=trc_log, stderr=subprocess.STDOUT)
|
||||
# p_svcmgr = Popen( [context['fbsvcmgr_path'], "localhost:service_mgr",
|
||||
# "action_trace_start","trc_cfg", trc_cfg.name],
|
||||
# stdout=trc_log, stderr=subprocess.STDOUT)
|
||||
#
|
||||
# # Wait! Trace session is initialized not instantly!
|
||||
# time.sleep(2)
|
||||
@ -74,9 +113,12 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# # Determine active trace session ID (for further stop):
|
||||
#
|
||||
# trc_lst=open(trc_lst.name, "w")
|
||||
# subprocess.call(["fbsvcmgr", "localhost:service_mgr", "user" , "SYSDBA" , "password" , "masterkey", "action_trace_list"], stdout=trc_lst, stderr=subprocess.STDOUT )
|
||||
# trc_lst.close()
|
||||
# trc_lst = open( os.path.join(context['temp_directory'],'tmp_trace_4889.lst'), 'w')
|
||||
# subprocess.call([context['fbsvcmgr_path'], "localhost:service_mgr",
|
||||
# "action_trace_list"],
|
||||
# stdout=trc_lst, stderr=subprocess.STDOUT
|
||||
# )
|
||||
# flush_and_close( trc_lst )
|
||||
#
|
||||
# # Session ID: 5
|
||||
# # user:
|
||||
@ -98,7 +140,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# # We have to terminate trace session that is running on server BEFORE we termitane process `p_svcmgr`
|
||||
# if trcssn==0:
|
||||
# print("Error parsing trace session ID.")
|
||||
# trc_log.close()
|
||||
# flush_and_close( trc_log )
|
||||
#
|
||||
# else:
|
||||
# #####################################################################
|
||||
@ -120,7 +162,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# isql_cmd=open( os.path.join(context['temp_directory'],'tmp_isql_4889.sql'), 'w')
|
||||
# isql_cmd.write(sql_cmd)
|
||||
# isql_cmd.close()
|
||||
# flush_and_close( isql_cmd )
|
||||
#
|
||||
# #######################################################################
|
||||
#
|
||||
@ -131,13 +173,18 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# # **HANGS** on WI-V3.0.0.31948, build 16-jul-2015
|
||||
#
|
||||
# isql_log=open( os.path.join(context['temp_directory'],'tmp_isql_4889.log'), 'w')
|
||||
# p_isql = Popen( [ "isql" , fdb_file, "-user", "tmp$no$such$user$4889", "-n", "-i", isql_cmd.name ], stdout=isql_log, stderr=subprocess.STDOUT )
|
||||
# p_isql = Popen( [ context['isql_path'] , fdb_file,
|
||||
# "-user", "tmp$no$such$user$4889",
|
||||
# "-n", "-i", isql_cmd.name ],
|
||||
# stdout=isql_log,
|
||||
# stderr=subprocess.STDOUT
|
||||
# )
|
||||
#
|
||||
# # do NOT remove this delay:
|
||||
# time.sleep(5)
|
||||
#
|
||||
# p_isql.terminate()
|
||||
# isql_log.close()
|
||||
# flush_and_close( isql_log )
|
||||
#
|
||||
# #####################################################################
|
||||
#
|
||||
@ -145,11 +192,14 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# trc_lst=open(trc_lst.name, "a")
|
||||
# trc_lst.seek(0,2)
|
||||
# subprocess.call([ "fbsvcmgr", "localhost:service_mgr", "user" , "SYSDBA" , "password" , "masterkey", "action_trace_stop","trc_id",trcssn], stdout=trc_lst, stderr=subprocess.STDOUT )
|
||||
# trc_lst.close()
|
||||
# subprocess.call([ context['fbsvcmgr_path'], "localhost:service_mgr",
|
||||
# "action_trace_stop","trc_id",trcssn],
|
||||
# stdout=trc_lst, stderr=subprocess.STDOUT
|
||||
# )
|
||||
# flush_and_close( trc_lst )
|
||||
#
|
||||
# p_svcmgr.terminate()
|
||||
# trc_log.close()
|
||||
# flush_and_close( trc_log )
|
||||
#
|
||||
# # do NOT remove this delay:
|
||||
# time.sleep(2)
|
||||
@ -182,8 +232,6 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# # do NOT remove this pause otherwise log of trace will not be enable for deletion and test will finish with
|
||||
# # Exception raised while executing Python test script. exception: WindowsError: 32
|
||||
#
|
||||
# time.sleep(1)
|
||||
#
|
||||
# # On WI-V3.0.0.31948 final output was:
|
||||
# # FAILED to found text in trace related to EMBEDDED connect.
|
||||
# # FAILED to print log from EMBEDDED connect: log is EMPTY.
|
||||
@ -191,13 +239,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# #####################################################################
|
||||
#
|
||||
# # Cleanup:
|
||||
#
|
||||
# f_list = [ trc_lst, trc_cfg, trc_log ]
|
||||
# if trcssn > 0:
|
||||
# f_list += [isql_cmd, isql_log, ]
|
||||
#
|
||||
# for f in f_list:
|
||||
# os.remove(f.name)
|
||||
# time.sleep(1)
|
||||
# cleanup( (trc_lst, trc_cfg, trc_log,isql_cmd, isql_log) )
|
||||
#
|
||||
#
|
||||
#---
|
||||
@ -213,7 +256,6 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_4889_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -10,11 +10,9 @@
|
||||
# # account local timezone from OS settings (this is so at least on Windows). Thus we have to add/substract time shift
|
||||
# # between UTC and local time - this is done by 'time.timezone' summand.
|
||||
# # On PC-host with CPU 3.0 GHz and 2Gb RAM) in almost all cases difference was less than 1000 ms, so it was decided
|
||||
# # to set threshold = 1200 ms.
|
||||
# # to set MAX_DETACH_TIME_THRESHOLD = 1200 ms.
|
||||
# # Tested on WI-V3.0.0.32140 (SS/SC/CC).
|
||||
# ##########################################################################
|
||||
# # Test on LINUX was not done yet, so I've assign platform = 'Windows' yet.
|
||||
# ##########################################################################
|
||||
#
|
||||
# Results for 22.05.2017:
|
||||
# fb30Cs, build 3.0.3.32725: OK, 1.796ss.
|
||||
# fb30SC, build 3.0.3.32725: OK, 1.047ss.
|
||||
@ -23,6 +21,9 @@
|
||||
# FB40SC, build 4.0.0.645: OK, 1.188ss.
|
||||
# FB40SS, build 4.0.0.645: OK, 1.157ss.
|
||||
#
|
||||
# 13.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 3.0.8.33445, 4.0.0.2416
|
||||
# Linux: 3.0.8.33426, 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-4977
|
||||
# min_versions: ['3.0']
|
||||
@ -52,6 +53,45 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
#
|
||||
# ############################################
|
||||
# ### d e f i n e t h r e s h o l d ###
|
||||
# ############################################
|
||||
# MAX_DETACH_TIME_THRESHOLD=1200
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# sqltxt='''
|
||||
# set list on;
|
||||
# select datediff(second from timestamp '01.01.1970 00:00:00.000' to current_timestamp) as " "
|
||||
@ -60,19 +100,19 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# f_isql_cmd=open( os.path.join(context['temp_directory'],'tmp_4977.sql'), 'w')
|
||||
# f_isql_cmd.write(sqltxt)
|
||||
# f_isql_cmd.close()
|
||||
# flush_and_close( f_isql_cmd )
|
||||
#
|
||||
# ms_before_detach=0
|
||||
#
|
||||
# f_isql_log = open( os.path.join(context['temp_directory'],'tmp_4977.log'), 'w')
|
||||
# f_isql_err = open( os.path.join(context['temp_directory'],'tmp_4977.err'), 'w')
|
||||
#
|
||||
# subprocess.call( ["isql", dsn, "-i", f_isql_cmd.name ],
|
||||
# subprocess.call( [context['isql_path'], dsn, "-i", f_isql_cmd.name ],
|
||||
# stdout = f_isql_log,
|
||||
# stderr = f_isql_err
|
||||
# )
|
||||
# f_isql_log.close()
|
||||
# f_isql_err.close()
|
||||
# flush_and_close( f_isql_log )
|
||||
# flush_and_close( f_isql_err )
|
||||
#
|
||||
# with open( f_isql_log.name,'r') as f:
|
||||
# for line in f:
|
||||
@ -84,20 +124,14 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# detach_during_ms = int( (time.time() - ms_before_detach - time.timezone) * 1000 )
|
||||
#
|
||||
# ############################################
|
||||
# ### d e f i n e t h r e s h o l d ###
|
||||
# ############################################
|
||||
# threshold=1200
|
||||
#
|
||||
# if detach_during_ms < threshold:
|
||||
# if detach_during_ms < MAX_DETACH_TIME_THRESHOLD:
|
||||
# print('Detach performed fast enough: less than threshold.')
|
||||
# else:
|
||||
# print('Detach lasted too long time: %s ms, threshold is %s ms' % (detach_during_ms, threshold) )
|
||||
# print('Detach lasted too long time: %s ms, MAX_DETACH_TIME_THRESHOLD is %s ms' % (detach_during_ms, MAX_DETACH_TIME_THRESHOLD) )
|
||||
#
|
||||
# f_list=(f_isql_log, f_isql_err, f_isql_cmd)
|
||||
# for i in range(len(f_list)):
|
||||
# if os.path.isfile(f_list[i].name):
|
||||
# os.remove(f_list[i].name)
|
||||
# # cleanup:
|
||||
# time.sleep(1)
|
||||
# cleanup((f_isql_log, f_isql_err, f_isql_cmd))
|
||||
#
|
||||
#---
|
||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
@ -107,7 +141,6 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_4977_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -1,7 +1,7 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_5077
|
||||
# title: ISQL does not show encryption status of database
|
||||
# title: ISQL 'SHOW DATABASE' command does not show encryption status of database
|
||||
# decription:
|
||||
# We create new database ('tmp_core_5077.fdb') and try to encrypt it usng IBSurgeon Demo Encryption package
|
||||
# ( https://ib-aid.com/download-demo-firebird-encryption-plugin/ ; https://ib-aid.com/download/crypt/CryptTest.zip )
|
||||
@ -9,14 +9,6 @@
|
||||
# This file was preliminary stored in FF Test machine.
|
||||
# Test assumes that this file and all neccessary libraries already were stored into FB_HOME and %FB_HOME%\\plugins.
|
||||
#
|
||||
# Anyone who wants to run this test on his own machine must
|
||||
# 1) download https://ib-aid.com/download/crypt/CryptTest.zip AND
|
||||
# 2) PURCHASE LICENSE and get from IBSurgeon file plugins\\dbcrypt.conf with apropriate expiration date and other info.
|
||||
#
|
||||
# ################################################ ! ! ! N O T E ! ! ! ##############################################
|
||||
# FF tests storage (aka "fbt-repo") does not (and will not) contain any license file for IBSurgeon Demo Encryption package!
|
||||
# #########################################################################################################################
|
||||
#
|
||||
# After test database will be created, we try to encrypt it using 'alter database encrypt with <plugin_name> ...' command
|
||||
# (where <plugin_name> = dbcrypt - name of .dll in FB_HOME\\plugins\\ folder that implements encryption).
|
||||
# Then we allow engine to complete this job - take delay about 1..2 seconds BEFORE detach from database.
|
||||
@ -27,28 +19,12 @@
|
||||
#
|
||||
# Checked on: 4.0.0.1629: OK, 6.264s; 3.0.5.33179: OK, 4.586s.
|
||||
#
|
||||
# === NOTE-1 ===
|
||||
# In case of "Crypt plugin DBCRYPT failed to load/607/335544351" check that all
|
||||
# needed files from IBSurgeon Demo Encryption package exist in %FB_HOME% and %FB_HOME%\\plugins
|
||||
# %FB_HOME%:
|
||||
# 283136 fbcrypt.dll
|
||||
# 2905600 libcrypto-1_1-x64.dll
|
||||
# 481792 libssl-1_1-x64.dll
|
||||
#
|
||||
# %FB_HOME%\\plugins:
|
||||
# 297984 dbcrypt.dll
|
||||
# 306176 keyholder.dll
|
||||
# 108 DbCrypt.conf
|
||||
# 856 keyholder.conf
|
||||
#
|
||||
# === NOTE-2 ===
|
||||
# Version of DbCrypt.dll of october-2018 must be replaced because it has hard-coded
|
||||
# date of expiration rather than reading it from DbCrypt.conf !!
|
||||
#
|
||||
# === NOTE-3 ===
|
||||
# firebird.conf must contain following line:
|
||||
# KeyHolderPlugin = KeyHolder
|
||||
#
|
||||
# 13.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
# Note: different names for encryption plugin and keyholde rare used for Windows vs Linux:
|
||||
# PLUGIN_NAME = 'dbcrypt' if os.name == 'nt' else '"fbSampleDbCrypt"'
|
||||
# KHOLDER_NAME = 'KeyHolder' if os.name == 'nt' else "fbSampleKeyHolder"
|
||||
#
|
||||
# tracker_id: CORE-5077
|
||||
# min_versions: ['3.0.0']
|
||||
@ -77,32 +53,64 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# import fdb
|
||||
# from fdb import services
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if os.path.isfile( f_names_list[i]):
|
||||
# os.remove( f_names_list[i] )
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
# engine = db_conn.engine_version
|
||||
# db_conn.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# fb_home = services.connect(host='localhost', user= user_name, password= user_password).get_home_directory()
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# db_conn.close()
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# tmpfdb='$(DATABASE_LOCATION)'+'tmp_core_5077.fdb'
|
||||
#
|
||||
# if os.path.isfile( tmpfdb ):
|
||||
# os.remove( tmpfdb )
|
||||
# cleanup( (tmpfdb,) )
|
||||
#
|
||||
# con = fdb.create_database( dsn = 'localhost:'+tmpfdb )
|
||||
# con.close()
|
||||
# con=fdb.connect( dsn = 'localhost:'+tmpfdb )
|
||||
#
|
||||
# # 14.04.2021.
|
||||
# # Name of encryption plugin depends on OS:
|
||||
# # * for Windows we (currently) use plugin by IBSurgeon, its name is 'dbcrypt';
|
||||
# # * for Linux we use:
|
||||
# # ** 'DbCrypt_example' for FB 3.x
|
||||
# # ** 'fbSampleDbCrypt' for FB 4.x+
|
||||
# #
|
||||
# PLUGIN_NAME = 'dbcrypt' if os.name == 'nt' else ( '"fbSampleDbCrypt"' if engine >= 4.0 else '"DbCrypt_example"')
|
||||
# KHOLDER_NAME = 'KeyHolder' if os.name == 'nt' else "fbSampleKeyHolder"
|
||||
#
|
||||
# cur = con.cursor()
|
||||
# cur.execute('alter database encrypt with dbcrypt key Red')
|
||||
# cur.execute('alter database encrypt with %(PLUGIN_NAME)s key Red' % locals())
|
||||
# ### DOES NOT WORK ON LINUX! ISSUES 'TOKEN UNKNOWN' !! >>> con.execute_immediate('alter database encrypt with %(PLUGIN_NAME)s key Red' % locals()) // sent letter to Alex and dimitr, 14.04.2021
|
||||
# con.commit()
|
||||
# time.sleep(2)
|
||||
# # ^
|
||||
@ -110,25 +118,27 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# con.close()
|
||||
#
|
||||
# #--------------------------------- run ISQL --------------------
|
||||
# ########################################
|
||||
# # run ISQL with 'SHOW DATABASE' command:
|
||||
# ########################################
|
||||
# f_isql_cmd=open( os.path.join(context['temp_directory'],'tmp_5077.sql'), 'w')
|
||||
# f_isql_cmd.write('show database;')
|
||||
# f_isql_cmd.close()
|
||||
# flush_and_close( f_isql_cmd )
|
||||
#
|
||||
# f_isql_log=open( os.path.join(context['temp_directory'], 'tmp_5077.log'), 'w')
|
||||
# f_isql_err=open( os.path.join(context['temp_directory'], 'tmp_5077.err'), 'w')
|
||||
# subprocess.call( [fb_home+'isql', 'localhost:' + tmpfdb, '-q', '-n', '-i', f_isql_cmd.name ], stdout=f_isql_log, stderr = f_isql_err)
|
||||
# f_isql_log.close()
|
||||
# f_isql_err.close()
|
||||
# subprocess.call( [context['isql_path'], 'localhost:' + tmpfdb, '-q', '-n', '-i', f_isql_cmd.name ], stdout=f_isql_log, stderr = f_isql_err)
|
||||
# flush_and_close( f_isql_log )
|
||||
# flush_and_close( f_isql_err )
|
||||
#
|
||||
# #---------------------------- shutdown temp DB --------------------
|
||||
#
|
||||
# f_dbshut_log = open( os.path.join(context['temp_directory'],'tmp_dbshut_5077.log'), 'w')
|
||||
# subprocess.call( [ "gfix", 'localhost:'+tmpfdb, "-shut", "full", "-force", "0" ],
|
||||
# subprocess.call( [ context['gfix_path'], 'localhost:'+tmpfdb, "-shut", "full", "-force", "0" ],
|
||||
# stdout = f_dbshut_log,
|
||||
# stderr = subprocess.STDOUT
|
||||
# )
|
||||
# f_dbshut_log.close()
|
||||
# flush_and_close( f_dbshut_log )
|
||||
#
|
||||
# allowed_patterns = (
|
||||
# re.compile( 'Database(\\s+not){0,1}\\s+encrypted\\.*', re.IGNORECASE),
|
||||
@ -148,15 +158,12 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# for line in f:
|
||||
# print("Unexpected error on SHUTDOWN temp database: "+line)
|
||||
#
|
||||
# time.sleep(1)
|
||||
#
|
||||
# # CLEANUP
|
||||
# #########
|
||||
# time.sleep(1)
|
||||
#
|
||||
# f_list = [ i.name for i in ( f_isql_log, f_isql_err, f_isql_cmd, f_dbshut_log ) ]
|
||||
# f_list += [ tmpfdb ]
|
||||
# cleanup( f_list )
|
||||
#
|
||||
# cleanup( ( f_isql_log, f_isql_err, f_isql_cmd, f_dbshut_log,tmpfdb ) )
|
||||
#
|
||||
#---
|
||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
@ -166,7 +173,6 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_5077_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -3,14 +3,18 @@
|
||||
# id: bugs.core_5220
|
||||
# title: ISQL -X: double quotes are missed for COLLATE <C> of CREATE DOMAIN statement when <C> is from any non-ascii charset
|
||||
# decription:
|
||||
# We create in init_script two collations with non-ascii names and two varchar domains which use these collations.
|
||||
# Then we extract metadata and save it to file as .sql script to be applied further.
|
||||
# This script should contain CORRECT domains definition, i.e. collations should be enclosed in double quotes.
|
||||
# We check correctness by removing from database all objects and applying this script: no errors should occur at that point.
|
||||
# Then we extract metadata second time, store it to second .sql and COMPARE this file with result of first metadata extraction.
|
||||
# These files should be equal, i.e. difference should be empty.
|
||||
#
|
||||
# Checked on WI-V3.0.0.32501, WI-T4.0.0.155.
|
||||
# We create in init_script two collations with non-ascii names and two varchar domains which use these collations.
|
||||
# Then we extract metadata and save it to file as .sql script to be applied further.
|
||||
# This script should contain CORRECT domains definition, i.e. collations should be enclosed in double quotes.
|
||||
# We check correctness by removing from database all objects and applying this script: no errors should occur at that point.
|
||||
# Then we extract metadata second time, store it to second .sql and COMPARE this file with result of first metadata extraction.
|
||||
# These files should be equal, i.e. difference should be empty.
|
||||
#
|
||||
# Checked on WI-V3.0.0.32501, WI-T4.0.0.155.
|
||||
#
|
||||
# 13.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-5220
|
||||
# min_versions: ['3.0']
|
||||
@ -25,14 +29,7 @@ from firebird.qa import db_factory, isql_act, Action
|
||||
|
||||
substitutions_1 = []
|
||||
|
||||
init_script_1 = """
|
||||
create collation "Циферки" for utf8 from unicode case insensitive 'NUMERIC-SORT=1';
|
||||
create collation "Испания" for iso8859_1 from es_es_ci_ai 'SPECIALS-FIRST=1';;
|
||||
commit;
|
||||
create domain "Артикулы" varchar(12) character set utf8 collate "Циферки";
|
||||
create domain "Комрады" varchar(40) character set iso8859_1 collate "Испания";
|
||||
commit;
|
||||
"""
|
||||
init_script_1 = """"""
|
||||
|
||||
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
|
||||
@ -42,44 +39,123 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# import time
|
||||
# import subprocess
|
||||
# import difflib
|
||||
# import io
|
||||
#
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
#
|
||||
# db_conn.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# sql_txt=''' set bail on;
|
||||
# set names utf8;
|
||||
# connect '%(dsn)s' user '%(user_name)s' password '%(user_password)s';
|
||||
#
|
||||
# create collation "Циферки" for utf8 from unicode case insensitive 'NUMERIC-SORT=1';
|
||||
# create collation "Испания" for iso8859_1 from es_es_ci_ai 'SPECIALS-FIRST=1';;
|
||||
# commit;
|
||||
# create domain "Артикулы" varchar(12) character set utf8 collate "Циферки";
|
||||
# create domain "Комрады" varchar(40) character set iso8859_1 collate "Испания";
|
||||
# commit;
|
||||
# ''' % dict(globals(), **locals())
|
||||
#
|
||||
# f_ddl_sql = open( os.path.join(context['temp_directory'], 'tmp_5220_ddl.sql'), 'w' )
|
||||
# f_ddl_sql.write( sql_txt )
|
||||
# flush_and_close( f_ddl_sql )
|
||||
#
|
||||
# f_ddl_log = open( os.path.splitext(f_ddl_sql.name)[0]+'.log', 'w')
|
||||
# subprocess.call( [ context['isql_path'], '-q', '-i', f_ddl_sql.name ],
|
||||
# stdout = f_ddl_log,
|
||||
# stderr = subprocess.STDOUT
|
||||
# )
|
||||
# flush_and_close( f_ddl_log )
|
||||
#
|
||||
#
|
||||
# f_extract_meta1_sql = open( os.path.join(context['temp_directory'],'tmp_5220_meta1.sql'), 'w')
|
||||
# subprocess.call( ["isql", dsn, "-x"],
|
||||
# subprocess.call( [context['isql_path'], dsn, "-x"],
|
||||
# stdout = f_extract_meta1_sql,
|
||||
# stderr = subprocess.STDOUT
|
||||
# )
|
||||
# f_extract_meta1_sql.close()
|
||||
# flush_and_close( f_extract_meta1_sql )
|
||||
#
|
||||
# f_remove_meta_sql = open( os.path.join(context['temp_directory'],'tmp_5220_kill.sql'), 'w')
|
||||
# f_remove_meta_sql.write('drop domain "Комрады"; drop domain "Артикулы"; drop collation "Испания"; drop collation "Циферки"; commit; show domain; show collation;')
|
||||
# f_remove_meta_sql.close()
|
||||
#
|
||||
# sql_txt=''' drop domain "Комрады";
|
||||
# drop domain "Артикулы";
|
||||
# drop collation "Испания";
|
||||
# drop collation "Циферки";
|
||||
# commit;
|
||||
#
|
||||
# set list on;
|
||||
# set count on;
|
||||
# select f.rdb$field_name
|
||||
# from rdb$fields f
|
||||
# where
|
||||
# f.rdb$system_flag is distinct from 1
|
||||
# and f.rdb$field_name not starting with upper('rdb$');
|
||||
#
|
||||
# select r.rdb$collation_name
|
||||
# from rdb$collations r
|
||||
# where
|
||||
# r.rdb$system_flag is distinct from 1;
|
||||
# '''
|
||||
# f_remove_meta_sql.write(sql_txt)
|
||||
# flush_and_close( f_remove_meta_sql )
|
||||
#
|
||||
# f_remove_meta_log = open( os.path.join(context['temp_directory'],'tmp_5220_kill.log'), 'w')
|
||||
# subprocess.call( ["isql", dsn, "-ch", "utf8", "-i", f_remove_meta_sql.name],
|
||||
# subprocess.call( [context['isql_path'], dsn, "-ch", "utf8", "-i", f_remove_meta_sql.name],
|
||||
# stdout = f_remove_meta_log,
|
||||
# stderr = subprocess.STDOUT
|
||||
# )
|
||||
# f_remove_meta_log.close()
|
||||
# flush_and_close( f_remove_meta_log )
|
||||
#
|
||||
# f_apply_meta_log = open( os.path.join(context['temp_directory'],'tmp_5220_apply.log'), 'w')
|
||||
# subprocess.call( ["isql", dsn, "-ch", "utf8", "-i", f_extract_meta1_sql.name],
|
||||
# subprocess.call( [context['isql_path'], dsn, "-ch", "utf8", "-i", f_extract_meta1_sql.name],
|
||||
# stdout = f_apply_meta_log,
|
||||
# stderr = subprocess.STDOUT
|
||||
# )
|
||||
# f_apply_meta_log.close()
|
||||
# flush_and_close( f_apply_meta_log )
|
||||
#
|
||||
#
|
||||
# f_extract_meta2_sql = open( os.path.join(context['temp_directory'],'tmp_5220_meta2.sql'), 'w')
|
||||
# subprocess.call( ["isql", dsn, "-x"],
|
||||
# subprocess.call( [context['isql_path'], dsn, "-x"],
|
||||
# stdout = f_extract_meta2_sql,
|
||||
# stderr = subprocess.STDOUT
|
||||
# )
|
||||
# f_extract_meta2_sql.close()
|
||||
# flush_and_close( f_extract_meta2_sql )
|
||||
#
|
||||
# time.sleep(1)
|
||||
#
|
||||
@ -92,7 +168,6 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# for line in f:
|
||||
# if line.strip():
|
||||
# print('REMOVE METADATA LOG: '+line)
|
||||
# f.close()
|
||||
#
|
||||
# # 2. Log f_apply_meta_log (result of APPLYING extracted metadata, file: f_extract_meta1_sql) should be EMPTY
|
||||
# # (because collation names now should be enclosed in double quotes)
|
||||
@ -100,7 +175,6 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# for line in f:
|
||||
# if line.strip():
|
||||
# print('APPLY EXTRACTED METADATA LOG: '+line)
|
||||
# f.close()
|
||||
#
|
||||
# # 3. Log f_extract_meta2_sql should EXACTLY match to first extracted metadata log (f_extract_meta1_sql).
|
||||
# # We compare these files using Python 'diff' package.
|
||||
@ -122,41 +196,30 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# old_file.close()
|
||||
# new_file.close()
|
||||
#
|
||||
# f_diff_txt.close()
|
||||
# flush_and_close( f_diff_txt )
|
||||
#
|
||||
# # Should be EMPTY:
|
||||
# ##################
|
||||
# with open( f_diff_txt.name,'r') as f:
|
||||
# for line in f:
|
||||
# print( 'METADATA DIFF:' + ' '.join(line.split()).upper() )
|
||||
# f.close()
|
||||
#
|
||||
#
|
||||
# #####################################################################
|
||||
# # Cleanup:
|
||||
#
|
||||
# f_list=[]
|
||||
# f_list.append(f_extract_meta1_sql)
|
||||
# f_list.append(f_extract_meta2_sql)
|
||||
# f_list.append(f_apply_meta_log)
|
||||
# f_list.append(f_remove_meta_log)
|
||||
# f_list.append(f_remove_meta_sql)
|
||||
# f_list.append(f_diff_txt)
|
||||
#
|
||||
# for i in range(len(f_list)):
|
||||
# if os.path.isfile(f_list[i].name):
|
||||
# os.remove(f_list[i].name)
|
||||
# time.sleep(1)
|
||||
# cleanup((f_extract_meta1_sql,f_extract_meta2_sql,f_apply_meta_log,f_remove_meta_log,f_remove_meta_sql,f_diff_txt,f_ddl_sql,f_ddl_log))
|
||||
#
|
||||
#
|
||||
#---
|
||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
expected_stdout_1 = """
|
||||
REMOVE METADATA LOG: There are no domains in this database
|
||||
REMOVE METADATA LOG: There are no user-defined collations in this database
|
||||
REMOVE METADATA LOG: Records affected: 0
|
||||
REMOVE METADATA LOG: Records affected: 0
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_5220_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -10,6 +10,10 @@
|
||||
# 4.0.0.1635 SS: 2.782s.
|
||||
# 4.0.0.1633 CS: 3.515s.
|
||||
# NB: old checked on: 4.0.0.639 - did pass without using codecs! Strange!
|
||||
#
|
||||
# 13.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-5389
|
||||
# min_versions: ['4.0']
|
||||
@ -36,38 +40,70 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# # 30.10.2019. This is needed in Python 2.7 for converting string in UTF8 to cp1251
|
||||
# import codecs
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if os.path.isfile( f_names_list[i]):
|
||||
# os.remove( f_names_list[i] )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# import io
|
||||
#
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
#
|
||||
# db_conn.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# non_ascii_ddl='''
|
||||
# set bail on;
|
||||
# set list on;
|
||||
# -- set names win1251;
|
||||
# connect '%(dsn)s' user '%(user_name)s' password '%(user_password)s';
|
||||
#
|
||||
# select
|
||||
# '' as "ФИО"
|
||||
# ,'' as "Д.рождения"
|
||||
# ,'' as "Город"
|
||||
# ,'' as "Расшифровка выступлений"
|
||||
# from rdb$database;
|
||||
# '''
|
||||
# ''' % dict(globals(), **locals())
|
||||
#
|
||||
# f_checksql=os.path.join(context['temp_directory'],'tmp_non_ascii_ddl_5389.sql')
|
||||
# with codecs.open( f_checksql, 'w', encoding='cp1251') as f:
|
||||
# f.write( non_ascii_ddl.decode('utf-8') )
|
||||
# f_checksql = open( os.path.join(context['temp_directory'], 'tmp_5389_w1251.sql'), 'w' )
|
||||
# f_checksql.write( non_ascii_ddl.decode('utf8').encode('cp1251') )
|
||||
# flush_and_close( f_checksql )
|
||||
#
|
||||
# # Result: file 'tmp_non_ascii_chk_5389.sql' is encoded in cp1251 and contains SQL statements to be executed.
|
||||
# # result: file 'tmp_non_ascii_chk_5389.sql' is encoded in win1251
|
||||
#
|
||||
# #f_checksql=os.path.join(context['temp_directory'],'tmp_non_ascii_ddl_5389.sql')
|
||||
# #with io.open( f_checksql, 'w', encoding='cp1251') as f:
|
||||
# # f.write( non_ascii_ddl.decode('utf-8') )
|
||||
#
|
||||
# ###########################################################################################################
|
||||
# ### check-1: attempt to apply DDL with non-ascii characters __WITHOUT__ charset specifying (for ISQL) ###
|
||||
@ -76,13 +112,13 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# f_apply_cset_none_log = open( os.path.join(context['temp_directory'],'tmp_5389_apply_cset_none.log'), 'w')
|
||||
# f_apply_cset_none_err = open( os.path.join(context['temp_directory'],'tmp_5389_apply_cset_none.err'), 'w')
|
||||
#
|
||||
# subprocess.call( ["isql", dsn, "-i", f_checksql ],
|
||||
# subprocess.call( [context['isql_path'], "-q", "-i", f_checksql.name ],
|
||||
# stdout = f_apply_cset_none_log,
|
||||
# stderr = f_apply_cset_none_err
|
||||
# )
|
||||
#
|
||||
# f_apply_cset_none_log.close()
|
||||
# f_apply_cset_none_err.close()
|
||||
# flush_and_close( f_apply_cset_none_log )
|
||||
# flush_and_close( f_apply_cset_none_err )
|
||||
#
|
||||
# #############################################################################################################
|
||||
# ### check-2: attempt to apply DDL with non-ascii characters ___WITH___ specifying: ISQL ... -ch WIN1251 ###
|
||||
@ -91,20 +127,15 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# f_apply_cset_1251_log = open( os.path.join(context['temp_directory'],'tmp_5389_apply_cset_1251.log'), 'w')
|
||||
# f_apply_cset_1251_err = open( os.path.join(context['temp_directory'],'tmp_5389_apply_cset_1251.err'), 'w')
|
||||
#
|
||||
# subprocess.call( ["isql", dsn, "-i", f_checksql, "-ch", "win1251" ],
|
||||
# subprocess.call( [context['isql_path'], "-q", "-i", f_checksql.name, "-ch", "win1251" ],
|
||||
# stdout = f_apply_cset_1251_log,
|
||||
# stderr = f_apply_cset_1251_err
|
||||
# )
|
||||
#
|
||||
# f_apply_cset_1251_log.close()
|
||||
# flush_and_close( f_apply_cset_1251_log )
|
||||
#
|
||||
# # This file should NOT contain any errors:
|
||||
# f_apply_cset_1251_err.close()
|
||||
#
|
||||
# # do NOT remove this pause otherwise some of logs will not be enable for deletion and test will finish with
|
||||
# # Exception raised while executing Python test script. exception: WindowsError: 32
|
||||
# time.sleep(1)
|
||||
#
|
||||
# flush_and_close( f_apply_cset_1251_err )
|
||||
#
|
||||
# # CHECK RESULTS:
|
||||
# ################
|
||||
@ -116,7 +147,6 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# out_txt='STDLOG WHEN CSET=NONE: ';
|
||||
# if line.strip():
|
||||
# print( out_txt+line.strip().decode("cp1251").encode('utf8') )
|
||||
# f.close()
|
||||
#
|
||||
#
|
||||
# with open( f_apply_cset_none_err.name, 'r') as f:
|
||||
@ -125,30 +155,23 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# if line.strip():
|
||||
# print( out_txt+line.strip().decode("cp1251").encode('utf8') )
|
||||
#
|
||||
# f.close()
|
||||
#
|
||||
#
|
||||
# with open( f_apply_cset_1251_log.name, 'r') as f:
|
||||
# for line in f:
|
||||
# out_txt='STDLOG WHEN CSET=WIN1251: ';
|
||||
# if line.strip():
|
||||
# print( out_txt+line.strip().decode("cp1251").encode('utf8') )
|
||||
# f.close()
|
||||
#
|
||||
# with open( f_apply_cset_1251_err.name, 'r') as f:
|
||||
# for line in f:
|
||||
# out_txt='STDERR WHEN CSET=WIN1251: ';
|
||||
# if line.strip():
|
||||
# print( out_txt+line.strip().decode("cp1251").encode('utf8') )
|
||||
# f.close()
|
||||
#
|
||||
#
|
||||
# #####################################################################
|
||||
# # Cleanup:
|
||||
#
|
||||
# f_list = [ i.name for i in ( f_apply_cset_none_log, f_apply_cset_none_err, f_apply_cset_1251_log, f_apply_cset_1251_err ) ]
|
||||
# f_list += [ f_checksql, ]
|
||||
# cleanup( f_list )
|
||||
# time.sleep(1)
|
||||
# cleanup( (f_apply_cset_none_log, f_apply_cset_none_err, f_apply_cset_1251_log, f_apply_cset_1251_err, f_checksql) )
|
||||
#
|
||||
#
|
||||
#---
|
||||
@ -165,7 +188,6 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_5389_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -28,6 +28,9 @@
|
||||
# FB40CS, build 4.0.0.690: OK, 3.891s.
|
||||
# FB40SC, build 4.0.0.690: OK, 2.750s.
|
||||
# FB40SS, build 4.0.0.690: OK, 2.828s.
|
||||
# 13.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-5579
|
||||
# min_versions: ['2.5.8']
|
||||
@ -57,9 +60,42 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
#
|
||||
# db_conn.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# zf = zipfile.ZipFile( os.path.join(context['files_location'],'core_5579_broken_nn.zip') )
|
||||
#
|
||||
# # Name of .fbk inside .zip:
|
||||
@ -71,28 +107,12 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# tmpfbk=''.join( ( context['temp_directory'], zipfbk ) )
|
||||
# tmpfdb=''.join( ( context['temp_directory'], 'core_5579_broken_nn.fdb') )
|
||||
#
|
||||
# # C:\\MIX
|
||||
# irebird\\QA
|
||||
# bt-repo mp\\core_5579_broken_nn.fbk
|
||||
# # C:\\MIX
|
||||
# irebird\\QA
|
||||
# bt-repo mp\\core_5579_broken_nn.fdb
|
||||
#
|
||||
# f_restore_log=open( os.path.join(context['temp_directory'],'tmp_restore_5579.log'), 'w')
|
||||
# f_restore_err=open( os.path.join(context['temp_directory'],'tmp_restore_5579.err'), 'w')
|
||||
#
|
||||
# if os.path.isfile(tmpfdb):
|
||||
# os.remove(tmpfdb)
|
||||
# cleanup( (tmpfdb,) )
|
||||
#
|
||||
# # C:\\MIX
|
||||
# irebird
|
||||
# b25Csin\\gbak -rep C:\\MIX
|
||||
# irebird\\QA
|
||||
# bt-repo mp\\c5579.fbk\\core_5579_broken_nn.fbk -v -o /:C:\\MIX
|
||||
# irebird\\QA
|
||||
# bt-repo mp\\c5579.fbk\\CORE_5579_BROKEN_NN.FDB
|
||||
#
|
||||
# subprocess.call([ "fbsvcmgr",
|
||||
# subprocess.call([ context['fbsvcmgr_path'],
|
||||
# "localhost:service_mgr",
|
||||
# "action_restore",
|
||||
# "bkp_file", tmpfbk,
|
||||
@ -105,8 +125,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# # before this ticket was fixed restore log did contain following line:
|
||||
# # gbak: ERROR:request synchronization error
|
||||
#
|
||||
# f_restore_log.close()
|
||||
# f_restore_err.close()
|
||||
# flush_and_close( f_restore_log )
|
||||
# flush_and_close( f_restore_err )
|
||||
#
|
||||
# # Check:
|
||||
# ########
|
||||
@ -131,14 +151,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# # do NOT remove this pause otherwise some of logs will not be enable for deletion and test will finish with
|
||||
# # Exception raised while executing Python test script. exception: WindowsError: 32
|
||||
# time.sleep(1)
|
||||
#
|
||||
# f_list=(f_restore_log, f_restore_err)
|
||||
# for i in range(len(f_list)):
|
||||
# if os.path.isfile(f_list[i].name):
|
||||
# os.remove(f_list[i].name)
|
||||
# os.remove(tmpfdb)
|
||||
# os.remove(tmpfbk)
|
||||
#
|
||||
# cleanup( (f_restore_log, f_restore_err, tmpfdb, tmpfbk) )
|
||||
#
|
||||
#
|
||||
#---
|
||||
@ -146,7 +159,6 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
|
||||
|
||||
@pytest.mark.version('>=2.5.8')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_5579_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -10,14 +10,6 @@
|
||||
# This file was preliminary stored in FF Test machine.
|
||||
# Test assumes that this file and all neccessary libraries already were stored into FB_HOME and %FB_HOME%\\plugins.
|
||||
#
|
||||
# Anyone who wants to run this test on his own machine must
|
||||
# 1) download https://ib-aid.com/download/crypt/CryptTest.zip AND
|
||||
# 2) PURCHASE LICENSE and get from IBSurgeon file plugins\\dbcrypt.conf with apropriate expiration date and other info.
|
||||
#
|
||||
# ################################################ ! ! ! N O T E ! ! ! ##############################################
|
||||
# FF tests storage (aka "fbt-repo") does not (and will not) contain any license file for IBSurgeon Demo Encryption package!
|
||||
# #########################################################################################################################
|
||||
#
|
||||
# We create table with UNIQUE constraint, add some data to it and try to encrypt database using 'alter database encrypt with <plugin_name> ...'
|
||||
# command (where <plugin_name> = dbcrypt - name of .dll in FB_HOME\\plugins\\ folder that implements encryption).
|
||||
# Then we allow engine to complete this job - take delay about 1..2 seconds BEFORE detach from database.
|
||||
@ -32,27 +24,9 @@
|
||||
# 4.0.0.1524: OK, 4.056s ; 4.0.0.1421: OK, 6.160s.
|
||||
# 3.0.5.33139: OK, 2.895s ; 3.0.5.33118: OK, 2.837s.
|
||||
#
|
||||
# === NOTE-1 ===
|
||||
# In case of "Crypt plugin DBCRYPT failed to load/607/335544351" check that all
|
||||
# needed files from IBSurgeon Demo Encryption package exist in %FB_HOME% and %FB_HOME%\\plugins
|
||||
# %FB_HOME%:
|
||||
# 283136 fbcrypt.dll
|
||||
# 2905600 libcrypto-1_1-x64.dll
|
||||
# 481792 libssl-1_1-x64.dll
|
||||
#
|
||||
# %FB_HOME%\\plugins:
|
||||
# 297984 dbcrypt.dll
|
||||
# 306176 keyholder.dll
|
||||
# 108 DbCrypt.conf
|
||||
# 856 keyholder.conf
|
||||
#
|
||||
# === NOTE-2 ===
|
||||
# Version of DbCrypt.dll of october-2018 must be replaced because it has hard-coded
|
||||
# date of expiration rather than reading it from DbCrypt.conf !!
|
||||
#
|
||||
# === NOTE-3 ===
|
||||
# firebird.conf must contain following line:
|
||||
# KeyHolderPlugin = KeyHolder
|
||||
# 15.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
#
|
||||
# tracker_id: CORE-5673
|
||||
@ -83,18 +57,18 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
#
|
||||
# engine = db_conn.engine_version
|
||||
# db_conn.close()
|
||||
#
|
||||
# #---------- aux func for cleanup: ---------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if os.path.isfile( f_names_list[i]):
|
||||
# os.remove( f_names_list[i] )
|
||||
#
|
||||
# #------------------------------------------
|
||||
# # 14.04.2021.
|
||||
# # Name of encryption plugin depends on OS:
|
||||
# # * for Windows we (currently) use plugin by IBSurgeon, its name is 'dbcrypt';
|
||||
# # * for Linux we use:
|
||||
# # ** 'DbCrypt_example' for FB 3.x
|
||||
# # ** 'fbSampleDbCrypt' for FB 4.x+
|
||||
# #
|
||||
# PLUGIN_NAME = 'dbcrypt' if os.name == 'nt' else ( '"fbSampleDbCrypt"' if engine >= 4.0 else '"DbCrypt_example"')
|
||||
# KHOLDER_NAME = 'KeyHolder' if os.name == 'nt' else "fbSampleKeyHolder"
|
||||
#
|
||||
#
|
||||
# con = fdb.connect( dsn = dsn )
|
||||
@ -105,7 +79,15 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# cur.execute( 'insert into test(x) select row_number()over() from rdb$types rows 10' )
|
||||
# con.commit()
|
||||
#
|
||||
# cur.execute('alter database encrypt with dbcrypt key Red')
|
||||
# ##############################################
|
||||
# # WARNING! Do NOT use 'connection_obj.execute_immediate()' for ALTER DATABASE ENCRYPT... command!
|
||||
# # There is bug in FB driver which leads this command to fail with 'token unknown' message
|
||||
# # The reason is that execute_immediate() silently set client dialect = 0 and any encryption statement
|
||||
# # can not be used for such value of client dialect.
|
||||
# # One need to to use only cursor_obj.execute() for encryption!
|
||||
# # See letter from Pavel Cisar, 20.01.20 10:36
|
||||
# ##############################################
|
||||
# cur.execute('alter database encrypt with %(PLUGIN_NAME)s key Red' % locals())
|
||||
# con.commit()
|
||||
#
|
||||
# time.sleep(2)
|
||||
@ -149,7 +131,6 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0.3')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_5673_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -10,15 +10,7 @@
|
||||
# This file was preliminary stored in FF Test machine.
|
||||
# Test assumes that this file and all neccessary libraries already were stored into FB_HOME and %FB_HOME%\\plugins.
|
||||
#
|
||||
# Anyone who wants to run this test on his own machine must
|
||||
# 1) download https://ib-aid.com/download/crypt/CryptTest.zip AND
|
||||
# 2) PURCHASE LICENSE and get from IBSurgeon file plugins\\dbcrypt.conf with apropriate expiration date and other info.
|
||||
#
|
||||
# ################################################ ! ! ! N O T E ! ! ! ##############################################
|
||||
# FF tests storage (aka "fbt-repo") does not (and will not) contain any license file for IBSurgeon Demo Encryption package!
|
||||
# #########################################################################################################################
|
||||
#
|
||||
# Firstly we try to encrypt DB with existing key and decrypt it aftee this - just to ensure that this mechanism works fine.
|
||||
# First, we try to encrypt DB with existing key and decrypt it aftee this - just to ensure that this mechanism works fine.
|
||||
# Then we use statement 'alter database encrypt ...' with NON existing key and check parts of exception that will raise.
|
||||
# From these three parts (multi-string, int and bigint numbers) we check that 1st contains phrase about missed crypt key.
|
||||
# ::: NOTE ::::
|
||||
@ -27,7 +19,7 @@
|
||||
# 4.0.0: - Missing database encryption key for your attachment
|
||||
# - so we use regexp tool for check pattern matching.
|
||||
# Because of different text related to missing plugin, this part is replaced with phrase:
|
||||
# <MESSAGE ABOUT MISSED ENCRYPTION KEY HERE> -- both for 3.0.x and 4.0.x.
|
||||
# <FOUND PATTERN-1 ABOUT MISSED ENCRYPTION KEY> -- both for 3.0.x and 4.0.x.
|
||||
#
|
||||
# Confirmed difference in error message (text decription, w/o sqlcode and gdscode):
|
||||
# 1) 3.0.3.32900
|
||||
@ -49,28 +41,9 @@
|
||||
# 4.0.0.1524: OK, 4.674s.
|
||||
# 3.0.5.33139: OK, 3.666s.
|
||||
#
|
||||
# === NOTE-1 ===
|
||||
# In case of "Crypt plugin DBCRYPT failed to load/607/335544351" check that all
|
||||
# needed files from IBSurgeon Demo Encryption package exist in %FB_HOME% and %FB_HOME%\\plugins
|
||||
# %FB_HOME%:
|
||||
# 283136 fbcrypt.dll
|
||||
# 2905600 libcrypto-1_1-x64.dll
|
||||
# 481792 libssl-1_1-x64.dll
|
||||
#
|
||||
# %FB_HOME%\\plugins:
|
||||
# 297984 dbcrypt.dll
|
||||
# 306176 keyholder.dll
|
||||
# 108 DbCrypt.conf
|
||||
# 856 keyholder.conf
|
||||
#
|
||||
# === NOTE-2 ===
|
||||
# Version of DbCrypt.dll of october-2018 must be replaced because it has hard-coded
|
||||
# date of expiration rather than reading it from DbCrypt.conf !!
|
||||
#
|
||||
# === NOTE-3 ===
|
||||
# firebird.conf must contain following line:
|
||||
# KeyHolderPlugin = KeyHolder
|
||||
#
|
||||
# 15.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-5793
|
||||
# min_versions: ['3.0.4']
|
||||
@ -96,60 +69,86 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# import re
|
||||
# import time
|
||||
#
|
||||
# # Messages differ:
|
||||
# # 3.0.5: - Missing correct crypt key
|
||||
# # 4.0.0: - Missing database encryption key for your attachment
|
||||
# # --> we can use regexp to parse exception text and try to find some common words for these messages:
|
||||
# missed_key_ptn=re.compile('.*missing\\s+.*(crypt key|encryption key).*', re.IGNORECASE)
|
||||
# engine = db_conn.engine_version
|
||||
#
|
||||
#
|
||||
# # 14.04.2021.
|
||||
# # Name of encryption plugin depends on OS:
|
||||
# # * for Windows we (currently) use plugin by IBSurgeon, its name is 'dbcrypt';
|
||||
# # * for Linux we use:
|
||||
# # ** 'DbCrypt_example' for FB 3.x
|
||||
# # ** 'fbSampleDbCrypt' for FB 4.x+
|
||||
# #
|
||||
# PLUGIN_NAME = 'dbcrypt' if os.name == 'nt' else ( '"fbSampleDbCrypt"' if engine >= 4.0 else '"DbCrypt_example"')
|
||||
#
|
||||
# cur = db_conn.cursor()
|
||||
#
|
||||
# print('1.1. Trying to encrypt with existing key.')
|
||||
# db_conn.execute_immediate('alter database encrypt with dbcrypt key red')
|
||||
#
|
||||
# ##############################################
|
||||
# # WARNING! Do NOT use 'connection_obj.execute_immediate()' for ALTER DATABASE ENCRYPT... command!
|
||||
# # There is bug in FB driver which leads this command to fail with 'token unknown' message
|
||||
# # The reason is that execute_immediate() silently set client dialect = 0 and any encryption statement
|
||||
# # can not be used for such value of client dialect.
|
||||
# # One need to to use only cursor_obj.execute() for encryption!
|
||||
# # See letter from Pavel Cisar, 20.01.20 10:36
|
||||
# ##############################################
|
||||
# cur.execute('alter database encrypt with %(PLUGIN_NAME)s key Red' % locals())
|
||||
#
|
||||
# db_conn.commit()
|
||||
# time.sleep(1)
|
||||
#
|
||||
# time.sleep(2)
|
||||
#
|
||||
# print('1.2. Delay completed, DB now must be encrypted.')
|
||||
#
|
||||
# print('2.1. Trying to decrypt.')
|
||||
# db_conn.execute_immediate('alter database decrypt')
|
||||
# cur.execute('alter database decrypt')
|
||||
# db_conn.commit()
|
||||
# time.sleep(2)
|
||||
# print('2.2. Delay completed, DB now must be decrypted.')
|
||||
#
|
||||
# print('3.1. Trying to encrypt with non-existing key')
|
||||
# try:
|
||||
# db_conn.execute_immediate('alter database encrypt with dbcrypt key foo')
|
||||
# cur.execute('alter database encrypt with %(PLUGIN_NAME)s key no_such_key_foo' % locals())
|
||||
# db_conn.commit()
|
||||
# time.sleep(1)
|
||||
# print('3.2 ??? ERROR ??? Encrypted with key "foo" ?!')
|
||||
# print('3.2 ### ERROR ### Encrypted with non-existing key ?')
|
||||
# except Exception as e:
|
||||
# # Messages about incorrect key differ depending of FB major version:
|
||||
# # 3.0.5: - Missing correct crypt key
|
||||
# # 4.0.0: - Missing database encryption key for your attachment
|
||||
# # --> we can use regexp to parse exception text and try to find some common words for these messages:
|
||||
# # Messages about missing this key in the keyholder differ depending on OS:
|
||||
# # Windows:
|
||||
# # - Plugin KeyHolder:
|
||||
# # Unknown key name NO_SUCH_KEY_FOO - key can't be found in KeyHolder.conf
|
||||
# # Linux:
|
||||
# # - Plugin CryptKeyHolder_example:
|
||||
# # Crypt key NO_SUCH_KEY_FOO not set
|
||||
#
|
||||
# missed_key_ptn1 = re.compile('.*missing\\s+.*(crypt key|encryption key).*', re.IGNORECASE)
|
||||
# missed_key_ptn2 = ''
|
||||
# if os.name == 'nt':
|
||||
# missed_key_ptn2 = re.compile(".*Unknown\\s+key\\s+name.*key\\s+can't\\s+be\\s+found.*", re.IGNORECASE)
|
||||
# else:
|
||||
# missed_key_ptn2 = re.compile(".*Crypt\\s+key\\s+.*\\s+not\\s+set", re.IGNORECASE)
|
||||
#
|
||||
# for x in e.args:
|
||||
# if isinstance( x, str):
|
||||
# for r in x.split('\\n'):
|
||||
# if missed_key_ptn.search( r ):
|
||||
# print('<MESSAGE ABOUT MISSED ENCRYPTION KEY HERE>')
|
||||
# if missed_key_ptn1.search( r ):
|
||||
# print('<FOUND PATTERN-1 ABOUT MISSED ENCRYPTION KEY>')
|
||||
# elif missed_key_ptn2.search( r ):
|
||||
# print('<FOUND PATTERN-2 ABOUT MISSED ENCRYPTION KEY>')
|
||||
# elif r.strip().lower().startswith('- plugin'):
|
||||
# pass
|
||||
# else:
|
||||
# print( r )
|
||||
# else:
|
||||
# print(x)
|
||||
#
|
||||
# finally:
|
||||
# cur.close()
|
||||
# db_conn.close()
|
||||
# '''
|
||||
# 1.1. Trying to encrypt with existing key.
|
||||
# 1.2. Delay completed, DB now must be encrypted.
|
||||
# 2.1. Trying to decrypt.
|
||||
# 2.2. Delay completed, DB now must be decrypted.
|
||||
# 3.1. Trying to encrypt with non-existing key
|
||||
# Error while executing SQL statement:
|
||||
# - SQLCODE: -607
|
||||
# - unsuccessful metadata update
|
||||
# - ALTER DATABASE failed
|
||||
# - Missing correct crypt key
|
||||
# - Plugin KeyHolder:
|
||||
# - Unknown key name FOO - key can't be found in KeyHolder.conf
|
||||
# -607
|
||||
# 335544351
|
||||
#
|
||||
# '''
|
||||
#
|
||||
#---
|
||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
@ -164,15 +163,13 @@ expected_stdout_1 = """
|
||||
- SQLCODE: -607
|
||||
- unsuccessful metadata update
|
||||
- ALTER DATABASE failed
|
||||
<MESSAGE ABOUT MISSED ENCRYPTION KEY HERE>
|
||||
- Plugin KeyHolder:
|
||||
- Unknown key name FOO - key can't be found in KeyHolder.conf
|
||||
<FOUND PATTERN-1 ABOUT MISSED ENCRYPTION KEY>
|
||||
<FOUND PATTERN-2 ABOUT MISSED ENCRYPTION KEY>
|
||||
-607
|
||||
335544351
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0.4')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_5793_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -9,14 +9,6 @@
|
||||
# This file was preliminary stored in FF Test machine.
|
||||
# Test assumes that this file and all neccessary libraries already were stored into FB_HOME and %FB_HOME%\\plugins.
|
||||
#
|
||||
# Anyone who wants to run this test on his own machine must
|
||||
# 1) download https://ib-aid.com/download/crypt/CryptTest.zip AND
|
||||
# 2) PURCHASE LICENSE and get from IBSurgeon file plugins\\dbcrypt.conf with apropriate expiration date and other info.
|
||||
#
|
||||
# ################################################ ! ! ! N O T E ! ! ! ##############################################
|
||||
# FF tests storage (aka "fbt-repo") does not (and will not) contain any license file for IBSurgeon Demo Encryption package!
|
||||
# #########################################################################################################################
|
||||
#
|
||||
# After test database will be created, we try to encrypt it using 'alter database encrypt with <plugin_name> ...' command
|
||||
# (where <plugin_name> = dbcrypt - name of .dll in FB_HOME\\plugins\\ folder that implements encryption).
|
||||
# Then we allow engine to complete this job - take delay about 1..2 seconds BEFORE detach from database.
|
||||
@ -33,28 +25,9 @@
|
||||
#
|
||||
# Finally, we change this temp DB statee to full shutdown in order to have 100% ability to drop this file.
|
||||
#
|
||||
# === NOTE-1 ===
|
||||
# In case of "Crypt plugin DBCRYPT failed to load/607/335544351" check that all
|
||||
# needed files from IBSurgeon Demo Encryption package exist in %FB_HOME% and %FB_HOME%\\plugins
|
||||
# %FB_HOME%:
|
||||
# 283136 fbcrypt.dll
|
||||
# 2905600 libcrypto-1_1-x64.dll
|
||||
# 481792 libssl-1_1-x64.dll
|
||||
#
|
||||
# %FB_HOME%\\plugins:
|
||||
# 297984 dbcrypt.dll
|
||||
# 306176 keyholder.dll
|
||||
# 108 DbCrypt.conf
|
||||
# 856 keyholder.conf
|
||||
#
|
||||
# === NOTE-2 ===
|
||||
# Version of DbCrypt.dll of october-2018 must be replaced because it has hard-coded
|
||||
# date of expiration rather than reading it from DbCrypt.conf !!
|
||||
#
|
||||
# === NOTE-3 ===
|
||||
# firebird.conf must contain following line:
|
||||
# KeyHolderPlugin = KeyHolder
|
||||
#
|
||||
# 15.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-5796
|
||||
# min_versions: ['3.0.4']
|
||||
@ -84,18 +57,70 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
# engine = db_conn.engine_version
|
||||
# db_conn.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
#
|
||||
# tmpfdb='$(DATABASE_LOCATION)'+'tmp_core_5796.fdb'
|
||||
#
|
||||
# if os.path.isfile( tmpfdb ):
|
||||
# os.remove( tmpfdb )
|
||||
# cleanup( (tmpfdb,) )
|
||||
#
|
||||
# con = fdb.create_database( dsn = 'localhost:'+tmpfdb )
|
||||
# con.close()
|
||||
# con=fdb.connect( dsn = 'localhost:'+tmpfdb )
|
||||
# cur = con.cursor()
|
||||
# cur.execute('alter database encrypt with dbcrypt key Red')
|
||||
#
|
||||
# # 14.04.2021.
|
||||
# # Name of encryption plugin depends on OS:
|
||||
# # * for Windows we (currently) use plugin by IBSurgeon, its name is 'dbcrypt';
|
||||
# # * for Linux we use:
|
||||
# # ** 'DbCrypt_example' for FB 3.x
|
||||
# # ** 'fbSampleDbCrypt' for FB 4.x+
|
||||
# #
|
||||
# PLUGIN_NAME = 'dbcrypt' if os.name == 'nt' else ( '"fbSampleDbCrypt"' if engine >= 4.0 else '"DbCrypt_example"')
|
||||
#
|
||||
# ##############################################
|
||||
# # WARNING! Do NOT use 'connection_obj.execute_immediate()' for ALTER DATABASE ENCRYPT... command!
|
||||
# # There is bug in FB driver which leads this command to fail with 'token unknown' message
|
||||
# # The reason is that execute_immediate() silently set client dialect = 0 and any encryption statement
|
||||
# # can not be used for such value of client dialect.
|
||||
# # One need to to use only cursor_obj.execute() for encryption!
|
||||
# # See letter from Pavel Cisar, 20.01.20 10:36
|
||||
# ##############################################
|
||||
#
|
||||
# cur.execute('alter database encrypt with %(PLUGIN_NAME)s key Red' % locals())
|
||||
# con.commit()
|
||||
# time.sleep(2)
|
||||
# # ^
|
||||
@ -108,23 +133,23 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# f_gstat_log = open( os.path.join(context['temp_directory'],'tmp_dbstat_5796.log'), 'w')
|
||||
# f_gstat_err = open( os.path.join(context['temp_directory'],'tmp_dbstat_5796.err'), 'w')
|
||||
#
|
||||
# subprocess.call( [ "gstat", "-e", "localhost:"+tmpfdb],
|
||||
# subprocess.call( [ context['gstat_path'], "-e", "localhost:"+tmpfdb],
|
||||
# stdout = f_gstat_log,
|
||||
# stderr = f_gstat_err
|
||||
# )
|
||||
#
|
||||
#
|
||||
# f_gstat_log.close()
|
||||
# f_gstat_err.close()
|
||||
# flush_and_close( f_gstat_log )
|
||||
# flush_and_close( f_gstat_err )
|
||||
#
|
||||
# #--------------------------------- shutdown temp DB --------------------
|
||||
#
|
||||
# f_dbshut_log = open( os.path.join(context['temp_directory'],'tmp_dbshut_5796.log'), 'w')
|
||||
# subprocess.call( [ "gfix", 'localhost:'+tmpfdb, "-shut", "full", "-force", "0" ],
|
||||
# subprocess.call( [ context['gfix_path'], 'localhost:'+tmpfdb, "-shut", "full", "-force", "0" ],
|
||||
# stdout = f_dbshut_log,
|
||||
# stderr = subprocess.STDOUT
|
||||
# )
|
||||
# f_dbshut_log.close()
|
||||
# flush_and_close( f_dbshut_log )
|
||||
#
|
||||
# allowed_patterns = (
|
||||
# re.compile( '\\s*Attributes\\.*', re.IGNORECASE)
|
||||
@ -143,13 +168,11 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# for line in f:
|
||||
# print("Unexpected STDERR: "+line)
|
||||
#
|
||||
# f_list=(f_gstat_log, f_gstat_err, f_dbshut_log)
|
||||
# for i in range(len(f_list)):
|
||||
# if os.path.isfile(f_list[i].name):
|
||||
# os.remove(f_list[i].name)
|
||||
# # cleanup:
|
||||
# ##########
|
||||
# time.sleep(1)
|
||||
# cleanup( (f_gstat_log, f_gstat_err, f_dbshut_log, tmpfdb) )
|
||||
#
|
||||
# if os.path.isfile( tmpfdb ):
|
||||
# os.remove( tmpfdb )
|
||||
#
|
||||
#
|
||||
#---
|
||||
@ -163,7 +186,6 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0.4')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_5796_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -10,14 +10,6 @@
|
||||
# This file was preliminary stored in FF Test machine.
|
||||
# Test assumes that this file and all neccessary libraries already were stored into FB_HOME and %FB_HOME%\\plugins.
|
||||
#
|
||||
# Anyone who wants to run this test on his own machine must
|
||||
# 1) download https://ib-aid.com/download/crypt/CryptTest.zip AND
|
||||
# 2) PURCHASE LICENSE and get from IBSurgeon file plugins\\dbcrypt.conf with apropriate expiration date and other info.
|
||||
#
|
||||
# ################################################ ! ! ! N O T E ! ! ! ##############################################
|
||||
# FF tests storage (aka "fbt-repo") does not (and will not) contain any license file for IBSurgeon Demo Encryption package!
|
||||
# #########################################################################################################################
|
||||
#
|
||||
# After test database will be created, we try to encrypt it using 'alter database encrypt with <plugin_name> ...' command
|
||||
# (where <plugin_name> = dbcrypt - name of .dll in FB_HOME\\plugins\\ folder that implements encryption).
|
||||
# Then we allow engine to complete this job - take delay about 1..2 seconds BEFORE detach from database.
|
||||
@ -31,6 +23,10 @@
|
||||
# 40sS, build 4.0.0.1487: OK, 6.552s.
|
||||
# 40sC, build 4.0.0.1421: OK, 11.812s.
|
||||
# 40Cs, build 4.0.0.1485: OK, 8.097s.
|
||||
#
|
||||
# 15.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-5808
|
||||
# min_versions: ['4.0']
|
||||
@ -63,11 +59,13 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
# db_conn.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def svc_get_fb_log( f_fb_log ):
|
||||
#
|
||||
# import subprocess
|
||||
# global subprocess
|
||||
#
|
||||
# subprocess.call( [ "fbsvcmgr",
|
||||
# subprocess.call( [ context['fbsvcmgr_path'],
|
||||
# "localhost:service_mgr",
|
||||
# "action_get_fb_log"
|
||||
# ],
|
||||
@ -75,11 +73,39 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# )
|
||||
# return
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if os.path.isfile( f_names_list[i]):
|
||||
# os.remove( f_names_list[i] )
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# tmpfdb='$(DATABASE_LOCATION)'+'tmp_core_5808.fdb'
|
||||
# tmpfbk='$(DATABASE_LOCATION)'+'tmp_core_5808.fbk'
|
||||
@ -88,14 +114,31 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# cleanup( f_list )
|
||||
#
|
||||
#
|
||||
# # 14.04.2021.
|
||||
# # Name of encryption plugin depends on OS:
|
||||
# # * for Windows we (currently) use plugin by IBSurgeon, its name is 'dbcrypt';
|
||||
# # * for Linux we use:
|
||||
# # ** 'DbCrypt_example' for FB 3.x
|
||||
# # ** 'fbSampleDbCrypt' for FB 4.x+
|
||||
# #
|
||||
# PLUGIN_NAME = 'dbcrypt' if os.name == 'nt' else '"fbSampleDbCrypt"'
|
||||
#
|
||||
# con = fdb.create_database( dsn = 'localhost:'+tmpfdb )
|
||||
# con.close()
|
||||
# con=fdb.connect( dsn = 'localhost:'+tmpfdb )
|
||||
# cur = con.cursor()
|
||||
# cur.execute('alter database encrypt with dbcrypt key Red')
|
||||
#
|
||||
# ##############################################
|
||||
# # WARNING! Do NOT use 'connection_obj.execute_immediate()' for ALTER DATABASE ENCRYPT... command!
|
||||
# # There is bug in FB driver which leads this command to fail with 'token unknown' message
|
||||
# # The reason is that execute_immediate() silently set client dialect = 0 and any encryption statement
|
||||
# # can not be used for such value of client dialect.
|
||||
# # One need to to use only cursor_obj.execute() for encryption!
|
||||
# # See letter from Pavel Cisar, 20.01.20 10:36
|
||||
# ##############################################
|
||||
# cur.execute('alter database encrypt with %(PLUGIN_NAME)s key Red' % locals())
|
||||
#
|
||||
# con.commit()
|
||||
#
|
||||
# time.sleep(1)
|
||||
# time.sleep(2)
|
||||
# # ^
|
||||
# # +-------- !! ALLOW BACKGROUND ENCRYPTION PROCESS TO COMPLETE ITS JOB !!
|
||||
#
|
||||
@ -104,43 +147,42 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# f_backup_log = open( os.path.join(context['temp_directory'],'tmp_backup_5808.log'), 'w')
|
||||
# f_backup_err = open( os.path.join(context['temp_directory'],'tmp_backup_5808.err'), 'w')
|
||||
#
|
||||
# subprocess.call( [ "gbak", "-v", "-b", 'localhost:' + tmpfdb, tmpfbk],
|
||||
# subprocess.call( [ context['gbak_path'], "-v", "-b", 'localhost:' + tmpfdb, tmpfbk],
|
||||
# stdout = f_backup_log,
|
||||
# stderr = f_backup_err
|
||||
# )
|
||||
# f_backup_log.close()
|
||||
# f_backup_err.close()
|
||||
# flush_and_close( f_backup_log )
|
||||
# flush_and_close( f_backup_err )
|
||||
#
|
||||
#
|
||||
# f_restore_log = open( os.path.join(context['temp_directory'],'tmp_restore_5808.log'), 'w')
|
||||
# f_restore_err = open( os.path.join(context['temp_directory'],'tmp_restore_5808.err'), 'w')
|
||||
#
|
||||
# subprocess.call( [ "gbak", "-v", "-rep", tmpfbk, 'localhost:'+tmpfdb],
|
||||
# subprocess.call( [ context['gbak_path'], "-v", "-rep", tmpfbk, 'localhost:'+tmpfdb],
|
||||
# stdout = f_restore_log,
|
||||
# stderr = f_restore_err
|
||||
# )
|
||||
# f_restore_log.close()
|
||||
# f_restore_err.close()
|
||||
# flush_and_close( f_restore_log )
|
||||
# flush_and_close( f_restore_err )
|
||||
#
|
||||
# f_fblog_before=open( os.path.join(context['temp_directory'],'tmp_5808_fblog_before.txt'), 'w')
|
||||
# svc_get_fb_log( f_fblog_before )
|
||||
# f_fblog_before.close()
|
||||
# flush_and_close( f_fblog_before )
|
||||
#
|
||||
#
|
||||
# f_validate_log = open( os.path.join(context['temp_directory'],'tmp_validate_5808.log'), 'w')
|
||||
# f_validate_err = open( os.path.join(context['temp_directory'],'tmp_validate_5808.err'), 'w')
|
||||
#
|
||||
# subprocess.call( [ "gfix", "-v", "-full", tmpfdb ],
|
||||
# subprocess.call( [ context['gfix_path'], "-v", "-full", tmpfdb ],
|
||||
# stdout = f_validate_log,
|
||||
# stderr = f_validate_err
|
||||
# )
|
||||
# f_validate_log.close()
|
||||
# f_validate_err.close()
|
||||
# flush_and_close( f_validate_log )
|
||||
# flush_and_close( f_validate_err )
|
||||
#
|
||||
# f_fblog_after=open( os.path.join(context['temp_directory'],'tmp_5808_fblog_after.txt'), 'w')
|
||||
# svc_get_fb_log( f_fblog_after )
|
||||
# f_fblog_after.close()
|
||||
# time.sleep(1)
|
||||
# flush_and_close( f_fblog_after )
|
||||
#
|
||||
#
|
||||
# # Compare firebird.log versions BEFORE and AFTER this test:
|
||||
@ -168,7 +210,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# f_diff_txt=open( os.path.join(context['temp_directory'],'tmp_5808_diff.txt'), 'w')
|
||||
# f_diff_txt.write(difftext)
|
||||
# f_diff_txt.close()
|
||||
# flush_and_close( f_diff_txt )
|
||||
#
|
||||
# allowed_patterns = (
|
||||
# re.compile( '\\+\\s+Validation\\s+started', re.IGNORECASE)
|
||||
@ -182,18 +224,12 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# if match2some:
|
||||
# print( (' '.join( line.split()).upper() ) )
|
||||
#
|
||||
# # CLEANUP:
|
||||
# ##########
|
||||
# # do NOT remove this pause otherwise some of logs will not be enable for deletion and test will finish with
|
||||
# # Exception raised while executing Python test script. exception: WindowsError: 32
|
||||
# time.sleep(1)
|
||||
#
|
||||
# # +=+=+=+=+=+=+=+=+=+=+
|
||||
# # +=+=+= CLEANUP +=+=+=
|
||||
# # +=+=+=+=+=+=+=+=+=+=+
|
||||
#
|
||||
# f_list = [ i.name for i in ( f_backup_log, f_backup_err, f_restore_log, f_restore_err, f_validate_log, f_validate_err, f_fblog_before, f_fblog_after, f_diff_txt ) ]
|
||||
# f_list += [ tmpfdb, tmpfbk ]
|
||||
# cleanup( f_list )
|
||||
#
|
||||
# cleanup( (f_backup_log, f_backup_err, f_restore_log, f_restore_err, f_validate_log, f_validate_err, f_fblog_before, f_fblog_after, f_diff_txt, tmpfdb, tmpfbk) )
|
||||
#
|
||||
#
|
||||
#---
|
||||
@ -205,7 +241,6 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_5808_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -9,14 +9,6 @@
|
||||
# This file was preliminary stored in FF Test machine.
|
||||
# Test assumes that this file and all neccessary libraries already were stored into FB_HOME and %FB_HOME%\\plugins.
|
||||
#
|
||||
# Anyone who wants to run this test on his own machine must
|
||||
# 1) download https://ib-aid.com/download/crypt/CryptTest.zip AND
|
||||
# 2) PURCHASE LICENSE and get from IBSurgeon file plugins\\dbcrypt.conf with apropriate expiration date and other info.
|
||||
#
|
||||
# ################################################ ! ! ! N O T E ! ! ! ##############################################
|
||||
# FF tests storage (aka "fbt-repo") does not (and will not) contain any license file for IBSurgeon Demo Encryption package!
|
||||
# #########################################################################################################################
|
||||
#
|
||||
# After test database will be created, we try to encrypt it using 'alter database encrypt with <plugin_name> ...' command
|
||||
# (where <plugin_name> = dbcrypt - name of .dll in FB_HOME\\plugins\\ folder that implements encryption).
|
||||
# Then we allow engine to complete this job - take delay about 1..2 seconds BEFORE detach from database.
|
||||
@ -39,24 +31,9 @@
|
||||
# 30sS, build 3.0.5.33120: OK, 2.697s.
|
||||
# 30Cs, build 3.0.5.33120: OK, 3.054s.
|
||||
#
|
||||
# === NOTE-1 ===
|
||||
# In case of "Crypt plugin DBCRYPT failed to load/607/335544351" check that all
|
||||
# needed files from IBSurgeon Demo Encryption package exist in %FB_HOME% and %FB_HOME%\\plugins
|
||||
# %FB_HOME%:
|
||||
# 283136 fbcrypt.dll
|
||||
# 2905600 libcrypto-1_1-x64.dll
|
||||
# 481792 libssl-1_1-x64.dll
|
||||
#
|
||||
# %FB_HOME%\\plugins:
|
||||
# 297984 dbcrypt.dll
|
||||
# 306176 keyholder.dll
|
||||
# 108 DbCrypt.conf
|
||||
# 856 keyholder.conf
|
||||
#
|
||||
# === NOTE-2 ===
|
||||
# Version of DbCrypt.dll of october-2018 must be replaced because it has hard-coded
|
||||
# date of expiration rather than reading it from DbCrypt.conf !!
|
||||
#
|
||||
# 15.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-5831
|
||||
# min_versions: ['3.0.4']
|
||||
@ -69,7 +46,7 @@ from firebird.qa import db_factory, isql_act, Action
|
||||
# version: 3.0.4
|
||||
# resources: None
|
||||
|
||||
substitutions_1 = [('CRYPT CHECKSUM.*', 'CRYPT CHECKSUM'), ('KEY HASH.*', 'KEY HASH')]
|
||||
substitutions_1 = [('ATTRIBUTES FORCE WRITE, ENCRYPTED, PLUGIN.*', 'ATTRIBUTES FORCE WRITE, ENCRYPTED'), ('CRYPT CHECKSUM.*', 'CRYPT CHECKSUM'), ('KEY HASH.*', 'KEY HASH')]
|
||||
|
||||
init_script_1 = """"""
|
||||
|
||||
@ -86,41 +63,94 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
# engine = db_conn.engine_version
|
||||
# db_conn.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
#
|
||||
# tmpfdb='$(DATABASE_LOCATION)'+'tmp_core_5831.fdb'
|
||||
#
|
||||
# if os.path.isfile( tmpfdb ):
|
||||
# os.remove( tmpfdb )
|
||||
# cleanup( (tmpfdb,) )
|
||||
#
|
||||
# con = fdb.create_database( dsn = 'localhost:'+tmpfdb )
|
||||
# con.close()
|
||||
# con=fdb.connect( dsn = 'localhost:'+tmpfdb )
|
||||
# cur = con.cursor()
|
||||
# cur.execute('alter database encrypt with dbcrypt key Red')
|
||||
#
|
||||
# # 14.04.2021.
|
||||
# # Name of encryption plugin depends on OS:
|
||||
# # * for Windows we (currently) use plugin by IBSurgeon, its name is 'dbcrypt';
|
||||
# # * for Linux we use:
|
||||
# # ** 'DbCrypt_example' for FB 3.x
|
||||
# # ** 'fbSampleDbCrypt' for FB 4.x+
|
||||
# #
|
||||
# PLUGIN_NAME = 'dbcrypt' if os.name == 'nt' else ( '"fbSampleDbCrypt"' if engine >= 4.0 else '"DbCrypt_example"')
|
||||
#
|
||||
# ##############################################
|
||||
# # WARNING! Do NOT use 'connection_obj.execute_immediate()' for ALTER DATABASE ENCRYPT... command!
|
||||
# # There is bug in FB driver which leads this command to fail with 'token unknown' message
|
||||
# # The reason is that execute_immediate() silently set client dialect = 0 and any encryption statement
|
||||
# # can not be used for such value of client dialect.
|
||||
# # One need to to use only cursor_obj.execute() for encryption!
|
||||
# # See letter from Pavel Cisar, 20.01.20 10:36
|
||||
# ##############################################
|
||||
# cur.execute('alter database encrypt with %(PLUGIN_NAME)s key Red' % locals())
|
||||
#
|
||||
# con.commit()
|
||||
#
|
||||
# time.sleep(1)
|
||||
# time.sleep(2)
|
||||
# # ^
|
||||
# # +-------- !! ALLOW BACKGROUND ENCRYPTION PROCESS TO COMPLETE ITS JOB !!
|
||||
# # DO NOT set this delay less than 2 seconds otherwise "crypt process" will be in the output!
|
||||
#
|
||||
# con.close()
|
||||
#
|
||||
# f_gstat_log = open( os.path.join(context['temp_directory'],'tmp_shut_5831.log'), 'w')
|
||||
# f_gstat_err = open( os.path.join(context['temp_directory'],'tmp_shut_5831.err'), 'w')
|
||||
#
|
||||
# subprocess.call( [ "gstat", "-h", tmpfdb],
|
||||
# subprocess.call( [ context['gstat_path'], "-h", tmpfdb],
|
||||
# stdout = f_gstat_log,
|
||||
# stderr = f_gstat_err
|
||||
# )
|
||||
#
|
||||
# subprocess.call( [ "gfix", 'localhost:'+tmpfdb, "-shut", "full", "-force", "0" ],
|
||||
# subprocess.call( [ context['gfix_path'], 'localhost:'+tmpfdb, "-shut", "full", "-force", "0" ],
|
||||
# stdout = f_gstat_log,
|
||||
# stderr = f_gstat_err
|
||||
# )
|
||||
#
|
||||
# f_gstat_log.close()
|
||||
# f_gstat_err.close()
|
||||
# flush_and_close( f_gstat_log )
|
||||
# flush_and_close( f_gstat_err )
|
||||
#
|
||||
# allowed_patterns = (
|
||||
# re.compile( '\\s*Attributes\\.*', re.IGNORECASE)
|
||||
@ -139,13 +169,10 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# for line in f:
|
||||
# print("Unexpected STDERR: "+line)
|
||||
#
|
||||
# f_list=(f_gstat_log, f_gstat_err)
|
||||
# for i in range(len(f_list)):
|
||||
# if os.path.isfile(f_list[i].name):
|
||||
# os.remove(f_list[i].name)
|
||||
#
|
||||
# if os.path.isfile( tmpfdb ):
|
||||
# os.remove( tmpfdb )
|
||||
# # cleanuo:
|
||||
# time.sleep(1)
|
||||
# cleanup( (f_gstat_log, f_gstat_err, tmpfdb) )
|
||||
#
|
||||
#
|
||||
#---
|
||||
@ -159,7 +186,6 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0.4')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_5831_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -1,8 +1,9 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_5936
|
||||
# title: Firebird crashes ...
|
||||
# title: Firebird crashes, related to Bugcheck 165 (cannot find tip page)
|
||||
# decription:
|
||||
# NB. Ticket title: "Firebird server segfaults in the end of database backup" - has nothing to the actual reason of segfault.
|
||||
# Confirmed crash on:
|
||||
# * 2.5.8.27089 SuperClassic
|
||||
# * 2.5.9.27117 Classic and SuperClassic (build date: 29-sep-2018 - is earlier than fix: 08-oct-2018)
|
||||
@ -28,6 +29,10 @@
|
||||
# 3.0.2.32658: OK, 3.309s.
|
||||
# 4.0.0.1501: OK, 5.602s.
|
||||
# 4.0.0.1421: OK, 6.920s.
|
||||
#
|
||||
# 15.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-5936
|
||||
# min_versions: ['2.5.9']
|
||||
@ -90,7 +95,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# f_ddl_script.write( ddl_script )
|
||||
# f_ddl_script.close()
|
||||
#
|
||||
# subprocess.call( ['isql', dsn, '-i', f_ddl_script.name ] )
|
||||
# subprocess.call( [context['isql_path'], dsn, '-i', f_ddl_script.name ] )
|
||||
#
|
||||
# os.remove( f_ddl_script.name )
|
||||
#
|
||||
@ -162,7 +167,6 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5.9')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_5936_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
242
tests/bugs/test_core_6015.py
Normal file
242
tests/bugs/test_core_6015.py
Normal file
@ -0,0 +1,242 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_6015
|
||||
# title: Segfault when using expression index with complex expression
|
||||
# decription:
|
||||
# Test creates following objects:
|
||||
# * table <T> with two columnad, with adding rows;
|
||||
# * stored proc <P>, which does update one record in the table <T> and returns changed value of column;
|
||||
# * computed-by index on table <T> which evaluates result of stored proc <P>.
|
||||
#
|
||||
# Procedure can either use:
|
||||
# 1) static PSQL code for updating record, or
|
||||
# 2) change it using ES,
|
||||
# 3) change it using ES+EDS.
|
||||
#
|
||||
# Currently test checks cases "1" and "2" only.
|
||||
# Check of case "3" if DEFERRED: ISQL will hang and, after it will be interrupted, Firebird process
|
||||
# keeps database file opened infinitely because of alived EDS connect.
|
||||
# Discussed with Vlad, letters 17.04.2021 09:52 and (reply from Vlad) 21.04.2021 10:40.
|
||||
#
|
||||
# ::: NB :::
|
||||
# Code for FB 3.x is separated from 4.x because content of STDERR differs: FB 3.x raises 'lock-conflict'
|
||||
# for static PSQL code (instead of "Attempt to evaluate index expression recursively").
|
||||
# Also, error messages differ because CORE-5606 was not backported to FB 3.x.
|
||||
#
|
||||
# Test cause FB crash on builds 3.0.8.33445 and 4.0.0.2416.
|
||||
# Checked on:
|
||||
# * Windows only: 3.0.8.33452 (SS/CS);
|
||||
# * Windows and Linux: 4.0.0.2436 (SS/CS)
|
||||
# -- all fine, no crashes.
|
||||
#
|
||||
# tracker_id: CORE-6015
|
||||
# min_versions: ['3.0.8']
|
||||
# versions: 3.0.8, 4.0
|
||||
# qmid:
|
||||
|
||||
import pytest
|
||||
from firebird.qa import db_factory, isql_act, Action
|
||||
|
||||
# version: 3.0.8
|
||||
# resources: None
|
||||
|
||||
substitutions_1 = [('(-)?At procedure .*', '')]
|
||||
|
||||
init_script_1 = """"""
|
||||
|
||||
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
|
||||
test_script_1 = """
|
||||
set bail on;
|
||||
set term ^;
|
||||
create procedure sp_eval_static_psql(a_id int) returns(x_changed int) as
|
||||
begin
|
||||
suspend;
|
||||
end^
|
||||
create procedure sp_eval_dynamic_sql(a_id int) returns(x_changed int) as
|
||||
begin
|
||||
suspend;
|
||||
end^
|
||||
set term ;^
|
||||
commit;
|
||||
|
||||
create table test_static_psql(id int primary key, x int);
|
||||
create index test_static_psql_eval on test_static_psql computed by ( ( select x_changed from sp_eval_static_psql( id ) ) );
|
||||
|
||||
create table test_dynamic_sql(id int primary key, x int);
|
||||
create index test_dynamic_sql_eval on test_dynamic_sql computed by ( ( select x_changed from sp_eval_dynamic_sql( id ) ) );
|
||||
commit;
|
||||
|
||||
insert into test_static_psql(id, x) values(1, 111);
|
||||
insert into test_static_psql(id, x) values(2, 222);
|
||||
|
||||
insert into test_dynamic_sql(id, x) values(1, 111);
|
||||
insert into test_dynamic_sql(id, x) values(2, 222);
|
||||
commit;
|
||||
|
||||
-- connect 'localhost:c: emp\\c6015.fdb' user 'SYSDBA' password 'masterkey';
|
||||
connect '$(DSN)' user 'SYSDBA' password 'masterkey';
|
||||
|
||||
set term ^;
|
||||
alter procedure sp_eval_static_psql(a_id int) returns(x_changed int) as
|
||||
begin
|
||||
update test_static_psql set x = -x order by x rows 1 returning x into x_changed;
|
||||
suspend;
|
||||
end^
|
||||
|
||||
alter procedure sp_eval_dynamic_sql(a_id int) returns(x_changed int) as
|
||||
begin
|
||||
execute statement 'update test_dynamic_sql set x = -x order by x rows 1 returning x' into x_changed;
|
||||
suspend;
|
||||
end^
|
||||
set term ;^
|
||||
commit;
|
||||
|
||||
set transaction read committed NO wait;
|
||||
|
||||
set bail off;
|
||||
set list on;
|
||||
|
||||
-- case-1: check when procedure changes record using STATIC PSQL code:
|
||||
-- #######
|
||||
select
|
||||
t.id as id_case_1
|
||||
,t.x as x_case_1
|
||||
,( select x_changed from sp_eval_static_psql( t.id ) ) as x_changed_1
|
||||
from test_static_psql t
|
||||
order by id
|
||||
;
|
||||
|
||||
-- case-2: check when procedure changes record using EXECUTE STATEMENT mechanism:
|
||||
-- #######
|
||||
select
|
||||
t.id as id_case_2
|
||||
,t.x as x_case_2
|
||||
,( select x_changed from sp_eval_dynamic_sql( t.id ) ) as x_changed_2
|
||||
from test_dynamic_sql t
|
||||
order by id
|
||||
;
|
||||
"""
|
||||
|
||||
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
expected_stderr_1 = """
|
||||
Statement failed, SQLSTATE = 40001
|
||||
lock conflict on no wait transaction
|
||||
-At procedure 'SP_EVAL_STATIC_PSQL' line: 3, col: 8
|
||||
At procedure 'SP_EVAL_STATIC_PSQL' line: 3, col: 8
|
||||
|
||||
Statement failed, SQLSTATE = 40001
|
||||
Attempt to evaluate index expression recursively
|
||||
-At procedure 'SP_EVAL_DYNAMIC_SQL' line: 3, col: 8
|
||||
-lock conflict on no wait transaction
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0.8,<4.0')
|
||||
def test_core_6015_1(act_1: Action):
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||
|
||||
# version: 4.0
|
||||
# resources: None
|
||||
|
||||
substitutions_2 = [('(-)?At procedure .*', '')]
|
||||
|
||||
init_script_2 = """"""
|
||||
|
||||
db_2 = db_factory(sql_dialect=3, init=init_script_2)
|
||||
|
||||
test_script_2 = """
|
||||
set bail on;
|
||||
set term ^;
|
||||
create procedure sp_eval_static_psql(a_id int) returns(x_changed int) as
|
||||
begin
|
||||
suspend;
|
||||
end^
|
||||
create procedure sp_eval_dynamic_sql(a_id int) returns(x_changed int) as
|
||||
begin
|
||||
suspend;
|
||||
end^
|
||||
set term ;^
|
||||
commit;
|
||||
|
||||
create table test_static_psql(id int primary key, x int);
|
||||
create index test_static_psql_eval on test_static_psql computed by ( ( select x_changed from sp_eval_static_psql( id ) ) );
|
||||
|
||||
create table test_dynamic_sql(id int primary key, x int);
|
||||
create index test_dynamic_sql_eval on test_dynamic_sql computed by ( ( select x_changed from sp_eval_dynamic_sql( id ) ) );
|
||||
commit;
|
||||
|
||||
insert into test_static_psql(id, x) values(1, 111);
|
||||
insert into test_static_psql(id, x) values(2, 222);
|
||||
|
||||
insert into test_dynamic_sql(id, x) values(1, 111);
|
||||
insert into test_dynamic_sql(id, x) values(2, 222);
|
||||
commit;
|
||||
|
||||
-- connect 'localhost:c: emp\\c6015.fdb' user 'SYSDBA' password 'masterkey';
|
||||
connect '$(DSN)' user 'SYSDBA' password 'masterkey';
|
||||
|
||||
set term ^;
|
||||
alter procedure sp_eval_static_psql(a_id int) returns(x_changed int) as
|
||||
begin
|
||||
update test_static_psql set x = -x order by x rows 1 returning x into x_changed;
|
||||
suspend;
|
||||
end^
|
||||
|
||||
alter procedure sp_eval_dynamic_sql(a_id int) returns(x_changed int) as
|
||||
begin
|
||||
execute statement 'update test_dynamic_sql set x = -x order by x rows 1 returning x' into x_changed;
|
||||
suspend;
|
||||
end^
|
||||
set term ;^
|
||||
commit;
|
||||
|
||||
set transaction read committed NO wait;
|
||||
|
||||
set bail off;
|
||||
set list on;
|
||||
|
||||
-- case-1: check when procedure changes record using STATIC PSQL code:
|
||||
-- #######
|
||||
select
|
||||
t.id as id_case_1
|
||||
,t.x as x_case_1
|
||||
,( select x_changed from sp_eval_static_psql( t.id ) ) as x_changed_1
|
||||
from test_static_psql t
|
||||
order by id
|
||||
;
|
||||
|
||||
-- case-2: check when procedure changes record using EXECUTE STATEMENT mechanism:
|
||||
-- #######
|
||||
select
|
||||
t.id as id_case_2
|
||||
,t.x as x_case_2
|
||||
,( select x_changed from sp_eval_dynamic_sql( t.id ) ) as x_changed_2
|
||||
from test_dynamic_sql t
|
||||
order by id
|
||||
;
|
||||
"""
|
||||
|
||||
act_2 = isql_act('db_2', test_script_2, substitutions=substitutions_2)
|
||||
|
||||
expected_stderr_2 = """
|
||||
Statement failed, SQLSTATE = 42000
|
||||
Expression evaluation error for index "TEST_STATIC_PSQL_EVAL" on table "TEST_STATIC_PSQL"
|
||||
-Attempt to evaluate index expression recursively
|
||||
-At procedure 'SP_EVAL_STATIC_PSQL' line: 3, col: 8
|
||||
At procedure 'SP_EVAL_STATIC_PSQL' line: 3, col: 8
|
||||
|
||||
Statement failed, SQLSTATE = 42000
|
||||
Expression evaluation error for index "TEST_DYNAMIC_SQL_EVAL" on table "TEST_DYNAMIC_SQL"
|
||||
-Attempt to evaluate index expression recursively
|
||||
-At procedure 'SP_EVAL_DYNAMIC_SQL' line: 3, col: 8
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_core_6015_2(act_2: Action):
|
||||
act_2.expected_stderr = expected_stderr_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stderr == act_2.clean_stderr
|
||||
|
@ -128,7 +128,6 @@ expected_stderr_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_6023_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -9,6 +9,10 @@
|
||||
# Checked on:
|
||||
# 4.0.0.1487: OK, 3.674s.
|
||||
# 3.0.5.33120: OK, 2.622s.
|
||||
#
|
||||
# 15.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-6040
|
||||
# min_versions: ['3.0.5']
|
||||
@ -39,10 +43,43 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
# db_conn.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# tmpfdb='$(DATABASE_LOCATION)'+'tmp_core_6040.fdb'
|
||||
#
|
||||
# if os.path.isfile( tmpfdb ):
|
||||
# os.remove( tmpfdb )
|
||||
# cleanup( (tmpfdb,) )
|
||||
#
|
||||
# con = fdb.create_database( dsn = 'localhost:'+tmpfdb, charset = 'win1252' )
|
||||
# con.close()
|
||||
@ -60,13 +97,13 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# f_meta_sql = open( os.path.join(context['temp_directory'],'tmp_meta_6040.sql'), 'w')
|
||||
# f_meta_err = open( os.path.join(context['temp_directory'],'tmp_meta_6040.err'), 'w')
|
||||
#
|
||||
# subprocess.call( [ "isql", "-x", "-ch", "win1252", 'localhost:'+tmpfdb],
|
||||
# subprocess.call( [ context['isql_path'], "-x", "-ch", "win1252", 'localhost:'+tmpfdb],
|
||||
# stdout = f_meta_sql,
|
||||
# stderr = f_meta_err
|
||||
# )
|
||||
#
|
||||
# f_meta_sql.close()
|
||||
# f_meta_err.close()
|
||||
# flush_and_close( f_meta_sql )
|
||||
# flush_and_close( f_meta_err )
|
||||
#
|
||||
# con.execute_immediate('drop table users')
|
||||
# con.commit()
|
||||
@ -75,16 +112,13 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# f_apply_log = open( os.path.join(context['temp_directory'],'tmp_apply_6040.log'), 'w')
|
||||
# f_apply_err = open( os.path.join(context['temp_directory'],'tmp_apply_6040.err'), 'w')
|
||||
#
|
||||
# subprocess.call( [ "isql", "-ch", "win1252", 'localhost:'+tmpfdb, "-i", f_meta_sql.name ],
|
||||
# subprocess.call( [ context['isql_path'], "-ch", "win1252", 'localhost:'+tmpfdb, "-i", f_meta_sql.name ],
|
||||
# stdout = f_apply_log,
|
||||
# stderr = f_apply_err
|
||||
# )
|
||||
#
|
||||
# f_apply_log.close()
|
||||
# f_apply_err.close()
|
||||
#
|
||||
# os.remove( tmpfdb )
|
||||
# time.sleep(1)
|
||||
# flush_and_close( f_apply_log )
|
||||
# flush_and_close( f_apply_err )
|
||||
#
|
||||
# with open( f_meta_err.name,'r') as f:
|
||||
# for line in f:
|
||||
@ -98,12 +132,10 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# for line in f:
|
||||
# print("METADATA APPLYING PROBLEM, STDERR: "+line)
|
||||
#
|
||||
#
|
||||
# f_list=(f_meta_sql, f_meta_err, f_apply_log, f_apply_err)
|
||||
# for i in range(len(f_list)):
|
||||
# if os.path.isfile(f_list[i].name):
|
||||
# os.remove(f_list[i].name)
|
||||
#
|
||||
# # cleanup:
|
||||
# ##########
|
||||
# time.sleep(1)
|
||||
# cleanup( (f_meta_sql, f_meta_err, f_apply_log, f_apply_err, tmpfdb, ) )
|
||||
#
|
||||
#
|
||||
#---
|
||||
@ -111,7 +143,6 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
|
||||
|
||||
@pytest.mark.version('>=3.0.5')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_6040_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -10,14 +10,6 @@
|
||||
# This file was preliminary stored in FF Test machine.
|
||||
# Test assumes that this file and all neccessary libraries already were stored into FB_HOME and %FB_HOME%\\plugins.
|
||||
#
|
||||
# Anyone who wants to run this test on his own machine must
|
||||
# 1) download https://ib-aid.com/download/crypt/CryptTest.zip AND
|
||||
# 2) PURCHASE LICENSE and get from IBSurgeon file plugins\\dbcrypt.conf with apropriate expiration date and other info.
|
||||
#
|
||||
# ################################################ ! ! ! N O T E ! ! ! ##############################################
|
||||
# FF tests storage (aka "fbt-repo") does not (and will not) contain any license file for IBSurgeon Demo Encryption package!
|
||||
# #########################################################################################################################
|
||||
#
|
||||
# After test database will be created, we try to encrypt it using 'alter database encrypt with <plugin_name> ...' command
|
||||
# (where <plugin_name> = dbcrypt - name of .dll in FB_HOME\\plugins\\ folder that implements encryption).
|
||||
# Then we allow engine to complete this job - take delay about 1..2 seconds BEFORE detach from database.
|
||||
@ -38,28 +30,16 @@
|
||||
#
|
||||
# Works fine on 4.0.0.1524, time ~8s.
|
||||
#
|
||||
# === NOTE-1 ===
|
||||
# In case of "Crypt plugin DBCRYPT failed to load/607/335544351" check that all
|
||||
# needed files from IBSurgeon Demo Encryption package exist in %FB_HOME% and %FB_HOME%\\plugins
|
||||
# %FB_HOME%:
|
||||
# 283136 fbcrypt.dll
|
||||
# 2905600 libcrypto-1_1-x64.dll
|
||||
# 481792 libssl-1_1-x64.dll
|
||||
#
|
||||
# %FB_HOME%\\plugins:
|
||||
# 297984 dbcrypt.dll
|
||||
# 306176 keyholder.dll
|
||||
# 108 DbCrypt.conf
|
||||
# 856 keyholder.conf
|
||||
#
|
||||
# === NOTE-2 ===
|
||||
# Version of DbCrypt.dll of october-2018 must be replaced because it has hard-coded
|
||||
# date of expiration rather than reading it from DbCrypt.conf !!
|
||||
#
|
||||
# === NOTE-3 ===
|
||||
# firebird.conf must contain following line:
|
||||
# KeyHolderPlugin = KeyHolder
|
||||
# 16.04.2021.
|
||||
# Changed code: database is created in dialect 3, then encrypted and after this we apply 'gfix -sql_dialect 1' to it.
|
||||
# Unfortunately, I could not find the way how to make it work on Linux: attempt to backup (gbak -KEYHOLDER ... -crypt ... ) fails with:
|
||||
# gbak: ERROR:unsuccessful metadata update
|
||||
# gbak: ERROR: ALTER DATABASE failed
|
||||
# gbak: ERROR: Error loading plugin FBSAMPLEDBCRYPT
|
||||
# gbak: ERROR: Module /var/tmp/fb40tmp/plugins/FBSAMPLEDBCRYPT does not contain plugin FBSAMPLEDBCRYPT type 9
|
||||
# (after file libfbSampleDbCrypt.so was copied to libFBSAMPLEDBCRYPT.so)
|
||||
#
|
||||
# Test remains WINDOWS only.
|
||||
#
|
||||
# tracker_id: CORE-6071
|
||||
# min_versions: ['4.0']
|
||||
@ -91,20 +71,71 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
# db_conn.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# tmpfdb='$(DATABASE_LOCATION)'+'tmp_core_6071.fdb'
|
||||
# tmpbkp='$(DATABASE_LOCATION)'+'tmp_core_6071.fbk'
|
||||
#
|
||||
# gbak_backup_finish_ptn=re.compile('gbak:closing\\s+file,\\s+committing,\\s+and\\s+finishing.*', re.IGNORECASE)
|
||||
# gbak_restore_finish_ptn=re.compile('gbak:adjusting\\s+the\\s+ONLINE\\s+and\\s+FORCED\\s+WRITES\\s+.*', re.IGNORECASE)
|
||||
#
|
||||
# if os.path.isfile( tmpfdb ):
|
||||
# os.remove( tmpfdb )
|
||||
# cleanup( (tmpfdb,) )
|
||||
#
|
||||
# con = fdb.create_database( dsn = 'localhost:'+tmpfdb, sql_dialect = 1 )
|
||||
# con.close()
|
||||
# con=fdb.connect( dsn = 'localhost:'+tmpfdb )
|
||||
# con = fdb.create_database( dsn = 'localhost:'+tmpfdb)
|
||||
# cur = con.cursor()
|
||||
# cur.execute('alter database encrypt with dbcrypt key Red')
|
||||
#
|
||||
# # 14.04.2021.
|
||||
# # Name of encryption plugin depends on OS:
|
||||
# # * for Windows we (currently) use plugin by IBSurgeon, its name is 'dbcrypt';
|
||||
# # * for Linux we use:
|
||||
# # ** 'DbCrypt_example' for FB 3.x
|
||||
# # ** 'fbSampleDbCrypt' for FB 4.x+
|
||||
# #
|
||||
# PLUGIN_NAME = 'dbcrypt' if os.name == 'nt' else '"fbSampleDbCrypt"'
|
||||
# KHOLDER_NAME = 'KeyHolder' if os.name == 'nt' else "fbSampleKeyHolder"
|
||||
#
|
||||
# ##############################################
|
||||
# # WARNING! Do NOT use 'connection_obj.execute_immediate()' for ALTER DATABASE ENCRYPT... command!
|
||||
# # There is bug in FB driver which leads this command to fail with 'token unknown' message
|
||||
# # The reason is that execute_immediate() silently set client dialect = 0 and any encryption statement
|
||||
# # can not be used for such value of client dialect.
|
||||
# # One need to to use only cursor_obj.execute() for encryption!
|
||||
# # See letter from Pavel Cisar, 20.01.20 10:36
|
||||
# ##############################################
|
||||
# cur.execute('alter database encrypt with %(PLUGIN_NAME)s key Red' % locals())
|
||||
#
|
||||
# con.commit()
|
||||
# time.sleep(2)
|
||||
# # ^
|
||||
@ -112,79 +143,66 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# con.close()
|
||||
#
|
||||
# #---------- aux func for cleanup: ---------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if os.path.isfile( f_names_list[i]):
|
||||
# os.remove( f_names_list[i] )
|
||||
#
|
||||
#
|
||||
# #-------------------------- shutdown temp DB and bring it online --------------------
|
||||
#
|
||||
# f_dbshut_log = open( os.path.join(context['temp_directory'],'tmp_dbshut_6071.log'), 'w')
|
||||
# subprocess.call( [ "gfix", 'localhost:'+tmpfdb, "-shut", "full", "-force", "0" ],
|
||||
# stdout = f_dbshut_log,
|
||||
# f_gfix_log = open( os.path.join(context['temp_directory'],'tmp_dbshut_6071.log'), 'w')
|
||||
# subprocess.call( [ context['gfix_path'], 'localhost:'+tmpfdb, "-sql_dialect", "1" ],
|
||||
# stdout = f_gfix_log,
|
||||
# stderr = subprocess.STDOUT
|
||||
# )
|
||||
# subprocess.call( [ "gfix", 'localhost:'+tmpfdb, "-online" ],
|
||||
# stdout = f_dbshut_log,
|
||||
# stderr = subprocess.STDOUT
|
||||
# )
|
||||
# f_dbshut_log.close()
|
||||
# flush_and_close( f_gfix_log )
|
||||
#
|
||||
# #--------------------------- backup and restore --------------------------------------
|
||||
# fn_bkp_log=open( os.path.join(context['temp_directory'],'tmp_backup_6071.log'), 'w')
|
||||
# fn_bkp_err=open( os.path.join(context['temp_directory'],'tmp_backup_6071.err'), 'w')
|
||||
#
|
||||
#
|
||||
# subprocess.call([ "gbak.exe"
|
||||
# subprocess.call([ context['gbak_path']
|
||||
# ,"-b"
|
||||
# ,"-v"
|
||||
# ,"-KEYHOLDER", "KeyHolder"
|
||||
# ,"-crypt", "DbCrypt"
|
||||
# ,"-KEYHOLDER", KHOLDER_NAME # "KeyHolder" | "fbSampleKeyHolder"
|
||||
# ,"-crypt", PLUGIN_NAME.replace('"','') # DbCrypt | fbSampleDbCrypt
|
||||
# ,'localhost:' + tmpfdb
|
||||
# ,tmpbkp
|
||||
# ],
|
||||
# stdout=fn_bkp_log, stderr=fn_bkp_err)
|
||||
#
|
||||
# fn_bkp_log.close()
|
||||
# fn_bkp_err.close()
|
||||
# flush_and_close( fn_bkp_log )
|
||||
# flush_and_close( fn_bkp_err )
|
||||
#
|
||||
#
|
||||
# fn_res_log=open( os.path.join(context['temp_directory'],'tmp_restore_6071.log'), 'w')
|
||||
# fn_res_err=open( os.path.join(context['temp_directory'],'tmp_restore_6071.err'), 'w')
|
||||
#
|
||||
# # C:\\FB SS\\gbak.exe -rep -KEYHOLDER KeyHolder C:\\FBTESTING\\qa\\misc\\C6071.fbk /:C:\\FBTESTING\\qa\\misc\\c6071.restored.FDB
|
||||
# subprocess.call([ "gbak"
|
||||
# subprocess.call([ context['gbak_path']
|
||||
# ,"-rep"
|
||||
# ,"-v"
|
||||
# ,"-KEYHOLDER", "KeyHolder"
|
||||
# ,"-KEYHOLDER", KHOLDER_NAME
|
||||
# ,tmpbkp
|
||||
# ,'localhost:' + tmpfdb
|
||||
# ],
|
||||
# stdout=fn_res_log, stderr=fn_res_err)
|
||||
#
|
||||
# fn_res_log.close()
|
||||
# fn_res_err.close()
|
||||
# flush_and_close( fn_res_log )
|
||||
# flush_and_close( fn_res_err )
|
||||
#
|
||||
# #-------------------------- validate just restored database --------------------
|
||||
#
|
||||
# f_valid_log = open( os.path.join(context['temp_directory'],'tmp_valid_6071.log'), 'w')
|
||||
# subprocess.call( [ "gfix", 'localhost:'+tmpfdb, "-v", "-full" ],
|
||||
# subprocess.call( [ context['gfix_path'], 'localhost:'+tmpfdb, "-v", "-full" ],
|
||||
# stdout = f_valid_log,
|
||||
# stderr = subprocess.STDOUT
|
||||
# )
|
||||
# f_valid_log.close()
|
||||
# flush_and_close( f_valid_log )
|
||||
#
|
||||
# #-----------------------------------------------
|
||||
#
|
||||
# # Check that all was fine:
|
||||
#
|
||||
# with open(f_dbshut_log.name,'r') as f:
|
||||
# with open(f_gfix_log.name,'r') as f:
|
||||
# for line in f:
|
||||
# print('UNEXPECTED SHUTDOWN OUTPUT: ' + line)
|
||||
# print('UNEXPECTED GFIX OUTPUT: ' + line)
|
||||
#
|
||||
# with open(fn_bkp_err.name,'r') as f:
|
||||
# for line in f:
|
||||
@ -194,7 +212,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# for line in f:
|
||||
# print('UNEXPECTED RESTORE STDERR: ' + line)
|
||||
#
|
||||
# with open(f_dbshut_log.name,'r') as f:
|
||||
# with open(f_gfix_log.name,'r') as f:
|
||||
# for line in f:
|
||||
# print('UNEXPECTED VALIDATION OUTPUT: ' + line)
|
||||
#
|
||||
@ -217,15 +235,10 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# print('EXPECTED RESTORE FINISH FOUND: '+line.upper() )
|
||||
#
|
||||
#
|
||||
# # Allow all file buffers to be flushed on disk before we will drop them:
|
||||
# time.sleep(1)
|
||||
#
|
||||
# # cleanup
|
||||
# ##########
|
||||
#
|
||||
# f_list = [ i.name for i in ( f_dbshut_log, fn_bkp_log, fn_bkp_err, fn_res_log, fn_res_err, f_valid_log ) ]
|
||||
# f_list += [ tmpfdb, tmpbkp ]
|
||||
# cleanup( f_list )
|
||||
# time.sleep(1)
|
||||
# cleanup( ( f_gfix_log, fn_bkp_log, fn_bkp_err, fn_res_log, fn_res_err, f_valid_log, tmpfdb, tmpbkp ) )
|
||||
#
|
||||
#
|
||||
#---
|
||||
|
@ -8,6 +8,10 @@
|
||||
# 4.0.0.1614: OK, 1.509s.
|
||||
# 3.0.5.33171: OK, 0.682s.
|
||||
# 2.5.9.27142: OK, 0.629s.
|
||||
#
|
||||
# 15.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2416
|
||||
# Linux: 4.0.0.2416
|
||||
#
|
||||
# tracker_id: CORE-6145
|
||||
# min_versions: ['2.5.0']
|
||||
@ -26,40 +30,120 @@ init_script_1 = """"""
|
||||
|
||||
db_1 = db_factory(charset='UTF8', sql_dialect=3, init=init_script_1)
|
||||
|
||||
test_script_1 = """
|
||||
set count on;
|
||||
set heading off;
|
||||
select 1 from rdb$database where 'я' similar to '%Я%';
|
||||
select 2 from rdb$database where 'Я' similar to '%я%';
|
||||
select 3 from rdb$database where 'я' similar to '[Яя]';
|
||||
select 4 from rdb$database where 'Я' similar to 'я';
|
||||
select 5 from rdb$database where 'Я' similar to 'Я';
|
||||
select 6 from rdb$database where 'Я' similar to '[яЯ]';
|
||||
"""
|
||||
|
||||
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
# test_script_1
|
||||
#---
|
||||
#
|
||||
# import os
|
||||
# import time
|
||||
# import subprocess
|
||||
#
|
||||
# os.environ["ISC_USER"] = user_name
|
||||
# os.environ["ISC_PASSWORD"] = user_password
|
||||
#
|
||||
# db_conn.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# non_ascii_ddl='''
|
||||
# set bail on;
|
||||
# set list on;
|
||||
# set names win1251;
|
||||
# connect '%(dsn)s' user '%(user_name)s' password '%(user_password)s';
|
||||
#
|
||||
# set count on;
|
||||
# set heading off;
|
||||
# -- NB: When this script is Python variable then we have to use DUPLICATE percent signs!
|
||||
# -- Otherwise get: "not enough arguments for format string"
|
||||
# select 1 result_1 from rdb$database where 'я' similar to '%%Я%%';
|
||||
# select 2 result_2 from rdb$database where 'Я' similar to '%%я%%';
|
||||
# select 3 result_3 from rdb$database where 'я' similar to '[Яя]';
|
||||
# select 4 result_4 from rdb$database where 'Я' similar to 'я';
|
||||
# select 5 result_5 from rdb$database where 'Я' similar to 'Я';
|
||||
# select 6 result_6 from rdb$database where 'Я' similar to '[яЯ]';
|
||||
# ''' % dict(globals(), **locals())
|
||||
#
|
||||
# f_ddl_sql = open( os.path.join(context['temp_directory'], 'tmp_6145_w1251.sql'), 'w' )
|
||||
# f_ddl_sql.write( non_ascii_ddl.decode('utf8').encode('cp1251') )
|
||||
# flush_and_close( f_ddl_sql )
|
||||
#
|
||||
# f_run_log = open( os.path.join(context['temp_directory'],'tmp_6145.log'), 'w')
|
||||
# f_run_err = open( os.path.join(context['temp_directory'],'tmp_6145.err'), 'w')
|
||||
#
|
||||
# subprocess.call( [context['isql_path'], "-q", "-i", f_ddl_sql.name ],
|
||||
# stdout = f_run_log,
|
||||
# stderr = f_run_err
|
||||
# )
|
||||
#
|
||||
# flush_and_close( f_run_log )
|
||||
# flush_and_close( f_run_err )
|
||||
#
|
||||
# with open( f_run_log.name, 'r') as f:
|
||||
# for line in f:
|
||||
# if line.strip():
|
||||
# print( line.strip().decode("cp1251").encode('utf8') )
|
||||
#
|
||||
# with open( f_run_err.name, 'r') as f:
|
||||
# for line in f:
|
||||
# out_txt='UNEXPECTED STDERR: ';
|
||||
# if line.strip():
|
||||
# print( out_txt + line.strip().decode("cp1251").encode('utf8') )
|
||||
#
|
||||
# # cleanup:
|
||||
# ##########
|
||||
# time.sleep(1)
|
||||
# #cleanup( (f_ddl_sql, f_run_log, f_run_err) )
|
||||
#
|
||||
#
|
||||
#---
|
||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
expected_stdout_1 = """
|
||||
Records affected: 0
|
||||
|
||||
Records affected: 0
|
||||
|
||||
3
|
||||
Records affected: 1
|
||||
|
||||
Records affected: 0
|
||||
|
||||
5
|
||||
Records affected: 1
|
||||
|
||||
6
|
||||
Records affected: 1
|
||||
Records affected: 0
|
||||
Records affected: 0
|
||||
RESULT_3 3
|
||||
Records affected: 1
|
||||
Records affected: 0
|
||||
RESULT_5 5
|
||||
Records affected: 1
|
||||
RESULT_6 6
|
||||
Records affected: 1
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5')
|
||||
@pytest.mark.platform('Windows')
|
||||
def test_core_6145_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@pytest.mark.xfail
|
||||
def test_core_6145_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
||||
|
||||
|
@ -462,7 +462,9 @@ db_2 = db_factory(sql_dialect=3, init=init_script_2)
|
||||
# -- The reason of that weird effect currently is unknown.
|
||||
# -- Here we make pause using 'set transaction lock timeout':
|
||||
#
|
||||
# set transaction lock timeout 2; -- THIS LOCK TIMEOUT SERVES ONLY FOR DELAY
|
||||
# -- 20.04.2021: increased delay from 2 to 3 seconds.
|
||||
# -- Otherwise can get "... crypt thread not complete":
|
||||
# set transaction lock timeout 3; -- THIS LOCK TIMEOUT SERVES ONLY FOR DELAY
|
||||
# execute procedure sp_delay;
|
||||
# rollback;
|
||||
# show database;
|
||||
|
@ -3,27 +3,42 @@
|
||||
# id: bugs.core_6348
|
||||
# title: Wire compression causes freezes
|
||||
# decription:
|
||||
# We create copy of %FIREBIRD_HOME%
|
||||
# irebird.conf and change it content by adding line:
|
||||
# WireCompression = true
|
||||
# Test does TWO measures related to speed of loading big blob into database:
|
||||
# 1) when WireCompression = true
|
||||
# 2) when WireCompression = false
|
||||
# (see below usage of 'WIRE_COMPRESSION_VALUE' variable)
|
||||
# Then we compare elapsed time (stored in milliseconds) between these two measures.
|
||||
#
|
||||
# Then we use pre-created large binary file which can not be compressed (it is .7z) and
|
||||
# check how long it is loaded into blob field of test table.
|
||||
#
|
||||
# ::: NOTE :::
|
||||
# EXTERNAL script for execution by Python is created here!
|
||||
# Otherwise one can not reproduce problem described in the ticket if original firebird.conf
|
||||
# does NOT contain 'WireCompression' or its value is set to false.
|
||||
# We have to launch NEW (child) Python process which will run fully separately from current.
|
||||
# Time of loading when WireCompression = true will be greater than time for WireCompression = false.
|
||||
# RATIO (i.e. <wc_ON> / <wc_OFF>) instead of absolute values is used as criteria for passing this test.
|
||||
# This ratio must not exceed threshold that was defined beforehand
|
||||
# I ran this test five times for each server mode, for FB 3.x and 4.x, both on Windows and Linux.
|
||||
#
|
||||
# Dozen measures show that after this CORE was fixed, blob is loaded for less 5 seconds
|
||||
# on usual PC with HDD/ram=12gb/CPU 3.07 MHz.
|
||||
# Results depend primarily on OS: about 3.05 for Windows and 1.48 for Linux.
|
||||
# This difference looks strange and may be it is a good idea to discussed this with FB developers.
|
||||
# CURRENTLY threshold is set to approx. double value of maximal detected ratio (see 'MAX_RATIO_THRESHOLD').
|
||||
#
|
||||
# NOTE-1
|
||||
# Test temporary changes firebird.conf, so any abnormal termination of it can cause
|
||||
# problems for other tests (which are to be executed after current).
|
||||
#
|
||||
# NOTE-2
|
||||
# EXTERNAL script for execution by Python is created here!
|
||||
# Otherwise one can not reproduce problem described in the ticket if original firebird.conf
|
||||
# We have to launch NEW (child) Python process which will run fully separately from current.
|
||||
#
|
||||
# NOTE-3
|
||||
# Test uses pre-created large binary file which can not be compressed: it is compressed trace log
|
||||
# with original size about 2.2 Gb which was processed by 7-Zip with '-mx9 -mfb273' switches.
|
||||
#
|
||||
# Confirmed bug on 4.0.0.1994: blob loading time is more than 120s.
|
||||
# Checked on 4.0.0.2089.
|
||||
#
|
||||
#
|
||||
# 15.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 3.0.8.33445 SS/CS, 4.0.0.2422 SS/CS
|
||||
# Linux: 3.0.8.33445 SS/CS, 4.0.0.2422 SS/CS
|
||||
#
|
||||
# It was decided to use THRESHOLD about 15 seconds to make conclusion that all remains fine.
|
||||
# May be this threshold needs to be sometime revised.
|
||||
#
|
||||
# Confirmed bug on 4.0.0.1994: blob loading time is more than 120s.
|
||||
# Checked on 4.0.0.2089 -- all fine, blob is loaded for less than 5s.
|
||||
#
|
||||
# tracker_id: CORE-6348
|
||||
# min_versions: ['3.0.6']
|
||||
@ -44,8 +59,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
|
||||
# test_script_1
|
||||
#---
|
||||
#
|
||||
# import os
|
||||
# import os
|
||||
# import sys
|
||||
# import subprocess
|
||||
# from subprocess import Popen
|
||||
@ -70,18 +84,20 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# def showtime():
|
||||
# global dt
|
||||
# return ''.join( (dt.now().strftime("%H:%M:%S.%f")[:11],'.') )
|
||||
# #-----------------------------------
|
||||
#
|
||||
# def flush_and_close(file_handle):
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# os.fsync(file_handle.fileno())
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
@ -89,91 +105,146 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if os.path.isfile( f_names_list[i]):
|
||||
# os.remove( f_names_list[i] )
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
#
|
||||
# fb_home = services.connect(host='localhost', user= user_name, password= user_password).get_home_directory()
|
||||
# # Resut: fb_home is full path to FB instance home (with trailing slash).
|
||||
# FB_HOME = services.connect(host='localhost', user= user_name, password= user_password).get_home_directory()
|
||||
# # Resut: FB_HOME is full path to FB instance home (with trailing slash).
|
||||
#
|
||||
# if os.name == 'nt':
|
||||
# # For Windows we assume that client library is always in FB_HOME dir:
|
||||
# FB_CLNT=os.path.join(FB_HOME, 'fbclient.dll')
|
||||
# else:
|
||||
# # For Linux client library will be searched in 'lib' subdirectory of FB_HOME:
|
||||
# FB_CLNT=os.path.join(FB_HOME, 'lib', 'libfbclient.so' )
|
||||
#
|
||||
#
|
||||
# dts = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
|
||||
#
|
||||
# fbconf_cur = os.path.join( fb_home, 'firebird.conf')
|
||||
# fbconf_bak = os.path.join( fb_home, 'firebird'+dts+'.bak')
|
||||
# fbconf_cur = os.path.join( FB_HOME, 'firebird.conf')
|
||||
# fbconf_bak = os.path.join( FB_HOME, 'firebird'+dts+'.bak')
|
||||
#
|
||||
# shutil.copy2( fb_home+'firebird.conf', fbconf_bak )
|
||||
# shutil.copy2( fbconf_cur, fbconf_bak )
|
||||
#
|
||||
# f_fbconf=open( fbconf_cur, 'r')
|
||||
# fbconf_content=f_fbconf.readlines()
|
||||
# f_fbconf.close()
|
||||
# for i,s in enumerate( fbconf_content ):
|
||||
# line = s.lower().lstrip()
|
||||
# if line.startswith( 'wirecompression'.lower() ):
|
||||
# fbconf_content[i] = '# [temply commented by fbtest for core_6348.fbt] ' + s
|
||||
# blob_load_elapsed_time = {}
|
||||
#
|
||||
# for iter in (1,2):
|
||||
# # Restore original content of firebird.conf:
|
||||
# ##################
|
||||
# shutil.copy2( fbconf_bak, fbconf_cur )
|
||||
#
|
||||
# f_fbconf=open( fbconf_cur, 'r')
|
||||
# fbconf_content=f_fbconf.readlines()
|
||||
# f_fbconf.close()
|
||||
# for i,s in enumerate( fbconf_content ):
|
||||
# line = s.lower().lstrip()
|
||||
# if line.startswith( 'wirecompression'.lower() ):
|
||||
# fbconf_content[i] = '# [temply commented by fbtest for core_6348.fbt] ' + s
|
||||
#
|
||||
#
|
||||
# text2app='''
|
||||
# ### TEMPORARY CHANGED FOR CORE_6348.FBT ###
|
||||
# WireCompression = true
|
||||
# ##############################################
|
||||
# '''
|
||||
# WIRE_COMPRESSION_VALUE = 'true' if iter == 1 else 'false'
|
||||
#
|
||||
# fbconf_content += [ os.linesep + x for x in text2app.split( os.linesep ) ]
|
||||
# text2app= '''
|
||||
# ### TEMPORARY CHANGED FOR CORE_6348.FBT ###
|
||||
# WireCompression = %(WIRE_COMPRESSION_VALUE)s
|
||||
# ##############################################
|
||||
# ''' % locals()
|
||||
#
|
||||
# f_fbconf=open( fbconf_cur, 'w', buffering = 0)
|
||||
# f_fbconf.writelines( fbconf_content )
|
||||
# flush_and_close( f_fbconf )
|
||||
# fbconf_content += [ os.linesep + x for x in text2app.split( os.linesep ) ]
|
||||
#
|
||||
# FB_CLNT = os.path.join(fb_home, 'fbclient.dll')
|
||||
# BLOB_FILE = os.path.join(context['files_location'],'core_6348.bin')
|
||||
# f_fbconf=open( fbconf_cur, 'w', buffering = 0)
|
||||
# f_fbconf.writelines( fbconf_content )
|
||||
# flush_and_close( f_fbconf )
|
||||
#
|
||||
# external_python_code='''from __future__ import print_function
|
||||
# from datetime import datetime as dt
|
||||
# from datetime import timedelta
|
||||
# import fdb
|
||||
# con = fdb.connect( dsn = r'%(dsn)s', user='%(user_name)s', password='%(user_password)s', fb_library_name = r'%(FB_CLNT)s' )
|
||||
# con.execute_immediate('create table test(b blob)')
|
||||
# con.commit()
|
||||
#
|
||||
# BLOB_FILE = os.path.join(context['files_location'],'core_6348.bin')
|
||||
#
|
||||
# cur=con.cursor()
|
||||
# blob_src = r'%(BLOB_FILE)s'
|
||||
# blob_handle = open( blob_src, 'rb')
|
||||
# external_python_code=''' from __future__ import print_function
|
||||
# from datetime import datetime as dt
|
||||
# from datetime import timedelta
|
||||
# import fdb
|
||||
# con = fdb.connect( dsn = r'%(dsn)s', user='%(user_name)s', password='%(user_password)s', fb_library_name = r'%(FB_CLNT)s' )
|
||||
# con.execute_immediate('recreate table test(b blob)')
|
||||
# con.commit()
|
||||
#
|
||||
# da=dt.now()
|
||||
# cur.execute('insert into test(b) values(?)',[blob_handle])
|
||||
# db=dt.now()
|
||||
# cur=con.cursor()
|
||||
# blob_src = r'%(BLOB_FILE)s'
|
||||
# blob_handle = open( blob_src, 'rb')
|
||||
#
|
||||
# blob_handle.close()
|
||||
# diff=db-da
|
||||
# print( 'Acceptable' if diff.seconds < %(MAX_SECONDS_FOR_LOAD)s else 'BLOB LOADED TOO SLOW: ' + str(diff.seconds) + 's, THRESHOLD IS: ' + str(%(MAX_SECONDS_FOR_LOAD)s)+'s' )
|
||||
# da = dt.now()
|
||||
# cur.execute('insert into test(b) values(?)',[blob_handle])
|
||||
# db = dt.now()
|
||||
#
|
||||
# cur.close()
|
||||
# con.commit()
|
||||
# con.close()
|
||||
# ''' % dict(globals(), **locals())
|
||||
# blob_handle.close()
|
||||
# diff_ms = (db-da).seconds*1000 + (db-da).microseconds//1000
|
||||
# print( str(diff_ms) )
|
||||
#
|
||||
# f_extern_py=open( os.path.join(context['temp_directory'],'tmp_6348.py'), 'w')
|
||||
# f_extern_py.write(external_python_code)
|
||||
# flush_and_close( f_extern_py )
|
||||
# cur.close()
|
||||
# con.commit()
|
||||
# con.close()
|
||||
# ''' % dict(globals(), **locals())
|
||||
#
|
||||
# f_external_py_log = open( os.path.join(context['temp_directory'],'tmp_6348.log'), 'w')
|
||||
# subprocess.call( [sys.executable, f_extern_py.name], stdout = f_external_py_log, stderr = subprocess.STDOUT )
|
||||
# flush_and_close( f_external_py_log )
|
||||
# f_extern_py = open( os.path.join(context['temp_directory'],'tmp_6348.' + str(iter) + '.py'), 'w')
|
||||
# f_extern_py.write( '\\n'.join( [i.strip() for i in external_python_code.split('\\n')] ) )
|
||||
# flush_and_close( f_extern_py )
|
||||
# # f_extern_py.close()
|
||||
#
|
||||
# f_external_py_log = open( os.path.join(context['temp_directory'],'tmp_6348_py.' + str(iter) + '.log' ), 'w')
|
||||
# subprocess.call( [sys.executable, f_extern_py.name], stdout = f_external_py_log, stderr = subprocess.STDOUT )
|
||||
# flush_and_close( f_external_py_log )
|
||||
#
|
||||
# with open(f_external_py_log.name,'r') as f:
|
||||
# blob_load_elapsed_time[ WIRE_COMPRESSION_VALUE ] = int(f.read().strip())
|
||||
# cleanup( ( f_extern_py, f_external_py_log ) )
|
||||
#
|
||||
# # Restore original content of firebird.conf:
|
||||
# ##################
|
||||
# shutil.copy2( fbconf_bak, fb_home+'firebird.conf' )
|
||||
# os.remove( fbconf_bak )
|
||||
# shutil.move( fbconf_bak, fbconf_cur )
|
||||
#
|
||||
# with open(f_external_py_log.name, 'r') as f:
|
||||
# for line in f:
|
||||
# print(line)
|
||||
# #print(blob_load_elapsed_time)
|
||||
# #print( 1.00 * blob_load_elapsed_time['true'] / blob_load_elapsed_time['false'] )
|
||||
#
|
||||
# time.sleep(1)
|
||||
# # 4.0.0.1994 SC: {'false': 2036, 'true': 126711}, ratio: 62.24
|
||||
# # 4.0.0.2422 SS: {'false': 831, 'true': 3722}, ratio: 4.48 // LINUX: 3.42; 3.11; 3.49; 3.44; 3.45
|
||||
# # 4.0.0.2422 CS: {'false': 2088, 'true': 6903}, ratio: 3.31 // LINUX: 1.46; 1.46; 1.48; 1.46; 1.51
|
||||
# # 3.0.8.33445 SS: {'false': 1135, 'true': 3862}, ratio: 3.40 // LINUX: 1.52; 1.63; 1.52; 1.48; 1.51
|
||||
# # 3.0.8.33445 CS: {'false': 2160, 'true': 7675}, ratio: 3.55 // LINUX: 1.56; 1.61; 1.56; 1.55; 1.54
|
||||
#
|
||||
# ratio = 1.00 * blob_load_elapsed_time['true'] / blob_load_elapsed_time['false']
|
||||
#
|
||||
# if os.name == 'nt':
|
||||
# MAX_RATIO_THRESHOLD = 7
|
||||
# else:
|
||||
# MAX_RATIO_THRESHOLD = 20
|
||||
# # ^
|
||||
# # |
|
||||
# # |
|
||||
# # ##################
|
||||
# # ### THRESHOLD ####
|
||||
# # ##################
|
||||
#
|
||||
# msg = 'Ratio is acceptable.' if ratio < MAX_RATIO_THRESHOLD else (
|
||||
# 'Performance degradation when WireCompression = true is too high. ' +
|
||||
# 'Without compression: %15.2f, with compression: %15.2f, ratio is %15.2f - more than max. threshold = %3d' % ( blob_load_elapsed_time['false'], blob_load_elapsed_time['true'], ratio, MAX_RATIO_THRESHOLD)
|
||||
# )
|
||||
#
|
||||
# print(msg)
|
||||
#
|
||||
# # Cleanup
|
||||
# #########
|
||||
# time.sleep(1)
|
||||
# f_list=( f_extern_py, f_external_py_log )
|
||||
# cleanup( [ i.name for i in f_list ] )
|
||||
#
|
||||
@ -182,11 +253,10 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
expected_stdout_1 = """
|
||||
Acceptable
|
||||
Ratio is acceptable.
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0.6')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_6348_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
@ -3,7 +3,9 @@
|
||||
# id: bugs.core_6397
|
||||
# title: Message length error with COALESCE and TIME/TIMESTAMP WITHOUT TIME ZONE and WITH TIME ZONE
|
||||
# decription:
|
||||
# We user ISQL "out nul;" command in order to supress STDOUT. STDERR is not redirected and must be empty.
|
||||
# Test uses EXECUTE BLOCK with dummy variable to store reuslt (w/o suspend in order to prevent any output).
|
||||
# EXECUTE STATEMENT must be used here for reproducing problem (no error with static PSQL code).
|
||||
#
|
||||
# Confirmed bug on 4.0.0.2173.
|
||||
# Checked on 4.0.0.2188 -- all fine.
|
||||
#
|
||||
@ -25,17 +27,20 @@ init_script_1 = """"""
|
||||
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
|
||||
test_script_1 = """
|
||||
set list on;
|
||||
out nul;
|
||||
select coalesce(localtimestamp, current_timestamp) as result from rdb$database;
|
||||
out;
|
||||
set term ^;
|
||||
execute block as
|
||||
declare dummy timestamp;
|
||||
begin
|
||||
execute statement 'select coalesce(localtimestamp, current_timestamp) from rdb$database' into dummy;
|
||||
end
|
||||
^
|
||||
set term ;^
|
||||
"""
|
||||
|
||||
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
def test_core_6397_1(act_1: Action):
|
||||
act_1.execute()
|
||||
|
||||
|
@ -4,24 +4,33 @@
|
||||
# title: Ability to query Firebird configuration using SQL
|
||||
# decription:
|
||||
# Test found FB_HOME directory and makes copy its firebird.conf and database.conf files.
|
||||
# Then it found free TCP port and overwrites content of firebird.conf: this new port
|
||||
# will be specified for RemoveServicePort and some other parameters also will be added.
|
||||
# Then:
|
||||
# * for Windows it founds free TCP port and overwrites content of firebird.conf: this new port
|
||||
# will be specified for RemoveServicePort and some other parameters also will be added.
|
||||
# * for Linux it will use local protocol rather than TCP (it is not possible to connect to
|
||||
# any database using TCP if new FB instance is launched using subprocess.Popen('firebird');
|
||||
# the reason of this is unknown)
|
||||
#
|
||||
# File <FB_HOME>\\databases.conf is also changed: we add new alias for database that will
|
||||
# be self-security and specify lot of per-database parameters for it.
|
||||
#
|
||||
# Some numeric parameters intentionally will be assigned to huge bigint values, namely:
|
||||
# * FileSystemCacheThreshold
|
||||
# * TempCacheLimit
|
||||
# Their huge values do not affect on actual work; this is done only for check proper
|
||||
# interpretation of them.
|
||||
# ServerMode is set to SuperClassic.
|
||||
#
|
||||
# After this test launches Firebird as application (see async. call of Popen()) and make
|
||||
# connect to new database by launching ISQL.
|
||||
# After this test:
|
||||
# * for Windows: launches Firebird as application (see async. call of Popen()) and make
|
||||
# connect to new database by launching ISQL.
|
||||
# * for Linux: makes connection to database using local (embedded) protocol.
|
||||
#
|
||||
# When connect is established, we query RDB$CONFIG table two times:
|
||||
# * as SYSDBA (in this case all config parameters and their actual values must be seen);
|
||||
# * as NON-privileged user (zero rows must be issued for query to RDB$CONFIG).
|
||||
#
|
||||
# Finally (after return from ISQL) test terminates Firebird application process.
|
||||
# Checked on 4.0.0.2365.
|
||||
# Finally (after return from ISQL, and only for Windows) test terminates Firebird application process.
|
||||
#
|
||||
# ::: CAUTION-1 :::
|
||||
# This test will fail if new parameter will appear in firebird.conf or if old one removed from there.
|
||||
@ -35,15 +44,18 @@
|
||||
# Perhaps, following command will be useful: netsh advfirewall set privateprofile state off
|
||||
#
|
||||
# ::: CAUTION-3 :::
|
||||
# 13.02.2021 Currently this test must be executed only on Windows!
|
||||
# On Linux it terminates with runtime ERROR ('E') and firebird.conf + databases.conf remains in $FB_HOME
|
||||
# with changed parameters.
|
||||
# For Classic this prevents all subsequent tests to be executed normally: all of them will also finish with 'E'.
|
||||
# This problem will be solved later.
|
||||
# Default values for some parameters differ on Windows and Linux.
|
||||
# They are: IpcName, MaxUnflushed* and OutputRedirectionFile.
|
||||
#
|
||||
# Because of such valuable differences, it was decided to make code for Windows and Linux separate.
|
||||
#
|
||||
# Initially checked on 4.0.0.2365 (Windows only).
|
||||
# Checked on 4.0.0.2422 - after adapted for work both Windows and Linux.
|
||||
# Checked on 4.0.0.2436 - parameter 'TempTableDirectory' appeared.
|
||||
#
|
||||
# tracker_id: CORE-6444
|
||||
# min_versions: ['4.0']
|
||||
# versions: 4.0
|
||||
# versions: 4.0, 4.0
|
||||
# qmid: None
|
||||
|
||||
import pytest
|
||||
@ -90,10 +102,17 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if os.path.isfile( f_names_list[i]):
|
||||
# os.remove( f_names_list[i] )
|
||||
# if os.path.isfile( f_names_list[i]):
|
||||
# print('ERROR: can not remove file ' + f_names_list[i])
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
@ -113,9 +132,10 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# FB_HOME = services.connect(host='localhost', user=user_name, password=user_password).get_home_directory()
|
||||
# FB_BINS = os.path.join(FB_HOME, 'bin') # we are in LINUX branch. Windows see in separate section, not here!
|
||||
#
|
||||
# fb_vers = str(db_conn.engine_version)[:1] # character for security.db file: engine = 4.0 --> '4'
|
||||
# sec_db = FB_HOME + 'security' + fb_vers+ '.fdb'
|
||||
# sec_db = os.path.join( FB_HOME, 'security' + fb_vers+ '.fdb')
|
||||
#
|
||||
# db_conn.close()
|
||||
#
|
||||
@ -134,9 +154,10 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# shutil.copy2( sec_db, fdb_test )
|
||||
#
|
||||
# TMPDIR = os.path.join( FB_HOME, 'examples' ) # tempfile.gettempdir()
|
||||
# TEMP_DIRECTORIES_VALUE = os.path.normpath( os.path.join(FB_HOME, 'examples') )
|
||||
# TTABLE_DIRECTORY_VALUE = os.path.normpath( context['temp_directory'] )
|
||||
#
|
||||
# TMP_FREE_PORT = find_free_port()
|
||||
# #TMP_FREE_PORT = 57456
|
||||
#
|
||||
# cfg_params_to_change= {
|
||||
# 'AllowEncryptedSecurityDatabase' : 'true'
|
||||
@ -170,7 +191,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# ,'TcpNoNagle' : 'false'
|
||||
# ,'TcpRemoteBufferSize' : '5555'
|
||||
# ,'TempBlockSize' : '5m'
|
||||
# ,'TempDirectories' : os.path.normpath( TMPDIR )
|
||||
# ,'TempDirectories' : TEMP_DIRECTORIES_VALUE
|
||||
# ,'TempTableDirectory' : os.path.normpath( tempfile.gettempdir() ) # since 4.0.0.2436, 21.04.2021
|
||||
# ,'UDFaccess' : 'Restrict UDF'
|
||||
# ,'UseFileSystemCache' : 'false'
|
||||
# ,'WireCompression' : 'true'
|
||||
@ -218,6 +240,18 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# TempBlockSize = 3m
|
||||
# TempCacheLimit = 8589934591G
|
||||
#
|
||||
# ###############################
|
||||
# # Appeared since 4.0.0.2436, 21.04.2021; per-database:
|
||||
# # ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# # Directory to put data of temporary tables and blobs
|
||||
# # When empty, not exists or not accessible, default directory will be used
|
||||
# # as determined by FIREBIRD_TMP, TEMP or TMP environment variables.
|
||||
# # Per-database configurable.
|
||||
# # Type: string
|
||||
# #TempTableDirectory =
|
||||
# ###############################
|
||||
# TempTableDirectory = %(TTABLE_DIRECTORY_VALUE)s
|
||||
#
|
||||
# TipCacheBlockSize = 3m
|
||||
#
|
||||
@ -229,24 +263,27 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# f_dbconf.write(alias_data)
|
||||
# flush_and_close( f_dbconf )
|
||||
#
|
||||
# p_tmp_fb_pid = subprocess.Popen( [ FB_HOME+'firebird', '-a'] )
|
||||
#
|
||||
# time.sleep(2)
|
||||
# # LINUX: we use local protocol rather than remote (as on Windows):
|
||||
# CONN_STR = 'tmp_6444'
|
||||
#
|
||||
# sql_text='''
|
||||
# -- set echo on;
|
||||
# set wng off;
|
||||
# connect 'tmp_6444';
|
||||
# create or alter user sysdba password 'masterkey' using plugin Srp;
|
||||
# create or alter user %(user_name)s password '%(user_password)s' using plugin Srp;
|
||||
# create or alter user tmp$c6444 password '123' using plugin Srp;
|
||||
# revoke all on all from tmp$c6444;
|
||||
# create or alter view v_config as
|
||||
# select
|
||||
# g.rdb$config_name param_name
|
||||
# ,iif(trim(g.rdb$config_value)='', '[empty]'
|
||||
# ,iif( g.rdb$config_name = 'TempDirectories' and upper(g.rdb$config_value) = upper('%(TMPDIR)s') or g.rdb$config_name = 'RemoteServicePort' and g.rdb$config_value = %(TMP_FREE_PORT)s
|
||||
# ,'[MATCHES]'
|
||||
# ,g.rdb$config_value)
|
||||
# ,iif( trim(g.rdb$config_value)=''
|
||||
# ,'[empty]'
|
||||
# ,iif( upper(g.rdb$config_name) = upper('TempDirectories') and upper(g.rdb$config_value) = upper('%(TEMP_DIRECTORIES_VALUE)s')
|
||||
# or upper(g.rdb$config_name) = upper('TempTableDirectory') and upper(g.rdb$config_value) = upper('%(TTABLE_DIRECTORY_VALUE)s')
|
||||
# or upper(g.rdb$config_name) = upper('RemoteServicePort') and g.rdb$config_value = %(TMP_FREE_PORT)s
|
||||
# ,'[MATCHES]'
|
||||
# ,g.rdb$config_value
|
||||
# )
|
||||
# ) param_value
|
||||
# ,iif(trim(g.rdb$config_default)='', '[empty]', replace(g.rdb$config_default,'%(FB_HOME)s','') ) param_default
|
||||
# ,g.rdb$config_is_set param_is_set
|
||||
@ -258,7 +295,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# grant select on v_config to tmp$c6444;
|
||||
# commit;
|
||||
#
|
||||
# connect 'localhost/%(TMP_FREE_PORT)s:tmp_6444' user sysdba password 'masterkey';
|
||||
# connect '%(CONN_STR)s' user %(user_name)s password '%(user_password)s';
|
||||
#
|
||||
# set count on;
|
||||
# set width param_name 50;
|
||||
@ -269,7 +306,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# select * from v_config; -- SYSDBA: must see all parameters with their effective values
|
||||
#
|
||||
# commit;
|
||||
# connect 'localhost/%(TMP_FREE_PORT)s:tmp_6444' user tmp$c6444 password '123';
|
||||
# connect '%(CONN_STR)s' user tmp$c6444 password '123';
|
||||
#
|
||||
# select * from v_config; -- NON-PRIVILEGED user: must see 0 rows
|
||||
#
|
||||
@ -281,6 +318,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# ,m.mon$database_name as db_name
|
||||
# ,m.mon$page_buffers as db_buffers
|
||||
# ,m.mon$sec_database as db_sec_name
|
||||
# ,a.mon$server_pid as server_pid
|
||||
# ,a.mon$remote_protocol
|
||||
# ,a.mon$idle_timeout
|
||||
# ,a.mon$statement_timeout
|
||||
@ -291,14 +329,14 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# cross join mon$attachments a
|
||||
# where a.mon$attachment_id = current_connection
|
||||
# ;
|
||||
# */
|
||||
# --*/
|
||||
#
|
||||
# commit;
|
||||
# connect 'localhost/%(TMP_FREE_PORT)s:tmp_6444' user sysdba password 'masterkey';
|
||||
# connect '%(CONN_STR)s' user sysdba password 'masterkey';
|
||||
# drop user tmp$c6444 using plugin Srp;
|
||||
# commit;
|
||||
#
|
||||
# ''' % locals()
|
||||
# ''' % dict(globals(), **locals())
|
||||
#
|
||||
# f_sql_cmd = open( os.path.join(context['temp_directory'],'tmp_c6444.sql'), 'w')
|
||||
# f_sql_cmd.write( sql_text )
|
||||
@ -307,18 +345,14 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# f_sql_log=open( os.path.join(context['temp_directory'],'tmp_c6444.log'), 'w')
|
||||
# f_sql_err=open( os.path.join(context['temp_directory'],'tmp_c6444.err'), 'w')
|
||||
#
|
||||
# #subprocess.call( [FB_HOME+'isql', 'localhost/%(TMP_FREE_PORT)s:tmp_6444' % locals(), '-i', f_sql_cmd.name], stdout=f_sql_log, stderr=f_sql_err )
|
||||
# subprocess.call( [FB_HOME+'isql', '-q', '-pag', '999999', '-i', f_sql_cmd.name, '-user', 'SYSDBA'], stdout=f_sql_log, stderr=f_sql_err )
|
||||
# subprocess.call( [context['isql_path'], '-q', '-pag', '999999', '-i', f_sql_cmd.name, '-user', 'SYSDBA'], stdout=f_sql_log, stderr=f_sql_err )
|
||||
#
|
||||
# flush_and_close( f_sql_log )
|
||||
# flush_and_close( f_sql_err )
|
||||
#
|
||||
# p_tmp_fb_pid.terminate()
|
||||
#
|
||||
# shutil.move( fbconf_bak, fbconf_cur )
|
||||
# shutil.move( dbconf_bak, dbconf_cur )
|
||||
#
|
||||
#
|
||||
# with open(f_sql_err.name, 'r') as f:
|
||||
# for line in f:
|
||||
# if line.split():
|
||||
@ -335,14 +369,417 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# # Cleanup
|
||||
# ##########
|
||||
# cleanup( [ i.name for i in f_list ] + [fdb_test] )
|
||||
#
|
||||
# # cleanup( [ i.name for i in f_list ] + [fdb_test] )
|
||||
#
|
||||
#
|
||||
#---
|
||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
expected_stdout_1 = """
|
||||
PARAM_NAME PARAM_VALUE PARAM_DEFAULT PARAM_IS_SET PARAM_SOURCE
|
||||
================================================== ================================================================ ================================================================ ============ ================================================================
|
||||
AllowEncryptedSecurityDatabase true false <true> firebird.conf
|
||||
AuditTraceConfigFile [empty] [empty] <false> <null>
|
||||
AuthClient Srp Srp256, Srp, Legacy_Auth <true> firebird.conf
|
||||
AuthServer Legacy_Auth, Srp Srp256 <true> firebird.conf
|
||||
BugcheckAbort true false <true> firebird.conf
|
||||
ClearGTTAtRetaining true false <true> databases.conf
|
||||
ClientBatchBuffer 262144 131072 <true> firebird.conf
|
||||
ConnectionIdleTimeout 99 0 <true> databases.conf
|
||||
ConnectionTimeout 123 180 <true> firebird.conf
|
||||
CpuAffinityMask 0 0 <false> <null>
|
||||
DataTypeCompatibility 3.0 <null> <true> databases.conf
|
||||
DatabaseAccess None Full <true> firebird.conf
|
||||
DatabaseGrowthIncrement 128974848 134217728 <true> databases.conf
|
||||
DeadlockTimeout 15 10 <true> firebird.conf
|
||||
DefaultDbCachePages 4321 2048 <true> databases.conf
|
||||
DefaultTimeZone -7:00 <null> <true> firebird.conf
|
||||
DummyPacketInterval 11 0 <true> firebird.conf
|
||||
EventMemSize 12321 65536 <true> firebird.conf
|
||||
ExtConnPoolLifeTime 1212 7200 <true> firebird.conf
|
||||
ExtConnPoolSize 123 0 <true> firebird.conf
|
||||
ExternalFileAccess Full None <true> databases.conf
|
||||
FileSystemCacheSize 0 0 <false> <null>
|
||||
FileSystemCacheThreshold 9223372035781033984 65536 <true> firebird.conf
|
||||
GCPolicy combined combined <false> <null>
|
||||
GuardianOption 1 1 <false> <null>
|
||||
IPv6V6Only true false <true> firebird.conf
|
||||
InlineSortThreshold 8192 1000 <true> firebird.conf
|
||||
IpcName fb4x_tmp_c6444 FirebirdIPI <true> firebird.conf
|
||||
KeyHolderPlugin [empty] [empty] <false> <null>
|
||||
LegacyHash true true <false> <null>
|
||||
LockAcquireSpins 0 0 <false> <null>
|
||||
LockHashSlots 49999 8191 <true> databases.conf
|
||||
LockMemSize 30408704 1048576 <true> databases.conf
|
||||
MaxIdentifierByteLength 31 252 <true> databases.conf
|
||||
MaxIdentifierCharLength 31 63 <true> databases.conf
|
||||
MaxUnflushedWriteTime 15 -1 <true> databases.conf
|
||||
MaxUnflushedWrites 111 -1 <true> databases.conf
|
||||
MaxUserTraceLogSize 100 10 <true> firebird.conf
|
||||
OutputRedirectionFile /dev/null /dev/null <false> <null>
|
||||
ProcessPriorityLevel 0 0 <false> <null>
|
||||
Providers Engine13, Remote Remote, Engine13, Loopback <true> databases.conf
|
||||
ReadConsistency false true <true> firebird.conf
|
||||
Redirection false false <false> <null>
|
||||
RelaxedAliasChecking false false <false> <null>
|
||||
RemoteAccess true true <true> databases.conf
|
||||
RemoteAuxPort 0 0 <false> <null>
|
||||
RemoteBindAddress <null> <null> <false> <null>
|
||||
RemoteFileOpenAbility false false <false> <null>
|
||||
RemotePipeName interbas interbas <false> <null>
|
||||
RemoteServiceName tmp_fbs_6444 gds_db <true> firebird.conf
|
||||
RemoteServicePort [MATCHES] 0 <true> firebird.conf
|
||||
SecurityDatabase tmp_6444 security4.fdb <true> databases.conf
|
||||
ServerMode SuperClassic Super <true> firebird.conf
|
||||
SnapshotsMemSize 103809024 65536 <true> databases.conf
|
||||
StatementTimeout 999 0 <true> databases.conf
|
||||
TcpLoopbackFastPath false true <true> firebird.conf
|
||||
TcpNoNagle false true <true> firebird.conf
|
||||
TcpRemoteBufferSize 5555 8192 <true> firebird.conf
|
||||
TempBlockSize 5242880 1048576 <true> firebird.conf
|
||||
TempCacheLimit 9223372035781033984 67108864 <true> databases.conf
|
||||
TempDirectories [MATCHES] <null> <true> firebird.conf
|
||||
TempTableDirectory [MATCHES] [empty] <true> databases.conf
|
||||
TipCacheBlockSize 3145728 4194304 <true> databases.conf
|
||||
TraceDSQL 0 0 <false> <null>
|
||||
TracePlugin fbtrace fbtrace <false> <null>
|
||||
UdfAccess Restrict UDF None <true> firebird.conf
|
||||
UseFileSystemCache false true <true> firebird.conf
|
||||
UserManager Legacy_UserManager, Srp Srp <true> databases.conf
|
||||
WireCompression true false <true> firebird.conf
|
||||
WireCrypt Required Required <true> firebird.conf
|
||||
WireCryptPlugin Arc4 ChaCha, Arc4 <true> firebird.conf
|
||||
|
||||
Records affected: 71
|
||||
Records affected: 0
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
@pytest.mark.platform('Linux')
|
||||
@pytest.mark.xfail
|
||||
def test_core_6444_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
||||
|
||||
# version: 4.0
|
||||
# resources: None
|
||||
|
||||
substitutions_2 = [('OutputRedirectionFile.*', ''), ('[ \t]+', ' '), ('[=]+', '')]
|
||||
|
||||
init_script_2 = """"""
|
||||
|
||||
db_2 = db_factory(sql_dialect=3, init=init_script_2)
|
||||
|
||||
# test_script_2
|
||||
#---
|
||||
#
|
||||
# import sys
|
||||
# import os
|
||||
# import shutil
|
||||
# import time
|
||||
# import datetime
|
||||
# import tempfile
|
||||
# import subprocess
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||
# global os
|
||||
#
|
||||
# file_handle.flush()
|
||||
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
# if type(f_names_list[i]) == file:
|
||||
# del_name = f_names_list[i].name
|
||||
# elif type(f_names_list[i]) == str:
|
||||
# del_name = f_names_list[i]
|
||||
# else:
|
||||
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
|
||||
# print('type(f_names_list[i])=',type(f_names_list[i]))
|
||||
# del_name = None
|
||||
#
|
||||
# if del_name and os.path.isfile( del_name ):
|
||||
# os.remove( del_name )
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def find_free_port():
|
||||
# import socket
|
||||
# from contextlib import closing
|
||||
# # AF_INET - constant represent the address (and protocol) families, used for the first argument to socket()
|
||||
# # A pair (host, port) is used for the AF_INET address family, where host is a string representing either a
|
||||
# # hostname in Internet domain notation like 'daring.cwi.nl' or an IPv4 address like '100.50.200.5', and port is an integer.
|
||||
# # SOCK_STREAM means that it is a TCP socket.
|
||||
# # SOCK_DGRAM means that it is a UDP socket.
|
||||
# with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
|
||||
# s.bind(('', 0))
|
||||
# s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
# return s.getsockname()[1]
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# svc = fdb.services.connect(host='localhost', user=user_name, password=user_password)
|
||||
# FB_HOME = svc.get_home_directory()
|
||||
# svc.close()
|
||||
#
|
||||
# fb_vers = str(db_conn.engine_version)[:1] # character for security.db file: engine = 4.0 --> '4'
|
||||
# sec_db = os.path.join( FB_HOME, 'security' + fb_vers+ '.fdb')
|
||||
#
|
||||
# db_conn.close()
|
||||
#
|
||||
# fdb_test = os.path.join(context['temp_directory'],'tmp_c6444.fdb')
|
||||
#
|
||||
# dts = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
|
||||
#
|
||||
# fbconf_cur = os.path.join(FB_HOME, 'firebird.conf')
|
||||
# fbconf_bak = os.path.join(context['temp_directory'], 'firebird_'+dts+'.bak')
|
||||
#
|
||||
# dbconf_cur = os.path.join(FB_HOME, 'databases.conf')
|
||||
# dbconf_bak = os.path.join(context['temp_directory'], 'databases_'+dts+'.bak')
|
||||
#
|
||||
# shutil.copy2( fbconf_cur, fbconf_bak )
|
||||
# shutil.copy2( dbconf_cur, dbconf_bak )
|
||||
#
|
||||
# shutil.copy2( sec_db, fdb_test )
|
||||
#
|
||||
# TEMP_DIRECTORIES_VALUE = os.path.normpath( os.path.join(FB_HOME, 'examples') )
|
||||
# TTABLE_DIRECTORY_VALUE = os.path.normpath( context['temp_directory'] )
|
||||
#
|
||||
# TMP_FREE_PORT = find_free_port()
|
||||
# #TMP_FREE_PORT = 57456
|
||||
#
|
||||
# cfg_params_to_change= {
|
||||
# 'AllowEncryptedSecurityDatabase' : 'true'
|
||||
# ,'AuthClient' : 'Srp'
|
||||
# ,'AuthServer' : 'Legacy_Auth, Srp'
|
||||
# ,'BugcheckAbort' : '1'
|
||||
# ,'ClientBatchBuffer' : '256k'
|
||||
# ,'ConnectionIdleTimeout' : '77' # will be also specified in databases.conf; effective value must be from databases.conf, NOT from here!
|
||||
# ,'ConnectionTimeout' : '123'
|
||||
# ,'DeadlockTimeout' : '15'
|
||||
# ,'DatabaseAccess' : 'None' # In order to display only ALIAS of database rather than its full name
|
||||
# ,'DefaultDbCachePages' : '1234' # will be also specified in databases.conf; effective value must be from databases.conf, NOT from here!
|
||||
# ,'DefaultTimeZone' : '-7:00'
|
||||
# ,'DummyPacketInterval' : '11'
|
||||
# ,'EventMemSize' : '12321'
|
||||
# ,'ExtConnPoolLifeTime' : '1212'
|
||||
# ,'ExtConnPoolSize' : '123'
|
||||
# ,'FileSystemCacheThreshold' : '8589934591G'
|
||||
# ,'IpcName' : 'fb4x_tmp_c6444'
|
||||
# ,'IPv6V6Only' : '1'
|
||||
# ,'InlineSortThreshold' : '8k'
|
||||
# ,'LockHashSlots' : '33333' # will be also specified in databases.conf; effective value must be from databases.conf, NOT from here!
|
||||
# ,'LockMemSize' : '17m' # will be also specified in databases.conf; effective value must be from databases.conf, NOT from here!
|
||||
# ,'MaxUserTraceLogSize' : '100'
|
||||
# ,'ReadConsistency' : '0'
|
||||
# ,'RemoteServiceName' : 'tmp_fbs_6444'
|
||||
# ,'RemoteServicePort' : str(TMP_FREE_PORT)
|
||||
# ,'ServerMode' : 'SuperClassic'
|
||||
# ,'StatementTimeout' : '777' # will be also specified in databases.conf; effective value must be from databases.conf, NOT from here!
|
||||
# ,'TcpLoopbackFastPath' : '0'
|
||||
# ,'TcpNoNagle' : 'false'
|
||||
# ,'TcpRemoteBufferSize' : '5555'
|
||||
# ,'TempBlockSize' : '5m'
|
||||
# ,'TempDirectories' : TEMP_DIRECTORIES_VALUE
|
||||
# ,'TempTableDirectory' : os.path.normpath( tempfile.gettempdir() ) # since 4.0.0.2436, 21.04.2021
|
||||
# ,'UDFaccess' : 'Restrict UDF'
|
||||
# ,'UseFileSystemCache' : 'false'
|
||||
# ,'WireCompression' : 'true'
|
||||
# ,'WireCrypt' : 'Required'
|
||||
# ,'WireCryptPlugin' : 'Arc4'
|
||||
#
|
||||
# }
|
||||
#
|
||||
# f_fbconf=open( fbconf_cur, 'w')
|
||||
# for k,v in sorted(cfg_params_to_change.items()):
|
||||
# f_fbconf.write( ''.join( (k, ' = ', v, '\\n') ) )
|
||||
# flush_and_close( f_fbconf )
|
||||
#
|
||||
# alias_data='''
|
||||
# # Added temporarily for executing test core_6444.fbt
|
||||
# tmp_6444 = %(fdb_test)s {
|
||||
#
|
||||
# SecurityDatabase = tmp_6444
|
||||
#
|
||||
# RemoteAccess = true
|
||||
# DatabaseGrowthIncrement = 123m
|
||||
# DataTypeCompatibility = 3.0
|
||||
# DefaultDbCachePages = 4321
|
||||
# ClearGTTAtRetaining = 1
|
||||
#
|
||||
# # Set number of minutes after which idle attachment will be disconnected by the engine. Zero means no timeout is set.
|
||||
# ConnectionIdleTimeout = 99
|
||||
#
|
||||
# ExternalFileAccess = Full
|
||||
#
|
||||
# LockHashSlots = 49999
|
||||
# LockMemSize = 29m
|
||||
#
|
||||
# MaxIdentifierByteLength = 31
|
||||
# MaxIdentifierCharLength = 31
|
||||
# MaxUnflushedWrites = 111
|
||||
# MaxUnflushedWriteTime = 15
|
||||
#
|
||||
# Providers = Engine13, Remote
|
||||
#
|
||||
# SnapshotsMemSize = 99m
|
||||
#
|
||||
# # Set number of seconds after which statement execution will be automatically cancelled by the engine. Zero means no timeout is set.
|
||||
# StatementTimeout = 999
|
||||
#
|
||||
# TempBlockSize = 3m
|
||||
# TempCacheLimit = 8589934591G
|
||||
#
|
||||
# ###############################
|
||||
# # Appeared since 4.0.0.2436, 21.04.2021; per-database:
|
||||
# # ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# # Directory to put data of temporary tables and blobs
|
||||
# # When empty, not exists or not accessible, default directory will be used
|
||||
# # as determined by FIREBIRD_TMP, TEMP or TMP environment variables.
|
||||
# # Per-database configurable.
|
||||
# # Type: string
|
||||
# #TempTableDirectory =
|
||||
# ###############################
|
||||
# TempTableDirectory = %(TTABLE_DIRECTORY_VALUE)s
|
||||
#
|
||||
# TipCacheBlockSize = 3m
|
||||
#
|
||||
# UserManager = Legacy_UserManager, Srp
|
||||
# }
|
||||
# ''' % locals()
|
||||
#
|
||||
# f_dbconf=open( dbconf_cur, 'w')
|
||||
# f_dbconf.write(alias_data)
|
||||
# flush_and_close( f_dbconf )
|
||||
#
|
||||
# p_tmp_fb_pid = subprocess.Popen( [ os.path.join( FB_HOME, 'firebird' ), '-a'] )
|
||||
# time.sleep(2)
|
||||
# CONN_STR = 'localhost/%(TMP_FREE_PORT)s:tmp_6444' % locals()
|
||||
#
|
||||
# sql_text='''
|
||||
# -- set echo on;
|
||||
# set wng off;
|
||||
# connect 'tmp_6444';
|
||||
# create or alter user %(user_name)s password '%(user_password)s' using plugin Srp;
|
||||
# create or alter user tmp$c6444 password '123' using plugin Srp;
|
||||
# revoke all on all from tmp$c6444;
|
||||
# create or alter view v_config as
|
||||
# select
|
||||
# g.rdb$config_name param_name
|
||||
# ,iif( trim(g.rdb$config_value)=''
|
||||
# ,'[empty]'
|
||||
# ,iif( upper(g.rdb$config_name) = upper('TempDirectories') and upper(g.rdb$config_value) = upper('%(TEMP_DIRECTORIES_VALUE)s')
|
||||
# or upper(g.rdb$config_name) = upper('TempTableDirectory') and upper(g.rdb$config_value) = upper('%(TTABLE_DIRECTORY_VALUE)s')
|
||||
# or upper(g.rdb$config_name) = upper('RemoteServicePort') and g.rdb$config_value = %(TMP_FREE_PORT)s
|
||||
# ,'[MATCHES]'
|
||||
# ,g.rdb$config_value
|
||||
# )
|
||||
# ) param_value
|
||||
# ,iif(trim(g.rdb$config_default)='', '[empty]', replace(g.rdb$config_default,'%(FB_HOME)s','') ) param_default
|
||||
# ,g.rdb$config_is_set param_is_set
|
||||
# ,g.rdb$config_source param_source
|
||||
# from rdb$config g
|
||||
# order by param_name
|
||||
# ;
|
||||
# commit;
|
||||
# grant select on v_config to tmp$c6444;
|
||||
# commit;
|
||||
#
|
||||
# connect '%(CONN_STR)s' user %(user_name)s password '%(user_password)s';
|
||||
#
|
||||
# set count on;
|
||||
# set width param_name 50;
|
||||
# set width param_value 64;
|
||||
# set width param_default 64;
|
||||
# set width param_source 64;
|
||||
#
|
||||
# select * from v_config; -- SYSDBA: must see all parameters with their effective values
|
||||
#
|
||||
# commit;
|
||||
# connect '%(CONN_STR)s' user tmp$c6444 password '123';
|
||||
#
|
||||
# select * from v_config; -- NON-PRIVILEGED user: must see 0 rows
|
||||
#
|
||||
# /*
|
||||
# -- for debug only:
|
||||
# set list on;
|
||||
# select
|
||||
# current_user as who_am_i
|
||||
# ,m.mon$database_name as db_name
|
||||
# ,m.mon$page_buffers as db_buffers
|
||||
# ,m.mon$sec_database as db_sec_name
|
||||
# ,a.mon$server_pid
|
||||
# ,a.mon$remote_protocol
|
||||
# ,a.mon$idle_timeout
|
||||
# ,a.mon$statement_timeout
|
||||
# ,a.mon$wire_compressed
|
||||
# ,a.mon$wire_encrypted
|
||||
# ,a.mon$wire_crypt_plugin
|
||||
# from mon$database m
|
||||
# cross join mon$attachments a
|
||||
# where a.mon$attachment_id = current_connection
|
||||
# ;
|
||||
# --*/
|
||||
#
|
||||
# commit;
|
||||
# connect '%(CONN_STR)s' user sysdba password 'masterkey';
|
||||
# drop user tmp$c6444 using plugin Srp;
|
||||
# commit;
|
||||
#
|
||||
# ''' % dict(globals(), **locals())
|
||||
#
|
||||
# f_sql_cmd = open( os.path.join(context['temp_directory'],'tmp_c6444.sql'), 'w')
|
||||
# f_sql_cmd.write( sql_text )
|
||||
# flush_and_close( f_sql_cmd )
|
||||
#
|
||||
# f_sql_log=open( os.path.join(context['temp_directory'],'tmp_c6444.log'), 'w')
|
||||
# f_sql_err=open( os.path.join(context['temp_directory'],'tmp_c6444.err'), 'w')
|
||||
#
|
||||
# #subprocess.call( [context['isql_path'], 'localhost/%(TMP_FREE_PORT)s:tmp_6444' % locals(), '-i', f_sql_cmd.name], stdout=f_sql_log, stderr=f_sql_err )
|
||||
# subprocess.call( [context['isql_path'], '-q', '-pag', '999999', '-i', f_sql_cmd.name, '-user', 'SYSDBA'], stdout=f_sql_log, stderr=f_sql_err )
|
||||
#
|
||||
# flush_and_close( f_sql_log )
|
||||
# flush_and_close( f_sql_err )
|
||||
#
|
||||
# if p_tmp_fb_pid:
|
||||
# p_tmp_fb_pid.terminate()
|
||||
#
|
||||
# shutil.move( fbconf_bak, fbconf_cur )
|
||||
# shutil.move( dbconf_bak, dbconf_cur )
|
||||
#
|
||||
# with open(f_sql_err.name, 'r') as f:
|
||||
# for line in f:
|
||||
# if line.split():
|
||||
# print('UNEXPECTED STDERR: ' + line)
|
||||
#
|
||||
# with open(f_sql_log.name, 'r') as f:
|
||||
# for line in f:
|
||||
# if line.split():
|
||||
# print(line)
|
||||
#
|
||||
#
|
||||
# # Cleanup
|
||||
# ##########
|
||||
# time.sleep(1)
|
||||
# cleanup( ( f_sql_log, f_sql_err, f_sql_cmd, fdb_test ) )
|
||||
#
|
||||
#
|
||||
#---
|
||||
#act_2 = python_act('db_2', test_script_2, substitutions=substitutions_2)
|
||||
|
||||
expected_stdout_2 = """
|
||||
PARAM_NAME PARAM_VALUE PARAM_DEFAULT PARAM_IS_SET PARAM_SOURCE
|
||||
================================================== ================================================================ ================================================================ ============ ================================================================
|
||||
AllowEncryptedSecurityDatabase true false <true> firebird.conf
|
||||
@ -406,6 +843,7 @@ expected_stdout_1 = """
|
||||
TempBlockSize 5242880 1048576 <true> firebird.conf
|
||||
TempCacheLimit 9223372035781033984 67108864 <true> databases.conf
|
||||
TempDirectories [MATCHES] <null> <true> firebird.conf
|
||||
TempTableDirectory [MATCHES] [empty] <true> databases.conf
|
||||
TipCacheBlockSize 3145728 4194304 <true> databases.conf
|
||||
TraceDSQL 0 0 <false> <null>
|
||||
TracePlugin fbtrace fbtrace <false> <null>
|
||||
@ -416,14 +854,14 @@ expected_stdout_1 = """
|
||||
WireCrypt Required Required <true> firebird.conf
|
||||
WireCryptPlugin Arc4 ChaCha, Arc4 <true> firebird.conf
|
||||
|
||||
Records affected: 70
|
||||
Records affected: 71
|
||||
Records affected: 0
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_6444_1(db_1):
|
||||
def test_core_6444_2(db_2):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
||||
|
||||
|
@ -19,12 +19,19 @@
|
||||
# 2. operation was cancelled
|
||||
#
|
||||
# ::: NB :::
|
||||
# subprocess.Popen() must have argument: creationflags = subprocess.CREATE_NEW_PROCESS_GROUP
|
||||
# Windows only: subprocess.Popen() must have argument: creationflags = subprocess.CREATE_NEW_PROCESS_GROUP
|
||||
# Otherwise we can not send signal Ctrl_C_EVENT to the child process.
|
||||
# Linux: parameter 'creationflags' must be 0, signal.SIGINT is used instead of Ctrl_C_EVENT.
|
||||
#
|
||||
# See: https://docs.python.org/2.7/library/subprocess.html
|
||||
#
|
||||
# Confirmed bug on 4.0.0.2307: query could NOT be interrupted and we had to wait until it completed.
|
||||
# Checked on 4.0.0.2324 (SS/CS): works OK, query can be interrupted via sending Ctrl-C signal.
|
||||
#
|
||||
# 16.04.2021. Adapted for run both on Windows and Linux. Checked on:
|
||||
# Windows: 4.0.0.2422 SS/CS
|
||||
# Linux: 4.0.0.2422 SS/CS
|
||||
#
|
||||
#
|
||||
# tracker_id: CORE-6458
|
||||
# min_versions: ['4.0']
|
||||
@ -69,7 +76,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# global datetime
|
||||
# return ''.join( (datetime.datetime.now().strftime("%H:%M:%S.%f")[:11],'.') )
|
||||
# #--------------------------------------------
|
||||
# def flush_and_close(file_handle):
|
||||
#
|
||||
# def flush_and_close( file_handle ):
|
||||
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||
# # If you're starting with a Python file object f,
|
||||
# # first do f.flush(), and
|
||||
@ -81,7 +89,9 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||
# os.fsync(file_handle.fileno())
|
||||
# file_handle.close()
|
||||
#
|
||||
# #--------------------------------------------
|
||||
#
|
||||
# def cleanup( f_names_list ):
|
||||
# global os
|
||||
# for i in range(len( f_names_list )):
|
||||
@ -94,19 +104,21 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
#
|
||||
# f_sql_cmd = open( os.path.join(context['temp_directory'],'tmp-c6458.sql'),'w')
|
||||
# f_sql_cmd.write("set list on; select count(*) as LONG_QUERY_RESULT from (select 1 i from rdb$types a,rdb$types b,rdb$types c);")
|
||||
# f_sql_cmd.close()
|
||||
# flush_and_close( f_sql_cmd )
|
||||
#
|
||||
# f_sql_log = open( os.path.splitext(f_sql_cmd.name)[0] + '.log','w')
|
||||
# f_sql_err = open( os.path.splitext(f_sql_cmd.name)[0] + '.err','w')
|
||||
#
|
||||
# try:
|
||||
# # NB: subprocess.CREATE_NEW_PROCESS_GROUP is MANDATORY FOR SENDING CTRL_C SIGNAL on Windows:
|
||||
# p_flag = 0 if platform.system() == 'Linux' else subprocess.CREATE_NEW_PROCESS_GROUP
|
||||
# p_long = subprocess.Popen( [ os.path.join(FB_BINS, 'isql'), dsn, '-q', '-i', f_sql_cmd.name]
|
||||
# ,stdout=f_sql_log
|
||||
# ,stderr=f_sql_err
|
||||
# ,creationflags = subprocess.CREATE_NEW_PROCESS_GROUP # <<< MANDATORY FOR SENDING CTRL_C SIGNAL <<<
|
||||
# ,creationflags = p_flag
|
||||
# )
|
||||
# time.sleep(1)
|
||||
# p_long.send_signal(signal.CTRL_C_EVENT)
|
||||
# p_long.send_signal( signal.SIGINT if platform.system() == 'Linux' else signal.CTRL_C_EVENT )
|
||||
# p_long.wait()
|
||||
# print('Was ISQL process terminated ? => ', p_long.poll())
|
||||
# except Exception,e:
|
||||
@ -149,7 +161,6 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
@pytest.mark.platform('Windows')
|
||||
@pytest.mark.xfail
|
||||
def test_core_6458_1(db_1):
|
||||
pytest.fail("Test not IMPLEMENTED")
|
||||
|
67
tests/bugs/test_core_6504.py
Normal file
67
tests/bugs/test_core_6504.py
Normal file
@ -0,0 +1,67 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_6504
|
||||
# title: Provide same results for date arithmetics when date is changed by values near +/-max(bigint)
|
||||
# decription:
|
||||
# Checked on 4.0.0.2437 (both on Linux and Windows).
|
||||
#
|
||||
# tracker_id:
|
||||
# min_versions: ['4.0']
|
||||
# versions: 4.0
|
||||
# qmid: None
|
||||
|
||||
import pytest
|
||||
from firebird.qa import db_factory, isql_act, Action
|
||||
|
||||
# version: 4.0
|
||||
# resources: None
|
||||
|
||||
substitutions_1 = []
|
||||
|
||||
init_script_1 = """"""
|
||||
|
||||
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
|
||||
test_script_1 = """
|
||||
set heading off;
|
||||
|
||||
-- All following statements must raise SQLSTATE = 22008.
|
||||
-- On LINUX builds before 4.0.0.2437 statements NN 5 and 6
|
||||
-- did not raise error. Instead, they issued date = 2020-02-01:
|
||||
|
||||
select 1 as chk_1, date '01.02.2020' + 9223372036854775807 from rdb$database;
|
||||
select 2 as chk_2, date '01.02.2020' + -9223372036854775807 from rdb$database;
|
||||
select 3 as chk_3, date '01.02.2020' - 9223372036854775807 from rdb$database;
|
||||
select 4 as chk_4, date '01.02.2020' - -9223372036854775807 from rdb$database;
|
||||
select 5 as chk_5, date '01.02.2020' + -9223372036854775808 from rdb$database;
|
||||
select 6 as chk_6, date '01.02.2020' - -9223372036854775808 from rdb$database;
|
||||
"""
|
||||
|
||||
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
expected_stderr_1 = """
|
||||
Statement failed, SQLSTATE = 22008
|
||||
value exceeds the range for valid dates
|
||||
|
||||
Statement failed, SQLSTATE = 22008
|
||||
value exceeds the range for valid dates
|
||||
|
||||
Statement failed, SQLSTATE = 22008
|
||||
value exceeds the range for valid dates
|
||||
|
||||
Statement failed, SQLSTATE = 22008
|
||||
value exceeds the range for valid dates
|
||||
|
||||
Statement failed, SQLSTATE = 22008
|
||||
value exceeds the range for valid dates
|
||||
|
||||
Statement failed, SQLSTATE = 22008
|
||||
value exceeds the range for valid dates
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_core_6504_1(act_1: Action):
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||
|
89
tests/bugs/test_core_6542.py
Normal file
89
tests/bugs/test_core_6542.py
Normal file
@ -0,0 +1,89 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: bugs.core_6542
|
||||
# title: Implementation of SUBSTRING for UTF8 character set is inefficient
|
||||
# decription:
|
||||
# Confirmed issues on 4.0.0.2422 and 3.0.8.33345: ratio is about 16x ... 17x.
|
||||
# Checked on 4.0.0.2425 and 3.0.8.33349: ratio is about 1.05 ... 1.07.
|
||||
# Decided to use threshold = 1.15 for check performance ratio.
|
||||
#
|
||||
# tracker_id: CORE-6542
|
||||
# min_versions: ['3.0.8']
|
||||
# versions: 3.0.8
|
||||
# qmid:
|
||||
|
||||
import pytest
|
||||
from firebird.qa import db_factory, isql_act, Action
|
||||
|
||||
# version: 3.0.8
|
||||
# resources: None
|
||||
|
||||
substitutions_1 = []
|
||||
|
||||
init_script_1 = """"""
|
||||
|
||||
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
|
||||
test_script_1 = """
|
||||
set term ^;
|
||||
execute block as
|
||||
declare str1 varchar(8000) character set unicode_fss;
|
||||
declare str2 varchar(10) character set unicode_fss;
|
||||
declare n int = 100000;
|
||||
declare t0 timestamp;
|
||||
declare t1 timestamp;
|
||||
begin
|
||||
str1 = LPAD('abcd', 8000, '--');
|
||||
t0 = 'now';
|
||||
while (n > 0) do
|
||||
begin
|
||||
str2 = SUBSTRING(str1 from 1 FOR 10);
|
||||
n = n - 1;
|
||||
end
|
||||
t1 = 'now';
|
||||
rdb$set_context('USER_SESSION', 'TIME_UFSS', datediff(millisecond from t0 to t1) );
|
||||
end
|
||||
^
|
||||
execute block as
|
||||
declare str1 varchar(8000) character set utf8;
|
||||
declare str2 varchar(10) character set utf8;
|
||||
declare n int = 100000;
|
||||
declare t0 timestamp;
|
||||
declare t1 timestamp;
|
||||
begin
|
||||
str1 = LPAD('abcd', 8000, '--');
|
||||
t0 = 'now';
|
||||
while (n > 0) do
|
||||
begin
|
||||
str2 = SUBSTRING(str1 from 1 FOR 10);
|
||||
n = n - 1;
|
||||
end
|
||||
t1 = 'now';
|
||||
rdb$set_context('USER_SESSION', 'TIME_UTF8', datediff(millisecond from t0 to t1) );
|
||||
end
|
||||
^
|
||||
set term ;^
|
||||
|
||||
set list on;
|
||||
select iif( r < threshold, 'acceptable.', 'POOR: ' || r || ' - exceeds threshold = ' || threshold) as "UTF8_substring_performance:"
|
||||
from (
|
||||
select
|
||||
1.000 * cast( rdb$get_context('USER_SESSION', 'TIME_UTF8') as int) / cast( rdb$get_context('USER_SESSION', 'TIME_UFSS') as int) as r
|
||||
,1.15 as threshold
|
||||
from rdb$database
|
||||
);
|
||||
|
||||
"""
|
||||
|
||||
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
expected_stdout_1 = """
|
||||
UTF8_substring_performance: acceptable.
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0.8')
|
||||
def test_core_6542_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_01
|
||||
# id: functional.arno.derived_tables.01
|
||||
# title: Simple derived table 1
|
||||
# decription: Test simple derived table
|
||||
# tracker_id:
|
||||
@ -61,7 +61,7 @@ expected_stdout_1 = """ ID DESCRIPTION
|
||||
9 nine"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_01_1(act_1: Action):
|
||||
def test_01_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_02
|
||||
# id: functional.arno.derived_tables.02
|
||||
# title: Simple derived table 2
|
||||
# decription: Test unnamed (no relation alias) derived table
|
||||
# tracker_id:
|
||||
@ -61,7 +61,7 @@ expected_stdout_1 = """ ID DESCRIPTION
|
||||
9 nine"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_02_1(act_1: Action):
|
||||
def test_02_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_03
|
||||
# id: functional.arno.derived_tables.03
|
||||
# title: Simple derived table 3
|
||||
# decription: Test explicit column names for derived table
|
||||
# tracker_id:
|
||||
@ -61,7 +61,7 @@ expected_stdout_1 = """ TEST_ID TEST_DESC
|
||||
9 nine"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_03_1(act_1: Action):
|
||||
def test_03_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_04
|
||||
# id: functional.arno.derived_tables.04
|
||||
# title: Simple derived table 4
|
||||
# decription: Derived table column names must be unique.
|
||||
# tracker_id:
|
||||
@ -55,7 +55,7 @@ Dynamic SQL Error
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5.0')
|
||||
def test_derived_tables_04_1(act_1: Action):
|
||||
def test_04_1(act_1: Action):
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_05
|
||||
# id: functional.arno.derived_tables.05
|
||||
# title: Simple derived table 5
|
||||
# decription: Derived table column names must be unique.
|
||||
# tracker_id:
|
||||
@ -55,7 +55,7 @@ Dynamic SQL Error
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5.0')
|
||||
def test_derived_tables_05_1(act_1: Action):
|
||||
def test_05_1(act_1: Action):
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_06
|
||||
# id: functional.arno.derived_tables.06
|
||||
# title: Derived table 6 outer reference
|
||||
# decription: Outer reference inside derived table to other relations in from clause is not allowed.
|
||||
# tracker_id:
|
||||
@ -58,7 +58,7 @@ Dynamic SQL Error
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5.0')
|
||||
def test_derived_tables_06_1(act_1: Action):
|
||||
def test_06_1(act_1: Action):
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_07
|
||||
# id: functional.arno.derived_tables.07
|
||||
# title: Derived table 7 outer reference
|
||||
# decription: Outer reference inside derived table to other relations in from clause is not allowed.
|
||||
# tracker_id:
|
||||
@ -58,7 +58,7 @@ Dynamic SQL Error
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5.0')
|
||||
def test_derived_tables_07_1(act_1: Action):
|
||||
def test_07_1(act_1: Action):
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_08
|
||||
# id: functional.arno.derived_tables.08
|
||||
# title: Derived table 8 outer reference
|
||||
# decription: Outer reference inside derived table to other relations in from clause is not allowed.
|
||||
# tracker_id:
|
||||
@ -58,7 +58,7 @@ Dynamic SQL Error
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5.0')
|
||||
def test_derived_tables_08_1(act_1: Action):
|
||||
def test_08_1(act_1: Action):
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_09
|
||||
# id: functional.arno.derived_tables.09
|
||||
# title: Derived table 9 outer reference
|
||||
# decription: Outer reference inside derived table to other relations in from clause is not allowed.
|
||||
# tracker_id:
|
||||
@ -58,7 +58,7 @@ Dynamic SQL Error
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.5.0')
|
||||
def test_derived_tables_09_1(act_1: Action):
|
||||
def test_09_1(act_1: Action):
|
||||
act_1.expected_stderr = expected_stderr_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_10
|
||||
# id: functional.arno.derived_tables.10
|
||||
# title: Derived table 10 outer reference
|
||||
# decription: Outer reference to upper scope-level is allowed. Such as fields inside derived table part of sub-query.
|
||||
# tracker_id:
|
||||
@ -63,7 +63,7 @@ expected_stdout_1 = """ ID DESCRIPTION
|
||||
9 nine"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_10_1(act_1: Action):
|
||||
def test_10_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_11
|
||||
# id: functional.arno.derived_tables.11
|
||||
# title: Derived table 11 outer reference
|
||||
# decription: Outer reference to upper scope-level is allowed. Such as fields inside derived table part of sub-query (IN-predicate).
|
||||
# tracker_id:
|
||||
@ -64,7 +64,7 @@ expected_stdout_1 = """ ID DESCRIPTION
|
||||
9 nine"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_11_1(act_1: Action):
|
||||
def test_11_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_12
|
||||
# id: functional.arno.derived_tables.12
|
||||
# title: Derived table 12 outer reference
|
||||
# decription: Outer reference to upper scope-level is allowed. Such as fields inside derived table part of sub-query (EXISTS).
|
||||
# tracker_id:
|
||||
@ -64,7 +64,7 @@ expected_stdout_1 = """ ID DESCRIPTION
|
||||
9 nine"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_12_1(act_1: Action):
|
||||
def test_12_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_13
|
||||
# id: functional.arno.derived_tables.13
|
||||
# title: Simple derived table
|
||||
# decription: Test DISTINCT inside derived table.
|
||||
# tracker_id:
|
||||
@ -60,7 +60,7 @@ two
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_13_1(act_1: Action):
|
||||
def test_13_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_14
|
||||
# id: functional.arno.derived_tables.14
|
||||
# title: Simple derived table
|
||||
# decription: Test FIRST / SKIP inside derived table.
|
||||
# tracker_id:
|
||||
@ -56,7 +56,7 @@ expected_stdout_1 = """ ID DESCRIPTION
|
||||
5 five"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_14_1(act_1: Action):
|
||||
def test_14_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_15
|
||||
# id: functional.arno.derived_tables.15
|
||||
# title: Simple derived table
|
||||
# decription: Test UNION inside derived table.
|
||||
# tracker_id:
|
||||
@ -64,7 +64,7 @@ expected_stdout_1 = """ ID DESCRIPTION
|
||||
9 nine"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_15_1(act_1: Action):
|
||||
def test_15_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_16
|
||||
# id: functional.arno.derived_tables.16
|
||||
# title: Simple derived table
|
||||
# decription: Test aggregate inside derived table.
|
||||
# tracker_id:
|
||||
@ -58,7 +58,7 @@ expected_stdout_1 = """ GROUPID ID_COUNT
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_derived_tables_16_1(act_1: Action):
|
||||
def test_16_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_17
|
||||
# id: functional.arno.derived_tables.17
|
||||
# title: Simple derived table
|
||||
# decription: Test aggregate inside derived table.
|
||||
# tracker_id:
|
||||
@ -57,7 +57,7 @@ expected_stdout_1 = """ GROUPID ID_COUNT
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_derived_tables_17_1(act_1: Action):
|
||||
def test_17_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_18
|
||||
# id: functional.arno.derived_tables.18
|
||||
# title: Simple derived table
|
||||
# decription: Test aggregate inside derived table.
|
||||
# tracker_id:
|
||||
@ -58,7 +58,7 @@ expected_stdout_1 = """ GROUPID ID_COUNT
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_derived_tables_18_1(act_1: Action):
|
||||
def test_18_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_19
|
||||
# id: functional.arno.derived_tables.19
|
||||
# title: Simple derived table
|
||||
# decription: Test sub-select inside derived table.
|
||||
# tracker_id:
|
||||
@ -62,7 +62,7 @@ expected_stdout_1 = """ ID GROUPID1 GROUPID2
|
||||
9 3 3"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_19_1(act_1: Action):
|
||||
def test_19_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_20
|
||||
# id: functional.arno.derived_tables.20
|
||||
# title: Simple derived table
|
||||
# decription: Test sub-select inside derived table.
|
||||
# tracker_id:
|
||||
@ -63,7 +63,7 @@ expected_stdout_1 = """ GROUPID MIN_ID MAX_ID
|
||||
3 6 9"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_20_1(act_1: Action):
|
||||
def test_20_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_21
|
||||
# id: functional.arno.derived_tables.21
|
||||
# title: Implicit derived table by IN predicate
|
||||
# decription: IN predicate uses derived table internally and should ignore column-name checks (Aggregate functions are unnamed by default).
|
||||
# tracker_id:
|
||||
@ -54,7 +54,7 @@ expected_stdout_1 = """ ID DESCRIPTION
|
||||
9 nine"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_21_1(act_1: Action):
|
||||
def test_21_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.derived_tables.derived_tables_22
|
||||
# id: functional.arno.derived_tables.22
|
||||
# title: Derived table outer reference (triggers)
|
||||
# decription: NEW/OLD context variables should be available inside the derived table.
|
||||
# tracker_id:
|
||||
@ -86,7 +86,7 @@ expected_stdout_1 = """ ID DESCRIPTION
|
||||
8 Yellow 4"""
|
||||
|
||||
@pytest.mark.version('>=2.0')
|
||||
def test_derived_tables_22_1(act_1: Action):
|
||||
def test_22_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.lower_bound_asc_02_segments_01
|
||||
# id: functional.arno.indices.lower_bound_asc_02_segments_01
|
||||
# title: ASC 2-segment index lower bound
|
||||
# decription: Check if all 5 values are fetched with "equals" operator over first segment and "greater than or equal" operator on second segment.
|
||||
# 2 values are bound to the upper segments and 1 value is bound to the lower segment.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.lower_bound_desc_02_segments_01
|
||||
# id: functional.arno.indices.lower_bound_desc_02_segments_01
|
||||
# title: DESC 2-segment index lower bound
|
||||
# decription: Check if all 5 values are fetched with "equals" operator over first segment and "lower than or equal" operator on second segment.
|
||||
# 2 values are bound to the lower segments and 1 value is bound to the upper segment.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.starting_with_01
|
||||
# id: functional.arno.indices.starting_with_01
|
||||
# title: STARTING WITH charset NONE
|
||||
# decription: STARTING WITH - Select from table with 2 entries
|
||||
#
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.starting_with_02
|
||||
# id: functional.arno.indices.starting_with_02
|
||||
# title: STARTING WITH charset ISO8859_1
|
||||
# decription: STARTING WITH - Select from table with 2 entries
|
||||
#
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.timestamps_01
|
||||
# id: functional.arno.indices.timestamps_01
|
||||
# title: TIMESTAMP in index with values below julian date
|
||||
# decription: Datetime values below the julian date (firebird base date '1858-11-17') should be stored in correct order.
|
||||
# tracker_id:
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.upper_bound_asc_01_segments_01
|
||||
# id: functional.arno.indices.upper_bound_asc_01_segments_01
|
||||
# title: ASC single index upper bound
|
||||
# decription: Check if all 15 values are fetched with "lower than or equal" operator.
|
||||
# tracker_id:
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.upper_bound_asc_01_segments_02
|
||||
# id: functional.arno.indices.upper_bound_asc_01_segments_02
|
||||
# title: ASC single index upper bound
|
||||
# decription: Check if all 32 values are fetched with "lower than" operator.
|
||||
# tracker_id:
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.upper_bound_asc_01_segments_03
|
||||
# id: functional.arno.indices.upper_bound_asc_01_segments_03
|
||||
# title: ASC single index upper bound
|
||||
# decription: Check if all 5 values are fetched with "lower than or equal" operator.
|
||||
# tracker_id:
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.upper_bound_asc_01_segments_04
|
||||
# id: functional.arno.indices.upper_bound_asc_01_segments_04
|
||||
# title: ASC single index upper bound
|
||||
# decription: Check if all 5 values are fetched with "lower than or equal" operator.
|
||||
# tracker_id:
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.upper_bound_asc_02_segments_01
|
||||
# id: functional.arno.indices.upper_bound_asc_02_segments_01
|
||||
# title: ASC 2-segment index upper bound
|
||||
# decription: Check if all 5 values are fetched with "equals" operator over first segment and "lower than or equal" operator on second segment.
|
||||
# 2 values are bound to the upper segments and 1 value is bound to the lower segments.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.upper_bound_desc_01_segments_01
|
||||
# id: functional.arno.indices.upper_bound_desc_01_segments_01
|
||||
# title: DESC single index upper bound
|
||||
# decription: Check if all 15 values are fetched with "greater than or equal" operator.
|
||||
# tracker_id:
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.upper_bound_desc_01_segments_02
|
||||
# id: functional.arno.indices.upper_bound_desc_01_segments_02
|
||||
# title: DESC single index upper bound
|
||||
# decription: Check if all 15 values are fetched with "greater than" operator.
|
||||
# tracker_id:
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.arno.indexes.upper_bound_desc_02_segments_01
|
||||
# id: functional.arno.indices.upper_bound_desc_02_segments_01
|
||||
# title: DESC 2-segment index upper bound
|
||||
# decription: Check if all 5 values are fetched with "equals" operator over first segment and "greater than or equal" operator on second segment.
|
||||
# 2 values are bound to the upper segments and 1 value is bound to the lower segment.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_02
|
||||
# id: functional.basic.db.02
|
||||
# title: Empty DB - RDB$CHARACTER_SETS
|
||||
# decription: Check the correct content of RDB$CHARACTER_SETS for empty database
|
||||
# tracker_id:
|
||||
@ -659,7 +659,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_db_02_1(act_1: Action):
|
||||
def test_02_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_03
|
||||
# id: functional.basic.db.03
|
||||
# title: Empty DB - RDB$COLLATIONS
|
||||
# decription: Check the correct content of RDB$COLLATIONS on empty DB.
|
||||
# tracker_id:
|
||||
@ -1836,7 +1836,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_db_03_1(act_1: Action):
|
||||
def test_03_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_07
|
||||
# id: functional.basic.db.07
|
||||
# title: Empty DB - RDB$FIELDS
|
||||
# decription:
|
||||
# Check for correct content of RDB$FIELDS in empty database.
|
||||
@ -4702,7 +4702,7 @@ Records affected: 150
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_db_07_1(act_1: Action):
|
||||
def test_07_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -10019,7 +10019,7 @@ Records affected: 170
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_db_07_2(act_2: Action):
|
||||
def test_07_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
@ -1,18 +1,18 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_11
|
||||
# title: New DB - RDB$FUNCTIONS
|
||||
# id: functional.basic.db.11
|
||||
# title: New DB - RDB$FUNCTION_ARGUMENTS
|
||||
# decription:
|
||||
# Check for correct content of RDB$FUNCTIONS in a new database.
|
||||
# Check for correct content of RDB$FUNCTION_ARGUMENTS in a new database.
|
||||
# Checked on:
|
||||
# 2.5.9.27126: OK, 1.734s.
|
||||
# 3.0.5.33086: OK, 1.250s.
|
||||
# 4.0.0.1378: OK, 5.422s.
|
||||
# 2.5.9.27126: OK, 0.656s.
|
||||
# 3.0.5.33086: OK, 1.156s.
|
||||
# 4.0.0.1378: OK, 5.344s.
|
||||
#
|
||||
# tracker_id:
|
||||
# min_versions: []
|
||||
# versions: 3.0, 4.0
|
||||
# qmid: functional.basic.db.db_12
|
||||
# qmid: functional.basic.db.db_11
|
||||
|
||||
import pytest
|
||||
from firebird.qa import db_factory, isql_act, Action
|
||||
@ -30,8 +30,8 @@ test_script_1 = """
|
||||
set list on;
|
||||
set count on;
|
||||
select *
|
||||
from rdb$functions rf
|
||||
order by rdb$engine_name, rf.rdb$package_name, rf.rdb$function_name, rdb$module_name, rdb$entrypoint;
|
||||
from rdb$function_arguments fa
|
||||
order by fa.rdb$function_name, fa.rdb$argument_position;
|
||||
"""
|
||||
|
||||
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
@ -41,7 +41,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_db_11_1(act_1: Action):
|
||||
def test_11_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -59,40 +59,41 @@ test_script_2 = """
|
||||
set list on;
|
||||
set count on;
|
||||
select *
|
||||
from rdb$functions rf
|
||||
order by rdb$engine_name, rf.rdb$package_name, rf.rdb$function_name, rdb$module_name, rdb$entrypoint;
|
||||
from rdb$function_arguments fa
|
||||
order by fa.rdb$function_name, fa.rdb$argument_position;
|
||||
"""
|
||||
|
||||
act_2 = isql_act('db_2', test_script_2, substitutions=substitutions_2)
|
||||
|
||||
expected_stdout_2 = """
|
||||
RDB$FUNCTION_NAME DATABASE_VERSION
|
||||
RDB$FUNCTION_TYPE <null>
|
||||
RDB$QUERY_NAME <null>
|
||||
RDB$DESCRIPTION <null>
|
||||
RDB$MODULE_NAME <null>
|
||||
RDB$ENTRYPOINT <null>
|
||||
RDB$RETURN_ARGUMENT 0
|
||||
RDB$SYSTEM_FLAG 1
|
||||
RDB$ENGINE_NAME SYSTEM
|
||||
RDB$ARGUMENT_POSITION 0
|
||||
RDB$MECHANISM <null>
|
||||
RDB$FIELD_TYPE <null>
|
||||
RDB$FIELD_SCALE <null>
|
||||
RDB$FIELD_LENGTH <null>
|
||||
RDB$FIELD_SUB_TYPE <null>
|
||||
RDB$CHARACTER_SET_ID <null>
|
||||
RDB$FIELD_PRECISION <null>
|
||||
RDB$CHARACTER_LENGTH <null>
|
||||
RDB$PACKAGE_NAME RDB$TIME_ZONE_UTIL
|
||||
RDB$PRIVATE_FLAG 0
|
||||
RDB$FUNCTION_SOURCE <null>
|
||||
RDB$FUNCTION_ID 1
|
||||
RDB$FUNCTION_BLR <null>
|
||||
RDB$VALID_BLR 1
|
||||
RDB$DEBUG_INFO <null>
|
||||
RDB$SECURITY_CLASS <null>
|
||||
RDB$OWNER_NAME SYSDBA
|
||||
RDB$LEGACY_FLAG <null>
|
||||
RDB$DETERMINISTIC_FLAG <null>
|
||||
RDB$SQL_SECURITY <null>
|
||||
RDB$ARGUMENT_NAME <null>
|
||||
RDB$FIELD_SOURCE RDB$DBTZ_VERSION
|
||||
RDB$DEFAULT_VALUE <null>
|
||||
RDB$DEFAULT_SOURCE <null>
|
||||
RDB$COLLATION_ID <null>
|
||||
RDB$NULL_FLAG 1
|
||||
RDB$ARGUMENT_MECHANISM <null>
|
||||
RDB$FIELD_NAME <null>
|
||||
RDB$RELATION_NAME <null>
|
||||
RDB$SYSTEM_FLAG 1
|
||||
RDB$DESCRIPTION <null>
|
||||
|
||||
Records affected: 1
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_db_11_2(act_2: Action):
|
||||
def test_11_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
99
tests/functional/basic/db/test_12.py
Normal file
99
tests/functional/basic/db/test_12.py
Normal file
@ -0,0 +1,99 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.12
|
||||
# title: New DB - RDB$FUNCTIONS
|
||||
# decription:
|
||||
# Check for correct content of RDB$FUNCTIONS in a new database.
|
||||
# Checked on:
|
||||
# 2.5.9.27126: OK, 1.734s.
|
||||
# 3.0.5.33086: OK, 1.250s.
|
||||
# 4.0.0.1378: OK, 5.422s.
|
||||
#
|
||||
# tracker_id:
|
||||
# min_versions: []
|
||||
# versions: 3.0, 4.0
|
||||
# qmid: functional.basic.db.db_12
|
||||
|
||||
import pytest
|
||||
from firebird.qa import db_factory, isql_act, Action
|
||||
|
||||
# version: 3.0
|
||||
# resources: None
|
||||
|
||||
substitutions_1 = []
|
||||
|
||||
init_script_1 = """"""
|
||||
|
||||
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||
|
||||
test_script_1 = """
|
||||
set list on;
|
||||
set count on;
|
||||
select *
|
||||
from rdb$functions rf
|
||||
order by rdb$engine_name, rf.rdb$package_name, rf.rdb$function_name, rdb$module_name, rdb$entrypoint;
|
||||
"""
|
||||
|
||||
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||
|
||||
expected_stdout_1 = """
|
||||
Records affected: 0
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_12_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
||||
# version: 4.0
|
||||
# resources: None
|
||||
|
||||
substitutions_2 = []
|
||||
|
||||
init_script_2 = """"""
|
||||
|
||||
db_2 = db_factory(sql_dialect=3, init=init_script_2)
|
||||
|
||||
test_script_2 = """
|
||||
set list on;
|
||||
set count on;
|
||||
select *
|
||||
from rdb$functions rf
|
||||
order by rdb$engine_name, rf.rdb$package_name, rf.rdb$function_name, rdb$module_name, rdb$entrypoint;
|
||||
"""
|
||||
|
||||
act_2 = isql_act('db_2', test_script_2, substitutions=substitutions_2)
|
||||
|
||||
expected_stdout_2 = """
|
||||
RDB$FUNCTION_NAME DATABASE_VERSION
|
||||
RDB$FUNCTION_TYPE <null>
|
||||
RDB$QUERY_NAME <null>
|
||||
RDB$DESCRIPTION <null>
|
||||
RDB$MODULE_NAME <null>
|
||||
RDB$ENTRYPOINT <null>
|
||||
RDB$RETURN_ARGUMENT 0
|
||||
RDB$SYSTEM_FLAG 1
|
||||
RDB$ENGINE_NAME SYSTEM
|
||||
RDB$PACKAGE_NAME RDB$TIME_ZONE_UTIL
|
||||
RDB$PRIVATE_FLAG 0
|
||||
RDB$FUNCTION_SOURCE <null>
|
||||
RDB$FUNCTION_ID 1
|
||||
RDB$FUNCTION_BLR <null>
|
||||
RDB$VALID_BLR 1
|
||||
RDB$DEBUG_INFO <null>
|
||||
RDB$SECURITY_CLASS <null>
|
||||
RDB$OWNER_NAME SYSDBA
|
||||
RDB$LEGACY_FLAG <null>
|
||||
RDB$DETERMINISTIC_FLAG <null>
|
||||
RDB$SQL_SECURITY <null>
|
||||
|
||||
Records affected: 1
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_12_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_13
|
||||
# id: functional.basic.db.13
|
||||
# title: Empty DB - RDB$GENERATORS
|
||||
# decription: Check for correct content of RDB$GENERATORS in empty database;
|
||||
# tracker_id:
|
||||
@ -165,7 +165,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0')
|
||||
def test_db_13_1(act_1: Action):
|
||||
def test_13_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_15
|
||||
# id: functional.basic.db.15
|
||||
# title: Empty DB - RDB$INDEX_SEGMENTS
|
||||
# decription:
|
||||
# Check for correct content of RDB$INDEX_SEGMENTS in empty database.
|
||||
@ -377,7 +377,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_db_15_1(act_1: Action):
|
||||
def test_15_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -776,7 +776,7 @@ expected_stdout_2 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_db_15_2(act_2: Action):
|
||||
def test_15_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_16
|
||||
# id: functional.basic.db.16
|
||||
# title: Empty DB - RDB$INDICES
|
||||
# decription:
|
||||
# Check for correct content of RDB$INDICES in empty database.
|
||||
@ -839,7 +839,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_db_16_1(act_1: Action):
|
||||
def test_16_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -1712,7 +1712,7 @@ expected_stdout_2 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_db_16_2(act_2: Action):
|
||||
def test_16_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_18
|
||||
# id: functional.basic.db.18
|
||||
# title: Empty DB - RDB$PAGES
|
||||
# decription: Check for correct content of RDB$PAGES in empty database.
|
||||
#
|
||||
@ -354,7 +354,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_db_18_1(act_1: Action):
|
||||
def test_18_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -717,7 +717,7 @@ expected_stdout_2 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_db_18_2(act_2: Action):
|
||||
def test_18_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_22
|
||||
# id: functional.basic.db.22
|
||||
# title: Empty DB - RDB$RELATION_CONSTRAINTS
|
||||
# decription: Check for correct content of RDB$RELATION_CONSTRAINTS in empty database.
|
||||
# tracker_id:
|
||||
@ -223,7 +223,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_db_22_1(act_1: Action):
|
||||
def test_22_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -463,7 +463,7 @@ expected_stdout_2 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_db_22_2(act_2: Action):
|
||||
def test_22_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_23
|
||||
# id: functional.basic.db.23
|
||||
# title: Empty DB - RDB$RELATIONS
|
||||
# decription: Check for correct content of RDB$RELATIONS in empty database.
|
||||
# tracker_id:
|
||||
@ -1176,7 +1176,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_db_23_1(act_1: Action):
|
||||
def test_23_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -2416,7 +2416,7 @@ expected_stdout_2 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_db_23_2(act_2: Action):
|
||||
def test_23_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_24
|
||||
# id: functional.basic.db.24
|
||||
# title: Empty DB - RDB$RELATION_FIELDS
|
||||
# decription: Check for correct content of RDB$RELATION_FIELDS in empty database.
|
||||
# tracker_id:
|
||||
@ -10113,7 +10113,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_db_24_1(act_1: Action):
|
||||
def test_24_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -21037,7 +21037,7 @@ expected_stdout_2 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_db_24_2(act_2: Action):
|
||||
def test_24_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_26
|
||||
# id: functional.basic.db.26
|
||||
# title: Empty DB - RDB$SECURITY_CLASSES
|
||||
# decription: Check for correct content of RDB$SECURITY_CLASSES in empty database.
|
||||
# tracker_id:
|
||||
@ -3849,7 +3849,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_db_26_1(act_1: Action):
|
||||
def test_26_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -7927,7 +7927,7 @@ expected_stdout_2 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_db_26_2(act_2: Action):
|
||||
def test_26_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding:utf-8
|
||||
#
|
||||
# id: functional.basic.db.db_29
|
||||
# id: functional.basic.db.29
|
||||
# title: Empty DB - RDB$TRIGGERS
|
||||
# decription:
|
||||
# Verify content of RDB$TRIGGERS in empty database.
|
||||
@ -2397,7 +2397,7 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=3.0,<4.0')
|
||||
def test_db_29_1(act_1: Action):
|
||||
def test_29_1(act_1: Action):
|
||||
act_1.expected_stdout = expected_stdout_1
|
||||
act_1.execute()
|
||||
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||
@ -4486,7 +4486,7 @@ expected_stdout_2 = """
|
||||
"""
|
||||
|
||||
@pytest.mark.version('>=4.0')
|
||||
def test_db_29_2(act_2: Action):
|
||||
def test_29_2(act_2: Action):
|
||||
act_2.expected_stdout = expected_stdout_2
|
||||
act_2.execute()
|
||||
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user