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-11-26 19:20:43 +01:00
parent 93a898b9ee
commit c66b267c73
54 changed files with 3573 additions and 2056 deletions

BIN
files/core_5078.zip Normal file

Binary file not shown.

View File

@ -352,11 +352,9 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
expected_stdout_1 = """ expected_stdout_1 = """
RESULT_OF_REQ_COMPARE_TO_ACTUAL EXPECTED: actual values were equal to required. RESULT_OF_REQ_COMPARE_TO_ACTUAL EXPECTED: actual values were equal to required.
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1): def test_1(db_1):
pytest.fail("Test not IMPLEMENTED") pytest.skip("Test requires manipulation with firebird.conf")
#pytest.fail("Test not IMPLEMENTED")

View File

@ -136,9 +136,8 @@ expected_stdout_1 = """
user_1 = user_factory(name='TMP$C1972', password='123') user_1 = user_factory(name='TMP$C1972', password='123')
@pytest.mark.version('>=2.1.1') @pytest.mark.version('>=2.1.1')
@pytest.mark.xfail
def test_1(act_1: Action, user_1: User): def test_1(act_1: Action, user_1: User):
pytest.fail("Test not IMPLEMENTED") pytest.skip("Test can't be implement with new Python driver")
# This test is not possible to implement with new Python driver as it does not # This test is not possible to implement with new Python driver as it does not
# allow to specify `forced_writes` or `reserve_space` options on connect() as tested # allow to specify `forced_writes` or `reserve_space` options on connect() as tested
# configuration options are passed to DPB only for create_database()! # configuration options are passed to DPB only for create_database()!

View File

@ -201,8 +201,6 @@ Expected line found.
""" """
@pytest.mark.version('>=2.5.2') @pytest.mark.version('>=2.5.2')
@pytest.mark.xfail
def test_1(db_1): def test_1(db_1):
pytest.fail("Test not IMPLEMENTED") pytest.skip("Implementation is complicated, and IMHO not worth of realization")
#pytest.fail("Test not IMPLEMENTED")

View File

@ -252,8 +252,7 @@ def test_1(act_1: Action):
c = con.cursor() c = con.cursor()
c.execute('update test set x = -x') c.execute('update test set x = -x')
con.commit() con.commit()
act_1.svcmgr(switches=['localhost:service_mgr', 'user', act_1.db.user, act_1.svcmgr(switches=['action_db_stats', 'dbname',
'password', act_1.db.password, 'action_db_stats', 'dbname',
str(act_1.db.db_path), 'sts_record_versions']) str(act_1.db.db_path), 'sts_record_versions'])
act_1.stdout = '\n'.join([line for line in act_1.stdout.splitlines() if 'versions:' in line.lower()]) act_1.stdout = '\n'.join([line for line in act_1.stdout.splitlines() if 'versions:' in line.lower()])
act_1.expected_stdout = expected_stdout_1 act_1.expected_stdout = expected_stdout_1

View File

@ -23,12 +23,17 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action import time
import re
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
substitutions_1 = [('^((?!PARAM0|EXECUTE_FUNCTION_START|EXECUTE_FUNCTION_FINISH|SA_FUNC|PG_FUNC).)*$', ''), ('LOG_FUNC_ENABLED.*EXECUTE_FUNCTION_START', 'LOG_FUNC_ENABLED EXECUTE_FUNCTION_START'), ('LOG_FUNC_ENABLED.*EXECUTE_FUNCTION_FINISH', 'LOG_FUNC_ENABLED EXECUTE_FUNCTION_FINISH')] substitutions_1 = [('^((?!PARAM0|EXECUTE_FUNCTION_START|EXECUTE_FUNCTION_FINISH|SA_FUNC|PG_FUNC).)*$', ''),
('LOG_FUNC_ENABLED.*EXECUTE_FUNCTION_START', 'LOG_FUNC_ENABLED EXECUTE_FUNCTION_START'),
('LOG_FUNC_ENABLED.*EXECUTE_FUNCTION_FINISH', 'LOG_FUNC_ENABLED EXECUTE_FUNCTION_FINISH')]
init_script_1 = """ init_script_1 = """
set term ^; set term ^;
@ -325,7 +330,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 = """ expected_stdout_1 = """
LOG_FUNC_ENABLED 2016-02-10T15:10:43.5940 (1700:00C52280) EXECUTE_FUNCTION_START LOG_FUNC_ENABLED 2016-02-10T15:10:43.5940 (1700:00C52280) EXECUTE_FUNCTION_START
@ -342,11 +348,100 @@ expected_stdout_1 = """
LOG_FUNC_ENABLED FUNCTION PG_TEST.PG_FUNC: LOG_FUNC_ENABLED FUNCTION PG_TEST.PG_FUNC:
LOG_FUNC_ENABLED PARAM0 = INTEGER, "456" LOG_FUNC_ENABLED PARAM0 = INTEGER, "456"
LOG_FUNC_ENABLED PARAM0 = BIGINT, "207936" LOG_FUNC_ENABLED PARAM0 = BIGINT, "207936"
""" """
def trace_session(act: Action, b: Barrier, logfunc: bool):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_errors = true',
' log_connections = true',
' log_transactions = true',
]
if logfunc:
cfg30.append(' log_function_start = true')
cfg30.append(' log_function_finish = true')
cfg30.append('}')
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line.upper())
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): output = []
pytest.fail("Test not IMPLEMENTED") trace_timestamp_prefix = '[.*\\s+]*20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3,4}\\s+\\(.+\\)'
func_start_ptn = re.compile(trace_timestamp_prefix + '\\s+(FAILED){0,1}\\s*EXECUTE_FUNCTION_START$', re.IGNORECASE)
func_finish_ptn = re.compile(trace_timestamp_prefix + '\\s+(FAILED){0,1}\\s*EXECUTE_FUNCTION_FINISH$', re.IGNORECASE)
func_name_ptn = re.compile('Function\\s+(SA_FUNC|PG_TEST.PG_FUNC):$')
func_param_prn = re.compile('param[0-9]+\\s+=\\s+', re.IGNORECASE)
#
func_script = """
set list on;
set term ^;
execute block as -- returns( sa_func_result bigint, pg_func_result bigint ) as
declare sa_func_result bigint;
declare pg_func_result bigint;
begin
sa_func_result = sa_func(%s);
pg_func_result = pg_test.pg_func(%s);
--suspend;
end
^
set term ;^
commit;
"""
# Case 1: Trace functions enabled
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b, True])
trace_thread.start()
b.wait()
try:
act_1.isql(switches=['-n', '-q'], input=func_script % (123, 456))
time.sleep(2)
finally:
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
#
trace_log = capsys.readouterr().out
for line in trace_log.splitlines():
if (func_start_ptn.search(line)
or func_finish_ptn.search(line)
or func_name_ptn.search(line)
or func_param_prn.search(line) ):
output.append('LOG_FUNC_ENABLED ' + line.upper())
# Case 1: Trace functions disabled
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b, False])
trace_thread.start()
b.wait()
try:
act_1.isql(switches=['-n', '-q'], input=func_script % (789, 987))
time.sleep(2)
finally:
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
#
trace_log += capsys.readouterr().out
for line in trace_log.splitlines():
if (func_start_ptn.search(line)
or func_finish_ptn.search(line)
or func_name_ptn.search(line)
or func_param_prn.search(line) ):
print('LOG_FUNC_DISABLED ' + line.upper())
# Test
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.stdout = '\n'.join(output)
assert act_1.clean_stderr == act_1.clean_expected_stderr

View File

@ -11,7 +11,8 @@
# qmid: None # qmid: None
import pytest 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 # version: 3.0
# resources: None # resources: None
@ -118,7 +119,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 = """ expected_stdout_1 = """
PARAMETERS: PARAMETERS:
@ -130,11 +132,63 @@ expected_stdout_1 = """
BLR TO SOURCE MAPPING: BLR TO SOURCE MAPPING:
BLR OFFSET LINE COLUMN BLR OFFSET LINE COLUMN
VALUES: <OFFSET> <LINE> <COLUMN> VALUES: <OFFSET> <LINE> <COLUMN>
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): # -- NB: i'm not sure that this test properly reflects the trouble described in the ticket.
pytest.fail("Test not IMPLEMENTED") # -- At least on 3.0 Alpha 1, Alpha 2 and Beta 2 (31807) output is identical.
# -- Note that value in "BLR to Source mapping" under 'Column' was changed to reflect
# -- real offset from the beginning of line in THIS .fbt file (right shifted on 4 character).
sql_script = """
set blob all;
set list on;
select rdb$debug_info from rdb$procedures;
"""
act_1.isql(switches=[], input=sql_script)
# RDB$DEBUG_INFO 1a:1e1
# Parameters:
# Number Name Type
# --------------------------------------------------
# 0 A_ID INPUT
# 0 O_TXT OUTPUT
#
# Variables:
# Number Name
# -------------------------------------------
# 0 O_TXT
#
# BLR to Source mapping:
# BLR offset Line Column
# --------------------------------
# 42 2 79
# ^ ^ ^
# | | |
# +-----------+----------+---- all of them can vary!
# Print content of log with filtering lines:we are interesting only for rows
# which contain words: {'Parameters', 'Number', 'Variables', 'BLR'}.
# For last line (with three numbers for offset, line and col) we just check
# matching of row to appropriate pattern.
# NB: we remove all exsessive spaces from printed lines.
pattern = re.compile("[\\s]+[0-9]+[\\s]+[0-9]+[\\s]+[0-9]+")
for line in act_1.stdout.splitlines():
line = line.upper()
if ('PARAMETER' in line or
'NUMBER' in line or
'INPUT' in line or
'OUTPUT' in line or
'VARIABLE' in line or
'BLR' in line):
print(' '.join(line.split()).upper())
if pattern.match(line):
print('VALUES: <OFFSET> <LINE> <COLUMN>')
# Test
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

@ -19,12 +19,13 @@
# qmid: # qmid:
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 4.0 # version: 4.0
# resources: None # resources: None
substitutions_1 = [('^((?!nodes).)*$', ''), ('Root page: [0-9]+,', ''), ('Depth', 'depth')] substitutions_1 = [('^((?!nodes).)*$', ''),
('Root page: [0-9]+,', ''), ('Depth', 'depth')]
init_script_1 = """""" init_script_1 = """"""
@ -61,15 +62,37 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# runProgram( 'gstat',['-i', dsn] ) # runProgram( 'gstat',['-i', dsn] )
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
Root page: 203, depth: 1, leaf buckets: 1, nodes: 1 Root page: 203, depth: 1, leaf buckets: 1, nodes: 1
""" """
@pytest.mark.version('>=4.0') @pytest.mark.version('>=4.0')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): sql_scipt = """
pytest.fail("Test not IMPLEMENTED") create table g_test (f integer);
create index g_ind on g_test (f);
insert into g_test values (1);
commit;
update g_test set f=2;
savepoint a;
update g_test set f=3;
savepoint b;
update g_test set f=4;
savepoint c;
update g_test set f=5;
savepoint d;
update g_test set f=6;
savepoint e;
update g_test set f=7;
commit;
select * from g_test;
"""
act_1.isql(switches=['-q'], input=sql_scipt)
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.gstat(switches=['-i'])
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -11,7 +11,8 @@
# qmid: None # qmid: None
import pytest 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.6 # version: 3.0.6
# resources: None # resources: None
@ -125,7 +126,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 = """ expected_stdout_1 = """
Error while commiting transaction: Error while commiting transaction:
@ -169,11 +171,89 @@ expected_stdout_1 = """
- unsuccessful metadata update - unsuccessful metadata update
- object INDEX "TEST2_ID_X_DESC" is in use - object INDEX "TEST2_ID_X_DESC" is in use
335544345 335544345
""" """
@pytest.mark.version('>=3.0.6') @pytest.mark.version('>=3.0.6')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): ddl_script = """
pytest.fail("Test not IMPLEMENTED") set bail on;
create or alter procedure sp_worker as begin end;
create or alter procedure sp_test as begin end;
create or alter view v_test as select 1 x from rdb$database;
commit;
recreate table test1(id int,x int);
recreate table test2(id int,x int);
commit;
create index test1_id on test1(id);
commit;
create descending index test2_id_x_desc on test2(id,x);
commit;
create or alter view v_test as select id,x from test1 where id between 15 and 30;
commit;
set term ^;
create or alter procedure sp_worker(a_id int) returns(x int) as
begin
for
execute statement ('select v.x from v_test v where v.id = ? and exists(select * from test2 b where b.id = v.id)') (:a_id)
into x
do
suspend;
end
^
create or alter procedure sp_test(a_id int) returns(x int) as
begin
for
execute statement ('select x from sp_worker(?)') (:a_id)
into x
do
suspend;
end
^
set term ;^
commit;
insert into test1 values(11,111);
insert into test1 values(21,222);
insert into test1 values(31,333);
insert into test1 values(41,444);
commit;
insert into test2 select * from test1;
commit;
"""
act_1.isql(switches=[], input=ddl_script)
#
tpb = TPB(isolation=Isolation.READ_COMMITTED_NO_RECORD_VERSION, lock_timeout=0).get_buffer()
with act_1.db.connect() as con:
cur1 = con.cursor()
cur1.execute('select x from sp_test(21)').fetchall()
drop_commands = ['drop procedure sp_test',
'drop procedure sp_worker',
'drop view v_test',
'drop table test2',
'drop index test1_id',
'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.begin()
cur2 = tx.cursor()
try:
cur2.execute(cmd)
except Exception as exc:
print(exc)
#
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
# [pcisar] 22.11.2021
# This test requires READ_COMMITTED_NO_RECORD_VERSION transaction to work, which
# requires ReadConsistency disabled in FB 4. However, it does not work as expected
# because all drop commands pass without exception even with ReadConsistency disabled.
# Not yet tested with FB3. I also expect it FAIL due to exception differences in FDB
# and new driver (this will be fixed once we make it to raise "object in use" exception)
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -34,19 +34,23 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action import subprocess
import time
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
# version: 3.0 # version: 3.0
# resources: None # resources: None
substitutions_1 = [('(-)?concurrent\\s+transaction\\s+number(\\s+is)?\\s+\\d+', 'concurrent transaction'), ('After\\s+line\\s+\\d+.*', '')] substitutions_1 = [('(-)?concurrent\\s+transaction\\s+number(\\s+is)?\\s+\\d+', 'concurrent transaction'),
('After\\s+line\\s+\\d+.*', '')]
init_script_1 = """ init_script_1 = """
create table test(id int primary key, x int); create table test(id int primary key, x int);
commit; commit;
insert into test values(1, 100); insert into test values(1, 100);
commit; commit;
""" """
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -143,18 +147,44 @@ 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 = """ expected_stdout_1 = """
Statement failed, SQLSTATE = 40001 Statement failed, SQLSTATE = 40001
deadlock deadlock
-update conflicts with concurrent update -update conflicts with concurrent update
-concurrent transaction number is 13 -concurrent transaction number is 13
""" """
test_script_1 = temp_file('test-script.sql')
script_out = temp_file('test-script.out')
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, test_script_1: Path, script_out: Path):
def test_1(db_1): with act_1.db.connect() as att1:
pytest.fail("Test not IMPLEMENTED") # Delete record but not yet commit - it's a time
# to make another connection:
att1.execute_immediate("delete from test where id = 1")
test_script_1.write_text("""
set list on;
-- set echo on;
commit;
set transaction lock timeout 20;
select x from test where id = 1 with lock;
""")
try:
with open(script_out, mode='w') as output:
p_test_sql = subprocess.Popen([act_1.vars['isql'], '-n', '-i', str(test_script_1),
'-user', act_1.db.user,
'-password', act_1.db.password, act_1.db.dsn],
stdout=output, stderr=subprocess.STDOUT)
#
time.sleep(2)
finally:
att1.commit()
p_test_sql.wait()
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = script_out.read_text()
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -9,7 +9,8 @@
# qmid: # qmid:
import pytest 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 # version: 3.0
# resources: None # resources: None
@ -40,7 +41,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# print ('Log file deleted.') # print ('Log file deleted.')
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
Starting backup... Starting backup...
@ -49,11 +51,23 @@ expected_stdout_1 = """
Backup file deleted. Backup file deleted.
Delete log file... Delete log file...
Log file deleted. Log file deleted.
""" """
backup_file_1 = temp_file('backup.fbk')
log_file_1 = temp_file('A012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.log')
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, capsys, log_file_1: Path, backup_file_1: Path):
def test_1(db_1): print ('Starting backup...')
pytest.fail("Test not IMPLEMENTED") act_1.gbak(switches=['-b', '-v', '-y', str(log_file_1), str(act_1.db.db_path), str(backup_file_1)])
print ('Backup finished.')
if backup_file_1.is_file():
print ('Delete backup file...')
backup_file_1.unlink()
print ('Backup file deleted.')
print ('Delete log file...')
log_file_1.unlink()
print ('Log file deleted.')
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

@ -15,7 +15,9 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -24,7 +26,7 @@ substitutions_1 = [('[ \t]+', ' '), ('[ \t]+[\\d]+[ \t]+ms', '')]
init_script_1 = """ init_script_1 = """
recreate table test(x int); recreate table test(x int);
""" """
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -194,17 +196,53 @@ 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 = """ expected_stdout_1 = """
Select Expression Select Expression
-> Aggregate -> Aggregate
-> Table "TEST" Full Scan -> Table "TEST" Full Scan
""" """
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_initfini = false',
' print_plan = true',
' explain_plan = true',
' log_statement_prepare = true',
' include_filter=%(from|join)[[:whitespace:]]test%',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): b = Barrier(2)
pytest.fail("Test not IMPLEMENTED") trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
act_1.isql(switches=[], input='select count(*) from test;')
time.sleep(2)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
#
show_line = 0
for line in capsys.readouterr().out.splitlines():
show_line = (show_line + 1 if ('^' * 79) in line or show_line>0 else show_line)
if show_line > 1:
print(line)
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

@ -9,16 +9,14 @@
# qmid: # qmid:
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 2.5.4 # version: 2.5.4
# resources: None # resources: None
substitutions_1 = [('Failure: Database error', '')] substitutions_1 = [('Failure: Database error', '')]
init_script_1 = """ init_script_1 = """"""
-- NB: line `Failure: Database error` exists only in 2.5.x output.
"""
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -26,7 +24,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#--- #---
# runProgram('nbackup',['-user','nonExistentFoo','-pas','invalidBar','-L',dsn]) # runProgram('nbackup',['-user','nonExistentFoo','-pas','invalidBar','-L',dsn])
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stderr_1 = """ expected_stderr_1 = """
[ [
@ -34,11 +33,13 @@ expected_stderr_1 = """
Your user name and password are not defined. Ask your database administrator to set up a Firebird login. Your user name and password are not defined. Ask your database administrator to set up a Firebird login.
SQLCODE:-902 SQLCODE:-902
] ]
""" """
@pytest.mark.version('>=2.5.4') @pytest.mark.version('>=2.5.4')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): act_1.expected_stderr = expected_stderr_1
pytest.fail("Test not IMPLEMENTED") act_1.nbackup(switches=['-user', 'nonExistentFoo', '-password', 'invalidBar',
'-L', act_1.db.dsn], credentials=False)
assert act_1.clean_stderr == act_1.clean_expected_stderr

