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:
parent
8166fbdb36
commit
7eb6992fd5
@ -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()
|
||||
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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")
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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')
|
||||
|
||||
|
||||
|
||||
|
@ -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.')
|
||||
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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',)]
|
||||
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
||||
|
||||
|
@ -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')
|
||||
|
@ -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')
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user