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

Implementation of Python-based tests

This commit is contained in:
Pavel Císař 2021-11-10 19:02:05 +01:00
parent 8166fbdb36
commit 7eb6992fd5
18 changed files with 950 additions and 502 deletions

View File

@ -2,15 +2,16 @@
#
# id: bugs.core_0210
# title: CS server crash altering SP in 2 connect
# decription:
#
# decription:
#
# tracker_id: CORE-0210
# min_versions: ['2.5.0']
# versions: 2.5
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
from firebird.driver import TPB, Isolation
# version: 2.5
# resources: None
@ -23,15 +24,15 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# test_script_1
#---
#
#
# import os
# import fdb
#
#
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
#
#
# db_conn.close()
#
#
# stm1='''create or alter procedure sp_test as
# begin
# exit;
@ -43,38 +44,63 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# exit;
# end
# '''
#
#
# con1 = fdb.connect(dsn=dsn)
# con2 = fdb.connect(dsn=dsn)
#
#
# xtpb = ( [ fdb.isc_tpb_concurrency ] )
#
#
# con1.begin( tpb = xtpb )
#
#
# cur1=con1.cursor()
# cur2=con2.cursor()
#
#
# cur1.execute(stm1)
# con1.commit()
#
#
# con2.begin( tpb = xtpb )
# cur2.execute(stm2)
# con2.commit()
#
#
# con1.begin( tpb = xtpb )
# cur1.execute(stm1)
# con1.commit()
#
#
# con1.close()
# con2.close()
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=2.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
stm1 = '''create or alter procedure sp_test as
begin
exit;
end
'''
stm2 = '''create or alter procedure sp_test as
declare x int;
begin
exit;
end
'''
tpb = TPB(isolation=Isolation.CONCURRENCY).get_buffer()
with act_1.db.connect() as con1, act_1.db.connect() as con2:
con1.begin(tpb)
cur1 = con1.cursor()
cur2 = con2.cursor()
cur1.execute(stm1)
con1.commit()
con2.begin(tpb)
cur2.execute(stm2)
con2.commit()
con1.begin(tpb)
cur1.execute(stm1)
con1.commit()

View File

@ -11,7 +11,7 @@
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 2.5
# resources: None
@ -38,7 +38,7 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# c.execute(cmd % i)
# i += 1
# db_conn.commit()
#
#
# # Grants
# i = 1
# cmd = """GRANT INSERT ON LOG TO TRIGGER LOGT_%d"""
@ -51,12 +51,30 @@ db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# i += 1
# db_conn.commit()
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=2.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.db.connect() as con:
c = con.cursor()
# Create 4000 triggers on table T
i = 1
cmd = """create trigger LOGT_%d for T after insert as
begin
insert into log (PK) values (new.pk);
end
"""
while i <= 4000:
c.execute(cmd % i)
i += 1
con.commit()
# Grants
i = 1
cmd = """GRANT INSERT ON LOG TO TRIGGER LOGT_%d"""
while i <= 4000:
c.execute(cmd % i)
i += 1
con.commit()

View File

