mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 21:43:06 +01:00
More pyton tests
This commit is contained in:
parent
c893f5c946
commit
e7b07eade0
@ -34,12 +34,19 @@
|
|||||||
# qmid: None
|
# qmid: None
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
import time
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
from firebird.qa import db_factory, python_act, Action, temp_file
|
||||||
|
|
||||||
# version: 2.5.6
|
# version: 2.5.6
|
||||||
# resources: None
|
# resources: None
|
||||||
|
|
||||||
substitutions_1 = [('0: CREATE INDEX LOG: RDB_EXPR_BLOB.*', '0: CREATE INDEX LOG: RDB_EXPR_BLOB'), ('BULK_INSERT_START.*', 'BULK_INSERT_START'), ('BULK_INSERT_FINISH.*', 'BULK_INSERT_FINISH'), ('CREATE_INDX_START.*', 'CREATE_INDX_START'), ('AFTER LINE.*', 'AFTER LINE')]
|
substitutions_1 = [('0: CREATE INDEX LOG: RDB_EXPR_BLOB.*', '0: CREATE INDEX LOG: RDB_EXPR_BLOB'),
|
||||||
|
('BULK_INSERT_START.*', 'BULK_INSERT_START'),
|
||||||
|
('BULK_INSERT_FINISH.*', 'BULK_INSERT_FINISH'),
|
||||||
|
('CREATE_INDX_START.*', 'CREATE_INDX_START'),
|
||||||
|
('AFTER LINE.*', 'AFTER LINE')]
|
||||||
|
|
||||||
init_script_1 = """
|
init_script_1 = """
|
||||||
create or alter procedure sp_ins(n int) as begin end;
|
create or alter procedure sp_ins(n int) as begin end;
|
||||||
@ -266,7 +273,11 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
|||||||
#
|
#
|
||||||
# cleanup( [i.name for i in (f_bulk_insert_sql, f_create_indx_sql, f_bulk_insert_log, f_create_indx_log)] )
|
# cleanup( [i.name for i in (f_bulk_insert_sql, f_create_indx_sql, f_bulk_insert_log, f_create_indx_log)] )
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
act_1 = python_act('db_1', substitutions=substitutions_1)
|
||||||
|
|
||||||
|
tmp_file_bi_in = temp_file('bulk_insert.sql')
|
||||||
|
tmp_file_bi_out = temp_file('bulk_insert.out')
|
||||||
|
|
||||||
expected_stdout_1 = """
|
expected_stdout_1 = """
|
||||||
0: BULK INSERTS LOG: BULK_INSERT_START
|
0: BULK INSERTS LOG: BULK_INSERT_START
|
||||||
@ -274,7 +285,7 @@ expected_stdout_1 = """
|
|||||||
0: CREATE INDEX LOG: INSERTS_STATE OK, IS RUNNING
|
0: CREATE INDEX LOG: INSERTS_STATE OK, IS RUNNING
|
||||||
0: CREATE INDEX LOG: CREATE_INDX_START
|
0: CREATE INDEX LOG: CREATE_INDX_START
|
||||||
0: CREATE INDEX LOG: SET TRANSACTION WAIT;
|
0: CREATE INDEX LOG: SET TRANSACTION WAIT;
|
||||||
0: CREATE INDEX LOG: CREATE INDEX TEST_WAIT ON TEST COMPUTED BY( 'WAIT'|| S );
|
0: CREATE INDEX LOG: CREATE INDEX TEST_WAIT ON TEST COMPUTED BY('WAIT'|| S);
|
||||||
0: CREATE INDEX LOG: COMMIT;
|
0: CREATE INDEX LOG: COMMIT;
|
||||||
0: CREATE INDEX LOG: SET ECHO OFF;
|
0: CREATE INDEX LOG: SET ECHO OFF;
|
||||||
0: CREATE INDEX LOG: INSERTS_STATE OK, FINISHED
|
0: CREATE INDEX LOG: INSERTS_STATE OK, FINISHED
|
||||||
@ -282,7 +293,7 @@ expected_stdout_1 = """
|
|||||||
0: CREATE INDEX LOG: RDB$UNIQUE_FLAG 0
|
0: CREATE INDEX LOG: RDB$UNIQUE_FLAG 0
|
||||||
0: CREATE INDEX LOG: RDB$INDEX_INACTIVE 0
|
0: CREATE INDEX LOG: RDB$INDEX_INACTIVE 0
|
||||||
0: CREATE INDEX LOG: RDB_EXPR_BLOB
|
0: CREATE INDEX LOG: RDB_EXPR_BLOB
|
||||||
0: CREATE INDEX LOG: ( 'WAIT'|| S )
|
0: CREATE INDEX LOG: ('WAIT'|| S)
|
||||||
0: CREATE INDEX LOG: RECORDS AFFECTED: 1
|
0: CREATE INDEX LOG: RECORDS AFFECTED: 1
|
||||||
0: CREATE INDEX LOG: SET PLAN ON;
|
0: CREATE INDEX LOG: SET PLAN ON;
|
||||||
0: CREATE INDEX LOG: SELECT 1 FROM TEST WHERE 'WAIT'|| S > '' ROWS 0;
|
0: CREATE INDEX LOG: SELECT 1 FROM TEST WHERE 'WAIT'|| S > '' ROWS 0;
|
||||||
@ -295,31 +306,166 @@ expected_stdout_1 = """
|
|||||||
1: CREATE INDEX LOG: INSERTS_STATE OK, IS RUNNING
|
1: CREATE INDEX LOG: INSERTS_STATE OK, IS RUNNING
|
||||||
1: CREATE INDEX LOG: CREATE_INDX_START
|
1: CREATE INDEX LOG: CREATE_INDX_START
|
||||||
1: CREATE INDEX LOG: SET TRANSACTION NO WAIT;
|
1: CREATE INDEX LOG: SET TRANSACTION NO WAIT;
|
||||||
1: CREATE INDEX LOG: CREATE INDEX TEST_NO_WAIT ON TEST COMPUTED BY( 'NO_WAIT'|| S );
|
1: CREATE INDEX LOG: CREATE INDEX TEST_NO_WAIT ON TEST COMPUTED BY('NO_WAIT'|| S);
|
||||||
1: CREATE INDEX LOG: COMMIT;
|
1: CREATE INDEX LOG: COMMIT;
|
||||||
1: CREATE INDEX LOG: STATEMENT FAILED, SQLSTATE = 40001
|
1: CREATE INDEX LOG: STATEMENT FAILED, SQLSTATE = 40001
|
||||||
1: CREATE INDEX LOG: LOCK CONFLICT ON NO WAIT TRANSACTION
|
1: CREATE INDEX LOG: LOCK CONFLICT ON NO WAIT TRANSACTION
|
||||||
1: CREATE INDEX LOG: -UNSUCCESSFUL METADATA UPDATE
|
1: CREATE INDEX LOG: -UNSUCCESSFUL METADATA UPDATE
|
||||||
1: CREATE INDEX LOG: -OBJECT TABLE "TEST" IS IN USE
|
1: CREATE INDEX LOG: -OBJECT TABLE "TEST" IS IN USE
|
||||||
1: CREATE INDEX LOG: AFTER LINE
|
|
||||||
|
|
||||||
2: BULK INSERTS LOG: BULK_INSERT_START
|
2: BULK INSERTS LOG: BULK_INSERT_START
|
||||||
2: BULK INSERTS LOG: BULK_INSERT_FINISH
|
2: BULK INSERTS LOG: BULK_INSERT_FINISH
|
||||||
2: CREATE INDEX LOG: INSERTS_STATE OK, IS RUNNING
|
2: CREATE INDEX LOG: INSERTS_STATE OK, IS RUNNING
|
||||||
2: CREATE INDEX LOG: CREATE_INDX_START
|
2: CREATE INDEX LOG: CREATE_INDX_START
|
||||||
2: CREATE INDEX LOG: SET TRANSACTION LOCK TIMEOUT 1;
|
2: CREATE INDEX LOG: SET TRANSACTION LOCK TIMEOUT 1;
|
||||||
2: CREATE INDEX LOG: CREATE INDEX TEST_LOCK_TIMEOUT_1 ON TEST COMPUTED BY( 'LOCK_TIMEOUT_1'|| S );
|
2: CREATE INDEX LOG: CREATE INDEX TEST_LOCK_TIMEOUT_1 ON TEST COMPUTED BY('LOCK_TIMEOUT_1'|| S);
|
||||||
2: CREATE INDEX LOG: COMMIT;
|
2: CREATE INDEX LOG: COMMIT;
|
||||||
2: CREATE INDEX LOG: STATEMENT FAILED, SQLSTATE = 40001
|
2: CREATE INDEX LOG: STATEMENT FAILED, SQLSTATE = 40001
|
||||||
2: CREATE INDEX LOG: LOCK TIME-OUT ON WAIT TRANSACTION
|
2: CREATE INDEX LOG: LOCK TIME-OUT ON WAIT TRANSACTION
|
||||||
2: CREATE INDEX LOG: -UNSUCCESSFUL METADATA UPDATE
|
2: CREATE INDEX LOG: -UNSUCCESSFUL METADATA UPDATE
|
||||||
2: CREATE INDEX LOG: -OBJECT TABLE "TEST" IS IN USE
|
2: CREATE INDEX LOG: -OBJECT TABLE "TEST" IS IN USE
|
||||||
2: CREATE INDEX LOG: AFTER LINE
|
"""
|
||||||
"""
|
|
||||||
|
|
||||||
@pytest.mark.version('>=2.5.6')
|
@pytest.mark.version('>=2.5.6')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action, tmp_file_bi_in: Path, tmp_file_bi_out: Path, capsys):
|
||||||
def test_1(db_1):
|
# NB-1: value of 'rows_to_add' must have value that will require at least
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
# 4...5 seconds for inserting such number of rows
|
||||||
|
# NB-2: FB 2.5 makes DML *faster* than 3.0 in single-connection mode!
|
||||||
|
rows_to_add = 1000
|
||||||
|
tmp_file_bi_in.write_text (f'''
|
||||||
|
set bail on;
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
-- do NOT use it !! >>> alter sequence g restart with 0; -- gen_id(g,1) will return 0 rather than 1 since 06-aug-2020 on FB 4.x !!
|
||||||
|
|
||||||
|
delete from test;
|
||||||
|
set term ^;
|
||||||
|
execute block as
|
||||||
|
declare c bigint;
|
||||||
|
begin
|
||||||
|
c = gen_id(g, -gen_id(g, 0)); -- restart sequence
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set transaction lock timeout 7; -- THIS LOCK TIMEOUT SERVES ONLY FOR DELAY, see below auton Tx start.
|
||||||
|
|
||||||
|
select current_timestamp as bulk_insert_start from rdb$database;
|
||||||
|
set term ^;
|
||||||
|
execute block as
|
||||||
|
declare i int;
|
||||||
|
begin
|
||||||
|
execute procedure sp_ins({rows_to_add});
|
||||||
|
begin
|
||||||
|
-- #########################################################
|
||||||
|
-- ####################### D E L A Y #####################
|
||||||
|
-- #########################################################
|
||||||
|
in autonomous transaction do
|
||||||
|
insert into test( x ) values({rows_to_add}); -- this will cause delay because of duplicate in index
|
||||||
|
when any do
|
||||||
|
begin
|
||||||
|
i = gen_id(g,1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
select current_timestamp as bulk_insert_finish from rdb$database;
|
||||||
|
''')
|
||||||
|
|
||||||
|
tx_param = ['WAIT', 'NO WAIT', 'LOCK TIMEOUT 1']
|
||||||
|
#
|
||||||
|
i = 0
|
||||||
|
#
|
||||||
|
for tx_decl in tx_param:
|
||||||
|
idx_name = tx_decl.replace(' ', '_')
|
||||||
|
idx_expr = "'" + idx_name + "'|| s"
|
||||||
|
|
||||||
|
sql_create_indx = f'''
|
||||||
|
set bail on;
|
||||||
|
set list on;
|
||||||
|
set blob all;
|
||||||
|
select
|
||||||
|
iif( gen_id(g,0) > 0 and gen_id(g,0) < 1 + {rows_to_add},
|
||||||
|
'OK, IS RUNNING',
|
||||||
|
iif( gen_id(g,0) <=0,
|
||||||
|
'WRONG: not yet started, current gen_id='||gen_id(g,0),
|
||||||
|
'WRONG: already finished, rows_to_add='|| {rows_to_add} ||', current gen_id='||gen_id(g,0)
|
||||||
|
)
|
||||||
|
) as inserts_state,
|
||||||
|
current_timestamp as create_indx_start
|
||||||
|
from rdb$database;
|
||||||
|
set autoddl off;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set echo on;
|
||||||
|
set transaction {tx_decl};
|
||||||
|
|
||||||
|
create index test_{idx_name} on test computed by({idx_expr});
|
||||||
|
commit;
|
||||||
|
set echo off;
|
||||||
|
|
||||||
|
select
|
||||||
|
iif( gen_id(g,0) >= 1 + {rows_to_add},
|
||||||
|
'OK, FINISHED',
|
||||||
|
'SOMETHING WRONG: current gen_id=' || gen_id(g,0)||', rows_to_add='|| {rows_to_add}
|
||||||
|
) as inserts_state
|
||||||
|
from rdb$database;
|
||||||
|
|
||||||
|
set count on;
|
||||||
|
select
|
||||||
|
rdb$index_name
|
||||||
|
,coalesce(rdb$unique_flag,0) as rdb$unique_flag
|
||||||
|
,coalesce(rdb$index_inactive,0) as rdb$index_inactive
|
||||||
|
,rdb$expression_source as rdb_expr_blob
|
||||||
|
from rdb$indices ri
|
||||||
|
where ri.rdb$index_name = upper( 'test_{idx_name}' )
|
||||||
|
;
|
||||||
|
set count off;
|
||||||
|
set echo on;
|
||||||
|
set plan on;
|
||||||
|
select 1 from test where {idx_expr} > '' rows 0;
|
||||||
|
set plan off;
|
||||||
|
set echo off;
|
||||||
|
commit;
|
||||||
|
drop index test_{idx_name};
|
||||||
|
commit;
|
||||||
|
'''
|
||||||
|
with open(tmp_file_bi_out, mode='w') as f_bulk_insert_log:
|
||||||
|
# This will insert rows and then stay in pause 10 seconds:
|
||||||
|
p_bulk_insert = subprocess.Popen([act_1.vars['isql'], act_1.db.dsn,
|
||||||
|
'-user', act_1.db.user,
|
||||||
|
'-password', act_1.db.password,
|
||||||
|
'-q', '-i', str(tmp_file_bi_in)],
|
||||||
|
stdout = f_bulk_insert_log,
|
||||||
|
stderr = subprocess.STDOUT
|
||||||
|
)
|
||||||
|
#act_1.isql(switches=['-q'], input=sql_bulk_insert)
|
||||||
|
#bulk_insert_log = act_1.stdout
|
||||||
|
# 3.0 Classic: seems that it requires at least 2 seconds for ISQL be loaded into memory.
|
||||||
|
time.sleep(3)
|
||||||
|
# This will wait until first ISQL finished
|
||||||
|
act_1.expected_stderr = 'DISABLED'
|
||||||
|
act_1.isql(switches=['-q', '-n'], input=sql_create_indx)
|
||||||
|
time.sleep(7) # NB: this delay plus previous (3+5=8) must be GREATER than lock timeout in <sql_bulk_insert>
|
||||||
|
|
||||||
|
p_bulk_insert.terminate()
|
||||||
|
bulk_insert_log = tmp_file_bi_out.read_text()
|
||||||
|
create_indx_log = act_1.stdout + act_1.stderr
|
||||||
|
|
||||||
|
for line in bulk_insert_log.splitlines():
|
||||||
|
if line.split():
|
||||||
|
print( str(i)+': BULK INSERTS LOG: '+line.strip().upper() )
|
||||||
|
|
||||||
|
for line in create_indx_log.splitlines():
|
||||||
|
if line.split():
|
||||||
|
print( str(i)+': CREATE INDEX LOG: '+line.strip().upper() )
|
||||||
|
#
|
||||||
|
i += 1
|
||||||
|
# Checks
|
||||||
|
act_1.reset()
|
||||||
|
act_1.stdout = capsys.readouterr().out
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
assert act_1.clean_stdout == act_1.clean_expected_stdout
|
||||||
|
@ -32,7 +32,61 @@ init_script_1 = """"""
|
|||||||
|
|
||||||
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
# test_script_1
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
-- binary literal ::= { x | X } <quote> [ { <hexit> <hexit> }... ] <quote>
|
||||||
|
|
||||||
|
select x'1' from rdb$database; -- raises: token unknown because length is odd
|
||||||
|
|
||||||
|
select x'11' from rdb$database; -- must raise: token unknown because length is odd
|
||||||
|
|
||||||
|
select x'0123456789' from rdb$database;
|
||||||
|
|
||||||
|
select x'01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' from rdb$database;
|
||||||
|
|
||||||
|
-- must raise: token unknown because last char is not hexit
|
||||||
|
select x'0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678x' from rdb$database;
|
||||||
|
|
||||||
|
select uuid_to_char(x'BA1749B583BF9146B360F54E25FE583E') from rdb$database;
|
||||||
|
|
||||||
|
|
||||||
|
-- ##############################################################################
|
||||||
|
|
||||||
|
-- Numeric literal: { 0x | 0X } <hexit> [ <hexit>... ]
|
||||||
|
-- https://firebirdsql.org/refdocs/langrefupd25-bigint.html
|
||||||
|
recreate view v_test as
|
||||||
|
select
|
||||||
|
+-0x1 "-1(a)"
|
||||||
|
,-+-0xf "+15"
|
||||||
|
,0x7FFF "32767"
|
||||||
|
,0x8000 "32768"
|
||||||
|
,0xFFFF "65535"
|
||||||
|
,0x10000 "65536(a)"
|
||||||
|
,0x000000000010000 "65536(b)"
|
||||||
|
,0x80000000 "-2147483648"
|
||||||
|
,0x080000000 "+2147483648(a)"
|
||||||
|
,0x000000080000000 "+2147483648(b)"
|
||||||
|
,0XFFFFFFFF "-1(b)"
|
||||||
|
,0X0FFFFFFFF "+4294967295"
|
||||||
|
,0x100000000 "+4294967296(a)"
|
||||||
|
,0x0000000100000000 "+4294967296(b)"
|
||||||
|
,0X7FFFFFFFFFFFFFFF "9223372036854775807"
|
||||||
|
,0x8000000000000000 "-9223372036854775808"
|
||||||
|
,0x8000000000000001 "-9223372036854775807"
|
||||||
|
,0x8000000000000002 "-9223372036854775806"
|
||||||
|
,0xffffffffffffffff "-1(c)"
|
||||||
|
from rdb$database;
|
||||||
|
|
||||||
|
select * from v_test;
|
||||||
|
|
||||||
|
-- If the number of <hexit> is greater than 8, the constant data type is a signed BIGINT
|
||||||
|
-- If it's less or equal than 8, the data type is a signed INTEGER
|
||||||
|
set sqlda_display on;
|
||||||
|
select * from v_test rows 0;
|
||||||
|
set sqlda_display off;
|
||||||
|
"""
|
||||||
|
|
||||||
#---
|
#---
|
||||||
#
|
#
|
||||||
# import os
|
# import os
|
||||||
@ -88,108 +142,114 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
|||||||
# cleanup( (f_sql_log.name, f_sql_err.name) )
|
# cleanup( (f_sql_log.name, f_sql_err.name) )
|
||||||
#
|
#
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
expected_stdout_1 = """
|
expected_stdout_1 = """
|
||||||
STDOUT: CONSTANT 11
|
CONSTANT 11
|
||||||
STDOUT: CONSTANT 0123456789
|
CONSTANT 0123456789
|
||||||
STDOUT: CONSTANT 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
|
CONSTANT 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||||
STDOUT: UUID_TO_CHAR BA1749B5-83BF-9146-B360-F54E25FE583E
|
UUID_TO_CHAR BA1749B5-83BF-9146-B360-F54E25FE583E
|
||||||
STDOUT: -1(a) -1
|
-1(a) -1
|
||||||
STDOUT: +15 15
|
+15 15
|
||||||
STDOUT: 32767 32767
|
32767 32767
|
||||||
STDOUT: 32768 32768
|
32768 32768
|
||||||
STDOUT: 65535 65535
|
65535 65535
|
||||||
STDOUT: 65536(a) 65536
|
65536(a) 65536
|
||||||
STDOUT: 65536(b) 65536
|
65536(b) 65536
|
||||||
STDOUT: -2147483648 -2147483648
|
-2147483648 -2147483648
|
||||||
STDOUT: +2147483648(a) 2147483648
|
+2147483648(a) 2147483648
|
||||||
STDOUT: +2147483648(b) 2147483648
|
+2147483648(b) 2147483648
|
||||||
STDOUT: -1(b) -1
|
-1(b) -1
|
||||||
STDOUT: +4294967295 4294967295
|
+4294967295 4294967295
|
||||||
STDOUT: +4294967296(a) 4294967296
|
+4294967296(a) 4294967296
|
||||||
STDOUT: +4294967296(b) 4294967296
|
+4294967296(b) 4294967296
|
||||||
STDOUT: 9223372036854775807 9223372036854775807
|
9223372036854775807 9223372036854775807
|
||||||
STDOUT: -9223372036854775808 -9223372036854775808
|
-9223372036854775808 -9223372036854775808
|
||||||
STDOUT: -9223372036854775807 -9223372036854775807
|
-9223372036854775807 -9223372036854775807
|
||||||
STDOUT: -9223372036854775806 -9223372036854775806
|
-9223372036854775806 -9223372036854775806
|
||||||
STDOUT: -1(c) -1
|
-1(c) -1
|
||||||
STDOUT: INPUT message field count: 0
|
INPUT message field count: 0
|
||||||
STDOUT: OUTPUT message field count: 19
|
OUTPUT message field count: 19
|
||||||
STDOUT: 01: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
01: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
||||||
STDOUT: : name: -1(a) alias: -1(a)
|
: name: -1(a) alias: -1(a)
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 02: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
02: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
||||||
STDOUT: : name: +15 alias: +15
|
: name: +15 alias: +15
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 03: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
03: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
||||||
STDOUT: : name: 32767 alias: 32767
|
: name: 32767 alias: 32767
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 04: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
04: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
||||||
STDOUT: : name: 32768 alias: 32768
|
: name: 32768 alias: 32768
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 05: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
05: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
||||||
STDOUT: : name: 65535 alias: 65535
|
: name: 65535 alias: 65535
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 06: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
06: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
||||||
STDOUT: : name: 65536(a) alias: 65536(a)
|
: name: 65536(a) alias: 65536(a)
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 07: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
07: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: 65536(b) alias: 65536(b)
|
: name: 65536(b) alias: 65536(b)
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 08: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
08: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
||||||
STDOUT: : name: -2147483648 alias: -2147483648
|
: name: -2147483648 alias: -2147483648
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 09: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
09: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: +2147483648(a) alias: +2147483648(a)
|
: name: +2147483648(a) alias: +2147483648(a)
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 10: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
10: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: +2147483648(b) alias: +2147483648(b)
|
: name: +2147483648(b) alias: +2147483648(b)
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 11: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
11: sqltype: 496 LONG Nullable scale: 0 subtype: 0 len: 4
|
||||||
STDOUT: : name: -1(b) alias: -1(b)
|
: name: -1(b) alias: -1(b)
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 12: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
12: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: +4294967295 alias: +4294967295
|
: name: +4294967295 alias: +4294967295
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 13: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
13: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: +4294967296(a) alias: +4294967296(a)
|
: name: +4294967296(a) alias: +4294967296(a)
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 14: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
14: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: +4294967296(b) alias: +4294967296(b)
|
: name: +4294967296(b) alias: +4294967296(b)
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 15: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
15: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: 9223372036854775807 alias: 9223372036854775807
|
: name: 9223372036854775807 alias: 9223372036854775807
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 16: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
16: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: -9223372036854775808 alias: -9223372036854775808
|
: name: -9223372036854775808 alias: -9223372036854775808
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 17: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
17: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: -9223372036854775807 alias: -9223372036854775807
|
: name: -9223372036854775807 alias: -9223372036854775807
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 18: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
18: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: -9223372036854775806 alias: -9223372036854775806
|
: name: -9223372036854775806 alias: -9223372036854775806
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
STDOUT: 19: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
19: sqltype: 580 INT64 Nullable scale: 0 subtype: 0 len: 8
|
||||||
STDOUT: : name: -1(c) alias: -1(c)
|
: name: -1(c) alias: -1(c)
|
||||||
STDOUT: : table: V_TEST owner: SYSDBA
|
: table: V_TEST owner: SYSDBA
|
||||||
|
"""
|
||||||
|
|
||||||
STDERR: Statement failed, SQLSTATE = 42000
|
expected_stderr_1 = """
|
||||||
STDERR: Dynamic SQL Error
|
Statement failed, SQLSTATE = 42000
|
||||||
STDERR: -SQL error code = -104
|
Dynamic SQL Error
|
||||||
STDERR: -Token unknown - line 1, column 9
|
-SQL error code = -104
|
||||||
STDERR: -'1'
|
-Token unknown - line 1, column 9
|
||||||
|
-'1'
|
||||||
|
|
||||||
STDERR: Statement failed, SQLSTATE = 42000
|
Statement failed, SQLSTATE = 42000
|
||||||
STDERR: Dynamic SQL Error
|
Dynamic SQL Error
|
||||||
STDERR: -SQL error code = -104
|
-SQL error code = -104
|
||||||
STDERR: -Token unknown - line 1, column 9
|
-Token unknown - line 1, column 9
|
||||||
STDERR: -'0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678x'
|
-'0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678x'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@pytest.mark.version('>=3.0')
|
@pytest.mark.version('>=3.0')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action):
|
||||||
def test_1(db_1):
|
act_1.expected_stdout = expected_stdout_1
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_stdout == act_1.clean_expected_stdout
|
||||||
|
assert act_1.clean_stderr == act_1.clean_expected_stderr
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,12 +24,13 @@
|
|||||||
# qmid: bugs.core_1845
|
# qmid: bugs.core_1845
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from firebird.qa import db_factory, python_act, Action, user_factory, User
|
||||||
|
from firebird.driver import DatabaseError
|
||||||
|
|
||||||
# version: 2.5
|
# version: 2.5
|
||||||
# resources: None
|
# resources: None
|
||||||
|
|
||||||
substitutions_1 = [('SERVER VERSION:.*', 'SERVER VERSION:'), ('SERVER IMPLEMENTATION:.*', 'SERVER IMPLEMENTATION:'), ('SERVICE MANAGER VERSION:.*', 'SERVICE MANAGER VERSION:'), ('Statement failed, SQLSTATE = HY000', ''), ('record not found for user.*', '')]
|
substitutions_1 = []
|
||||||
|
|
||||||
init_script_1 = """"""
|
init_script_1 = """"""
|
||||||
|
|
||||||
@ -133,31 +134,22 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
|
||||||
expected_stdout_1 = """
|
act_1 = python_act('db_1', substitutions=substitutions_1)
|
||||||
WHO_AM_I TMP$C1845
|
|
||||||
CHECK SERVICE 'INFO_SERVER_VERSION':
|
user_1 = user_factory(name='TMP$C1845', password='QweRtyUi')
|
||||||
SERVER VERSION: WI-V3.0.0.32266 FIREBIRD 3.0 RELEASE CANDIDATE 2
|
|
||||||
CHECK SERVICE 'INFO_IMPLEMENTATION':
|
|
||||||
SERVER IMPLEMENTATION: FIREBIRD/WINDOWS/INTEL/I386
|
|
||||||
CHECK SERVICE 'INFO_USER_DBPATH':
|
|
||||||
SERVICE ISC_INFO_SVC_USER_DBPATH REQUIRES SYSDBA PERMISSIONS. REATTACH TO THE SERVICE MANAGER USING THE SYSDBA ACCOUNT.
|
|
||||||
CHECK SERVICE 'INFO_GET_ENV':
|
|
||||||
SERVICE ISC_INFO_SVC_GET_ENV REQUIRES SYSDBA PERMISSIONS. REATTACH TO THE SERVICE MANAGER USING THE SYSDBA ACCOUNT.
|
|
||||||
CHECK SERVICE 'INFO_GET_ENV_LOCK':
|
|
||||||
SERVICE ISC_INFO_SVC_GET_ENV REQUIRES SYSDBA PERMISSIONS. REATTACH TO THE SERVICE MANAGER USING THE SYSDBA ACCOUNT.
|
|
||||||
CHECK SERVICE 'INFO_GET_ENV_MSG':
|
|
||||||
SERVICE ISC_INFO_SVC_GET_ENV REQUIRES SYSDBA PERMISSIONS. REATTACH TO THE SERVICE MANAGER USING THE SYSDBA ACCOUNT.
|
|
||||||
CHECK SERVICE 'INFO_SVR_DB_INFO':
|
|
||||||
SERVICE ISC_INFO_SVC_SVR_DB_INFO REQUIRES SYSDBA PERMISSIONS. REATTACH TO THE SERVICE MANAGER USING THE SYSDBA ACCOUNT.
|
|
||||||
CHECK SERVICE 'INFO_VERSION':
|
|
||||||
SERVICE MANAGER VERSION: 2
|
|
||||||
"""
|
|
||||||
|
|
||||||
@pytest.mark.version('>=2.5')
|
@pytest.mark.version('>=2.5')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action, user_1: User):
|
||||||
def test_1(db_1):
|
with act_1.connect_server(user=user_1.name, password=user_1.password) as srv:
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
with pytest.raises(DatabaseError, match='.*requires SYSDBA permissions.*'):
|
||||||
|
print(srv.info.security_database)
|
||||||
|
with pytest.raises(DatabaseError, match='.*requires SYSDBA permissions.*'):
|
||||||
|
print(srv.info.home_directory)
|
||||||
|
with pytest.raises(DatabaseError, match='.*requires SYSDBA permissions.*'):
|
||||||
|
print(srv.info.lock_directory)
|
||||||
|
with pytest.raises(DatabaseError, match='.*requires SYSDBA permissions.*'):
|
||||||
|
print(srv.info.message_directory)
|
||||||
|
with pytest.raises(DatabaseError, match='.*requires SYSDBA permissions.*'):
|
||||||
|
print(srv.info.attached_databases)
|
||||||
|
|
||||||
|
@ -19,14 +19,22 @@
|
|||||||
# qmid: None
|
# qmid: None
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from io import BytesIO
|
||||||
|
from firebird.qa import db_factory, python_act, Action
|
||||||
|
from firebird.driver import SrvRestoreFlag
|
||||||
|
|
||||||
# version: 2.0
|
# version: 2.0
|
||||||
# resources: None
|
# resources: None
|
||||||
|
|
||||||
substitutions_1 = []
|
substitutions_1 = []
|
||||||
|
|
||||||
init_script_1 = """"""
|
init_script_1 = """
|
||||||
|
create table tmain(id int);
|
||||||
|
create table tdetl( id int, pid int, cost numeric(12,2) );
|
||||||
|
alter table tmain
|
||||||
|
add dsum2 computed by ( (select sum(cost) from tdetl d where d.pid = tmain.id) ) ;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
@ -76,12 +84,16 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
|
||||||
|
act_1 = python_act('db_1', substitutions=substitutions_1)
|
||||||
|
|
||||||
@pytest.mark.version('>=2.0')
|
@pytest.mark.version('>=2.0')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action):
|
||||||
def test_1(db_1):
|
backup = BytesIO()
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
with act_1.connect_server() as srv:
|
||||||
|
srv.database.local_backup(database=str(act_1.db.db_path), backup_stream=backup)
|
||||||
|
backup.seek(0)
|
||||||
|
# test fails if restore raises an exception
|
||||||
|
srv.database.local_restore(backup_stream=backup, database=str(act_1.db.db_path),
|
||||||
|
flags=SrvRestoreFlag.ONE_AT_A_TIME | SrvRestoreFlag.REPLACE)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
# qmid: bugs.core_1926
|
# qmid: bugs.core_1926
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from firebird.qa import db_factory, python_act, Action
|
||||||
|
|
||||||
# version: 2.1.2
|
# version: 2.1.2
|
||||||
# resources: None
|
# resources: None
|
||||||
@ -37,14 +37,21 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
|||||||
# print (j-i)
|
# print (j-i)
|
||||||
# con_detail.commit()
|
# con_detail.commit()
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
|
||||||
expected_stdout_1 = """1
|
act_1 = python_act('db_1', substitutions=substitutions_1)
|
||||||
"""
|
|
||||||
|
|
||||||
@pytest.mark.version('>=2.1.2')
|
@pytest.mark.version('>=2.1.2')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action):
|
||||||
def test_1(db_1):
|
with act_1.db.connect() as con:
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
c = con.cursor()
|
||||||
|
c.execute('SELECT 1 FROM RDB$DATABASE')
|
||||||
|
with act_1.db.connect() as con_detail:
|
||||||
|
con_detail.begin()
|
||||||
|
c_detail = con_detail.cursor()
|
||||||
|
c_detail.execute("select MON$NEXT_TRANSACTION from MON$DATABASE")
|
||||||
|
tra_1 = c_detail.fetchone()[0]
|
||||||
|
con_detail.commit()
|
||||||
|
c_detail.execute("select MON$NEXT_TRANSACTION from MON$DATABASE")
|
||||||
|
tra_2 = c_detail.fetchone()[0]
|
||||||
|
con_detail.commit()
|
||||||
|
assert tra_2 - tra_1 == 1
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
# decription:
|
# decription:
|
||||||
# We create common user using Services API and try to establish TWO subsequent connections under his login:
|
# We create common user using Services API and try to establish TWO subsequent connections under his login:
|
||||||
# 1) with flag 'forced_write' = 1 and then
|
# 1) with flag 'forced_write' = 1 and then
|
||||||
# 2) with flad 'no_reserve' = 1.
|
# 2) with flag 'no_reserve' = 1.
|
||||||
# Note: both values of these flags have to be equal 1 because of some specifics of DPB building inside fdb driver:
|
# Note: both values of these flags have to be equal 1 because of some specifics of DPB building inside fdb driver:
|
||||||
# value 0 means 'nothing to add', so no error will be raised in this case (and we DO expect error in this ticket).
|
# value 0 means 'nothing to add', so no error will be raised in this case (and we DO expect error in this ticket).
|
||||||
# In WI-V2.1.1.17910 one may to specify *ANY* values of these flags and NO error will be raised.
|
# In WI-V2.1.1.17910 one may to specify *ANY* values of these flags and NO error will be raised.
|
||||||
@ -33,7 +33,8 @@
|
|||||||
# qmid: None
|
# qmid: None
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from firebird.qa import db_factory, python_act, Action, user_factory, User
|
||||||
|
from firebird.driver import driver_config, connect
|
||||||
|
|
||||||
# version: 2.1.1
|
# version: 2.1.1
|
||||||
# resources: None
|
# resources: None
|
||||||
@ -116,7 +117,8 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
act_1 = python_act('db_1', substitutions=substitutions_1)
|
||||||
|
|
||||||
expected_stdout_1 = """
|
expected_stdout_1 = """
|
||||||
Successfully added non-privileged user
|
Successfully added non-privileged user
|
||||||
@ -131,9 +133,23 @@ expected_stdout_1 = """
|
|||||||
Successfully finished script
|
Successfully finished script
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
user_1 = user_factory(name='TMP$C1972', password='123')
|
||||||
|
|
||||||
@pytest.mark.version('>=2.1.1')
|
@pytest.mark.version('>=2.1.1')
|
||||||
@pytest.mark.xfail
|
@pytest.mark.xfail
|
||||||
def test_1(db_1):
|
def test_1(act_1: Action, user_1: User):
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
pytest.fail("Test not IMPLEMENTED")
|
||||||
|
# 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()!
|
||||||
|
# This is intentional change in firebird-driver from fdb, as using these DPB options
|
||||||
|
# on connect has side-effects (changes database option) which was considered dangerous.
|
||||||
|
#
|
||||||
|
# 1. Try to specifying 'force_write' flag: no errors and NO changes in 2.1.1; error in 2.1.2 and above
|
||||||
|
act_1.db._make_config(user=user_1.name, password=user_1.password)
|
||||||
|
db_conf = driver_config.get_database('pytest')
|
||||||
|
db_conf.forced_writes.value = True
|
||||||
|
with pytest.raises():
|
||||||
|
connect('pytest')
|
||||||
|
# 2. Try to specifying 'no_reserve' flag: no errors and NO changes in 2.1.1; error in 2.1.2 and above
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@
|
|||||||
# qmid: None
|
# qmid: None
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from firebird.qa import db_factory, python_act, Action, temp_file
|
||||||
|
from firebird.driver import SrvBackupFlag, SrvRestoreFlag
|
||||||
|
|
||||||
# version: 3.0.5
|
# version: 3.0.5
|
||||||
# resources: None
|
# resources: None
|
||||||
@ -208,16 +209,47 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
|
||||||
expected_stdout_1 = """
|
act_1 = python_act('db_1', substitutions=substitutions_1)
|
||||||
bkp: rows_without_stat=1
|
|
||||||
res: rows_without_stat=2
|
file_1 = temp_file('pytest-run.fbk')
|
||||||
"""
|
|
||||||
|
|
||||||
@pytest.mark.version('>=3.0.5')
|
@pytest.mark.version('>=3.0.5')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action, file_1):
|
||||||
def test_1(db_1):
|
src_backup = act_1.vars['backups'] / 'core1999_30.fbk'
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
with act_1.connect_server() as srv:
|
||||||
|
srv.database.restore(database=str(act_1.db.db_path), backup=str(src_backup),
|
||||||
|
flags=SrvRestoreFlag.REPLACE,
|
||||||
|
verbose=True, stats='TDWR')
|
||||||
|
restore_log = srv.readlines()
|
||||||
|
srv.database.backup(database=str(act_1.db.db_path), backup=str(file_1),
|
||||||
|
verbose=True, stats='TDWR')
|
||||||
|
backup_log = srv.readlines()
|
||||||
|
#
|
||||||
|
# Backup log should contain SINGLE row without statistics, in its header (1st line):
|
||||||
|
# gbak: time delta reads writes
|
||||||
|
#
|
||||||
|
rows_without_stat = 0
|
||||||
|
for line in backup_log:
|
||||||
|
tokens = line.split()
|
||||||
|
if not (tokens[1].replace('.', '', 1).replace(',', '', 1).isdigit() and
|
||||||
|
tokens[2].replace('.', '', 1).replace(',', '', 1).isdigit() and
|
||||||
|
tokens[3].replace('.', '', 1).replace(',', '', 1).isdigit() and
|
||||||
|
tokens[4].replace('.', '', 1).replace(',', '', 1).isdigit()):
|
||||||
|
rows_without_stat = rows_without_stat + 1
|
||||||
|
assert rows_without_stat == 1
|
||||||
|
#
|
||||||
|
# Restore log should contain TWO rows without statistics, first and last:
|
||||||
|
# gbak: time delta reads writes
|
||||||
|
# gbak:adjusting the ONLINE and FORCED WRITES flags
|
||||||
|
#
|
||||||
|
rows_without_stat = 0
|
||||||
|
for line in restore_log:
|
||||||
|
tokens = line.split()
|
||||||
|
if not (tokens[1].replace('.', '', 1).replace(',', '', 1).isdigit() and
|
||||||
|
tokens[2].replace('.', '', 1).replace(',', '', 1).isdigit() and
|
||||||
|
tokens[3].replace('.', '', 1).replace(',', '', 1).isdigit() and
|
||||||
|
tokens[4].replace('.', '', 1).replace(',', '', 1).isdigit()):
|
||||||
|
rows_without_stat = rows_without_stat + 1
|
||||||
|
assert rows_without_stat == 2
|
||||||
|
|
||||||
|
@ -25,12 +25,13 @@
|
|||||||
# qmid: None
|
# qmid: None
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from firebird.qa import db_factory, python_act, Action, user_factory, User
|
||||||
|
|
||||||
# version: 3.0
|
# version: 3.0
|
||||||
# resources: None
|
# resources: None
|
||||||
|
|
||||||
substitutions_1 = [('Use CONNECT or CREATE DATABASE.*', ''), ('.*After line.*', '')]
|
substitutions_1 = [('Use CONNECT or CREATE DATABASE.*', ''),
|
||||||
|
('.*After line.*', '')]
|
||||||
|
|
||||||
init_script_1 = """
|
init_script_1 = """
|
||||||
create or alter view v_check as
|
create or alter view v_check as
|
||||||
@ -179,40 +180,103 @@ 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)
|
||||||
|
|
||||||
|
user_1 = user_factory(name='tmp$c2004_foo', password='123')
|
||||||
|
user_2 = user_factory(name='tmp$c2004_bar', password='456')
|
||||||
|
|
||||||
expected_stdout_1 = """
|
expected_stdout_1 = """
|
||||||
STDLOG: MSG init_state
|
MSG init_state
|
||||||
STDLOG: SEC$USER_NAME TMP$C2004_FOO
|
SEC$USER_NAME TMP$C2004_FOO
|
||||||
STDLOG: SEC$ACTIVE <false>
|
SEC$ACTIVE <false>
|
||||||
STDLOG: SEC$PLUGIN Srp
|
SEC$PLUGIN Srp
|
||||||
STDLOG: MSG init_state
|
MSG init_state
|
||||||
STDLOG: SEC$USER_NAME TMP$C2004_BAR
|
SEC$USER_NAME TMP$C2004_BAR
|
||||||
STDLOG: SEC$ACTIVE <false>
|
SEC$ACTIVE <false>
|
||||||
STDLOG: SEC$PLUGIN Srp
|
SEC$PLUGIN Srp
|
||||||
STDLOG: Records affected: 2
|
Records affected: 2
|
||||||
STDLOG: MSG try to connect as INACTIVE users
|
MSG try to connect as INACTIVE users
|
||||||
STDLOG: MSG try to connect as user FOO which was just set as active by SYSDBA.
|
MSG try to connect as user FOO which was just set as active by SYSDBA.
|
||||||
STDLOG: WHO_AM_I TMP$C2004_FOO
|
WHO_AM_I TMP$C2004_FOO
|
||||||
STDLOG: WHATS_MY_ROLE RDB$ADMIN
|
WHATS_MY_ROLE RDB$ADMIN
|
||||||
STDLOG: MSG try to connect as user BAR which was just set as active by FOO.
|
MSG try to connect as user BAR which was just set as active by FOO.
|
||||||
STDLOG: WHO_AM_I TMP$C2004_BAR
|
WHO_AM_I TMP$C2004_BAR
|
||||||
STDLOG: MSG try to drop both non-privileged users by SYSDBA.
|
"""
|
||||||
STDLOG: MSG final_state
|
|
||||||
STDLOG: SEC$USER_NAME <null>
|
expected_stderr_1 = """
|
||||||
STDLOG: SEC$ACTIVE <null>
|
Statement failed, SQLSTATE = 28000
|
||||||
STDLOG: SEC$PLUGIN <null>
|
Your user name and password are not defined. Ask your database administrator to set up a Firebird login.
|
||||||
STDLOG: Records affected: 1
|
Statement failed, SQLSTATE = 28000
|
||||||
STDERR: Statement failed, SQLSTATE = 28000
|
Your user name and password are not defined. Ask your database administrator to set up a Firebird login.
|
||||||
STDERR: Your user name and password are not defined. Ask your database administrator to set up a Firebird login.
|
After line 19 in file tmp_check_2004.sql
|
||||||
STDERR: Statement failed, SQLSTATE = 28000
|
"""
|
||||||
STDERR: Your user name and password are not defined. Ask your database administrator to set up a Firebird login.
|
|
||||||
STDERR: After line 19 in file C:\\MIXirebird\\QAbt-repo mp mp_check_2004.sql
|
|
||||||
"""
|
|
||||||
|
|
||||||
@pytest.mark.version('>=3.0')
|
@pytest.mark.version('>=3.0')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action, user_1: User, user_2: User):
|
||||||
def test_1(db_1):
|
act_1.script = f'''
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
set list on;
|
||||||
|
commit;
|
||||||
|
create or alter user tmp$c2004_foo password '123' inactive using plugin Srp grant admin role;
|
||||||
|
|
||||||
|
-- NB: currently it seems strange that one need to grant rdb$admin to 'foo'
|
||||||
|
-- For what reason this role need to be added if 'foo' does his actions only in security_db ?
|
||||||
|
-- Sent letter to dimitr and alex, 10-mar-18 16:00
|
||||||
|
grant rdb$admin to tmp$c2004_foo;
|
||||||
|
|
||||||
|
create or alter user tmp$c2004_bar password '456' inactive using plugin Srp;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set count on;
|
||||||
|
select 'init_state' as msg, v.* from v_check v;
|
||||||
|
set count off;
|
||||||
|
|
||||||
|
select 'try to connect as INACTIVE users' as msg from rdb$database;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
connect '{act_1.db.dsn}' user tmp$c2004_foo password '123'; -- should fail
|
||||||
|
select current_user as who_am_i from rdb$database;
|
||||||
|
rollback;
|
||||||
|
|
||||||
|
connect '{act_1.db.dsn}' user tmp$c2004_bar password '456'; -- should fail
|
||||||
|
select current_user as who_am_i from rdb$database;
|
||||||
|
rollback;
|
||||||
|
|
||||||
|
connect '{act_1.db.dsn}' user SYSDBA password 'masterkey';
|
||||||
|
|
||||||
|
|
||||||
|
-- NB: following "alter user" statement must contain "using plugin Srp" clause
|
||||||
|
-- otherwise get:
|
||||||
|
-- Statement failed, SQLSTATE = HY000
|
||||||
|
-- record not found for user: TMP$C2004_BAR
|
||||||
|
|
||||||
|
alter user tmp$c2004_foo active using plugin Srp;
|
||||||
|
select 'try to connect as user FOO which was just set as active by SYSDBA.' as msg from rdb$database;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
connect '{act_1.db.dsn}' user tmp$c2004_foo password '123' role 'RDB$ADMIN'; -- should pass
|
||||||
|
select current_user as who_am_i, current_role as whats_my_role from rdb$database;
|
||||||
|
|
||||||
|
|
||||||
|
-- should pass because foo has admin role:
|
||||||
|
create or alter user tmp$c2004_rio password '123' using plugin Srp;
|
||||||
|
drop user tmp$c2004_rio using plugin Srp;
|
||||||
|
|
||||||
|
-- should pass because foo has admin role:
|
||||||
|
alter user tmp$c2004_bar active using plugin Srp;
|
||||||
|
select 'try to connect as user BAR which was just set as active by FOO.' as msg from rdb$database;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
connect '{act_1.db.dsn}' user tmp$c2004_bar password '456'; -- should pass
|
||||||
|
select current_user as who_am_i from rdb$database;
|
||||||
|
commit;
|
||||||
|
'''
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_stderr == act_1.clean_expected_stderr
|
||||||
|
assert act_1.clean_stdout == act_1.clean_expected_stdout
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
# qmid: None
|
# qmid: None
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from firebird.qa import db_factory, python_act, Action
|
||||||
|
|
||||||
# version: 2.5.7
|
# version: 2.5.7
|
||||||
# resources: None
|
# resources: None
|
||||||
@ -117,15 +117,37 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
|||||||
# # BEFORE 3.0.2.32641: (202472, 'select * from sp_test', '3.0.0') // after: 104942
|
# # BEFORE 3.0.2.32641: (202472, 'select * from sp_test', '3.0.0') // after: 104942
|
||||||
# # BEFORE 4.0.0.459: (202472, 'select * from sp_test', '4.0.0') // after: 104942
|
# # BEFORE 4.0.0.459: (202472, 'select * from sp_test', '4.0.0') // after: 104942
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
act_1 = python_act('db_1', substitutions=substitutions_1)
|
||||||
|
|
||||||
expected_stdout_1 = """
|
expected_stdout_1 = """
|
||||||
IO statistics for procedure is OK
|
IO statistics for procedure is OK
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@pytest.mark.version('>=2.5.7')
|
@pytest.mark.version('>=2.5.7')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action, capsys):
|
||||||
def test_1(db_1):
|
sp_query = 'select * from sp_test'
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
sql_io = '''
|
||||||
|
select
|
||||||
|
iif( i.mon$page_fetches > 104500, 'IO statistics for procedure is OK',
|
||||||
|
'Strange low value for fetches: ' || i.mon$page_fetches
|
||||||
|
) as fetches_result
|
||||||
|
from rdb$database r
|
||||||
|
left join mon$statements m on
|
||||||
|
m.mon$sql_text containing 'select * from sp_test'
|
||||||
|
and m.mon$sql_text NOT containing 'mon$statements'
|
||||||
|
left join mon$io_stats i on
|
||||||
|
m.mon$stat_id = i.mon$stat_id and i.mon$stat_group = 3
|
||||||
|
;
|
||||||
|
'''
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
with act_1.db.connect() as con:
|
||||||
|
stt1 = con.cursor()
|
||||||
|
stt2 = con.cursor()
|
||||||
|
stt2.execute(sp_query)
|
||||||
|
stt2.fetchall()
|
||||||
|
stt1.execute(sql_io)
|
||||||
|
for row in stt1:
|
||||||
|
print(row[0])
|
||||||
|
act_1.stdout = capsys.readouterr().out
|
||||||
|
assert act_1.clean_stdout == act_1.clean_expected_stdout
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
from firebird.driver import DbAccessMode
|
||||||
|
|
||||||
# version: 2.5
|
# version: 2.5
|
||||||
# resources: None
|
# resources: None
|
||||||
@ -53,22 +54,44 @@ db_1 = db_factory(charset='ISO8859_1', sql_dialect=3, init=init_script_1)
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
|
||||||
expected_stdout_1 = """
|
test_script_1 = """
|
||||||
MON$READ_ONLY 0
|
set list on;
|
||||||
RDB$FIELD_NAME X
|
set blob all;
|
||||||
default 0
|
select mon$read_only from mon$database;
|
||||||
Records affected: 1
|
set count on;
|
||||||
MON$READ_ONLY 1
|
select RDB$FIELD_NAME, rdb$default_source from rdb$relation_fields
|
||||||
RDB$FIELD_NAME X
|
where rdb$default_source is not null;
|
||||||
default 0
|
"""
|
||||||
Records affected: 1
|
|
||||||
"""
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1_a = """
|
||||||
|
MON$READ_ONLY 0
|
||||||
|
RDB$FIELD_NAME X
|
||||||
|
default 0
|
||||||
|
Records affected: 1
|
||||||
|
"""
|
||||||
|
|
||||||
|
expected_stdout_1_b = """
|
||||||
|
MON$READ_ONLY 1
|
||||||
|
RDB$FIELD_NAME X
|
||||||
|
default 0
|
||||||
|
Records affected: 1
|
||||||
|
"""
|
||||||
|
|
||||||
@pytest.mark.version('>=2.5')
|
@pytest.mark.version('>=2.5')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action):
|
||||||
def test_1(db_1):
|
act_1.expected_stdout = expected_stdout_1_a
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
act_1.execute()
|
||||||
|
assert act_1.clean_stdout == act_1.clean_expected_stdout
|
||||||
|
#
|
||||||
|
with act_1.connect_server() as srv:
|
||||||
|
srv.database.set_access_mode(database=str(act_1.db.db_path), mode=DbAccessMode.READ_ONLY)
|
||||||
|
#
|
||||||
|
act_1.reset()
|
||||||
|
act_1.expected_stdout = expected_stdout_1_b
|
||||||
|
act_1.isql(switches=[], charset='iso8859_1', input=act_1.script)
|
||||||
|
assert act_1.clean_stdout == act_1.clean_expected_stdout
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
# qmid: None
|
# qmid: None
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from zipfile import Path
|
||||||
|
from firebird.qa import db_factory, python_act, Action
|
||||||
|
|
||||||
# version: 3.0
|
# version: 3.0
|
||||||
# resources: None
|
# resources: None
|
||||||
@ -178,15 +179,17 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
|
||||||
expected_stdout_1 = """
|
act_1 = python_act('db_1', substitutions=substitutions_1)
|
||||||
Current plans match to original ones.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@pytest.mark.version('>=3.0')
|
@pytest.mark.version('>=3.0')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action):
|
||||||
def test_1(db_1):
|
# Read script and expected stdout from zip file
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
datafile = Path(act_1.vars['files'] / 'core_2115.zip',
|
||||||
|
at='tmp_core_2115_queries_with_long_plans.sql')
|
||||||
|
act_1.script = datafile.read_text()
|
||||||
|
datafile = Path(act_1.vars['files'] / 'core_2115.zip',
|
||||||
|
at='tmp_core_2115_check_txt_of_long_plans.log')
|
||||||
|
act_1.expected_stdout = datafile.read_text()
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_stdout == act_1.clean_expected_stdout
|
||||||
|
@ -24,16 +24,50 @@
|
|||||||
# qmid: None
|
# qmid: None
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from firebird.qa import db_factory, python_act, Action
|
||||||
|
from firebird.driver import DbWriteMode, SrvRestoreFlag
|
||||||
|
#from difflib import unified_diff
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
# version: 4.0
|
# version: 4.0
|
||||||
# resources: None
|
# resources: None
|
||||||
|
|
||||||
substitutions_1 = []
|
substitutions_1 = []
|
||||||
|
|
||||||
init_script_1 = """"""
|
test_size = 32768 # -- Ran 1 tests in 4.504s
|
||||||
|
# test_size = 16384 # -- Ran 1 tests in 2.735s
|
||||||
|
max_indx1 = int(test_size / 4 - 9)
|
||||||
|
max_indx6 = int(max_indx1 / 6)
|
||||||
|
max_indx8 = int(max_indx1 / 8)
|
||||||
|
|
||||||
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
init_script_1 = f"""
|
||||||
|
set list on;
|
||||||
|
set bail on;
|
||||||
|
set echo on;
|
||||||
|
create sequence g;
|
||||||
|
commit;
|
||||||
|
create collation utf8_ci for utf8 from unicode case insensitive;
|
||||||
|
create collation utf8_ai_ci for utf8 from unicode accent insensitive case insensitive ;
|
||||||
|
commit;
|
||||||
|
create domain dm_non_coll as varchar({max_indx1});
|
||||||
|
create domain dm_collated_ci as varchar({max_indx6}) character set utf8 collate utf8_ci;
|
||||||
|
create domain dm_collated_ai_ci as varchar({max_indx6}) character set utf8 collate utf8_ai_ci;
|
||||||
|
commit;
|
||||||
|
recreate table test_non_coll(
|
||||||
|
txt_non_coll dm_non_coll
|
||||||
|
);
|
||||||
|
recreate table test_collated(
|
||||||
|
txt_ci dm_collated_ci
|
||||||
|
,txt_ai_ci dm_collated_ai_ci
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
create index test_non_coll on test_non_coll(txt_non_coll);
|
||||||
|
create index test_coll_ci on test_collated(txt_ci);
|
||||||
|
create index test_coll_ai_ci on test_collated(txt_ai_ci);
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1, page_size=32784)
|
||||||
|
|
||||||
# test_script_1
|
# test_script_1
|
||||||
#---
|
#---
|
||||||
@ -384,12 +418,150 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
|
||||||
|
test_script_1 = f'''
|
||||||
|
--show version;
|
||||||
|
delete from test_non_coll;
|
||||||
|
delete from test_collated;
|
||||||
|
commit;
|
||||||
|
set count on;
|
||||||
|
insert into test_non_coll(txt_non_coll)
|
||||||
|
select
|
||||||
|
rpad('', {max_indx1}, 'QWERTY' || gen_id(g,1) )
|
||||||
|
from
|
||||||
|
-- rdb$types rows 10000
|
||||||
|
(select 1 i from rdb$types rows 200), (select 1 i from rdb$types rows 5)
|
||||||
|
rows 361
|
||||||
|
;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test_collated(txt_ci, txt_ai_ci)
|
||||||
|
select
|
||||||
|
rpad('', {max_indx6}, 'Ещё Съешь Этих Мягких Французских Булочек Да Выпей Же Чаю')
|
||||||
|
,rpad('', {max_indx6}, 'Ещё Французских Булочек Этих Мягких Съешь Да Чаю Выпей Же')
|
||||||
|
from
|
||||||
|
(select 1 i from rdb$types rows 250), (select 1 i from rdb$types rows 2)
|
||||||
|
;
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set count off;
|
||||||
|
set list on;
|
||||||
|
set plan on;
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
from test_non_coll
|
||||||
|
where txt_non_coll starting with 'QWERTY'
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
from test_collated
|
||||||
|
where txt_ci starting with 'еЩё'
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
from test_collated
|
||||||
|
where txt_ai_ci starting with 'ёЩЕ'
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
from test_collated
|
||||||
|
where txt_ci = lower(rpad('', {max_indx6}, 'Ещё Съешь Этих Мягких Французских Булочек Да Выпей Же Чаю'))
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
from test_collated
|
||||||
|
where txt_ai_ci = rpad('', {max_indx6}, 'Ещё Французских Булочек Этих Мягких Съешь Да Чаю Выпей Же')
|
||||||
|
;
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
from test_non_coll
|
||||||
|
where txt_non_coll like 'QWERTY%%'
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
from test_collated
|
||||||
|
where txt_ci like 'еЩё%%'
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
from test_collated
|
||||||
|
where txt_ai_ci like 'ёЩЕ%%'
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
from test_collated
|
||||||
|
where txt_ci between
|
||||||
|
rpad('', {max_indx6}, 'ещё Съешь ЭТИХ Мягких Французских Булочек Да Выпей Же Чаю')
|
||||||
|
and
|
||||||
|
rpad('', {max_indx6}, 'ЕЩЁ Съешь Этих МЯГКИХ фРанцузских Булочек Да Выпей Же Чаю')
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
from test_collated
|
||||||
|
where txt_ai_ci between
|
||||||
|
rpad('', {max_indx6}, 'ёще фРанцузских Булочек Этих Мягких Съешь Да Чаю Выпёй Же')
|
||||||
|
and
|
||||||
|
rpad('', {max_indx6}, 'ёщё Французских Булочёк Этих Мягких Съёшь Да Чаю Выпёй Жё')
|
||||||
|
;
|
||||||
|
|
||||||
|
set plan off;
|
||||||
|
'''
|
||||||
|
|
||||||
|
act_1 = python_act('db_1', substitutions=substitutions_1)
|
||||||
|
|
||||||
@pytest.mark.version('>=4.0')
|
@pytest.mark.version('>=4.0')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action):
|
||||||
def test_1(db_1):
|
# CHANGE FW to OFF
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
with act_1.connect_server() as srv:
|
||||||
|
srv.database.set_write_mode(database=str(act_1.db.db_path), mode=DbWriteMode.ASYNC)
|
||||||
|
# 1. FIRST RUN DML_TEST
|
||||||
|
act_1.script = test_script_1
|
||||||
|
act_1.execute()
|
||||||
|
run_dml_log_1 = act_1.stdout
|
||||||
|
# 2. EXTRACT METADATA-1
|
||||||
|
act_1.reset()
|
||||||
|
act_1.isql(switches=['-x'])
|
||||||
|
extract_meta1_sql = act_1.stdout
|
||||||
|
# 3. VALIDATE DATABASE-1
|
||||||
|
# [pcisar] I don't understand the point of validation as the original test does not check
|
||||||
|
# that validation passed
|
||||||
|
with act_1.connect_server() as srv:
|
||||||
|
srv.database.validate(database=str(act_1.db.db_path))
|
||||||
|
validate_log_1 = srv.readlines()
|
||||||
|
# 4. TRY TO BACKUP AND RESTORE
|
||||||
|
with act_1.connect_server() as srv:
|
||||||
|
backup = BytesIO()
|
||||||
|
srv.database.local_backup(database=str(act_1.db.db_path), backup_stream=backup)
|
||||||
|
backup.seek(0)
|
||||||
|
srv.database.local_restore(backup_stream=backup, database=str(act_1.db.db_path),
|
||||||
|
flags=SrvRestoreFlag.REPLACE)
|
||||||
|
backup.close()
|
||||||
|
# 5. EXTRACT METADATA-2
|
||||||
|
act_1.reset()
|
||||||
|
act_1.isql(switches=['-x'])
|
||||||
|
extract_meta2_sql = act_1.stdout
|
||||||
|
# 6. AGAIN RUN DML_TEST
|
||||||
|
act_1.reset()
|
||||||
|
act_1.script = test_script_1
|
||||||
|
act_1.execute()
|
||||||
|
run_dml_log_2 = act_1.stdout
|
||||||
|
# 7. VALIDATE DATABASE-2
|
||||||
|
with act_1.connect_server() as srv:
|
||||||
|
srv.database.validate(database=str(act_1.db.db_path))
|
||||||
|
validate_log_2 = srv.readlines()
|
||||||
|
# 8. CHECKS
|
||||||
|
# 1) STDERR for: create DB, backup, restore, validation-1 and validation-2 - they all must be EMPTY.
|
||||||
|
# [pcisar] This is granted as exception would be raised if there would be any error
|
||||||
|
# 2) diff between dml_1.log and dml_2.log should be EMPTY.
|
||||||
|
assert run_dml_log_1 == run_dml_log_2
|
||||||
|
# 3) diff between meta1.log and meta2.log should be EMPTY.
|
||||||
|
assert extract_meta1_sql == extract_meta2_sql
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from firebird.qa import db_factory, isql_act, Action
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
from io import BytesIO
|
||||||
|
from firebird.driver import SrvRestoreFlag, SrvBackupFlag
|
||||||
|
|
||||||
# version: 2.5
|
# version: 2.5
|
||||||
# resources: None
|
# resources: None
|
||||||
@ -124,16 +126,49 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#---
|
#---
|
||||||
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
|
||||||
|
test_script_1 = '''
|
||||||
|
delete from log;
|
||||||
|
commit;
|
||||||
|
set term ^;
|
||||||
|
execute block as begin
|
||||||
|
rdb$set_context('USER_SESSION', 'INIT_STATE','1');
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
alter trigger trg_attach active;
|
||||||
|
alter trigger trg_detach active;
|
||||||
|
commit;
|
||||||
|
--set count on;
|
||||||
|
--select * from log;
|
||||||
|
'''
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
expected_stdout_1 = """
|
expected_stdout_1 = """
|
||||||
Records affected: 0
|
Records affected: 0
|
||||||
Records affected: 0
|
"""
|
||||||
"""
|
|
||||||
|
|
||||||
@pytest.mark.version('>=2.5')
|
@pytest.mark.version('>=2.5')
|
||||||
@pytest.mark.xfail
|
def test_1(act_1: Action):
|
||||||
def test_1(db_1):
|
check_sql = 'set list on; set count on; select 1, g.* from log g;'
|
||||||
pytest.fail("Test not IMPLEMENTED")
|
act_1.execute()
|
||||||
|
backup = BytesIO()
|
||||||
|
with act_1.connect_server() as srv:
|
||||||
|
srv.database.local_backup(database=str(act_1.db.db_path), backup_stream=backup,
|
||||||
|
flags=SrvBackupFlag.NO_TRIGGERS)
|
||||||
|
backup.seek(0)
|
||||||
|
act_1.reset()
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.isql(switches=['-nod'], input=check_sql)
|
||||||
|
assert act_1.clean_stdout == act_1.clean_expected_stdout
|
||||||
|
srv.database.local_restore(backup_stream=backup, database=str(act_1.db.db_path),
|
||||||
|
flags=SrvRestoreFlag.REPLACE)
|
||||||
|
backup.close()
|
||||||
|
act_1.reset()
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.isql(switches=['-nod'], input=check_sql)
|
||||||
|
assert act_1.clean_stdout == act_1.clean_expected_stdout
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user