View File

@ -22,7 +22,9 @@
# qmid: None # qmid: None
import pytest 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
from firebird.driver import SrvRestoreFlag
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -260,7 +262,7 @@ init_script_1 = """
set term ;^ set term ;^
commit; commit;
""" """
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1) db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
@ -282,18 +284,24 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# os.remove(fbn) # os.remove(fbn)
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
Creating backup...
Creating restore...
METEO METEO
WF WF
""" """
fbk_file_1 = temp_file('test.fbk')
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, fbk_file_1: Path):
def test_1(db_1): with act_1.connect_server() as srv:
pytest.fail("Test not IMPLEMENTED") srv.database.backup(database=str(act_1.db.db_path), backup=str(fbk_file_1))
srv.wait()
srv.database.restore(backup=str(fbk_file_1), database=str(act_1.db.db_path),
flags=SrvRestoreFlag.REPLACE)
srv.wait()
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q'], input='show view; show package;')
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -27,7 +27,8 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from difflib import unified_diff
from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -127,8 +128,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# for line in f: # for line in f:
# if line.split() and not 'Database:' in line: # if line.split() and not 'Database:' in line:
# # This line must be ignored: # # This line must be ignored:
# # Database: localhost/3333:C:\\FBTESTING\\qa # # Database: localhost/3333:C:\\FBTESTING\\qa\\fbt-repo\\tmp\\bugs.core_4472.fdb, User: SYSDBA
# bt-repo mpugs.core_4472.fdb, User: SYSDBA
# print('UNEXPECTED: ' + line) # print('UNEXPECTED: ' + line)
# #
# #
@ -151,15 +151,41 @@ 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)
OK: log was not changed.
"""
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): script = """
pytest.fail("Test not IMPLEMENTED") set autoddl off;
commit;
set term ^;
create or alter function fn_01() returns int
as begin
return 1;
end
^
create or alter procedure sp_01
as
declare function fn_internal_01 returns int as
begin
if ( fn_01() > 0 ) then return 1;
else return 0;
end
begin
end
^
set term ;^
commit;
"""
with act_1.connect_server() as srv:
srv.info.get_log()
log_before = srv.readlines()
act_1.expected_stdout = ''
act_1.isql(switches=['-q', '-m'], input=script)
with act_1.connect_server() as srv:
srv.info.get_log()
log_after = srv.readlines()
assert act_1.clean_stdout == act_1.clean_expected_stdout
assert list(unified_diff(log_before, log_after)) == []

View File

@ -22,25 +22,14 @@
# qmid: # qmid:
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action, user_factory, User
# version: 3.0 # version: 3.0
# resources: None # resources: None
substitutions_1 = [] substitutions_1 = []
init_script_1 = """ init_script_1 = ""
create or alter user TMP$C4503_BILL password '123';
create or alter user TMP$C4503_JOHN password '456';
create or alter user TMP$C4503_MICK password '789';
create or alter user TMP$C4503_BOSS password '000';
-- do NOT remove or change name 'test' - it is used in several old tests, see resources/test_user.fbr:
-- core_1083.fbt core_1845.fbt core_1148.fbt core_2729.fbt -- all of them can create user 'TEST' and do not remove it.
create or alter user test password 'test';
drop user test; -- immediatelly remove this name
commit;
"""
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -96,7 +85,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# ''' # '''
# runProgram('isql',[dsn,'-q'],script) # runProgram('isql',[dsn,'-q'],script)
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
IS_CURRENT_USER # IS_CURRENT_USER #
@ -118,11 +108,50 @@ expected_stdout_1 = """
IS_CURRENT_USER IS_CURRENT_USER
USER_NAME TMP$C4503_MICK USER_NAME TMP$C4503_MICK
KEEPS_ATTACHMENTS 1 KEEPS_ATTACHMENTS 1
""" """
user_bill = user_factory(name='TMP$C4503_BILL', password='123')
user_john = user_factory(name='TMP$C4503_JOHN', password='456')
user_mick = user_factory(name='TMP$C4503_MICK', password='789')
user_boss = user_factory(name='TMP$C4503_BOSS', password='000')
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, user_bill: User, user_john: User, user_mick: User, user_boss: User):
def test_1(db_1): with act_1.db.connect() as con_0a, act_1.db.connect(), \
pytest.fail("Test not IMPLEMENTED") act_1.db.connect(user='TMP$C4503_BILL', password='123'), \
act_1.db.connect(user='TMP$C4503_BILL', password='123'), \
act_1.db.connect(user='TMP$C4503_BILL', password='123'), \
act_1.db.connect(user='TMP$C4503_BILL', password='123'), \
act_1.db.connect(user='TMP$C4503_BILL', password='123'), \
act_1.db.connect(user='TMP$C4503_JOHN', password='456'), \
act_1.db.connect(user='TMP$C4503_JOHN', password='456'), \
act_1.db.connect(user='TMP$C4503_JOHN', password='456'), \
act_1.db.connect(user='TMP$C4503_JOHN', password='456'), \
act_1.db.connect(user='TMP$C4503_MICK', password='789'):
#
script = """
set list on;
-- "SHOW USERS" command actually runs following query:
select
case
when coalesce(mon$user, sec$user_name) = current_user
then '#'
when sec$user_name is distinct from null
then ' '
else '-'
end is_current_user
,coalesce(m.mon$user, u.sec$user_name) user_name
,iif( m.mon$user = upper('SYSDBA'), 1, count(m.mon$user) ) keeps_attachments
from mon$attachments m
full join sec$users u on m.mon$user = u.sec$user_name
where
coalesce(mon$system_flag, 0) = 0
and coalesce(m.mon$user, u.sec$user_name) in ( upper('TMP$C4503_BILL'), upper('TMP$C4503_BOSS'), upper('TMP$C4503_JOHN'), upper('TMP$C4503_MICK'), upper('SYSDBA') )
group by mon$user, sec$user_name
order by coalesce(mon$user, sec$user_name);
commit;
"""
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q'], input=script)
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -34,6 +34,8 @@
# KHOLDER_NAME = 'KeyHolder' if os.name == 'nt' else "fbSampleKeyHolder" # KHOLDER_NAME = 'KeyHolder' if os.name == 'nt' else "fbSampleKeyHolder"
# #
# #
# [pcisar] 23.11.2021
# Test not implemented because it depends on 3rd party encryption plugin.
# tracker_id: CORE-4524 # tracker_id: CORE-4524
# min_versions: ['4.0'] # min_versions: ['4.0']
# versions: 4.0 # versions: 4.0
@ -367,11 +369,9 @@ expected_stdout_1 = """
2147483646 feffff7f NOT FOUND. 2147483646 feffff7f NOT FOUND.
EXPECTED BACKUP FINISH FOUND: GBAK:CLOSING FILE, COMMITTING, AND FINISHING. EXPECTED BACKUP FINISH FOUND: GBAK:CLOSING FILE, COMMITTING, AND FINISHING.
EXPECTED RESTORE FINISH FOUND: GBAK:ADJUSTING THE ONLINE AND FORCED WRITES FLAGS EXPECTED RESTORE FINISH FOUND: GBAK:ADJUSTING THE ONLINE AND FORCED WRITES FLAGS
""" """
@pytest.mark.version('>=4.0') @pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1): def test_1(db_1):
pytest.fail("Test not IMPLEMENTED") pytest.skip("Test requires 3rd party encryption plugin")
#pytest.fail("Test not IMPLEMENTED")

View File