@ -2,22 +2,22 @@
#
# id: bugs.core_0337
# title: bug #910430 ISQL and database dialect
# decription:
# ::: NB :::
# decription:
# ::: NB :::
# ### Name of original test has no any relation with actual task of this test: ###
# https://github.com/FirebirdSQL/fbtcs/blob/master/GTCS/tests/CF_ISQL_25.script
#
#
# When ISQL disconnects from database (either by dropping it or by trying to connect to
# non-existent database) is still remembers its sql dialect, which can lead to some
# inappropriate warning messages.
#
#
# Issue in original script: bug #910430 ISQL and database dialect
# Found in FB tracker as: http://tracker.firebirdsql.org/browse/CORE-337
# Fixed in 2.0 Beta 1
#
#
# Checked on: 4.0.0.1803 SS; 3.0.6.33265 SS; 2.5.9.27149 SC.
#
# tracker_id:
#
# tracker_id:
# min_versions: ['2.5.0']
# versions: 2.5
# qmid: None
@ -36,112 +36,137 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# test_script_1
#---
#
#
# import os
# import sys
# import subprocess
#
#
# #--------------------------------------------
#
#
# 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
# # 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'):
# # 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 os.path.isfile( f_names_list[i]):
# os.remove( f_names_list[i] )
#
#
# #--------------------------------------------
#
#
# test_fdb=os.path.join(context['temp_directory'],'tmp_0337.fdb')
#
#
# cleanup( test_fdb, )
#
#
# db_conn.close()
# sql='''
# set echo on;
#
#
# show sql dialect;
#
#
# set sql dialect 1;
#
#
# show sql dialect;
#
#
# set sql dialect 3;
#
#
# create database 'localhost:%(test_fdb)s' user '%(user_name)s' password '%(user_password)s';
#
#
# show sql dialect;
#
#
# drop database;
#
#
# show database;
#
#
# show sql dialect;
#
#
# set sql dialect 1;
# ''' % dict(globals(), **locals())
#
#
# f_sql_chk = open( os.path.join(context['temp_directory'],'tmp_0337_ddl.sql'), 'w', buffering = 0)
# f_sql_chk.write(sql)
# flush_and_close( f_sql_chk )
#
#
# f_sql_log = open( ''.join( (os.path.splitext(f_sql_chk.name)[0], '.log' ) ), 'w', buffering = 0)
# subprocess.call( [ context['isql_path'], '-q', '-i', f_sql_chk.name ], stdout = f_sql_log, stderr = subprocess.STDOUT)
# flush_and_close( f_sql_log )
#
#
# with open(f_sql_log.name,'r') as f:
# for line in f:
# if line.split():
# print( line.upper() )
#
#
# cleanup( (test_fdb, f_sql_log.name, f_sql_chk.name) )
#
#
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
SHOW SQL DIALECT;
CLIENT SQL DIALECT HAS NOT BEEN SET AND NO DATABASE HAS BEEN CONNECTED YET.
Client SQL dialect has not been set and no database has been connected yet.
SET SQL DIALECT 1;
SHOW SQL DIALECT;
CLIENT SQL DIALECT IS SET TO: 1. NO DATABASE HAS BEEN CONNECTED.
Client SQL dialect is set to: 1. No database has been connected.
SET SQL DIALECT 3;
CREATE DATABASE 'LOCALHOST:C:\\FBTESTING\\QA\\FBT-REPO\\TMP2\\TMP_0337.FDB' USER 'SYSDBA' PASSWORD 'MASTERKEY';
SHOW SQL DIALECT;
CLIENT SQL DIALECT IS SET TO: 3 AND DATABASE SQL DIALECT IS: 3
Client SQL dialect is set to: 3 and database SQL dialect is: 3
DROP DATABASE;
SHOW DATABASE;
COMMAND ERROR: SHOW DATABASE
SHOW SQL DIALECT;
CLIENT SQL DIALECT IS SET TO: 3. NO DATABASE HAS BEEN CONNECTED.
Client SQL dialect is set to: 3. No database has been connected.
SET SQL DIALECT 1;
"""
expected_stderr_1 = """
Use CONNECT or CREATE DATABASE to specify a database
Use CONNECT or CREATE DATABASE to specify a database
Command error: SHOW DATABASE
"""
act_1 = isql_act('db_1', "", substitutions=substitutions_1)
@pytest.mark.version('>=2.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.db.drop()
act_1.script = f"""
SET ECHO ON;
SHOW SQL DIALECT;
SET SQL DIALECT 1;
SHOW SQL DIALECT;
SET SQL DIALECT 3;
CREATE DATABASE '{act_1.db.dsn}' USER '{act_1.db.user}' PASSWORD '{act_1.db.password}';
SHOW SQL DIALECT;
DROP DATABASE;
SHOW DATABASE;
SHOW SQL DIALECT;
SET SQL DIALECT 1;
"""
act_1.expected_stdout = expected_stdout_1
act_1.expected_stderr = expected_stderr_1
act_1.execute(do_not_connect=True)
assert act_1.clean_expected_stdout == act_1.clean_stdout
assert act_1.clean_expected_stderr == act_1.clean_stderr
act_1.db.create()

View File

@ -2,7 +2,7 @@
#
# id: bugs.core_0405
# title: Garbage vs indices/constraints
# decription:
# decription:
# Confirmed bug on 3.0.4.32924, got:
# DatabaseError:
# Error while commiting transaction:
@ -14,14 +14,14 @@
# :: NB ::
# No error on Firebird 4.0 (any: SS,SC, CS).
# Works OK on: 4.0.0.838
#
#
# tracker_id: CORE-0405
# min_versions: ['3.0.4']
# versions: 3.0.4
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0.4
# resources: None
@ -34,63 +34,84 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# test_script_1
#---
#
#
# import os
# import sys
# import fdb
#
#
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
#
#
# db_conn.close()
#
#
# con=fdb.connect( dsn=dsn, no_gc=1 )
# #print( con.firebird_version )
#
#
# con.execute_immediate('recreate table test(x int)')
# con.commit()
# cur=con.cursor()
#
#
# stm='insert into test( x ) values( ? )'
# val = [ (2,), (3,), (3,), (2,) ]
# cur.executemany( stm, val )
#
#
# cur.execute('select x from test order by x')
# for r in cur:
# print(r[0])
#
#
# cur.execute('delete from test')
#
#
# cur.execute('select count(*) from test')
# for r in cur:
# print(r[0])
#
#
# con.execute_immediate('create unique index test_x on test(x)')
# con.commit()
#
#
#
#
# cur.execute("select rdb$index_name from rdb$indices where rdb$relation_name='TEST'")
# for r in cur:
# print( r[0].rstrip() )
#
#
# con.close()
#
#
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
2
2
3
3
0
TEST_X
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """2
2
3
3
0
TEST_X
"""
@pytest.mark.version('>=3.0.4')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, capsys):
with act_1.db.connect() as con:
con.execute_immediate('recreate table test(x int)')
con.commit()
cur = con.cursor()
cur.executemany('insert into test( x ) values( ? )', [(2,), (3,), (3,), (2,)])
for r in cur.execute('select x from test order by x'):
print(r[0])
cur.execute('delete from test')
for r in cur.execute('select count(*) from test'):
print(r[0])
con.execute_immediate('create unique index test_x on test(x)')
con.commit()
for r in cur.execute("select rdb$index_name from rdb$indices where rdb$relation_name='TEST'"):
print(r[0].rstrip())
#
output = capsys.readouterr()
assert output.out == expected_stdout_1

View File

@ -2,7 +2,7 @@
#
# id: bugs.core_0733
# title: Compress Data over the Network
# decription:
# decription:
# CHANGED 22.12.2019: CODE REDUCTION: REMOVED MEASURES OT TIME.
# Results are completely opposite to those which were obtained on snapshots when this test was implenmented (3.0.5.33084, 4.0.0.1347).
# Requirement to compress data leads to DEGRADATION of performance when data are stored on local machine, and we have no ability
@ -10,16 +10,16 @@
# After discuss with dimitr it was decided to remove any logging and its analysis.
# We only verify matching of RDB$GET_CONTEXT('SYSTEM', 'WIRE_COMPRESSED') and value that was stored in the firebird.conf
# for current check.
#
#
# ### NOTE ###
# Changed value of parameter WireCompression (in firebird.conf) will be seen by application if it reloads client library.
# Changed value of parameter WireCompression (in firebird.conf) will be seen by application if it reloads client library.
# Reconnect is NOT enough for this. For this reason we use subprocess and call ISQL utility to do above mentioned actions
# in new execution context.
#
#
# See also tests for:
# CORE-5536 - checks that field mon$wire_compressed actually exists in MON$ATTACHMENTS table;
# CORE-5913 - checks that built-in rdb$get_context('SYSTEM','WIRE_ENCRYPTED') is avaliable;
#
#
# Checked on:
# 4.0.0.1693 SS: 3.031s.
# 4.0.0.1346 SC: 2.890s.
@ -27,8 +27,12 @@
# 3.0.5.33215 SS: 1.452s.
# 3.0.5.33084 SC: 1.344s.
# 3.0.5.33212 CS: 3.175s.
#
#
#
# [pcisar] 9.11.2021
# This test was fragile from start, usualy lefts behind resources and requires
# temporary changes to firebird.conf on run-time. It's questionable whether
# wire-compression should be tested at all.
#
# tracker_id: CORE-0733
# min_versions: ['3.0.0']
# versions: 3.0
@ -46,8 +50,8 @@ init_script_1 = """
create domain dm_dump varchar(32700) character set none;
recreate table t_log( required_value varchar(5), actual_value varchar(5), elap_ms int );
commit;
set term ^;
create or alter procedure sp_uuid(a_compressable boolean, n_limit int default 1)
set term ^;
create or alter procedure sp_uuid(a_compressable boolean, n_limit int default 1)
returns (b dm_dump) as
declare g char(16) character set octets;
begin
@ -76,7 +80,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# test_script_1
#---
#
#
# import os
# import time as tm
# import datetime
@ -85,86 +89,86 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# import shutil
# import subprocess
# import platform
#
#
# from fdb import services
#
#
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
#
#
# DB_NAME = '$(DATABASE_LOCATION)' + 'bugs.core_0733.fdb'
#
#
# DB_PATH = '$(DATABASE_LOCATION)'
# U_NAME = user_name
# U_PSWD = user_password
# NUL_DEVICE = 'nul' if platform.system() == 'Windows' else '/dev/null'
#
#
# N_ROWS = 1
#
#
# F_SQL_NAME=os.path.join(context['temp_directory'],'tmp_core_0733.sql')
#
#
# fb_home = services.connect(host='localhost', user= user_name, password= user_password).get_home_directory()
# dts = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
# fbconf_bak = fb_home+'firebird_'+dts+'.tmp_0733.bak'
# shutil.copy2( fb_home+'firebird.conf', fbconf_bak )
#
#
# 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
# # 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'):
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
# os.fsync(file_handle.fileno())
# file_handle.close()
#
#
# #--------------------------------------------
#
#
# def prepare_fb_conf( fb_home, a_required_value ):
#
#
# f_fbconf=open(fb_home+'firebird.conf','r')
# fbconf_content=f_fbconf.readlines()
# f_fbconf.close()
# for i,s in enumerate( fbconf_content ):
# if s.lower().lstrip().startswith( 'wirecompression'.lower() ):
# fbconf_content[i] = '# <temply commented> ' + s
#
#
# fbconf_content.append('\\n# Temporarily added by fbtest, CORE-0733. Should be removed auto:')
# fbconf_content.append("\\n#" + '='*30 )
# fbconf_content.append('\\nWireCompression = %s' % a_required_value )
# fbconf_content.append("\\n#" + '='*30 )
# fbconf_content.append("\\n" )
#
#
# f_fbconf=open(fb_home+'firebird.conf','w')
# f_fbconf.writelines( fbconf_content )
# f_fbconf.close()
# #------------------------------------------------------------------------------------
#
#
# def prepare_sql_4run( required_compression, db_path, n_rows, sql_file_name ):
# global os
# global U_NAME
# global U_PSWD
# global NUL_DEVICE
#
#
# sql_dump='tmp_core_0733_compression_%(required_compression)s.dump' % ( locals() )
#
#
# if os.path.isfile( '%(db_path)s%(sql_dump)s' % (locals()) ):
# os.remove( '%(db_path)s%(sql_dump)s' % (locals()) )
#
#
# if n_rows is None:
# return
#
#
# #------------------
#
#
# sql_text='''
# set list on;
#
#
# set term ^;
# execute block returns(dts timestamp) as
# begin
@ -174,10 +178,10 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# end
# ^
# set term ;^
#
#
# --out %(db_path)s%(sql_dump)s;
# out nul;
#
#
# set term ^;
# execute block returns(b dm_dump) as
# begin
@ -194,7 +198,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# ^
# set term ;^
# out;
#
#
# set term ^;
# execute block returns(dts timestamp) as
# begin
@ -204,97 +208,97 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# end
# ^
# set term ;^
#
#
# insert into t_log( required_value, actual_value, elap_ms)
# values(
# upper( '%(required_compression)s' )
# ,upper( rdb$get_context('SYSTEM','WIRE_COMPRESSED') )
# ,datediff( millisecond
# from cast(rdb$get_context('USER_SESSION','DTS_BEG') as timestamp)
# to cast(rdb$get_context('USER_SESSION','DTS_END') as timestamp)
# )
# ,datediff( millisecond
# from cast(rdb$get_context('USER_SESSION','DTS_BEG') as timestamp)
# to cast(rdb$get_context('USER_SESSION','DTS_END') as timestamp)
# )
# )
# returning required_value, actual_value, elap_ms
# ;
# commit;
# ''' % dict(globals(), **locals())
# # ( locals() )
#
#
# f_sql=open( sql_file_name, 'w')
# f_sql.write( sql_text )
# f_sql.close()
#
#
# #-------------------------
#
#
# # Call for removing dump from disk:
# prepare_sql_4run( 'false', DB_PATH, None, None )
# prepare_sql_4run( 'true', DB_PATH, None, None )
#
#
#
#
# REQUIRED_WIRE_COMPRESSION = 'false'
# # ------------------------------------------------------ ###########
# # Generate SQL script for running when WireCompression = |||FALSE|||
# # ------------------------------------------------------ ###########
# prepare_sql_4run( REQUIRED_WIRE_COMPRESSION, DB_PATH, N_ROWS, F_SQL_NAME )
#
#
# # ------------------------------------------------------ ###########
# # Update content of firebird.conf with WireCompression = |||FALSE|||
# # ------------------------------------------------------ ###########
# prepare_fb_conf( fb_home, REQUIRED_WIRE_COMPRESSION)
#
#
#
#
# # --------------------------------------------------------------------------------------
# # Launch ISQL in separate context of execution with job to obtain data and log duration
# # --------------------------------------------------------------------------------------
#
#
# fn_log = open(os.devnull, 'w')
# #fn_log = open( os.path.join(context['temp_directory'],'tmp_0733_with_compression.log'), 'w')
# f_isql_obtain_data_err = open( os.path.join(context['temp_directory'],'tmp_0733_obtain_data.err'), 'w')
#
#
# subprocess.call( [ context['isql_path'], dsn, "-i", F_SQL_NAME ],
# stdout = fn_log,
# stderr = f_isql_obtain_data_err
# )
# fn_log.close()
# f_isql_obtain_data_err.close()
#
#
# # Call for removing dump from disk:
# #prepare_sql_4run( False, DB_PATH, None, None )
# #prepare_sql_4run( True, DB_PATH, None, None )
#
#
#
#
# # Update content of firebird.conf with WireCompression = true
# ##############################################################
#
#
# REQUIRED_WIRE_COMPRESSION = 'true'
# # ------------------------------------------------------ ###########
# # Generate SQL script for running when WireCompression = ||| TRUE|||
# # ------------------------------------------------------ ###########
# prepare_sql_4run( REQUIRED_WIRE_COMPRESSION, DB_PATH, N_ROWS, F_SQL_NAME )
#
#
# # ------------------------------------------------------ ###########
# # Update content of firebird.conf with WireCompression = ||| TRUE|||
# # ------------------------------------------------------ ###########
# prepare_fb_conf( fb_home, REQUIRED_WIRE_COMPRESSION)
#
# fn_log = open(os.devnull, 'w')
#
# fn_log = open(os.devnull, 'w')
# #fn_log = open( os.path.join(context['temp_directory'],'tmp_0733_without_compress.log'), 'w')
# f_isql_obtain_data_err = open( os.path.join(context['temp_directory'],'tmp_0733_obtain_data.err'), 'a')
#
#
# subprocess.call( [ context['isql_path'], dsn, "-i", F_SQL_NAME ],
# stdout = fn_log,
# stderr = f_isql_obtain_data_err
# )
# fn_log.close()
# flush_and_close( f_isql_obtain_data_err )
#
#
# # Call for removing dump from disk:
# #prepare_sql_4run( REQUIRED_WIRE_COMPRESSION, DB_PATH, None, None )
#
#
# # RESTORE original config:
# ##########################
# shutil.copy2( fbconf_bak , fb_home+'firebird.conf')
#
#
# sql='''
# -- select * from t_log;
# -- REQUIRED_VALUE ACTUAL_VALUE ELAP_MS
@ -304,15 +308,15 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# set list on;
# select
# result_of_req_compare_to_actual
# --,iif( slowest_with_compression < fastest_without_compression,
# -- 'EXPECTED: compression was FASTER.',
# --,iif( slowest_with_compression < fastest_without_compression,
# -- 'EXPECTED: compression was FASTER.',
# -- 'POOR. slowest_with_compression=' || slowest_with_compression || ', fastest_without_compression=' || fastest_without_compression
# -- ) as result_of_compression_benchmark
# from (
# select
# select
# min( iif( upper(required_value) is distinct from upper(actual_value)
# ,coalesce(required_value,'<null>') || coalesce(actual_value,'<null>')
# ,'EXPECTED: actual values were equal to required.'
# ,'EXPECTED: actual values were equal to required.'
# )
# ) as result_of_req_compare_to_actual
# ,min( iif( upper(required_value) = upper('false'), elap_ms, null ) ) fastest_without_compression
@ -322,14 +326,14 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# ;
# set list off;
# --select * from t_log;
#
#
# '''
# runProgram('isql', [ dsn ], sql)
#
#
#
#
# # Additional check: STDERR for ISQL must be EMPTY.
# ##################################################
#
#
# f_list=(f_isql_obtain_data_err,)
# for i in range(len(f_list)):
# f_name=f_list[i].name
@ -337,12 +341,12 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# with open( f_name,'r') as f:
# for line in f:
# print("Unexpected STDERR, file "+f_name+": "+line)
#
#
# os.remove(f_isql_obtain_data_err.name)
# os.remove(fbconf_bak)
# os.remove(F_SQL_NAME)
#
#
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)

View File

@ -2,7 +2,7 @@
#
# id: bugs.core_0790
# title: Alter view
# decription:
# decription:
# tracker_id: CORE-790
# min_versions: ['2.5.0']
# versions: 2.5.0
@ -46,7 +46,7 @@ show view v_users_name;
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """Database: localhost:C: btest2 mpugs.core_0790.fdb, User: SYSDBA
expected_stdout_1 = """Database: localhost:C:/fbtest2/tmp/bugs.core_0790.fdb, User: SYSDBA
SQL> CON> SQL> SQL> ID INTEGER Nullable
NAME VARCHAR(20) Nullable
PASSWD VARCHAR(20) Nullable
@ -65,7 +65,8 @@ View Source:
==== ======
select name from v_users
SQL> SQL> SQL> SQL>"""
SQL> SQL> SQL> SQL>
"""
@pytest.mark.version('>=2.5.0')
def test_1(act_1: Action):

View File

