Show firebird.log [FOUND messages for interval when this test was running]
Jump to: output_first_mismatch    outcomes_full_history    elapsed_time_chart
Show cross-report outcomes.

Annotation type Annotation details
2 @message
firebird.driver.types.DatabaseError: I/O error during "lock" operation for file "/home/fbqa/qa-2024/unpacked-snapshot.tmp/examples/empbuild/qa/tmp_gh_8429_c.fdb"
-Database already opened with engine instance, incompatible with current

LOG DETAILS:

2025-02-25 12:45:21.868
2025-02-25 12:45:21.876 act_a = <firebird.qa.plugin.Action object at [hex]>
2025-02-25 12:45:21.883 act_b = <firebird.qa.plugin.Action object at [hex]>
2025-02-25 12:45:21.898 act_c = <firebird.qa.plugin.Action object at [hex]>
2025-02-25 12:45:21.908 usr_x = <firebird.qa.plugin.User object at [hex]>
2025-02-25 12:45:21.914 usr_y = <firebird.qa.plugin.User object at [hex]>
2025-02-25 12:45:21.921 usr_z = <firebird.qa.plugin.User object at [hex]>
2025-02-25 12:45:21.927 capsys = <_pytest.capture.CaptureFixture object at [hex]>
2025-02-25 12:45:21.933
2025-02-25 12:45:21.940 @pytest.mark.es_eds
2025-02-25 12:45:21.947 @pytest.mark.encryption
2025-02-25 12:45:21.953 @pytest.mark.version('>=4.0.6')
2025-02-25 12:45:21.960 def test_1(act_a: Action, act_b: Action, act_c: Action, usr_x: User, usr_y: User, usr_z: User, capsys):
2025-02-25 12:45:21.966
2025-02-25 12:45:21.973 dbfile_a = get_filename_by_alias(act_a)
2025-02-25 12:45:21.980 dbfile_b = get_filename_by_alias(act_b)
2025-02-25 12:45:21.986 dbfile_c = get_filename_by_alias(act_c)
2025-02-25 12:45:22.002
2025-02-25 12:45:22.013 dbfile_a.unlink(missing_ok = True)
2025-02-25 12:45:22.023 dbfile_b.unlink(missing_ok = True)
2025-02-25 12:45:22.031 dbfile_c.unlink(missing_ok = True)
2025-02-25 12:45:22.039
2025-02-25 12:45:22.046 with create_database(act_a.db.db_path, user = act_a.db.user, password = act_a.db.password) as con_a, \
2025-02-25 12:45:22.055 create_database(act_b.db.db_path, user = act_b.db.user, password = act_b.db.password) as con_b, \
2025-02-25 12:45:22.070 create_database(act_c.db.db_path, user = act_c.db.user, password = act_c.db.password) as con_c:
2025-02-25 12:45:22.079
2025-02-25 12:45:22.088 sql = f"""
2025-02-25 12:45:22.101 create procedure sp_a (a_who varchar(31)) returns (o_info varchar(512)) as
2025-02-25 12:45:22.114 begin
2025-02-25 12:45:22.127 -- e1-meta.sql:
2025-02-25 12:45:22.138 execute statement 'select * from sp_b(''' || a_who || ''')' as user '{usr_x.name}' password '{usr_x.password}' on external 'gh_8429_alias_b' into o_info;
2025-02-25 12:45:22.148 suspend;
2025-02-25 12:45:22.156 end
2025-02-25 12:45:22.163 ^
2025-02-25 12:45:22.169 grant execute on procedure sp_a to public
2025-02-25 12:45:22.175 ^
2025-02-25 12:45:22.182 alter database set linger to 0
2025-02-25 12:45:22.192 ^
2025-02-25 12:45:22.205 """
2025-02-25 12:45:22.217 for x in sql.split('^'):
2025-02-25 12:45:22.228 if (s := x.strip()):
2025-02-25 12:45:22.237 con_a.execute_immediate(s)
2025-02-25 12:45:22.246 con_a.commit()
2025-02-25 12:45:22.255
2025-02-25 12:45:22.268 # ..................................................
2025-02-25 12:45:22.276
2025-02-25 12:45:22.283 sql = f"""
2025-02-25 12:45:22.290 create procedure sp_b (a_who varchar(31)) returns (o_info varchar(512)) as
2025-02-25 12:45:22.297 begin
2025-02-25 12:45:22.308 execute statement 'select * from sp_c' as user a_who password a_who on external 'gh_8429_alias_c' into o_info;
2025-02-25 12:45:22.322 suspend;
2025-02-25 12:45:22.331 end
2025-02-25 12:45:22.340 ^
2025-02-25 12:45:22.347 grant execute on procedure sp_b to public
2025-02-25 12:45:22.354 ^
2025-02-25 12:45:22.361 alter database set linger to 0
2025-02-25 12:45:22.369 ^
2025-02-25 12:45:22.380 """
2025-02-25 12:45:22.393 for x in sql.split('^'):
2025-02-25 12:45:22.408 if (s := x.strip()):
2025-02-25 12:45:22.421 con_b.execute_immediate(s)
2025-02-25 12:45:22.433 con_b.commit()
2025-02-25 12:45:22.446
2025-02-25 12:45:22.455 # ..................................................
2025-02-25 12:45:22.462
2025-02-25 12:45:22.468 sql = f"""
2025-02-25 12:45:22.476 create procedure sp_c returns (o_info varchar(512)) as
2025-02-25 12:45:22.485 begin
2025-02-25 12:45:22.491 o_info = lower(current_user);
2025-02-25 12:45:22.498 -- o_info = lower(rdb$get_context('SYSTEM', 'DB_NAME')) || ':' || lower(current_user);
2025-02-25 12:45:22.503 suspend;
2025-02-25 12:45:22.508 end
2025-02-25 12:45:22.519 ^
2025-02-25 12:45:22.531 grant execute on procedure sp_c to public
2025-02-25 12:45:22.539 ^
2025-02-25 12:45:22.547 alter database set linger to 0
2025-02-25 12:45:22.561 ^
2025-02-25 12:45:22.577 """
2025-02-25 12:45:22.586 for x in sql.split('^'):
2025-02-25 12:45:22.601 if (s := x.strip()):
2025-02-25 12:45:22.611 con_c.execute_immediate(s)
2025-02-25 12:45:22.619 con_c.commit()
2025-02-25 12:45:22.628
2025-02-25 12:45:22.640 ############################################
2025-02-25 12:45:22.649 ###   E N C R Y P T    D A T A B A S E   ###
2025-02-25 12:45:22.657 ############################################
2025-02-25 12:45:22.664 >           run_encr_decr(act_c, 'encrypt', MAX_WAITING_ENCR_FINISH, capsys)
2025-02-25 12:45:22.673
2025-02-25 12:45:22.681 tests/bugs/gh_8429_test.py:272:
2025-02-25 12:45:22.688 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-02-25 12:45:22.695
2025-02-25 12:45:22.708 act = <firebird.qa.plugin.Action object at [hex]>, mode = 'encrypt'
2025-02-25 12:45:22.719 max_wait_encr_thread_finish = 10000
2025-02-25 12:45:22.729 capsys = <_pytest.capture.CaptureFixture object at [hex]>
2025-02-25 12:45:22.746
2025-02-25 12:45:22.759 def run_encr_decr(act: Action, mode, max_wait_encr_thread_finish, capsys):
2025-02-25 12:45:22.767 if mode == 'encrypt':
2025-02-25 12:45:22.780 # See letter from Alex, 15.12.2023 16:16 demo-plugin can not transfer named key over network.
2025-02-25 12:45:22.791 # Because of that, we have to use 'ALTER DATABASE ENCRYPT WITH <plugin>'  _WITHOUT_ adding 'key "{ENCRYPTION_KEY}"'.
2025-02-25 12:45:22.805 # ::: NB ::: One need to be sure that $FB_HOME/plugins.conf contains following lines:
2025-02-25 12:45:22.813 # Plugin = KH2 {
2025-02-25 12:45:22.821 #     Module = $(dir_plugins)/fbSampleKeyHolder
2025-02-25 12:45:22.827 #     RegisterName = fbSampleKeyHolder
2025-02-25 12:45:22.833 #     Config = KH2
2025-02-25 12:45:22.838 # }
2025-02-25 12:45:22.845 #  Config = KH2 {
2025-02-25 12:45:22.850 #     Auto = false
2025-02-25 12:45:22.859 # }
2025-02-25 12:45:22.868 # Otherwise error will raise:
2025-02-25 12:45:22.881 # unsuccessful metadata update
2025-02-25 12:45:22.894 # -ALTER DATABASE failed
2025-02-25 12:45:22.908 # -Missing database encryption key for your attachment
2025-02-25 12:45:22.920 # -Plugin fbSampleDbCrypt:
2025-02-25 12:45:22.928 # -Crypt key not set
2025-02-25 12:45:22.935 #
2025-02-25 12:45:22.942 alter_db_sttm = f'alter database encrypt with "{ENCRYPTION_PLUGIN}"' # <<< ::: NB ::: DO NOT add '... key "{ENCRYPTION_KEY}"' here!
2025-02-25 12:45:22.949 wait_for_state = 'Database encrypted'
2025-02-25 12:45:22.955 elif mode == 'decrypt':
2025-02-25 12:45:22.961 alter_db_sttm = 'alter database decrypt'
2025-02-25 12:45:22.968 wait_for_state = 'Database not encrypted'
2025-02-25 12:45:22.977
2025-02-25 12:45:22.984
2025-02-25 12:45:22.991 e_thread_finished = False
2025-02-25 12:45:22.997
2025-02-25 12:45:23.004 # 0 = non crypted;
2025-02-25 12:45:23.011 # 1 = has been encrypted;
2025-02-25 12:45:23.029 # 2 = is DEcrypting;
2025-02-25 12:45:23.039 # 3 = is Encrypting;
2025-02-25 12:45:23.048 #
2025-02-25 12:45:23.056 REQUIRED_CRYPT_STATE = 1 if mode == 'encrypt' else 0
2025-02-25 12:45:23.062 current_crypt_state = -1
2025-02-25 12:45:23.069 d1 = py_dt.timedelta(0)
2025-02-25 12:45:23.077 >       with act.db.connect() as con:
2025-02-25 12:45:23.084
2025-02-25 12:45:23.092 tests/bugs/gh_8429_test.py:147:
2025-02-25 12:45:23.098 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-02-25 12:45:23.104
2025-02-25 12:45:23.110 database = 'gh_8429_alias_c'
2025-02-25 12:45:23.116
2025-02-25 12:45:23.124 def connect(database: str, *, user: str=None, password: str=None, role: str=None,
2025-02-25 12:45:23.139 no_gc: bool=None, no_db_triggers: bool=None, dbkey_scope: DBKeyScope=None,
2025-02-25 12:45:23.149 crypt_callback: iCryptKeyCallbackImpl=None, charset: str=None,
2025-02-25 12:45:23.161 auth_plugin_list: str=None, session_time_zone: str=None) -> Connection:
2025-02-25 12:45:23.167 """Establishes a connection to the database.
2025-02-25 12:45:23.175
2025-02-25 12:45:23.186 Arguments:
2025-02-25 12:45:23.199 database: DSN or Database configuration name.
2025-02-25 12:45:23.211 user: User name.
2025-02-25 12:45:23.223 password: User password.
2025-02-25 12:45:23.236 role: User role.
2025-02-25 12:45:23.245 no_gc: Do not perform garbage collection for this connection.
2025-02-25 12:45:23.260 no_db_triggers: Do not execute database triggers for this connection.
2025-02-25 12:45:23.273 dbkey_scope: DBKEY scope override for connection.
2025-02-25 12:45:23.283 crypt_callback: Callback that provides encryption key for the database.
2025-02-25 12:45:23.297 charset: Character set for connection.
2025-02-25 12:45:23.308 auth_plugin_list: List of authentication plugins override
2025-02-25 12:45:23.317 session_time_zone: Session time zone [Firebird 4]
2025-02-25 12:45:23.330
2025-02-25 12:45:23.340 Hooks:
2025-02-25 12:45:23.350 Event `.ConnectionHook.ATTACH_REQUEST`: Executed after all parameters
2025-02-25 12:45:23.361 are preprocessed and before `Connection` is created. Hook
2025-02-25 12:45:23.372 must have signature::
2025-02-25 12:45:23.382
2025-02-25 12:45:23.390 hook_func(dsn: str, dpb: bytes) -> Optional[Connection]
2025-02-25 12:45:23.403
2025-02-25 12:45:23.417 Hook may return `Connection` instance or None.
2025-02-25 12:45:23.433 First instance returned by any hook will become the return value
2025-02-25 12:45:23.443 of this function and other hooks are not called.
2025-02-25 12:45:23.451
2025-02-25 12:45:23.459 Event `.ConnectionHook.ATTACHED`: Executed before `Connection` instance is
2025-02-25 12:45:23.466 returned. Hook must have signature::
2025-02-25 12:45:23.478
2025-02-25 12:45:23.490 hook_func(connection: Connection) -> None
2025-02-25 12:45:23.501
2025-02-25 12:45:23.515 Any value returned by hook is ignored.
2025-02-25 12:45:23.526 """
2025-02-25 12:45:23.537 db_config = driver_config.get_database(database)
2025-02-25 12:45:23.547 if db_config is None:
2025-02-25 12:45:23.563 db_config = driver_config.db_defaults
2025-02-25 12:45:23.572 else:
2025-02-25 12:45:23.580 database = db_config.database.value
2025-02-25 12:45:23.587 if db_config.server.value is None:
2025-02-25 12:45:23.598 srv_config = driver_config.server_defaults
2025-02-25 12:45:23.612 else:
2025-02-25 12:45:23.623 srv_config = driver_config.get_server(db_config.server.value)
2025-02-25 12:45:23.635 if srv_config is None:
2025-02-25 12:45:23.647 raise ValueError(f"Configuration for server '{db_config.server.value}' not found")
2025-02-25 12:45:23.657 if user is None:
2025-02-25 12:45:23.665 user = db_config.user.value
2025-02-25 12:45:23.672 if user is None:
2025-02-25 12:45:23.681 user = srv_config.user.value
2025-02-25 12:45:23.695 if password is None:
2025-02-25 12:45:23.708 password = db_config.password.value
2025-02-25 12:45:23.718 if password is None:
2025-02-25 12:45:23.731 password = srv_config.password.value
2025-02-25 12:45:23.738 if role is None:
2025-02-25 12:45:23.745 role = db_config.role.value
2025-02-25 12:45:23.754 if charset is None:
2025-02-25 12:45:23.767 charset = db_config.charset.value
2025-02-25 12:45:23.776 if charset:
2025-02-25 12:45:23.786 charset = charset.upper()
2025-02-25 12:45:23.795 if auth_plugin_list is None:
2025-02-25 12:45:23.806 auth_plugin_list = db_config.auth_plugin_list.value
2025-02-25 12:45:23.820 if session_time_zone is None:
2025-02-25 12:45:23.829 session_time_zone = db_config.session_time_zone.value
2025-02-25 12:45:23.836 dsn = _connect_helper(db_config.dsn.value, srv_config.host.value, srv_config.port.value,
2025-02-25 12:45:23.855 database, db_config.protocol.value)
2025-02-25 12:45:23.864 dpb = DPB(user=user, password=password, role=role, trusted_auth=db_config.trusted_auth.value,
2025-02-25 12:45:23.874 sql_dialect=db_config.sql_dialect.value, timeout=db_config.timeout.value,
2025-02-25 12:45:23.883 charset=charset, cache_size=db_config.cache_size.value,
2025-02-25 12:45:23.892 no_linger=db_config.no_linger.value, utf8filename=db_config.utf8filename.value,
2025-02-25 12:45:23.900 no_gc=no_gc, no_db_triggers=no_db_triggers, dbkey_scope=dbkey_scope,
2025-02-25 12:45:23.907 dummy_packet_interval=db_config.dummy_packet_interval.value,
2025-02-25 12:45:23.913 config=db_config.config.value, auth_plugin_list=auth_plugin_list,
2025-02-25 12:45:23.919 session_time_zone=session_time_zone, set_bind=db_config.set_bind.value,
2025-02-25 12:45:23.925 decfloat_round=db_config.decfloat_round.value,
2025-02-25 12:45:23.931 decfloat_traps=db_config.decfloat_traps.value,
2025-02-25 12:45:23.937 parallel_workers=db_config.parallel_workers.value)
2025-02-25 12:45:23.954 >       return __make_connection(False, dsn, db_config.utf8filename.value, dpb.get_buffer(),
2025-02-25 12:45:23.968 db_config.sql_dialect.value, charset, crypt_callback)
2025-02-25 12:45:23.981
2025-02-25 12:45:23.991 ../lib/python3.11/site-packages/firebird/driver/core.py:2149:
2025-02-25 12:45:24.003 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-02-25 12:45:24.012
2025-02-25 12:45:24.019 create = False, dsn = 'localhost/3716:gh_8429_alias_c', utf8filename = False
2025-02-25 12:45:24.030 dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x00', sql_dialect = 3
2025-02-25 12:45:24.041 charset = None, crypt_callback = None
2025-02-25 12:45:24.055
2025-02-25 12:45:24.066 def __make_connection(create: bool, dsn: str, utf8filename: bool, dpb: bytes,
2025-02-25 12:45:24.080 sql_dialect: int, charset: str,
2025-02-25 12:45:24.091 crypt_callback: iCryptKeyCallbackImpl) -> Connection:
2025-02-25 12:45:24.101 with a.get_api().master.get_dispatcher() as provider:
2025-02-25 12:45:24.116 if crypt_callback is not None:
2025-02-25 12:45:24.127 provider.set_dbcrypt_callback(crypt_callback)
2025-02-25 12:45:24.134 if create:
2025-02-25 12:45:24.140 att = provider.create_database(dsn, dpb, 'utf-8' if utf8filename else FS_ENCODING)
2025-02-25 12:45:24.148 con = Connection(att, dsn, dpb, sql_dialect, charset)
2025-02-25 12:45:24.155 else:
2025-02-25 12:45:24.162 con = None
2025-02-25 12:45:24.174 for hook in get_callbacks(ConnectionHook.ATTACH_REQUEST, Connection):
2025-02-25 12:45:24.180 try:
2025-02-25 12:45:24.191 con = hook(dsn, dpb)
2025-02-25 12:45:24.202 except Exception as e:
2025-02-25 12:45:24.212 raise InterfaceError("Error in DATABASE_ATTACH_REQUEST hook.", *e.args) from e
2025-02-25 12:45:24.226 if con is not None:
2025-02-25 12:45:24.235 break
2025-02-25 12:45:24.243 if con is None:
2025-02-25 12:45:24.251 >                   att = provider.attach_database(dsn, dpb, 'utf-8' if utf8filename else FS_ENCODING)
2025-02-25 12:45:24.257
2025-02-25 12:45:24.270 ../lib/python3.11/site-packages/firebird/driver/core.py:2064:
2025-02-25 12:45:24.285 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-02-25 12:45:24.298
2025-02-25 12:45:24.312 self = <firebird.driver.interfaces.iProvider object at [hex]>
2025-02-25 12:45:24.325 filename = 'localhost/3716:gh_8429_alias_c'
2025-02-25 12:45:24.334 dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x00'
2025-02-25 12:45:24.344 encoding = 'utf-8'
2025-02-25 12:45:24.353
2025-02-25 12:45:24.367 def attach_database(self, filename: str, dpb: Optional[bytes] = None, encoding: str = 'ascii') -> iAttachment:
2025-02-25 12:45:24.377 "Replaces `isc_attach_database()`"
2025-02-25 12:45:24.385 result = self.vtable.attachDatabase(self, self.status, filename.encode(encoding),
2025-02-25 12:45:24.393 0 if dpb is None else len(dpb), dpb)
2025-02-25 12:45:24.400 >       self._check()
2025-02-25 12:45:24.407
2025-02-25 12:45:24.415 ../lib/python3.11/site-packages/firebird/driver/interfaces.py:1295:
2025-02-25 12:45:24.428 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-02-25 12:45:24.440
2025-02-25 12:45:24.452 self = <firebird.driver.interfaces.iProvider object at [hex]>
2025-02-25 12:45:24.464
2025-02-25 12:45:24.473 def _check(self) -> None:
2025-02-25 12:45:24.480 state = self.status.get_state()
2025-02-25 12:45:24.487 if StateFlag.ERRORS in state:
2025-02-25 12:45:24.494 >           raise self.__report(DatabaseError, self.status.get_errors())
2025-02-25 12:45:24.506 E           firebird.driver.types.DatabaseError: I/O error during "lock" operation for file "/home/fbqa/qa-2024/unpacked-snapshot.tmp/examples/empbuild/qa/tmp_gh_8429_c.fdb"
2025-02-25 12:45:24.520 E           -Database already opened with engine instance, incompatible with current
2025-02-25 12:45:24.534
2025-02-25 12:45:24.542 ../lib/python3.11/site-packages/firebird/driver/interfaces.py:113: DatabaseError
2025-02-25 12:45:24.551 ---------------------------- Captured stdout setup -----------------------------
2025-02-25 12:45:24.567 Creating db: localhost:/var/tmp/qa_2024/test_11683/test.fdb [page_size=None, sql_dialect=None, charset='NONE', user=SYSDBA, password=masterkey]
2025-02-25 12:45:24.579 CREATE user: TMP_8429_X PLUGIN: Srp
2025-02-25 12:45:24.590 CREATE user: TMP_8429_Y PLUGIN: Srp
2025-02-25 12:45:24.604 CREATE user: TMP_8429_Z PLUGIN: Srp
2025-02-25 12:45:24.615 --------------------------- Captured stdout teardown ---------------------------
2025-02-25 12:45:24.626 DROP user: TMP_8429_Z PLUGIN: Srp
2025-02-25 12:45:24.635 DROP user: TMP_8429_Y PLUGIN: Srp
2025-02-25 12:45:24.643 DROP user: TMP_8429_X PLUGIN: Srp
3 #text
act_a = <firebird.qa.plugin.Action pytest object at [hex]>
act_b = <firebird.qa.plugin.Action pytest object at [hex]>
act_c = <firebird.qa.plugin.Action pytest object at [hex]>
usr_x = <firebird.qa.plugin.User pytest object at [hex]>
usr_y = <firebird.qa.plugin.User pytest object at [hex]>
usr_z = <firebird.qa.plugin.User pytest object at [hex]>
capsys = <_pytest.capture.CaptureFixture pytest object at [hex]>

    @pytest.mark.es_eds
    @pytest.mark.encryption
    @pytest.mark.version('>=4.0.6')
    def test_1(act_a: Action, act_b: Action, act_c: Action, usr_x: User, usr_y: User, usr_z: User, capsys):
    
        dbfile_a = get_filename_by_alias(act_a)
        dbfile_b = get_filename_by_alias(act_b)
        dbfile_c = get_filename_by_alias(act_c)
    
        dbfile_a.unlink(missing_ok = True)
        dbfile_b.unlink(missing_ok = True)
        dbfile_c.unlink(missing_ok = True)
    
        with create_database(act_a.db.db_path, user = act_a.db.user, password = act_a.db.password) as con_a, \
            create_database(act_b.db.db_path, user = act_b.db.user, password = act_b.db.password) as con_b, \
            create_database(act_c.db.db_path, user = act_c.db.user, password = act_c.db.password) as con_c:
    
            sql = f"""
                create procedure sp_a (a_who varchar(31)) returns (o_info varchar(512)) as
                begin
                    -- e1-meta.sql:
                    execute statement 'select * from sp_b(''' || a_who || ''')' as user '{usr_x.name}' password '{usr_x.password}' on external 'gh_8429_alias_b' into o_info;
                    suspend;
                end
                ^
                grant execute on procedure sp_a to public
                ^
                alter database set linger to 0
                ^
            """
            for x in sql.split('^'):
                if (s := x.strip()):
                    con_a.execute_immediate(s)
            con_a.commit()
    
            # ..................................................
    
            sql = f"""
                create procedure sp_b (a_who varchar(31)) returns (o_info varchar(512)) as
                begin
                    execute statement 'select * from sp_c' as user a_who password a_who on external 'gh_8429_alias_c' into o_info;
                    suspend;
                end
                ^
                grant execute on procedure sp_b to public
                ^
                alter database set linger to 0
                ^
            """
            for x in sql.split('^'):
                if (s := x.strip()):
                    con_b.execute_immediate(s)
            con_b.commit()
    
            # ..................................................
    
            sql = f"""
                create procedure sp_c returns (o_info varchar(512)) as
                begin
                    o_info = lower(current_user);
                    -- o_info = lower(rdb$get_context('SYSTEM', 'DB_NAME')) || ':' || lower(current_user);
                    suspend;
                end
                ^
                grant execute on procedure sp_c to public
                ^
                alter database set linger to 0
                ^
            """
            for x in sql.split('^'):
                if (s := x.strip()):
                    con_c.execute_immediate(s)
            con_c.commit()
    
            ############################################
            ###   E N C R Y P T    D A T A B A S E   ###
            ############################################
