mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 21:43:06 +01:00
129 lines
4.2 KiB
Python
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
|