@ -2,16 +2,16 @@
#
# id: bugs.core_0800
# title: Easy metadata extract improvements
# decription:
# decription:
# Domain DDL: move its CHECK clause from 'create' to 'alter' statement.
#
#
# tracker_id: CORE-0800
# min_versions: ['3.0']
# versions: 3.0
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0
# resources: None
@ -37,10 +37,10 @@ init_script_1 = """
create collation name_coll for utf8 from unicode no pad case insensitive accent insensitive;
commit;
create domain dm_test varchar(20)
character set utf8
default 'foo'
not null
create domain dm_test varchar(20)
character set utf8
default 'foo'
not null
check (value in ('foo', 'rio', 'bar'))
collate name_coll
;
@ -53,46 +53,49 @@ db_1 = db_factory(charset='UTF8', sql_dialect=3, init=init_script_1)
#---
# import os
# import subprocess
#
#
# db_conn.close()
#
#
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
# db_file="$(DATABASE_LOCATION)bugs.core_0800.fdb"
#
#
# f_extract_meta = open( os.path.join(context['temp_directory'],'tmp_meta_0800_init.sql'), 'w')
# subprocess.call( [context['isql_path'], dsn, "-x", "-ch", "utf8"],
# stdout = f_extract_meta,
# stderr = subprocess.STDOUT
# )
# f_extract_meta.close()
#
#
# with open( f_extract_meta.name, 'r') as f:
# for line in f:
# if 'ALTER DOMAIN' in line.upper():
# print( line )
#
#
# ###############################
# # Cleanup.
#
#
# f_list=[]
# f_list.append(f_extract_meta)
#
#
# for i in range(len(f_list)):
# if os.path.isfile(f_list[i].name):
# os.remove(f_list[i].name)
#
#
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
ALTER DOMAIN DM_TEST ADD CONSTRAINT
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.extract_meta()
expected = ''.join([x for x in act_1.clean_stdout.splitlines() if 'ALTER DOMAIN' in x.upper()])
assert act_1.clean_expected_stdout == expected

View File

@ -2,7 +2,7 @@
#
# id: bugs.core_0857
# title: Containing not working correctly
# decription:
# decription:
# Could not find build 2.0 RC3.
# Checked on:
# 4.0.0.1713 SS: 1.625s.
@ -10,15 +10,15 @@
# 3.0.5.33218 SS: 1.000s.
# 3.0.5.33084 SC: 0.890s.
# 2.5.9.27149 SC: 0.266s.
#
#
# 02-mar-2021. Re-implemented in ordeer to have ability to run this test on Linux.
# We run 'init_script' using charset = utf8 but then run separate ISQL-process
# with request to establish connection using charset = win1252.
#
#
# Checked on:
# * Windows: 4.0.0.2377, 3.0.8.33420, 2.5.9.27152
# * Linux: 4.0.0.2377, 3.0.8.33415
#
#
# tracker_id: CORE-857
# min_versions: ['2.5.0']
# versions: 2.5
@ -55,7 +55,7 @@ db_1 = db_factory(charset='WIN1252', sql_dialect=3, init=init_script_1)
# test_script_1
#---
#
#
# sql_cmd='''
# set names win1252;
# connect '%(dsn)s' user '%(user_name)s' password '%(user_password)s';
@ -64,7 +64,7 @@ db_1 = db_factory(charset='WIN1252', sql_dialect=3, init=init_script_1)
# from mon$attachments a
# join rdb$character_sets c on a.mon$character_set_id = c.rdb$character_set_id
# where a.mon$attachment_id = current_connection;
#
#
# select t.id as "test_1 result:" from rdb$database r left join test t on t.f01 not containing 'P1' and t.f01 like 'IHF|gro_|850_C|P1';
# select t.id as "test_2 result:" from rdb$database r left join test t on t.f01 containing 'P1' and t.f01 like 'IHF|gro_|850_C|P1';
# select t.id as "ci_ai result:" from rdb$database r left join test t on lower(t.f02) = upper(t.f02);
@ -72,8 +72,8 @@ db_1 = db_factory(charset='WIN1252', sql_dialect=3, init=init_script_1)
# select * from v_test;
# ''' % dict(globals(), **locals())
# runProgram( 'isql', [ '-q' ], sql_cmd)
#
#
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
@ -86,9 +86,27 @@ expected_stdout_1 = """
octet_length diff: 1
"""
test_script_1 = """
set list on;
select c.rdb$character_set_name as connection_cset
from mon$attachments a
join rdb$character_sets c on a.mon$character_set_id = c.rdb$character_set_id
where a.mon$attachment_id = current_connection;
select t.id as "test_1 result:" from rdb$database r left join test t on t.f01 not containing 'P1' and t.f01 like 'IHF|gro_|850_C|P1';
select t.id as "test_2 result:" from rdb$database r left join test t on t.f01 containing 'P1' and t.f01 like 'IHF|gro_|850_C|P1';
select t.id as "ci_ai result:" from rdb$database r left join test t on lower(t.f02) = upper(t.f02);
select t.id as "between result:" from rdb$database r left join test t on lower(t.f01) between lower(t.f02) and upper(t.f02);
select * from v_test;
"""
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
@pytest.mark.version('>=2.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
act_1.charset = 'WIN1252'
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -2,14 +2,14 @@
#
# id: bugs.core_0929
# title: Bug in DSQL parameter
# decription:
# decription:
# tracker_id: CORE-929
# min_versions: []
# versions: 2.1
# qmid: bugs.core_929
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 2.1
# resources: None
@ -37,14 +37,18 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# except Exception,e:
# print ('Test FAILED')
# print (e)
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=2.1')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.db.connect() as con:
c = con.cursor()
try:
c.prepare('SELECT * FROM TEST WHERE MYDATE + CAST(? AS INTEGER) >= ?')
except:
pytest.fail("Test FAILED")

View File

@ -2,9 +2,9 @@
#
# id: bugs.core_0959
# title: GSTAT does not work using the localhost connection string
# decription:
# decription:
# Refactored 17.11.2017. Covers ticket CORE-5629.
#
#
# For 3.0+ we check in log of GSTAT presense of following lines:
# * with timestamp of GSTAT start
# * with DB name
@ -13,30 +13,41 @@
# * with count of data pages and average fill for table 'TEST'
# * with number of index root page, depath of index and number of buckets and nodes for index 'TEST_S'
# * with timestamp of GSTAT finish.
# If line from log matches to any of pattenrs then we do output if this line for checking in 'expected_stdout' section.
# If line from log matches to any of patterns then we do output if this line for checking in 'expected_stdout' section.
# Otherwise line is ignored.
#
#
# Check is done using regexp searches -- see definition of patterns hdr_dbname_ptn, hdr_dbattr_ptn, table_ppip_ptn etc.
#
#
# For 2.5.x check was changed only by added line with with timestamp of GSTAT start in 'expected_stdout' section.
#
#
# Checked on:
# FB25SC, build 2.5.8.27078: OK, 0.297s.
# FB30SS, build 3.0.3.32837: OK, 2.344s.
# FB40SS, build 4.0.0.800: OK, 2.437s.
#
#
# [pcisar] 9.11.2021
# This test is wrong as it uses service manager.
# It should use gstat directly with pseudo-remote path (i.e. localhost:filename)
#
# tracker_id: CORE-959
# min_versions: ['2.5']
# versions: 3.0
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
import re
# version: 3.0
# resources: None
substitutions_1 = [('Database ".*', 'Database'), ('Gstat execution time .*', 'Gstat execution time'), ('Attributes .*', 'Attributes'), ('Primary pointer page: \\d+, Index root page: \\d+\\s*', 'Primary pointer page, Index root page'), ('Data pages: \\d+, average fill: \\d+[percent_sign]', 'Data pages, average fill'), ('Root page: \\d+, depth: \\d+, leaf buckets: \\d+, nodes: \\d+\\s*', 'Root page, depth, leaf buckets, nodes'), ('Gstat completion time .*', 'Gstat completion time')]
substitutions_1 = [('Database ".*', 'Database'),
('Gstat execution time .*', 'Gstat execution time'),
('Attributes .*', 'Attributes'),
('Primary pointer page: \\d+, Index root page: \\d+\\s*', 'Primary pointer page, Index root page'),
('Data pages: \\d+, average fill: \\d+[percent_sign]', 'Data pages, average fill'),
('Root page: \\d+, depth: \\d+, leaf buckets: \\d+, nodes: \\d+\\s*', 'Root page, depth, leaf buckets, nodes'),
('Gstat completion time .*', 'Gstat completion time')]
init_script_1 = """
create sequence g;
@ -50,25 +61,25 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# test_script_1
#---
#
#
# import os
# import sys
# import subprocess
# import time
# import re
#
#
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
#
#
# hdr_dbname_ptn=re.compile('Database\\s+"', re.IGNORECASE)
# hdr_dbattr_ptn=re.compile('Attributes\\s+\\.*', re.IGNORECASE)
# table_ppip_ptn=re.compile('Primary\\s+pointer\\s+page:\\s+\\d+,\\s+Index root page:\\s+\\d+\\s*', re.IGNORECASE)
# table_dpaf_ptn=re.compile('Data\\s+pages:\\s+\\d+,\\s+average\\s+fill:\\s+\\d+%\\s*', re.IGNORECASE)
# index_root_ptn=re.compile('Root\\s+page:\\s+\\d+,\\s+depth:\\s+\\d+,\\s+leaf\\s+buckets:\\s+\\d+,\\s+nodes:\\s+\\d+\\s*', re.IGNORECASE)
#
#
# gstat_init_ptn=re.compile('Gstat\\s+execution\\s+time\\s+', re.IGNORECASE)
# gstat_fini_ptn=re.compile('Gstat\\s+completion\\s+time\\s+', re.IGNORECASE)
#
#
# watched_ptn_list=(
# hdr_dbname_ptn
# ,hdr_dbattr_ptn
@ -80,24 +91,24 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# )
# 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
# # 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'):
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
# os.fsync(file_handle.fileno())
# file_handle.close()
#
#
# #--------------------------------------------
#
#
# f_dbstat_log = open( os.path.join(context['temp_directory'],'tmp_local_host_0959.log'), 'w')
# f_dbstat_err = open( os.path.join(context['temp_directory'],'tmp_local_host_0959.err'), 'w')
# context['isql_path']
@ -112,39 +123,40 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# stdout=f_dbstat_log,
# stderr=f_dbstat_err
# )
#
#
# flush_and_close( f_dbstat_log )
# flush_and_close( f_dbstat_err )
#
#
# with open( f_dbstat_log.name,'r') as f:
# for line in f:
# if line.split():
# for p in watched_ptn_list:
# if p.search( line ):
# print( ' '.join(line.replace('%','[percent_sign]').split()) )
#
#
# with open( f_dbstat_err.name,'r') as f:
# for line in f:
# if line.split():
# print('UNEXPECTED STDERR in '+f_dbstat_err.name+': '+line)
#
#
#
#
# #####################
# # Cleanup.
# time.sleep(1)
#
# f_list=(
#
# f_list=(
# f_dbstat_log
# ,f_dbstat_err
# )
#
#
# for i in range(len(f_list)):
# if os.path.isfile(f_list[i].name):
# os.remove(f_list[i].name)
#
#
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
Database "C:\\MIX\\FIREBIRD\\QA\\FBT-REPO\\TMP\\BUGS.CORE_0959.FDB"
@ -157,8 +169,31 @@ expected_stdout_1 = """
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
hdr_dbname_ptn = re.compile('Database\\s+"', re.IGNORECASE)
hdr_dbattr_ptn = re.compile('Attributes\\s+\\.*', re.IGNORECASE)
table_ppip_ptn = re.compile('Primary\\s+pointer\\s+page:\\s+\\d+,\\s+Index root page:\\s+\\d+\\s*', re.IGNORECASE)
table_dpaf_ptn = re.compile('Data\\s+pages:\\s+\\d+,\\s+average\\s+fill:\\s+\\d+%\\s*', re.IGNORECASE)
index_root_ptn = re.compile('Root\\s+page:\\s+\\d+,\\s+depth:\\s+\\d+,\\s+leaf\\s+buckets:\\s+\\d+,\\s+nodes:\\s+\\d+\\s*', re.IGNORECASE)
#
gstat_init_ptn = re.compile('Gstat\\s+execution\\s+time\\s+', re.IGNORECASE)
gstat_fini_ptn = re.compile('Gstat\\s+completion\\s+time\\s+', re.IGNORECASE)
#
watched_ptn_list = [hdr_dbname_ptn, hdr_dbattr_ptn, table_ppip_ptn, table_dpaf_ptn,
index_root_ptn, gstat_init_ptn, gstat_fini_ptn]
#
act_1.expected_stdout = expected_stdout_1
act_1.gstat(switches=['-d', '-i', '-r'])
#
matched = []
for line in act_1.stdout.splitlines():
for p in watched_ptn_list:
if p.search(line):
matched.append(' '.join(line.replace('%','[percent_sign]').split()))
#
actual = '\n'.join(matched)
actual = act_1.string_strip(actual, act_1.substitutions)
assert 'localhost' in act_1.db.dsn
assert act_1.clean_expected_stdout == actual

View File

@ -2,14 +2,15 @@
#
# id: bugs.core_0967
# title: SQL with incorrect characters (outside the ASCII range) may be processed wrongly
# decription:
# decription:
# tracker_id: CORE-967
# min_versions: []
# versions: 2.1
# qmid: bugs.core_967
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
from firebird.driver import DatabaseError
# version: 2.1
# resources: None
@ -36,14 +37,18 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# c.execute('select * from t')
# printData(c)
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """'Error while preparing SQL statement:/n- SQLCODE: -104/n- Dynamic SQL Error/n- SQL error code = -104/n- Token unknown - line 1, column 17/n- /xee'
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
#expected_stdout_1 = """'Error while preparing SQL statement:/n- SQLCODE: -104/n- Dynamic SQL Error/n- SQL error code = -104/n- Token unknown - line 1, column 17/n- /xee'
#"""
@pytest.mark.version('>=2.1')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.db.connect() as con:
c = con.cursor()
with pytest.raises(DatabaseError, match="Dynamic SQL Error\n-SQL error code = -104\n-Token unknown - line 1, column 17\n.*") as excinfo:
c.execute('update t set i=1'+chr(238)+' where 1=0')

