2 @message |
assert
- Problem(s) detected:
- blob_err:
- arithmetic exception, numeric overflow, or string truncation
- -Cannot transliterate character between character sets
LOG DETAILS:
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 act_db_main = <firebird.qa.plugin.Action object at [hex]>
2024-04-05 06:52:09.211 act_db_repl = <firebird.qa.plugin.Action object at [hex]>
2024-04-05 06:52:09.211 tmp_data = WindowsPath('R:/temp/qa/fbqa/test_12055/tmp_blob_for_replication.dat')
2024-04-05 06:52:09.211 capsys = <_pytest.capture.CaptureFixture object at [hex]>
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 @pytest.mark.replication
2024-04-05 06:52:09.211 @pytest.mark.version('>=4.0.5')
2024-04-05 06:52:09.211 def test_1(act_db_main: Action, act_db_repl: Action, tmp_data: Path, capsys):
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 out_prep, out_main, out_drop, blob_err = '', '', '', ''
2024-04-05 06:52:09.211 # Obtain full path + filename for DB_MAIN and DB_REPL aliases.
2024-04-05 06:52:09.211 # NOTE: we must NOT use 'a.db.db_path' for ALIASED databases!
2024-04-05 06:52:09.211 # It will return '.' rather than full path+filename.
2024-04-05 06:52:09.211 # Use only con.info.name for that!
2024-04-05 06:52:09.211 #
2024-04-05 06:52:09.211 db_info = {}
2024-04-05 06:52:09.211 for a in (act_db_main, act_db_repl):
2024-04-05 06:52:09.211 with a.db.connect() as con:
2024-04-05 06:52:09.211 db_info[a, 'db_full_path'] = con.info.name
2024-04-05 06:52:09.211 cur = con.cursor()
2024-04-05 06:52:09.211 cur.execute('select trim(rdb$character_set_name) from rdb$database')
2024-04-05 06:52:09.211 for r in cur:
2024-04-05 06:52:09.211 db_info[a, 'db_cset_initial'] = r[0]
2024-04-05 06:52:09.211 con.execute_immediate('alter database set default character set utf8')
2024-04-05 06:52:09.211 con.commit()
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 # Must be EMPTY:
2024-04-05 06:52:09.211 out_prep = capsys.readouterr().out
2024-04-05 06:52:09.211 if out_prep:
2024-04-05 06:52:09.211 # Some problem raised during change DB header(s)
2024-04-05 06:52:09.211 pass
2024-04-05 06:52:09.211 else:
2024-04-05 06:52:09.211 sql_init = '''
2024-04-05 06:52:09.211 set bail on;
2024-04-05 06:52:09.211 recreate table test (
2024-04-05 06:52:09.211 id bigint generated by default as identity constraint test_pk primary key
2024-04-05 06:52:09.211 ,v varchar(30) character set utf8
2024-04-05 06:52:09.211 ,b blob sub_type text character set utf8
2024-04-05 06:52:09.211 );
2024-04-05 06:52:09.211 commit;
2024-04-05 06:52:09.211 '''
2024-04-05 06:52:09.211 act_db_main.isql(switches=['-q'], charset = 'utf8', input = sql_init, combine_output = True)
2024-04-05 06:52:09.211 out_prep = act_db_main.clean_stdout
2024-04-05 06:52:09.211 act_db_main.reset()
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 if out_prep:
2024-04-05 06:52:09.211 # Some problem raised during init_sql execution
2024-04-05 06:52:09.211 pass
2024-04-05 06:52:09.211 else:
2024-04-05 06:52:09.211 # Query to be used for check that all DB objects present in replica (after last DML statement completed on master DB):
2024-04-05 06:52:09.211 ddl_ready_query = "select 1 from rdb$relations where rdb$relation_name = upper('test')"
2024-04-05 06:52:09.211 ##############################################################################
2024-04-05 06:52:09.211 ### W A I T U N T I L R E P L I C A B E C O M E S A C T U A L ###
2024-04-05 06:52:09.211 ##############################################################################
2024-04-05 06:52:09.211 watch_replica( act_db_repl, MAX_TIME_FOR_WAIT_DATA_IN_REPLICA, ddl_ready_query)
2024-04-05 06:52:09.211 # Must be EMPTY:
2024-04-05 06:52:09.211 out_prep = capsys.readouterr().out
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 if out_prep:
2024-04-05 06:52:09.211 # Some problem raised with delivering DDL changes to replica
2024-04-05 06:52:09.211 pass
2024-04-05 06:52:09.211 else:
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 cp1251_txt1 = bytes('', 'cp1251').decode('cp1251')
2024-04-05 06:52:09.211 cp1251_txt2 = bytes('', 'cp1251').decode('cp1251')
2024-04-05 06:52:09.211 with act_db_main.db.connect(charset = 'win1251') as con:
2024-04-05 06:52:09.211 cur = con.cursor()
2024-04-05 06:52:09.211 ps = cur.prepare("insert into test(v, b) values(?, ?)")
2024-04-05 06:52:09.211 cur.execute(ps, (cp1251_txt1, None))
2024-04-05 06:52:09.211 cur.execute(ps, (None, cp1251_txt2))
2024-04-05 06:52:09.211 con.commit()
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 # Must be EMPTY:
2024-04-05 06:52:09.211 out_main = capsys.readouterr().out
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 if out_main:
2024-04-05 06:52:09.211 # Some problem raised with writing blob into replica or master DB:
2024-04-05 06:52:09.211 pass
2024-04-05 06:52:09.211 else:
2024-04-05 06:52:09.211 # No errors must be now. We have to wait now until blob from MASTER be delivered
2024-04-05 06:52:09.211 # to REPLICA and replace there "old" blob (in the record with ID = 1).
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 # Query to be used that replica DB contains all expected data (after last DML statement completed on master DB):
2024-04-05 06:52:09.211 isql_check_script = """
2024-04-05 06:52:09.211 set bail on;
2024-04-05 06:52:09.211 set list on;
2024-04-05 06:52:09.211 set count on;
2024-04-05 06:52:09.211 select
2024-04-05 06:52:09.211 rdb$get_context('SYSTEM','REPLICA_MODE') replica_mode
2024-04-05 06:52:09.211 ,id
2024-04-05 06:52:09.211 from test
2024-04-05 06:52:09.211 where id = 2;
2024-04-05 06:52:09.211 """
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 isql_expected_out = f"""
2024-04-05 06:52:09.211 REPLICA_MODE READ-ONLY
2024-04-05 06:52:09.211 ID 2
2024-04-05 06:52:09.211 Records affected: 1
2024-04-05 06:52:09.211 """
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 ##############################################################################
2024-04-05 06:52:09.211 ### W A I T U N T I L R E P L I C A B E C O M E S A C T U A L ###
2024-04-05 06:52:09.211 ##############################################################################
2024-04-05 06:52:09.211 watch_replica( act_db_repl, MAX_TIME_FOR_WAIT_DATA_IN_REPLICA, '', isql_check_script, isql_expected_out)
2024-04-05 06:52:09.211 # Must be EMPTY:
2024-04-05 06:52:09.211 out_main = capsys.readouterr().out
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 if out_main:
2024-04-05 06:52:09.211 # Some problem raised with writing blob into replica or master DB:
2024-04-05 06:52:09.211 pass
2024-04-05 06:52:09.211 else:
2024-04-05 06:52:09.211 with act_db_repl.db.connect(charset = 'win1251') as con:
2024-04-05 06:52:09.211 cur = con.cursor()
2024-04-05 06:52:09.211 try:
2024-04-05 06:52:09.211 cur.execute("select id from test where b = ?", (cp1251_txt2,))
2024-04-05 06:52:09.211 for r in cur:
2024-04-05 06:52:09.211 pass
2024-04-05 06:52:09.211 except DatabaseError as e:
2024-04-05 06:52:09.211 # On 6.0.0.217 error raised here:
2024-04-05 06:52:09.211 # arithmetic exception, numeric overflow, or string truncation
2024-04-05 06:52:09.211 # -Cannot transliterate character between character sets
2024-04-05 06:52:09.211 #
2024-04-05 06:52:09.211 blob_err = e.__str__()
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 drop_db_objects(act_db_main, act_db_repl, capsys)
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 # Return character set to NONE for both databases:
2024-04-05 06:52:09.211 for a in (act_db_main, act_db_repl):
2024-04-05 06:52:09.211 with a.db.connect() as con:
2024-04-05 06:52:09.211 con.execute_immediate(f"alter database set default character set {db_info[a, 'db_cset_initial']}")
2024-04-05 06:52:09.211 con.commit()
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 # Must be EMPTY:
2024-04-05 06:52:09.211 out_drop = capsys.readouterr().out
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 if [ x for x in (out_prep, out_main, blob_err, out_drop) if x.strip() ]:
2024-04-05 06:52:09.211 # We have a problem either with DDL/DML or with dropping DB objects.
2024-04-05 06:52:09.211 # First, we have to RECREATE both master and slave databases
2024-04-05 06:52:09.211 # (otherwise further execution of this test or other replication-related tests most likely will fail):
2024-04-05 06:52:09.211 out_reset = reset_replication(act_db_main, act_db_repl, db_info[act_db_main,'db_full_path'], db_info[act_db_repl,'db_full_path'])
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 # Next, we display out_main, out_drop and out_reset:
2024-04-05 06:52:09.211 #
2024-04-05 06:52:09.211 print('Problem(s) detected:')
2024-04-05 06:52:09.211 if out_prep.strip():
2024-04-05 06:52:09.211 print('out_prep:')
2024-04-05 06:52:09.211 print(out_prep)
2024-04-05 06:52:09.211 if out_main.strip():
2024-04-05 06:52:09.211 print('out_main:')
2024-04-05 06:52:09.211 print(out_main)
2024-04-05 06:52:09.211 if blob_err.strip():
2024-04-05 06:52:09.211 print('blob_err:')
2024-04-05 06:52:09.211 print(blob_err)
2024-04-05 06:52:09.211 if out_drop.strip():
2024-04-05 06:52:09.211 print('out_drop:')
2024-04-05 06:52:09.211 print(out_drop)
2024-04-05 06:52:09.211 if out_reset.strip():
2024-04-05 06:52:09.211 print('out_reset:')
2024-04-05 06:52:09.211 print(out_reset)
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 > assert '' == capsys.readouterr().out
2024-04-05 06:52:09.211 E assert
2024-04-05 06:52:09.211 E - Problem(s) detected:
2024-04-05 06:52:09.211 E - blob_err:
2024-04-05 06:52:09.211 E - arithmetic exception, numeric overflow, or string truncation
2024-04-05 06:52:09.211 E - -Cannot transliterate character between character sets
2024-04-05 06:52:09.211
2024-04-05 06:52:09.211 tests\functional\replication\test_blob_characters_garbled_when_conn_charset_differs.py:490: AssertionError
|
3 #text |
act_db_main = <firebird.qa.plugin.Action pytest object at [hex]>
act_db_repl = <firebird.qa.plugin.Action pytest object at [hex]>
tmp_data = WindowsPath('R:/temp/qa/fbqa/test_12055/tmp_blob_for_replication.dat')
capsys = <_pytest.capture.CaptureFixture pytest object at [hex]>
@pytest.mark.replication
@pytest.mark.version('>=4.0.5')
def test_1(act_db_main: Action, act_db_repl: Action, tmp_data: Path, capsys):
out_prep, out_main, out_drop, blob_err = '', '', '', ''
# Obtain full path + filename for DB_MAIN and DB_REPL aliases.
# NOTE: we must NOT use 'a.db.db_path' for ALIASED databases!
# It will return '.' rather than full path+filename.
# Use only con.info.name for that!
#
db_info = {}
for a in (act_db_main, act_db_repl):
with a.db.connect() as con:
db_info[a, 'db_full_path'] = con.info.name
cur = con.cursor()
cur.execute('select trim(rdb$character_set_name) from rdb$database')
for r in cur:
db_info[a, 'db_cset_initial'] = r[0]
con.execute_immediate('alter database set default character set utf8')
con.commit()
# Must be EMPTY:
out_prep = capsys.readouterr().out
if out_prep:
# Some problem raised during change DB header(s)
pass
else:
sql_init = '''
set bail on;
recreate table test (
id bigint generated by default as identity constraint test_pk primary key
,v varchar(30) character set utf8
,b blob sub_type text character set utf8
);
commit;
'''
act_db_main.isql(switches=['-q'], charset = 'utf8', input = sql_init, combine_output = True)
out_prep = act_db_main.clean_stdout
act_db_main.reset()
if out_prep:
# Some problem raised during init_sql execution
pass
else:
# Query to be used for check that all DB objects present in replica (after last DML statement completed on master DB):
ddl_ready_query = "select 1 from rdb$relations where rdb$relation_name = upper('test')"
##############################################################################
### W A I T U N T I L R E P L I C A B E C O M E S A C T U A L ###
##############################################################################
watch_replica( act_db_repl, MAX_TIME_FOR_WAIT_DATA_IN_REPLICA, ddl_ready_query)
# Must be EMPTY:
out_prep = capsys.readouterr().out
if out_prep:
# Some problem raised with delivering DDL changes to replica
pass
else:
cp1251_txt1 = bytes('привет', 'cp1251').decode('cp1251')
cp1251_txt2 = bytes('мир', 'cp1251').decode('cp1251')
with act_db_main.db.connect(charset = 'win1251') as con:
cur = con.cursor()
ps = cur.prepare("insert into test(v, b) values(?, ?)")
cur.execute(ps, (cp1251_txt1, None))
cur.execute(ps, (None, cp1251_txt2))
con.commit()
# Must be EMPTY:
out_main = capsys.readouterr().out
if out_main:
# Some problem raised with writing blob into replica or master DB:
pass
else:
# No errors must be now. We have to wait now until blob from MASTER be delivered
# to REPLICA and replace there "old" blob (in the record with ID = 1).
# Query to be used that replica DB contains all expected data (after last DML statement completed on master DB):
isql_check_script = """
set bail on;
set list on;
set count on;
select
rdb$get_context('SYSTEM','REPLICA_MODE') replica_mode
,id
from test
where id = 2;
"""
isql_expected_out = f"""
REPLICA_MODE READ-ONLY
ID 2
Records affected: 1
"""
##############################################################################
### W A I T U N T I L R E P L I C A B E C O M E S A C T U A L ###
##############################################################################
watch_replica( act_db_repl, MAX_TIME_FOR_WAIT_DATA_IN_REPLICA, '', isql_check_script, isql_expected_out)
# Must be EMPTY:
out_main = capsys.readouterr().out
if out_main:
# Some problem raised with writing blob into replica or master DB:
pass
else:
with act_db_repl.db.connect(charset = 'win1251') as con:
cur = con.cursor()
try:
cur.execute("select id from test where b = ?", (cp1251_txt2,))
for r in cur:
pass
except DatabaseError as e:
# On 6.0.0.217 error raised here:
# arithmetic exception, numeric overflow, or string truncation
# -Cannot transliterate character between character sets
#
blob_err = e.__str__()
drop_db_objects(act_db_main, act_db_repl, capsys)
# Return character set to NONE for both databases:
for a in (act_db_main, act_db_repl):
with a.db.connect() as con:
con.execute_immediate(f"alter database set default character set {db_info[a, 'db_cset_initial']}")
con.commit()
# Must be EMPTY:
out_drop = capsys.readouterr().out
if [ x for x in (out_prep, out_main, blob_err, out_drop) if x.strip() ]:
# We have a problem either with DDL/DML or with dropping DB objects.
# First, we have to RECREATE both master and slave databases
# (otherwise further execution of this test or other replication-related tests most likely will fail):
out_reset = reset_replication(act_db_main, act_db_repl, db_info[act_db_main,'db_full_path'], db_info[act_db_repl,'db_full_path'])
# Next, we display out_main, out_drop and out_reset:
#
print('Problem(s) detected:')
if out_prep.strip():
print('out_prep:')
print(out_prep)
if out_main.strip():
print('out_main:')
print(out_main)
if blob_err.strip():
print('blob_err:')
print(blob_err)
if out_drop.strip():
print('out_drop:')
print(out_drop)
if out_reset.strip():
print('out_reset:')
print(out_reset)
> assert '' == capsys.readouterr().out
E assert
E - Problem(s) detected:
E - blob_err:
E - arithmetic exception, numeric overflow, or string truncation
E - -Cannot transliterate character between character sets
tests\functional\replication\test_blob_characters_garbled_when_conn_charset_differs.py:490: AssertionError
|