@ -12,18 +12,24 @@
# FB40SC, build 4.0.0.645: OK, 2.703ss. # FB40SC, build 4.0.0.645: OK, 2.703ss.
# FB40SS, build 4.0.0.645: OK, 2.187ss. # FB40SS, build 4.0.0.645: OK, 2.187ss.
# #
# [pcisar] 23.11.2021
# This test FAILs on v4.0.0.2496 as database couldn't be reverted to online state, not yet tested with 3.0
# tracker_id: CORE-4582 # tracker_id: CORE-4582
# min_versions: ['3.0'] # min_versions: ['3.0']
# versions: 3.0 # versions: 3.0
# qmid: # qmid:
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
from firebird.driver import DbWriteMode, DbAccessMode, ShutdownMode, ShutdownMethod, \
SrvStatFlag
# version: 3.0 # version: 3.0
# resources: None # resources: None
substitutions_1 = [('^((?!:::MSG:::|buffers|before|after|Attributes).)*$', ''), ('Page buffers([\t]|[ ])+', 'Page buffers '), ('Attributes([\t]|[ ])+', 'Attributes '), ('N/A', 'YES')] substitutions_1 = [('^((?!:::MSG:::|buffers|before|after|Attributes).)*$', ''),
('Page buffers([\t]|[ ])+', 'Page buffers '),
('Attributes([\t]|[ ])+', 'Attributes '), ('N/A', 'YES')]
init_script_1 = """ init_script_1 = """
-- Result of this test on WI-T3.0.0.31374 Beta 1: -- Result of this test on WI-T3.0.0.31374 Beta 1:
@ -40,7 +46,7 @@ init_script_1 = """
create or alter procedure sp_get_buff returns(mon_buffers int) as create or alter procedure sp_get_buff returns(mon_buffers int) as
begin begin
mon_buffers = -1; mon_buffers = -1;
if ( exists( select * from mon$attachments where mon$user containing 'cache writer' and mon$system_flag = 1 ) ) if (exists(select * from mon$attachments where mon$user containing 'cache writer' and mon$system_flag = 1))
then then
select mon$page_buffers from mon$database into mon_buffers; select mon$page_buffers from mon$database into mon_buffers;
@ -52,7 +58,7 @@ init_script_1 = """
commit; commit;
recreate table log(buf_before int, buf_after int); recreate table log(buf_before int, buf_after int);
commit; commit;
""" """
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -101,7 +107,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# print (':::MSG::: ISQL for extract old and new value of page finished.') # print (':::MSG::: ISQL for extract old and new value of page finished.')
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
:::MSG::: Starting ISQL setting new value for linger... :::MSG::: Starting ISQL setting new value for linger...
@ -114,11 +121,64 @@ expected_stdout_1 = """
:::MSG::: Starting ISQL for extract old and new value of page buffers... :::MSG::: Starting ISQL for extract old and new value of page buffers...
GFIX could change buffers ? => YES GFIX could change buffers ? => YES
:::MSG::: ISQL for extract old and new value of page finished. :::MSG::: ISQL for extract old and new value of page finished.
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): script_1 = """
pytest.fail("Test not IMPLEMENTED") insert into log(buf_before) select mon_buffers from sp_get_buff;
commit;
alter database set linger to 15;
commit;
set list on;
select rdb$linger as ":::MSG::: linger_time" from rdb$database;
"""
print (':::MSG::: Starting ISQL setting new value for linger...')
act_1.isql(switches=[], input=script_1)
print (':::MSG::: ISQL setting new value for linger finished.')
print (':::MSG::: Starting GFIX setting new value for page buffers...')
#with act_1.connect_server() as srv:
#srv.database.set_default_cache_size(database=str(act_1.db.db_path), size=3791)
#srv.database.set_write_mode(database=str(act_1.db.db_path), mode=DbWriteMode.ASYNC)
#srv.database.set_access_mode(database=str(act_1.db.db_path), mode=DbAccessMode.READ_ONLY)
#srv.database.shutdown(database=str(act_1.db.db_path), mode=ShutdownMode.SINGLE,
#method=ShutdownMethod.DENNY_ATTACHMENTS, timeout=20)
#srv.database.get_statistics(database=str(act_1.db.db_path), flags=SrvStatFlag.HDR_PAGES,
#callback=print)
#srv.database.bring_online(database=str(act_1.db.db_path))
#srv.database.set_access_mode(database=str(act_1.db.db_path), mode=DbAccessMode.READ_WRITE)
act_1.reset()
act_1.gfix(switches=['-buffers', '3791', act_1.db.dsn])
act_1.reset()
act_1.gfix(switches=['-write','async', act_1.db.dsn])
act_1.reset()
act_1.gfix(switches=['-mode','read_only', act_1.db.dsn])
act_1.reset()
act_1.gfix(switches=['-shutdown','single', '-at', '20', act_1.db.dsn])
act_1.reset()
act_1.gstat(switches=['-h'])
print(act_1.stdout)
act_1.reset()
act_1.gfix(switches=[act_1.db.dsn, '-online'])
act_1.reset()
act_1.gfix(switches=['-mode','read_write', act_1.db.dsn])
print (':::MSG::: GFIX setting new value for page buffers finished.')
print (':::MSG::: Starting ISQL for extract old and new value of page buffers...')
script_2 = """
set list on;
update log set buf_after = (select mon_buffers from sp_get_buff);
commit;
select iif( g.buf_before > 0,
iif( g.buf_before is distinct from g.buf_after, 'YES', 'NO!' ),
'N/A'
) as "GFIX could change buffers ? =>"
from log g;
"""
act_1.reset()
act_1.isql(switches=[], input=script_2)
print(act_1.stdout)
print (':::MSG::: ISQL for extract old and new value of page finished.')
# Check
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_expected_stdout == act_1.clean_expected_stdout

View File

@ -18,7 +18,8 @@
# qmid: None # qmid: None
import pytest 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: 2.5.6 # version: 2.5.6
# resources: None # resources: None
@ -52,12 +53,28 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# runProgram('isql',[dsn,'-user',user_name,'-password',user_password],script) # runProgram('isql',[dsn,'-user',user_name,'-password',user_password],script)
# #
#--- #---
#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.6') @pytest.mark.version('>=2.5.6')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): with act_1.connect_server() as srv:
pytest.fail("Test not IMPLEMENTED") srv.database.set_access_mode(database=str(act_1.db.db_path), mode=DbAccessMode.READ_ONLY)
script = """
commit;
set transaction read committed;
set term ^;
execute block as
declare n int = 20000;
begin
while (n>0) do
in autonomous transaction do
select :n-1 from rdb$database into n;
end
^
set term ;^
commit;
"""
act_1.isql(switches=[], input=script)
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -9,23 +9,28 @@
# qmid: # qmid:
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from io import BytesIO
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, user_factory, User, temp_file
from firebird.driver import SrvRestoreFlag
# version: 3.0 # version: 3.0
# resources: None # resources: None
substitutions_1 = [] substitutions_1 = []
init_script_1 = """ init_script_1 = ""
set wng off;
create or alter user tmp$c4648 password '123' revoke admin role; #init_script_1 = """
commit; #set wng off;
revoke all on all from tmp$c4648; #create or alter user tmp$c4648 password '123' revoke admin role;
-- 'create ... grant admin role' or 'grant rdb$admin' are NOT neccessary #commit;
-- for enabling to creating database by non-sysdba user: #revoke all on all from tmp$c4648;
grant create database to user tmp$c4648; #-- 'create ... grant admin role' or 'grant rdb$admin' are NOT neccessary
commit; #-- for enabling to creating database by non-sysdba user:
""" #grant create database to user tmp$c4648;
#commit;
#"""
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -69,26 +74,63 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# runProgram('isql',[dsn,'-q','-user',user_name,'-password',user_password],script) # runProgram('isql',[dsn,'-q','-user',user_name,'-password',user_password],script)
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
Starting backup... Starting backup...
Backup finished. Backup finished.
Starting restore using NON sysdba user account... Starting restore using NON sysdba user account...
Restore using NON sysdba user account finished. Restore using NON sysdba user account finished.
Delete backup file...
Backup file deleted.
Starting ISQL using NON sysdba user account... Starting ISQL using NON sysdba user account...
Who am I: TMP$C4648 Who am I: TMP$C4648
Used protocol: TCP Used protocol: TCP
Connected to restored DB ? YES Connected to restored DB ? YES
Owner of DB is: TMP$C4648 Owner of DB is: TMP$C4648
ISQL using NON sysdba user account finished. ISQL using NON sysdba user account finished.
""" """
user_1 = user_factory(name='tmp$c4648', password='123')
temp_db_1 = temp_file('tmp4648.fdb')
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, user_1: User, temp_db_1: Path, capsys):
def test_1(db_1): with act_1.db.connect() as con:
pytest.fail("Test not IMPLEMENTED") c = con.cursor()
#-- 'create ... grant admin role' or 'grant rdb$admin' are NOT neccessary
#-- for enabling to creating database by non-sysdba user:
c.execute('grant create database to user tmp$c4648')
con.commit()
#
print ('Starting backup...')
backup = BytesIO()
with act_1.connect_server() as srv:
srv.database.local_backup(database=str(act_1.db.db_path), backup_stream=backup)
print ('Backup finished.')
backup.seek(0)
with act_1.connect_server(user=user_1.name, password=user_1.password) as srv:
print ('Starting restore using NON sysdba user account...')
srv.database.local_restore(database=str(temp_db_1), backup_stream=backup,
flags=SrvRestoreFlag.REPLACE)
print ('Restore using NON sysdba user account finished.')
#
script = """
set list on;
select
a.mon$user as "Who am I:"
,left(a.mon$remote_protocol,3) as "Used protocol:"
,iif(m.mon$database_name containing 'tmp4648.fdb','YES','NO! ' || m.mon$database_name ) as "Connected to restored DB ?"
,m.mon$owner as "Owner of DB is:"
from mon$attachments a, mon$database m
where a.mon$attachment_id=current_connection;
commit;
"""
print ('Starting ISQL using NON sysdba user account...')
act_1.isql(switches=['-q', '-user', 'tmp$c4648', '-pas', '123', f'localhost:{temp_db_1}'],
connect_db=False, input=script)
print(act_1.stdout)
print ('ISQL using NON sysdba user account finished.')
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