View File

@ -2,7 +2,7 @@
#
# id: bugs.core_0986
# title: Non-ASCII quoted identifiers are not converted to metadata (UNICODE_FSS) charset
# decription:
# decription:
# Test prepares file that will serve as input SQL script and will have CYRYLLIC names for all
# database objects: collations, domains, exceptions, tables, views etc.
# File has name = 'tmp_non_ascii_ddl_0986.sql' and is encoded to windows-1251 codepage.
@ -14,47 +14,48 @@
# 1.2) STDERR with single exception, it depends on major FB version:
# * for FB 3.x: SQLSTATE = 22000 / malformed string;
# * for FB 4.x: SQLSTATE = 22018 / Cannot transliterate ...
#
#
# 2. Attempt to apply the same script but now _WITH_ specification of connect charset: -ch win1251.
# This attempt should finish SUCCESSFULLY, and we will verify it by checking its:
# 2.1) STDOUT - it should contain phrase "Metadata created OK."
# 2.2) STDERR - it should be EMPTY.
#
#
# Confirmed on 2.0.7: one might to run ISQL without specifying '-ch XXXX' switch and give it
# script which
# 1) was encoded in NON unicode character set (e.g. win1251 - as is used in this test) and
# script which
# 1) was encoded in NON unicode character set (e.g. win1251 - as is used in this test) and
# 2) did create DB objects with non-ascii names.
#
#
# Checked on:
# 4.0.0.1635 SS: 3.217s.
# 4.0.0.1633 CS: 3.619s.
# 3.0.5.33180 SS: 2.548s.
# 3.0.5.33178 CS: 3.153s.
#
#
# 17-mar-2021. Re-implemented in order to have ability to run this test on Linux.
# Ttest creates table and fills it with non-ascii characters in init_script, using charset = UTF8.
# Test creates table and fills it with non-ascii characters in init_script, using charset = UTF8.
# Then it generates .sql script for running it in separae ISQL process.
# This script makes connection to test DB using charset = WIN1251 and perform needed DML.
# Result will be redirected to .log which will be opened via codecs.open(...encoding='cp1251').
# Its content will be converted to UTF8 for further parsing.
#
#
# Checked on:
# * Windows: 4.0.0.2387, 3.0.8.33426
# * Linux: 4.0.0.2387, 3.0.8.33426
#
#
#
#
# tracker_id: CORE-0986
# min_versions: ['3.0']
# versions: 3.0
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action, temp_file
from pathlib import Path
# version: 3.0
# resources: None
substitutions_1 = []
substitutions_1 = [('in file .*', 'in file XXX')]
init_script_1 = """"""
@ -65,30 +66,30 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# import os
# import time
# import subprocess
#
#
# # 28.10.2019. This is needed in Python 2.7 for converting string in UTF8 to cp1251
# import codecs
#
#
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
#
#
# #--------------------------------------------
#
#
# 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 )):
@ -99,54 +100,54 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# else:
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
# del_name = None
#
#
# if del_name and os.path.isfile( del_name ):
# os.remove( del_name )
#
#
# #--------------------------------------------
#
#
#
#
# # Obtain engine version:
# cur1 = db_conn.cursor()
# cur1.execute("select rdb$get_context('SYSTEM','ENGINE_VERSION') as engine_version from rdb$database")
# for row in cur1:
# engine = row[0]
#
#
# db_conn.close()
#
#
# non_ascii_ddl='''
# set bail on;
#
#
# -- set names win1251;
# connect '%(dsn)s' user '%(user_name)s' password '%(user_password)s';
#
#
# set echo on;
#
#
# create collation "Циферки" for utf8 from unicode case insensitive 'NUMERIC-SORT=1';
# create collation "Испания" for iso8859_1 from es_es_ci_ai 'SPECIALS-FIRST=1';;
# commit;
#
#
# create domain "ИД'шники" int;
# create domain "Группы" varchar(30) check( value in ('Электрика', 'Ходовая', 'Арматурка', 'Кузовщина') );
# create domain "Артикулы" varchar(12) character set utf8 check( value = upper(value) )
# create domain "Артикулы" varchar(12) character set utf8 check( value = upper(value) )
# collate "Циферки" -- enabled since core-5220 was fixed (30.04.2016)
# ;
# create domain "Комрады" varchar(40) character set iso8859_1
# create domain "Комрады" varchar(40) character set iso8859_1
# collate "Испания" -- enabled since core-5220 was fixed (30.04.2016)
# ;
# create domain "Кол-во" numeric(12,3) not null;
#
#
# create sequence generilka;
# create sequence "Генерилка";
#
#
# create role "манагер";
# create role "начсклд";
#
#
# -- TEMPLY COMMENTED UNTIL CORE-5209 IS OPEN:
# -- ISQL -X ignores connection charset for text of EXCEPTION message (restoring it in initial charset when exception was created)
# recreate exception "Невзлет" 'Запись обломалась, ваши не пляшут. Но не стесняйтесь и обязательно заходите еще, мы всегда рады видеть вас. До скорой встречи, товарищ!';
# commit;
#
#
# -------------------------------------------------
# recreate table "склад" (
# "ИД'шник" "ИД'шники"
@ -158,25 +159,25 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# ,constraint "ФК-на-родока" foreign key("ИД'родителя") references "склад" ("ИД'шник") using index "склад_ФК"
# ,constraint "остаток >=0" check ("сколько там" >= 0)
# );
#
#
# recreate view "Электрика"("ид изделия", "Название", "Запас") as
# select
# "ИД'шник"
# select
# "ИД'шник"
# ,"Номенклатура"
# ,"сколько там"
# from "склад"
# where "Откудова" = 'Электрика'
# ;
#
#
# set term ^;
# create or alter trigger "склад би" for "склад" active before insert as
# begin
# --new."ИД'шник" = coalesce( new."ИД'шник", gen_id(generilka, 1) );
# -- not avail up to 2.5.6:
# -- not avail up to 2.5.6:
# new."ИД'шник" = coalesce( new."ИД'шник", gen_id("Генерилка", 1) );
# end
# ^
#
#
# create or alter procedure "Доб на склад"(
# "Откудова" varchar(30)
# ,"Номенклатура" varchar(30)
@ -189,24 +190,24 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# insert into "склад"(
# "Откудова"
# ,"Номенклатура"
# ,"ИД'родителя"
# ,"ИД'родителя"
# ,"сколько там"
# ) values (
# :"Откудова"
# ,:"Номенклатура"
# ,:"ИД'родителя"
# ,:"ИД'родителя"
# ,:"сколько там"
# );
#
#
# end
# ^
# create or alter procedure "Удалить" as
# begin
# /*
# Антон Павлович Чехов. Каштанка
#
#
# 1. Дурное поведение
#
#
# Молодая рыжая собака - помесь такса с дворняжкой - очень похожая мордой
# на лисицу, бегала взад и вперед по тротуару и беспокойно оглядывалась по
# сторонам. Изредка она останавливалась и, плача, приподнимая то одну озябшую
@ -216,38 +217,38 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# end
# ^
# set term ;^
#
#
# grant select on "склад" to "манагер";
# grant select, insert, update, delete on "склад" to "начсклд";
# -- no avail in 2.0: grant execute procedure "Доб на склад" to "начсклд";
#
#
#
#
# comment on sequence "Генерилка" is 'Генератор простых идей';
# comment on table "склад" is 'Это всё, что мы сейчас имеем в наличии';
# comment on view "Электрика" is 'Не суй пальцы в розетку, будет бо-бо!';
# comment on procedure "Доб на склад" is 'Процедурка добавления изделия на склад';
# comment on parameter "Доб на склад"."Откудова" is 'Группа изделия, которое собираемся добавить';
#
#
# comment on parameter "Доб на склад"."ИД'родителя" is '
# Федор Михайлович Достоевский
#
#
# Преступление и наказание
#
#
# Роман в шести частях с эпилогом
#
#
#
#
# Часть первая
#
#
# I
# В начале июля, в чрезвычайно жаркое время, под вечер, один молодой человек вышел из своей каморки, которую нанимал от жильцов в С -- м переулке, на улицу и медленно, как бы в нерешимости, отправился к К -- ну мосту.
# Он благополучно избегнул встречи с своею хозяйкой на лестнице. Каморка его приходилась под самою кровлей высокого пятиэтажного дома и походила более на шкаф, чем на квартиру. Квартирная же хозяйка его, у которой он нанимал эту каморку с обедом и прислугой, помещалась одною лестницей ниже, в отдельной квартире, и каждый раз, при выходе на улицу, ему непременно надо было проходить мимо хозяйкиной кухни, почти всегда настежь отворенной на лестницу. И каждый раз молодой человек, проходя мимо, чувствовал какое-то болезненное и трусливое ощущение, которого стыдился и от которого морщился. Он был должен кругом хозяйке и боялся с нею встретиться.
# Не то чтоб он был так труслив и забит, совсем даже напротив; но с некоторого времени он был в раздражительном и напряженном состоянии, похожем на ипохондрию. Он до того углубился в себя и уединился от всех, что боялся даже всякой встречи, не только встречи с хозяйкой. Он был задавлен бедностью; но даже стесненное положение перестало в последнее время тяготить его. Насущными делами своими он совсем перестал и не хотел заниматься. Никакой хозяйки, в сущности, он не боялся, что бы та ни замышляла против него. Но останавливаться на лестнице, слушать всякий вздор про всю эту обыденную дребедень, до которой ему нет никакого дела, все эти приставания о платеже, угрозы, жалобы, и при этом самому изворачиваться, извиняться, лгать, -- нет уж, лучше проскользнуть как-нибудь кошкой по лестнице и улизнуть, чтобы никто не видал.
# Впрочем, на этот раз страх встречи с своею кредиторшей даже его самого поразил по выходе на улицу.
# "На какое дело хочу покуситься и в то же время каких пустяков боюсь! -- подумал он с странною улыбкой. -- Гм... да... всё в руках человека, и всё-то он мимо носу проносит, единственно от одной трусости... это уж аксиома... Любопытно, чего люди больше всего боятся? Нового шага, нового собственного слова они всего больше боятся... А впрочем, я слишком много болтаю. Оттого и ничего не делаю, что болтаю. Пожалуй, впрочем, и так: оттого болтаю, что ничего не делаю. Это я в этот последний месяц выучился болтать, лежа по целым суткам в углу и думая... о царе Горохе. Ну зачем я теперь иду? Разве я способен на это? Разве это серьезно? Совсем не серьезно. Так, ради фантазии сам себя тешу; игрушки! Да, пожалуй что и игрушки!"
# На улице жара стояла страшная, к тому же духота, толкотня, всюду известка, леса, кирпич, пыль и та особенная летняя вонь, столь известная каждому петербуржцу, не имеющему возможности нанять дачу, -- всё это разом неприятно потрясло и без того уже расстроенные нервы юноши. Нестерпимая же вонь из распивочных, которых в этой части города особенное множество, и пьяные, поминутно попадавшиеся, несмотря на буднее время, довершили отвратительный и грустный колорит картины. Чувство глубочайшего омерзения мелькнуло на миг в тонких чертах молодого человека. Кстати, он был замечательно хорош собою, с прекрасными темными глазами, темно-рус, ростом выше среднего, тонок и строен. Но скоро он впал как бы в глубокую задумчивость, даже, вернее сказать, как бы в какое-то забытье, и пошел, уже не замечая окружающего, да и не желая его замечать. Изредка только бормотал он что-то про себя, от своей привычки к монологам, в которой он сейчас сам себе признался. В эту же минуту он и сам сознавал, что мысли его порою мешаются и что он очень слаб: второй день как уж он почти совсем ничего не ел.
# Он был до того худо одет, что иной, даже и привычный человек, посовестился бы днем выходить в таких лохмотьях на улицу. Впрочем, квартал был таков, что костюмом здесь было трудно кого-нибудь удивить. Близость Сенной, обилие известных заведений и, по преимуществу, цеховое и ремесленное население, скученное в этих серединных петербургских улицах и переулках, пестрили иногда общую панораму такими субъектами, что странно было бы и удивляться при встрече с иною фигурой. Но столько злобного презрения уже накопилось в душе молодого человека, что, несмотря на всю свою, иногда очень молодую, щекотливость, он менее всего совестился своих лохмотьев на улице. Другое дело при встрече с иными знакомыми или с прежними товарищами, с которыми вообще он не любил встречаться... А между тем, когда один пьяный, которого неизвестно почему и куда провозили в это время по улице в огромной телеге, запряженной огромною ломовою лошадью, крикнул ему вдруг, проезжая: "Эй ты, немецкий шляпник!" -- и заорал во всё горло, указывая на него рукой, -- молодой человек вдруг остановился и судорожно схватился за свою шляпу. Шляпа эта была высокая, круглая, циммермановская, но вся уже изношенная, совсем рыжая, вся в дырах и пятнах, без полей и самым безобразнейшим углом заломившаяся на сторону. Но не стыд, а совсем другое чувство, похожее даже на испуг, охватило его.
# "Я так и знал! -- бормотал он в смущении, -- я так и думал! Это уж всего сквернее! Вот эдакая какая-нибудь глупость, какая-нибудь пошлейшая мелочь, весь замысел может испортить! Да, слишком приметная шляпа... Смешная, потому и приметная... К моим лохмотьям непременно нужна фуражка, хотя бы старый блин какой-нибудь, а не этот урод. Никто таких не носит, за версту заметят, запомнят... главное, потом запомнят, ан и улика. Тут нужно быть как можно неприметнее... Мелочи, мелочи главное!.. Вот эти-то мелочи и губят всегда и всё..."
#
# В начале июля, в чрезвычайно жаркое время, под вечер, один молодой человек вышел из своей каморки, которую нанимал от жильцов в С -- м переулке, на улицу и медленно, как бы в нерешимости, отправился к К -- ну мосту.
# Он благополучно избегнул встречи с своею хозяйкой на лестнице. Каморка его приходилась под самою кровлей высокого пятиэтажного дома и походила более на шкаф, чем на квартиру. Квартирная же хозяйка его, у которой он нанимал эту каморку с обедом и прислугой, помещалась одною лестницей ниже, в отдельной квартире, и каждый раз, при выходе на улицу, ему непременно надо было проходить мимо хозяйкиной кухни, почти всегда настежь отворенной на лестницу. И каждый раз молодой человек, проходя мимо, чувствовал какое-то болезненное и трусливое ощущение, которого стыдился и от которого морщился. Он был должен кругом хозяйке и боялся с нею встретиться.
# Не то чтоб он был так труслив и забит, совсем даже напротив; но с некоторого времени он был в раздражительном и напряженном состоянии, похожем на ипохондрию. Он до того углубился в себя и уединился от всех, что боялся даже всякой встречи, не только встречи с хозяйкой. Он был задавлен бедностью; но даже стесненное положение перестало в последнее время тяготить его. Насущными делами своими он совсем перестал и не хотел заниматься. Никакой хозяйки, в сущности, он не боялся, что бы та ни замышляла против него. Но останавливаться на лестнице, слушать всякий вздор про всю эту обыденную дребедень, до которой ему нет никакого дела, все эти приставания о платеже, угрозы, жалобы, и при этом самому изворачиваться, извиняться, лгать, -- нет уж, лучше проскользнуть как-нибудь кошкой по лестнице и улизнуть, чтобы никто не видал.
# Впрочем, на этот раз страх встречи с своею кредиторшей даже его самого поразил по выходе на улицу.
# "На какое дело хочу покуситься и в то же время каких пустяков боюсь! -- подумал он с странною улыбкой. -- Гм... да... всё в руках человека, и всё-то он мимо носу проносит, единственно от одной трусости... это уж аксиома... Любопытно, чего люди больше всего боятся? Нового шага, нового собственного слова они всего больше боятся... А впрочем, я слишком много болтаю. Оттого и ничего не делаю, что болтаю. Пожалуй, впрочем, и так: оттого болтаю, что ничего не делаю. Это я в этот последний месяц выучился болтать, лежа по целым суткам в углу и думая... о царе Горохе. Ну зачем я теперь иду? Разве я способен на это? Разве это серьезно? Совсем не серьезно. Так, ради фантазии сам себя тешу; игрушки! Да, пожалуй что и игрушки!"
# На улице жара стояла страшная, к тому же духота, толкотня, всюду известка, леса, кирпич, пыль и та особенная летняя вонь, столь известная каждому петербуржцу, не имеющему возможности нанять дачу, -- всё это разом неприятно потрясло и без того уже расстроенные нервы юноши. Нестерпимая же вонь из распивочных, которых в этой части города особенное множество, и пьяные, поминутно попадавшиеся, несмотря на буднее время, довершили отвратительный и грустный колорит картины. Чувство глубочайшего омерзения мелькнуло на миг в тонких чертах молодого человека. Кстати, он был замечательно хорош собою, с прекрасными темными глазами, темно-рус, ростом выше среднего, тонок и строен. Но скоро он впал как бы в глубокую задумчивость, даже, вернее сказать, как бы в какое-то забытье, и пошел, уже не замечая окружающего, да и не желая его замечать. Изредка только бормотал он что-то про себя, от своей привычки к монологам, в которой он сейчас сам себе признался. В эту же минуту он и сам сознавал, что мысли его порою мешаются и что он очень слаб: второй день как уж он почти совсем ничего не ел.
# Он был до того худо одет, что иной, даже и привычный человек, посовестился бы днем выходить в таких лохмотьях на улицу. Впрочем, квартал был таков, что костюмом здесь было трудно кого-нибудь удивить. Близость Сенной, обилие известных заведений и, по преимуществу, цеховое и ремесленное население, скученное в этих серединных петербургских улицах и переулках, пестрили иногда общую панораму такими субъектами, что странно было бы и удивляться при встрече с иною фигурой. Но столько злобного презрения уже накопилось в душе молодого человека, что, несмотря на всю свою, иногда очень молодую, щекотливость, он менее всего совестился своих лохмотьев на улице. Другое дело при встрече с иными знакомыми или с прежними товарищами, с которыми вообще он не любил встречаться... А между тем, когда один пьяный, которого неизвестно почему и куда провозили в это время по улице в огромной телеге, запряженной огромною ломовою лошадью, крикнул ему вдруг, проезжая: "Эй ты, немецкий шляпник!" -- и заорал во всё горло, указывая на него рукой, -- молодой человек вдруг остановился и судорожно схватился за свою шляпу. Шляпа эта была высокая, круглая, циммермановская, но вся уже изношенная, совсем рыжая, вся в дырах и пятнах, без полей и самым безобразнейшим углом заломившаяся на сторону. Но не стыд, а совсем другое чувство, похожее даже на испуг, охватило его.
# "Я так и знал! -- бормотал он в смущении, -- я так и думал! Это уж всего сквернее! Вот эдакая какая-нибудь глупость, какая-нибудь пошлейшая мелочь, весь замысел может испортить! Да, слишком приметная шляпа... Смешная, потому и приметная... К моим лохмотьям непременно нужна фуражка, хотя бы старый блин какой-нибудь, а не этот урод. Никто таких не носит, за версту заметят, запомнят... главное, потом запомнят, ан и улика. Тут нужно быть как можно неприметнее... Мелочи, мелочи главное!.. Вот эти-то мелочи и губят всегда и всё..."
#
# ';
# --------------------------------------------------
# commit;
@ -267,34 +268,34 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# set list on;
# set echo off;
# select 'Metadata created OK.' as msg from rdb$database;
#
#
# ''' % dict(globals(), **locals())
#
#
#
#
# f_checksql = open( os.path.join(context['temp_directory'], 'tmp_0986_w1251.sql'), 'w' )
# f_checksql.write( non_ascii_ddl.decode('utf8').encode('cp1251') )
# flush_and_close( f_checksql )
#
#
# # Result: file 'tmp_0986_w1251' is encoded in cp1251 and contains SQL statements to be executed.
#
#
# ###########################################################################################################
# ### check-1: attempt to apply DDL with non-ascii characters __WITHOUT__ charset specifying (for ISQL) ###
# ###########################################################################################################
#
#
# f_apply_cset_none_log = open( os.path.join(context['temp_directory'],'tmp_0986_apply_cset_none.log'), 'w')
# f_apply_cset_none_err = open( os.path.join(context['temp_directory'],'tmp_0986_apply_cset_none.err'), 'w')
#
#
# subprocess.call( [ context['isql_path'], "-q", "-i", f_checksql.name ],
# stdout = f_apply_cset_none_log,
# stderr = f_apply_cset_none_err
# )
#
#
# # This file should contain only FIRST statement from DDL hich contains non-ascii characters:
# # (because of 'set BAIL on' ISQL should immediately terminate its job):
# # create collation "Циферки" for utf8 from unicode case insensitive 'NUMERIC-SORT=1';:
# #
# flush_and_close( f_apply_cset_none_log )
#
#
# # This file should contain error on 1st DDL statement which contains non-ascii characters:
# # FB 3.x:
# # Statement failed, SQLSTATE = 22000
@ -307,29 +308,29 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# # -Cannot transliterate character between character sets
# #
# flush_and_close( f_apply_cset_none_err )
#
#
# #############################################################################################################
# ### check-2: attempt to apply DDL with non-ascii characters ___WITH___ specifying: ISQL ... -ch WIN1251 ###
# #############################################################################################################
#
#
# f_apply_cset_1251_log = open( os.path.join(context['temp_directory'],'tmp_0986_apply_cset_1251.log'), 'w')
# f_apply_cset_1251_err = open( os.path.join(context['temp_directory'],'tmp_0986_apply_cset_1251.err'), 'w')
#
#
# subprocess.call( [ context['isql_path'], "-q", "-i", f_checksql.name, "-ch", "win1251" ],
# stdout = f_apply_cset_1251_log,
# stderr = f_apply_cset_1251_err
# )
#
#
# # This file should contain ALL applied statements, plus final message:
# # MSG Metadata created OK.
# flush_and_close( f_apply_cset_1251_log )
#
#
# # This file should NOT contain any errors:
# flush_and_close( f_apply_cset_1251_err )
#
#
# # CHECK RESULTS:
# ################
#
#
# # This stdout log should contain only ONE statement (create collation <non_ascii_name> ...),
# # this DDL failed and caused ISQL to immediately terminate:
# #
@ -341,7 +342,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# print( out_txt + "FOUND EXPECTED 'CREATE COLLATION STATEMENT'" )
# else:
# print( out_txt+'SOME OTHER STATEMENT FOUND' )
#
#
# with open( f_apply_cset_none_err.name, 'r') as f:
# for line in f:
# out_txt='STDERR WHEN CSET=NONE: ';
@ -350,13 +351,13 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# print( out_txt+'FOUND EXPECTED SQLSTATE IN ERROR MESSAGE' )
# else:
# print( out_txt+'SOME OTHER ERROR FOUND: '+line )
#
#
# # This log should contain 'magic text' which tells that all finished OK:
# # MSG Metadata created OK.
#
#
# if 'Metadata created OK.' in open(f_apply_cset_1251_log.name).read():
# print('STDLOG WHEN CSET=1251: ALL FINISHED OK.')
#
#
# # This log should be EMPTY: when we used '-ch win1251' then metadata
# # with non-ascii names in DB objects should be created successfully:
# #
@ -364,25 +365,202 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# for line in f:
# if line:
# print('Unexpected STDERR when use -ch win1251: ' + line)
#
#
# # CLEANUP
# #########
# time.sleep(1)
# cleanup( ( f_apply_cset_none_log, f_apply_cset_none_err, f_apply_cset_1251_log, f_apply_cset_1251_err,f_checksql, ) )
#
#
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
STDLOG WHEN CSET=NONE: FOUND EXPECTED 'CREATE COLLATION STATEMENT'
STDERR WHEN CSET=NONE: FOUND EXPECTED SQLSTATE IN ERROR MESSAGE
STDLOG WHEN CSET=1251: ALL FINISHED OK.
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1_a = """create collation "Циферки" for utf8 from unicode case insensitive 'NUMERIC-SORT=1';"""
expected_stderr_1_a_40 = """
Statement failed, SQLSTATE = 22018
arithmetic exception, numeric overflow, or string truncation
-Cannot transliterate character between character sets
After line 4 in file /tmp/pytest/pytest-124/test/non_ascii_ddl.sql
"""
expected_stderr_1_a_30 = """
Statement failed, SQLSTATE = 22000
unsuccessful metadata update
-CREATE COLLATION Циферки failed
-Malformed string
"""
non_ascii_ddl='''
set bail on;
set echo on;
create collation "Циферки" for utf8 from unicode case insensitive 'NUMERIC-SORT=1';
create collation "Испания" for iso8859_1 from es_es_ci_ai 'SPECIALS-FIRST=1';;
commit;
create domain "ИД'шники" int;
create domain "Группы" varchar(30) check( value in ('Электрика', 'Ходовая', 'Арматурка', 'Кузовщина') );
create domain "Артикулы" varchar(12) character set utf8 check( value = upper(value) )
collate "Циферки" -- enabled since core-5220 was fixed (30.04.2016)
;
create domain "Комрады" varchar(40) character set iso8859_1
collate "Испания" -- enabled since core-5220 was fixed (30.04.2016)
;
create domain "Кол-во" numeric(12,3) not null;
create sequence generilka;
create sequence "Генерилка";
create role "манагер";
create role "начсклд";
-- TEMPLY COMMENTED UNTIL CORE-5209 IS OPEN:
-- ISQL -X ignores connection charset for text of EXCEPTION message (restoring it in initial charset when exception was created)
recreate exception "Невзлет" 'Запись обломалась, ваши не пляшут. Но не стесняйтесь и обязательно заходите еще, мы всегда рады видеть вас. До скорой встречи, товарищ!';
commit;
-------------------------------------------------
recreate table "склад" (
"ИД'шник" "ИД'шники"
,"Откудова" "Группы"
,"Номенклатура" "Артикулы"
,"ИД'родителя" "ИД'шники"
,"сколько там" "Кол-во"
,constraint "ПК-ИД'шник" primary key ("ИД'шник") using index "склад_ПК"
,constraint "ФК-на-родока" foreign key("ИД'родителя") references "склад" ("ИД'шник") using index "склад_ФК"
,constraint "остаток >=0" check ("сколько там" >= 0)
);
recreate view "Электрика"("ид изделия", "Название", "Запас") as
select
"ИД'шник"
,"Номенклатура"
,"сколько там"
from "склад"
where "Откудова" = 'Электрика'
;
set term ^;
create or alter trigger "склад би" for "склад" active before insert as
begin
--new."ИД'шник" = coalesce( new."ИД'шник", gen_id(generilka, 1) );
-- not avail up to 2.5.6:
new."ИД'шник" = coalesce( new."ИД'шник", gen_id("Генерилка", 1) );
end
^
create or alter procedure "Доб на склад"(
"Откудова" varchar(30)
,"Номенклатура" varchar(30)
,"ИД'родителя" int
,"сколько там" numeric(12,3)
) returns (
"код возврата" int
) as
begin
insert into "склад"(
"Откудова"
,"Номенклатура"
,"ИД'родителя"
,"сколько там"
) values (
:"Откудова"
,:"Номенклатура"
,:"ИД'родителя"
,:"сколько там"
);
end
^
create or alter procedure "Удалить" as
begin
/*
Антон Павлович Чехов. Каштанка
1. Дурное поведение
Молодая рыжая собака - помесь такса с дворняжкой - очень похожая мордой
на лисицу, бегала взад и вперед по тротуару и беспокойно оглядывалась по
сторонам. Изредка она останавливалась и, плача, приподнимая то одну озябшую
лапу, то другую, старалась дать себе отчет: как это могло случиться, что она
заблудилась?
*/
end
^
set term ;^
grant select on "склад" to "манагер";
grant select, insert, update, delete on "склад" to "начсклд";
-- no avail in 2.0: grant execute procedure "Доб на склад" to "начсклд";
comment on sequence "Генерилка" is 'Генератор простых идей';
comment on table "склад" is 'Это всё, что мы сейчас имеем в наличии';
comment on view "Электрика" is 'Не суй пальцы в розетку, будет бо-бо!';
comment on procedure "Доб на склад" is 'Процедурка добавления изделия на склад';
comment on parameter "Доб на склад"."Откудова" is 'Группа изделия, которое собираемся добавить';
comment on parameter "Доб на склад"."ИД'родителя" is '
Федор Михайлович Достоевский
Преступление и наказание
Роман в шести частях с эпилогом
Часть первая
I
В начале июля, в чрезвычайно жаркое время, под вечер, один молодой человек вышел из своей каморки, которую нанимал от жильцов в С -- м переулке, на улицу и медленно, как бы в нерешимости, отправился к К -- ну мосту.
Он благополучно избегнул встречи с своею хозяйкой на лестнице. Каморка его приходилась под самою кровлей высокого пятиэтажного дома и походила более на шкаф, чем на квартиру. Квартирная же хозяйка его, у которой он нанимал эту каморку с обедом и прислугой, помещалась одною лестницей ниже, в отдельной квартире, и каждый раз, при выходе на улицу, ему непременно надо было проходить мимо хозяйкиной кухни, почти всегда настежь отворенной на лестницу. И каждый раз молодой человек, проходя мимо, чувствовал какое-то болезненное и трусливое ощущение, которого стыдился и от которого морщился. Он был должен кругом хозяйке и боялся с нею встретиться.
Не то чтоб он был так труслив и забит, совсем даже напротив; но с некоторого времени он был в раздражительном и напряженном состоянии, похожем на ипохондрию. Он до того углубился в себя и уединился от всех, что боялся даже всякой встречи, не только встречи с хозяйкой. Он был задавлен бедностью; но даже стесненное положение перестало в последнее время тяготить его. Насущными делами своими он совсем перестал и не хотел заниматься. Никакой хозяйки, в сущности, он не боялся, что бы та ни замышляла против него. Но останавливаться на лестнице, слушать всякий вздор про всю эту обыденную дребедень, до которой ему нет никакого дела, все эти приставания о платеже, угрозы, жалобы, и при этом самому изворачиваться, извиняться, лгать, -- нет уж, лучше проскользнуть как-нибудь кошкой по лестнице и улизнуть, чтобы никто не видал.
Впрочем, на этот раз страх встречи с своею кредиторшей даже его самого поразил по выходе на улицу.
"На какое дело хочу покуситься и в то же время каких пустяков боюсь! -- подумал он с странною улыбкой. -- Гм... да... всё в руках человека, и всё-то он мимо носу проносит, единственно от одной трусости... это уж аксиома... Любопытно, чего люди больше всего боятся? Нового шага, нового собственного слова они всего больше боятся... А впрочем, я слишком много болтаю. Оттого и ничего не делаю, что болтаю. Пожалуй, впрочем, и так: оттого болтаю, что ничего не делаю. Это я в этот последний месяц выучился болтать, лежа по целым суткам в углу и думая... о царе Горохе. Ну зачем я теперь иду? Разве я способен на это? Разве это серьезно? Совсем не серьезно. Так, ради фантазии сам себя тешу; игрушки! Да, пожалуй что и игрушки!"
На улице жара стояла страшная, к тому же духота, толкотня, всюду известка, леса, кирпич, пыль и та особенная летняя вонь, столь известная каждому петербуржцу, не имеющему возможности нанять дачу, -- всё это разом неприятно потрясло и без того уже расстроенные нервы юноши. Нестерпимая же вонь из распивочных, которых в этой части города особенное множество, и пьяные, поминутно попадавшиеся, несмотря на буднее время, довершили отвратительный и грустный колорит картины. Чувство глубочайшего омерзения мелькнуло на миг в тонких чертах молодого человека. Кстати, он был замечательно хорош собою, с прекрасными темными глазами, темно-рус, ростом выше среднего, тонок и строен. Но скоро он впал как бы в глубокую задумчивость, даже, вернее сказать, как бы в какое-то забытье, и пошел, уже не замечая окружающего, да и не желая его замечать. Изредка только бормотал он что-то про себя, от своей привычки к монологам, в которой он сейчас сам себе признался. В эту же минуту он и сам сознавал, что мысли его порою мешаются и что он очень слаб: второй день как уж он почти совсем ничего не ел.
Он был до того худо одет, что иной, даже и привычный человек, посовестился бы днем выходить в таких лохмотьях на улицу. Впрочем, квартал был таков, что костюмом здесь было трудно кого-нибудь удивить. Близость Сенной, обилие известных заведений и, по преимуществу, цеховое и ремесленное население, скученное в этих серединных петербургских улицах и переулках, пестрили иногда общую панораму такими субъектами, что странно было бы и удивляться при встрече с иною фигурой. Но столько злобного презрения уже накопилось в душе молодого человека, что, несмотря на всю свою, иногда очень молодую, щекотливость, он менее всего совестился своих лохмотьев на улице. Другое дело при встрече с иными знакомыми или с прежними товарищами, с которыми вообще он не любил встречаться... А между тем, когда один пьяный, которого неизвестно почему и куда провозили в это время по улице в огромной телеге, запряженной огромною ломовою лошадью, крикнул ему вдруг, проезжая: "Эй ты, немецкий шляпник!" -- и заорал во всё горло, указывая на него рукой, -- молодой человек вдруг остановился и судорожно схватился за свою шляпу. Шляпа эта была высокая, круглая, циммермановская, но вся уже изношенная, совсем рыжая, вся в дырах и пятнах, без полей и самым безобразнейшим углом заломившаяся на сторону. Но не стыд, а совсем другое чувство, похожее даже на испуг, охватило его.
"Я так и знал! -- бормотал он в смущении, -- я так и думал! Это уж всего сквернее! Вот эдакая какая-нибудь глупость, какая-нибудь пошлейшая мелочь, весь замысел может испортить! Да, слишком приметная шляпа... Смешная, потому и приметная... К моим лохмотьям непременно нужна фуражка, хотя бы старый блин какой-нибудь, а не этот урод. Никто таких не носит, за версту заметят, запомнят... главное, потом запомнят, ан и улика. Тут нужно быть как можно неприметнее... Мелочи, мелочи главное!.. Вот эти-то мелочи и губят всегда и всё..."
';
--------------------------------------------------
commit;
--/*
--TEMPLY COMMENTED UNTIL CORE-5221 IS OPEN:
set echo on;
show collation;
show domain;
show exception; -- <<<<<<<<<<<<<
show sequence;
show table;
show trigger;
show view;
show procedure;
show role;
--*/
set list on;
set echo off;
select 'Metadata created OK.' as msg from rdb$database;
'''
tmp_file_1 = temp_file('non_ascii_ddl.sql')
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, tmp_file_1: Path):
#
tmp_file_1.write_bytes(non_ascii_ddl.encode('cp1251'))
# run without specifying charset
act_1.expected_stdout = expected_stdout_1_a
act_1.expected_stderr = expected_stderr_1_a_40 if act_1.is_version('>=4.0') else expected_stderr_1_a_30
act_1.isql(switches=['-q'], input_file=tmp_file_1, charset=None, io_enc='cp1251')
assert act_1.clean_stdout == act_1.clean_expected_stdout
assert act_1.clean_stderr == act_1.clean_expected_stderr
# run with charset
act_1.reset()
act_1.isql(switches=['-q'], input_file=tmp_file_1, charset='win1251', io_enc='cp1251')
assert act_1.clean_stdout.endswith('Metadata created OK.')

