6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 13:33:07 +01:00
firebird-qa/tests/bugs/core_5831_test.py

129 lines
4.2 KiB
Python

#coding:utf-8
"""
ID: issue-6092
ISSUE: 6092
TITLE: Not user friendly output of gstat at encrypted database
DESCRIPTION:
Test encrypts empty database: we run 'ALTER DATABASE ENCRYPT ...' and wait until 'SHOW DATABASE'
will display text that database encrypted.
Then we check that 'gstat -h' output contains (beside encryption state in 'Attributes' line):
* crypt checksum
* key hash
* encryption key name
Because of randomness in data that is displayed, we use substitutions list which must suppress it.
JIRA: CORE-5831
FBTEST: bugs.core_5831
NOTES:
[13.06.2022] pzotov
Checked on 4.0.1.2692, 3.0.8.33535 - both on Linux and Windows.
"""
import os
import re
import datetime as py_dt
from datetime import timedelta
import pytest
from firebird.qa import *
from firebird.driver import DatabaseError
###########################
### S E T T I N G S ###
###########################
# QA_GLOBALS -- dict, is defined in qa/plugin.py, obtain settings
# from act.files_dir/'test_config.ini':
enc_settings = QA_GLOBALS['encryption']
# ACHTUNG: this must be carefully tuned on every new host:
#
MAX_WAITING_ENCR_FINISH = int(enc_settings['MAX_WAIT_FOR_ENCR_FINISH_WIN' if os.name == 'nt' else 'MAX_WAIT_FOR_ENCR_FINISH_NIX'])
assert MAX_WAITING_ENCR_FINISH > 0
ENCRYPTION_PLUGIN = enc_settings['encryption_plugin'] # fbSampleDbCrypt
ENCRYPTION_KEY = enc_settings['encryption_key'] # Red
substitutions = [
('ATTRIBUTES (FORCE WRITE,)? ENCRYPTED, PLUGIN.*', 'ATTRIBUTES ENCRYPTED'),
('CRYPT CHECKSUM.*', 'CRYPT CHECKSUM'),
('KEY HASH: .*', 'KEY HASH')
]
db = db_factory()
act = python_act('db', substitutions=substitutions)
expected_stdout_gstat = """
ATTRIBUTES ENCRYPTED
CRYPT CHECKSUM: EDU3BS2YNQ2V+8OKQARRH2UQEKW=
KEY HASH: 9EG30XIHPMHNOZJGGMLLOD+NA9Y=
ENCRYPTION KEY NAME: RED
"""
@pytest.mark.encryption
@pytest.mark.version('>=3.0.4')
def test_1(act: Action, capsys):
encryption_started = False
encryption_finished = False
with act.db.connect() as con:
t1=py_dt.datetime.now()
d1 = t1-t1
sttm = f'alter database encrypt with "{ENCRYPTION_PLUGIN}" key "{ENCRYPTION_KEY}"'
try:
con.execute_immediate(sttm)
con.commit()
encryption_started = True
except DatabaseError as e:
# -ALTER DATABASE failed
# -Crypt plugin fbSampleDbCrypt failed to load
# ==> no sense to do anything else, encryption_started remains False.
print( e.__str__() )
while encryption_started:
t2=py_dt.datetime.now()
d1=t2-t1
if d1.seconds*1000 + d1.microseconds//1000 > MAX_WAITING_ENCR_FINISH:
print(f'TIMEOUT EXPIRATION: encryption took {d1.seconds*1000 + d1.microseconds//1000} ms which exceeds limit = {MAX_WAITING_ENCR_FINISH} ms.')
break
# Possible output:
# Database not encrypted
# Database encrypted, crypt thread not complete
act.isql(switches=['-q'], input = 'show database;', combine_output = True)
if 'Database encrypted' in act.stdout:
if 'not complete' in act.stdout:
pass
else:
encryption_finished = True
break
act.reset()
act.expected_stdout = ''
act.stdout = capsys.readouterr().out
assert act.clean_stdout == act.clean_expected_stdout
act.reset()
if encryption_finished:
act.gstat(switches=['-h'])
db_attr_check_patterns = [
r"\s*Attributes\.*"
,r"crypt\s+checksum:\s+\S+"
,r"key\s+hash:\s+\S+"
,r"encryption\s+key\s+name:\s+\S+"
]
db_attr_check_patterns = [ re.compile(s, re.IGNORECASE) for s in db_attr_check_patterns ]
for line in act.stdout.splitlines():
if act.match_any(line, db_attr_check_patterns):
print(line.upper().replace('\t',' '))
act.expected_stdout = expected_stdout_gstat
act.stdout = capsys.readouterr().out
assert act.clean_stdout == act.clean_expected_stdout