@ -11,12 +11,16 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action import subprocess
import time
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
# version: 2.5.5 # version: 2.5.5
# resources: None # resources: None
substitutions_1 = [('[\\d]{2}:[\\d]{2}:[\\d]{2}.[\\d]{2}', ''), ('Relation [\\d]{3,4}', 'Relation')] substitutions_1 = [('[\\d]{2}:[\\d]{2}:[\\d]{2}.[\\d]{2}', ''),
('Relation [\\d]{3,4}', 'Relation')]
init_script_1 = """ init_script_1 = """
set term ^; set term ^;
@ -42,7 +46,7 @@ init_script_1 = """
create index test2_c on test2 computed by(s); create index test2_c on test2 computed by(s);
create index test2_t on test2 computed by(t); create index test2_t on test2 computed by(t);
commit; commit;
""" """
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -180,7 +184,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 = """ expected_stdout_1 = """
ISQL_MSG Starting EB with infinite pause. ISQL_MSG Starting EB with infinite pause.
@ -199,11 +204,67 @@ expected_stdout_1 = """
08:37:03.17 Acquire relation lock failed 08:37:03.17 Acquire relation lock failed
08:37:03.17 Relation 130 (TEST3) : 1 ERRORS found 08:37:03.17 Relation 130 (TEST3) : 1 ERRORS found
08:37:03.17 Validation finished 08:37:03.17 Validation finished
""" """
hang_script_1 = temp_file('hang_script.sql')
hang_output_1 = temp_file('hang_script.out')
@pytest.mark.version('>=2.5.5') @pytest.mark.version('>=2.5.5')
@pytest.mark.xfail def test_1(act_1: Action, hang_script_1: Path, hang_output_1: Path, capsys, request):
def test_1(db_1): # Fializer for FB4
pytest.fail("Test not IMPLEMENTED") def drop_connections():
with act_1.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_1.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_1.db.user}' password '{act_1.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_1, mode='w') as hang_out:
p_hang_sql = subprocess.Popen([act_1.vars['isql'], '-i', str(hang_script_1),
'-user', act_1.db.user,
'-password', act_1.db.password, act_1.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_1.svcmgr(switches=['action_validate', 'dbname', str(act_1.db.db_path),
'val_lock_timeout', '1'])
finally:
p_hang_sql.terminate()
#
print(hang_output_1.read_text())
print(act_1.stdout)
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

@ -2,19 +2,22 @@
# #
# id: bugs.core_4715 # id: bugs.core_4715
# title: Restore of shadowed database fails using -k ("restore without shadow") switch # title: Restore of shadowed database fails using -k ("restore without shadow") switch
# decription: # decription: [pcisar] 23.11.2021
# For unknow reason, on v4.0.0.2496 the gstat -h does not report active shadow
# and test thus fail.
# tracker_id: CORE-4715 # tracker_id: CORE-4715
# min_versions: ['3.0'] # min_versions: ['3.0']
# versions: 3.0 # versions: 3.0
# qmid: None # qmid: None
import pytest 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 # version: 3.0
# resources: None # resources: None
substitutions_1 = [('^((?!HASH_IN_SOURCE|RDB\\$SHADOW_NUMBER|HASH_IN_RESTORED|Attributes).)*$', ''), ('[ ]+', ' '), ('[\t]*', ' ')] substitutions_1 = [('^((?!HASH_IN_SOURCE|RDB\\$SHADOW_NUMBER|HASH_IN_RESTORED|Attributes).)*$', '')]
init_script_1 = """ init_script_1 = """
-- Confirmed on WI-T3.0.0.31374: -- Confirmed on WI-T3.0.0.31374:
@ -24,7 +27,7 @@ init_script_1 = """
-- gbak:Exiting before completion due to errors -- gbak:Exiting before completion due to errors
recreate table test(s varchar(30)); recreate table test(s varchar(30));
commit; commit;
""" """
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1) db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
@ -48,7 +51,8 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# os.remove(fbn) # os.remove(fbn)
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
Creating shadow... Creating shadow...
@ -56,11 +60,30 @@ HASH_IN_SOURCE 1499836372373901520
RDB$SHADOW_NUMBER 1 RDB$SHADOW_NUMBER 1
Attributes force write, active shadow Attributes force write, active shadow
HASH_IN_RESTORED 1499836372373901520 HASH_IN_RESTORED 1499836372373901520
""" """
fbk_1 = temp_file('core_4715-shadowed.fbk')
fbn_1 = temp_file('core_4715-restored.fdb')
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, fbk_1: Path, fbn_1: Path, capsys):
def test_1(db_1): act_1.isql(switches=['-q'],
pytest.fail("Test not IMPLEMENTED") input=f'''create shadow 1 '{fbn_1.with_suffix('.shd')}'; commit; insert into test select 'line #'||lpad(row_number()over(), 3, '0') from rdb$types rows 200; commit; set list on; select hash(list(s)) hash_in_source from test; select * from rdb$files;''')
print(act_1.stdout)
act_1.reset()
act_1.gstat(switches=['-h'])
print(act_1.stdout)
act_1.reset()
act_1.gbak(switches=['-b', act_1.db.dsn, str(fbk_1)])
act_1.reset()
act_1.gbak(switches=['-rep', '-k', str(fbk_1), str(fbn_1)])
act_1.reset()
act_1.isql(switches=['-q', '-user', act_1.db.user, '-password', act_1.db.password,
str(fbn_1)], connect_db=False,
input='set list on; select hash(list(s)) hash_in_restored from test;')
print(act_1.stdout)
#
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

@ -56,7 +56,9 @@
# qmid: None # qmid: None
import pytest 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
from firebird.driver import ShutdownMode, ShutdownMethod
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -252,7 +254,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 = """ expected_stdout_1 = """
-- Executed with role: NONE. Expressions that passes WITHOUT errors: -- Executed with role: NONE. Expressions that passes WITHOUT errors:
@ -285,11 +288,104 @@ expected_stdout_1 = """
VULNERABLE_EXPR update RDB$TYPES t set t.RDB$TYPE_NAME = 'C' where coalesce(rdb$system_flag,0)=0 rows 1 returning t.rdb$db_key; -- length of returned rdb$dbkey=8 VULNERABLE_EXPR update RDB$TYPES t set t.RDB$TYPE_NAME = 'C' where coalesce(rdb$system_flag,0)=0 rows 1 returning t.rdb$db_key; -- length of returned rdb$dbkey=8
VULNERABLE_EXPR update RDB$TYPES t set t.RDB$TYPE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1 returning t.rdb$db_key; -- length of returned rdb$dbkey=8 VULNERABLE_EXPR update RDB$TYPES t set t.RDB$TYPE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1 returning t.rdb$db_key; -- length of returned rdb$dbkey=8
-- gdscode list for blocked: 335544926 -- gdscode list for blocked: 335544926
""" """
dba_privileged_user = user_factory(name='tmp_c4731_cooldba', password='123')
non_privileged_user = user_factory(name='tmp_c4731_manager', password='123')
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, dba_privileged_user: User, non_privileged_user: User, capsys):
def test_1(db_1): # Run prepare script
pytest.fail("Test not IMPLEMENTED") prep_script = (act_1.vars['files'] / 'core_4731.sql').read_text()
prep_script = prep_script % {'dba_privileged_name': dba_privileged_user.name,
'non_privileged_name': non_privileged_user.name}
act_1.isql(switches=['-q'], input=prep_script)
#
with act_1.connect_server() as srv:
srv.database.shutdown(database=str(act_1.db.db_path), mode=ShutdownMode.FULL,
method=ShutdownMethod.FORCED, timeout=0)
srv.database.bring_online(database=str(act_1.db.db_path))
#
test_script = f"""
-- ###################################################################################
-- R U N A S N O N - P R I V I L E G E D U S E R
-- ###################################################################################
execute procedure sp_run_vulnerable_expressions('{non_privileged_user.name}', '123', 'NONE');
-- Note: as of build 3.0.31810, we can SKIP restoring of 'pure-state' of RDB$ tables
-- after this SP because non-privileged user can NOT change enything.
-- All his attempts should FAIL, system tables should be in unchanged state.
set list off;
set heading off;
select '-- Executed with role: '||trim(( select actual_role from vulnerable_on_sys_tables rows 1 ))
||'. Expressions that passes WITHOUT errors:' as msg
from rdb$database
;
commit; -- 11-04-2018, do not remove!
set transaction no wait;
set list on;
select count(*) as "-- count_of_passed: "
from v_passed;
set list on;
select * from v_passed;
set list on;
select distinct vulnerable_gdscode as "-- gdscode list for blocked:"
from vulnerable_on_sys_tables
where vulnerable_gdscode is distinct from -1;
-- #########################################################################################
-- R U N A S U S E R W H O I S G R A N T E D W I T H R B D $ A D M I N
-- #########################################################################################
execute procedure sp_run_vulnerable_expressions('{dba_privileged_user.name}', '123', 'RDB$ADMIN');
set list off;
set heading off;
select '-- Executed with role: '||trim(( select actual_role from vulnerable_on_sys_tables rows 1 ))
||'. Expressions that passes WITHOUT errors:' as msg
from rdb$database
;
commit; -- 11-04-2018, do not remove!
set list on;
select count(*) as "-- count_of_passed: "
from v_passed;
set list on;
select * from v_passed;
set list on;
select distinct vulnerable_gdscode as "-- gdscode list for blocked:"
from vulnerable_on_sys_tables
where vulnerable_gdscode is distinct from -1;
----------------
commit;
connect '{act_1.db.dsn}' user '{act_1.db.user}' password '{act_1.db.password}';
-- ||||||||||||||||||||||||||||
-- ###################################||| FB 4.0+, SS and SC |||##############################
-- ||||||||||||||||||||||||||||
-- If we check SS or SC and ExtConnPoolLifeTime > 0 (config parameter FB 4.0+) then current
-- DB (bugs.core_NNNN.fdb) will be 'captured' by firebird.exe process and fbt_run utility
-- will not able to drop this database at the final point of test.
-- Moreover, DB file will be hold until all activity in firebird.exe completed and AFTER this
-- we have to wait for <ExtConnPoolLifeTime> seconds after it (discussion and small test see
-- in the letter to hvlad and dimitr 13.10.2019 11:10).
-- This means that one need to kill all connections to prevent from exception on cleanup phase:
-- SQLCODE: -901 / lock time-out on wait transaction / object <this_test_DB> is in use
-- #############################################################################################
delete from mon$attachments where mon$attachment_id != current_connection;
commit;
"""
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q'], input=test_script)
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -36,7 +36,7 @@
# qmid: bugs.core_4743 # qmid: bugs.core_4743
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action, user_factory, User
# version: 4.0 # version: 4.0
# resources: None # resources: None
@ -302,7 +302,89 @@ db_1 = db_factory(charset='UTF8', 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)
ddl_script_1 = """
grant "Старший дворник" to "Вася Пупкин";
commit;
create table "Документы"(id int primary key, pid int references "Документы");
create exception "НЕ_число" 'Ваша строка не может быть преобразована в число.';
create sequence "ИД_документа";
set term ^;
create procedure "Хранимка" as
begin
end
^
create function "СтрВЧисло"(a_text varchar(100)) returns int as
begin
return 0;
end
^
create or alter package "Утилиты" as
begin
procedure pg_sp_worker;
end
^
recreate package body "Утилиты" as
begin
procedure pg_sp_worker as
begin
end
end
^
set term ;^
commit;
create or alter view v_current_privileges as
select
g.rdb$user as who_is_granted
,g.rdb$relation_name as obj_name
,decode( g.rdb$object_type
,0,'table'
,1,'view'
,2,'trigger'
,5,'procedure'
,7,'exception'
,9,'domain'
,11,'charset'
,13,'role'
,14,'generator'
,15,'function'
,16,'blob filt'
,18,'package'
,22,'systable'
,cast(g.rdb$object_type as varchar(50))
) as obj_type
,max(iif(g.rdb$privilege='S','YES',' ')) as "privilege:select"
,max(iif(g.rdb$privilege='I','YES',' ')) as "privilege:insert"
,max(iif(g.rdb$privilege='U','YES',' ')) as "privilege:update"
,max(iif(g.rdb$privilege='D','YES',' ')) as "privilege:delete"
,max(iif(g.rdb$privilege='G','YES',' ')) as "privilege:usage"
,max(iif(g.rdb$privilege='X','YES',' ')) as "privilege:exec"
,max(iif(g.rdb$privilege='R','YES',' ')) as "privilege:refer"
,max(iif(g.rdb$privilege='C','YES',' ')) as "privilege:create"
,max(iif(g.rdb$privilege='L','YES',' ')) as "privilege:alter"
,max(iif(g.rdb$privilege='O','YES',' ')) as "privilege:drop"
,max(iif(g.rdb$privilege='M','YES',' ')) as "privilege:member"
from rdb$user_privileges g
where g.rdb$user in( current_user, current_role )
group by 1,2,3;
grant select on v_current_privileges to "Старший дворник";
grant select,insert,update,delete,references on "Документы" to "Старший дворник";
grant usage on exception "НЕ_число" to "Старший дворник";
grant usage on sequence "ИД_документа" to "Старший дворник";
grant execute on procedure "Хранимка" to "Старший дворник";
grant execute on function "СтрВЧисло" to "Старший дворник";
grant execute on package "Утилиты" to "Старший дворник";
grant create table to "Старший дворник";
grant alter any table to "Старший дворник";
grant drop any table to "Старший дворник";
commit;
"""
expected_stdout_1 = """ expected_stdout_1 = """
MON$USER : Вася Пупкин MON$USER : Вася Пупкин
@ -358,14 +440,31 @@ expected_stdout_1 = """
OBJ_NAME : Хранимка OBJ_NAME : Хранимка
OBJ_TYPE : procedure OBJ_TYPE : procedure
privilege:exec : YES privilege:exec : YES
"""
NON_ASCII_USER_BEFORE_DROP 1 non_acii_user = user_factory(name='"Вася Пупкин"', password= '123', encoding= 'utf8')
NON_ASCII_USER_AFTER_DROP 0
"""
@pytest.mark.version('>=4.0') @pytest.mark.version('>=4.0')
@pytest.mark.xfail def test_1(act_1: Action, non_acii_user: User, capsys):
def test_1(db_1): with act_1.test_role('"Старший дворник"', charset= 'utf8'):
pytest.fail("Test not IMPLEMENTED") act_1.isql(switches=['-b', '-q'], input=ddl_script_1)
print(act_1.stdout)
with act_1.db.connect(user=non_acii_user.name, password=non_acii_user.password,
role='"Старший дворник"') as con:
cur = con.cursor()
cur.execute('select m.mon$user,m.mon$role from mon$attachments m where m.mon$attachment_id = current_connection')
col = cur.description
for r in cur:
for i in range(len(col)):
print(' '.join((col[i][0], ':', r[i])))
cur.execute("select v.* from v_current_privileges v")
col = cur.description
for r in cur:
for i in range(len(col)):
if 'privilege:' not in col[i][0] or 'privilege:' in col[i][0] and r[i] == 'YES':
print(' '.join((col[i][0], ':', r[i])))
#
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: # qmid:
import pytest 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, TraAccessMode, DatabaseError
# version: 2.5.5 # version: 2.5.5
# resources: None # resources: None
@ -30,7 +31,7 @@ substitutions_1 = []
init_script_1 = """ init_script_1 = """
recreate global temporary table gtt_session(x int, y int) on commit preserve rows; recreate global temporary table gtt_session(x int, y int) on commit preserve rows;
commit; commit;
""" """
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -95,20 +96,46 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# con2.close() # con2.close()
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
Error-1: Error-1:
Error while commiting transaction: lock conflict on no wait transaction
- SQLCODE: -901 -unsuccessful metadata update
- lock conflict on no wait transaction -object TABLE "GTT_SESSION" is in use
- unsuccessful metadata update """
- object TABLE "GTT_SESSION" is in use
"""
@pytest.mark.version('>=2.5.5') @pytest.mark.version('>=2.5.5')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): custom_tpb = TPB(isolation=Isolation.READ_COMMITTED_RECORD_VERSION,
pytest.fail("Test not IMPLEMENTED") access_mode=TraAccessMode.WRITE, lock_timeout=0).get_buffer()
with act_1.db.connect() as con1:
tx1a = con1.transaction_manager(custom_tpb)
cur1a = tx1a.cursor()
tx1b = con1.transaction_manager(custom_tpb)
cur1b = tx1b.cursor()
try:
cur1a.execute("insert into gtt_session select rand()*10, rand()*10 from rdb$types")
cur1b.execute("create index gtt_session_x_y on gtt_session computed by (x+y)")
tx1b.commit() # WI-V2.5.6.27013 issues here: lock conflict on no wait transaction unsuccessful metadata update object TABLE "GTT_SESSION" is in use -901 335544345
tx1a.commit()
except DatabaseError as e:
print('Error-1:')
msg = e.args[0]
print(msg)
#
if not msg.split():
# 2.5.5: control should NOT pass here at all!
with act_1.db.connect() as con2:
try:
tx2a = con2.transaction_manager()
cur2a = tx2a.cursor()
cur2a.execute("insert into gtt_session select rand()*11, rand()*11 from rdb$types")
except DatabaseError as e:
print('Error-2:')
print(e.args[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

@ -11,13 +11,17 @@
# #
# Checked on: 4.0.0.2416 (Windows and Linux) # Checked on: 4.0.0.2416 (Windows and Linux)
# #
# [pcisar] 24.11.2021
# 1. This problem is covered by test for core_4743 as side effect
# 2. For sake of completness, it was reimplemented by simply using
# user_factory fixture.
# tracker_id: # tracker_id:
# min_versions: ['4.0'] # min_versions: ['4.0']
# versions: 4.0 # versions: 4.0
# qmid: bugs.core_4760 # qmid: bugs.core_4760
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action, user_factory, User
# version: 4.0 # version: 4.0
# resources: None # resources: None
@ -158,17 +162,20 @@ db_1 = db_factory(charset='UTF8', 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)
MON$USER : Εὐκλείδης
NON_ASCII_USER_BEFORE_DROP 1 #expected_stdout_1 = """
NON_ASCII_USER_AFTER_DROP 0 #MON$USER : Εὐκλείδης
""" #NON_ASCII_USER_BEFORE_DROP 1
#NON_ASCII_USER_AFTER_DROP 0
#"""
non_ascii_user = user_factory(name='"Εὐκλείδης"', password='123', encoding='utf8')
@pytest.mark.version('>=4.0') @pytest.mark.version('>=4.0')
@pytest.mark.xfail def test_1(act_1: Action, non_ascii_user: User):
def test_1(db_1): with act_1.db.connect(user=non_ascii_user.name, password=non_ascii_user.password) as con:
pytest.fail("Test not IMPLEMENTED") pass

View File

@ -30,6 +30,13 @@
# 3.0.5.33221 SC: 5.416s. # 3.0.5.33221 SC: 5.416s.
# 3.0.5.33084 CS: 2.891s. # 3.0.5.33084 CS: 2.891s.
# #
# [pcisar] 24.11.2021
# On FB v4.0.0.2496 this test fails as provided script file raises error in
# execute block->execute statement->create/drop user:
# Statement failed, SQLSTATE = 28000
# Your user name and password are not defined. Ask your database administrator to set up a Firebird login.
# -At block line: 3, col: 9
# Variant for FB 3 not yet implemented.
# #
# tracker_id: CORE-4766 # tracker_id: CORE-4766
# min_versions: ['3.0'] # min_versions: ['3.0']
@ -37,12 +44,13 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
substitutions_1 = [('TCPv.*', 'TCP'), ('.*After line \\d+.*', ''), ('find/delete', 'delete'), ('TABLE PLG\\$.*', 'TABLE PLG')] substitutions_1 = [('TCPv.*', 'TCP'), ('.*After line \\d+.*', ''),
('find/delete', 'delete'), ('TABLE PLG\\$.*', 'TABLE PLG')]
init_script_1 = """""" init_script_1 = """"""
@ -108,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 = """ expected_stdout_1 = """
Srp: BOSS_SEC_NAME TMP_4766_BOSS Srp: BOSS_SEC_NAME TMP_4766_BOSS
@ -141,18 +150,19 @@ expected_stdout_1 = """
Leg: find/delete record error Leg: find/delete record error
Leg: -no permission for DELETE access to TABLE PLG$VIEW_USERS Leg: -no permission for DELETE access to TABLE PLG$VIEW_USERS
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0,<4')
@pytest.mark.xfail @pytest.mark.xfail
def test_1(db_1): def test_1(act_1: Action):
pytest.fail("Test not IMPLEMENTED") pytest.fail("Test not IMPLEMENTED")
# version: 4.0 # version: 4.0
# resources: None # resources: None
substitutions_2 = [('TCPv.*', 'TCP'), ('.*After line \\d+.*', ''), ('find/delete', 'delete'), ('TABLE PLG\\$.*', 'TABLE PLG')] substitutions_2 = [('TCPv.*', 'TCP'), ('.*After line \\d+.*', ''),
('find/delete', 'delete'), ('TABLE PLG\\$.*', 'TABLE PLG')]
init_script_2 = """""" init_script_2 = """"""
@ -232,7 +242,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 = """ expected_stdout_2 = """
Leg: BOSS_SEC_NAME TMP_4766_BOSS Leg: BOSS_SEC_NAME TMP_4766_BOSS
@ -252,11 +263,24 @@ expected_stdout_2 = """
Leg: find/delete record error Leg: find/delete record error
Leg: -no permission for DELETE access to TABLE PLG$VIEW_USERS Leg: -no permission for DELETE access to TABLE PLG$VIEW_USERS
Leg: -Effective user is TMP_4766_BOSS Leg: -Effective user is TMP_4766_BOSS
""" """
@pytest.mark.version('>=4.0') @pytest.mark.version('>=4.0')
@pytest.mark.xfail def test_2(act_2: Action, capsys):
def test_2(db_2): sql_text = (act_2.vars['files'] / 'core_4766.sql').read_text()
pytest.fail("Test not IMPLEMENTED") # ::: NB :::
# Only Legacy_UserManager is checked for FB 4.0. Srp has totally different behaviour, at least for 4.0.0.1714.
# Sent letter to dimitr and alex, 05.01.2020 22:00.
subs = {'dsn': act_2.db.dsn, 'user_name': act_2.db.user, 'user_password': act_2.db.password,
'current_auth_plugin': None,}
for current_auth_plugin in ['Legacy_UserManager', ]:
subs['current_auth_plugin'] = current_auth_plugin
act_2.isql(switches=['-q'], input=sql_text % subs)
for line in act_2.stdout.splitlines():
if line.strip():
print(current_auth_plugin[:3] + ': ' + line)
#
act_2.reset()
act_2.expected_stdout = expected_stdout_2
act_2.stdout = capsys.readouterr().out
assert act_2.clean_stdout == act_2.clean_expected_stdout

View File

@ -13,7 +13,7 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action, user_factory, User
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -123,7 +123,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( [i.name for i in ( f_chk_sql, f_tags_log, f_tags_err ) ] ) # cleanup( [i.name for i in ( f_chk_sql, f_tags_log, f_tags_err ) ] )
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
USR_NAME TMP$C4768_1 USR_NAME TMP$C4768_1
@ -134,11 +135,37 @@ expected_stdout_1 = """
VAL_MAX VAL99999 VAL_MAX VAL99999
TAG_CNT 100000 TAG_CNT 100000
Records affected: 1 Records affected: 1
""" """
test_user_1 = user_factory(name='tmp$c4768_1', password='123')
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, test_user_1: User):
def test_1(db_1): TAGS_COUNT = 100000
pytest.fail("Test not IMPLEMENTED") check_lines = ['set bail on;',
"create or alter user tmp$c4768_1 password '123' using plugin Srp tags ("]
for i in range(TAGS_COUNT):
check_lines.append(f"{' ,' if i > 0 else ' '}arg_{i}='val{i}'")
#check_lines.append((' ,' if i>0 else ' ') + 'arg_' + str(i) + "='val" + str(i) + "'")
check_lines.append(');')
check_lines.append('commit;')
test_script = '\n'.join(check_lines) + """
set count on;
set list on;
select
u.sec$user_name as usr_name
,u.sec$plugin sec_plugin
,upper(min( a.sec$key )) tag_min
,upper(min( a.sec$value )) val_min
,upper(max( a.sec$key )) tag_max
,upper(max( a.sec$value )) val_max
,count(*) tag_cnt
from sec$users u
left join sec$user_attributes a on u.sec$user_name = a.sec$user_name
where u.sec$user_name = upper('tmp$c4768_1')
group by 1,2 ;
commit;
"""
act_1.expected_stdout = expected_stdout_1
act_1 .isql(switches=['-q'], input=test_script)
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -34,18 +34,36 @@
# Windows: 3.0.8.33445, 4.0.0.2416 # Windows: 3.0.8.33445, 4.0.0.2416
# Linux: 3.0.8.33426, 4.0.0.2416 # Linux: 3.0.8.33426, 4.0.0.2416
# #
# [pcisar] 24.11.2021
# This test FAILs because it's not possible to grant create database to role tmp$db_creator
# although it exists (in test database):
# Statement failed, SQLSTATE = 28000
# unsuccessful metadata update
# -GRANT failed
# -SQL role TMP$DB_CREATOR does not exist
# -in security database
#
# tracker_id: CORE-4821 # tracker_id: CORE-4821
# min_versions: ['3.0.5'] # min_versions: ['3.0.5']
# versions: 3.0.5 # versions: 3.0.5
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action import sys
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file, user_factory, User
# version: 3.0.5 # version: 3.0.5
# resources: None # resources: None
substitutions_1 = [('no permission for CREATE access to DATABASE .*', 'no permission for CREATE access to DATABASE'), ('gbak: ERROR:failed to create database .*', 'gbak: ERROR:failed to create database'), ('-failed to create database .*', '-failed to create database'), ('CREATED_DB_NAME .*', 'CREATED_DB_NAME'), ('FDB_RESTORED_USING_GBAK .*', 'FDB_RESTORED_USING_GBAK'), ('FDB_RESTORED_USING_SMGR .*', 'FDB_RESTORED_USING_SMGR')] substitutions_1 = [('no permission for CREATE access to DATABASE .*',
'no permission for CREATE access to DATABASE'),
('gbak: ERROR:failed to create database .*',
'gbak: ERROR:failed to create database'),
('-failed to create database .*', '-failed to create database'),
('CREATED_DB_NAME .*', 'CREATED_DB_NAME'),
('FDB_RESTORED_USING_GBAK .*', 'FDB_RESTORED_USING_GBAK'),
('FDB_RESTORED_USING_SMGR .*', 'FDB_RESTORED_USING_SMGR')]
init_script_1 = """""" init_script_1 = """"""
@ -184,13 +202,15 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup( f_list ) # cleanup( f_list )
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
CREATED_DB_NAME /opt/scripts/qa-rundaily/dbg-repo/tmp/tmp_4821_test2.fdb CREATED_DB_NAME /opt/scripts/qa-rundaily/dbg-repo/tmp/tmp_4821_test2.fdb
FDB_RESTORED_USING_GBAK /opt/scripts/qa-rundaily/dbg-repo/tmp/tmp_4821_restored.gbak.fdb FDB_RESTORED_USING_GBAK /opt/scripts/qa-rundaily/dbg-repo/tmp/tmp_4821_restored.gbak.fdb
FDB_RESTORED_USING_SMGR /opt/scripts/qa-rundaily/dbg-repo/tmp/tmp_4821_restored.smgr.fdb FDB_RESTORED_USING_SMGR /opt/scripts/qa-rundaily/dbg-repo/tmp/tmp_4821_restored.smgr.fdb
""" """
expected_stderr_1 = """ expected_stderr_1 = """
Statement failed, SQLSTATE = 28000 Statement failed, SQLSTATE = 28000
no permission for CREATE access to DATABASE no permission for CREATE access to DATABASE
@ -206,11 +226,86 @@ expected_stderr_1 = """
no permission for CREATE access to DATABASE no permission for CREATE access to DATABASE
-failed to create database -failed to create database
-Exiting before completion due to errors -Exiting before completion due to errors
""" """
test_user_1 = user_factory(name='tmp$c4821_boss', password='123')
fdb_test1 = temp_file('tmp_4821_test1.fdb')
fdb_test2 = temp_file('tmp_4821_test2.fdb')
fbk_name = temp_file('tmp_4821_test2.fbk')
fdb_restored_using_gbak = temp_file('tmp_4821_restored.gbak.fdb')
fdb_restored_using_smgr = temp_file('tmp_4821_restored.smgr.fdb')
fdb_restored_unexpected = temp_file('tmp_4821_restored.no_grant.fdb')
@pytest.mark.version('>=3.0.5') @pytest.mark.version('>=3.0.5')
@pytest.mark.xfail def test_1(act_1: Action, test_user_1: User, capsys, fdb_test1: Path, fdb_test2: Path,
def test_1(db_1): fbk_name: Path, fdb_restored_using_gbak: Path, fdb_restored_using_smgr: Path,
pytest.fail("Test not IMPLEMENTED") fdb_restored_unexpected: Path):
with act_1.test_role('tmp$db_creator'):
with act_1.db.connect() as con:
#con.execute_immediate('revoke all on all from tmp$c4821_boss')
con.execute_immediate('grant create database to role tmp$db_creator')
con.execute_immediate('grant tmp$db_creator to tmp$c4821_boss')
con.commit()
#
sql_test = f"""
create database 'localhost:{fdb_test1}' user tmp$c4821_boss password '123';
select mon$database_name as created_db_name from mon$database;
rollback;
create database 'localhost:{fdb_test2}' user tmp$c4821_boss password '123' role tmp$db_creator;
set list on;
select mon$database_name as created_db_name from mon$database;
"""
act_1.isql(switches=['-q'], input=sql_test)
print(act_1.stdout)
# Must PASS because user tmp$c4821_boss is the owner of this DB:
act_1.reset()
act_1.gbak(switches=['-b', '-user', 'tmp$c4821_boss', '-pas', '123',
f'localhost:{fdb_test2}', str(fbk_name)],
credentials=False)
# Must FAIL because we do not specify role, with text:
# "gbak: ERROR:no permission for CREATE access to DATABASE ... / gbak: ERROR:failed to create database localhost:tmp_4821_restored.gbak.fdb"
act_1.reset()
act_1.expected_stderr = "Must FAIL because we do not specify role"
act_1.gbak(switches=['-rep', '-user', 'tmp$c4821_boss', '-pas', '123',
str(fbk_name), f'localhost:{fdb_restored_using_gbak}'],
credentials=False)
print(act_1.stderr, file=sys.stderr)
# Must PASS because we DO specify role:
act_1.reset()
act_1.gbak(switches=['-rep', '-user', 'tmp$c4821_boss', '-pas', '123', '-role', 'tmp$db_creator',
str(fbk_name), f'localhost:{fdb_restored_using_gbak}'],
credentials=False)
#
act_1.reset()
act_1.isql(switches=['-user', act_1.db.user, '-password', act_1.db.password,
f'localhost:{fdb_restored_using_gbak}'], connect_db=False,
input='set list on; select mon$database_name as fdb_restored_using_gbak from mon$database;')
print(act_1.stdout)
# Must FAIL because we do not specify role, with text: "no permission for CREATE access to DATABASE ... / failed to create database tmp_4821_restored.smgr.fdb"
act_1.reset()
act_1.expected_stderr = "Must FAIL because we do not specify role"
act_1.svcmgr(switches=['localhost:service_mgr', 'user', 'tmp$c4821_boss', 'password', '123',
'action_restore', 'res_replace', 'bkp_file', str(fbk_name),
'dbname', str(fdb_restored_using_smgr)], connect_mngr=False)
print(act_1.stderr, file=sys.stderr)
# Must PASS because we DO specify role:
act_1.reset()
act_1.svcmgr(switches=['localhost:service_mgr', 'user', 'tmp$c4821_boss', 'password', '123',
'role', 'tmp$db_creator', 'action_restore', 'res_replace',
'bkp_file', str(fbk_name), 'dbname', str(fdb_restored_using_smgr)],
connect_mngr=False)
#
act_1.reset()
act_1.isql(switches=['-user', act_1.db.user, '-password', act_1.db.password,
f'localhost:{fdb_restored_using_gbak}'], connect_db=False,
input='set list on; select mon$database_name as fdb_restored_using_smgr from mon$database;')
print(act_1.stdout)
#
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.expected_stderr = expected_stderr_1
act_1.stdout = capsys.readouterr().out
act_1.stderr = capsys.readouterr().err
assert act_1.clean_stdout == act_1.clean_expected_stdout
assert act_1.clean_stderr == act_1.clean_expected_stderr

View File

@ -25,7 +25,8 @@
# qmid: None # qmid: None
import pytest 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 # version: 2.5
# resources: None # resources: None
@ -75,17 +76,43 @@ db_1 = db_factory(charset='UTF8', sql_dialect=3, init=init_script_1)
# runProgram('isql',[dsn,'-user',user_name,'-pas',user_password,'-q'],sqltxt) # runProgram('isql',[dsn,'-user',user_name,'-pas',user_password,'-q'],sqltxt)
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
OUT1 out string OUT1 out string
OUT2 6.283185005187988 OUT2 6.283185005187988
OUT3 37035 OUT3 37035
""" """
@pytest.mark.version('>=2.5') @pytest.mark.version('>=2.5')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): with act_1.db.connect() as con:
pytest.fail("Test not IMPLEMENTED") custom_tpb = TPB(isolation=Isolation.READ_COMMITTED_RECORD_VERSION, auto_commit=True).get_buffer()
con.begin(custom_tpb)
c = con.cursor()
sp_ddl = """
create or alter procedure sp_test (in1 integer, in2 float)
returns (
out1 varchar(20),
out2 double precision,
out3 integer
) as
declare x integer;
begin
out1 = 'out string';
out2 = 2 * in2;
out3 = 3 * in1;
suspend;
end
"""
#
sp_rem = "comment on procedure sp_test is 'Det är inte alla präster, som göra prästgården eller dess torp till änkesäte åt orkeslösa trotjänarinnor, hade biskopen en gång sagt om Helenas prost.'"
# For confirmation of ticket issues it is enough to do just this:
c.execute(sp_ddl)
c.execute(sp_rem)
con.commit()
#
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q'], input='set list on; select * from sp_test(12345, 3.1415926);')
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -29,12 +29,19 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action import subprocess
import time
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
from firebird.driver import DbWriteMode
# version: 3.0 # version: 3.0
# resources: None # resources: None
substitutions_1 = [('[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9]', ''), ('Relation [0-9]{3,4}', 'Relation'), ('Statement failed, SQLSTATE = HY008', ''), ('operation was cancelled', ''), ('After line .*', '')] substitutions_1 = [('[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9]', ''),
('Relation [0-9]{3,4}', 'Relation'),
('Statement failed, SQLSTATE = HY008', ''),
('operation was cancelled', ''), ('After line .*', '')]
init_script_1 = """""" init_script_1 = """"""
@ -216,10 +223,10 @@ db_1 = db_factory(page_size=4096, 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 = """ expected_stdout_1 = """
INSERTED_ROWS OK, LOT OF.
Iteration #1: Iteration #1:
21:16:28.31 Validation started 21:16:28.31 Validation started
21:16:28.31 Relation 128 (TEST) 21:16:28.31 Relation 128 (TEST)
@ -238,11 +245,63 @@ Iteration #2:
21:16:35.09 process pointer page 0 of 1 21:16:35.09 process pointer page 0 of 1
21:16:35.09 Relation 129 (STOP) is ok 21:16:35.09 Relation 129 (STOP) is ok
21:16:35.09 Validation finished 21:16:35.09 Validation finished
""" INSERTED_ROWS OK, LOT OF.
"""
heavy_script_1 = temp_file('heavy_script.sql')
heavy_output_1 = temp_file('heavy_script.out')
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, heavy_script_1: Path, heavy_output_1: Path, capsys):
def test_1(db_1): # Change database FW to OFF in order to increase speed of insertions and output its header info
pytest.fail("Test not IMPLEMENTED") with act_1.connect_server() as srv:
srv.database.set_write_mode(database=str(act_1.db.db_path), mode=DbWriteMode.ASYNC)
# Preparing script for ISQL that will do 'heavy DML'
heavy_script_1.write_text("""
recreate sequence g;
recreate table test(id int, s varchar( 36 ) unique using index test_s_unq);
recreate table stop(id int);
commit;
set list on;
set transaction read committed;
set term ^;
execute block returns( inserted_rows varchar(20) ) as
begin
while ( not exists(select * from stop) ) do
begin
insert into test(id, s) values( gen_id(g,1), rpad('', 36, uuid_to_char(gen_uuid())) );
end
inserted_rows = iif(gen_id(g,0) > 0, 'OK, LOT OF.', 'FAIL: ZERO!');
suspend;
end
^
set term ;^
commit;
""")
with open(heavy_output_1, mode='w') as heavy_out:
p_heavy_sql = subprocess.Popen([act_1.vars['isql'], '-i', str(heavy_script_1),
'-user', act_1.db.user,
'-password', act_1.db.password, act_1.db.dsn],
stdout=heavy_out, stderr=subprocess.STDOUT)
try:
time.sleep(4)
# Run validation twice
with act_1.connect_server() as srv:
print('Iteration #1:')
srv.database.validate(database=str(act_1.db.db_path), lock_timeout=1,
callback=print)
print('Iteration #2:')
srv.database.validate(database=str(act_1.db.db_path), lock_timeout=1,
callback=print)
# Stopping ISQL that is doing now 'heavy DML' (bulk-inserts):
act_1.isql(switches=[], input='insert into stop(id) values(1); commit;')
finally:
p_heavy_sql.terminate()
#
print(heavy_output_1.read_text())
# 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