View File

@ -2,14 +2,14 @@
#
# id: bugs.core_1073
# title: SINGULAR buggy when nulls present
# decription:
# decription:
# tracker_id: CORE-1073
# min_versions: []
# versions: 2.1
# qmid: bugs.core_1073
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 2.1
# resources: None
@ -30,82 +30,153 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# if (exp and (r is None)) or (not exp and (r is not None)):
# print ('Test FAILED in step ',step,', expectation ',exp)
# print ('Statement:',statement)
#
#
# c = db_conn.cursor()
# p_singular = 'select 1 from rdb$database where singular(select * from t where a = 1)'
# n_singular = 'select 1 from rdb$database where not(singular(select * from t where a = 1))'
# p_nsingular = 'select 1 from rdb$database where not singular( select * from t where a = 1)'
# n_nsingular = 'select 1 from rdb$database where not(not singular(select * from t where a = 1))'
#
#
# ins = 'insert into t values (%s)'
#
#
# # Step 1
#
#
# c.execute(ins % '2')
# c.execute(ins % 'null')
# db_conn.commit()
#
#
# check(1,c,p_singular,False)
# check(1,c,n_singular,True)
# check(1,c,p_nsingular,True)
# check(1,c,n_nsingular,False)
#
#
# c.execute('delete from t')
# db_conn.commit()
#
#
# # Step 2
#
#
# c.execute(ins % '1')
# c.execute(ins % 'null')
# db_conn.commit()
#
#
# check(2,c,p_singular,True)
# check(2,c,n_singular,False)
# check(2,c,p_nsingular,False)
# check(2,c,n_nsingular,True)
#
#
# c.execute('delete from t')
# db_conn.commit()
#
#
# # Step 3
#
#
# c.execute(ins % '1')
# c.execute(ins % 'null')
# c.execute(ins % '1')
# db_conn.commit()
#
#
# check(3,c,p_singular,False)
# check(3,c,n_singular,True)
# check(3,c,p_nsingular,True)
# check(3,c,n_nsingular,False)
#
#
# c.execute('delete from t')
# db_conn.commit()
#
#
# # Step 4
#
#
# c.execute(ins % '1')
# c.execute(ins % '1')
# c.execute(ins % 'null')
# db_conn.commit()
#
#
# check(4,c,p_singular,False)
# check(4,c,n_singular,True)
# check(4,c,p_nsingular,True)
# check(4,c,n_nsingular,False)
#
#
# c.execute('delete from t')
# db_conn.commit()
#
#
#
#
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
def check(step, cur, statement, exp):
r = cur.execute(statement).fetchone()
if (exp and (r is None)) or (not exp and (r is not None)):
pytest.fail(f'Test FAILED in step {step}, expectation {exp}')
@pytest.mark.version('>=2.1')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.db.connect() as con:
c = con.cursor()
#
p_singular = 'select 1 from rdb$database where singular(select * from t where a = 1)'
n_singular = 'select 1 from rdb$database where not(singular(select * from t where a = 1))'
p_nsingular = 'select 1 from rdb$database where not singular( select * from t where a = 1)'
n_nsingular = 'select 1 from rdb$database where not(not singular(select * from t where a = 1))'
#
ins = 'insert into t values (%s)'
#
# Step 1
#
c.execute(ins % '2')
c.execute(ins % 'null')
con.commit()
#
check(1, c, p_singular, False)
check(1, c, n_singular, True)
check(1, c, p_nsingular, True)
check(1, c, n_nsingular, False)
#
c.execute('delete from t')
con.commit()
#
# Step 2
#
c.execute(ins % '1')
c.execute(ins % 'null')
con.commit()
#
check(2, c, p_singular, True)
check(2, c, n_singular, False)
check(2, c, p_nsingular, False)
check(2, c, n_nsingular, True)
#
c.execute('delete from t')
con.commit()
#
# Step 3
#
c.execute(ins % '1')
c.execute(ins % 'null')
c.execute(ins % '1')
con.commit()
#
check(3, c, p_singular, False)
check(3, c, n_singular, True)
check(3, c, p_nsingular, True)
check(3, c, n_nsingular, False)
#
c.execute('delete from t')
con.commit()
#
# Step 4
#
c.execute(ins % '1')
c.execute(ins % '1')
c.execute(ins % 'null')
con.commit()
#
check(4, c, p_singular, False)
check(4, c, n_singular, True)
check(4, c, p_nsingular, True)
check(4, c, n_nsingular, False)
#
c.execute('delete from t')
con.commit()

