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

@ -355,8 +355,6 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
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')
@pytest.mark.version('>=2.1.1')
@pytest.mark.xfail
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
# allow to specify `forced_writes` or `reserve_space` options on connect() as tested
# 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.xfail
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.execute('update test set x = -x')
con.commit()
act_1.svcmgr(switches=['localhost:service_mgr', 'user', act_1.db.user,
'password', act_1.db.password, 'action_db_stats', 'dbname',
act_1.svcmgr(switches=['action_db_stats', 'dbname',
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.expected_stdout = expected_stdout_1

View File

@ -23,12 +23,17 @@
# qmid: None
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
# 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 = """
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 = """
LOG_FUNC_ENABLED 2016-02-10T15:10:43.5940 (1700:00C52280) EXECUTE_FUNCTION_START
@ -344,9 +350,98 @@ expected_stdout_1 = """
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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
output = []
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
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
# 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 = """
PARAMETERS:
@ -133,8 +135,60 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
# -- NB: i'm not sure that this test properly reflects the trouble described in the ticket.
# -- 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:
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 4.0
# resources: None
substitutions_1 = [('^((?!nodes).)*$', ''), ('Root page: [0-9]+,', ''), ('Depth', 'depth')]
substitutions_1 = [('^((?!nodes).)*$', ''),
('Root page: [0-9]+,', ''), ('Depth', 'depth')]
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] )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Root page: 203, depth: 1, leaf buckets: 1, nodes: 1
"""
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
sql_scipt = """
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
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
# 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 = """
Error while commiting transaction:
@ -172,8 +174,86 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0.6')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
ddl_script = """
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,12 +34,16 @@
# qmid: None
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
# 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 = """
create table test(id int primary key, x int);
@ -143,7 +147,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Statement failed, SQLSTATE = 40001
@ -152,9 +157,34 @@ expected_stdout_1 = """
-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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, test_script_1: Path, script_out: Path):
with act_1.db.connect() as att1:
# 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:
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
# resources: None
@ -40,7 +41,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# 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 = """
Starting backup...
@ -51,9 +53,21 @@ expected_stdout_1 = """
Log file deleted.
"""
backup_file_1 = temp_file('backup.fbk')
log_file_1 = temp_file('A012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.log')
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys, log_file_1: Path, backup_file_1: Path):
print ('Starting backup...')
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
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
# resources: None
@ -194,7 +196,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 = """
Select Expression
@ -202,9 +205,44 @@ expected_stdout_1 = """
-> 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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
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='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:
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 2.5.4
# resources: None
substitutions_1 = [('Failure: Database error', '')]
init_script_1 = """
-- NB: line `Failure: Database error` exists only in 2.5.x output.
"""
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])
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stderr_1 = """
[
@ -37,8 +36,10 @@ expected_stderr_1 = """
"""
@pytest.mark.version('>=2.5.4')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
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
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
# resources: None
@ -282,18 +284,24 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# 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 = """
Creating backup...
Creating restore...
METEO
WF
"""
fbk_file_1 = temp_file('test.fbk')
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, fbk_file_1: Path):
with act_1.connect_server() as srv:
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
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
# resources: None
@ -127,8 +128,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# for line in f:
# if line.split() and not 'Database:' in line:
# # This line must be ignored:
# # Database: localhost/3333:C:\\FBTESTING\\qa
# bt-repo mpugs.core_4472.fdb, User: SYSDBA
# # Database: localhost/3333:C:\\FBTESTING\\qa\\fbt-repo\\tmp\\bugs.core_4472.fdb, User: SYSDBA
# 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 = """
OK: log was not changed.
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
script = """
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:
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
# resources: None
substitutions_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;
"""
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)
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
IS_CURRENT_USER #
@ -120,9 +110,48 @@ expected_stdout_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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, user_bill: User, user_john: User, user_mick: User, user_boss: User):
with act_1.db.connect() as con_0a, act_1.db.connect(), \
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"
#
#
# [pcisar] 23.11.2021
# Test not implemented because it depends on 3rd party encryption plugin.
# tracker_id: CORE-4524
# min_versions: ['4.0']
# versions: 4.0
@ -370,8 +372,6 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
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.
# 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
# min_versions: ['3.0']
# versions: 3.0
# qmid:
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
# 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 = """
-- Result of this test on WI-T3.0.0.31374 Beta 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.')
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
:::MSG::: Starting ISQL setting new value for linger...
@ -117,8 +124,61 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
script_1 = """
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
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
# 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)
#
#---
#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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.connect_server() as srv:
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:
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
# resources: None
substitutions_1 = []
init_script_1 = """
set wng off;
create or alter user tmp$c4648 password '123' revoke admin role;
commit;
revoke all on all from tmp$c4648;
-- 'create ... grant admin role' or 'grant rdb$admin' are NOT neccessary
-- for enabling to creating database by non-sysdba user:
grant create database to user tmp$c4648;
commit;
"""
init_script_1 = ""
#init_script_1 = """
#set wng off;
#create or alter user tmp$c4648 password '123' revoke admin role;
#commit;
#revoke all on all from tmp$c4648;
#-- 'create ... grant admin role' or 'grant rdb$admin' are NOT neccessary
#-- 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)
@ -69,15 +74,14 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# 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 = """
Starting backup...
Backup finished.
Starting restore using NON sysdba user account...
Restore using NON sysdba user account finished.
Delete backup file...
Backup file deleted.
Starting ISQL using NON sysdba user account...
Who am I: TMP$C4648
Used protocol: TCP
@ -86,9 +90,47 @@ expected_stdout_1 = """
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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, user_1: User, temp_db_1: Path, capsys):
with act_1.db.connect() as con:
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
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
# 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 = """
set term ^;
@ -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 = """
ISQL_MSG Starting EB with infinite pause.
@ -201,9 +206,65 @@ expected_stdout_1 = """
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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, hang_script_1: Path, hang_output_1: Path, capsys, request):
# Fializer for FB4
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
# 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
# min_versions: ['3.0']
# versions: 3.0
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
# version: 3.0
# 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 = """
-- Confirmed on WI-T3.0.0.31374:
@ -48,7 +51,8 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# 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 = """
Creating shadow...
@ -58,9 +62,28 @@ Attributes force write, active shadow
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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, fbk_1: Path, fbn_1: Path, capsys):
act_1.isql(switches=['-q'],
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
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
# 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 = """
-- Executed with role: NONE. Expressions that passes WITHOUT errors:
@ -287,9 +290,102 @@ expected_stdout_1 = """
-- 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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, dba_privileged_user: User, non_privileged_user: User, capsys):
# Run prepare script
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
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
# 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 = """
MON$USER : Вася Пупкин
@ -358,14 +440,31 @@ expected_stdout_1 = """
OBJ_NAME : Хранимка
OBJ_TYPE : procedure
privilege:exec : YES
NON_ASCII_USER_BEFORE_DROP 1
NON_ASCII_USER_AFTER_DROP 0
"""
non_acii_user = user_factory(name='"Вася Пупкин"', password= '123', encoding= 'utf8')
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, non_acii_user: User, capsys):
with act_1.test_role('"Старший дворник"', charset= 'utf8'):
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:
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
# resources: None
@ -95,20 +96,46 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# 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 = """
Error-1:
Error while commiting transaction:
- SQLCODE: -901
- lock conflict on no wait transaction
lock conflict on no wait transaction
-unsuccessful metadata update
-object TABLE "GTT_SESSION" is in use
"""
@pytest.mark.version('>=2.5.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
custom_tpb = TPB(isolation=Isolation.READ_COMMITTED_RECORD_VERSION,
access_mode=TraAccessMode.WRITE, lock_timeout=0).get_buffer()
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)
#
# [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:
# min_versions: ['4.0']
# versions: 4.0
# qmid: bugs.core_4760
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
# 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 = """
MON$USER : Εὐκλείδης
NON_ASCII_USER_BEFORE_DROP 1
NON_ASCII_USER_AFTER_DROP 0
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
#expected_stdout_1 = """
#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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, non_ascii_user: User):
with act_1.db.connect(user=non_ascii_user.name, password=non_ascii_user.password) as con:
pass