@ -159,11 +159,9 @@ expected_stdout_1 = """
MON$REMOTE_ADDRESS <null> MON$REMOTE_ADDRESS <null>
MON$REMOTE_PROCESS <null> MON$REMOTE_PROCESS <null>
MON$AUTH_METHOD User name in DPB MON$AUTH_METHOD User name in DPB
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1): def test_1(db_1):
pytest.fail("Test not IMPLEMENTED") pytest.skip("Test requires manipulation with firebird.conf")
#pytest.fail("Test not IMPLEMENTED")

View File

@ -16,7 +16,7 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -95,12 +95,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') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): act_1.expected_stderr = 'We do not expect any error output'
pytest.fail("Test not IMPLEMENTED") act_1.svcmgr(switches=['action_add_user', 'dbname', str(act_1.db.db_path),
'sec_username', 'TMP$C4879', 'sec_password', '123'])
# There should be no output at all
assert act_1.clean_stderr == ''
assert act_1.clean_stdout == ''
# add_user passed, so remove it
act_1.reset()
act_1.svcmgr(switches=['action_delete_user', 'dbname', str(act_1.db.db_path),
'sec_username', 'TMP$C4879'])

View File

@ -32,7 +32,9 @@
# qmid: # qmid:
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from zipfile import Path
from firebird.qa import db_factory, python_act, Action
from firebird.driver import DbWriteMode
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -41,15 +43,15 @@ substitutions_1 = []
init_script_1 = """ init_script_1 = """
recreate table log( recreate table log(
standalone_func_beg timestamp default null standalone_func_beg timestamp default null,
,standalone_func_end timestamp default null standalone_func_end timestamp default null,
,pkg_head_n_body_beg timestamp default null pkg_head_n_body_beg timestamp default null,
,pkg_head_n_body_end timestamp default null pkg_head_n_body_end timestamp default null
); );
commit; commit;
insert into log default values; insert into log default values;
commit; commit;
""" """
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -108,15 +110,63 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# """ # """
# runProgram('isql',[dsn,'-q'],script) # runProgram('isql',[dsn,'-q'],script)
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
RESULT_MSG Ratio is acceptable RESULT_MSG Ratio is acceptable
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): with act_1.connect_server() as srv:
pytest.fail("Test not IMPLEMENTED") srv.database.set_write_mode(database=str(act_1.db.db_path), mode=DbWriteMode.ASYNC)
# Read FNC scripts from zip file and execute it
script_file = Path(act_1.vars['files'] / 'core_4880.zip',
at='core_4880_fnc.tmp')
act_1.script = script_file.read_text()
act_1.execute()
# Read PKG scripts from zip file and execute it
script_file = Path(act_1.vars['files'] / 'core_4880.zip',
at='core_4880_pkg.tmp')
act_1.script = script_file.read_text()
act_1.execute()
# Check
test_script = """
set list on;
set term ^;
execute block as
begin
rdb$set_context('USER_SESSION', 'MAX_ACCEPTABLE_RATIO', '2');
-- ^
-- #################
-- T H R E S H O L D
-- #################
end
^
set term ;^
select iif(x.ratio < cast( rdb$get_context('USER_SESSION', 'MAX_ACCEPTABLE_RATIO') as int ),
'Ratio is acceptable',
'Regression, ratio >= ' || rdb$get_context('USER_SESSION', 'MAX_ACCEPTABLE_RATIO') || 'x'
) as result_msg
--, x.*
from (
select
standalone_func_sec,
pkg_head_n_body_sec,
cast(iif( pkg_head_n_body_sec > standalone_func_sec, 1.00 * pkg_head_n_body_sec / standalone_func_sec, 1.00 * standalone_func_sec / pkg_head_n_body_sec ) as numeric(12,2) ) as ratio,
cast(1.00 * pkg_head_n_body_sec / standalone_func_sec as numeric(12,2)) package_vs_standalone,
cast(1.00 * standalone_func_sec / pkg_head_n_body_sec as numeric(12,2)) standalone_vs_package
from (
select
nullif(datediff(second from standalone_func_beg to standalone_func_end), 0) standalone_func_sec,
nullif(datediff(second from pkg_head_n_body_beg to pkg_head_n_body_end), 0) pkg_head_n_body_sec
from log
)
) x;
"""
act_1.reset()
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q'], input=test_script)
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -4,8 +4,7 @@
# title: ISQL input command (or -i option) reads large (> 64K) lines incorrectly # title: ISQL input command (or -i option) reads large (> 64K) lines incorrectly
# decription: # decription:
# This test verifies ability of parsing multiple statements that are going as `single-lined stream`. # This test verifies ability of parsing multiple statements that are going as `single-lined stream`.
# Source for this test is file `fbt-repo # Source for this test is file `fbt-repo\\files\\core_4882.sql`.
# iles\\core_4882.sql`.
# It contains almost all source code of test that emulates OLTP workload - without initial script for data filling. # It contains almost all source code of test that emulates OLTP workload - without initial script for data filling.
# This test can be found here: svn://svn.code.sf.net/p/firebird/code/qa/oltp-emul/ # This test can be found here: svn://svn.code.sf.net/p/firebird/code/qa/oltp-emul/
# Three files were taken from it: oltp30_DDL.sql, oltp30_sp.sql and oltp_main_filling.sql - with total size ~600 Kb. # Three files were taken from it: oltp30_DDL.sql, oltp30_sp.sql and oltp_main_filling.sql - with total size ~600 Kb.
@ -22,7 +21,7 @@
# qmid: # qmid:
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -42,7 +41,8 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# scriptfile.close() # scriptfile.close()
# runProgram('isql',[dsn,'-user',user_name,'-pas',user_password,'-i',scriptfile.name]) # runProgram('isql',[dsn,'-user',user_name,'-pas',user_password,'-i',scriptfile.name])
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
MSG oltp30_DDL.sql start MSG oltp30_DDL.sql start
@ -51,11 +51,12 @@ expected_stdout_1 = """
MSG oltp30_sp.sql finish MSG oltp30_sp.sql finish
MSG oltp_main_filling.sql start MSG oltp_main_filling.sql start
MSG oltp_main_filling.sql finish MSG oltp_main_filling.sql finish
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): act_1.expected_stdout = expected_stdout_1
pytest.fail("Test not IMPLEMENTED") act_1.isql(switches=[], input_file=act_1.vars['files'] / 'core_4882.sql')
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -21,7 +21,9 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -244,7 +246,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 = """ expected_stdout_1 = """
OK: found text in trace related to EMBEDDED connect. OK: found text in trace related to EMBEDDED connect.
@ -253,11 +256,66 @@ expected_stdout_1 = """
CONNECTION_REMOTE_PID internal CONNECTION_REMOTE_PID internal
AUTH_METHOD User name in DPB AUTH_METHOD User name in DPB
Records affected: 1 Records affected: 1
""" """
def trace_session(act: Action, b: Barrier):
cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
f'database=%[\\\\/]{act.db.db_path.name}',
'{',
' enabled = true',
' time_threshold = 0',
' log_initfini = false',
' log_errors = true',
' log_statement_finish = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): b = Barrier(2)
pytest.fail("Test not IMPLEMENTED") trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
isq_script = """
set list on;
set count on;
select
iif(a.mon$remote_protocol is null, 'internal', 'remote') as connection_protocol,
iif(a.mon$remote_process is null, 'internal', 'remote') as connection_process,
iif(a.mon$remote_pid is null, 'internal', 'remote') as connection_remote_pid,
a.mon$auth_method as auth_method -- should be: 'User name in DPB'
from rdb$database r
left join mon$attachments a on a.mon$attachment_id = current_connection and a.mon$system_flag = 0;
commit;
"""
act_1.isql(switches=['-n', '-user', 'tmp$no$such$user$4889', str(act_1.db.db_path)],
connect_db=False, input=isq_script)
output = act_1.stdout
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
trace_log = capsys.readouterr().out
#
# Process logs
i = 0
for line in trace_log.splitlines():
if ') EXECUTE_STATEMENT_FINISH' in line:
i = 1
if i == 1 and '1 records fetched' in line:
i = 2
print("OK: found text in trace related to EMBEDDED connect.")
break
if not i == 2:
print("FAILED to found text in trace related to EMBEDDED connect.")
print(output if output else "FAILED to print log from EMBEDDED connect: log is EMPTY.")
# 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

