[stub, to be replaced]

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

    Permission error
    I/O error

    firebird.driver.types.DatabaseError: I/O error during "CreateFile (open)" operation for file "gh_8429_alias_c"
    -Error while trying to open file
    -The process cannot access the file because it is being used by another process.

    LOG DETAILS:

    2025-02-25 10:48:29.757
    2025-02-25 10:48:29.757 act_a = <firebird.qa.plugin.Action object at [hex]>
    2025-02-25 10:48:29.757 act_b = <firebird.qa.plugin.Action object at [hex]>
    2025-02-25 10:48:29.757 act_c = <firebird.qa.plugin.Action object at [hex]>
    2025-02-25 10:48:29.757 usr_x = <firebird.qa.plugin.User object at [hex]>
    2025-02-25 10:48:29.757 usr_y = <firebird.qa.plugin.User object at [hex]>
    2025-02-25 10:48:29.757 usr_z = <firebird.qa.plugin.User object at [hex]>
    2025-02-25 10:48:29.757 capsys = <_pytest.capture.CaptureFixture object at [hex]>
    2025-02-25 10:48:29.757
    2025-02-25 10:48:29.758     @pytest.mark.es_eds
    2025-02-25 10:48:29.758     @pytest.mark.encryption
    2025-02-25 10:48:29.758     @pytest.mark.version('>=4.0.6')
    2025-02-25 10:48:29.758     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 10:48:29.758
    2025-02-25 10:48:29.758         dbfile_a = get_filename_by_alias(act_a)
    2025-02-25 10:48:29.758         dbfile_b = get_filename_by_alias(act_b)
    2025-02-25 10:48:29.758         dbfile_c = get_filename_by_alias(act_c)
    2025-02-25 10:48:29.758
    2025-02-25 10:48:29.758         dbfile_a.unlink(missing_ok = True)
    2025-02-25 10:48:29.758         dbfile_b.unlink(missing_ok = True)
    2025-02-25 10:48:29.758         dbfile_c.unlink(missing_ok = True)
    2025-02-25 10:48:29.758
    2025-02-25 10:48:29.758         with create_database(act_a.db.db_path, user = act_a.db.user, password = act_a.db.password) as con_a, \
    2025-02-25 10:48:29.758             create_database(act_b.db.db_path, user = act_b.db.user, password = act_b.db.password) as con_b, \
    2025-02-25 10:48:29.758             create_database(act_c.db.db_path, user = act_c.db.user, password = act_c.db.password) as con_c:
    2025-02-25 10:48:29.758
    2025-02-25 10:48:29.758             sql = f"""
    2025-02-25 10:48:29.758                 create procedure sp_a (a_who varchar(31)) returns (o_info varchar(512)) as
    2025-02-25 10:48:29.759                 begin
    2025-02-25 10:48:29.759                     -- e1-meta.sql:
    2025-02-25 10:48:29.759                     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 10:48:29.759                     suspend;
    2025-02-25 10:48:29.759                 end
    2025-02-25 10:48:29.759                 ^
    2025-02-25 10:48:29.759                 grant execute on procedure sp_a to public
    2025-02-25 10:48:29.759                 ^
    2025-02-25 10:48:29.759                 alter database set linger to 0
    2025-02-25 10:48:29.759                 ^
    2025-02-25 10:48:29.759             """
    2025-02-25 10:48:29.759             for x in sql.split('^'):
    2025-02-25 10:48:29.759                 if (s := x.strip()):
    2025-02-25 10:48:29.759                     con_a.execute_immediate(s)
    2025-02-25 10:48:29.759             con_a.commit()
    2025-02-25 10:48:29.759
    2025-02-25 10:48:29.759             # ..................................................
    2025-02-25 10:48:29.759
    2025-02-25 10:48:29.759             sql = f"""
    2025-02-25 10:48:29.759                 create procedure sp_b (a_who varchar(31)) returns (o_info varchar(512)) as
    2025-02-25 10:48:29.760                 begin
    2025-02-25 10:48:29.760                     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 10:48:29.760                     suspend;
    2025-02-25 10:48:29.760                 end
    2025-02-25 10:48:29.760                 ^
    2025-02-25 10:48:29.760                 grant execute on procedure sp_b to public
    2025-02-25 10:48:29.760                 ^
    2025-02-25 10:48:29.760                 alter database set linger to 0
    2025-02-25 10:48:29.760                 ^
    2025-02-25 10:48:29.760             """
    2025-02-25 10:48:29.760             for x in sql.split('^'):
    2025-02-25 10:48:29.760                 if (s := x.strip()):
    2025-02-25 10:48:29.760                     con_b.execute_immediate(s)
    2025-02-25 10:48:29.760             con_b.commit()
    2025-02-25 10:48:29.760
    2025-02-25 10:48:29.760             # ..................................................
    2025-02-25 10:48:29.760
    2025-02-25 10:48:29.760             sql = f"""
    2025-02-25 10:48:29.760                 create procedure sp_c returns (o_info varchar(512)) as
    2025-02-25 10:48:29.761                 begin
    2025-02-25 10:48:29.761                     o_info = lower(current_user);
    2025-02-25 10:48:29.761                     -- o_info = lower(rdb$get_context('SYSTEM', 'DB_NAME')) || ':' || lower(current_user);
    2025-02-25 10:48:29.761                     suspend;
    2025-02-25 10:48:29.761                 end
    2025-02-25 10:48:29.761                 ^
    2025-02-25 10:48:29.761                 grant execute on procedure sp_c to public
    2025-02-25 10:48:29.761                 ^
    2025-02-25 10:48:29.761                 alter database set linger to 0
    2025-02-25 10:48:29.761                 ^
    2025-02-25 10:48:29.761             """
    2025-02-25 10:48:29.761             for x in sql.split('^'):
    2025-02-25 10:48:29.761                 if (s := x.strip()):
    2025-02-25 10:48:29.761                     con_c.execute_immediate(s)
    2025-02-25 10:48:29.761             con_c.commit()
    2025-02-25 10:48:29.761
    2025-02-25 10:48:29.761             ############################################
    2025-02-25 10:48:29.761             ###   E N C R Y P T    D A T A B A S E   ###
    2025-02-25 10:48:29.761             ############################################
    2025-02-25 10:48:29.762 >           run_encr_decr(act_c, 'encrypt', MAX_WAITING_ENCR_FINISH, capsys)
    2025-02-25 10:48:29.762
    2025-02-25 10:48:29.762 tests\bugs\gh_8429_test.py:272:
    2025-02-25 10:48:29.762 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    2025-02-25 10:48:29.762
    2025-02-25 10:48:29.762 act = <firebird.qa.plugin.Action object at [hex]>, mode = 'encrypt'
    2025-02-25 10:48:29.762 max_wait_encr_thread_finish = 10000
    2025-02-25 10:48:29.762 capsys = <_pytest.capture.CaptureFixture object at [hex]>
    2025-02-25 10:48:29.762
    2025-02-25 10:48:29.762     def run_encr_decr(act: Action, mode, max_wait_encr_thread_finish, capsys):
    2025-02-25 10:48:29.762         if mode == 'encrypt':
    2025-02-25 10:48:29.762             # See letter from Alex, 15.12.2023 16:16 demo-plugin can not transfer named key over network.
    2025-02-25 10:48:29.762             # Because of that, we have to use 'ALTER DATABASE ENCRYPT WITH <plugin>'  _WITHOUT_ adding 'key "{ENCRYPTION_KEY}"'.
    2025-02-25 10:48:29.762             # ::: NB ::: One need to be sure that $FB_HOME/plugins.conf contains following lines:
    2025-02-25 10:48:29.762             # Plugin = KH2 {
    2025-02-25 10:48:29.762             #     Module = $(dir_plugins)/fbSampleKeyHolder
    2025-02-25 10:48:29.762             #     RegisterName = fbSampleKeyHolder
    2025-02-25 10:48:29.762             #     Config = KH2
    2025-02-25 10:48:29.762             # }
    2025-02-25 10:48:29.763             #  Config = KH2 {
    2025-02-25 10:48:29.763             #     Auto = false
    2025-02-25 10:48:29.763             # }
    2025-02-25 10:48:29.763             # Otherwise error will raise:
    2025-02-25 10:48:29.763             # unsuccessful metadata update
    2025-02-25 10:48:29.763             # -ALTER DATABASE failed
    2025-02-25 10:48:29.763             # -Missing database encryption key for your attachment
    2025-02-25 10:48:29.763             # -Plugin fbSampleDbCrypt:
    2025-02-25 10:48:29.763             # -Crypt key not set
    2025-02-25 10:48:29.763             #
    2025-02-25 10:48:29.763             alter_db_sttm = f'alter database encrypt with "{ENCRYPTION_PLUGIN}"' # <<< ::: NB ::: DO NOT add '... key "{ENCRYPTION_KEY}"' here!
    2025-02-25 10:48:29.763             wait_for_state = 'Database encrypted'
    2025-02-25 10:48:29.763         elif mode == 'decrypt':
    2025-02-25 10:48:29.763             alter_db_sttm = 'alter database decrypt'
    2025-02-25 10:48:29.763             wait_for_state = 'Database not encrypted'
    2025-02-25 10:48:29.763
    2025-02-25 10:48:29.763
    2025-02-25 10:48:29.763         e_thread_finished = False
    2025-02-25 10:48:29.763
    2025-02-25 10:48:29.764         # 0 = non crypted;
    2025-02-25 10:48:29.764         # 1 = has been encrypted;
    2025-02-25 10:48:29.764         # 2 = is DEcrypting;
    2025-02-25 10:48:29.764         # 3 = is Encrypting;
    2025-02-25 10:48:29.764         #
    2025-02-25 10:48:29.764         REQUIRED_CRYPT_STATE = 1 if mode == 'encrypt' else 0
    2025-02-25 10:48:29.764         current_crypt_state = -1
    2025-02-25 10:48:29.764         d1 = py_dt.timedelta(0)
    2025-02-25 10:48:29.764 >       with act.db.connect() as con:
    2025-02-25 10:48:29.764
    2025-02-25 10:48:29.764 tests\bugs\gh_8429_test.py:147:
    2025-02-25 10:48:29.764 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    2025-02-25 10:48:29.764
    2025-02-25 10:48:29.764 database = 'gh_8429_alias_c'
    2025-02-25 10:48:29.764
    2025-02-25 10:48:29.764     def connect(database: str, *, user: str=None, password: str=None, role: str=None,
    2025-02-25 10:48:29.764                 no_gc: bool=None, no_db_triggers: bool=None, dbkey_scope: DBKeyScope=None,
    2025-02-25 10:48:29.764                 crypt_callback: iCryptKeyCallbackImpl=None, charset: str=None,
    2025-02-25 10:48:29.764                 auth_plugin_list: str=None, session_time_zone: str=None) -> Connection:
    2025-02-25 10:48:29.764         """Establishes a connection to the database.
    2025-02-25 10:48:29.765
    2025-02-25 10:48:29.765         Arguments:
    2025-02-25 10:48:29.765             database: DSN or Database configuration name.
    2025-02-25 10:48:29.765             user: User name.
    2025-02-25 10:48:29.765             password: User password.
    2025-02-25 10:48:29.765             role: User role.
    2025-02-25 10:48:29.765             no_gc: Do not perform garbage collection for this connection.
    2025-02-25 10:48:29.765             no_db_triggers: Do not execute database triggers for this connection.
    2025-02-25 10:48:29.765             dbkey_scope: DBKEY scope override for connection.
    2025-02-25 10:48:29.765             crypt_callback: Callback that provides encryption key for the database.
    2025-02-25 10:48:29.765             charset: Character set for connection.
    2025-02-25 10:48:29.765             auth_plugin_list: List of authentication plugins override
    2025-02-25 10:48:29.765             session_time_zone: Session time zone [Firebird 4]
    2025-02-25 10:48:29.765
    2025-02-25 10:48:29.765         Hooks:
    2025-02-25 10:48:29.765             Event `.ConnectionHook.ATTACH_REQUEST`: Executed after all parameters
    2025-02-25 10:48:29.765             are preprocessed and before `Connection` is created. Hook
    2025-02-25 10:48:29.765             must have signature::
    2025-02-25 10:48:29.766
    2025-02-25 10:48:29.766                 hook_func(dsn: str, dpb: bytes) -> Optional[Connection]
    2025-02-25 10:48:29.766
    2025-02-25 10:48:29.766             Hook may return `Connection` instance or None.
    2025-02-25 10:48:29.766             First instance returned by any hook will become the return value
    2025-02-25 10:48:29.766             of this function and other hooks are not called.
    2025-02-25 10:48:29.766
    2025-02-25 10:48:29.766             Event `.ConnectionHook.ATTACHED`: Executed before `Connection` instance is
    2025-02-25 10:48:29.766             returned. Hook must have signature::
    2025-02-25 10:48:29.766
    2025-02-25 10:48:29.766                 hook_func(connection: Connection) -> None
    2025-02-25 10:48:29.766
    2025-02-25 10:48:29.766             Any value returned by hook is ignored.
    2025-02-25 10:48:29.766         """
    2025-02-25 10:48:29.766         db_config = driver_config.get_database(database)
    2025-02-25 10:48:29.766         if db_config is None:
    2025-02-25 10:48:29.766             db_config = driver_config.db_defaults
    2025-02-25 10:48:29.766         else:
    2025-02-25 10:48:29.766             database = db_config.database.value
    2025-02-25 10:48:29.767         if db_config.server.value is None:
    2025-02-25 10:48:29.767             srv_config = driver_config.server_defaults
    2025-02-25 10:48:29.767         else:
    2025-02-25 10:48:29.767             srv_config = driver_config.get_server(db_config.server.value)
    2025-02-25 10:48:29.767             if srv_config is None:
    2025-02-25 10:48:29.767                 raise ValueError(f"Configuration for server '{db_config.server.value}' not found")
    2025-02-25 10:48:29.767         if user is None:
    2025-02-25 10:48:29.767             user = db_config.user.value
    2025-02-25 10:48:29.767             if user is None:
    2025-02-25 10:48:29.767                 user = srv_config.user.value
    2025-02-25 10:48:29.767         if password is None:
    2025-02-25 10:48:29.767             password = db_config.password.value
    2025-02-25 10:48:29.767             if password is None:
    2025-02-25 10:48:29.767                 password = srv_config.password.value
    2025-02-25 10:48:29.767         if role is None:
    2025-02-25 10:48:29.767             role = db_config.role.value
    2025-02-25 10:48:29.767         if charset is None:
    2025-02-25 10:48:29.767             charset = db_config.charset.value
    2025-02-25 10:48:29.767         if charset:
    2025-02-25 10:48:29.768             charset = charset.upper()
    2025-02-25 10:48:29.768         if auth_plugin_list is None:
    2025-02-25 10:48:29.768             auth_plugin_list = db_config.auth_plugin_list.value
    2025-02-25 10:48:29.768         if session_time_zone is None:
    2025-02-25 10:48:29.768             session_time_zone = db_config.session_time_zone.value
    2025-02-25 10:48:29.768         dsn = _connect_helper(db_config.dsn.value, srv_config.host.value, srv_config.port.value,
    2025-02-25 10:48:29.768                               database, db_config.protocol.value)
    2025-02-25 10:48:29.768         dpb = DPB(user=user, password=password, role=role, trusted_auth=db_config.trusted_auth.value,
    2025-02-25 10:48:29.768                   sql_dialect=db_config.sql_dialect.value, timeout=db_config.timeout.value,
    2025-02-25 10:48:29.768                   charset=charset, cache_size=db_config.cache_size.value,
    2025-02-25 10:48:29.768                   no_linger=db_config.no_linger.value, utf8filename=db_config.utf8filename.value,
    2025-02-25 10:48:29.768                   no_gc=no_gc, no_db_triggers=no_db_triggers, dbkey_scope=dbkey_scope,
    2025-02-25 10:48:29.768                   dummy_packet_interval=db_config.dummy_packet_interval.value,
    2025-02-25 10:48:29.768                   config=db_config.config.value, auth_plugin_list=auth_plugin_list,
    2025-02-25 10:48:29.768                   session_time_zone=session_time_zone, set_bind=db_config.set_bind.value,
    2025-02-25 10:48:29.768                   decfloat_round=db_config.decfloat_round.value,
    2025-02-25 10:48:29.768                   decfloat_traps=db_config.decfloat_traps.value,
    2025-02-25 10:48:29.768                   parallel_workers=db_config.parallel_workers.value)
    2025-02-25 10:48:29.768 >       return __make_connection(False, dsn, db_config.utf8filename.value, dpb.get_buffer(),
    2025-02-25 10:48:29.768                                  db_config.sql_dialect.value, charset, crypt_callback)
    2025-02-25 10:48:29.769
    2025-02-25 10:48:29.769 C:\Python3x\Lib\site-packages\firebird\driver\core.py:2149:
    2025-02-25 10:48:29.769 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    2025-02-25 10:48:29.769
    2025-02-25 10:48:29.769 create = False, dsn = 'localhost/33337:gh_8429_alias_c', utf8filename = False
    2025-02-25 10:48:29.769 dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x00', sql_dialect = 3
    2025-02-25 10:48:29.769 charset = None, crypt_callback = None
    2025-02-25 10:48:29.769
    2025-02-25 10:48:29.769     def __make_connection(create: bool, dsn: str, utf8filename: bool, dpb: bytes,
    2025-02-25 10:48:29.769                           sql_dialect: int, charset: str,
    2025-02-25 10:48:29.769                           crypt_callback: iCryptKeyCallbackImpl) -> Connection:
    2025-02-25 10:48:29.769         with a.get_api().master.get_dispatcher() as provider:
    2025-02-25 10:48:29.769             if crypt_callback is not None:
    2025-02-25 10:48:29.769                 provider.set_dbcrypt_callback(crypt_callback)
    2025-02-25 10:48:29.769             if create:
    2025-02-25 10:48:29.769                 att = provider.create_database(dsn, dpb, 'utf-8' if utf8filename else FS_ENCODING)
    2025-02-25 10:48:29.769                 con = Connection(att, dsn, dpb, sql_dialect, charset)
    2025-02-25 10:48:29.769             else:
    2025-02-25 10:48:29.769                 con = None
    2025-02-25 10:48:29.769                 for hook in get_callbacks(ConnectionHook.ATTACH_REQUEST, Connection):
    2025-02-25 10:48:29.769                     try:
    2025-02-25 10:48:29.770                         con = hook(dsn, dpb)
    2025-02-25 10:48:29.770                     except Exception as e:
    2025-02-25 10:48:29.770                         raise InterfaceError("Error in DATABASE_ATTACH_REQUEST hook.", *e.args) from e
    2025-02-25 10:48:29.770                     if con is not None:
    2025-02-25 10:48:29.770                         break
    2025-02-25 10:48:29.770                 if con is None:
    2025-02-25 10:48:29.770 >                   att = provider.attach_database(dsn, dpb, 'utf-8' if utf8filename else FS_ENCODING)
    2025-02-25 10:48:29.770
    2025-02-25 10:48:29.770 C:\Python3x\Lib\site-packages\firebird\driver\core.py:2064:
    2025-02-25 10:48:29.770 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    2025-02-25 10:48:29.770
    2025-02-25 10:48:29.770 self = <firebird.driver.interfaces.iProvider object at [hex]>
    2025-02-25 10:48:29.770 filename = 'localhost/33337:gh_8429_alias_c'
    2025-02-25 10:48:29.770 dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x00'
    2025-02-25 10:48:29.770 encoding = 'utf-8'
    2025-02-25 10:48:29.770
    2025-02-25 10:48:29.770     def attach_database(self, filename: str, dpb: Optional[bytes] = None, encoding: str = 'ascii') -> iAttachment:
    2025-02-25 10:48:29.770         "Replaces `isc_attach_database()`"
    2025-02-25 10:48:29.770         result = self.vtable.attachDatabase(self, self.status, filename.encode(encoding),
    2025-02-25 10:48:29.770                                             0 if dpb is None else len(dpb), dpb)
    2025-02-25 10:48:29.771 >       self._check()
    2025-02-25 10:48:29.771
    2025-02-25 10:48:29.771 C:\Python3x\Lib\site-packages\firebird\driver\interfaces.py:1295:
    2025-02-25 10:48:29.771 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    2025-02-25 10:48:29.771
    2025-02-25 10:48:29.771 self = <firebird.driver.interfaces.iProvider object at [hex]>
    2025-02-25 10:48:29.771
    2025-02-25 10:48:29.771     def _check(self) -> None:
    2025-02-25 10:48:29.771         state = self.status.get_state()
    2025-02-25 10:48:29.771         if StateFlag.ERRORS in state:
    2025-02-25 10:48:29.771 >           raise self.__report(DatabaseError, self.status.get_errors())
    2025-02-25 10:48:29.771 E           firebird.driver.types.DatabaseError: I/O error during "CreateFile (open)" operation for file "gh_8429_alias_c"
    2025-02-25 10:48:29.771 E           -Error while trying to open file
    2025-02-25 10:48:29.771 E           -The process cannot access the file because it is being used by another process.
    2025-02-25 10:48:29.771
    2025-02-25 10:48:29.771 C:\Python3x\Lib\site-packages\firebird\driver\interfaces.py:113: DatabaseError
    2025-02-25 10:48:29.771 ---------------------------- Captured stdout setup ----------------------------
    2025-02-25 10:48:29.771 Creating db: localhost:H:\QA\temp\qa2024.tmp\fbqa\test_11705\test.fdb [page_size=None, sql_dialect=None, charset='NONE', user=SYSDBA, password=masterkey]
    2025-02-25 10:48:29.771 CREATE user: TMP_8429_X PLUGIN: Srp
    2025-02-25 10:48:29.771 CREATE user: TMP_8429_Y PLUGIN: Srp
    2025-02-25 10:48:29.772 CREATE user: TMP_8429_Z PLUGIN: Srp
    2025-02-25 10:48:29.772 -------------------------- Captured stdout teardown ---------------------------
    2025-02-25 10:48:29.772 DROP user: TMP_8429_Z PLUGIN: Srp
    2025-02-25 10:48:29.772 DROP user: TMP_8429_Y PLUGIN: Srp
    2025-02-25 10:48:29.772 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)

    C:\Python3x\Lib\site-packages\firebird\driver\core.py:2149:
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    create = False, dsn = 'localhost/33337: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)

    C:\Python3x\Lib\site-packages\firebird\driver\core.py:2064:
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    self = <firebird.driver.interfaces.iProvider pytest object at [hex]>
    filename = 'localhost/33337: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()

    C:\Python3x\Lib\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 "CreateFile (open)" operation for file "gh_8429_alias_c"
    E           -Error while trying to open file
    E           -The process cannot access the file because it is being used by another process.

    C:\Python3x\Lib\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 | 3219 | 2069 | 2025.06.30 11:07:17.484 | 2025.06.30 11:07:20.703 | 2025.06.30 10:05:55.750 | 2025.06.30 10:05:57.819
