6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 13:33:07 +01:00

More python tests

This commit is contained in:
Pavel Císař 2021-12-10 19:50:31 +01:00
parent f6294a3afe
commit 560873a3f0
38 changed files with 2280 additions and 1174 deletions

BIN
files/core_5965.zip Normal file

Binary file not shown.

Binary file not shown.

BIN
files/core_6028_25.zip Normal file

Binary file not shown.

386
files/core_6078.sql Normal file
View File

@ -0,0 +1,386 @@
-- connect '%(dsn)s' user %(user_name)s password '%(user_password)s';
set list on;
set count on;
set term ^;
execute block as
begin
begin
execute statement 'drop domain dm_test';
when any do begin end
end
end
^
set term ;^
commit;
-- ALTER statement will try to change its NOT_NULL state:
create domain dm_test as int;
commit;
recreate table test( uid char(16) character set octets, x int, y int, constraint test_unq unique(uid) );
commit;
comment on table test is 'This is table TEST. And no one allowed to alter it!.';
commit;
create descending index test_uid on test(uid); -- ALTER statement will try to change its state to INACTIVE
commit;
set term ^;
create or alter trigger test_bi for test active before insert position 0 as
begin
new.uid = gen_uuid();
end
^
set term ;^
commit;
alter user tmp$c6078_0 using plugin Srp revoke admin role; -- Unprivileged user
-- create or alter user tmp$c6078_0 password '123' using plugin Srp revoke admin role; -- Unprivileged user
-- create or alter user tmp$c6078_1 password '123' using plugin Srp;
-- create or alter user tmp$c6078_2 password '456' using plugin Srp;
-- commit;
create or alter mapping local_map_c6078 using plugin srp from user tmp$c6078_1 to user ltost;
create or alter global mapping global_map_c6078 using plugin srp from user tmp$c6078_2 to user gtost;
commit;
connect '%(dsn)s' user tmp$c6078_0 password '123';
commit;
-- ######################################################################################################
-- ### F o l l o w i n g i s d o n e b y n o n - p r i v i l e g e d u s e r ###
-- ######################################################################################################
-- 29.01.2020. Attempt to alter another non-privileged USER.
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- modify record error
-- -no permission for UPDATE access to COLUMN PLG$SRP_VIEW.PLG$ACTIVE
-- (FB 4.0.0 only): -Effective user is TMP$C6078_0
alter user tmp$c6078_1 inactive using plugin Srp;
commit;
-- 29.01.2020. Attempt to alter THE WHOLE DATABASE.
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -ALTER DATABASE failed
-- -no permission for ALTER access to DATABASE
alter database set linger to 31;
commit;
----------------------------------------------------------------
-- 29.01.2020. Attempt to alter DOMAIN.
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -ALTER DOMAIN DM_TEST failed
-- -no permission for ALTER access to DOMAIN DM_TEST
-- (FB 4.0.0 only): -Effective user is TMP$C6078_0
alter domain dm_test set not null;
commit;
----------------------------------------------------------------
-- 29.01.2020. Attempt to alter table DROP constraint.
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -ALTER TABLE TEST failed
-- -no permission for ALTER access to TABLE TEST
-- (FB 4.0.0 only): -Effective user is TMP$C6078_0
alter table test drop constraint test_unq;
----------------------------------------------------------------
-- 29.01.2020. Attempt to alter table alter column.
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -ALTER TABLE TEST failed
-- -no permission for ALTER access to TABLE TEST
-- (FB 4.0.0 only): -Effective user is TMP$C6078_0
alter table test alter x type bigint;
----------------------------------------------------------------
-- 29.01.2020. Attempt to alter INDEX: make it inactive.
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -ALTER INDEX TEST_UID failed
-- -no permission for ALTER access to TABLE TEST
-- -Effective user is TMP$C6078_0
alter index test_uid inactive;
----------------------------------------------------------------
-- 29.01.2020. Attempt to change existing COMMENT to the table TEST (make it NULL).
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -COMMENT ON TEST failed
-- -no permission for ALTER access to TABLE TEST
-- (FB 4.0.0): -Effective user is TMP$C6078_0
comment on table test is null;
----------------------------------------------------------------
-- Attempt to alter TRIGGER on existing table (CREATED BY SYSDBA)
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -CREATE OR ALTER TRIGGER TEST_BI failed
-- -no permission for ALTER access to TABLE TEST
-- (FB 4.0.0 only): -Effective user is TMP$C6078_0
set term ^;
create or alter trigger test_bi for test active before insert position 0 as
begin
new.uid = 'QWE';
end
^
set term ;^
commit;
----------------------------------------------------------------
-- Attempt to create/alter TRIGGER on DB-level event:
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -CREATE OR ALTER TRIGGER TRG$START failed
-- -no permission for ALTER access to DATABASE
set term ^;
create or alter trigger trg$start
inactive on transaction start position 0
as
begin
rdb$set_context('USER_SESSION', 'TRANS_ID', current_transaction);
end
^
set term ;^
----------------------------------------------------------------
-- Attempt to alter TRIGGER for DDL event:
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -CREATE OR ALTER TRIGGER TRIG_DDL_SP failed
-- -no permission for ALTER access to DATABASE
set term ^;
create or alter trigger trig_ddl_sp before create procedure as
begin
end
^
set term ;^
-- Check that there is still ONE trigger that was created at the start ofthis script (by SYSDBA) and it has unchanged body:
-- Expected:
-- RDB$TRIGGER_NAME TEST_BI
-- RDB$TRIGGER_SOURCE c:3cc
-- as
-- begin
-- new.uid = gen_uuid();
-- end
-- Records affected: 1
select t.rdb$trigger_name altered_trigger_name, t.rdb$trigger_source altered_trigger_source
from rdb$database r
left join rdb$triggers t on t.rdb$system_flag is distinct from 1;
---------------------------------------------------------------
-- Attempt to alter PACKAGE header.
-- Expected:
-- Statement failed, SQLSTATE = 42000
-- unsuccessful metadata update
-- -CREATE OR ALTER PACKAGE PKG_TEST failed
-- -No permission for CREATE PACKAGE operation
set term ^ ;
create or alter package pkg_test -- error did raise, but packages still WAS created.
as
begin
function f_test_inside_pkg
returns smallint;
end
^
set term ;^
---------------------------------------------------------------
-- Attempt to alter PACKAGE body.
-- Expected:
-- Statement failed, SQLSTATE = 42000
-- unsuccessful metadata update
-- -RECREATE PACKAGE BODY PKG_TEST failed
-- -No permission for CREATE PACKAGE operation
set term ^;
recreate package body PKG_TEST
as
begin
function f_test_inside_pkg
returns smallint
as
begin
return 1;
end
end
^
set term ;^
commit;
-- Check that no packages did appear in the database.
-- Expected:
-- RDB$PACKAGE_NAME <null>
-- Records affected: 1
select p.rdb$package_name as altered_pkg_name
from rdb$database r
left join rdb$packages p on p.rdb$system_flag is distinct from 1;
commit;
---------------------------------------------------------------
-- Attempt to alter standalone PSQL function
set term ^;
create or alter function fn_c6078 returns int as -- error did raise, but function still WAS created.
begin
return 123987;
end
^
set term ^;
commit;
-- Expected:
-- RDB$FUNCTION_NAME <null>
-- Records affected: 1
select f.rdb$function_name as altered_standalone_func from rdb$database r left join rdb$functions f on f.rdb$system_flag is distinct from 1 and f.RDB$PACKAGE_NAME is null;
commit;
---------------------------------------------------------------
-- Attempt to alter standalone procedure
set term ^;
create or alter procedure sp_c6078 returns(whoami varchar(32)) as
begin
whoami = current_user;
suspend;
end
^
set term ;^
commit;
-- Expected:
-- RDB$PROCEDURE_NAME <null>
-- Records affected: 1
select p.rdb$procedure_name as altered_standalone_proc from rdb$database r left join rdb$procedures p on p.rdb$system_flag is distinct from 1;
---------------------------------------------------------------
-- Attempt to alter view
create or alter view v_c6078 as select * from rdb$database; -- NO error at all, view WAS created.
commit;
-- Expected
-- RDB$RELATION_NAME <null>
-- Records affected: 1
select v.rdb$relation_name as altered_view_name from rdb$database r left join rdb$relations v on v.rdb$system_flag is distinct from 1 and v.rdb$relation_name = upper('v_c6078');
commit;
---------------------------------------------------------------
-- Attempt to alter sequence
create or alter sequence sq_c6078 start with 192837465;
commit;
-- Expected:
-- RDB$GENERATOR_NAME <null>
-- Records affected: 1
select g.rdb$generator_name as altered_sequence_name from rdb$database r left join rdb$generators g on g.rdb$system_flag is distinct from 1;
commit;
---------------------------------------------------------------
-- Attempt to alter exception
--create or alter exception ex_c6078 'Something wrong.'; -- here no error, even for 1st run of this statement!
create or alter exception ex_c6078 'Something wrong.';
commit;
-- Expected
-- RDB$EXCEPTION_NAME <null>
-- Records affected: 1
select x.rdb$exception_name as altered_exception_name from rdb$database r left join rdb$exceptions x on x.rdb$system_flag is distinct from 1;
commit;
---------------------------------------------------------------
-- Attempt to alter UDR-base function:
-- before fix there was NO error here and UDR-based funtion WAS created
create or alter function wait_event (
event_name varchar(31) character set utf8 not null
) returns integer not null
external name 'udrcpp_example!wait_event'
engine udr;
commit;
-- Expected:
-- RDB$FUNCTION_NAME <null>
-- Records affected: 1
select f.rdb$function_name as altered_UDR_based_func from rdb$database r left join rdb$functions f on f.rdb$system_flag is distinct from 1 and f.rdb$engine_name = upper('udr');
commit;
---------------------------------------------------------------
-- 29.01.2020. Attempt to alter character set.
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -ALTER CHARACTER SET UTF8 failed
-- -no permission for ALTER access to CHARACTER SET UTF8
-- (FB 4.0.0 only): -Effective user is TMP$C6078_0
ALTER CHARACTER SET UTF8 SET DEFAULT COLLATION UNICODE_CI_AI;
---------------------------------------------------------------
-- 29.01.2020. Attempt to alter LOCAL MAPPING.
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -ALTER MAPPING LOCAL_MAP_C6078 failed
-- -Unable to perform operation
-- 4.0.0: -System privilege CHANGE_MAPPING_RULES is missing
-- 3.0.x: -Unable to perform operation. You must be either SYSDBA or owner of the database
alter mapping local_map_c6078 using plugin srp from user tmp$c6078_1 to user ltost_2;
---------------------------------------------------------------
-- 29.01.2020. Attempt to alter GLOBAL MAPPING.
-- Expected:
-- Statement failed, SQLSTATE = 28000
-- unsuccessful metadata update
-- -ALTER MAPPING GLOBAL_MAP_C6078 failed
-- -Unable to perform operation
-- (FB 4.0.0): -System privilege CHANGE_MAPPING_RULES is missing
-- (FB 3.0.x): -Unable to perform operation. You must be either SYSDBA or owner of the database
alter global mapping global_map_c6078 using plugin srp from user tmp$c6078_2 to user gtost_2;
commit;
-- cleanup:
-- ########
connect '%(dsn)s' user %(user_name)s password '%(user_password)s';
drop global mapping global_map_c6078;
drop mapping local_map_c6078;
commit;
-- drop user tmp$c6078_0 using plugin Srp;
-- drop user tmp$c6078_1 using plugin Srp;
-- drop user tmp$c6078_2 using plugin Srp;
-- commit;