View File

@ -2,20 +2,20 @@
#
# id: bugs.core_1076
# title: gsec truncate First.Middle.Last Name fields to 17 chars instead of 32 chars available in field definition
# decription:
# decription:
# FB2.0 correctly saves First, Middle & Last Name fields in the security database to the available length of 32 characters.
# FB1.5.3 and still now FB1.5.4RC1 truncates these field lengths to 17 chars.
# ---
# 11.01.2016: refactored for 3.0: use FBSVCMGR instead of GSEC. This was agreed with Alex, see his reply 11.01.2015 17:57.
#
#
#
#
# tracker_id: CORE-1076
# min_versions: []
# versions: 3.0
# qmid:
# qmid:
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 3.0
# resources: None
@ -33,52 +33,52 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# import subprocess
# from subprocess import Popen
# from fdb import services
#
#
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
#
#
#
#
# #--------------------------------------------
#
#
# 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
# # 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'):
# # 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 os.path.isfile( f_names_list[i]):
# os.remove( f_names_list[i] )
#
#
# #--------------------------------------------
#
#
# db_name=db_conn.database_name
# db_conn.close()
#
#
# svc = services.connect(host='localhost')
# security_db_name = svc.get_security_database_path() # path+name of security DB
# svc.close()
#
#
# check_login="Nebuchadnezzar2_King_of_Babylon"
#
#
# f_svc_log=open( os.path.join(context['temp_directory'],'tmp_1076_fbsvc.log'), 'w')
# f_svc_err=open( os.path.join(context['temp_directory'],'tmp_1076_fbsvc.err'), 'w')
#
#
# f_svc_log.write("Try to add user.")
# f_svc_log.write("\\n")
# f_svc_log.seek(0,2)
#
#
# subprocess.call( [ context['fbsvcmgr_path']
# ,"localhost:service_mgr"
# ,"action_add_user"
@ -88,13 +88,13 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# ]
# ,stdout=f_svc_log, stderr=f_svc_err
# )
#
#
# f_svc_log.seek(0,2)
# f_svc_log.write("\\n")
# f_svc_log.write("Try to modify user: change password and some attributes.")
# f_svc_log.write("\\n")
# f_svc_log.seek(0,2)
#
#
# subprocess.call( [ context['fbsvcmgr_path']
# ,"localhost:service_mgr"
# ,"action_modify_user"
@ -106,83 +106,95 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# ]
# ,stdout=f_svc_log, stderr=f_svc_err
# )
#
#
# f_svc_log.seek(0,2)
# f_svc_log.write("\\n")
# f_svc_log.write("All done.")
# f_svc_log.write("\\n")
#
#
# flush_and_close( f_svc_log )
# flush_and_close( f_svc_err )
#
# isql_txt=''' set list on;
# select sec$user_name, sec$first_name, sec$middle_name, sec$last_name from sec$users
#
# isql_txt=''' set list on;
# select sec$user_name, sec$first_name, sec$middle_name, sec$last_name from sec$users
# where upper(sec$user_name) = upper('%s');
# commit;
# drop user %s;
# ''' % (check_login, check_login)
#
#
# f_sql_txt=open( os.path.join(context['temp_directory'],'tmp_1076_isql.sql'), 'w')
# f_sql_txt.write(isql_txt)
# flush_and_close( f_sql_txt )
#
#
# f_sql_log=open( os.path.join(context['temp_directory'],'tmp_1076_isql.log'), 'w')
# f_sql_err=open( os.path.join(context['temp_directory'],'tmp_1076_isql.err'), 'w')
#
#
# subprocess.call( [ context['isql_path'], dsn, "-i", f_sql_txt.name ]
# ,stdout=f_sql_log
# ,stderr=f_sql_err
# )
#
#
# flush_and_close( f_sql_log )
# flush_and_close( f_sql_err )
#
#
# with open( f_svc_log.name,'r') as f:
# l = [l for l in f.readlines() if l.strip()]
#
#
# for line in l:
# print("SVC STDOUT: "+line )
#
#
# with open( f_svc_err.name,'r') as f:
# l = [l for l in f.readlines() if l.strip()]
#
#
# for line in l:
# print("SVC STDERR: "+line )
#
#
# with open( f_sql_log.name,'r') as f:
# l = [l for l in f.readlines() if l.strip()]
#
#
# for line in l:
# print("SQL STDOUT: "+line )
#
#
# with open( f_sql_err.name,'r') as f:
# l = [l for l in f.readlines() if l.strip()]
#
#
# for line in l:
# print("SQL STDERR: "+line )
#
#
# #############################################
#
#
# # Cleanup.
# time.sleep(1)
# cleanup( [i.name for i in (f_svc_log, f_svc_err, f_sql_log, f_sql_err, f_sql_txt)] )
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
expected_stdout_1 = """
SVC STDOUT: Try to add user.
SVC STDOUT: Try to modify user: change password and some attributes.
SVC STDOUT: All done.
SQL STDOUT: SEC$USER_NAME NEBUCHADNEZZAR2_KING_OF_BABYLON
SQL STDOUT: SEC$FIRST_NAME Nebuchadnezzar3_King_of_Babylon
SQL STDOUT: SEC$MIDDLE_NAME Nebuchadnezzar4_King_of_Babylon
SQL STDOUT: SEC$LAST_NAME Nebuchadnezzar5_King_of_Babylon
"""
SEC$USER_NAME NEBUCHADNEZZAR2_KING_OF_BABYLON
SEC$FIRST_NAME Nebuchadnezzar3_King_of_Babylon
SEC$MIDDLE_NAME Nebuchadnezzar4_King_of_Babylon
SEC$LAST_NAME Nebuchadnezzar5_King_of_Babylon
"""
@pytest.mark.version('>=3.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.connect_server() as srv:
check_login = "Nebuchadnezzar2_King_of_Babylon"
srv.user.add(user_name=check_login, password="Nebu_King_of_Babylon")
srv.user.update(user_name=check_login,
first_name="Nebuchadnezzar3_King_of_Babylon",
middle_name="Nebuchadnezzar4_King_of_Babylon",
last_name="Nebuchadnezzar5_King_of_Babylon")
#
act_1.script = f"""set list on;
select sec$user_name, sec$first_name, sec$middle_name, sec$last_name from sec$users
where upper(sec$user_name) = upper('{check_login}');
commit;
drop user {check_login};
"""
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_stdout == act_1.clean_expected_stdout

View File

@ -9,7 +9,7 @@
# qmid: bugs.core_1112
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 2.1
# resources: None
@ -28,7 +28,7 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# c.execute("select * from rdb$database where '%s' = 'a'" % longstr)
# except:
# pass
#
#
# try:
# c.execute("select * from rdb$database where '%s' containing 'a'" % longstr)
# except:
@ -36,14 +36,18 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# c.execute("select 'a' from rdb$database")
# print (c.fetchall())
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """[('a',)]
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=2.1')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.db.connect() as con:
c = con.cursor()
longstr = 'abc' * 10930
c.execute(f"select * from rdb$database where '{longstr}' = 'a'")
c.execute(f"select * from rdb$database where '{longstr}' containing 'a'")
c.execute("select 'a' from rdb$database")
result = c.fetchall()
assert result == [('a',)]