>           run_encr_decr(act_c, 'encrypt', MAX_WAITING_ENCR_FINISH, capsys)

tests/bugs/gh_8429_test.py:272: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

act = <firebird.qa.plugin.Action pytest object at [hex]>, mode = 'encrypt'
max_wait_encr_thread_finish = 10000
capsys = <_pytest.capture.CaptureFixture pytest object at [hex]>

    def run_encr_decr(act: Action, mode, max_wait_encr_thread_finish, capsys):
        if mode == 'encrypt':
            # See letter from Alex, 15.12.2023 16:16 demo-plugin can not transfer named key over network.
            # Because of that, we have to use 'ALTER DATABASE ENCRYPT WITH <plugin>'  _WITHOUT_ adding 'key "{ENCRYPTION_KEY}"'.
            # ::: NB ::: One need to be sure that $FB_HOME/plugins.conf contains following lines:
            # Plugin = KH2 {
            #     Module = $(dir_plugins)/fbSampleKeyHolder
            #     RegisterName = fbSampleKeyHolder
            #     Config = KH2
            # }
            #  Config = KH2 {
            #     Auto = false
            # }
            # Otherwise error will raise:
            # unsuccessful metadata update
            # -ALTER DATABASE failed
            # -Missing database encryption key for your attachment
            # -Plugin fbSampleDbCrypt:
            # -Crypt key not set
            #
            alter_db_sttm = f'alter database encrypt with "{ENCRYPTION_PLUGIN}"' # <<< ::: NB ::: DO NOT add '... key "{ENCRYPTION_KEY}"' here!
            wait_for_state = 'Database encrypted'
        elif mode == 'decrypt':
            alter_db_sttm = 'alter database decrypt'
            wait_for_state = 'Database not encrypted'
    
    
        e_thread_finished = False
    
        # 0 = non crypted;
        # 1 = has been encrypted;
        # 2 = is DEcrypting;
        # 3 = is Encrypting;
        #
        REQUIRED_CRYPT_STATE = 1 if mode == 'encrypt' else 0
        current_crypt_state = -1
        d1 = py_dt.timedelta(0)