@ -10,7 +10,7 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -75,9 +75,7 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# # Note: gfix attachment via remote protocol refects with following lines in trace: # # Note: gfix attachment via remote protocol refects with following lines in trace:
# # 2015-08-24T18:30:03.8520 (3256:01B526A8) ATTACH_DATABASE # # 2015-08-24T18:30:03.8520 (3256:01B526A8) ATTACH_DATABASE
# # C:\\MIX\\FIREBIRD\\QA\\FBT-REPO\\TMP\\CORE4899-TMP.FDB (ATT_9, SYSDBA:NONE, NONE, TCPv4:127.0.0.1) # # C:\\MIX\\FIREBIRD\\QA\\FBT-REPO\\TMP\\CORE4899-TMP.FDB (ATT_9, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
# # C:\\MIX # # C:\\MIX\\firebird\\db30\\gfix.exe:1448
# irebird
# b30\\gfix.exe:1448
# #
# runProgram('gstat',['-h',fdx]) # runProgram('gstat',['-h',fdx])
# #
@ -88,18 +86,54 @@ db_1 = db_factory(page_size=4096, 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 = """ expected_stdout_1 = """
Attributes force write, full shutdown Attributes force write, full shutdown
Attributes force write Attributes force write
Attributes force write, full shutdown Attributes force write, full shutdown
Attributes force write Attributes force write
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): # Trying to move database to OFFLINE:
pytest.fail("Test not IMPLEMENTED") act_1.gfix(switches=['-shut', 'full', '-force', '0', str(act_1.db.db_path)])
print(act_1.stdout)
act_1.reset()
act_1.gstat(switches=['-h', str(act_1.db.db_path)], connect_db=False)
print(act_1.stdout)
# Trying to move database online using LOCAL protocol:
act_1.reset()
act_1.gfix(switches=['-online', str(act_1.db.db_path)])
print(act_1.stdout)
# gfix attachment via local protocol reflects with following lines in trace:
# 2015-08-24T18:30:03.2580 (2516:012417E0) ATTACH_DATABASE
# C:\\MIX\\FIREBIRD\\QA\\FBT-REPO\\TMP\\CORE4899-TMP.FDB (ATT_9, SYSDBA:NONE, NONE, <internal>)
act_1.reset()
act_1.gstat(switches=['-h', str(act_1.db.db_path)], connect_db=False)
print(act_1.stdout)
# --------------------- II ---------------
act_1.reset()
act_1.gfix(switches=['-shut', 'full', '-force', '0', str(act_1.db.db_path)])
print(act_1.stdout)
act_1.reset()
act_1.gstat(switches=['-h', str(act_1.db.db_path)], connect_db=False)
print(act_1.stdout)
# Trying to move database online using REMOTE protocol:
act_1.reset()
act_1.gfix(switches=['-online', f'localhost:{act_1.db.db_path}'])
print(act_1.stdout)
# Note: gfix attachment via remote protocol refects with following lines in trace:
# 2015-08-24T18:30:03.8520 (3256:01B526A8) ATTACH_DATABASE
# C:\\MIX\\FIREBIRD\\QA\\FBT-REPO\\TMP\\CORE4899-TMP.FDB (ATT_9, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
# C:\\MIX\\firebird\\db30\\gfix.exe:1448
act_1.reset()
act_1.gstat(switches=['-h', str(act_1.db.db_path)], connect_db=False)
print(act_1.stdout)
# 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

@ -19,12 +19,16 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
from firebird.driver import DbWriteMode
# version: 3.0 # version: 3.0
# resources: None # resources: None
substitutions_1 = [('[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9]', ''), ('Maximum index .* reached', 'Maximum index reached'), ('Relation [0-9]{3,4}', 'Relation'), ('After line .*', ''), ('-At block line: [\\d]+, col: [\\d]+', '-At block line')] substitutions_1 = [('[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9]', ''),
('Maximum index .* reached', 'Maximum index reached'),
('Relation [0-9]{3,4}', 'Relation'), ('After line .*', ''),
('-At block line: [\\d]+, col: [\\d]+', '-At block line')]
init_script_1 = """""" init_script_1 = """"""
@ -149,7 +153,8 @@ db_1 = db_factory(page_size=4096, 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 = """ expected_stdout_1 = """
Statement failed, SQLSTATE = 54000 Statement failed, SQLSTATE = 54000
@ -163,11 +168,37 @@ expected_stdout_1 = """
Index 1 (TEST_S) Index 1 (TEST_S)
Relation (TEST) is ok Relation (TEST) is ok
Validation finished Validation finished
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): # Move database to FW = OFF in order to increase speed of insertions and output its header info:
pytest.fail("Test not IMPLEMENTED") with act_1.connect_server() as srv:
srv.database.set_write_mode(database=str(act_1.db.db_path), mode=DbWriteMode.ASYNC)
# Preparing script for ISQL that will do inserts with long keys:
long_keys_cmd = """
recreate table test(s varchar(1015)); -- with THIS length of field following EB will get exception very fast.
create index test_s on test(s);
commit;
set term ^;
execute block as
begin
insert into test(s)
select rpad('', 1015, uuid_to_char(gen_uuid()) )
from rdb$types, rdb$types
rows 50000; -- this is extra-huge reserve; exception should raise when about 120-130 rows will be inserted.
end
^
set term ;^
commit;
"""
act_1.expected_stderr = "We expect errors"
act_1.isql(switches=[], input=long_keys_cmd)
print(act_1.stdout)
print(act_1.stderr)
# Run validation after ISQL will finish (with runtime exception due to implementation limit exceeding):
srv.database.validate(database=str(act_1.db.db_path), lock_timeout=1, callback=print)
# 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

@ -34,12 +34,16 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action import time
from threading import Thread, Barrier
from firebird.qa import db_factory, python_act, Action
# version: 2.5.5 # version: 2.5.5
# resources: None # resources: None
substitutions_1 = [('^((?!HEADER_|DETAIL_).)*$', ''), ('HEADER_2100.*', 'HEADER_2100'), ('DETAIL_2100.*', 'DETAIL_2100')] substitutions_1 = [('^((?!HEADER_|DETAIL_).)*$', ''),
('HEADER_2100.*', 'HEADER_2100'),
('DETAIL_2100.*', 'DETAIL_2100')]
init_script_1 = """ init_script_1 = """
create or alter procedure sp_test as begin end; create or alter procedure sp_test as begin end;
@ -109,7 +113,7 @@ init_script_1 = """
create index d2100_wsrs on detail_2100 (ware_id,snd_optype_id,rcv_optype_id,snd_id); create index d2100_wsrs on detail_2100 (ware_id,snd_optype_id,rcv_optype_id,snd_id);
create index d3300_wsrs on detail_3300 (ware_id,snd_optype_id,rcv_optype_id,snd_id); create index d3300_wsrs on detail_3300 (ware_id,snd_optype_id,rcv_optype_id,snd_id);
commit; commit;
""" """
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -268,16 +272,47 @@ 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 = """ expected_stdout_1 = """
HEADER_2100 HEADER_2100
DETAIL_2100 DETAIL_2100
""" """
@pytest.mark.version('>=2.5.5') def trace_session(act: Action, b: Barrier):
@pytest.mark.xfail cfg30 = ['# Trace config, format for 3.0. Generated auto, do not edit!',
def test_1(db_1): f'database=%[\\\\/]{act.db.db_path.name}',
pytest.fail("Test not IMPLEMENTED") '{',
' enabled = true',
' time_threshold = 0',
' log_initfini = false',
' log_statement_finish = true',
' print_perf = true',
'}']
with act.connect_server() as srv:
srv.trace.start(config='\n'.join(cfg30))
b.wait()
for line in srv:
print(line)
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, capsys):
b = Barrier(2)
trace_thread = Thread(target=trace_session, args=[act_1, b])
trace_thread.start()
b.wait()
act_1.isql(switches=[], input='set list on; select result from sp_test;')
time.sleep(2)
with act_1.connect_server() as srv:
for session in list(srv.trace.sessions.keys()):
srv.trace.stop(session_id=session)
trace_thread.join(1.0)
if trace_thread.is_alive():
pytest.fail('Trace thread still alive')
# 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

