mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 13:33:07 +01:00
New existing_db_factory; fixed errors; release 1.20.0
This commit is contained in:
parent
a72a4069c7
commit
8e9f832d8b
14
CHANGELOG.md
14
CHANGELOG.md
@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
## [0.20.0] - 2024-05-09
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Fixture `existing_db_factory` to directly use database from `databases` subdirectory.
|
||||||
|
It's not intended for use in Firebird QA, but it's necessary for other plugin
|
||||||
|
users.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Report test error also in cases when unexpected stderr is returned from tool execution
|
||||||
|
while `returncode` is zero.
|
||||||
|
- Select test marked for current platform also when it's not marked for Firebird version.
|
||||||
|
|
||||||
## [0.19.3] - 2024-03-21
|
## [0.19.3] - 2024-03-21
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@ -4,6 +4,17 @@ Changelog
|
|||||||
|
|
||||||
.. currentmodule:: firebird.qa.plugin
|
.. currentmodule:: firebird.qa.plugin
|
||||||
|
|
||||||
|
Version 0.20.0
|
||||||
|
==============
|
||||||
|
|
||||||
|
* New `.existing_db_factory` firxture to directly use database from `databases` subdirectory.
|
||||||
|
It's not intended for use in Firebird QA, but it's necessary for other plugin
|
||||||
|
users.
|
||||||
|
* Fix: Report test error also in cases when unexpected stderr is returned from tool execution
|
||||||
|
while `returncode` is zero.
|
||||||
|
* Fix: Select test marked for current platform also when it's not marked for Firebird version.
|
||||||
|
|
||||||
|
|
||||||
Version 0.19.3
|
Version 0.19.3
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
@ -19,6 +19,10 @@ db_factory
|
|||||||
----------
|
----------
|
||||||
.. autofunction:: db_factory
|
.. autofunction:: db_factory
|
||||||
|
|
||||||
|
existing_db_factory
|
||||||
|
-------------------
|
||||||
|
.. autofunction:: existing_db_factory
|
||||||
|
|
||||||
user_factory
|
user_factory
|
||||||
------------
|
------------
|
||||||
.. autofunction:: user_factory
|
.. autofunction:: user_factory
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
Sphinx==7.2.6
|
||||||
sphinx-bootstrap-theme>=0.8.0
|
sphinx-bootstrap-theme>=0.8.0
|
||||||
sphinx-autodoc-typehints>=1.17.0
|
sphinx-autodoc-typehints>=1.17.0
|
||||||
.
|
.
|
||||||
|
@ -32,7 +32,7 @@ classifiers = [
|
|||||||
"Framework :: Pytest",
|
"Framework :: Pytest",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"firebird-base>=1.7.2",
|
"firebird-base>=1.8.0",
|
||||||
"firebird-driver~=1.10",
|
"firebird-driver~=1.10",
|
||||||
"pytest>=7.4",
|
"pytest>=7.4",
|
||||||
"psutil~=5.9",
|
"psutil~=5.9",
|
||||||
@ -89,7 +89,7 @@ python = ["3.8", "3.9", "3.10", "3.11", "3.12"]
|
|||||||
detached = false
|
detached = false
|
||||||
platforms = ["linux"]
|
platforms = ["linux"]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Sphinx>=7.2.6",
|
"Sphinx==7.2.6",
|
||||||
"sphinx-bootstrap-theme>=0.8.1",
|
"sphinx-bootstrap-theme>=0.8.1",
|
||||||
"sphinx-autodoc-typehints>=1.24.0",
|
"sphinx-autodoc-typehints>=1.24.0",
|
||||||
"doc2dash>=3.0.0"
|
"doc2dash>=3.0.0"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: 2021-present The Firebird Projects <www.firebirdsql.org>
|
# SPDX-FileCopyrightText: 2021-present The Firebird Projects <www.firebirdsql.org>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
__version__ = "0.19.3"
|
__version__ = "0.20.0"
|
||||||
|
@ -40,4 +40,4 @@
|
|||||||
|
|
||||||
from .plugin import db_factory, Database, user_factory, User, isql_act, python_act, Action, \
|
from .plugin import db_factory, Database, user_factory, User, isql_act, python_act, Action, \
|
||||||
temp_file, temp_files, role_factory, Role, envar_factory, Envar, Mapping, mapping_factory, \
|
temp_file, temp_files, role_factory, Role, envar_factory, Envar, Mapping, mapping_factory, \
|
||||||
ServerKeeper, ExecutionError, QA_GLOBALS
|
ServerKeeper, ExecutionError, QA_GLOBALS, existing_db_factory
|
||||||
|
@ -512,6 +512,8 @@ def pytest_collection_modifyitems(session, config, items):
|
|||||||
item.add_marker(version_skip)
|
item.add_marker(version_skip)
|
||||||
else:
|
else:
|
||||||
deselected.append(item)
|
deselected.append(item)
|
||||||
|
elif platform_ok:
|
||||||
|
selected.append(item)
|
||||||
items[:] = selected
|
items[:] = selected
|
||||||
config.hook.pytest_deselected(items=deselected)
|
config.hook.pytest_deselected(items=deselected)
|
||||||
# Add OUR OWN test metadata to Item
|
# Add OUR OWN test metadata to Item
|
||||||
@ -886,6 +888,38 @@ class Database:
|
|||||||
with connect_server(_vars_['server']) as srv:
|
with connect_server(_vars_['server']) as srv:
|
||||||
srv.database.set_write_mode(database=self.db_path, mode=DbWriteMode.SYNC)
|
srv.database.set_write_mode(database=self.db_path, mode=DbWriteMode.SYNC)
|
||||||
|
|
||||||
|
def existing_db_factory(*, filename: str='test.fdb', charset: Optional[str]=None,
|
||||||
|
user: Optional[str]=None, password: Optional[str]=None,
|
||||||
|
config_name: str='pytest', utf8filename: bool=False):
|
||||||
|
"""Factory function that returns :doc:`fixture <pytest:explanation/fixtures>` providing
|
||||||
|
the `Database` instance to existing database.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
filename: Test database filename. It's also possible to specify database alias using
|
||||||
|
'#' as prefix, for example `#employee` means alias `employee`.
|
||||||
|
The database with this alias must be defined in `databases.conf`.
|
||||||
|
charset: Default charset for connections.
|
||||||
|
user: User name used to connect the test database. Default is taken from server configuration.
|
||||||
|
password: User password used to connect the test database. Default
|
||||||
|
is taken from server configuration.
|
||||||
|
config_name: Name for database configuration.
|
||||||
|
utf8filename: Use utf8filename DPB flag.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The returned instance must be assigned to module-level variable. Name of this variable
|
||||||
|
is important, as it's used to reference the fixture in other fixture-factory functions
|
||||||
|
that use the database, and the test function itself.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def existing_database_fixture(request: pytest.FixtureRequest) -> Database:
|
||||||
|
db = Database(_vars_['databases'], filename, user, password, charset, debug=str(request.module),
|
||||||
|
config_name=config_name, utf8filename=utf8filename)
|
||||||
|
yield db
|
||||||
|
|
||||||
|
return existing_database_fixture
|
||||||
|
|
||||||
def db_factory(*, filename: str='test.fdb', init: Optional[str]=None,
|
def db_factory(*, filename: str='test.fdb', init: Optional[str]=None,
|
||||||
from_backup: Optional[str]=None, copy_of: Optional[str]=None,
|
from_backup: Optional[str]=None, copy_of: Optional[str]=None,
|
||||||
page_size: Optional[int]=None, sql_dialect: Optional[int]=None,
|
page_size: Optional[int]=None, sql_dialect: Optional[int]=None,
|
||||||
@ -1779,7 +1813,7 @@ class Action:
|
|||||||
else:
|
else:
|
||||||
result: CompletedProcess = run(params, input=self.script,
|
result: CompletedProcess = run(params, input=self.script,
|
||||||
encoding=io_enc, capture_output=True)
|
encoding=io_enc, capture_output=True)
|
||||||
if result.returncode and not bool(self.expected_stderr) and not combine_output:
|
if (result.returncode or result.stderr) and not bool(self.expected_stderr) and not combine_output:
|
||||||
self._node.add_report_section('call', 'ISQL stdout', result.stdout)
|
self._node.add_report_section('call', 'ISQL stdout', result.stdout)
|
||||||
self._node.add_report_section('call', 'ISQL stderr', result.stderr)
|
self._node.add_report_section('call', 'ISQL stderr', result.stderr)
|
||||||
raise ExecutionError("Test script execution failed")
|
raise ExecutionError("Test script execution failed")
|
||||||
@ -1893,7 +1927,7 @@ class Action:
|
|||||||
if connect_db:
|
if connect_db:
|
||||||
params.append(str(self.db.dsn))
|
params.append(str(self.db.dsn))
|
||||||
result: CompletedProcess = run(params, encoding=io_enc, capture_output=True)
|
result: CompletedProcess = run(params, encoding=io_enc, capture_output=True)
|
||||||
if result.returncode and not bool(self.expected_stderr):
|
if (result.returncode or result.stderr) and not bool(self.expected_stderr):
|
||||||
self._node.add_report_section('call', 'gstat stdout', result.stdout)
|
self._node.add_report_section('call', 'gstat stdout', result.stdout)
|
||||||
self._node.add_report_section('call', 'gstat stderr', result.stderr)
|
self._node.add_report_section('call', 'gstat stderr', result.stderr)
|
||||||
raise ExecutionError("gstat execution failed")
|
raise ExecutionError("gstat execution failed")
|
||||||
@ -1957,7 +1991,7 @@ class Action:
|
|||||||
params.extend(['-user', self.db.user, '-password', self.db.password])
|
params.extend(['-user', self.db.user, '-password', self.db.password])
|
||||||
result: CompletedProcess = run(params, input=input,
|
result: CompletedProcess = run(params, input=input,
|
||||||
encoding=io_enc, capture_output=True)
|
encoding=io_enc, capture_output=True)
|
||||||
if result.returncode and not bool(self.expected_stderr):
|
if (result.returncode or result.stderr) and not bool(self.expected_stderr):
|
||||||
self._node.add_report_section('call', 'gsec stdout', result.stdout)
|
self._node.add_report_section('call', 'gsec stdout', result.stdout)
|
||||||
self._node.add_report_section('call', 'gsec stderr', result.stderr)
|
self._node.add_report_section('call', 'gsec stderr', result.stderr)
|
||||||
raise ExecutionError("gsec execution failed")
|
raise ExecutionError("gsec execution failed")
|
||||||
@ -2021,7 +2055,7 @@ class Action:
|
|||||||
result: CompletedProcess = run(params, encoding=io_enc, stdout=PIPE, stderr=STDOUT)
|
result: CompletedProcess = run(params, encoding=io_enc, stdout=PIPE, stderr=STDOUT)
|
||||||
else:
|
else:
|
||||||
result: CompletedProcess = run(params, encoding=io_enc, capture_output=True)
|
result: CompletedProcess = run(params, encoding=io_enc, capture_output=True)
|
||||||
if result.returncode and not (bool(self.expected_stderr) or combine_output):
|
if (result.returncode or result.stderr) and not (bool(self.expected_stderr) or combine_output):
|
||||||
self._node.add_report_section('call', 'gbak stdout', result.stdout)
|
self._node.add_report_section('call', 'gbak stdout', result.stdout)
|
||||||
self._node.add_report_section('call', 'gbak stderr', result.stderr)
|
self._node.add_report_section('call', 'gbak stderr', result.stderr)
|
||||||
raise ExecutionError("gbak execution failed")
|
raise ExecutionError("gbak execution failed")
|
||||||
@ -2084,7 +2118,7 @@ class Action:
|
|||||||
result: CompletedProcess = run(params, encoding=io_enc, stdout=PIPE, stderr=STDOUT)
|
result: CompletedProcess = run(params, encoding=io_enc, stdout=PIPE, stderr=STDOUT)
|
||||||
else:
|
else:
|
||||||
result: CompletedProcess = run(params, encoding=io_enc, capture_output=True)
|
result: CompletedProcess = run(params, encoding=io_enc, capture_output=True)
|
||||||
if result.returncode and not (bool(self.expected_stderr) or combine_output):
|
if (result.returncode or result.stderr) and not (bool(self.expected_stderr) or combine_output):
|
||||||
self._node.add_report_section('call', 'nbackup stdout', result.stdout)
|
self._node.add_report_section('call', 'nbackup stdout', result.stdout)
|
||||||
self._node.add_report_section('call', 'nbackup stderr', result.stderr)
|
self._node.add_report_section('call', 'nbackup stderr', result.stderr)
|
||||||
raise ExecutionError("nbackup execution failed")
|
raise ExecutionError("nbackup execution failed")
|
||||||
@ -2148,7 +2182,7 @@ class Action:
|
|||||||
result: CompletedProcess = run(params, encoding=io_enc, stdout=PIPE, stderr=STDOUT)
|
result: CompletedProcess = run(params, encoding=io_enc, stdout=PIPE, stderr=STDOUT)
|
||||||
else:
|
else:
|
||||||
result: CompletedProcess = run(params, encoding=io_enc, capture_output=True)
|
result: CompletedProcess = run(params, encoding=io_enc, capture_output=True)
|
||||||
if result.returncode and not (bool(self.expected_stderr) or combine_output):
|
if (result.returncode or result.stderr) and not (bool(self.expected_stderr) or combine_output):
|
||||||
self._node.add_report_section('call', 'gfix stdout', result.stdout)
|
self._node.add_report_section('call', 'gfix stdout', result.stdout)
|
||||||
self._node.add_report_section('call', 'gfix stderr', result.stderr)
|
self._node.add_report_section('call', 'gfix stderr', result.stderr)
|
||||||
raise ExecutionError("gfix execution failed")
|
raise ExecutionError("gfix execution failed")
|
||||||
@ -2226,7 +2260,7 @@ class Action:
|
|||||||
else:
|
else:
|
||||||
result: CompletedProcess = run(params, input=input,
|
result: CompletedProcess = run(params, input=input,
|
||||||
encoding=io_enc, capture_output=True)
|
encoding=io_enc, capture_output=True)
|
||||||
if result.returncode and not (bool(self.expected_stderr) or combine_output):
|
if (result.returncode or result.stderr) and not (bool(self.expected_stderr) or combine_output):
|
||||||
self._node.add_report_section('call', 'ISQL stdout', result.stdout)
|
self._node.add_report_section('call', 'ISQL stdout', result.stdout)
|
||||||
self._node.add_report_section('call', 'ISQL stderr', result.stderr)
|
self._node.add_report_section('call', 'ISQL stderr', result.stderr)
|
||||||
raise ExecutionError("ISQL execution failed")
|
raise ExecutionError("ISQL execution failed")
|
||||||
@ -2289,7 +2323,7 @@ class Action:
|
|||||||
if switches is not None:
|
if switches is not None:
|
||||||
params.extend(switches)
|
params.extend(switches)
|
||||||
result: CompletedProcess = run(params, encoding=io_enc, capture_output=True)
|
result: CompletedProcess = run(params, encoding=io_enc, capture_output=True)
|
||||||
if result.returncode and not bool(self.expected_stderr):
|
if (result.returncode or result.stderr) and not bool(self.expected_stderr):
|
||||||
self._node.add_report_section('call', 'fbsvcmgr stdout', result.stdout)
|
self._node.add_report_section('call', 'fbsvcmgr stdout', result.stdout)
|
||||||
self._node.add_report_section('call', 'fbsvcmgr stderr', result.stderr)
|
self._node.add_report_section('call', 'fbsvcmgr stderr', result.stderr)
|
||||||
raise ExecutionError("fbsvcmgr execution failed")
|
raise ExecutionError("fbsvcmgr execution failed")
|
||||||
|
Loading…
Reference in New Issue
Block a user