#coding:utf-8 # # id: bugs.core_6509 # title: Segfault when gfix requests for database page buffer more memory than available from OS # decription: # Confirmed crash on 4.0.0.2377 (Windows and Linux) # Checked on 4.0.0.2384 - all OK, get STDERR: "unable to allocate memory from operating system" # NB: currently acceptable value for '-buffers' is limited from 50 to 2147483646. # # tracker_id: CORE-6509 # min_versions: ['4.0.0'] # versions: 4.0 # qmid: None import pytest import re from firebird.qa import db_factory, python_act, Action # version: 4.0 # resources: None substitutions_1 = [] init_script_1 = """""" db_1 = db_factory(page_size=32768, sql_dialect=3, init=init_script_1) # test_script_1 #--- # import os # import sys # import re # import time # # so=sys.stdout # se=sys.stderr # # os.environ["ISC_USER"] = user_name # os.environ["ISC_PASSWORD"] = user_password # db_name = 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 ) # # #-------------------------------------------- # # # f_log = open( os.path.join(context['temp_directory'],'tmp_c6509.log'), 'w') # f_err = open( os.path.join(context['temp_directory'],'tmp_c6509.err'), 'w') # sys.stdout = f_log # sys.stderr = f_err # # runProgram('gstat',[ '-h', db_name ]) # runProgram('gfix',[dsn,'-buffers','2147483646']) # runProgram('gstat',[ '-h', db_name ]) # # sys.stdout = so # sys.stderr = se # # flush_and_close( f_log ) # flush_and_close( f_err ) # # pattern_for_page_buffers = re.compile('\\s*Page\\s+buffers\\s+\\d+', re.IGNORECASE) # # buffers_set=set() # with open(f_log.name,'r') as f: # for line in f: # if pattern_for_page_buffers.search(line): # buffers_set.add( line.split()[2] ) # # print('gstat output:', line) # # print( 'Buffers value was ' + ('not changed (expected)' if len(buffers_set) == 1 else 'UNEXPECTEDLY changed: ' + (', '.join(buffers_set)) ) ) # # with open(f_err.name,'r') as f: # for line in f: # print('STDERR in gfix:', line) # # # cleanup: # ########## # time.sleep(1) # cleanup( (f_log,f_err) ) # # #--- act_1 = python_act('db_1', substitutions=substitutions_1) expected_stdout_1 = """ Buffers value was not changed (expected) STDERR in gfix: unable to allocate memory from operating system """ pattern_for_page_buffers = re.compile('\\s*Page\\s+buffers\\s+\\d+', re.IGNORECASE) @pytest.mark.version('>=4.0') def test_1(act_1: Action, capsys): act_1.gstat(switches=['-h']) print(act_1.stdout) act_1.reset() act_1.expected_stderr = "We expect errors" act_1.gfix(switches=[act_1.db.dsn, '-buffers', '2147483646']) gfix_err = act_1.stderr act_1.reset() act_1.gstat(switches=['-h']) print(act_1.stdout) # buffers_set = set() for line in capsys.readouterr().out.splitlines(): if pattern_for_page_buffers.search(line): buffers_set.add(line.split()[2]) result = 'not changed (expected)' if len(buffers_set) == 1 else 'UNEXPECTEDLY changed: ' + ', '.join(buffers_set) print(f'Buffers value was {result}') for line in gfix_err.splitlines(): print('STDERR in gfix:', line) # Check act_1.reset() act_1.expected_stdout = expected_stdout_1 act_1.stdout = capsys.readouterr().out assert act_1.clean_stdout == act_1.clean_expected_stdout