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:
parent
f6294a3afe
commit
560873a3f0
BIN
files/core_5965.zip
Normal file
BIN
files/core_5965.zip
Normal file
Binary file not shown.
BIN
files/core_6023-ods-11_2-fdb.zip
Normal file
BIN
files/core_6023-ods-11_2-fdb.zip
Normal file
Binary file not shown.
BIN
files/core_6028_25.zip
Normal file
BIN
files/core_6028_25.zip
Normal file
Binary file not shown.
386
files/core_6078.sql
Normal file
386
files/core_6078.sql
Normal 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;
|
@ -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()
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -171,9 +173,48 @@ expected_stdout_1 = """
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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,7 +70,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 = """
|
||||
60 1
|
||||
@ -77,8 +79,17 @@ expected_stdout_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):
|
||||
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)
|
||||
|
@ -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
|
||||
|
@ -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\\qabt-repo mp mp_5972_repl.fdb
|
||||
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
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
@ -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'
|
||||
|
@ -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)
|
||||
|
@ -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.'
|
||||
|
@ -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
|
||||
@ -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
|
||||
@ -135,14 +139,56 @@ expected_stdout_1 = """
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
(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
|
||||
(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
|
||||
(335544351, 336397272, 335544352)
|
||||
"""
|
||||
|
||||
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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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,7 +186,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 = """
|
||||
Is database encrypted ? 1
|
||||
@ -194,8 +195,7 @@ expected_stdout_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):
|
||||
pytest.skip("Requires encryption plugin")
|
||||
|
||||
|
||||
|
@ -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
|
||||
@ -264,10 +270,16 @@ expected_stdout_1 = """
|
||||
-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
|
||||
@ -511,8 +524,13 @@ expected_stdout_2 = """
|
||||
"""
|
||||
|
||||
@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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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,7 +111,8 @@ 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
|
||||
@ -118,8 +120,20 @@ expected_stdout_1 = """
|
||||
"""
|
||||
|
||||
@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
|
||||
|
@ -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])
|
||||
|
Loading…
Reference in New Issue
Block a user