2 @message |
Server crashed ?
Network / firewall ?
Test caused CRASH of server or FB utility. Dump LastModified: UTC 26.06.2025 07:00:34.1170
failed on teardown with "firebird.driver.types.DatabaseError: Unable to complete network request to host "localhost".
-Failed to establish a connection."
LOG DETAILS:
2025-06-26 10:12:44.756
2025-06-26 10:12:44.756 act_db_main = <firebird.qa.plugin.Action object at [hex]>
2025-06-26 10:12:44.756 act_db_repl = <firebird.qa.plugin.Action object at [hex]>
2025-06-26 10:12:44.756 db_main_owner = <firebird.qa.plugin.User object at [hex]>
2025-06-26 10:12:44.756 capsys = <_pytest.capture.CaptureFixture object at [hex]>
2025-06-26 10:12:44.756
2025-06-26 10:12:44.756 @pytest.mark.replication
2025-06-26 10:12:44.756 @pytest.mark.version('>=4.0.5')
2025-06-26 10:12:44.756 def test_1(act_db_main: Action, act_db_repl: Action, db_main_owner: User, capsys):
2025-06-26 10:12:44.756
2025-06-26 10:12:44.757 # Map for storing mnemonas and details for every FAILED step:
2025-06-26 10:12:44.757 run_errors_map = {}
2025-06-26 10:12:44.757
2025-06-26 10:12:44.757 # Obtain full path + filename for DB_MAIN and DB_REPL aliases.
2025-06-26 10:12:44.757 # NOTE: we must NOT use 'a.db.db_path' for ALIASED databases!
2025-06-26 10:12:44.757 # It will return '.' rather than full path+filename.
2025-06-26 10:12:44.757 # Use only con.info.name for that!
2025-06-26 10:12:44.757 #
2025-06-26 10:12:44.757 db_info = {}
2025-06-26 10:12:44.757 for a in (act_db_main, act_db_repl):
2025-06-26 10:12:44.757 with a.db.connect() as con:
2025-06-26 10:12:44.757 db_info[a, 'db_full_path'] = con.info.name
2025-06-26 10:12:44.757
2025-06-26 10:12:44.757 run_errors_map['init_reset'] = reset_replication(act_db_main, act_db_repl, db_info[act_db_main,'db_full_path'], db_info[act_db_repl,'db_full_path'], db_main_owner)
2025-06-26 10:12:44.757
2025-06-26 10:12:44.757 # Result: owner of db_main_alias = db_main_owner, i.e. NOT 'SYSDBA'
2025-06-26 10:12:44.757
2025-06-26 10:12:44.757 sql_init = f"""
2025-06-26 10:12:44.757 set bail on;
2025-06-26 10:12:44.757 recreate table test (
2025-06-26 10:12:44.758 id int generated by default as identity constraint test_pk primary key
2025-06-26 10:12:44.758 ,f01 int
2025-06-26 10:12:44.758 );
2025-06-26 10:12:44.758
2025-06-26 10:12:44.758 recreate table t_completed(id int primary key);
2025-06-26 10:12:44.758 commit;
2025-06-26 10:12:44.758 """
2025-06-26 10:12:44.758 act_db_main.isql(switches=['-q', '-user', db_main_owner.name, '-pass', db_main_owner.password], credentials = False, input = sql_init, combine_output = True)
2025-06-26 10:12:44.758 run_errors_map['out_prep_ddl'] = act_db_main.clean_stdout
2025-06-26 10:12:44.758 act_db_main.reset()
2025-06-26 10:12:44.758
2025-06-26 10:12:44.758 if max(v.strip() for v in run_errors_map.values()):
2025-06-26 10:12:44.758 # Some problem raised during init_sql execution
2025-06-26 10:12:44.758 pass
2025-06-26 10:12:44.758 else:
2025-06-26 10:12:44.758 # Query to be used for check that all DB objects present in replica (after last DML statement completed on master DB):
2025-06-26 10:12:44.758 ddl_ready_query = "select 1 from rdb$relations where rdb$relation_name = upper('t_completed')"
2025-06-26 10:12:44.758 ######################################################
2025-06-26 10:12:44.758 ### WAIT UNTIL REPLICA GETS INITIAL DDL AND DATA ###
2025-06-26 10:12:44.758 ######################################################
2025-06-26 10:12:44.758 watch_replica( act_db_repl, MAX_TIME_FOR_WAIT_DATA_IN_REPLICA, ddl_ready_query)
2025-06-26 10:12:44.759
2025-06-26 10:12:44.759 # Must be EMPTY:
2025-06-26 10:12:44.759 run_errors_map['out_repl_ddl'] = capsys.readouterr().out
2025-06-26 10:12:44.759
2025-06-26 10:12:44.759
2025-06-26 10:12:44.759 if max(v.strip() for v in run_errors_map.values()):
2025-06-26 10:12:44.759 # Some problem raised with delivering DDL changes to replica
2025-06-26 10:12:44.759 pass
2025-06-26 10:12:44.759 else:
2025-06-26 10:12:44.759
2025-06-26 10:12:44.759 sql_revoke_access = f"""
2025-06-26 10:12:44.759 set wng off;
2025-06-26 10:12:44.759 set list on;
2025-06-26 10:12:44.759 revoke delete on test from {db_main_owner.name};
2025-06-26 10:12:44.759 commit;
2025-06-26 10:12:44.759 select 1 as db_main_privilege_unexp_remains
2025-06-26 10:12:44.759 from rdb$database
2025-06-26 10:12:44.759 where exists (
2025-06-26 10:12:44.759 select 1 from rdb$user_privileges p
2025-06-26 10:12:44.759 where p.rdb$relation_name = upper('test') and p.rdb$privilege = upper('D')
2025-06-26 10:12:44.759 );
2025-06-26 10:12:44.760 commit;
2025-06-26 10:12:44.760 """
2025-06-26 10:12:44.760 act_db_main.isql(switches=['-q', '-user', db_main_owner.name, '-pass', db_main_owner.password], credentials = False, input = sql_revoke_access, combine_output = True)
2025-06-26 10:12:44.760 run_errors_map['db_main_privilege_unexp_remains'] = act_db_repl.stdout # must be EMPTY
2025-06-26 10:12:44.760 act_db_main.reset()
2025-06-26 10:12:44.760
2025-06-26 10:12:44.760
2025-06-26 10:12:44.760 if max(v.strip() for v in run_errors_map.values()):
2025-06-26 10:12:44.760 # Some problem was in just executed statement
2025-06-26 10:12:44.760 pass
2025-06-26 10:12:44.760 else:
2025-06-26 10:12:44.760 ############################################################
2025-06-26 10:12:44.760 ### WAIT UNTIL REPLICA APPLY 'REVOKE' PRIVILEGE COMMAND ###
2025-06-26 10:12:44.760 ############################################################
2025-06-26 10:12:44.760 # ( a: Action, max_allowed_time_for_wait, ddl_ready_query = '', isql_check_script = '', replica_expected_out = ''):
2025-06-26 10:12:44.760 chk_repl_sql = f"set list on;select 1 as db_repl_privilege_unexp_remains from rdb$database where exists(select 1 from rdb$user_privileges p where p.rdb$relation_name = upper('test') and p.rdb$privilege = upper('D'));"
2025-06-26 10:12:44.760 watch_replica( act_db_repl, MAX_TIME_FOR_WAIT_DATA_IN_REPLICA, ddl_ready_query = '', isql_check_script = chk_repl_sql, replica_expected_out = '' )
2025-06-26 10:12:44.760 # Must be EMPTY:
2025-06-26 10:12:44.761 run_errors_map['db_repl_privilege_not_deleted'] = capsys.readouterr().out
2025-06-26 10:12:44.761
2025-06-26 10:12:44.761 # This test changes OWNER of db_main to NON-sysdba.
2025-06-26 10:12:44.761 # We have to revert this change regardless on test outcome.
2025-06-26 10:12:44.761 > run_errors_map['final_reset'] = reset_replication(act_db_main, act_db_repl, db_info[act_db_main,'db_full_path'], db_info[act_db_repl,'db_full_path'])
2025-06-26 10:12:44.761
2025-06-26 10:12:44.761 tests\functional\replication\test_grantor_not_changes_in_replica_if_owner_not_sysdba.py:483:
2025-06-26 10:12:44.761 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-06-26 10:12:44.761
2025-06-26 10:12:44.761 act_db_main = <firebird.qa.plugin.Action object at [hex]>
2025-06-26 10:12:44.761 act_db_repl = <firebird.qa.plugin.Action object at [hex]>
2025-06-26 10:12:44.761 db_main_file = 'H:\\QA\\rundaily-2024\\unpacked-snapshot.tmp\\examples\\empbuild\\qa_replication\\db_main.fdb'
2025-06-26 10:12:44.761 db_repl_file = 'H:\\QA\\rundaily-2024\\unpacked-snapshot.tmp\\examples\\empbuild\\qa_replication\\db_repl.fdb'
2025-06-26 10:12:44.761 db_main_owner = None
2025-06-26 10:12:44.761
2025-06-26 10:12:44.761 def reset_replication(act_db_main: Action, act_db_repl: Action, db_main_file, db_repl_file, db_main_owner: User = None):
2025-06-26 10:12:44.761 out_reset = ''
2025-06-26 10:12:44.761 failed_shutdown_db_map = {} # K = 'db_main', 'db_repl'; V = error that occurred when we attempted to change DB state to full shutdown (if it occurred)
2025-06-26 10:12:44.761
2025-06-26 10:12:44.761 > with act_db_main.connect_server() as srv:
2025-06-26 10:12:44.762
2025-06-26 10:12:44.762 tests\functional\replication\test_grantor_not_changes_in_replica_if_owner_not_sysdba.py:105:
2025-06-26 10:12:44.762 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-06-26 10:12:44.762
2025-06-26 10:12:44.762 server = 'qa_rundaily_fb40'
2025-06-26 10:12:44.762
2025-06-26 10:12:44.762 def connect_server(server: str, *, user: str=None, password: str=None,
2025-06-26 10:12:44.762 crypt_callback: iCryptKeyCallbackImpl=None,
2025-06-26 10:12:44.762 expected_db: str=None, role: str=None, encoding: str=None,
2025-06-26 10:12:44.762 encoding_errors: str=None) -> Server:
2025-06-26 10:12:44.762 """Establishes a connection to server's service manager.
2025-06-26 10:12:44.762
2025-06-26 10:12:44.762 Arguments:
2025-06-26 10:12:44.762 server: Server host machine or Server configuration name.
2025-06-26 10:12:44.762 user: User name.
2025-06-26 10:12:44.762 password: User password.
2025-06-26 10:12:44.762 crypt_callback: Callback that provides encryption key.
2025-06-26 10:12:44.762 expected_db: Database that would be accessed (for using services with non-default
2025-06-26 10:12:44.762 security database)
2025-06-26 10:12:44.762 role: SQL role used for connection.
2025-06-26 10:12:44.763 encoding: Encoding for string values passed in parameter buffer. Default is
2025-06-26 10:12:44.763 `.ServerConfig.encoding`.
2025-06-26 10:12:44.763 encoding_errors: Error handler used for encoding errors. Default is
2025-06-26 10:12:44.763 `.ServerConfig.encoding_errors`.
2025-06-26 10:12:44.763
2025-06-26 10:12:44.763 Hooks:
2025-06-26 10:12:44.763 Event `.ServerHook.ATTACHED`: Executed before `Service` instance is
2025-06-26 10:12:44.763 returned. Hook must have signature::
2025-06-26 10:12:44.763
2025-06-26 10:12:44.763 hook_func(server: Server) -> None
2025-06-26 10:12:44.763
2025-06-26 10:12:44.763 Any value returned by hook is ignored.
2025-06-26 10:12:44.763 """
2025-06-26 10:12:44.763 srv_config = driver_config.get_server(server)
2025-06-26 10:12:44.763 if srv_config is None:
2025-06-26 10:12:44.763 srv_config = driver_config.server_defaults
2025-06-26 10:12:44.763 host = server or None
2025-06-26 10:12:44.763 port = None
2025-06-26 10:12:44.763 else:
2025-06-26 10:12:44.763 host = srv_config.host.value
2025-06-26 10:12:44.764 port = srv_config.port.value
2025-06-26 10:12:44.764 if host is None:
2025-06-26 10:12:44.764 host = 'service_mgr'
2025-06-26 10:12:44.764 if not host.endswith('service_mgr'):
2025-06-26 10:12:44.764 if host and not host.endswith(':'):
2025-06-26 10:12:44.764 if port:
2025-06-26 10:12:44.764 host += f"/{port}"
2025-06-26 10:12:44.764 host += ':'
2025-06-26 10:12:44.764 host += 'service_mgr'
2025-06-26 10:12:44.764 if user is None:
2025-06-26 10:12:44.764 user = srv_config.user.value
2025-06-26 10:12:44.764 if password is None:
2025-06-26 10:12:44.764 password = srv_config.password.value
2025-06-26 10:12:44.764 spb = SPB_ATTACH(user=user, password=password, config=srv_config.config.value,
2025-06-26 10:12:44.764 trusted_auth=srv_config.trusted_auth.value,
2025-06-26 10:12:44.764 auth_plugin_list=srv_config.auth_plugin_list.value,
2025-06-26 10:12:44.764 expected_db=expected_db, encoding=srv_config.encoding.value,
2025-06-26 10:12:44.764 errors=srv_config.encoding_errors.value, role=role)
2025-06-26 10:12:44.764 spb_buf = spb.get_buffer()
2025-06-26 10:12:44.765 with a.get_api().master.get_dispatcher() as provider:
2025-06-26 10:12:44.765 if crypt_callback is not None:
2025-06-26 10:12:44.765 provider.set_dbcrypt_callback(crypt_callback)
2025-06-26 10:12:44.765 > svc = provider.attach_service_manager(host, spb_buf)
2025-06-26 10:12:44.765
2025-06-26 10:12:44.765 C:\Python3x\Lib\site-packages\firebird\driver\core.py:5692:
2025-06-26 10:12:44.765 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-06-26 10:12:44.765
2025-06-26 10:12:44.765 self = <firebird.driver.interfaces.iProvider object at [hex]>
2025-06-26 10:12:44.765 service = 'localhost/33337:service_mgr'
2025-06-26 10:12:44.765 spb = b'\x02\x02\x1c\x06SYSDBA\x1d\tmasterkey'
2025-06-26 10:12:44.765
2025-06-26 10:12:44.765 def attach_service_manager(self, service: str, spb: bytes) -> iService:
2025-06-26 10:12:44.765 "Replaces `isc_service_attach()`"
2025-06-26 10:12:44.765 result = self.vtable.attachServiceManager(self, self.status, service.encode(), len(spb), spb)
2025-06-26 10:12:44.765 > self._check()
2025-06-26 10:12:44.765
2025-06-26 10:12:44.765 C:\Python3x\Lib\site-packages\firebird\driver\interfaces.py:1310:
2025-06-26 10:12:44.765 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2025-06-26 10:12:44.765
2025-06-26 10:12:44.765 self = <firebird.driver.interfaces.iProvider object at [hex]>
2025-06-26 10:12:44.766
2025-06-26 10:12:44.766 def _check(self) -> None:
2025-06-26 10:12:44.766 state = self.status.get_state()
2025-06-26 10:12:44.766 if StateFlag.ERRORS in state:
2025-06-26 10:12:44.766 > raise self.__report(DatabaseError, self.status.get_errors())
2025-06-26 10:12:44.766 E firebird.driver.types.DatabaseError: Unable to complete network request to host "localhost".
2025-06-26 10:12:44.766 E -Failed to establish a connection.
2025-06-26 10:12:44.766
2025-06-26 10:12:44.766 C:\Python3x\Lib\site-packages\firebird\driver\interfaces.py:113: DatabaseError
2025-06-26 10:12:44.766 ---------------------------- Captured stdout setup ----------------------------
2025-06-26 10:12:44.766 CREATE user: TMP_GH_8058 PLUGIN: Srp
|
3 #text |
request = <SubRequest 'db_main_owner' for <Function test_1>>
@pytest.fixture
def user_fixture(request: pytest.FixtureRequest) -> User:
> with User(request.getfixturevalue(db_fixture_name), name=name, password=password,
plugin=plugin, charset=charset, active=active, tags=tags,
first_name=first_name, middle_name=middle_name, last_name=last_name,
admin=admin, do_not_create=do_not_create) as user:
src\firebird\qa\plugin.py:1243:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <firebird.qa.plugin.User pytest object at [hex]>, exc_type = None
exc_value = None, traceback = None
def __exit__(self, exc_type, exc_value, traceback) -> None:
> if self.exists():
src\firebird\qa\plugin.py:1071:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
database = 'db_main_alias'
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:2159:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
create = False, dsn = 'localhost/33337:db_main_alias', utf8filename = False
dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x000\x04UTF8'
sql_dialect = 3, charset = 'UTF8', 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:2074:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <firebird.driver.interfaces.iProvider pytest object at [hex]>
filename = 'localhost/33337:db_main_alias'
dpb = b'\x01\x1c\x06SYSDBA\x1d\tmasterkey?\x04\x03\x00\x00\x000\x04UTF8'
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:1300:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
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: Unable to complete network request to host "localhost".
E -Failed to establish a connection.
C:\Python3x\Lib\site-packages\firebird\driver\interfaces.py:113: DatabaseError
|