@ -9,7 +9,8 @@
# qmid: None # qmid: None
import pytest 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 # version: 3.0
# resources: None # resources: None
@ -35,12 +36,12 @@ init_script_1 = """
in autonomous transaction do in autonomous transaction do
insert into att_log(att_id, att_name, att_user, att_addr, att_prot, att_auth) insert into att_log(att_id, att_name, att_user, att_addr, att_prot, att_auth)
select select
mon$attachment_id mon$attachment_id,
,mon$attachment_name mon$attachment_name,
,mon$user mon$user,
,mon$remote_address mon$remote_address,
,mon$remote_protocol mon$remote_protocol,
,mon$auth_method mon$auth_method
from mon$attachments from mon$attachments
where mon$remote_protocol starting with upper('TCP') and mon$user = upper('SYSDBA') where mon$remote_protocol starting with upper('TCP') and mon$user = upper('SYSDBA')
; ;
@ -48,7 +49,7 @@ init_script_1 = """
^ ^
set term ;^ set term ;^
commit; commit;
""" """
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -79,7 +80,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# os.remove(fbk) # os.remove(fbk)
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
IS_ATT_ID_OK 1 IS_ATT_ID_OK 1
@ -89,11 +91,33 @@ expected_stdout_1 = """
IS_ATT_PROT_OK 1 IS_ATT_PROT_OK 1
IS_ATT_AUTH_OK 1 IS_ATT_AUTH_OK 1
IS_ATT_DTS_OK 1 IS_ATT_DTS_OK 1
""" """
fbk_file_1 = temp_file('tmp_core_4928.fbk')
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, fbk_file_1: Path):
def test_1(db_1): act_1.gbak(switches=['-b', act_1.db.dsn, str(fbk_file_1)])
pytest.fail("Test not IMPLEMENTED") act_1.reset()
# This was in original test, but it makes no sense as it overwites att_log content
# from backup that does not contain any data on v4.0.0.2496
# It's not important to test the issue anyway
#act_1.gbak(switches=['-rep', str(fbk_file_1), act_1.db.dsn])
#act_1.reset()
# Check
act_1.expected_stdout = expected_stdout_1
act_1.script = """
set list on;
select
iif(att_id > 0, 1, 0) is_att_id_ok,
iif(att_name containing 'test.fdb', 1, 0) is_att_name_ok,
iif(att_user = upper('SYSDBA'), 1, 0) is_att_user_ok,
iif(att_addr is not null, 1, 0) is_att_addr_ok,
iif(upper(att_prot) starting with upper('TCP'), 1, 0) is_att_prot_ok,
iif(att_auth is not null, 1, 0) is_att_auth_ok,
iif(att_dts is not null, 1, 0) is_att_dts_ok
from att_log
where att_id <> current_connection;
"""
act_1.execute()
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -11,7 +11,7 @@
# Then we TURN ON keeping of Tx parameters (SET KEEP_TRAN ON) and do some manipulations in this # Then we TURN ON keeping of Tx parameters (SET KEEP_TRAN ON) and do some manipulations in this
# ('main') script, including invocation of auxiliary ('addi') script using IN <...> command. # ('main') script, including invocation of auxiliary ('addi') script using IN <...> command.
# #
# Second script creates another database and the same view in it, then does soma actions there # Second script creates another database and the same view in it, then does some actions there
# and also check output of this view. # and also check output of this view.
# After this (second) script finish, we return to 1st one and resume there final actions. # After this (second) script finish, we return to 1st one and resume there final actions.
# #
@ -26,7 +26,8 @@
# qmid: None # qmid: None
import pytest 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.6 # version: 3.0.6
# resources: None # resources: None
@ -155,7 +156,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 = """ expected_stdout_1 = """
MSG main_script: initial MSG main_script: initial
@ -246,11 +248,99 @@ expected_stdout_1 = """
TX_READ_ONLY_MON_TRANS read_write TX_READ_ONLY_MON_TRANS read_write
TX_READ_ONLY_RDB_GET_CONTEXT FALSE TX_READ_ONLY_RDB_GET_CONTEXT FALSE
TX_AUTOUNDO_MON_TRANS 1 TX_AUTOUNDO_MON_TRANS 1
""" """
addi_script_1 = temp_file('addi_script.sql')
main_script_1 = temp_file('main_script.sql')
tmp_db_1 = temp_file('tmp_addi_4933.fdb')
@pytest.mark.version('>=3.0.6') @pytest.mark.version('>=3.0.6')
@pytest.mark.xfail def test_1(act_1: Action, addi_script_1: Path, main_script_1: Path):
def test_1(db_1): addi_script_1.write_text(f"""
pytest.fail("Test not IMPLEMENTED") create database 'localhost:{tmp_db_1}' user {act_1.db.user} password '{act_1.db.password}';
recreate view v_check as
select
decode(t.mon$isolation_mode, 0,'consistency', 1,'snapshot', 2,'rc rec_vers', 3,'rc no_recv', 4,'rc read_cons', 'UNKNOWN') as tx_til_mon_trans,
rdb$get_context('SYSTEM', 'ISOLATION_LEVEL') as tx_til_rdb_get_context,
decode(t.mon$lock_timeout, -1, 'wait', 0, 'no_wait', 'timeout ' || t.mon$lock_timeout) as tx_lock_timeout_mon_trans,
rdb$get_context('SYSTEM', 'LOCK_TIMEOUT') as tx_lock_timeout_rdb_get_context,
iif(t.mon$read_only=1,'read_only','read_write') as tx_read_only_mon_trans,
rdb$get_context('SYSTEM', 'READ_ONLY') as tx_read_only_rdb_get_context,
t.mon$auto_undo as tx_autoundo_mon_trans
-- only in FB 4.x+: ,t.mon$auto_commit as tx_autocommit_mon_trans
from mon$transactions t
where t.mon$transaction_id = current_transaction;
commit;
select 'addi_script: create_new_db' as msg, v.* from v_check v;
rollback;
connect 'localhost:{tmp_db_1}' user {act_1.db.user} password '{act_1.db.password}';
select 'addi_script: reconnect' as msg, v.* from v_check v;
rollback;
drop database;
""")
main_script_1.write_text(f"""
set list on;
connect '{act_1.db.dsn}' user {act_1.db.user} password '{act_1.db.password}';
recreate view v_check as
select
decode(t.mon$isolation_mode, 0,'consistency', 1,'snapshot', 2,'rc rec_vers', 3,'rc no_recv', 4,'rc read_cons', 'UNKNOWN') as tx_til_mon_trans,
rdb$get_context('SYSTEM', 'ISOLATION_LEVEL') as tx_til_rdb_get_context,
decode(t.mon$lock_timeout, -1, 'wait', 0, 'no_wait', 'timeout ' || t.mon$lock_timeout) as tx_lock_timeout_mon_trans,
rdb$get_context('SYSTEM', 'LOCK_TIMEOUT') as tx_lock_timeout_rdb_get_context,
iif(t.mon$read_only=1,'read_only','read_write') as tx_read_only_mon_trans,
rdb$get_context('SYSTEM', 'READ_ONLY') as tx_read_only_rdb_get_context,
t.mon$auto_undo as tx_autoundo_mon_trans
-- only 4.x: ,t.mon$auto_commit as tx_autocommit_mon_trans
from mon$transactions t
where t.mon$transaction_id = current_transaction;
commit;
select 'main_script: initial' as msg, v.* from v_check v;
commit;
set keep_tran on;
commit;
set transaction read only read committed record_version lock timeout 5 no auto undo; -- only in 4.x: auto commit;
select 'main_script: started Tx' as msg, v.* from v_check v;
commit; -------------------------------------------------------------------------------------- [ 1 ]
select 'main_script: after_commit' as msg, v.* from v_check v;
rollback; ------------------------------------------------------------------------------------ [ 2 ]
select 'main_script: after_rollback' as msg, v.* from v_check v;
rollback;
connect '{act_1.db.dsn}' user {act_1.db.user} password '{act_1.db.password}'; --------------------------- [ 3 ]
select 'main_script: after_reconnect' as msg, v.* from v_check v;
rollback;
--###################
in {addi_script_1};
--###################
connect '{act_1.db.dsn}' user {act_1.db.user} password '{act_1.db.password}'; --------------------------- [ 5 ]
select 'main_script: resume' as msg, v.* from v_check v;
rollback;
set keep_tran off;
commit;
select 'keep_tran: turned_off' as msg, v.* from v_check v;
commit;
""")
# Check
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q'], input_file=main_script_1)
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -34,7 +34,7 @@
# file <...> is not a valid database # file <...> is not a valid database
# 2) Srp: # 2) Srp:
# Authentication error # Authentication error
# file C:\\FBSS\\FIREBIRD.MSG is not a valid database # file C:\\FB\\SS\\FIREBIRD.MSG is not a valid database
# #
# Checked for: # Checked for:
# FB30SS, build 3.0.4.32972: OK, 3.360s. # FB30SS, build 3.0.4.32972: OK, 3.360s.
@ -55,7 +55,8 @@ from firebird.qa import db_factory, isql_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
substitutions_1 = [('FILE.*FIREBIRD.MSG', 'FILE FIREBIRD.MSG'), ('CLIENT_MSG: 335545106L', 'CLIENT_MSG: 335545106')] substitutions_1 = [('FILE.*FIREBIRD.MSG', 'FILE FIREBIRD.MSG'),
('CLIENT_MSG: 335545106L', 'CLIENT_MSG: 335545106')]
init_script_1 = """""" init_script_1 = """"""
@ -255,11 +256,9 @@ expected_stdout_1 = """
CLIENT_MSG: 335545106L CLIENT_MSG: 335545106L
FIREBIRD.LOG: + AUTHENTICATION ERROR FIREBIRD.LOG: + AUTHENTICATION ERROR
FIREBIRD.LOG: + FILE FIREBIRD.MSG IS NOT A VALID DATABASE FIREBIRD.LOG: + FILE FIREBIRD.MSG IS NOT A VALID DATABASE
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1): def test_1(db_1):
pytest.fail("Test not IMPLEMENTED") pytest.skip("Test requires manipulation with databases.conf")
#pytest.fail("Test not IMPLEMENTED")

View File

@ -8,7 +8,7 @@
# # from UNIX standard epoch time inside ISQL and writing it to log. After returning control from ISQL we evaluate again # # from UNIX standard epoch time inside ISQL and writing it to log. After returning control from ISQL we evaluate again
# # that number by calling Python 'time.time()' - and it will return value upto current UTC time, i.e. it WILL take in # # that number by calling Python 'time.time()' - and it will return value upto current UTC time, i.e. it WILL take in
# # account local timezone from OS settings (this is so at least on Windows). Thus we have to add/substract time shift # # account local timezone from OS settings (this is so at least on Windows). Thus we have to add/substract time shift
# # between UTC and local time - this is done by 'time.timezone' summand. # # between UTC and local time - this is done by 'time.timezone' command.
# # On PC-host with CPU 3.0 GHz and 2Gb RAM) in almost all cases difference was less than 1000 ms, so it was decided # # On PC-host with CPU 3.0 GHz and 2Gb RAM) in almost all cases difference was less than 1000 ms, so it was decided
# # to set MAX_DETACH_TIME_THRESHOLD = 1200 ms. # # to set MAX_DETACH_TIME_THRESHOLD = 1200 ms.
# # Tested on WI-V3.0.0.32140 (SS/SC/CC). # # Tested on WI-V3.0.0.32140 (SS/SC/CC).
@ -31,7 +31,8 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action import time
from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -134,15 +135,25 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup((f_isql_log, f_isql_err, f_isql_cmd)) # cleanup((f_isql_log, f_isql_err, f_isql_cmd))
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """ act_1 = python_act('db_1', substitutions=substitutions_1)
Detach performed fast enough: less than threshold.
"""
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): MAX_DETACH_TIME_THRESHOLD=1200
pytest.fail("Test not IMPLEMENTED") act_1.script = """
set list on;
select datediff(second from timestamp '01.01.1970 00:00:00.000' to current_timestamp) as " "
from rdb$types rows 1;
"""
act_1.execute()
ms_before_detach = 0
for line in act_1.stdout.splitlines():
# ::: NB ::: do NOT remove "and line.split()[0].isdigit()" if decide to replace subprocess.call()
# with pipe-way like: runProgram('isql',[dsn,'-q','-o',sqllog.name], sqltxt) !!
# String like: 'Database ....' does appear first in log instead of result!
splitted = line.split()
if splitted and splitted[0].isdigit():
ms_before_detach = int(splitted[0])
detach_during_ms = int((time.time() - ms_before_detach - time.timezone) * 1000)
assert detach_during_ms < MAX_DETACH_TIME_THRESHOLD

View File

@ -232,8 +232,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1): def test_1(db_1):
pytest.fail("Test not IMPLEMENTED") pytest.skip("Test requires manipulation with firebird.conf")
#pytest.fail("Test not IMPLEMENTED")

View File

@ -10,7 +10,7 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -44,15 +44,29 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# print(r[0]) # print(r[0])
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
OK OK
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): with act_1.db.connect() as con:
pytest.fail("Test not IMPLEMENTED") c = con.cursor()
cmd = """
select iif(port > 0, 'OK', 'BAD') as port_value
from (
select cast(substring(mon$remote_address from 1 + position('/' in mon$remote_address)) as int) as port
from mon$attachments
where mon$attachment_id = current_connection)
"""
for row in c.execute(cmd):
print(row[0])
# 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

@ -42,13 +42,16 @@
# Increased threshold to 6000 ms instead of old 5000 ms -- see # Increased threshold to 6000 ms instead of old 5000 ms -- see
# http://web.firebirdsql.org/download/prerelease/results/archive/3.0.2.32630/bugs.core_5034.html # http://web.firebirdsql.org/download/prerelease/results/archive/3.0.2.32630/bugs.core_5034.html
# #
# [pcisar] 26.11.2021
# New implementation should be done using multiprocessing Python module
# Postponed for later due to complexity
# tracker_id: CORE-5034 # tracker_id: CORE-5034
# min_versions: ['3.0'] # min_versions: ['3.0']
# versions: 3.0 # versions: 3.0
# qmid: # qmid:
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -240,7 +243,7 @@ init_script_1 = """
rows 10 rows 10
); );
commit; commit;
""" """
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -269,9 +272,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# #
# ISQL_BINARY = context['isql_path'] # ISQL_BINARY = context['isql_path']
# svc = services.connect(host='localhost') # svc = services.connect(host='localhost')
# FB_HOME = os.path.normpath( svc.get_home_directory() ) # 'c: # FB_HOME = os.path.normpath( svc.get_home_directory() ) # 'c:\firebird\' --> 'c:\firebird' (i.e. remove trailing backslash if needed)
# irebird' --> 'c:
# irebird' (i.e. remove trailing backslash if needed)
# svc.close() # svc.close()
# #
# if os.name == 'nt': # if os.name == 'nt':
@ -451,16 +452,17 @@ 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 = """ expected_stdout_1 = """
All detaches not exceeded threshold All detaches not exceeded threshold
Records affected: 1 Records affected: 1
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail @pytest.mark.xfail
def test_1(db_1): def test_1(act_1: Action):
pytest.fail("Test not IMPLEMENTED") pytest.fail("Test not IMPLEMENTED")