>       with act.db.connect() as con:

tests/bugs/gh_8429_test.py:147: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

database = 'gh_8429_alias_c'

    def connect(database: str, *, user: str=None, password: str=None, role: str=None,
                no_gc: bool=None, no_db_triggers: bool=None, dbkey_scope: DBKeyScope=None,
                crypt_callback: iCryptKeyCallbackImpl=None, charset: str=None,
                auth_plugin_list: str=None, session_time_zone: str=None) -> Connection:
        """Establishes a connection to the database.
    
        Arguments:
            database: DSN or Database configuration name.
            user: User name.
            password: User password.
            role: User role.
            no_gc: Do not perform garbage collection for this connection.
            no_db_triggers: Do not execute database triggers for this connection.
            dbkey_scope: DBKEY scope override for connection.
            crypt_callback: Callback that provides encryption key for the database.
            charset: Character set for connection.
            auth_plugin_list: List of authentication plugins override
            session_time_zone: Session time zone [Firebird 4]
    
        Hooks:
            Event `.ConnectionHook.ATTACH_REQUEST`: Executed after all parameters
            are preprocessed and before `Connection` is created. Hook
            must have signature::
    
                hook_func(dsn: str, dpb: bytes) -> Optional[Connection]
    
            Hook may return `Connection` instance or None.
            First instance returned by any hook will become the return value
            of this function and other hooks are not called.
    
            Event `.ConnectionHook.ATTACHED`: Executed before `Connection` instance is
            returned. Hook must have signature::
    
                hook_func(connection: Connection) -> None
    
            Any value returned by hook is ignored.
        """
        db_config = driver_config.get_database(database)
        if db_config is None:
            db_config = driver_config.db_defaults
        else:
            database = db_config.database.value
        if db_config.server.value is None:
            srv_config = driver_config.server_defaults
        else:
            srv_config = driver_config.get_server(db_config.server.value)
            if srv_config is None:
                raise ValueError(f"Configuration for server '{db_config.server.value}' not found")
        if user is None:
            user = db_config.user.value
            if user is None:
                user = srv_config.user.value
        if password is None:
            password = db_config.password.value
            if password is None:
                password = srv_config.password.value
        if role is None:
            role = db_config.role.value
        if charset is None:
            charset = db_config.charset.value
        if charset:
            charset = charset.upper()
        if auth_plugin_list is None:
            auth_plugin_list = db_config.auth_plugin_list.value
        if session_time_zone is None:
            session_time_zone = db_config.session_time_zone.value
        dsn = _connect_helper(db_config.dsn.value, srv_config.host.value, srv_config.port.value,
                              database, db_config.protocol.value)
        dpb = DPB(user=user, password=password, role=role, trusted_auth=db_config.trusted_auth.value,
                  sql_dialect=db_config.sql_dialect.value, timeout=db_config.timeout.value,
                  charset=charset, cache_size=db_config.cache_size.value,
                  no_linger=db_config.no_linger.value, utf8filename=db_config.utf8filename.value,
                  no_gc=no_gc, no_db_triggers=no_db_triggers, dbkey_scope=dbkey_scope,
                  dummy_packet_interval=db_config.dummy_packet_interval.value,
                  config=db_config.config.value, auth_plugin_list=auth_plugin_list,
                  session_time_zone=session_time_zone, set_bind=db_config.set_bind.value,
                  decfloat_round=db_config.decfloat_round.value,
                  decfloat_traps=db_config.decfloat_traps.value,
                  parallel_workers=db_config.parallel_workers.value)
