mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-23 14:03:06 +01:00
160 lines
6.4 KiB
Python
160 lines
6.4 KiB
Python
#coding:utf-8
|
|
|
|
"""
|
|
ID: issue-6492
|
|
ISSUE: 6492
|
|
TITLE: A number of errors when database name is longer than 255 symbols
|
|
DESCRIPTION:
|
|
Test verifies that one may to create DB with total path plus name length L = 255 and 259 characters.
|
|
Each DB is then subject for 'gbak -b', 'gbak -c', 'gstat -h', 'gfix -sweep' and 'gfix -v -full'.
|
|
All these commands must NOT issue something to their STDERR.
|
|
|
|
STDOUT-log of initial SQL must contain full DB name.
|
|
Changed part of firebird.log for SWEEP and VALIDATION also must have full DB name (this is verified using regexp):
|
|
+[tab]Database: C:\\FBTESTING\\QA\\FBT-REPO\\TMP\\ABC.FDB // for validation
|
|
+[tab]Database "C:\\FBTESTING\\QA\\FBT-REPO\\TMP\\ABC.FDB // for sweep
|
|
|
|
STDOUT-logs of backup, restore and gstat currently (09-mar-2020) have only truncated name (~235...241 chars).
|
|
This may change in the future if FB developers will decide to fix this small inconveniences.
|
|
|
|
For L=259 we must see in backup log following phrase:
|
|
gbak:text for attribute 7 is too large in put_asciz(), truncating to 255 bytes
|
|
- but currently this is not checked here.
|
|
[09.02.2022] pcisar
|
|
Fails on Windows10 / 4.0.1 with:
|
|
"CreateFile (create)" operation for file "..."
|
|
-Error while trying to create file
|
|
-System can't find specified path
|
|
Variant with 255 chars fails in init script, while 259 chars variant fails in database fixture while
|
|
db creation.
|
|
On national windows with OS i/o error messages in locale.getpreferredencoding(), it may fail while
|
|
reading stderr from isql. But using io_enc=locale.getpreferredencoding() will show the message.
|
|
JIRA: CORE-6248
|
|
FBTEST: bugs.core_6248
|
|
"""
|
|
|
|
import pytest
|
|
import re
|
|
import time
|
|
import platform
|
|
from difflib import unified_diff
|
|
from firebird.qa import *
|
|
from firebird.driver import SrvRepairFlag
|
|
|
|
init_script = """
|
|
set list on;
|
|
|
|
create exception exc_dbname_diff q'{Value in mon$database.mon$database_name differs from rdb$get_context('SYSTEM', 'DB_NAME'):@1@2@3=== vs ===@4@5}';
|
|
set term ^;
|
|
execute block returns(
|
|
mon_database_column varchar(260)
|
|
,sys_context_db_name varchar(260)
|
|
) as
|
|
declare lf char(1) = x'0A';
|
|
begin
|
|
select
|
|
mon$database_name as mon_database_column
|
|
from mon$database
|
|
into mon_database_column;
|
|
|
|
sys_context_db_name = rdb$get_context('SYSTEM', 'DB_NAME');
|
|
|
|
if ( substring( sys_context_db_name from 1 for 255 ) is distinct from mon_database_column ) then
|
|
begin
|
|
exception exc_dbname_diff using(
|
|
lf
|
|
,mon_database_column
|
|
,lf
|
|
,lf
|
|
,sys_context_db_name
|
|
);
|
|
end
|
|
|
|
suspend;
|
|
end
|
|
^
|
|
set term ;^
|
|
commit;
|
|
"""
|
|
|
|
db = db_factory()
|
|
|
|
act = python_act('db')
|
|
|
|
expected_stdout = """
|
|
ddl : found at least 255 characters
|
|
backup : found truncated DB name.
|
|
restore : found truncated DB name.
|
|
gstat : found truncated DB name.
|
|
fblog_diff_sweep : found at least 255 characters
|
|
fblog_diff_validate : found at least 255 characters
|
|
"""
|
|
|
|
@pytest.fixture
|
|
def test_db(request: pytest.FixtureRequest, db_path) -> Database:
|
|
required_name_len = request.param[0]
|
|
chars2fil = request.param[1]
|
|
filename = (chars2fil * 1000)[:required_name_len - len(str(db_path)) - 4] + '.fdb'
|
|
db = Database(db_path, filename)
|
|
db.create()
|
|
yield db
|
|
db.drop()
|
|
|
|
MINIMAL_LEN_TO_SHOW = 255
|
|
|
|
PATTERN = re.compile('\\+\\s+Database[:]{0,1}\\s+"{0,1}', re.IGNORECASE)
|
|
|
|
def check_filename_presence(lines, *, log_name: str, db: Database):
|
|
filename = str(db.db_path) # To convert Path to string
|
|
for line in lines:
|
|
if log_name not in ('fblog_diff_sweep', 'fblog_diff_validate') or line.startswith('+') and PATTERN.search(line):
|
|
if filename[:MINIMAL_LEN_TO_SHOW].upper() in line.upper():
|
|
print(f'{log_name} : found at least {str(MINIMAL_LEN_TO_SHOW)} characters')
|
|
return
|
|
elif filename[:128].upper() in line.upper():
|
|
print(f'{log_name} : found truncated DB name.')
|
|
return
|
|
print(f'{log_name} : DB NAME NOT FOUND')
|
|
|
|
|
|
@pytest.mark.skipif(platform.system() == 'Windows', reason='FIXME: see notes')
|
|
@pytest.mark.version('>=4.0')
|
|
@pytest.mark.parametrize('test_db', [pytest.param((255, 'abc255def'), id='255'),
|
|
pytest.param((259, 'qwe259rty'), id='259')], indirect=True)
|
|
def test_1(act: Action, test_db: Database, capsys):
|
|
# INIT test
|
|
act.isql(switches=['-q', test_db.dsn], input=init_script, connect_db=False)
|
|
check_filename_presence(act.stdout.splitlines(), log_name='ddl', db=test_db)
|
|
# GBAK BACKUP test
|
|
backup_name = test_db.db_path.with_name(f"tmp_6248_backup_{len(test_db.db_path.with_suffix('').name)}.fbk")
|
|
act.reset()
|
|
act.gbak(switches=['-b', '-se', 'localhost:servce_mgr', '-v', '-st', 'tdwr', str(test_db.db_path), str(backup_name)])
|
|
check_filename_presence(act.stdout.splitlines(), log_name='backup', db=test_db)
|
|
# GBAK RESTORE test
|
|
act.reset()
|
|
act.gbak(switches=['-rep', '-se', 'localhost:servce_mgr', '-v', '-st', 'tdwr', str(backup_name), str(test_db.db_path)])
|
|
check_filename_presence(act.stdout.splitlines(), log_name='restore', db=test_db)
|
|
# GSTAT test
|
|
act.reset()
|
|
act.gstat(switches=['-h', test_db.dsn], connect_db=False)
|
|
check_filename_presence(act.stdout.splitlines(), log_name='gstat', db=test_db)
|
|
# SWEEP test
|
|
log_before = act.get_firebird_log()
|
|
with act.connect_server() as srv:
|
|
srv.database.sweep(database=test_db.db_path)
|
|
time.sleep(1) # Let firebird.log to be fulfilled with text about just finished SWEEP
|
|
log_after = act.get_firebird_log()
|
|
check_filename_presence(list(unified_diff(log_before, log_after)), log_name='fblog_diff_sweep', db=test_db)
|
|
# VALIDATE test
|
|
log_before = act.get_firebird_log()
|
|
with act.connect_server() as srv:
|
|
srv.database.repair(database=test_db.db_path, flags=SrvRepairFlag.FULL | SrvRepairFlag.VALIDATE_DB)
|
|
time.sleep(1) # Let firebird.log to be fulfilled with text about just finished VALIDATION
|
|
log_after = act.get_firebird_log()
|
|
check_filename_presence(list(unified_diff(log_before, log_after)), log_name='fblog_diff_validate', db=test_db)
|
|
# Check
|
|
act.reset()
|
|
act.expected_stdout = expected_stdout
|
|
act.stdout = capsys.readouterr().out
|
|
assert act.clean_stdout == act.clean_expected_stdout
|