View File

@ -2,7 +2,7 @@
#
# id: bugs.core_1148
# title: Every user can view server log using services API
# decription:
# decription:
# Instead of usage 'resource:test_user' (as it was before) we create every time this test run user TMP$C1148
# and make test connect to database as this user in order to check ability to connect and get engine version.
# Then we parse engine version (is it 2.5 or 3.0 ?) and construct command to obtain Firebird log using FBSVCMGR
@ -10,19 +10,22 @@
# After that we try to extract firebird log using fbsvcmgr and this command is EXPECTED return error, so we log
# this message to separate file (and STDOUT is redirected to /dev/null).
# Finally, we check content of 1st and 2nd files and remove temply created user.
#
#
# tracker_id: CORE-1148
# min_versions: ['2.5.0']
# versions: 2.5
# qmid: bugs.core_1148
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action, temp_user, User
from firebird.driver import DatabaseError
# version: 2.5
# resources: None
substitutions_1 = [('ENGINE_VERSION .*', 'ENGINE_VERSION'), ('STDERR: UNABLE TO PERFORM OPERATION.*', 'STDERR: UNABLE TO PERFORM OPERATION'), ('STDERR: -YOU MUST HAVE SYSDBA RIGHTS AT THIS SERVER*', '')]
substitutions_1 = [('ENGINE_VERSION .*', 'ENGINE_VERSION'),
('STDERR: UNABLE TO PERFORM OPERATION.*', 'STDERR: UNABLE TO PERFORM OPERATION'),
('STDERR: -YOU MUST HAVE SYSDBA RIGHTS AT THIS SERVER*', '')]
init_script_1 = """"""
@ -30,35 +33,35 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# test_script_1
#---
#
#
#
#
# # Refactored 05-JAN-2016: removed dependency on recource 'test_user' because this lead to:
# # UNTESTED: bugs.core_2729
# # Add new user
# # Unexpected stderr stream received from GSEC.
# # (i.e. test remained in state "Untested" because of internal error in gsec while creating user 'test' from resource).
# # Checked on WI-V2.5.5.26952 (SC), WI-V3.0.0.32266 (SS/SC/CS).
#
#
# import os
# import subprocess
# import time
#
#
# # Obtain engine version:
# engine = str(db_conn.engine_version)
#
#
# db_conn.execute_immediate("create user tmp$c1148 password 'QweRtyUi'")
# db_conn.commit()
#
#
# if engine.startswith('2.5'):
# get_firebird_log_key='action_get_ib_log'
# else:
# get_firebird_log_key='action_get_fb_log'
#
#
# fn_nul = open(os.devnull, 'w')
# fn_err=open( os.path.join(context['temp_directory'],'tmp_1148_get_fb_log.err'), 'w')
# subprocess.call([ context['fbsvcmgr_path'],
# "localhost:service_mgr",
# "user","TMP$C1148","password","QweRtyUi",
# "user","TMP$C1148","password","QweRtyUi",
# get_firebird_log_key
# ],
# stdout=fn_nul,
@ -66,12 +69,12 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# )
# fn_nul.close()
# fn_err.close()
#
#
# # CLEANUP: drop user that was temp-ly created for this test:
# ##########
# db_conn.execute_immediate('drop user tmp$c1148')
# db_conn.commit()
#
#
# # Ouput error log: it should contain text about unable to perform operation.
# # NB: text in FB 4.0 was splitted, phrase "You must have SYSDBA rights..." is
# # printed on separate line. Checking for matching to this phrase can be skipped
@ -79,25 +82,26 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# with open( fn_err.name,'r') as f:
# for line in f:
# print("STDERR: "+line.upper())
#
# # Do not remove this pause: on Windows closing of handles can take some (small) time.
#
# # Do not remove this pause: on Windows closing of handles can take some (small) time.
# # Otherwise Windows(32) access error can raise here.
# time.sleep(1)
#
#
# if os.path.isfile(fn_err.name):
# os.remove(fn_err.name)
#
#
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
STDERR: UNABLE TO PERFORM OPERATION
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
user_1 = temp_user(name='TMP$C1148', password='QweRtyUi')
@pytest.mark.version('>=2.5')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action, user_1: User):
with act_1.connect_server(user=user_1.name, password=user_1.password) as srv:
with pytest.raises(DatabaseError, match='Unable to perform operation\n-You must have SYSDBA rights at this server'):
srv.info.get_log()

