6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 21:43:06 +01:00
firebird-qa/tests/bugs/core_6248_test.py

367 lines
15 KiB
Python

#coding:utf-8
#
# id: bugs.core_6248
# title: A number of errors when database name is longer than 255 symbols
# decription:
# 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.
#
# Checked on 4.0.0.1796.
# Checked on 4.0.0.2353: rdb$get_context('SYSTEM','DB_NAME') do not cut off full path and name to database
# and can return string with length = 32K, i.e. exceeding length of mon$database_name.
# See commit of 29-01-2021:
# https://github.com/FirebirdSQL/firebird/commit/d4835cab7f48288490ed83541132555c5cd0376d
#
# tracker_id: CORE-6248
# min_versions: ['4.0']
# versions: 4.0
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
# version: 4.0
# resources: None
substitutions_1 = []
init_script_1 = """"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
# test_script_1
#---
#
# import os
# import sys
# import tempfile
# import difflib
# import re
# import time
# import subprocess
# from fdb import services
#
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
# this_db = db_conn.database_name
# db_conn.close()
#
# #--------------------------------------------
#
# def flush_and_close( file_handle ):
# # https://docs.python.org/2/library/os.html#os.fsync
# # If you're starting with a Python file object f,
# # first do f.flush(), and
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
# global os
#
# file_handle.flush()
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
# os.fsync(file_handle.fileno())
# file_handle.close()
#
# #--------------------------------------------
#
# def cleanup( f_names_list ):
# global os
# for f in f_names_list:
# if type(f) == file:
# del_name = f.name
# elif type(f) == str:
# del_name = f
# else:
# print('Unrecognized type of element:', f, ' - can not be treated as file.')
# del_name = None
#
# if del_name and os.path.isfile( del_name ):
# os.remove( del_name )
#
# #--------------------------------------------
#
# def svc_get_fb_log( f_fb_log ):
#
# global subprocess
# subprocess.call([ context['fbsvcmgr_path'],
# "localhost:service_mgr",
# "action_get_fb_log"
# ],
# stdout=f_fb_log, stderr=subprocess.STDOUT
# )
#
# return
#
# #--------------------------------------------
#
# def check_long_dbname(required_name_len, chars2fil):
#
# global time, tempfile, subprocess, difflib
# global flush_and_close, cleanup, svc_get_fb_log, re
#
# MINIMAL_LEN_TO_SHOW=255
# REDUCE_NAME_LEN_BY=0
#
# folder = tempfile.gettempdir()
# folder = context['temp_directory']
# #folder = os.path.dirname(os.path.abspath(__file__))
#
# f_name = ( chars2fil * 1000) [ : required_name_len - len(folder) - len('.fdb') - REDUCE_NAME_LEN_BY ] + '.fdb'
#
# dbname = os.path.join( folder, f_name )
#
# bkname = dbname[:-4] + '.fbk'
#
# cleanup( (dbname,) )
#
# sql_ddl=''' create database 'localhost:%(dbname)s';
# 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;
# ''' % locals()
#
#
# f_sql_chk = open( os.path.join(context['temp_directory'],'tmp_6248_ddl.sql'), 'w')
# f_sql_chk.write(sql_ddl)
# flush_and_close( f_sql_chk )
#
# ########################################################################
#
# f_ddl_log = open( os.path.join(context['temp_directory'],'tmp_6248.ddl_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# f_ddl_err = open( ''.join( (os.path.splitext(f_sql_chk.name)[0], '.err' ) ), 'w', buffering = 0)
#
# subprocess.call( [ context['isql_path'], '-q', '-i', f_sql_chk.name ], stdout = f_ddl_log, stderr = f_ddl_err)
#
# flush_and_close( f_ddl_log )
# flush_and_close( f_ddl_err )
#
# ########################################################################
#
# f_backup_log = open( os.path.join(context['temp_directory'],'tmp_6248.backup_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# f_backup_err = open( ''.join( (os.path.splitext(f_backup_log.name)[0], '.err' ) ), 'w', buffering = 0)
#
# subprocess.call( [ context['gbak_path'], '-b', '-se', 'localhost:servce_mgr', dbname, bkname, '-v', '-st', 'tdrw' ], stdout = f_backup_log, stderr = f_backup_err)
#
# flush_and_close( f_backup_log )
# flush_and_close( f_backup_err )
#
# ########################################################################
#
# os.remove(dbname)
#
# f_restore_log = open( os.path.join(context['temp_directory'],'tmp_6248.restore_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# f_restore_err = open( ''.join( (os.path.splitext(f_restore_log.name)[0], '.err' ) ), 'w', buffering = 0)
#
# subprocess.call( [ context['gbak_path'], '-rep', '-se', 'localhost:servce_mgr', bkname, dbname, '-v', '-st', 'tdrw' ], stdout = f_restore_log, stderr = f_restore_err)
#
# flush_and_close( f_restore_log )
# flush_and_close( f_restore_err )
#
# ########################################################################
#
# f_gstat_log = open( os.path.join(context['temp_directory'],'tmp_6248.gstat_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# f_gstat_err = open( ''.join( (os.path.splitext(f_gstat_log.name)[0], '.err' ) ), 'w', buffering = 0)
#
# subprocess.call( [ context['gstat_path'], '-h', 'localhost:' + dbname ], stdout = f_gstat_log, stderr = f_gstat_err)
#
# flush_and_close( f_gstat_log )
# flush_and_close( f_gstat_err )
#
# ########################################################################
#
# f_fblog_sweep_before = open( os.path.join(context['temp_directory'],'tmp_6248.fblog_before_sweep_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# svc_get_fb_log( f_fblog_sweep_before )
# flush_and_close( f_fblog_sweep_before )
#
# f_sweep_log = open( os.path.join(context['temp_directory'],'tmp_6248.sweep_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# f_sweep_err = open( ''.join( (os.path.splitext(f_sweep_log.name)[0], '.err' ) ), 'w', buffering = 0)
#
# subprocess.call( [ context['fbsvcmgr_path'], 'localhost:service_mgr', 'action_repair', 'dbname', dbname, 'rpr_sweep_db' ], stdout = f_sweep_log, stderr = f_sweep_err)
#
# flush_and_close( f_sweep_log )
# flush_and_close( f_sweep_err )
#
# # Here we let firebird.log to be fulfilled with text about just finished SWEEP:
# time.sleep(1)
#
# f_fblog_sweep_after = open( os.path.join(context['temp_directory'],'tmp_6248.fblog_after_sweep_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# svc_get_fb_log( f_fblog_sweep_after )
# flush_and_close( f_fblog_sweep_after )
#
# oldfb=open(f_fblog_sweep_before.name, 'r')
# newfb=open(f_fblog_sweep_after.name, 'r')
#
# difftext = ''.join(difflib.unified_diff(
# oldfb.readlines(),
# newfb.readlines()
# ))
# oldfb.close()
# newfb.close()
#
# f_diff_sweep = open( os.path.join(context['temp_directory'],'tmp_6248.fblog_diff_sweep_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# f_diff_sweep.write(difftext)
# flush_and_close( f_diff_sweep )
#
# ########################################################################
#
# f_fblog_validate_before = open( os.path.join(context['temp_directory'],'tmp_6248.fblog_before_validate_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# svc_get_fb_log( f_fblog_validate_before )
# flush_and_close( f_fblog_validate_before )
#
# f_valid_log = open( os.path.join(context['temp_directory'],'tmp_6248.valid_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# f_valid_err = open( ''.join( (os.path.splitext(f_valid_log.name)[0], '.err' ) ), 'w', buffering = 0)
#
# subprocess.call( [ context['fbsvcmgr_path'], 'localhost:service_mgr', 'action_repair', 'dbname', dbname, 'rpr_validate_db', 'rpr_full' ], stdout = f_valid_log, stderr = f_valid_err)
#
# flush_and_close( f_valid_log )
# flush_and_close( f_valid_err )
#
# # Here we let firebird.log to be fulfilled with text about just finished VALIDATION:
# time.sleep(1)
#
# f_fblog_validate_after = open( os.path.join(context['temp_directory'],'tmp_6248.fblog_after_validate_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# svc_get_fb_log( f_fblog_validate_after )
# flush_and_close( f_fblog_validate_after )
#
#
# f_fblog_validate_after = open( os.path.join(context['temp_directory'],'tmp_6248.fblog_after_validate_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# svc_get_fb_log( f_fblog_validate_after )
# flush_and_close( f_fblog_validate_after )
#
# oldfb=open(f_fblog_validate_before.name, 'r')
# newfb=open(f_fblog_validate_after.name, 'r')
#
# difftext = ''.join(difflib.unified_diff(
# oldfb.readlines(),
# newfb.readlines()
# ))
# oldfb.close()
# newfb.close()
#
# f_diff_validate = open( os.path.join(context['temp_directory'],'tmp_6248.fblog_diff_validate_'+str(required_name_len)+'.log'), 'w', buffering = 0)
# f_diff_validate.write(difftext)
# flush_and_close( f_diff_validate )
#
#
# ########################################################################
#
# chk_list = (f_ddl_err, f_backup_err, f_restore_err, f_gstat_err, f_sweep_err, f_valid_err)
# for c in chk_list:
# with open(c.name,'r') as f:
# for line in f:
# if line.split():
# print('UNEXPECTED ERROR, file:' + c.name +': ', line )
#
# dbname_present_map = {}
#
# # diff VALIDATION:
# # +[tab]Database: C:\\FBTESTING\\QA\\FBT-REPO\\TMP\\ABC.FDB
# # diff SWEEP:
# # +[tab]Database "C:\\FBTESTING\\QA\\FBT-REPO\\TMP\\ABC.FDB
# dbptrn = re.compile('\\+\\s+Database[:]{0,1}\\s+"{0,1}', re.IGNORECASE)
#
# # STDOUT results: we have to check that AT LEAST 255 characters of database name present in log.
# chk_list = (f_ddl_log, f_backup_log, f_restore_log, f_gstat_log, f_diff_sweep, f_diff_validate)
# for c in chk_list:
#
# # Name of STDOUT-log will serve as KEY for dbname_present_map{}, e.g.:
# # C:\\FBTESTING\\qa
# bt-repo mp mp_6248.backup_255.log --> tmp_6248.backup_255
# stdout_file = os.path.split( os.path.splitext( c.name )[0] )[1]
#
# dbname_present_map[ stdout_file ] = 'DB NAME NOT FOUND'
# with open(c.name,'r') as f:
# for line in f:
# if c not in (f_diff_sweep, f_diff_validate) or line.startswith('+') and dbptrn.search(line):
# if dbname[:MINIMAL_LEN_TO_SHOW].upper() in line.upper():
# dbname_present_map[ stdout_file ] = 'found at least ' + str(MINIMAL_LEN_TO_SHOW)+' characters'
# break
# elif dbname[:128].upper() in line.upper():
# dbname_present_map[ stdout_file ] = 'found truncated DB name.'
# break
#
# for k,v in sorted( dbname_present_map.items() ):
# print(k, ':', v)
#
# # Other STDOUT results will be analyzed after get developers resolution about
# # truncation of DB names to ~235...241 characters.
# # See notes of: 06/Mar/20 06:38 AM; 06/Mar/20 06:45 AM; 09/Mar/20 07:53 AM.
# # Currently we do nothing and just remove them:
#
# time.sleep(1)
# cleanup( (f_sql_chk.name, bkname, dbname, f_ddl_err, f_backup_err, f_restore_err, f_gstat_err, f_sweep_err, f_valid_err, f_ddl_log, f_backup_log, f_restore_log, f_gstat_log, f_sweep_log, f_valid_log, f_fblog_sweep_before, f_fblog_sweep_after, f_diff_sweep, f_fblog_validate_before, f_fblog_validate_after, f_diff_validate) )
#
#
# #--------------------------------------------
#
# check_long_dbname(255, 'abc255def')
# check_long_dbname(259, 'qwe259rty')
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
tmp_6248.backup_255 : found truncated DB name.
tmp_6248.ddl_255 : found at least 255 characters
tmp_6248.fblog_diff_sweep_255 : found at least 255 characters
tmp_6248.fblog_diff_validate_255 : found at least 255 characters
tmp_6248.gstat_255 : found truncated DB name.
tmp_6248.restore_255 : found truncated DB name.
tmp_6248.backup_259 : found truncated DB name.
tmp_6248.ddl_259 : found at least 255 characters
tmp_6248.fblog_diff_sweep_259 : found at least 255 characters
tmp_6248.fblog_diff_validate_259 : found at least 255 characters
tmp_6248.gstat_259 : found truncated DB name.
tmp_6248.restore_259 : found truncated DB name.
"""
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")