>       return __make_connection(False, dsn, db_config.utf8filename.value, dpb.get_buffer(),
                                 db_config.sql_dialect.value, charset, crypt_callback)

../lib/python3.11/site-packages/firebird/driver/core.py:2149: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

create = False, dsn = 'localhost/3716:gh_8429_alias_c', utf8filename = False
dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x00', sql_dialect = 3
charset = None, crypt_callback = None

    def __make_connection(create: bool, dsn: str, utf8filename: bool, dpb: bytes,
                          sql_dialect: int, charset: str,
                          crypt_callback: iCryptKeyCallbackImpl) -> Connection:
        with a.get_api().master.get_dispatcher() as provider:
            if crypt_callback is not None:
                provider.set_dbcrypt_callback(crypt_callback)
            if create:
                att = provider.create_database(dsn, dpb, 'utf-8' if utf8filename else FS_ENCODING)
                con = Connection(att, dsn, dpb, sql_dialect, charset)
            else:
                con = None
                for hook in get_callbacks(ConnectionHook.ATTACH_REQUEST, Connection):
                    try:
                        con = hook(dsn, dpb)
                    except Exception as e:
                        raise InterfaceError("Error in DATABASE_ATTACH_REQUEST hook.", *e.args) from e
                    if con is not None:
                        break
                if con is None:
