6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-02-02 02:40:42 +01:00

Added/Updated functional\trigger\database\test_connect_04.py: Checked on: 3.0.8.33535, 4.0.1.2692, 5.0.0.497

This commit is contained in:
zotov 2022-05-26 13:21:29 +03:00
parent 5e6f7c15cf
commit a0a57a07e2

View File

@ -1,90 +1,140 @@
#coding:utf-8
"""
ID: trigger.database.connect-04
TITLE: Error handling in trigger on database connect - multiple triggers.
ID: trigger.database.connect-02
TITLE: Error handling when multiple triggers on database connect exist
DESCRIPTION:
This test verifies the proper error handling. Uncaught exceptions in trigger roll back
the transaction, disconnect the attachment and are returned to the client. Because this
test is implemented in Python, our test support class creates a database connection for
our test code (db_conn) that attach to the database without role specification. We verify
that this connection was properly logged for convenience.
FBTEST: functional.trigger.database.connect_04
Test behavoiur when MULTIPLE db-level triggers on CONNECT exist:
first uncaught exception in the trigger declared with attribute 'position N'
must prevent execution of any subsequent triggers (i.e. with position > N);
FBTEST: functional.trigger.database.connect_02
NOTES:
[26.05.2022] pzotov
Re-implemented for work in firebird-qa suite.
Checked on: 3.0.8.33535, 4.0.1.2692, 5.0.0.497
"""
import pytest
from firebird.qa import *
init_script = """create table LOG (ID integer, MSG varchar(100));
create generator LOGID;
create exception CONNECTERROR 'Exception in ON CONNECT trigger';
create role TEST;
grant TEST to PUBLIC;
set term ^;
create trigger LOG_BI for LOG active before insert position 0
as
begin
if (new.ID is null) then
new.ID = gen_id(LOGID,1);
end ^
create trigger ONCONNECT_1 on connect position 0
as
begin
insert into LOG (MSG) values ('Connect T1 as ' || current_role);
end ^
create trigger ONCONNECT_2 on connect position 0
as
begin
insert into LOG (MSG) values ('Connect T2 as ' || current_role);
if (current_role ='TEST') then
exception CONNECTERROR;
end ^
create trigger ONCONNECT_3 on connect position 20
as
begin
insert into LOG (MSG) values ('Connect T3 as ' || current_role);
end ^
set term ;^
commit;
"""
db = db_factory(init=init_script)
db = db_factory()
tmp_worker = user_factory('db', name='tmp_worker', password='123')
tmp_hacker = user_factory('db', name='tmp_hacker', password='456')
act = python_act('db', substitutions=[('line:.*', '')])
expected_stdout = """Error while connecting to database:
- SQLCODE: -836
- exception 1
- CONNECTERROR
- Exception in ON CONNECT trigger
- At trigger 'ONCONNECT_2' line: 5, col: 29
-836
335544517
ID MSG
----------- ----------------------------------------------------------------------------------------------------
1 Connect T1 as NONE
2 Connect T2 as NONE
3 Connect T3 as NONE
"""
@pytest.mark.skip('FIXME: Not IMPLEMENTED')
@pytest.mark.version('>=3.0')
def test_1(act: Action):
pytest.fail("Not IMPLEMENTED")
def test_1(act: Action, tmp_worker: User, tmp_hacker: User):
# Original python code for this test:
# -----------------------------------
# try:
# con = kdb.connect(dsn=dsn.encode(),user=user_name.encode(),password=user_password.encode(),role='TEST')
# except Exception,e:
# for msg in e: print (msg)
#
# c = db_conn.cursor()
# c.execute('select * from LOG')
# printData(c)
# -----------------------------------
expected_stdout = f"""
Statement failed, SQLSTATE = HY000
exception 1
-EXC_CONNECT
-Exception in ON CONNECT trigger trg_connect_1 for user {tmp_hacker.name}
-At trigger 'TRG_CONNECT_1'
ID 1
AUDIT_WHO {tmp_worker.name}
TRG_NAME trg_connect_1
ID 2
AUDIT_WHO {tmp_worker.name}
TRG_NAME trg_connect_2
ID 3
AUDIT_WHO {tmp_worker.name}
TRG_NAME trg_connect_3
ID 4
AUDIT_WHO {tmp_hacker.name}
TRG_NAME trg_connect_1
Records affected: 4
ID 1
SESSION_WHO {tmp_worker.name}
TRG_NAME trg_connect_1
ID 2
SESSION_WHO {tmp_worker.name}
TRG_NAME trg_connect_2
ID 3
SESSION_WHO {tmp_worker.name}
TRG_NAME trg_connect_3
Records affected: 3
"""
script = f"""
create table sessions_in_work(
id int generated by default as identity constraint pk_ssn_in_work primary key
,session_who varchar(31) default current_user
,trg_name varchar(31)
);
create table sessions_audit(
id int generated by default as identity constraint pk_ssn_audit primary key
,audit_who varchar(31) default current_user
,trg_name varchar(31)
);
create exception exc_connect 'Exception in ON CONNECT trigger @1 for user @2';
set term ^;
create trigger trg_connect_1 on connect position 1 as
begin
if ( current_user = '{act.db.user}' ) then
exit;
in autonomous transaction do
insert into sessions_audit(trg_name) values('trg_connect_1');
insert into sessions_in_work(trg_name) values('trg_connect_1');
if ( current_user = upper('{tmp_hacker.name}') ) then
exception exc_connect using('trg_connect_1', current_user);
end
^
----------------------------------------------------------------------
create trigger trg_connect_2 on connect position 2 as
begin
if ( current_user = '{act.db.user}' ) then
exit;
in autonomous transaction do
insert into sessions_audit(trg_name) values('trg_connect_2');
insert into sessions_in_work(trg_name) values('trg_connect_2');
if ( current_user = upper('{tmp_hacker.name}') ) then
exception exc_connect using('trg_connect_2', current_user);
end
^
----------------------------------------------------------------------
create trigger trg_connect_3 on connect position 3 as
begin
if ( current_user = '{act.db.user}' ) then
exit;
in autonomous transaction do
insert into sessions_audit(trg_name) values('trg_connect_3');
insert into sessions_in_work(trg_name) values('trg_connect_3');
if ( current_user = upper('{tmp_hacker.name}') ) then
exception exc_connect using('trg_connect_3', current_user);
end
^
set term ;^
commit;
-----------------------------------------------------
connect '{act.db.dsn}' user '{tmp_worker.name}' password '{tmp_worker.password}';
commit;
connect '{act.db.dsn}' user '{tmp_hacker.name}' password '{tmp_hacker.password}';
commit;
-----------------------------------------------------
-- Connect as DBA for obtaining results:
connect '{act.db.dsn}' user '{act.db.user}' password '{act.db.password}';
set list on;
set count on;
select * from sessions_audit;
select * from sessions_in_work;
"""
act.expected_stdout = expected_stdout
act.isql(switches=['-q'], input = script, combine_output=True)
assert act.clean_stdout == act.clean_expected_stdout