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_4298_test.py

252 lines
9.9 KiB
Python
Raw Normal View History

2021-04-26 20:07:00 +02:00
#coding:utf-8
#
# id: bugs.core_4298
# title: fbsvcmgr doesn't recognise sts_record_versions and other sts switches
# decription:
# Test creates table and add 5 rows to it. Than we run in child async. process ISQL with EB which has ES/EDS
# and will stay in pause due to update conflict in lock-timeout transaction (Python currently can not operate
# with several attachments which open cursors with DML - this will crash).
# When EB will be paused, we start another ISQL which will add one row to the same table and finish.
# At this point table will have 5 versions and this should be shown in the output of fbsvcmgr when it is run
# with 'action_db_stats sts_record_versions' keys.
# Finally, we terminate hanged ISQL process and proceed with logs (STDOUR and STDERR) of fbsvcmgr.
# Log of errors should be empty, log of STDOUT should contain text with non-zero number of versions.
# Checked on:
# WI-V2.5.5.26942 (SS), WI-V2.5.5.26952 (sC);
# WI-V3.0.0.32239 (SS), WI-V3.0.0.32208 (Cs, sC).
# ### NOTE ###
# Classic keeps database file opened when hanged ISQL is killed by teminate(), thus leading to access error
# when fbtest tries to remove database by dropping it (get "Windows error (32)"). For that reason we have
# to allow ISQL that stays in pause to finish by Tx timeout expiration and close itself his own process.
#
# Checked on (28.10.2019):
# 4.0.0.1635 SS: 7.720s.
# 4.0.0.1633 CS: 7.378s.
# 3.0.5.33180 SS: 7.313s.
# 3.0.5.33178 CS: 6.720s.
# 2.5.9.27119 SS: 6.506s.
# 2.5.9.27146 SC: 5.388s.
#
# 13.04.2021. Adapted for run both on Windows and Linux. Checked on:
# Windows: 3.0.8.33445, 4.0.0.2416
# Linux: 3.0.8.33426, 4.0.0.2416
#
#
# tracker_id: CORE-4298
# min_versions: ['2.5.2']
# versions: 2.5.2
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
# version: 2.5.2
# resources: None
substitutions_1 = [('Average version length: [\\d]+.[\\d]+, total versions: 5, max versions: 1', 'total versions: 5, max versions: 1')]
init_script_1 = """
recreate table test(id int, x int);
commit;
insert into test values(1, 100);
insert into test values(2, 200);
insert into test values(3, 300);
insert into test values(4, 400);
insert into test values(5, 500);
commit;
"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
# test_script_1
#---
# import os
# import time
# import subprocess
# from subprocess import Popen
# from fdb import services
#
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
#
# # Obtain engine version:
# engine = str(db_conn.engine_version) # convert to text because 'float' object has no attribute 'startswith'
#
# #--------------------------------------------
#
# 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 i in range(len( f_names_list )):
# if type(f_names_list[i]) == file:
# del_name = f_names_list[i].name
# elif type(f_names_list[i]) == str:
# del_name = f_names_list[i]
# else:
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
# print('type(f_names_list[i])=',type(f_names_list[i]))
# del_name = None
#
# if del_name and os.path.isfile( del_name ):
# os.remove( del_name )
#
# #--------------------------------------------
#
# sqltxt='''
# set term ^;
# execute block as
# begin
# execute statement 'drop role TMP$R4298';
# when any do begin end
# end ^
# set term ;^
# commit;
#
#
# commit;
# set transaction lock timeout 15;
# update test set x = -x;
# set term ^;
# execute block as
# begin
# execute statement 'update test set x = -x'
# on external 'localhost:' || rdb$get_context('SYSTEM','DB_NAME')
# as user '%s' password '%s' role 'TMP$R4298';
# when any do
# begin
# end
# end
# ^
# set term ;^
# rollback;
#
# ''' % (user_name, user_password)
#
#
# f_hanged_sql=open( os.path.join(context['temp_directory'],'tmp_4298_hang.sql'), 'w')
# f_hanged_sql.write(sqltxt)
# flush_and_close( f_hanged_sql )
#
# f_hanged_log=open( os.path.join(context['temp_directory'],'tmp_4298_hang.log'), 'w')
#
# # Execute a child program in a new process, redirecting STDERR to the same target as of STDOUT:
# p_hang = Popen([context['isql_path'], dsn, "-i" , f_hanged_sql.name], stdout=f_hanged_log, stderr=subprocess.STDOUT)
#
# time.sleep(1)
#
# runProgram('isql',[dsn],'insert into test(id, x) values(-1, -100); commit;')
#
# this_fdb='$(DATABASE_LOCATION)bugs.core_4298.fdb'
#
# f_stat_log=open( os.path.join(context['temp_directory'],'tmp_4298_dbstat.log'), 'w')
# f_stat_err=open( os.path.join(context['temp_directory'],'tmp_4298_dbstat.err'), 'w')
#
# subprocess.call( [ context['fbsvcmgr_path'],"localhost:service_mgr",
# "action_db_stats", "dbname", this_fdb,
# "sts_record_versions"
# ],
# stdout=f_stat_log,
# stderr=f_stat_err
# )
#
# flush_and_close( f_stat_log )
# flush_and_close( f_stat_err )
#
# # do NOT remove this pause: Classic 3.0 keeps database opened even after we kill hanged ISQL by p_hang.terminate().
# # So we have to wait enough for 1st ISQL process that currently will hangs about 4 seconds to be CORRECTLY closed
# # by itself:
#
# time.sleep(3)
#
# # These kill and close commands are also needed here, despite that corresponding ISQL has been already closed itself.
# # It is so at least for Cs 3.0:
# p_hang.terminate()
# flush_and_close( f_hanged_log )
#
# # ERRORS log of obtaining DB statistics should be EMPTY:
# with open( f_stat_err.name,'r') as f:
# for line in f:
# if line.split():
# print("UNEXPECTED STDERR for 'action_db_stats': " + line)
#
# # STDOUT of obtaining DB statistics should NOT be EMPTY:
# with open(f_stat_log.name,'r') as f:
# for line in f:
# if 'versions:' in line.lower():
# print(line)
#
# #####################################################################
# # 28.10.2019: add full shutdown to forcedly drop all attachments.
# ## ||||||||||||||||||||||||||||
# ## ###################################||| FB 4.0+, SS and SC |||##############################
# ## ||||||||||||||||||||||||||||
# ## If we check SS or SC and ExtConnPoolLifeTime > 0 (config parameter FB 4.0+) then current
# ## DB (bugs.core_NNNN.fdb) will be 'captured' by firebird.exe process and fbt_run utility
# ## will not able to drop this database at the final point of test.
# ## Moreover, DB file will be hold until all activity in firebird.exe completed and AFTER this
# ## we have to wait for <ExtConnPoolLifeTime> seconds after it (discussion and small test see
# ## in the letter to hvlad and dimitr 13.10.2019 11:10).
# ## This means that one need to kill all connections to prevent from exception on cleanup phase:
# ## SQLCODE: -901 / lock time-out on wait transaction / object <this_test_DB> is in use
# ## #############################################################################################
#
# f_shutdown_log=open( os.path.join(context['temp_directory'],'tmp_4298_shutdown.log'), 'w')
#
# subprocess.call( [context['fbsvcmgr_path'], "localhost:service_mgr",
# "action_properties", "prp_shutdown_mode", "prp_sm_full", "prp_shutdown_db", "0", "dbname", this_fdb,
# ],
# stdout = f_shutdown_log,
# stderr = subprocess.STDOUT
# )
# subprocess.call( [context['fbsvcmgr_path'], "localhost:service_mgr",
# "action_properties", "prp_db_online", "dbname", this_fdb,
# ],
# stdout = f_shutdown_log,
# stderr = subprocess.STDOUT
# )
#
# flush_and_close( f_shutdown_log )
#
# with open( f_shutdown_log.name,'r') as f:
# for line in f:
# if line.split():
# print( 'UNEXPECTED OUTPUT IN DB SHUTDOWN LOG: ' + (' '.join(line.split()).upper()) )
#
#
# # Cleanup:
# ##########
# # do NOT remove this pause otherwise some of logs will not be enable for deletion and test will finish with
# # Exception raised while executing Python test script. exception: WindowsError: 32
# time.sleep(1)
#
# cleanup( (f_hanged_sql, f_hanged_log, f_stat_log, f_stat_err, f_shutdown_log) )
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
Average version length: 9.00, total versions: 5, max versions: 1
"""
@pytest.mark.version('>=2.5.2')
@pytest.mark.xfail
2021-04-28 12:42:11 +02:00
def test_1(db_1):
2021-04-26 20:07:00 +02:00
pytest.fail("Test not IMPLEMENTED")