2 | 5.0.3.1657 2025.06.26 dcb8a | P | P | 3381 | 2088 | 2025.06.27 11:08:40.243 | 2025.06.27 11:08:43.624 | 2025.06.27 10:07:31.415 | 2025.06.27 10:07:33.503
3 | 5.0.3.1657 2025.06.20 8b4d2 | P | P | 3236 | 2072 | 2025.06.26 11:23:08.611 | 2025.06.26 11:23:11.847 | 2025.06.26 10:21:47.857 | 2025.06.26 10:21:49.929
4 | 5.0.3.1657 2025.06.19 4bd4c | P | P | 3436 | 2079 | 2025.06.20 05:27:22.515 | 2025.06.20 05:27:25.951 | 2025.06.20 04:26:06.506 | 2025.06.20 04:26:08.585
5 | 5.0.3.1657 2025.06.11 dae6f | P | P | 3221 | 2079 | 2025.06.19 10:58:50.116 | 2025.06.19 10:58:53.337 | 2025.06.19 09:57:30.667 | 2025.06.19 09:57:32.746
6 | 5.0.3.1657 2025.06.10 dbc92 | P | P | 3387 | 2082 | 2025.06.11 08:44:59.711 | 2025.06.11 08:45:03.098 | 2025.06.11 07:43:27.145 | 2025.06.11 07:43:29.227
7 | 5.0.3.1656 2025.06.05 00512 | P | P | 3275 | 2062 | 2025.06.10 10:00:30.093 | 2025.06.10 10:00:33.368 | 2025.06.10 08:58:32.900 | 2025.06.10 08:58:34.962
8 | 5.0.3.1656 2025.05.20 c4b11 | P | P | 3232 | 2096 | 2025.06.03 09:47:23.131 | 2025.06.03 09:47:26.363 | 2025.06.03 08:46:36.220 | 2025.06.03 08:46:38.316
9 | 5.0.3.1652 2025.05.13 f51c6 | P | P | 3236 | 2057 | 2025.05.21 06:28:21.687 | 2025.05.21 06:28:24.923 | 2025.05.21 05:27:51.877 | 2025.05.21 05:27:53.934
10 | 5.0.3.1651 2025.05.08 ee9d2 | P | E | 3253 | 2396 | 2025.05.13 06:41:01.273 | 2025.05.13 06:41:04.526 | 2025.05.13 05:21:59.072 | 2025.05.13 05:22:01.468
11 | 5.0.3.1651 2025.05.04 3d914 | P | E | 3251 | 2413 | 2025.05.09 04:30:04.526 | 2025.05.09 04:30:07.777 | 2025.05.09 03:10:56.910 | 2025.05.09 03:10:59.323
12 | 5.0.3.1651 2025.04.30 141ef | P | E | 3398 | 2236 | 2025.05.02 04:37:40.731 | 2025.05.02 04:37:44.129 | 2025.05.02 03:18:50.309 | 2025.05.02 03:18:52.545
13 | 5.0.3.1650 2025.04.30 6253f | P | E | 3242 | 2405 | 2025.05.01 04:36:44.257 | 2025.05.01 04:36:47.499 | 2025.05.01 03:17:46.516 | 2025.05.01 03:17:48.921
14 | 5.0.3.1650 2025.04.28 4cbff | P | E | 3218 | 2235 | 2025.04.30 04:35:45.300 | 2025.04.30 04:35:48.518 | 2025.04.30 03:16:59.574 | 2025.04.30 03:17:01.809
15 | 5.0.3.1649 2025.04.21 5b2d0 | P | E | 3292 | 2445 | 2025.04.26 10:09:43.342 | 2025.04.26 10:09:46.634 | 2025.04.26 08:49:59.557 | 2025.04.26 08:50:02.002
16 | 5.0.3.1648 2025.04.18 2f4c5 | P | P | 3266 | 2113 | 2025.04.20 04:20:57.274 | 2025.04.20 04:21:00.540 | 2025.04.20 03:19:25.150 | 2025.04.20 03:19:27.263
17 | 5.0.3.1635 2025.04.03 f6bd1 | P | E | 3244 | 2398 | 2025.04.18 06:48:37.831 | 2025.04.18 06:48:41.075 | 2025.04.18 05:29:09.722 | 2025.04.18 05:29:12.120
18 | 5.0.3.1635 2025.03.31 22ec6 | P | E | 3284 | 2399 | 2025.04.03 09:54:28.042 | 2025.04.03 09:54:31.326 | 2025.04.03 08:34:40.163 | 2025.04.03 08:34:42.562
19 | 5.0.3.1633 2025.03.28 3123a | P | E | 3264 | 2400 | 2025.03.31 09:52:56.160 | 2025.03.31 09:52:59.424 | 2025.03.31 08:33:16.212 | 2025.03.31 08:33:18.612
20 | 5.0.3.1633 2025.03.27 e0fb8 | P | E | 3426 | 2426 | 2025.03.28 10:24:36.213 | 2025.03.28 10:24:39.639 | 2025.03.28 09:01:10.439 | 2025.03.28 09:01:12.865
21 | 5.0.3.1631 2025.03.25 bda65 | P | P | 3453 | 2173 | 2025.03.27 10:05:07.048 | 2025.03.27 10:05:10.501 | 2025.03.27 08:59:53.029 | 2025.03.27 08:59:55.202
22 | 5.0.3.1631 2025.03.21 1925b | P | P | 3459 | 2268 | 2025.03.25 06:39:09.577 | 2025.03.25 06:39:13.036 | 2025.03.25 05:33:45.618 | 2025.03.25 05:33:47.886
23 | 5.0.3.1629 2025.03.18 506d7 | P | P | 3328 | 2214 | 2025.03.20 09:39:26.940 | 2025.03.20 09:39:30.268 | 2025.03.20 08:33:52.512 | 2025.03.20 08:33:54.726
24 | 5.0.3.1628 2025.03.14 16d05 | P | P | 3333 | 2113 | 2025.03.18 09:33:34.800 | 2025.03.18 09:33:38.133 | 2025.03.18 08:29:34.983 | 2025.03.18 08:29:37.096
25 | 5.0.3.1627 2025.02.26 4e218 | P | P | 3408 | 2253 | 2025.03.13 09:52:52.721 | 2025.03.13 09:52:56.129 | 2025.03.13 08:47:06.915 | 2025.03.13 08:47:09.168
26 | 5.0.3.1624 2025.02.25 dc3b2 | P | P | 3132 | 2101 | 2025.02.26 15:25:07.404 | 2025.02.26 15:25:10.536 | 2025.02.26 14:20:03.476 | 2025.02.26 14:20:05.577
27 | 5.0.2.1615 2025.02.20 4a726 | P | F | 2842 | 1393 | 2025.02.25 08:39:16.257 | 2025.02.25 08:39:19.099 | 2025.02.25 07:17:36.371 | 2025.02.25 07:17:37.764

#### Elapsed time, ms. Chart for last 27 runs:

Last commits information (all timestamps in UTC):