mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 21:43:06 +01:00
133 lines
5.0 KiB
Python
133 lines
5.0 KiB
Python
#coding:utf-8
|
|
|
|
"""
|
|
ID: issue-6785
|
|
ISSUE: 6785
|
|
TITLE: Problem when restoring the database on FB 4.0 RC1 (gbak regression)
|
|
DESCRIPTION:
|
|
Test used database backup that was provided in the ticket.
|
|
|
|
Maximal allowed time is set here for restoring process and gbak will be
|
|
forcedly killed if it can not complete during this time.
|
|
Currently this time is 300 seconds (see 'MAX_THRESHOLD' variable).
|
|
|
|
Database is validated (using 'gfix -v -full') after successful restore finish.
|
|
Test checks that returned codes for both gbak and validation are zero.
|
|
Also, it checks that firebird.log contains message with 'all-zeroes' values
|
|
for validation outcome ("Validation finished: 0 errors, 0 warnings, 0 fixed").
|
|
|
|
Restore issues warnings:
|
|
gbak: WARNING:function F_DATETOSTR is not defined
|
|
gbak: WARNING: module name or entrypoint could not be found
|
|
gbak: WARNING:function F_DATETOSTR is not defined
|
|
gbak: WARNING: module name or entrypoint could not be found
|
|
All of them are ignored by this test when gbak output is parsed.
|
|
|
|
Confirmed bug on 4.0.0.2452 SS: gbak infinitely hanged.
|
|
Checked on 4.0.0.2453 SS/CS (Linux and Windows): all OK, restore lasts near 200s.
|
|
FBTEST: bugs.gh_6785
|
|
NOTES:
|
|
[30.06.2022] pzotov
|
|
Checked again on 4.0.1.2692, 5.0.0.509. Confirmed reproducing of problem on 4.0.0.2452.
|
|
|
|
[20.07.2022] pzotov
|
|
firebird.log may contain messages encoded in different code pages (say, in cp1251 and in utf8).
|
|
Because of this, one need to IGNORE any decoding errors when obtain content of log.
|
|
In this case call of act.get_firebird_log() will raise:
|
|
UnicodeDecodeError: 'ascii' codec can't decode byte 0x** ... ordinal not in range(128)
|
|
|
|
We have either to specify this using somewhat like "act.connect_server(encoding_errors = 'ignore')",
|
|
or to change firebid-driver.conf - and this will be more proper way.
|
|
This file (firebid-driver.conf) must have section with name [DEFAULT] with encoding_errors = ignore.
|
|
Test assumes exactly THIS, i.e. we do NOT specify "encoding_errors = 'ignore'" in acty.connect_server()
|
|
"""
|
|
|
|
import locale
|
|
import zipfile
|
|
import subprocess
|
|
import re
|
|
|
|
import pytest
|
|
from firebird.qa import *
|
|
from firebird.driver import SrvRepairFlag
|
|
from pathlib import Path
|
|
from difflib import unified_diff
|
|
import time
|
|
|
|
db = db_factory()
|
|
act = python_act('db')
|
|
|
|
tmp_log = temp_file('gh_6785.tmp.log')
|
|
tmp_fbk = temp_file('gh_6785.tmp.fbk')
|
|
tmp_fdb = temp_file('gh_6785.tmp.fdb')
|
|
|
|
###################
|
|
MAX_THRESHOLD = 300
|
|
###################
|
|
|
|
expected_stdout = """
|
|
Restore retcode: 0
|
|
Validation retcode: 0
|
|
"""
|
|
|
|
restore_completed_msg = 'Restore COMPLETED.'
|
|
|
|
@pytest.mark.version('>=4.0')
|
|
def test_1(act: Action, tmp_fbk: Path, tmp_fdb: Path, tmp_log: Path, capsys):
|
|
zipped_fbk_file = zipfile.Path(act.files_dir / 'gh_6785.zip', at = 'gh_6785.fbk')
|
|
tmp_fbk.write_bytes(zipped_fbk_file.read_bytes())
|
|
|
|
restore_code = -1
|
|
|
|
# If the timeout expires, the child process will be killed and waited for.
|
|
# The TimeoutExpired exception will be re-raised after the child process has terminated.
|
|
try:
|
|
p = subprocess.run([ act.vars['gbak'],
|
|
'-user', act.db.user, '-password', act.db.password,
|
|
'-rep', tmp_fbk, tmp_fdb,
|
|
'-st', 'tdrw',
|
|
'-v', '-y', str(tmp_log)
|
|
]
|
|
,stderr = subprocess.STDOUT
|
|
,timeout = MAX_THRESHOLD
|
|
)
|
|
print( restore_completed_msg )
|
|
restore_code = p.returncode
|
|
|
|
except Exception as e:
|
|
print(e.__str__())
|
|
tmp_fdb.unlink()
|
|
|
|
act.expected_stdout = restore_completed_msg
|
|
act.stdout = capsys.readouterr().out
|
|
assert act.clean_stdout == act.clean_expected_stdout
|
|
act.reset()
|
|
|
|
if restore_code == 0:
|
|
|
|
# Get FB log before validation, run validation and get FB log after it:
|
|
with act.connect_server() as srv:
|
|
|
|
fblog_1 = act.get_firebird_log()
|
|
#with act.connect_server(encoding=locale.getpreferredencoding()) as srv:
|
|
# srv.info.get_log()
|
|
# fblog_1 = srv.readlines()
|
|
|
|
srv.database.repair(database = str(tmp_fdb), flags=SrvRepairFlag.CORRUPTION_CHECK)
|
|
|
|
fblog_2 = act.get_firebird_log()
|
|
#with act.connect_server(encoding=locale.getpreferredencoding()) as srv:
|
|
# srv.info.get_log()
|
|
# fblog_2 = srv.readlines()
|
|
|
|
p_diff = re.compile('Validation finished: \\d+ errors, \\d+ warnings, \\d+ fixed')
|
|
validation_result = ''
|
|
for line in unified_diff(fblog_1, fblog_2):
|
|
if line.startswith('+') and p_diff.search(line):
|
|
validation_result =line.strip().replace('\t', ' ')
|
|
break
|
|
|
|
|
|
assert validation_result == '+ Validation finished: 0 errors, 0 warnings, 0 fixed'
|
|
act.reset()
|