>                   att = provider.attach_database(dsn, dpb, 'utf-8' if utf8filename else FS_ENCODING)

../lib/python3.11/site-packages/firebird/driver/core.py:2064: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <firebird.driver.interfaces.iProvider pytest object at [hex]>
filename = 'localhost/3716:gh_8429_alias_c'
dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x00'
encoding = 'utf-8'

    def attach_database(self, filename: str, dpb: Optional[bytes] = None, encoding: str = 'ascii') -> iAttachment:
        "Replaces `isc_attach_database()`"
        result = self.vtable.attachDatabase(self, self.status, filename.encode(encoding),
                                            0 if dpb is None else len(dpb), dpb)
>       self._check()

../lib/python3.11/site-packages/firebird/driver/interfaces.py:1295: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <firebird.driver.interfaces.iProvider pytest object at [hex]>

    def _check(self) -> None:
        state = self.status.get_state()
        if StateFlag.ERRORS in state:
>           raise self.__report(DatabaseError, self.status.get_errors())
E           firebird.driver.types.DatabaseError: I/O error during "lock" operation for file "/home/fbqa/qa-2024/unpacked-snapshot.tmp/examples/empbuild/qa/tmp_gh_8429_c.fdb"
E           -Database already opened with engine instance, incompatible with current

../lib/python3.11/site-packages/firebird/driver/interfaces.py:113: DatabaseError
Full history of outcomes and elapsed time, ms:
NN SNAP_INFO CS_outcome SS_outcome CS_run_time SS_run_time CS_run_beg CS_run_end SS_run_beg SS_run_end
1 5.0.3.1674 2025.06.27 3ee5c P P 4138 2524 2025.06.29 13:09:30.087 2025.06.29 13:09:34.225 2025.06.29 11:44:20.346 2025.06.29 11:44:22.870
2 5.0.3.1657 2025.06.19 4bd4c P P 3711 2305 2025.06.27 12:22:16.394 2025.06.27 12:22:20.105 2025.06.27 11:03:04.463 2025.06.27 11:03:06.768
3 5.0.3.1657 2025.06.11 dae6f P P 3763 2317 2025.06.17 07:27:24.506 2025.06.17 07:27:28.269 2025.06.17 06:06:58.113 2025.06.17 06:07:00.430
4 5.0.3.1657 2025.06.10 dbc92 P P 4028 2744 2025.06.11 12:17:55.090 2025.06.11 12:17:59.118 2025.06.11 10:48:56.015 2025.06.11 10:48:58.759
5 5.0.3.1656 2025.05.20 c4b11 P P 4143 2440 2025.06.10 12:11:47.695 2025.06.10 12:11:51.838 2025.06.10 10:47:17.268 2025.06.10 10:47:19.708
6 5.0.3.1652 2025.05.13 f51c6 P P 4213 2619 2025.05.20 05:16:10.708 2025.05.20 05:16:14.921 2025.05.20 03:39:48.283 2025.05.20 03:39:50.902
7 5.0.3.1651 2025.04.30 141ef P P 4378 2719 2025.05.13 12:14:11.545 2025.05.13 12:14:15.923 2025.05.13 10:36:43.359 2025.05.13 10:36:46.078
8 5.0.3.1650 2025.04.28 4cbff P P 4287 2675 2025.05.01 11:48:00.319 2025.05.01 11:48:04.606 2025.05.01 10:11:28.575 2025.05.01 10:11:31.250
9 5.0.3.1649 2025.04.21 5b2d0 P P 4389 2716 2025.04.28 05:45:45.025 2025.04.28 05:45:49.414 2025.04.28 04:11:06.984 2025.04.28 04:11:09.700
10 5.0.3.1648 2025.04.18 2f4c5 P P 4374 2595 2025.04.20 05:37:26.514 2025.04.20 05:37:30.888 2025.04.20 04:05:25.023 2025.04.20 04:05:27.618
11 5.0.3.1635 2025.03.31 22ec6 P P 4395 2499 2025.04.18 12:00:36.286 2025.04.18 12:00:40.681 2025.04.18 10:24:38.047 2025.04.18 10:24:40.546
12 5.0.3.1633 2025.03.28 3123a P P 4286 3096 2025.03.31 10:34:18.592 2025.03.31 10:34:22.878 2025.03.31 09:04:45.516 2025.03.31 09:04:48.612
13 5.0.3.1633 2025.03.27 e0fb8 P P 4414 3080 2025.03.28 11:09:49.775 2025.03.28 11:09:54.189 2025.03.28 09:37:24.923 2025.03.28 09:37:28.003
14 5.0.3.1631 2025.03.21 1925b P P 4181 2622 2025.03.27 10:57:30.534 2025.03.27 10:57:34.715 2025.03.27 09:26:03.543 2025.03.27 09:26:06.165
15 5.0.3.1628 2025.03.14 16d05 P P 872 437 2025.03.17 08:30:38.270 2025.03.17 08:30:39.142 2025.03.17 06:50:18.354 2025.03.17 06:50:18.791
16 5.0.3.1627 2025.02.26 4e218 P P 843 400 2025.03.14 11:45:01.139 2025.03.14 11:45:01.982 2025.03.14 10:03:36.662 2025.03.14 10:03:37.062
17 5.0.3.1624 2025.02.25 dc3b2 P P 756 398 2025.02.26 10:35:37.750 2025.02.26 10:35:38.506 2025.02.26 08:59:40.154 2025.02.26 08:59:40.552
18 5.0.2.1615 2025.02.20 4a726 P F 1040 1242 2025.02.25 11:02:12.021 2025.02.25 11:02:13.061 2025.02.25 09:24:46.981 2025.02.25 09:24:48.223

Elapsed time, ms. Chart for last 18 runs:

Last commits information (all timestamps in UTC):