View File

@ -2,14 +2,14 @@
#
# id: bugs.core_1156
# title: Prepare fails when having a parameter in a DSQL statement before a sub query
# decription:
# decription:
# tracker_id: CORE-1156
# min_versions: []
# versions: 2.1
# qmid: bugs.core_1156
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 2.1
# resources: None
@ -27,34 +27,52 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# c.prep('select count(*) from rdb$database where ? < (select count(*) from rdb$database)')
# except:
# print ('Test FAILED in case 1')
#
#
# try:
# c.prep('select count(*) from rdb$database where (select count(*) from rdb$database) > ?')
# except:
# print ('Test FAILED in case 2')
#
#
# try:
# c.prep('select count(*) from rdb$database where ? < cast ((select count(*) from rdb$database) as integer)')
# except:
# print ('Test FAILED in case 3')
#
#
# try:
# c.prep('select count(*) from rdb$database where 0 < (select count(*) from rdb$database)')
# except:
# print ('Test FAILED in case 4')
#
#
# try:
# c.prep('select count(*) from rdb$database where cast (? as integer) < (select count(*) from rdb$database)')
# except:
# print ('Test FAILED in case 5')
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=2.1')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.db.connect() as con:
c = con.cursor()
try:
c.prepare('select count(*) from rdb$database where ? < (select count(*) from rdb$database)')
except:
pytest.fail('Test FAILED in case 1')
try:
c.prepare('select count(*) from rdb$database where (select count(*) from rdb$database) > ?')
except:
pytest.fail('Test FAILED in case 2')
try:
c.prepare('select count(*) from rdb$database where ? < cast ((select count(*) from rdb$database) as integer)')
except:
pytest.fail('Test FAILED in case 3')
try:
c.prepare('select count(*) from rdb$database where 0 < (select count(*) from rdb$database)')
except:
pytest.fail('Test FAILED in case 4')
try:
c.prepare('select count(*) from rdb$database where cast (? as integer) < (select count(*) from rdb$database)')
except:
pytest.fail('Test FAILED in case 5')

View File

@ -2,30 +2,30 @@
#
# id: bugs.core_1175
# title: Error "Data type unknown" when any UDF argument is a built-in function containing a DSQL parameter reference
# decription:
# decription:
# For FB 2.5 and 3.x - this test uses UDF from ib_udf.
#
#
# 24.01.2019. Added separate code for running on FB 4.0+.
# UDF usage is deprecated in FB 4+, see: ".../doc/README.incompatibilities.3to4.txt".
# Functions div, frac, dow, sdow, getExactTimestampUTC and isLeapYear got safe replacement
# Functions div, frac, dow, sdow, getExactTimestampUTC and isLeapYear got safe replacement
# in UDR library "udf_compat", see it in folder: ../plugins/udr/
#
#
# Checked on:
# 4.0.0.1340: OK, 2.594s.
# 4.0.0.1378: OK, 5.579s.
#
#
# NOTE. Build 4.0.0.1172 (date: 25.08.2018) raises here:
# SQLCODE: -902... expression evaluation not supported...
# SQLCODE: -902... expression evaluation not supported...
# Invalid data type for division in dialect 3
# gdscode = 335544569.
#
#
# tracker_id: CORE-1175
# min_versions: []
# versions: 4.0
# qmid: bugs.core_1175
import pytest
from firebird.qa import db_factory, isql_act, Action
from firebird.qa import db_factory, python_act, Action
# version: 4.0
# resources: None
@ -62,17 +62,18 @@ db_1 = db_factory(sql_dialect=3, init=init_script_1)
# except Exception,e:
# print( 'Test FAILED!' )
# print( e )
#
#
#---
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
Test PASSED!
"""
act_1 = python_act('db_1', substitutions=substitutions_1)
@pytest.mark.version('>=4.0')
@pytest.mark.xfail
def test_1(db_1):
pytest.fail("Test not IMPLEMENTED")
def test_1(act_1: Action):
with act_1.db.connect() as con:
c = con.cursor()
try:
c.prepare('select 1 from rdb$database where UDR40_frac(?) != UDR40_div(?, ?) / ?')
except:
pytest.fail('Test FAILED')