View File

@ -11,7 +11,7 @@
import pytest
from firebird.qa import db_factory, python_act, Action
from firebird.driver import TPB, Isolation
from firebird.driver import tpb, Isolation
# version: 2.5
# resources: None
@ -86,20 +86,20 @@ def test_1(act_1: Action):
exit;
end
'''
tpb = TPB(isolation=Isolation.CONCURRENCY).get_buffer()
custom_tpb = tpb(isolation=Isolation.CONCURRENCY)
with act_1.db.connect() as con1, act_1.db.connect() as con2:
con1.begin(tpb)
con1.begin(custom_tpb)
cur1 = con1.cursor()
cur2 = con2.cursor()
cur1.execute(stm1)
con1.commit()
con2.begin(tpb)
con2.begin(custom_tpb)
cur2.execute(stm2)
con2.commit()
con1.begin(tpb)
con1.begin(custom_tpb)
cur1.execute(stm1)
con1.commit()

View File

@ -20,7 +20,7 @@
import pytest
from firebird.qa import db_factory, python_act, Action
from firebird.driver import TPB, TraAccessMode, Isolation
from firebird.driver import tpb, TraAccessMode, Isolation
# version: 2.5.7
# resources: None
@ -156,9 +156,9 @@ act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=2.5.7')
def test_1(act_1: Action):
with act_1.db.connect() as con:
txparam_read = TPB(isolation=Isolation.READ_COMMITTED_RECORD_VERSION, lock_timeout=0,
access_mode=TraAccessMode.READ).get_buffer()
txparam_write = TPB(isolation=Isolation.READ_COMMITTED_RECORD_VERSION, lock_timeout=0).get_buffer()
txparam_read = tpb(isolation=Isolation.READ_COMMITTED_RECORD_VERSION, lock_timeout=0,
access_mode=TraAccessMode.READ)
txparam_write = tpb(isolation=Isolation.READ_COMMITTED_RECORD_VERSION, lock_timeout=0)
tx_read = con.transaction_manager(txparam_read)
cur_read = tx_read.cursor()

View File

@ -24,6 +24,7 @@
import pytest
from firebird.qa import db_factory, python_act, Action
from firebird.driver import tpb, Isolation
# version: 3.0
# resources: None
@ -92,10 +93,11 @@ act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=3.0')
def test_1(act_1: Action):
with act_1.db.connect() as con_1:
c_1 = con_1.cursor()
c_1.execute('select * from sec$users')
with act_1.db.connect() as con_2:
custom_tpb = tpb(isolation=Isolation.READ_COMMITTED_RECORD_VERSION, lock_timeout=0)
#
with act_1.db.connect() as con1:
trn1 = con1.transaction_manager(custom_tpb)
cur1 = trn1.cursor()
cur1.execute('select sec$user_name from sec$users')
with act_1.db.connect() as con2:
pass # Connect should not raise an exception

View File

@ -12,7 +12,7 @@
import pytest
from firebird.qa import db_factory, python_act, Action
from firebird.driver import TPB, Isolation
from firebird.driver import tpb, Isolation
# version: 3.0.6
# resources: None
@ -227,7 +227,7 @@ def test_1(act_1: Action, capsys):
"""
act_1.isql(switches=[], input=ddl_script)
#
tpb = TPB(isolation=Isolation.READ_COMMITTED_NO_RECORD_VERSION, lock_timeout=0).get_buffer()
custom_tpb = tpb(isolation=Isolation.READ_COMMITTED_NO_RECORD_VERSION, lock_timeout=0)
with act_1.db.connect() as con:
cur1 = con.cursor()
cur1.execute('select x from sp_test(21)').fetchall()
@ -239,7 +239,7 @@ def test_1(act_1: Action, capsys):
'drop index test2_id_x_desc']
for cmd in drop_commands:
with act_1.db.connect() as con2:
tx = con2.transaction_manager(default_tpb=tpb)
tx = con2.transaction_manager(custom_tpb)
tx.begin()
cur2 = tx.cursor()
try:

View File

@ -21,7 +21,7 @@
import pytest
from firebird.qa import db_factory, python_act, Action
from firebird.driver import TPB, Isolation, TraAccessMode, DatabaseError
from firebird.driver import tpb, Isolation, TraAccessMode, DatabaseError
# version: 2.5.5
# resources: None
@ -108,8 +108,8 @@ lock conflict on no wait transaction
@pytest.mark.version('>=2.5.5')
def test_1(act_1: Action, capsys):
custom_tpb = TPB(isolation=Isolation.READ_COMMITTED_RECORD_VERSION,
access_mode=TraAccessMode.WRITE, lock_timeout=0).get_buffer()
custom_tpb = tpb(isolation=Isolation.READ_COMMITTED_RECORD_VERSION,
access_mode=TraAccessMode.WRITE, lock_timeout=0)
with act_1.db.connect() as con1:
tx1a = con1.transaction_manager(custom_tpb)
cur1a = tx1a.cursor()

View File

@ -26,7 +26,7 @@
import pytest
from firebird.qa import db_factory, python_act, Action
from firebird.driver import TPB, Isolation
from firebird.driver import tpb, Isolation
# version: 2.5.6
# resources: None
@ -87,7 +87,7 @@ expected_stdout_1 = """
def test_1(act_1: Action):
act_1.db.set_async_write()
#
custom_tpb = TPB(isolation=Isolation.CONCURRENCY).get_buffer()
custom_tpb = tpb(isolation=Isolation.CONCURRENCY)
with act_1.db.connect(no_gc=True) as con:
tx1 = con.transaction_manager(custom_tpb)
tx2 = con.transaction_manager(custom_tpb)

View File

@ -34,6 +34,7 @@ init_script_1 = """
"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
db_1_repl = db_factory(sql_dialect=3, init=init_script_1, filename='tmp_5645_repl.fd')
# test_script_1
#---
@ -167,13 +168,8 @@ expected_stdout_1 = """
Records affected: 2
"""
db_1_repl = db_factory(sql_dialect=3, init=init_script_1, filename='tmp_5645_repl.fd')
@pytest.mark.version('>=3.0.3')
def test_1(act_1: Action, db_1_repl: Database):
pytest.skip("Requires UDR udrcpp_example")
ddl_for_replication = f"""
create table replicate_config (
name varchar(31) not null,
@ -181,7 +177,7 @@ def test_1(act_1: Action, db_1_repl: Database):
);
insert into replicate_config (name, data_source)
values ('ds1', '{db_1_repl}');
values ('ds1', '{db_1_repl.db_path}');
create trigger persons_replicate
after insert on persons

View File

@ -14,19 +14,20 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 4.0
# resources: None
substitutions_1 = [('.*{CORE_5907.97}.TMP', '{CORE_5907.97}.TMP'), ('.*{core_5907.97}.tmp', '{CORE_5907.97}.TMP')]
substitutions_1 = [('.*{CORE_5907.97}.FDB', '{CORE_5907.97}.FDB'),
('.*{core_5907.97}.fdb', '{CORE_5907.97}.FDB')]
init_script_1 = """
recreate table test(id int);
commit;
"""
"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
db_1 = db_factory(sql_dialect=3, init=init_script_1, filename='{core_5907.97}.fdb')
# test_script_1
#---
@ -43,7 +44,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# os.environ["ISC_PASSWORD"] = user_password
#
# this_fdb = db_conn.database_name
# test_fdb = os.path.join( os.path.split(this_fdb)[0], "{core_5907.97}.tmp") # name of copy will be: %FBT_REPO% mp\\{core_5907.97}.tmp
# test_fdb = os.path.join( os.path.split(this_fdb)[0], "{core_5907.97}.tmp") # name of copy will be: %FBT_REPO%\\tmp\\{core_5907.97}.tmp
#
# db_conn.close()
#
@ -228,17 +229,37 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
{CORE_5907.97}.TMP
{CORE_5907.97}.FDB
Found expected ATTACH.
Found expected DETACH.
"""
"""
trace_conf = ['database=(%[\\\\/](\\{{core_5907.[[:DIGIT:]]{{2}}\\}}).fdb)',
'{',
'enabled = true',
'time_threshold = 0',
'log_connections = true',
'log_initfini = false',
'}'
]
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
with act_1.trace(config=trace_conf):
act_1.isql(switches=[],
input='set list on;select mon$database_name from mon$database;')
print(act_1.stdout)
#
for line in act_1.trace_log:
if 'ATTACH_DATABASE' in line:
print('Found expected ATTACH.')
if 'DETACH_DATABASE' in line:
print('Found expected DETACH.')
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -4,7 +4,7 @@
# title: Enhance dynamic libraries loading related error messages
# decription:
# We intentionally try to load unit from non-existent UDR module with name "udrcpp_foo".
# Message 'module not found' issued BEFORE fix - without any detalization.
# Message 'module not found' issued BEFORE fix - without any detailization.
# Current output should contain phrase: 'UDR module not loaded'.
# Filtering is used for prevent output of localized message about missed UDR library.
#
@ -19,7 +19,9 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import re
from firebird.qa import db_factory, python_act, Action
from firebird.driver import DatabaseError
# version: 3.0.4
# resources: None
@ -64,15 +66,33 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
- UDR MODULE NOT LOADED
"""
UDR module not loaded
"""
@pytest.mark.version('>=3.0.4')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
udr_ddl = """
create or alter procedure gen_foo2 (
start_n integer not null,
end_n integer not null
) returns( n integer not null )
external name 'udrcpp_foo!gen_rows'
engine udr
"""
pattern = re.compile('\\.*module\\s+not\\s+(found|loaded)\\.*', re.IGNORECASE)
with act_1.db.connect() as con:
try:
con.execute_immediate(udr_ddl)
con.commit()
except DatabaseError as e:
for line in str(e).splitlines():
if pattern.search(line):
print(line)
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -26,7 +26,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
# version: 3.0.4
# resources: None
@ -160,7 +161,8 @@ db_1 = db_factory(charset='WIN1252', sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
RDB$MAP_USING P
@ -169,11 +171,50 @@ expected_stdout_1 = """
RDB$MAP_TO_TYPE 0
Records affected: 1
"""
"""
test_script = temp_file('test_script.sql')
@pytest.mark.version('>=3.0.4')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, test_script: Path):
if act_1.is_version('<4'):
# Maximal length of user name in FB 3.x is 31 (charset unicode_fss).
#mapping_name = 'áâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
mapping_name = 'áâãäåæçèéêëìíîï1'
# mapping_name = 'áâãäåæçèéêëìíîïð'
non_ascii_user_name = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞ'
ascii_only_user_name = 'ABCDEFGHIJKLMNOPQRSTUWYXYZ12345'
else:
# Maximal length of user name in FB 4.x is 63 (charset utf8).
#
mapping_name = 'áâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿŒ'
non_ascii_user_name = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿŒœŠšŸŽžƒ'
ascii_only_user_name = 'ABCDEFGHIJKLMNOPQRSTUWYXYZ12345ABCDEFGHIJKLMNOPQRSTUWYXYZ123456'
#
plugin_for_mapping = 'Srp'
test_script.write_text(f"""
create or alter mapping "{mapping_name}" using plugin {plugin_for_mapping} from user '{non_ascii_user_name}' to user "{ascii_only_user_name}";
commit;
-- show mapping;
set count on;
set list on;
select
rdb$map_using
,rdb$map_db
,rdb$map_from_type
,rdb$map_to_type
-- ,rdb$map_plugin
-- 03.03.2021: do NOT show because it differs for FB 3.x and 4.x: ,rdb$map_from
-- 03.03.2021: do NOT show because it differs for FB 3.x and 4.x: ,rdb$map_to
from rdb$auth_mapping
where
upper(rdb$map_name) = upper('{mapping_name}')
and rdb$map_plugin = upper('{plugin_for_mapping}')
and rdb$map_from = '{non_ascii_user_name}'
and rdb$map_to containing '{ascii_only_user_name}'
;
commit;
""", encoding='cp1252')
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-b', '-q'], input_file=test_script, charset='WIN1252')
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -28,7 +28,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
from firebird.driver import tpb, Isolation
# version: 3.0.5
# resources: None
@ -183,15 +184,105 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Passed.
"""
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.db.set_async_write()
# CONCURRENCY | WAIT | READ_WRITE
dml_tpb = tpb(isolation=Isolation.CONCURRENCY)
# READ_COMMITTED | NO_REC_VERSION | WAIT | READ_WRITE
ddl_tpb = tpb(isolation=Isolation.READ_COMMITTED_NO_RECORD_VERSION)
#
with act_1.db.connect() as con:
con.execute_immediate('recreate table a (id int)')
con.commit()
con.execute_immediate('create index idx_a on a(id)')
con.commit()
sql = """
create or alter procedure p_gen_tx(n int) as
declare i int = 0;
begin
while (i < n) do
in autonomous transaction do
i = i + 1;
end
"""
con.execute_immediate(sql)
con.commit()
# Test
con = act_1.db.connect()
tx1a = con.transaction_manager(dml_tpb)
tx1a.begin()
cur1 = tx1a.cursor()
cur1.execute('delete from a')
tx1a.commit()
#
tx1a.begin()
cur1.execute("select current_transaction, rdb$get_context('SYSTEM', 'ISOLATION_LEVEL') from rdb$database")
cur1.fetchall()
# ---
con2 = act_1.db.connect()
tx2a = con2.transaction_manager(dml_tpb)
tx2b = con2.transaction_manager(ddl_tpb)
#
tx2a.begin()
tx2b.begin()
cur2 = tx2a.cursor()
cur2.callproc('p_gen_tx', [33000])
tx2a.commit()
tx2b.commit()
#
tx2a.begin()
tx2b.begin()
cur2.execute('insert into a (id) values (?)', [tx2a.info.id])
tx2a.commit()
tx2b.commit()
#
tx2a.begin()
tx2b.begin()
cur2.execute('set statistics index idx_a')
tx2a.commit()
tx2b.commit()
#
tx2a.begin()
tx2b.begin()
cur2.execute('select rdb$index_name, rdb$record_version from rdb$indices where rdb$relation_name = ?', ['A'])
cur2.fetchall()
cur2.execute('select id from a where id > ?', [0])
cur2.fetchall()
tx2a.commit()
tx2b.commit()
#
tx2a.begin()
tx2b.begin()
cur2 = tx2a.cursor()
cur2.callproc('p_gen_tx', [33000])
tx2a.commit()
tx2b.commit()
# ---
tx1a.commit()
# ---
tx2a.begin()
tx2b.begin()
cur2.execute('select id from a where id > ?', [0])
cur2.fetchall()
# ---
tx1a.begin()
cur1.execute('select id from a where id > ?', [0])
cur1.fetchall()
#
cur1.close()
tx1a.rollback()
con.close()
#
cur2.close()
tx2a.rollback()
tx2b.rollback()
con2.close()
# Passed

View File

@ -40,7 +40,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
from firebird.driver import tpb, Isolation
# version: 2.5.9
# resources: None
@ -159,16 +160,69 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
GEN_ROWS = 17000 # ----- minimal value needed for making FB to crash
expected_stdout_1 = """
Query completed.
All fine.
"""
"""
ddl_script = """
create table a (id int);
create index idx_a on a computed by (id);
commit;
set term ^;
create procedure p_gen_tx(n int) as
declare i int = 0;
begin
while (i < n) do
in autonomous transaction do
i = i + 1;
end ^
set term ;^
commit;
"""
@pytest.mark.version('>=2.5.9')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.db.set_async_write()
act_1.isql(switches=[], input=ddl_script)
custom_tpb = tpb(isolation=Isolation.CONCURRENCY)
#
with act_1.db.connect() as con1:
tx1 = con1.transaction_manager(custom_tpb)
tx1.begin()
cur1 = tx1.cursor()
cur1.execute( "select current_transaction, rdb$get_context('SYSTEM', 'ISOLATION_LEVEL') from rdb$database" )
cur1.fetchall()
with act_1.db.connect() as con2:
tx2 = con2.transaction_manager(custom_tpb)
tx2.begin()
cur2 = tx2.cursor()
cur2.callproc('p_gen_tx', [GEN_ROWS])
tx2.commit()
#
tx2.begin()
cur2.execute('insert into a values (current_transaction)')
tx2.commit()
#
tx2.begin()
cur2.execute('set statistics index idx_a')
tx2.commit()
#
tx2.begin()
cur2.execute('select * from a where id > 0')
cur2.fetchall()
tx2.commit()
#
tx2.begin()
cur2.callproc('p_gen_tx', [GEN_ROWS])
tx2.commit()
# ---
tx1.commit()
cur1.execute('select * from a where id > 0')
cur1.fetchall() # WI-V2.5.8.27089 crashed here
tx1.commit()

View File

@ -19,7 +19,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
# version: 2.5.9
# resources: None
@ -47,16 +48,18 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stderr_1 = """
gbak: ERROR:service name parameter missing
gbak:Exiting before completion due to errors
"""
"""
fbk_file = temp_file('tmp_core_5939.fbk')
@pytest.mark.version('>=2.5.9')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, fbk_file: Path):
act_1.expected_stderr = expected_stderr_1
act_1.gbak(switches=['-b', act_1.db.dsn, str(fbk_file), '-se'])
assert act_1.clean_stderr == act_1.clean_expected_stderr

View File

@ -16,7 +16,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
from firebird.driver import DbAccessMode
# version: 3.0.5
# resources: None
@ -69,16 +70,26 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
60 1
COMPLETED.
"""
"""
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.db.connect() as con:
con.execute_immediate('alter database set linger to 60')
con.commit()
#
with act_1.connect_server() as srv:
srv.database.set_access_mode(database=act_1.db.db_path, mode=DbAccessMode.READ_ONLY)
# Test
with act_1.db.connect() as con:
c = con.cursor()
c.execute('select r.rdb$linger, d.mon$read_only from rdb$database r cross join mon$database d')
result = c.fetchone()
con.commit()
assert result == (60, 1)

View File

@ -23,7 +23,9 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import zipfile
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file, Database
# version: 3.0
# resources: None
@ -33,6 +35,8 @@ substitutions_1 = []
init_script_1 = """"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
db_1_tmp = db_factory(sql_dialect=3, filename='tmp_core_5965.fdb', do_not_create=True)
# test_script_1
#---
@ -159,16 +163,37 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( (tmpfbk, tmpfdb, f_restore_log) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
PLAN SORT (OPT_TEST INDEX (O_CLID_CUSTTY_CUSTID))
PLAN SORT (OPT_TEST INDEX (O_CLID_CUSTTY_CUSTID))
"""
"""
fbk_file = temp_file('core_5965.fbk')
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, fbk_file: Path, db_1_tmp: Database, capsys):
zipped_fbk_file = zipfile.Path(act_1.vars['files'] / 'core_5965.zip',
at='core_5965.fbk')
fbk_file.write_bytes(zipped_fbk_file.read_bytes())
#
with act_1.connect_server() as srv:
srv.database.restore(backup=fbk_file, database=db_1_tmp.db_path)
srv.wait()
# Test
with db_1_tmp.connect() as con:
c1 = con.cursor()
c2 = con.cursor()
c1.execute("select 1 from opt_test where clid = 23 and cust_type = 1 and cust_id = 73 order by order_no desc")
c1.fetchall()
print(c1.statement.plan)
#
c2.execute("select 2 from opt_test where sysid = 1 and clid = 23 and cust_type = 1 and cust_id = 73 order by order_no desc")
c2.fetchall()
print(c2.statement.plan)
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -19,7 +19,7 @@
# 335544382 : COMP
# 336397208 : At line 1, column 57
# Statement : insert into "PERSONS" ("ID", "NAME", "ADDRESS", "INFO", "COMP") values (?, ?, ?, ?, ?)
# Data source : Firebird::C:\\FBTESTING\\qa\\misc mprepl.fdb
# Data source : Firebird::C:\\FBTESTING\\qa\\misc\\tmprepl.fdb
# -At block line: ...
# -At trigger 'PERSONS_REPLICATE'
#
@ -38,16 +38,29 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action, Database
from firebird.driver import DatabaseError
# version: 3.0.6
# resources: None
substitutions_1 = [('[ \t]+', ' '), ('.* At block line.*', 'At block'), ('read-only column.*', 'read-only column'), ('Statement.*', 'Statement'), ('Data source.*', 'Data source'), ('.* At trigger.*', 'At trigger')]
substitutions_1 = [('[ \t]+', ' '), ('.* At block line.*', 'At block'),
('read-only column.*', 'read-only column'),
('Statement.*', 'Statement'), ('Data source.*', 'Data source'),
('.* At trigger.*', 'At trigger')]
init_script_1 = """"""
init_script_1 = """
create table persons (
id integer not null,
name varchar(60) not null,
address varchar(60),
info blob sub_type text,
comp int computed by (1) -- COMPUTED_BY FIELD AS IT IS DESCRIBED IN THE TICKET
);
"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
db_1_repl = db_factory(sql_dialect=3, init=init_script_1, filename='core_5972_repl.fdb')
# test_script_1
#---
@ -168,23 +181,57 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Got exception: <class 'fdb.fbcore.DatabaseError'>
Error while executing SQL statement:
- SQLCODE: -901
- Execute statement error at isc_dsql_prepare :
Got exception: <class 'firebird.driver.types.DatabaseError'>
Execute statement error at isc_dsql_prepare :
335544359 : attempted update of read-only column PERSONS.COMP
Statement : insert into "PERSONS" ("ID", "NAME", "ADDRESS", "INFO", "COMP") values (?, ?, ?, ?, ?)
Data source : Firebird::C:\\FBTESTING\\qa bt-repo mp mp_5972_repl.fdb
- At block line: 9, col: 5
- At trigger 'PERSONS_REPLICATE'
"""
Data source : Firebird::C:\\FBTESTING\\qa\\fbt-repo\\tmp\\tmp_5972_repl.fdb
-At block line: 9, col: 5
-At trigger 'PERSONS_REPLICATE'
"""
@pytest.mark.version('>=3.0.6')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, db_1_repl: Database, capsys):
ddl_for_replication = f"""
create table replicate_config (
name varchar(31) not null,
data_source varchar(255) not null
);
insert into replicate_config (name, data_source)
values ('ds1', '{db_1_repl.db_path}');
create trigger persons_replicate
after insert on persons
external name 'udrcpp_example!replicate!ds1'
engine udr;
create trigger persons_replicate2
after insert on persons
external name 'udrcpp_example!replicate_persons!ds1'
engine udr;
commit;
"""
act_1.isql(switches=['-q'], input=ddl_for_replication)
# Test
with act_1.db.connect() as con:
c = con.cursor()
try:
c.execute("insert into persons values (1, 'One', 'some_address', 'some_blob_info')")
con.commit()
except DatabaseError as e:
print(f'Got exception: {e.__class__}')
print(e)
#
if act_1.is_version('>=4'):
act_1.reset()
act_1.isql(switches=['-q'], input='ALTER EXTERNAL CONNECTIONS POOL CLEAR ALL;')
#
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -26,7 +26,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 2.5.1
# resources: None
@ -74,12 +74,19 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=2.5.1')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.db.connect() as con1, act_1.db.connect() as con2:
con1.execute_immediate('recreate table t1(id int)')
con1.execute_immediate('create index t1_idx on t1 computed by (id + 0)')
con1.commit()
c = con1.cursor()
c.execute('insert into t1(id) values(?)', [1])
con1.commit()
# this lead to corruption of database in 2.5.0
# page 0 is of wrong type (expected 6, found 1)
con2.execute_immediate('alter index t1_idx active')
con2.commit()

View File

@ -9,8 +9,7 @@
# In order to reproduce bug one need to create config file for trace with following
# _SINGLE_ file name in databases-section:
# =====
# database = 'C:\\FBTESTING\\qa
# bt-repo mp mp_5991.o'clock.fdb'
# database = 'C:\\FBTESTING\\qa\\fbt-repo\\tmp\\tmp_5991.o'clock.fdb'
# {
# enabled = true
# time_threshold = 0
@ -20,8 +19,7 @@
# log_statement_finish = true
# }
# =====
# (path 'C:\\FBTESTING\\qa
# bt-repo mp' will be replaced with actual test DB location)
# (path 'C:\\FBTESTING\\qa\\fbt-repo\\tmp' will be replaced with actual test DB location)
#
# Then we start trace session.
#
@ -64,7 +62,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import re
from firebird.qa import db_factory, python_act, Action
# version: 3.0.5
# resources: None
@ -73,7 +72,7 @@ substitutions_1 = [('Trying to create.*', '')]
init_script_1 = """"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
db_1 = db_factory(sql_dialect=3, init=init_script_1, filename="core_5991.o'clock.fdb")
# test_script_1
#---
@ -278,24 +277,61 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Trying to create: "localhost:C:/FBTESTING/qa/fbt-repo/tmp/tmp_5991.o''clock.fdb"
Database created OK.
Database name contains single quote.
Database dropped OK.
Pattern 1. TRACE_START : FOUND
Pattern 2. DB_CREATION : FOUND
Pattern 3. TX_START : FOUND
Pattern 4. STATEMENT_DONE : FOUND
Pattern 5. TX_FINISH : FOUND
Pattern 6. DB_REMOVAL : FOUND
"""
Pattern 1. DB_ATTACH : FOUND
Pattern 2. TX_START : FOUND
Pattern 3. STATEMENT_DONE : FOUND
Pattern 4. TX_FINISH : FOUND
Pattern 5. DB_DETACH : FOUND
"""
trace_1 = ['{',
'enabled = true',
'log_connections = true',
'log_transactions = true',
'log_statement_finish = true',
'log_initfini = false',
'time_threshold = 0',
'}'
]
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
trace_1.insert(0, f"database = '{act_1.db.db_path}'")
with act_1.trace(config=trace_1):
with act_1.db.connect() as con:
c = con.cursor()
for row in c.execute("select 'Database name contains single quote.' as result from mon$database where lower(mon$database_name) similar to '%[\\/](core_5991.o''clock).fdb'"):
print(row[0])
# Process trace
allowed_patterns = {'1. DB_ATTACH': re.compile('[.*]*ATTACH_DATABASE\\.*', re.IGNORECASE),
'2. TX_START': re.compile('[.*]*START_TRANSACTION\\.*', re.IGNORECASE),
'3. STATEMENT_DONE': re.compile('[.*]*EXECUTE_STATEMENT_FINISH\\.*', re.IGNORECASE),
'4. TX_FINISH': re.compile('[.*]*ROLLBACK_TRANSACTION\\.*', re.IGNORECASE),
'5. DB_DETACH': re.compile('[.*]*DETACH_DATABASE\\.*', re.IGNORECASE),
}
found_patterns = {}
for line in act_1.trace_log:
if line.rstrip().split():
for key, pattern in allowed_patterns.items():
if pattern.search(line):
found_patterns[key] = 'FOUND'
for key, status in sorted(found_patterns.items()):
print(f'Pattern {key} : {status}')
if len(found_patterns) < len(allowed_patterns):
print('==== INCOMPLETE TRACE LOG: ====')
for line in act_1.trace_log:
if line.strip():
print(' ' + line)
print('=' * 31)
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -18,7 +18,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0.5
# resources: None
@ -172,15 +172,17 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( (trc_lst, trc_cfg, trc_log) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
Trace was started by: SYSDBA
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
trace_1 = ['log_initfini = false',
'time_threshold = 0',
'log_statement_finish = true',
]
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.trace(db_events=trace_1), act_1.connect_server() as srv:
assert len(srv.trace.sessions) == 1
for session in srv.trace.sessions.values():
assert session.user == 'SYSDBA'

View File

@ -23,7 +23,9 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import os
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
# version: 3.0.5
# resources: None
@ -144,16 +146,25 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( ( f_psw_correct, f_psw_invalid, f_log_correct, f_err_correct, f_log_invalid, f_err_invalid, this_fbk ) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
EXPECTED STDERR FOR INVALID PASSWORD: gbak: ERROR:Your user name and password are not defined. Ask your database administrator to set up a Firebird login.
EXPECTED STDERR FOR INVALID PASSWORD: gbak:Exiting before completion due to errors
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stderr_1 = """
gbak: ERROR:Your user name and password are not defined. Ask your database administrator to set up a Firebird login.
gbak:Exiting before completion due to errors
"""
pwd_file = temp_file('pwd.dat')
fbk_file = temp_file('tmp_core_6000.fbk')
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, pwd_file: Path, fbk_file: Path):
pwd_file.write_text('T0t@1lywr0ng')
with act_1.envar('ISC_PASSWORD', act_1.db.password):
act_1.expected_stderr = expected_stderr_1
act_1.gbak(switches=['-b', '-se', 'localhost:service_mgr', '-user', act_1.db.user,
'-fe', str(pwd_file), act_1.db.dsn, str(fbk_file)], credentials=False)
assert act_1.clean_stderr == act_1.clean_expected_stderr
pwd_file.write_text(act_1.db.password)
act_1.gbak(switches=['-b', '-se', 'localhost:service_mgr', '-user', act_1.db.user,
'-fe', str(pwd_file), act_1.db.dsn, str(fbk_file)], credentials=False)

View File

@ -16,7 +16,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
from firebird.driver import tpb, Isolation
# version: 4.0
# resources: None
@ -78,15 +79,23 @@ 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 = """
Result is expected: NOT null.
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
custom_tpb = tpb(isolation=Isolation.CONCURRENCY)
with act_1.db.connect() as con1:
tx1a = con1.transaction_manager(custom_tpb)
tx1a.begin() # tx1a must be started BEFORE tx2a!
with act_1.db.connect() as con2:
tx2a = con2.transaction_manager(custom_tpb)
tx2a.begin()
#
cur2 = tx2a.cursor()
trn2 = cur2.execute('select current_transaction from rdb$database').fetchone()[0]
tx2a.commit()
#
cur1 = tx1a.cursor()
cur1.execute(f"select 'Result is ' || iif( rdb$get_transaction_cn({trn2}) is null, 'INCORRECT: NULL.', 'expected: NOT null.') from rdb$database")
assert cur1.fetchone()[0] == 'Result is expected: NOT null.'

View File

@ -28,7 +28,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
from firebird.driver import tpb, Isolation
# version: 4.0
# resources: None
@ -36,9 +37,9 @@ from firebird.qa import db_factory, isql_act, Action
substitutions_1 = []
init_script_1 = """
recreate table tsn(sn int);
recreate table tsn (sn int);
commit;
"""
"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -111,9 +112,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 = """
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1_a = """
MSG SET_TX_SNAPSHOT_WITHOUT_NUM
============================ ===========================
Tx base snapshot: yet exists -2
@ -123,7 +125,9 @@ expected_stdout_1 = """
============================ ===========================
Tx base snapshot: yet exists -2
Records affected: 1
"""
expected_stdout_1_b = """
MSG SET_TX_SNAPSHOT_WITHOUT_NUM
================================= ===========================
Tx base snapshot: does not exists -2
@ -134,15 +138,57 @@ expected_stdout_1 = """
Tx base snapshot: does not exists -2
Tx base snapshot: does not exists -1
Records affected: 2
"""
"""
expected_stderr_1 = """
Statement failed, SQLSTATE = 0B000
Transaction's base snapshot number does not exist
"""
"""
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
custom_tpb = tpb(isolation=Isolation.CONCURRENCY, lock_timeout=0)
with act_1.db.connect() as con1:
tx1a = con1.transaction_manager(custom_tpb)
tx1a.begin()
cur1 = tx1a.cursor()
cur1.execute('insert into tsn (sn) values( -2 )')
tx1a.commit()
#
sql_get_sn = """
execute block returns(o_sn bigint) as
begin
o_sn = RDB$GET_CONTEXT('SYSTEM', 'SNAPSHOT_NUMBER');
suspend;
in autonomous transaction do
insert into tsn(sn) values( -1 );
end
"""
tx1b = con1.transaction_manager(custom_tpb)
cur1 = tx1b.cursor()
snap_num = cur1.execute(sql_get_sn).fetchone()[0]
#
for msg, expect_out, expect_err in [('yet exists', expected_stdout_1_a, ''),
('does not exists', expected_stdout_1_b, expected_stderr_1)]:
sql_chk_sn = f"""
-- NB!! looks strange but it seems that this 'SET BAIL ON' does not work here because
-- both records will be extracted in any case. // todo later: check it!
--set bail on;
set count on;
commit;
set transaction snapshot;
select 'Tx base snapshot: {msg}' as msg, t.sn as set_tx_snapshot_without_num from tsn t order by sn;
commit;
set transaction snapshot at number {snap_num};
select 'Tx base snapshot: {msg}' as msg, t.sn as set_tx_snapshot_at_number_N from tsn t order by sn;
commit;
quit;
"""
act_1.reset()
act_1.expected_stdout = expect_out
act_1.expected_stderr = expect_err
act_1.isql(switches=['-q'], input=sql_chk_sn)
if tx1b.is_active():
tx1b.commit()
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -38,7 +38,9 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import zipfile
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
# version: 4.0
# resources: None
@ -47,8 +49,10 @@ substitutions_1 = [('[ \t]+', ' '), ('expected [\\d]+', 'expected NN')]
init_script_1 = """"""
# Database is extracted from zip
db_1 = db_factory(sql_dialect=3, init=init_script_1)
# test_script_1
#---
#
@ -118,18 +122,39 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
RESTORE_WITH_REPLACE_RESULT 1
"""
"""
expected_stderr_1 = """
Wrong ODS version, expected 13, encountered 11
"""
"""
fdb_112_file = temp_file('core_6023-ods-11_2.fdb')
fbk_file = temp_file('core_6023.fbk')
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, fdb_112_file: Path, fbk_file: Path):
zipped_fdb_file = zipfile.Path(act_1.vars['files'] / 'core_6023-ods-11_2-fdb.zip',
at='core_6023-ods-11_2.fdb')
fdb_112_file.write_bytes(zipped_fdb_file.read_bytes())
# Change permissions
fdb_112_file.chmod(16895)
# Ensure that we really have deal with .fdb file with old ODS.
act_1.expected_stderr = expected_stderr_1
act_1.gstat(switches=['-h', str(fdb_112_file)], connect_db=False)
assert act_1.clean_stderr == act_1.clean_expected_stderr
# Backup work database and restore over extracted db
act_1.reset()
act_1.gbak(switches=['-b', act_1.db.dsn, str(fbk_file)])
act_1.reset()
act_1.gbak(switches=['-rep', str(fbk_file), f'localhost:{fdb_112_file}'])
#
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q', f'localhost:{fdb_112_file}'], connect_db=False,
input='set list on; select sign(current_connection) as restore_with_replace_result from rdb$database;')
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -42,7 +42,10 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import zipfile
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file, Database
from firebird.driver import SrvRestoreFlag, DatabaseError
# version: 3.0.5
# resources: None
@ -52,6 +55,7 @@ substitutions_1 = []
init_script_1 = """"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
db_1_tmp = db_factory(sql_dialect=3, filename='tmp_core_602.fdb', do_not_create=True)
# test_script_1
#---
@ -206,26 +210,99 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( (tmpfbk, tmpfdb, f_restore_log) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
NO USER-DEFINED TRIGGERS IN JUST RESTORED DATABASE.
NO ACTIONS WAS LOGGED IN THE TABLE TLOG.
unsuccessful metadata update
-CREATE OR ALTER TRIGGER NEW_TRG_RDB_REL_FLDS_BI failed
-no permission for ALTER access to TABLE RDB$RELATION_FIELDS
-607
(335544351, 336397272, 335544352)
unsuccessful metadata update
-CREATE OR ALTER TRIGGER NEW_TRG_MON_STM_BD failed
-no permission for ALTER access to TABLE MON$STATEMENTS
-607
(335544351, 336397272, 335544352)
unsuccessful metadata update
-CREATE OR ALTER TRIGGER NEW_TRG_MON_ATT_BD failed
-no permission for ALTER access to TABLE MON$ATTACHMENTS
-607
(335544351, 336397272, 335544352)
"""
- no permission for ALTER access to TABLE RDB$RELATION_FIELDS
-607
335544351
- no permission for ALTER access to TABLE MON$STATEMENTS
-607
335544351
- no permission for ALTER access to TABLE MON$ATTACHMENTS
-607
335544351
"""
fbk_file_1 = temp_file('core_6028_25.fbk')
ddl_probes = ["""
create or alter trigger new_trg_rdb_rel_flds_bi for rdb$relation_fields active before insert position 0 as
begin
insert into tlog(id, action) values( gen_id(g, 111), 'rdb$relation_fields: record is to be created' );
end
""", """
create or alter trigger new_trg_mon_stm_bd for mon$statements active before delete position 0 as
begin
insert into tlog(id, action) values( gen_id(g, 222), 'mon$statements: record is to be removed' );
end
""", """
create or alter trigger new_trg_mon_att_bd for mon$attachments active before delete position 0 as
begin
insert into tlog(id, action) values( gen_id(g, 333), 'mon$attachments: record is to be removed' );
end
"""]
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, fbk_file_1: Path, db_1_tmp: Database, capsys):
zipped_fbk_file = zipfile.Path(act_1.vars['files'] / 'core_6028_25.zip',
at='core_6028_25.fbk')
fbk_file_1.write_bytes(zipped_fbk_file.read_bytes())
#
with act_1.connect_server() as srv:
srv.database.restore(backup=fbk_file_1, database=db_1_tmp.db_path,
flags=SrvRestoreFlag.REPLACE)
srv.wait()
#
con_worker = db_1_tmp.connect()
con_worker_attachment_id = con_worker.info.id
con_worker.execute_immediate('create table test(id int)')
con_worker.commit()
con_worker.execute_immediate('drop table test')
con_worker.commit()
#
cur_worker=con_worker.cursor()
cur_worker.execute("select coalesce(rt.rdb$trigger_name, 'NO USER-DEFINED TRIGGERS IN JUST RESTORED DATABASE.') from rdb$database rd left join rdb$triggers rt on rt.rdb$system_flag is distinct from 1 order by 1")
for r in cur_worker:
print(r[0])
#
with db_1_tmp.connect() as con_killer:
cur_killer = con_killer.cursor()
cur_killer.execute(f'delete from mon$statements s where s.mon$attachment_id = {con_worker_attachment_id}')
con_killer.commit()
cur_killer.execute(f'delete from mon$attachments a where a.mon$attachment_id = {con_worker_attachment_id}')
con_killer.commit()
cur_killer.execute("select coalesce(t.action, 'NO ACTIONS WAS LOGGED IN THE TABLE TLOG.') as sys_tabs_action from rdb$database rd left join tlog t on 1=1")
for r in cur_killer:
print(r[0])
#
try:
cur_worker.close()
except Exception:
pass
try:
con_worker.close()
except Exception:
pass
#
for cmd in ddl_probes:
try:
con_killer.execute_immediate(cmd)
except DatabaseError as e:
print(e)
print(e.sqlcode)
print(e.gds_codes)
# Check
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -20,16 +20,21 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0.5
# resources: None
substitutions_1 = []
init_script_1 = """"""
init_script_1 = """
recreate table users (
f01 varchar(32) character set win1252 not null collate win_ptbr
,f02 computed by ( f01 collate win_ptbr )
);
"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
db_1 = db_factory(sql_dialect=3, init=init_script_1, charset='win1252')
# test_script_1
#---
@ -139,12 +144,18 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.isql(switches=['-x'], charset='win1252')
meta = act_1.stdout
#
with act_1.db.connect() as con:
con.execute_immediate('drop table users')
con.commit()
#
act_1.reset()
act_1.isql(switches=[], charset='win1252', input=meta)

View File

@ -44,7 +44,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, isql_act, python_act, Action
# version: 3.0
# resources: None
@ -221,7 +221,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
When ClearGTTAtRetaining = 0: ID 3
@ -233,10 +234,9 @@ expected_stdout_1 = """
When ClearGTTAtRetaining = 1: Records affected: 0
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
@pytest.mark.version('>=3.0,<4')
def test_1(act_1: Action):
pytest.skip("Requires changes to databases.conf")
# version: 4.0

View File

@ -49,7 +49,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 4.0
# resources: None
@ -186,16 +186,16 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Is database encrypted ? 1
Is database encrypted ? 0
"""
"""
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
pytest.skip("Requires encryption plugin")

View File

@ -28,7 +28,12 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, user_factory, User
user_0 = user_factory(name='tmp$c6078_0', password='123')
user_1 = user_factory(name='tmp$c6078_1', password='123')
user_2 = user_factory(name='tmp$c6078_2', password='456')
# version: 3.0.5
# resources: None
@ -111,7 +116,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Statement failed, SQLSTATE = 28000
@ -262,12 +268,18 @@ expected_stdout_1 = """
unsuccessful metadata update
-ALTER MAPPING GLOBAL_MAP_C6078 failed
-Unable to perform operation. You must be either SYSDBA or owner of the database
"""
"""
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
@pytest.mark.version('>=3.0.5,<4')
def test_1(act_1: Action, user_0: User, user_1: User, user_2: User):
script_vars = {'dsn': act_1.db.dsn,
'user_name': act_1.db.user,
'user_password': act_1.db.password,}
script_file = act_1.vars['files'] / 'core_6078.sql'
script = script_file.read_text() % script_vars
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q'], input=script, combine_output=True)
assert act_1.clean_stdout == act_1.clean_expected_stdout
# version: 4.0
@ -353,7 +365,8 @@ db_2 = db_factory(sql_dialect=3, init=init_script_2)
#
#
#---
#act_2 = python_act('db_2', test_script_2, substitutions=substitutions_2)
act_2 = python_act('db_2', substitutions=substitutions_2)
expected_stdout_2 = """
Statement failed, SQLSTATE = 28000
@ -508,11 +521,16 @@ expected_stdout_2 = """
-ALTER MAPPING GLOBAL_MAP_C6078 failed
-Unable to perform operation
-System privilege CHANGE_MAPPING_RULES is missing
"""
"""
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_2(db_2):
pytest.fail("Test not IMPLEMENTED")
def test_2(act_2: Action, user_0: User, user_1: User, user_2: User):
script_vars = {'dsn': act_2.db.dsn,
'user_name': act_2.db.user,
'user_password': act_2.db.password,}
script_file = act_2.vars['files'] / 'core_6078.sql'
script = script_file.read_text() % script_vars
act_2.expected_stdout = expected_stdout_2
act_2.isql(switches=['-q'], input=script, combine_output=True)
assert act_2.clean_stdout == act_2.clean_expected_stdout

View File

@ -20,7 +20,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import re
from firebird.qa import db_factory, python_act, Action
# version: 3.0.5
# resources: None
@ -128,15 +129,42 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( (f_isql_cmd, f_isql_log) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
Number of unique blob IDs: 3
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
test_script_1 = """
set bail on;
set list on;
set blob off;
recreate table t (col1 int, col2 blob);
recreate view v as select col2 as col2_blob_id from t; -- NB: alias for column have to be matched to re.compile() argument
commit;
insert into t values (1, '1');
insert into t values (2, '2');
insert into t values (3, '3');
commit;
select v.* from v;
update t set col1 = -col1;
select v.* from v;
rollback;
alter table t add col3 date;
select v.* from v;
update t set col1 = -col1;
select v.* from v; -- bug was here
quit;
"""
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
pattern = re.compile('COL2_BLOB_ID\\s+\\S+', re.IGNORECASE)
blob_id_set = set()
act_1.isql(switches=['-q'], input=test_script_1)
for line in act_1.stdout.splitlines():
if pattern.search(line):
blob_id_set.add(line.split()[1])
# Check
assert len(blob_id_set) == 3

View File

@ -20,7 +20,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import re
from firebird.qa import db_factory, python_act, Action
# version: 3.0.5
# resources: None
@ -149,16 +150,65 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( (f_isql_cmd, f_isql_log) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Number of unique blob IDs: 3
Number of nullified blobs: 0
"""
"""
test_script_1 = """
set bail on;
set blob all;
set list on;
recreate view v as select 1 x from rdb$database;
commit;
recreate table test (n1 int, n2 int, n3 int, blob_id blob);
recreate view v as select blob_id from test;
commit;
insert into test values (0, 0, null, '0:foo');
insert into test values (1, 1, 1, '1:rio');
insert into test values (2, 2, 2, '2:bar');
commit;
select 1 as point, v.* from v;
update test set n1 = 1 where n2 >= 0; -- n1 should be set to 1 in all three rows
select 2 as point, v.* from v;
rollback;
update test set n1 = 1 where n2 >= 0 and n3 >= 0; -- n1 should be set to 1 in 2nd and 3rd rows
select 3 as point, v.* from v;
rollback;
alter table test add col5 date;
commit;
update test set n1 = 1 where n2 >= 0; -- n1 should be set to 1 in all three rows
select 4 as point, v.* from v; -- Here blob_id were changed because of other bug, see CORE-6089, but contents is correct
rollback;
update test set n1 = 1 where n2 >= 0 and n3 >= 0;
-- n1 should be set to 1 in 2nd and 3rd rows
select 5 as point, v.* from v; -- BUG: BLOB_ID in the second row was nullified!!!
quit;
"""
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
pattern = re.compile('BLOB_ID\\s+\\S+', re.IGNORECASE)
blob_id_set = set()
null_blob_cnt = 0
act_1.isql(switches=['-q'], input=test_script_1)
for line in act_1.stdout.splitlines():
if pattern.search(line):
blob_id_set.add(line.split()[1])
if '<null>' in line.lower():
null_blob_cnt += 1
# Check
assert len(blob_id_set) == 3
assert null_blob_cnt == 0

View File

@ -31,7 +31,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import re
from firebird.qa import db_factory, python_act, Action
# version: 3.0.6
# resources: None
@ -54,7 +55,7 @@ init_script_1 = """
^
set term ;^
commit;
"""
"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -253,7 +254,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( (trc_lst, trc_cfg, trc_log) )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Found record with "NEW NUMBER" for subsequent Tx numbers: 1
@ -263,11 +265,52 @@ expected_stdout_1 = """
Found record with "NEW NUMBER" for subsequent Tx numbers: 3
Found "INIT_" token in "TRA_" record. Tx that is origin of changes: 0 ; Tx that finished now: 3
Found record with "NEW NUMBER" for subsequent Tx numbers: 3
"""
Found "INIT_" token in "TRA_" record. Tx that is origin of changes: 0 ; Tx that finished now: 3
"""
trace_1 = ['log_initfini = false',
'log_transactions = true',
'time_threshold = 0'
]
@pytest.mark.version('>=3.0.6')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
allowed_patterns = [re.compile('\\s*\\(TRA_\\d+,', re.IGNORECASE),
re.compile('\\s*New\\s+number\\s+\\d+\\s*', re.IGNORECASE),
]
with act_1.trace(db_events=trace_1):
with act_1.db.connect() as con:
cur = con.cursor()
con.execute_immediate('insert into test(x) values(123)')
con.commit(retaining = True) # (TRA_12, ... ; next line: "New number 13"
cur.callproc('sp_worker', [456]) # (TRA_13, INIT_12, ...
con.commit(retaining = True) # (TRA_13, INIT_12, ... ; next line: "New number 14"
con.execute_immediate('delete from test') # (TRA_14, INIT_12, ...
con.commit(retaining = True) # (TRA_14, INIT_12, ... ; next line: "New number 15"
# This statement does not change anything:
con.execute_immediate('update test set x = -x') # (TRA_15, INIT_12, ...
con.commit(retaining = True) # (TRA_15, INIT_12, ... ; next line: "New number 15" -- THE SAME AS PREVIOUS!
# Process trace
tx_base = -1
for line in act_1.trace_log:
if line.rstrip().split():
for p in allowed_patterns:
if p.search(line):
if '(TRA_' in line:
words = line.replace(',',' ').replace('_',' ').replace('(',' ').split()
# Result:
# 1) for tx WITHOUT retaining: ['TRA', '12', 'READ', 'COMMITTED', '|', 'REC', 'VERSION', '|', 'WAIT', '|', 'READ', 'WRITE)']
# 2) for tx which is RETAINED: ['TRA', '13', 'INIT', '12', 'READ', 'COMMITTED', '|', 'REC', 'VERSION', '|', 'WAIT', '|', 'READ', 'WRITE)']
# 0 1 2 3
tx_base = int(words[1]) if tx_base == -1 else tx_base
if words[2] == 'INIT':
tx_origin_of_changes = int(words[3]) - tx_base
tx_that_finished_now = int(words[1]) - tx_base
print('Found "INIT_" token in "TRA_" record. Tx that is origin of changes: ', tx_origin_of_changes, '; Tx that finished now:', tx_that_finished_now)
elif 'number' in line:
tx_for_subsequent_changes = int(line.split()[2]) - tx_base # New number 15 --> 15
print('Found record with "NEW NUMBER" for subsequent Tx numbers: ', tx_for_subsequent_changes)
#
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -12,7 +12,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 2.5
# resources: None
@ -47,15 +47,32 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
2019-03-01 00:00:00
"""
"""
proc_ddl = """
create or alter procedure test_proc ( a_dts timestamp) returns ( o_dts timestamp) as
begin
o_dts = a_dts;
suspend;
end
"""
@pytest.mark.version('>=2.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
with act_1.db.connect() as con:
con.execute_immediate(proc_ddl)
con.commit()
c = con.cursor()
for row in c.execute("select o_dts from test_proc('2019-'|| COALESCE( ?, 1) ||'-01' )", [3]):
print(row[0])
#
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -20,7 +20,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
import re
from firebird.qa import db_factory, python_act, Action
# version: 3.0.6
# resources: None
@ -110,16 +111,29 @@ db_1 = db_factory(from_backup='core6116-25.fbk', init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Length in "CREATE TABLE" statement: 100
Length in "ALTER COLUMN" statement: 100
"""
"""
@pytest.mark.version('>=3.0.6')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
comp_field_initial_ptn = re.compile( 'FULL_NAME\\s+VARCHAR\\(\\d+\\).*COMPUTED BY', re.IGNORECASE )
comp_field_altered_ptn = re.compile( 'ALTER\\s+FULL_NAME\\s+TYPE\\s+VARCHAR\\(\\d+\\).*COMPUTED BY', re.IGNORECASE )
#
act_1.isql(switches=['-x'])
for line in act_1.stdout.splitlines():
if comp_field_initial_ptn.search(line):
words = line.replace('(',' ').replace(')',' ').split() # ['FULL_NAME', 'VARCHAR', '0', ... , 'COMPUTED', 'BY']
print(f'Length in "CREATE TABLE" statement: {words[2]}')
if comp_field_altered_ptn.search(line):
words = line.replace('(',' ').replace(')',' ').split() # ['ALTER', 'FULL_NAME', 'TYPE', 'VARCHAR', '0', ... , 'COMPUTED', 'BY']
print(f'Length in "ALTER COLUMN" statement: {words[4]}')
# Check
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -20,7 +20,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
from firebird.driver import tpb, Isolation, DatabaseError
# version: 3.0.5
# resources: None
@ -86,15 +87,29 @@ 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 = """
EXPECTED: FK violation encountered.
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=3.0.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
custom_tpb = tpb(isolation=Isolation.CONCURRENCY, lock_timeout=0)
with act_1.db.connect() as con1, act_1.db.connect() as con2:
con2.begin(custom_tpb)
con1.execute_immediate('create table a (id int primary key)')
con1.execute_immediate('create table b (id int primary key, id_a int, constraint fk_b__a foreign key(id_a) references a(id) on update cascade on delete cascade)')
con1.commit()
con1.begin(custom_tpb)
cur1 = con1.cursor()
cur1.execute('insert into a(id) values( ? )', [1])
con2.commit()
con2.begin(custom_tpb)
cur2 = con2.cursor()
cur2.execute('select id from a')
con1.commit()
with pytest.raises(DatabaseError, match='.*violation of FOREIGN KEY constraint.*'):
cur2.execute('insert into b (id, id_a) values (?, ?)', [1, 1])