View File

@ -8,6 +8,8 @@
# ("service_mgr" to be cleaned out from connection string completely...") # ("service_mgr" to be cleaned out from connection string completely...")
# Disabled this test to be run on FB 4.0: added record to '%FBT_REPO% ests\\qa4x-exclude-list.txt'. # Disabled this test to be run on FB 4.0: added record to '%FBT_REPO% ests\\qa4x-exclude-list.txt'.
# Added EMPTY section for FB version 4.0 in this .fbt as one more way to protect from running. # Added EMPTY section for FB version 4.0 in this .fbt as one more way to protect from running.
# [pcisar] 26.112021
# "Empty" 4.0 version was removed completelly, as it's not needed with pytest
# #
# tracker_id: CORE-5039 # tracker_id: CORE-5039
# min_versions: ['3.0'] # min_versions: ['3.0']
@ -15,7 +17,7 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -33,40 +35,18 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# runProgram('fbsvcmgr',['localhost:qwe_mnb_zxc_9','user','SYSDBA','password','masterkey','info_server_version']) # runProgram('fbsvcmgr',['localhost:qwe_mnb_zxc_9','user','SYSDBA','password','masterkey','info_server_version'])
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stderr_1 = """ expected_stderr_1 = """
Cannot attach to services manager Cannot attach to services manager
-service qwe_mnb_zxc_9 is not defined -service qwe_mnb_zxc_9 is not defined
""" """
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
# version: 4.0
# resources: None
substitutions_2 = []
init_script_2 = """"""
db_2 = db_factory(sql_dialect=3, init=init_script_2)
test_script_2 = """
-- This section was intentionally left empty.
-- No message should be in expected_* sections.
-- It is STRONGLY RECOMMENDED to add this ticket
-- in the 'excluded-list file:
-- %FBT_REPO% ests\\qa4x-exclude-list.txt
"""
act_2 = isql_act('db_2', test_script_2, substitutions=substitutions_2)
@pytest.mark.version('>=4.0')
def test_2(act_2: Action):
act_2.execute()
@pytest.mark.version('>=3.0,<4')
def test_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.svcmgr(switches=['localhost:qwe_mnb_zxc_9', 'user', 'SYSDBA',
'password', 'masterkey', 'info_server_version'],
connect_mngr=False)
assert act_1.clean_stderr == act_1.clean_expected_stderr

View File

@ -132,12 +132,83 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# os.remove(sqllog.name) # os.remove(sqllog.name)
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
test_script_1 = """
set list on;
set explain on;
set planonly;
set blob all;
with recursive
r1 as (
select 1 as i from rdb$database
union all
select r.i+1 from r1 r where r.i < 2
)
--select count(*) from r1;
,r2 as (
select first 1 row_number() over() i
from r1 ra
full join r1 rb on rb.i=ra.i
group by ra.i
having count(*)>0
union all
select rx.i+1 from r2 rx
where rx.i+1 <= 2
)
--select count(*) from r2
,r3 as (
select first 1 row_number() over() i
from r2 ra
full join r2 rb on rb.i=ra.i
group by ra.i
having count(*)>0
union all
select rx.i+1 from r3 rx
where rx.i+1 <= 2
)
--select count(*) from r3
,r4 as (
select first 1 row_number() over() i
from r3 ra
full join r3 rb on rb.i=ra.i
group by ra.i
having count(*)>0
union all
select rx.i+1 from r4 rx
where rx.i+1 <= 2
)
,rn as (
select row_number() over() i
from rdb$database r full join rdb$database r2 on r2.rdb$relation_id=r.rdb$relation_id
group by r.rdb$relation_id
having count(*)>0
order by r.rdb$relation_id
rows 1 to 1
)
select
char_length(mon$explained_plan)
,(select count(*) from r4)
,(select count(*) from rn)
--,(select count(*) from rn)
from mon$statements
;
"""
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): act_1.execute()
pytest.fail("Test not IMPLEMENTED") i = 0
for line in act_1.stdout.splitlines():
i += 1
if '...' in line or 'truncated' in line or 'error' in line:
pytest.fail(f"Plan is truncated or empty. Found at line {i}")

View File

@ -9,14 +9,24 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 2.5.6 # version: 2.5.6
# resources: None # resources: None
substitutions_1 = [] substitutions_1 = []
init_script_1 = """""" init_script_1 = """
recreate table test_uuid(
datavalue int,
uuid char(16) character set octets,
constraint test_uuid_unq unique(uuid)
);
commit;
insert into test_uuid(datavalue, uuid) values( 1, char_to_uuid('57F2B8C7-E1D8-4B61-9086-C66D1794F2D9') );
--insert into test_uuid(datavalue, uuid) values( 2, char_to_uuid('37F2B8C3-E1D8-4B31-9083-C33D1794F2D3') );
commit;
"""
db_1 = db_factory(sql_dialect=3, init=init_script_1) db_1 = db_factory(sql_dialect=3, init=init_script_1)
@ -45,7 +55,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# con2 = fdb.connect(dsn=dsn, user=user_name, password=user_password, charset='utf8') # con2 = fdb.connect(dsn=dsn, user=user_name, password=user_password, charset='utf8')
# #
# xcur2 = con2.cursor() # xcur2 = con2.cursor()
# psSel = xcur2.prep("select datavalue from test_uuid where uuid = char_to_uuid(?)") # psSel = xcur2.stmt("select datavalue from test_uuid where uuid = char_to_uuid(?)")
# #
# print ( psSel.plan ) # print ( psSel.plan )
# xcur2.execute(psSel, [('57F2B8C7-E1D8-4B61-9086-C66D1794F2D9')]) # xcur2.execute(psSel, [('57F2B8C7-E1D8-4B61-9086-C66D1794F2D9')])
@ -55,16 +65,21 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# con2.close() # con2.close()
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """ act_1 = python_act('db_1', substitutions=substitutions_1)
PLAN (TEST_UUID INDEX (TEST_UUID_UNQ))
1
"""
@pytest.mark.version('>=2.5.6') # Not needed for new implementation
@pytest.mark.xfail #expected_stdout_1 = """
def test_1(db_1): #PLAN (TEST_UUID INDEX (TEST_UUID_UNQ))
pytest.fail("Test not IMPLEMENTED") #1
#"""
@pytest.mark.version('>=3.0')
def test_1(act_1: Action):
with act_1.db.connect() as con:
c = con.cursor()
stmt = c.prepare("select datavalue from test_uuid where uuid = char_to_uuid(?)")
assert stmt.plan == 'PLAN (TEST_UUID INDEX (TEST_UUID_UNQ))'
result = c.execute(stmt, ['57F2B8C7-E1D8-4B61-9086-C66D1794F2D9']).fetchall()
assert result == [(1, )]

View File

@ -1,47 +0,0 @@
#coding:utf-8
#
# id: bugs.core_5068
# title: gbak with invalid parameter crashes FB
# decription:
# Confirmed crash on 2.5.5.26952, but only when use 'gbak' utility (with services call).
# As of fbsvcmgr, it works correct and reports error: Unknown switch "res_user_all_space".
# Output when use gbak is:
# gbak:unknown switch "USER_ALL_SPACE"
# gbak: ERROR:Unable to complete network request to host "localhost".
# gbak: ERROR: Error reading data from the connection.
# gbak:Exiting before completion due to errors
#
# Checked on WI-V2.5.6.26962 - works OK.
# No test needed for 3.0 thus only stub code present here in 'firebird_version': '3.0' section.
#
# tracker_id: CORE-5068
# min_versions: ['2.5.5']
# versions: 3.0
# qmid:
import pytest
from firebird.qa import db_factory, isql_act, Action
# version: 3.0
# resources: None
substitutions_1 = []
init_script_1 = """"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
# test_script_1
#---
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")

View File

@ -22,7 +22,8 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from difflib import unified_diff
from firebird.qa import db_factory, python_act, Action
# version: 3.0 # version: 3.0
# resources: None # resources: None
@ -209,7 +210,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# cleanup((f_sql_init,f_fblog_before,f_fblog_after,f_diff_txt)) # cleanup((f_sql_init,f_fblog_before,f_fblog_after,f_diff_txt))
# #
#--- #---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """ expected_stdout_1 = """
EVENT_ID 1 EVENT_ID 1
@ -236,11 +238,81 @@ expected_stdout_1 = """
EVENT_ID 1 EVENT_ID 1
EVENT_NAME connect EVENT_NAME connect
Records affected: 1 Records affected: 1
""" """
init_script = """
set term ^;
create or alter trigger trg_connect active on connect position 0 as
begin
end
^
create or alter trigger trg_disc active on disconnect position 0 as
begin
end
^
set term ;^
commit;
recreate sequence g;
recreate table log(
event_id int generated by default as identity constraint pk_log primary key,
event_name varchar(20),
when_it_was timestamp default 'now'
);
commit;
set term ^;
execute block as
begin
rdb$set_context('USER_SESSION','INITIAL_DDL','1');
end
^
create or alter trigger trg_connect active on connect position 0 as
begin
execute statement 'insert into log(event_name) values(''connect'')'
with autonomous transaction;
end
^
create or alter trigger trg_disc active on disconnect position 0 as
begin
if ( rdb$get_context('USER_SESSION','INITIAL_DDL') is null ) then
execute statement 'insert into log(event_name) values(''disconnect'')'
with autonomous transaction;
end
^
set term ;^
commit;
"""
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail def test_1(act_1: Action, capsys):
def test_1(db_1): with act_1.connect_server() as srv:
pytest.fail("Test not IMPLEMENTED") srv.info.get_log()
log_before = srv.readlines()
#
act_1.isql(switches=['-nod'], input=init_script)
# Tests 3x
test_cmd = 'set list on;set count on; select event_id, event_name from log;'
for step in range(3):
act_1.reset()
act_1.isql(switches=[], input=test_cmd)
print(act_1.stdout)
# Init again
act_1.reset()
act_1.isql(switches=['-nod'], input=init_script)
# Test again
act_1.reset()
act_1.isql(switches=[], input=test_cmd)
print(act_1.stdout)
# Get log again
with act_1.connect_server() as srv:
srv.info.get_log()
log_after = srv.readlines()
#
act_1.expected_stdout = expected_stdout_1
act_1.stdout = capsys.readouterr().out
assert act_1.clean_stdout == act_1.clean_expected_stdout
assert list(unified_diff(log_before, log_after)) == []

View File

@ -170,11 +170,9 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
expected_stdout_1 = """ expected_stdout_1 = """
DATABASE ENCRYPTED DATABASE ENCRYPTED
""" """
@pytest.mark.version('>=3.0') @pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1): def test_1(db_1):
pytest.fail("Test not IMPLEMENTED") pytest.skip("Test depends on 3rd party encryption plugin")
#pytest.fail("Test not IMPLEMENTED")

View File

@ -22,7 +22,9 @@
# qmid: None # qmid: None
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from pathlib import Path
import zipfile
from firebird.qa import db_factory, python_act, Action, temp_file
# version: 2.5.6 # version: 2.5.6
# resources: None # resources: None
@ -121,12 +123,20 @@ 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)
fbk_file_1 = temp_file('tmp_core_5078.fbk')
fdb_file_1 = temp_file('tmp_core_5078.fdb')
@pytest.mark.version('>=2.5.6') @pytest.mark.version('>=2.5.6')
@pytest.mark.xfail def test_1(act_1: Action, fbk_file_1: Path, fdb_file_1: Path):
def test_1(db_1): script_file = zipfile.Path(act_1.vars['files'] / 'core_5078.zip',
pytest.fail("Test not IMPLEMENTED") at='tmp_core_5078.fbk')
fbk_file_1.write_bytes(script_file.read_bytes())
with act_1.connect_server() as srv:
srv.database.restore(database=str(fdb_file_1), backup=str(fbk_file_1))
srv.wait()
# This should execute without errors
act_1.isql(switches=[str(fdb_file_1)], input='set list on; select * from do_changeTxStatus;',
connect_db=False)

View File

@ -11,7 +11,7 @@
# qmid: # qmid:
import pytest import pytest
from firebird.qa import db_factory, isql_act, Action from firebird.qa import db_factory, python_act, Action
# version: 4.0 # version: 4.0
# resources: None # resources: None
@ -111,15 +111,24 @@ 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)
0
""" #expected_stdout_1 = """
#0
#"""
@pytest.mark.version('>=4.0') @pytest.mark.version('>=4.0')
@pytest.mark.xfail def test_1(act_1: Action):
def test_1(db_1): act_1.nbackup(switches=['-l', str(act_1.db.db_path)])
pytest.fail("Test not IMPLEMENTED") #with act_1.connect_server() as srv:
# This raises error in new FB OO API while calling spb.insert_string(SPBItem.DBNAME, database):
# "Internal error when using clumplet API: attempt to store data in dataless clumplet"
#srv.database.nfix_database(database=str(act_1.db.db_path))
# So we have to use svcmgr...
act_1.reset()
act_1.svcmgr(switches=['action_nfix', 'dbname', str(act_1.db.db_path)])
with act_1.db.connect() as con:
c = con.cursor()
result = c.execute('select mon$backup_state from mon$database').fetchall()
assert result == [(0, )]