View File

@ -30,6 +30,13 @@
# 3.0.5.33221 SC: 5.416s.
# 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
# min_versions: ['3.0']
@ -37,12 +44,13 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0
# 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 = """"""
@ -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 = """
Srp: BOSS_SEC_NAME TMP_4766_BOSS
@ -143,16 +152,17 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0')
@pytest.mark.version('>=3.0,<4')
@pytest.mark.xfail
def test_1(db_1):
def test_1(act_1: Action):
pytest.fail("Test not IMPLEMENTED")
# version: 4.0
# 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 = """"""
@ -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 = """
Leg: BOSS_SEC_NAME TMP_4766_BOSS
@ -255,8 +266,21 @@ expected_stdout_2 = """
"""
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_2(db_2):
pytest.fail("Test not IMPLEMENTED")
def test_2(act_2: Action, capsys):
sql_text = (act_2.vars['files'] / 'core_4766.sql').read_text()
# ::: 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
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
# 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 ) ] )
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
USR_NAME TMP$C4768_1
@ -136,9 +137,35 @@ expected_stdout_1 = """
Records affected: 1
"""
test_user_1 = user_factory(name='tmp$c4768_1', password='123')
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, test_user_1: User):
TAGS_COUNT = 100000
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
# 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
# min_versions: ['3.0.5']
# versions: 3.0.5
# qmid: None
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
# 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 = """"""
@ -184,13 +202,15 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# 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 = """
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_SMGR /opt/scripts/qa-rundaily/dbg-repo/tmp/tmp_4821_restored.smgr.fdb
"""
expected_stderr_1 = """
Statement failed, SQLSTATE = 28000
no permission for CREATE access to DATABASE
@ -208,9 +228,84 @@ expected_stderr_1 = """
-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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, test_user_1: User, capsys, fdb_test1: Path, fdb_test2: Path,
fbk_name: Path, fdb_restored_using_gbak: Path, fdb_restored_using_smgr: Path,
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
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
# resources: None
@ -75,7 +76,8 @@ db_1 = db_factory(charset='UTF8', sql_dialect=3, init=init_script_1)
# 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 = """
OUT1 out string
@ -84,8 +86,33 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=2.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.db.connect() as con:
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
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
# 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 = """"""
@ -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 = """
INSERTED_ROWS OK, LOT OF.
Iteration #1:
21:16:28.31 Validation started
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 Relation 129 (STOP) is ok
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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, heavy_script_1: Path, heavy_output_1: Path, capsys):
# Change database FW to OFF in order to increase speed of insertions and output its header info
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

@ -162,8 +162,6 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
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
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0
# 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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.expected_stderr = 'We do not expect any error output'
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:
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
# resources: None
@ -41,10 +43,10 @@ substitutions_1 = []
init_script_1 = """
recreate table log(
standalone_func_beg timestamp default null
,standalone_func_end timestamp default null
,pkg_head_n_body_beg timestamp default null
,pkg_head_n_body_end timestamp default null
standalone_func_beg timestamp default null,
standalone_func_end timestamp default null,
pkg_head_n_body_beg timestamp default null,
pkg_head_n_body_end timestamp default null
);
commit;
insert into log default values;
@ -108,15 +110,63 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# """
# 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 = """
RESULT_MSG Ratio is acceptable
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.connect_server() as srv:
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
# decription:
# This test verifies ability of parsing multiple statements that are going as `single-lined stream`.
# Source for this test is file `fbt-repo
# iles\\core_4882.sql`.
# Source for this test is file `fbt-repo\\files\\core_4882.sql`.
# 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/
# 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:
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0
# resources: None
@ -42,7 +41,8 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# scriptfile.close()
# 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 = """
MSG oltp30_DDL.sql start
@ -54,8 +54,9 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
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
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
# 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 = """
OK: found text in trace related to EMBEDDED connect.
@ -255,9 +258,64 @@ expected_stdout_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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
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()
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
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0
# 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:
# # 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
# irebird
# b30\\gfix.exe:1448
# # C:\\MIX\\firebird\\db30\\gfix.exe:1448
#
# runProgram('gstat',['-h',fdx])
#
@ -88,7 +86,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 = """
Attributes force write, full shutdown
@ -98,8 +97,43 @@ Attributes force write
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
# Trying to move database to OFFLINE:
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
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
# 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 = """"""
@ -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 = """
Statement failed, SQLSTATE = 54000
@ -166,8 +171,34 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
# Move database to FW = OFF in order to increase speed of insertions and output its header info:
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
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
# 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 = """
create or alter procedure sp_test as begin end;
@ -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 = """
HEADER_2100
DETAIL_2100
"""
@pytest.mark.version('>=2.5.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
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_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
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
# resources: None
@ -35,12 +36,12 @@ init_script_1 = """
in autonomous transaction do
insert into att_log(att_id, att_name, att_user, att_addr, att_prot, att_auth)
select
mon$attachment_id
,mon$attachment_name
,mon$user
,mon$remote_address
,mon$remote_protocol
,mon$auth_method
mon$attachment_id,
mon$attachment_name,
mon$user,
mon$remote_address,
mon$remote_protocol,
mon$auth_method
from mon$attachments
where mon$remote_protocol starting with upper('TCP') and mon$user = upper('SYSDBA')
;
@ -79,7 +80,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# 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 = """
IS_ATT_ID_OK 1
@ -91,9 +93,31 @@ expected_stdout_1 = """
IS_ATT_DTS_OK 1
"""
fbk_file_1 = temp_file('tmp_core_4928.fbk')
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, fbk_file_1: Path):
act_1.gbak(switches=['-b', act_1.db.dsn, str(fbk_file_1)])
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
# ('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.
# After this (second) script finish, we return to 1st one and resume there final actions.
#
@ -26,7 +26,8 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
# version: 3.0.6
# 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 = """
MSG main_script: initial
@ -248,9 +250,97 @@ expected_stdout_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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, addi_script_1: Path, main_script_1: Path):
addi_script_1.write_text(f"""
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
# 2) Srp:
# 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:
# 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
# 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 = """"""
@ -258,8 +259,6 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
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
# # 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
# # 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
# # to set MAX_DETACH_TIME_THRESHOLD = 1200 ms.
# # Tested on WI-V3.0.0.32140 (SS/SC/CC).
@ -31,7 +31,8 @@
# qmid: None
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
# 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))
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
Detach performed fast enough: less than threshold.
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
MAX_DETACH_TIME_THRESHOLD=1200
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.xfail
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
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0
# resources: None
@ -44,15 +44,29 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# 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 = """
OK
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
with act_1.db.connect() as con:
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
# 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
# min_versions: ['3.0']
# versions: 3.0
# qmid:
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0
# resources: None
@ -269,9 +272,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
#
# ISQL_BINARY = context['isql_path']
# svc = services.connect(host='localhost')
# FB_HOME = os.path.normpath( svc.get_home_directory() ) # 'c:
# irebird' --> 'c:
# irebird' (i.e. remove trailing backslash if needed)
# FB_HOME = os.path.normpath( svc.get_home_directory() ) # 'c:\firebird\' --> 'c:\firebird' (i.e. remove trailing backslash if needed)
# svc.close()
#
# if os.name == 'nt':
@ -451,7 +452,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 = """
All detaches not exceeded threshold
@ -460,7 +462,7 @@ expected_stdout_1 = """
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
def test_1(act_1: Action):
pytest.fail("Test not IMPLEMENTED")

View File

@ -8,6 +8,8 @@
# ("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'.
# 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
# min_versions: ['3.0']
@ -15,7 +17,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0
# 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'])
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stderr_1 = """
Cannot attach to services manager
-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)
#
#---
#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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.execute()
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
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 2.5.6
# resources: None
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)
@ -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')
#
# 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 )
# 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()
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
PLAN (TEST_UUID INDEX (TEST_UUID_UNQ))
1
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=2.5.6')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
# Not needed for new implementation
#expected_stdout_1 = """
#PLAN (TEST_UUID INDEX (TEST_UUID_UNQ))
#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
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
# 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))
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
EVENT_ID 1
@ -238,9 +240,79 @@ expected_stdout_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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
with act_1.connect_server() as srv:
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

@ -173,8 +173,6 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
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
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
# 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.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, fbk_file_1: Path, fdb_file_1: Path):
script_file = zipfile.Path(act_1.vars['files'] / 'core_5078.zip',
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:
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 4.0
# resources: None
@ -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 = """
0
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
#expected_stdout_1 = """
#0
#"""
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.nbackup(switches=['-l', str(act_1.db.db_path)])
#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, )]