mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 13:33:07 +01:00
131 lines
4.4 KiB
Python
131 lines
4.4 KiB
Python
#coding:utf-8
|
|
|
|
"""
|
|
ID: issue-5015
|
|
ISSUE: 5015
|
|
TITLE: Implement ability to validate tables and indices online (without exclusive access to database)
|
|
DESCRIPTION:
|
|
JIRA: CORE-4707
|
|
FBTEST: bugs.core_4707
|
|
"""
|
|
|
|
import pytest
|
|
import subprocess
|
|
import time
|
|
from pathlib import Path
|
|
from firebird.qa import *
|
|
|
|
init_script = """
|
|
set term ^;
|
|
execute block as
|
|
begin
|
|
execute statement 'drop sequence g';
|
|
when any do begin end
|
|
end^
|
|
set term ;^
|
|
commit;
|
|
create sequence g;
|
|
commit;
|
|
recreate table test1(id int, s varchar(1000));
|
|
recreate table test2(id int primary key using index test2_pk, s varchar(1000), t computed by (s) );
|
|
recreate table test3(id int);
|
|
commit;
|
|
|
|
insert into test1(id, s) select gen_id(g,1), rpad('', 1000, gen_id(g,0) ) from rdb$types rows 100;
|
|
insert into test2(id, s) select id, s from test1;
|
|
commit;
|
|
|
|
create index test2_s on test2(s);
|
|
create index test2_c on test2 computed by(s);
|
|
create index test2_t on test2 computed by(t);
|
|
commit;
|
|
"""
|
|
|
|
db = db_factory(init=init_script)
|
|
|
|
act = python_act('db', substitutions=[('[\\d]{2}:[\\d]{2}:[\\d]{2}.[\\d]{2}', ''),
|
|
('Relation [\\d]{3,4}', 'Relation')])
|
|
|
|
expected_stdout = """
|
|
ISQL_MSG Starting EB with infinite pause.
|
|
08:37:01.14 Validation started
|
|
08:37:01.15 Relation 128 (TEST1)
|
|
08:37:02.15 Acquire relation lock failed
|
|
08:37:02.15 Relation 128 (TEST1) : 1 ERRORS found
|
|
08:37:02.15 Relation 129 (TEST2)
|
|
08:37:02.15 process pointer page 0 of 1
|
|
08:37:02.15 Index 1 (TEST2_PK)
|
|
08:37:02.15 Index 2 (TEST2_S)
|
|
08:37:02.15 Index 3 (TEST2_C)
|
|
08:37:02.15 Index 4 (TEST2_T)
|
|
08:37:02.17 Relation 129 (TEST2) is ok
|
|
08:37:02.17 Relation 130 (TEST3)
|
|
08:37:03.17 Acquire relation lock failed
|
|
08:37:03.17 Relation 130 (TEST3) : 1 ERRORS found
|
|
08:37:03.17 Validation finished
|
|
"""
|
|
|
|
hang_script_file = temp_file('hang_script.sql')
|
|
hang_output = temp_file('hang_script.out')
|
|
|
|
@pytest.mark.es_eds
|
|
@pytest.mark.version('>=2.5.5')
|
|
def test_1(act: Action, hang_script_file: Path, hang_output: Path, capsys, request):
|
|
# Fializer for FB4
|
|
def drop_connections():
|
|
with act.db.connect() as con4cleanup:
|
|
con4cleanup.execute_immediate('delete from mon$attachments where mon$attachment_id != current_connection')
|
|
con4cleanup.commit()
|
|
|
|
request.addfinalizer(drop_connections)
|
|
# Following script will hang for sevral seconds (see 'lock timeout' argument - and this will serve as pause
|
|
# during which we can launch fbsvcmgr to validate database:
|
|
hang_script_file.write_text(f"""
|
|
set term ^;
|
|
execute block as
|
|
begin
|
|
execute statement 'drop role tmp$r4707';
|
|
when any do begin end
|
|
end ^
|
|
set term ;^
|
|
commit;
|
|
|
|
set transaction wait;
|
|
|
|
delete from test1;
|
|
insert into test3(id) values(1);
|
|
set list on;
|
|
select 'Starting EB with infinite pause.' as isql_msg from rdb$database;
|
|
set term ^;
|
|
execute block as
|
|
begin
|
|
execute statement 'update test1 set id=-id'
|
|
on external 'localhost:' || rdb$get_context('SYSTEM','DB_NAME')
|
|
as user '{act.db.user}' password '{act.db.password}'
|
|
role 'TMP$R4707' -- this will force to create new attachment, and its Tx will be paused on INFINITE time.
|
|
;
|
|
when any do begin end
|
|
end ^
|
|
set term ;^
|
|
select 'EB with pause finished.' as msg_2 from rdb$database;
|
|
""")
|
|
# Make asynchronous call of ISQL which will stay several seconds in pause due to row-level lock
|
|
with open(hang_output, mode='w') as hang_out:
|
|
p_hang_sql = subprocess.Popen([act.vars['isql'], '-i', str(hang_script_file),
|
|
'-user', act.db.user,
|
|
'-password', act.db.password, act.db.dsn],
|
|
stdout=hang_out, stderr=subprocess.STDOUT)
|
|
try:
|
|
time.sleep(2)
|
|
# Make SYNC. call of fbsvcmgr in order to validate database which has locks on some relations
|
|
act.svcmgr(switches=['action_validate', 'dbname', str(act.db.db_path),
|
|
'val_lock_timeout', '1'])
|
|
finally:
|
|
p_hang_sql.terminate()
|
|
#
|
|
print(hang_output.read_text())
|
|
print(act.stdout)
|
|
act.expected_stdout = expected_stdout
|
|
act.stdout = capsys.readouterr().out
|
|
assert act.clean_stdout == act.clean_expected_stdout
|