././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7375436 oslotest-6.1.1/0000775000175000017500000000000015171355730012224 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/.coveragerc0000664000175000017500000000015315171355650014345 0ustar00zuulzuul[run] branch = True source = oslotest omit = oslotest/tests/* [report] ignore_errors = True precision = 2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/.mailmap0000664000175000017500000000013015171355650013640 0ustar00zuulzuul# Format is: # # ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/.pre-commit-config.yaml0000664000175000017500000000130515171355650016505 0ustar00zuulzuulrepos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - id: trailing-whitespace - id: mixed-line-ending args: ['--fix', 'lf'] exclude: '.*\.(svg)$' - id: fix-byte-order-marker - id: check-executables-have-shebangs - id: check-merge-conflict - id: debug-statements - id: check-yaml files: .*\.(yaml|yml)$ - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.14.9 hooks: - id: ruff-check args: ['--fix', '--unsafe-fixes'] - id: ruff-format - repo: https://opendev.org/openstack/hacking rev: 8.0.0 hooks: - id: hacking additional_dependencies: [] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/.stestr.conf0000664000175000017500000000006615171355650014500 0ustar00zuulzuul[DEFAULT] test_path=./oslotest/tests/unit top_path=./ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/.zuul.yaml0000664000175000017500000000032415171355650014165 0ustar00zuulzuul- project: templates: - check-requirements - openstack-cover-jobs - openstack-python3-jobs - periodic-stable-jobs - publish-openstack-docs-pti - release-notes-jobs-python3 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671703.0 oslotest-6.1.1/AUTHORS0000664000175000017500000000600415171355727013302 0ustar00zuulzuulAlessio Ababilov Alex Meade Alexander Gorodnev Andreas Jaeger Angus Salkeld Ben Nemec Brant Knudson Chang Bo Guo ChangBo Guo(gcb) Christian Berendt Chuck Short Claudiu Belu Corey Bryant Danek Duvall Daniel Bengtsson Davanum Srinivas Davanum Srinivas Dirk Mueller Doug Hellmann Doug Hellmann Flavio Percoco George Peristerakis Ghanshyam Ghanshyam Mann Hervé Beraud Ian Wienand Ihar Hrachyshka Ilya Pekelny James Carey Jamie Lennox Jason Kölker Jay Pipes Jeremy Stanley Joe Gordon Joe Heck Jon Grimm Joshua Harlow Julien Danjou Luis A. Garcia Luong Anh Tuan Marc Koderer Mark McLoughlin Masayuki Igawa Mauro S. M. Rodrigues Monty Taylor Noorul Islam K M OpenStack Release Bot Petr Vaněk Rajaram Mallya Ronald Bradford Sean McGinnis Sergey Kraynev Soren Hansen Sorin Sbarnea Stephen Finucane Steve Martinelli Takashi Kajinami Thomas Bechtold Thomas Goirand Tony Breeds Van Hung Pham Victor Stinner Vieri <15050873171@163.com> Vu Cong Tuan Yikun Jiang YuehuiLei Yuriy Taraday ZhijunWei Zhongyue Luo jacky06 kavithahr lingyongxu melissaml niuke qingszhao ricolin songwenping venkatamahesh wanghui wangqi wu.shiming yan.haifeng zhangboye ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/CONTRIBUTING.rst0000664000175000017500000000134015171355650014664 0ustar00zuulzuulIf you would like to contribute to the development of oslo's libraries, first you must take a look to this page: https://specs.openstack.org/openstack/oslo-specs/specs/policy/contributing.html If you would like to contribute to the development of OpenStack, you must follow the steps in this page: http://docs.openstack.org/infra/manual/developers.html Once those steps have been completed, changes to OpenStack should be submitted for review via the Gerrit tool, following the workflow documented at: http://docs.openstack.org/infra/manual/developers.html#development-workflow Pull requests submitted through GitHub will be ignored. Bugs should be filed on Launchpad, not GitHub: https://bugs.launchpad.net/oslotest././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671703.0 oslotest-6.1.1/ChangeLog0000664000175000017500000003251115171355727014006 0ustar00zuulzuulCHANGES ======= 6.1.1 ----- * typing: Broaden type for create\_tempfiles * typing: Indicate type for TIMEOUT\_SCALING\_FACTOR * Remove redundant monkey patching 6.1.0 ----- * ruff: Configure hacking as external linter * mypy: Disabling warnings for untyped imports * Add typing classifier * Add mypy * typing: Add initial types * Remove unused dependency * Enable logging related ruff checks * Delay string interpolations at logging calls * Remove reference to tag framework * ruff: Use more specific name to enable pyupgrade rule 6.0.0 ----- * Add ruff * Remove cross-testing functionality * Bump pyupgrade target to 3.10+ * pre-commit: Bump dependencies * Migrate setup configuration to pyproject.toml * Drop Python 3.8, 3.9 support * add pyproject.toml to support pip 23.1 5.0.1 ----- * Run pyupgrade to clean up Python 2 syntaxes * pre-commit: Bump versions * Declare Python 3.12 support * Remove old excludes * reno: Update master for unmaintained/victoria 5.0.0 ----- * Bump hacking * Update python classifier in setup.cfg * pre-commit: Bump versions * tox: Bump minimum to tox 4.x * Remove usage of six * Replace find\_module function * Revert "Moves supported python runtimes from version 3.8 to 3.10" * Moves supported python runtimes from version 3.8 to 3.10 * Cleanup py27 support * Fix formatting of release list * Drop python3.6/3.7 support in testing runtime * Remove unnecessary unicode prefixes * Update CI to use unversioned jobs template 4.5.0 ----- * setup.cfg: Replace dashes with underscores * Use TOX\_CONSTRAINTS\_FILE * Document unit of measure for OS\_TEST\_TIMEOUT * Move flake8 as a pre-commit local target * Remove lower-constraints remnants * Dropping lower constraints testing * Use TOX\_CONSTRAINTS\_FILE * Use py3 as the default runtime for tox * Adding pre-commit * Add Python3 wallaby unit tests * Update master for stable/victoria 4.4.1 ----- 4.4.0 ----- 4.3.0 ----- * Stop to use the \_\_future\_\_ module * Switch to newer openstackdocstheme and reno versions * Align contributing doc with oslo's policy * Bump default tox env from py37 to py38 * Add py38 package metadata * Add release notes links to doc index * Add Python3 victoria unit tests * Update master for stable/ussuri * Revert "Revert "Switch to unittest.mock from mock"" 4.2.0 ----- * Revert "Switch to unittest.mock from mock" 4.1.0 ----- * Switch to unittest.mock from mock * Remove os-client-config and debtcollector 4.0.0 ----- * Remove 'oslotest.functional' * Remove 'oslotest.moxstubout' module * remove outdated header * gitignore: Ignore reno artefacts * [ussuri][goal] Drop python 2.7 support and testing * trivial: Cleanup of doc config file * tox: Trivial cleanup * tools: Default to Python 3 3.9.0 ----- * Invoke correct python version in shell scripts * Switch to Ussuri jobs * Update master for stable/train 3.8.1 ----- * Add Python 3 Train unit tests 3.8.0 ----- * Sync Sphinx requirement * Replace git.openstack.org URLs with opendev.org URLs * Stop testing mock functionality * OpenDev Migration Patch * Dropping the py35 testing * Replace openstack.org git:// URLs with https:// * Update master for stable/stein 3.7.1 ----- * Change python3.5 job to python3.7 job on Stein+ * Update hacking version * Change openstack-dev to openstack-discuss * Title underline too long * Remove stestr from requirements.txt * Don't quote {posargs} in tox.ini * Fix nits in timeout change 3.7.0 ----- * Add DEFAULT\_TIMEOUT and TIMEOUT\_SCALING\_FACTOR * Use templates for cover and lower-constraints * Fix requirements check ci in oslotest * add python 3.6 unit test job * import zuul job settings from project-config * Update reno for stable/rocky * Add release note link in README 3.6.0 ----- * Switch to using stestr * fix tox python3 overrides 3.5.0 ----- * Deprecate MoxStubout class * Fix requirements * mock: Perform patch's autospec checks on \_\_enter\_\_ 3.4.2 ----- * Trivial: Update pypi url to new url * set default python to python3 * mock: Apply autospec to a mock's return\_value 3.4.1 ----- * mock: Properly patch mock.MagicMock 3.4.0 ----- * add lower-constraints job * make the CaptureOutput fixture easier to control * Updated from global requirements 3.3.0 ----- * Updated from global requirements * Update links in README * Update reno for stable/queens * Updated from global requirements * Updated from global requirements * mock: Fixes mock.patch.multiple autospec 3.2.0 ----- * Adds mock autospec fixture 3.1.0 ----- * Remove -U from pip install * Avoid tox\_install.sh for constraints support * Updated from global requirements * Remove setting of version/release from releasenotes * Updated from global requirements 3.0.0 ----- 2.18.1 ------ 2.18.0 ------ * Updated from global requirements * Updated from global requirements * Deprecate oslotest.functional * Remove oslotest.mockpatch * Updated from global requirements * Updated from global requirements * Update reno for stable/pike * Updated from global requirements 2.17.0 ------ * Update URLs in documents according to document migration * Use assertIsNone(...) instead of assertIs(None,...) * rearrange content to fit the new standard layout * Using fixtures instead of deprecated mockpatch module 2.16.1 ------ * Switch from oslosphinx to openstackdocstheme 2.16.0 ------ * Updated from global requirements * Trivial fix style in document * Updated from global requirements * Remove pbr warnerrors in favor of sphinx check * Updated from global requirements * Updated from global requirements * Updated from global requirements * Updated from global requirements * Updated from global requirements 2.15.0 ------ * Updated from global requirements * Remove support for py34 2.14.0 ------ * Updated from global requirements * [Fix gate]Update test requirement * Updated from global requirements * Update reno for stable/ocata * Updated from global requirements 2.13.0 ------ * Add Constraints support * Show team and repo badges on README 2.12.0 ------ * Updated from global requirements * Add reno for release notes management * Updated from global requirements * Updated from global requirements * Changed the home-page link 2.11.0 ------ * Remove testscenarios from requirements * Updated from global requirements * Updated from global requirements * Updated from global requirements 2.10.0 ------ * Updated from global requirements 2.9.0 ----- * Updated from global requirements 2.8.0 ----- * Import mock so that it works on Python 3.x * Fix parameters of assertEqual are misplaced * Updated from global requirements * Add Python 3.5 classifier and venv * A DisableModules fixture that removes modules from path 2.7.0 ----- * Updated from global requirements 2.6.0 ----- * Updated from global requirements 2.5.0 ----- * Remove mockpatch re-implementations * Updated from global requirements * Updated from global requirements * Updated from global requirements 2.3.0 ----- * Add some gitignore files 2.2.0 ----- * move unit tests into the oslotest package * Updated from global requirements * Hack to get back stopall cleanup behavior feature * Fix misspelling 2.1.0 ----- * Updated from global requirements * Updated from global requirements * Updated from global requirements * Trival: Remove 'MANIFEST.in' 2.0.0 ----- * Updated from global requirements * Remove Python 2.6 classifier * mockpatch: deprecate in favor of native fixtures * Remove python 2.6 and cleanup tox.ini * Updated from global requirements 1.12.0 ------ * Fix coverage configuration and execution * Updated from global requirements * Add documentation about using oslo\_debug\_helper * add oslo.config a test requirement * clean up readme and doc title * clean up toctree * auto-generate API documentation * Fix the home-page with Oslotest wikipage * Fixup docstrings * Updated from global requirements 1.11.0 ------ * Updated from global requirements 1.10.0 ------ * Allow TRACE and integer logging levels for 'OS\_DEBUG' * Updated from global requirements * Updated from global requirements * Updated from global requirements 1.9.0 ----- * Fix use of mock * Updated from global requirements * Add documentation for cross-project unit testing * Updated from global requirements * Fix build break with Fixtures 1.3 * Updated from global requirements 1.8.0 ----- * Updated from global requirements * Allow \`\`OS\_DEBUG\`\` environment variable to specify log level * Updated from global requirements * always rebuild cross-test venv * Add CreateFileWithContent fixture * Create ConfigureLogging fixture * Create CaptureOutput fixture * Create Timeout wrapper fixture * Document the mock attribute for mockpatch 1.7.0 ----- * Updated from global requirements * Fix argument handling in oslo\_run\_cross\_tests * Add class to deal with clouds.yaml support * Remove unneeded runtime pbr dep * Updated from global requirements * Advertise support for Python3.4 / Remove support for Python 3.3 * Do not sync run\_cross\_tests.sh * Remove unused discover dependency 1.6.0 ----- * Uncap library requirements for liberty * Cleanup README.rst and setup.cfg * mockpatch: factorize code * Update to latest hacking * Updated from global requirements * mockpatch: fix a potential race condition 1.5.1 ----- 1.5.0 ----- * Force rebuild egg-info before running cross tests * Restore missing module for pre-release test script * Updated from global requirements 1.4.0 ----- * Set a higher default for maxDiff * Move the script for running pre-releases into oslotest * Update docs for new script name * Publish cross-test runner as part of oslotest * Remove six.moves call * Fix for mktemp failure on osx * Activate pep8 check that \_ is imported * Workflow documentation is now in infra-manual * Fix the URL for reporting bugs in the README 1.3.0 ----- * Updated from global requirements * Updated from global requirements * Updated from global requirements * Add pbr to installation requirements * Clean up the docs for oslo\_debug\_helper 1.2.0 ----- * Updated from global requirements * Set install\_command in tox to avoid pre-releases * Add an extra parameter for test directory in debugger script * Handle tempfile content encoding * Work toward Python 3.4 support and testing * Add links to best practices video and etherpad * Updated from global requirements * Drop .sh extension from oslo\_debug\_helper.sh * Add history/changelog to docs * fix typo and formatting in contributing docs 1.1.0 ----- * warn against sorting requirements * Add fixture for mock.patch.multiple * Ensure that mock.patch.stopall is called last * Remove differences between Python 2.x and 3.x versions * Require six * Add documentation for running oslo\_debug\_heler.sh * Restructure oslotest docs * Add pdb support to tox with debug helper shell script * Updated from global requirements * Cleaning up index.rst file * Add known issue about time.time mocking * Updated from global requirements * Add API documentation * Moving to use the mock module found in Python3 1.1.0.0a1 --------- * Update to hacking 0.9.2 * Cleanup mock patches on BaseTestCase tearDown() * Add unit test for olsotest base class * fix .gitreview after rename * Sync new sphinx requirement spec * Set log level to default value * Updated from global requirements * Update cross-test directions * Update project name in doc build 1.0.0 ----- * Import run\_cross\_tests.sh from oslo-incubator * Fix up documentation files * Fake logger as instance attribute * Require testrepository and other tools at runtime * Updated from global requirements * Add tool to run cross-project tests 0.1 --- * Rename oslo.test to oslotest * Add test for moxstubout * Switch to oslosphinx * Sync requirements and fix pep8 errors * Remove oslo.test.fixture * Remove unused tempdirs attribute * Remove translations infrastructure * apply oslo-cookiecutter * Differentiate runtime and test requirements * flatten package hierarchy * remove dependency on oslo.config to avoid cycle * Remove lockutils fixture from this library * Run python 3.3 tests first to set testr db type * Add packaging and test control files * rearrange files into the proper package * Generalize base test case into common code * Add 'new' parameter to mock.Patch and mock.PatchObject classes * Make the log capture in tests more configurable * log all test messages not just oslo ones * Fix violations of H302:import only modules * Trivial: Make vertical white space after license header consistent * Remove vim header * Fix copyright header on test module * Use cleaner version from cookiecutter OpenStack template * Add TempHomeDir fixture which is already part of cookiecutter template * Fix typos in oslo * Move LockFixture into a fixtures module * Consolidate the use of stubs * Make openstack.common.fixture.config Py3 compliant * Using NestedTempfile in new BaseTestCase class * Bump hacking to 0.7.0 * Add a fixture for dealing with config * Add common part of test-related tools to oslo * Add eclipse project files to .gitignore * Add .testrepository to .gitignore * Ignore backup files in .gitignore * Add join\_consumer\_pool() to RPC connections * Add a fixture for dealing with mock patching * Start adding reusable test fixtures * updating sphinx documentation * Correcting openstack-common mv to oslo-incubator * Update .gitreview for oslo * .gitignore updates for generated files * Updated tox config for multi-python testing * Added .gitreview file * ignore cover's html directory * Rajaram/Vinkesh|increased tests for Request and Response serializers * Rajaram/Vinkesh|Added nova's serializaiton classes into common * Initial skeleton project ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/HACKING.rst0000664000175000017500000000017015171355650014021 0ustar00zuulzuulStyle Commandments ================== Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/LICENSE0000664000175000017500000002363615171355650013244 0ustar00zuulzuul Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7365434 oslotest-6.1.1/PKG-INFO0000644000175000017500000000340015171355730013314 0ustar00zuulzuulMetadata-Version: 2.4 Name: oslotest Version: 6.1.1 Summary: Oslo test framework Author-email: OpenStack Project-URL: Homepage, https://docs.openstack.org/oslotest Project-URL: Repository, https://opendev.org/openstack/oslotest Classifier: Environment :: OpenStack Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Information Technology Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Typing :: Typed Requires-Python: >=3.10 Description-Content-Type: text/x-rst License-File: LICENSE Requires-Dist: fixtures>=3.0.0 Requires-Dist: testtools>=2.2.0 Dynamic: license-file Dynamic: requires-dist ===================================================== oslotest -- OpenStack Testing Framework and Utilities ===================================================== .. image:: https://governance.openstack.org/tc/badges/oslotest.svg .. Change things from this point on The Oslo Test framework provides common fixtures, support for debugging, and better support for mocking results. * Free software: Apache license * Documentation: https://docs.openstack.org/oslotest/latest/ * Source: https://opendev.org/openstack/oslotest * Bugs: https://bugs.launchpad.net/oslotest * Release notes: https://docs.openstack.org/releasenotes/oslotest ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/README.rst0000664000175000017500000000117215171355650013715 0ustar00zuulzuul===================================================== oslotest -- OpenStack Testing Framework and Utilities ===================================================== .. image:: https://governance.openstack.org/tc/badges/oslotest.svg .. Change things from this point on The Oslo Test framework provides common fixtures, support for debugging, and better support for mocking results. * Free software: Apache license * Documentation: https://docs.openstack.org/oslotest/latest/ * Source: https://opendev.org/openstack/oslotest * Bugs: https://bugs.launchpad.net/oslotest * Release notes: https://docs.openstack.org/releasenotes/oslotest ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7155423 oslotest-6.1.1/doc/0000775000175000017500000000000015171355730012771 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/requirements.txt0000664000175000017500000000022715171355650016257 0ustar00zuulzuulsphinx>=2.0.0 # BSD openstackdocstheme>=2.2.0 # Apache-2.0 sphinxcontrib-apidoc>=0.2.0 # BSD oslo.config>=5.2.0 # Apache-2.0 reno>=3.1.0 # Apache-2.0 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7165422 oslotest-6.1.1/doc/source/0000775000175000017500000000000015171355730014271 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/conf.py0000664000175000017500000000372515171355650015600 0ustar00zuulzuul# Copyright (C) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'openstackdocstheme', 'sphinxcontrib.apidoc', ] modindex_common_prefix = ['oslotest.'] # The master toctree document. master_doc = 'index' # General information about the project. copyright = '2014-2019, OpenStack Foundation' # If true, '()' will be appended to :func: etc. cross-reference text. add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). add_module_names = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. html_theme = 'openstackdocs' # -- openstackdocstheme configuration ---------------------------------------- openstackdocs_repo_name = 'openstack/oslotest' openstackdocs_bug_project = 'oslotest' openstackdocs_bug_tag = '' # sphinxcontrib.apidoc options apidoc_module_dir = '../../oslotest' apidoc_output_dir = 'reference/api' apidoc_excluded_paths = ['tests/*', 'tests'] apidoc_separate_modules = True ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7175424 oslotest-6.1.1/doc/source/contributor/0000775000175000017500000000000015171355730016643 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/contributor/index.rst0000664000175000017500000000011715171355650020504 0ustar00zuulzuul============ Contributing ============ .. include:: ../../../CONTRIBUTING.rst ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/index.rst0000664000175000017500000000076215171355650016140 0ustar00zuulzuul===================================================== oslotest -- OpenStack Testing Framework and Utilities ===================================================== Contents ======== .. toctree:: :maxdepth: 2 install/index contributor/index user/index reference/index Release Notes ============= Read also the `oslotest Release Notes `_. Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7175424 oslotest-6.1.1/doc/source/install/0000775000175000017500000000000015171355730015737 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/install/index.rst0000664000175000017500000000013215171355650017575 0ustar00zuulzuul============ Installation ============ At the command line:: $ pip install oslotest ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7175424 oslotest-6.1.1/doc/source/reference/0000775000175000017500000000000015171355730016227 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/reference/index.rst0000664000175000017500000000010615171355650020066 0ustar00zuulzuul.. _using: API === .. toctree:: :maxdepth: 1 api/modules.rst ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7195425 oslotest-6.1.1/doc/source/user/0000775000175000017500000000000015171355730015247 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/user/debugging.rst0000664000175000017500000000106315171355650017735 0ustar00zuulzuul=============== Debugging Tests =============== Running tests through testrepository_ makes it difficult to use pdb for debugging them. oslotest includes ``oslo_debug_helper`` to make using pdb simpler/possible. First, add a pdb call to the test code:: import pdb; pdb.set_trace() Then run the tests through ``oslo_debug_helper`` like :: $ oslo_debug_helper [tests to run] or :: $ tox -e venv -- oslo_debug_helper [tests to run] .. seealso:: * https://wiki.openstack.org/wiki/Testr .. _testrepository: https://pypi.org/project/testrepository ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/user/features.rst0000664000175000017500000000340015171355650017615 0ustar00zuulzuul======== Features ======== Debugging with oslo_debug_helper ================================ The oslotest package also distributes a shell file that may be used to assist in debugging python code. The shell file uses testtools, and supports debugging with `pdb `_. Adding breakpoints to the code ------------------------------ The typical usage to break into the debugger from a running program is to insert: .. code-block:: python import pdb; pdb.set_trace() Update tox.ini -------------- Within the ``tox.ini`` file of your project add the following:: [testenv:debug] commands = oslo_debug_helper {posargs} If the project name, and the module that precedes the tests directory do not match, then consider passing a `-t` argument to `oslo_debug_helper` to indicate the directory where tests are located. For example, the ``python-keystoneclient`` project has tests in ``keystoneclient/tests``, thus it would have to pass in:: [testenv:debug] commands = oslo_debug_helper -t keystoneclient/tests {posargs} Similarly, most ``oslo`` projects have the tests at the package level, it would have to pass in:: [testenv:debug] commands = oslo_debug_helper -t tests {posargs} Debugging with tox ------------------ To enable debugging, run tox with the ``debug`` environment: .. code-block:: bash $ tox -e debug $ tox -e debug test_notifications $ tox -e debug test_notifications.NotificationsTestCase $ tox -e debug test_notifications.NotificationsTestCase.test_send_notification Which results in an interactive prompt: .. code-block:: bash > /opt/stack/ceilometer/ceilometer/tests/identity/test_notifications.py(106)notification_for_role_change() -> action_name = '%s.%s' % (action, ROLE_ASSIGNMENT) (Pdb) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/user/history.rst0000664000175000017500000000004015171355650017475 0ustar00zuulzuul.. include:: ../../../ChangeLog ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/user/index.rst0000664000175000017500000000023115171355650017105 0ustar00zuulzuul============== Using oslotest ============== .. toctree:: :maxdepth: 2 features debugging testing mock-autospec resources history ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/user/mock-autospec.rst0000664000175000017500000000616715171355650020566 0ustar00zuulzuul============= Mock autospec ============= In typical unit tests, almost all of the dependencies are mocked or patched (``mock.patch``), without any guarantee that the mocked methods actually exist, or if their signatures are respected. Because of this, actual issues can be easily overlooked and missed, as the unit tests are wrongfully passing. The ``mock.Mock`` class accepts a spec as an argument, which only solves half the problem: it only checks if an attribute exists, based on the given spec. It does not guarantee that the given attribute is actually a method, or if its signature is respected. The Mock class does not accept an autospec argument [1]. ``mock.patch``, ``mock.patch.object``, ``mock.patch.multiple`` accept an autospec argument, but because of a bug [2], it cannot be used properly. oslotest offers a solution for problems mentioned above. 1. https://github.com/testing-cabal/mock/issues/393 2. https://github.com/testing-cabal/mock/issues/396 Patching the ``mock`` module ============================ The ``oslotest.mock_fixture`` module contains 2 components: - patch_mock_module - MockAutospecFixture Both components need to be used in order to fix various issues within ``mock`` regarding autospec. patch_mock_module ----------------- At the moment, ``mock.patch``, ``mock.patch.object``, ``mock.patch.multiple`` accepts the ``autospec`` argument, but it does not correctly consume the self / cls argument of methods or class methods. ``patch_mock_module`` addresses this issue. In order to make sure that the original version of ``mock.patch`` is not used by the unit tests, this function has to be called as early as possible within the test module, or the base test module. E.g.:: nova/test.py ... from oslotest import mock_fixture mock_fixture.patch_mock_module() Additionally, this function will set the ``autospec`` argument's value to ``True``, unless otherwise specified or these arguments are passed in: ``new_callable, create, spec``. MockAutospecFixture ------------------- ``mock.Mock`` and ``mock.MagicMock`` classes do not accept any ``autospec`` argument. This fixture will replace the ``mock.Mock`` and ``mock.MagicMock`` classes with subclasses which accepts the said argument. The fixture can be used in the test ``setUp`` method. E.g.:: nova/test.py ... from oslotest import mock_fixture class TestCase(testtools.TestCase): def setUp(self): super(TestCase, self).setUp() self.useFixture(mock_fixture.MockAutospecFixture()) Mock autospec usage =================== Consider the following class as an example:: class Foo(object): def bar(self, a, b, c, d=None): pass Using the setup described above, the following unit tests will now pass correctly:: class FooTestCase(TestCase): def test_mock_bar(self): mock_foo = mock.Mock(autospec=Foo) self.assertRaises(TypeError, mock_foo.bar, invalid='argument') @mock.patch.object(Foo, 'bar', autospec=True) def test_patch_bar(self, mock_bar): foo = Foo() self.assertRaises(TypeError, foo.bar, invalid='argument') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/user/resources.rst0000664000175000017500000000052515171355650020016 0ustar00zuulzuul====================== Other Useful Resources ====================== * Mock_ library documentation * OpenStack Bootstrapping Hour: Mock Best Practices: `video `__ and `etherpad `__ .. _Mock: http://www.voidspace.org.uk/python/mock/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/doc/source/user/testing.rst0000664000175000017500000000020615171355650017455 0ustar00zuulzuul======= Testing ======= oslotest can be tested via ``tox``, like any other OpenStack project: .. code-block:: shell tox -e py3 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7225425 oslotest-6.1.1/oslotest/0000775000175000017500000000000015171355730014100 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/__init__.py0000664000175000017500000000000015171355650016200 0ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/base.py0000664000175000017500000001551715171355650015376 0ustar00zuulzuul# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Common utilities used in testing""" from collections.abc import Callable, Iterable import logging from typing import Any from unittest import mock import fixtures from oslotest import createfile from oslotest import log from oslotest import output from oslotest import timeout import testtools LOG = logging.getLogger(__name__) _TRUE_VALUES = ('True', 'true', '1', 'yes') _LOG_FORMAT = '%(levelname)8s [%(name)s] %(message)s' class BaseTestCase(testtools.TestCase): """Base class for unit test classes. If the environment variable ``OS_TEST_TIMEOUT`` is set to an integer value (**seconds**), a timer is configured to control how long individual test cases can run. This lets tests fail for taking too long, and prevents deadlocks from completely hanging test runs. The class variable ``DEFAULT_TIMEOUT`` can be set to configure a test suite default test value for cases in which ``OS_TEST_TIMEOUT`` is not set. It defaults to ``0``, which means no timeout. The class variable ``TIMEOUT_SCALING_FACTOR`` can be set on an individual test class for tests that reasonably take longer than the rest of the test suite so that the overall timeout can be kept small. It defaults to ``1``. If the environment variable ``OS_STDOUT_CAPTURE`` is set, a fake stream replaces ``sys.stdout`` so the test can look at the output it produces. If the environment variable ``OS_STDERR_CAPTURE`` is set, a fake stream replaces ``sys.stderr`` so the test can look at the output it produces. If the environment variable ``OS_DEBUG`` is set to a true value, debug logging is enabled. Alternatively, the ``OS_DEBUG`` environment variable can be set to a valid log level. If the environment variable ``OS_LOG_CAPTURE`` is set to a true value, a logging fixture is installed to capture the log output. Uses the fixtures_ module to configure a :class:`NestedTempFile` to ensure that all temporary files are created in an isolated location. Uses the fixtures_ module to configure a :class:`TempHomeDir` to change the ``HOME`` environment variable to point to a temporary location. PLEASE NOTE: Usage of this class may change the log level globally by setting the environment variable ``OS_DEBUG``. A mock of ``time.time`` will be called many more times than might be expected because it's called often by the logging module. A usage of such a mock should be avoided when a test needs to verify logging behavior or counts the number of invocations. A workaround is to overload the ``_fake_logs`` function in a base class but this will deactivate fake logging globally. .. _fixtures: https://pypi.org/project/fixtures """ DEFAULT_TIMEOUT = 0 TIMEOUT_SCALING_FACTOR: int | float = 1 def __init__( self, methodName: str = 'runTest', runTest: Any = None, ) -> None: super().__init__(methodName=methodName, runTest=runTest) # This is the number of characters shown when two objects do not # match for assertDictEqual, assertMultiLineEqual, and # assertSequenceEqual. The default is 640 which is too # low for comparing most dicts self.maxDiff = 10000 def addCleanup( self, cleanup: Callable[..., object], /, *args: object, **kwargs: object, ) -> None: # NOTE(dims): This is a hack for Mitaka. We'll need to undo this as # early as possible in Newton and advertise that this hack will not # be supported anymore. if hasattr(self, '_cleanups') and isinstance(self._cleanups, list): if not self._cleanups: # Ensure that the mock.patch.stopall cleanup is registered # before any addCleanup() methods have a chance to register # other things to be cleaned up, so it is called last. This # allows tests to register their own cleanups with a mock.stop # method so those mocks are not included in the stopall set. super().addCleanup(mock.patch.stopall) else: LOG.error( 'Unable to patch test case. ' 'mock.patch.stopall cleanup was not registered.' ) super().addCleanup(cleanup, *args, **kwargs) def setUp(self) -> None: super().setUp() self._set_timeout() self._fake_output() self._fake_logs() self.useFixture(fixtures.NestedTempfile()) self.useFixture(fixtures.TempHomeDir()) def _set_timeout(self) -> None: self.useFixture( timeout.Timeout( default_timeout=self.DEFAULT_TIMEOUT, scaling_factor=self.TIMEOUT_SCALING_FACTOR, ) ) def _fake_output(self) -> None: self.output_fixture = self.useFixture(output.CaptureOutput()) def _fake_logs(self) -> None: self.log_fixture = self.useFixture(log.ConfigureLogging()) def create_tempfiles( self, files: Iterable[ tuple[str, str | bytes, str] | tuple[str, str | bytes] ], ext: str = '.conf', default_encoding: str = 'utf-8', ) -> list[str]: """Safely create temporary files. :param files: Sequence of tuples containing ``(filename, file_contents)`` or ``(filename, file_contents, encoding)``. :param ext: File name extension for the temporary file. :param default_encoding: Default file content encoding when it is not provided. Used to decode the tempfile contents from a text string into a binary string. :return: A list of str with the names of the files created. """ tempfiles = [] for f in files: if len(f) == 3: basename, contents, encoding = f else: basename, contents = f encoding = default_encoding fix = self.useFixture( createfile.CreateFileWithContent( filename=basename, contents=contents, ext=ext, encoding=encoding, ) ) tempfiles.append(fix.path) return tempfiles ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/createfile.py0000664000175000017500000000454615171355650016567 0ustar00zuulzuul# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os import tempfile import fixtures class CreateFileWithContent(fixtures.Fixture): """Create a temporary file with the given content. Creates a file using a predictable name, to be used by tests for code that need a filename to load data or otherwise interact with the real filesystem. .. warning:: It is the responsibility of the caller to ensure that the file is removed. Users of this fixture may also want to use :class:`fixtures.NestedTempfile` to set the temporary directory somewhere safe and to ensure the files are cleaned up. :param filename: Base file name or full literal path to the file to be created. :param contents: The data to write to the file. Unicode data will be encoded before being written. :param ext: An extension to add to filename. :param encoding: An encoding to use for unicode data (ignored for byte strings). """ #: The canonical name of the file created. path: str def __init__( self, filename: str, contents: str | bytes, ext: str = '.conf', encoding: str = 'utf-8', ) -> None: self._filename = filename self._contents = contents self._ext = ext self._encoding = encoding def setUp(self) -> None: super().setUp() contents = self._contents if isinstance(contents, str): contents = contents.encode(self._encoding) if not os.path.isabs(self._filename): fd, self.path = tempfile.mkstemp( prefix=self._filename, suffix=self._ext ) else: self.path = self._filename + self._ext fd = os.open(self.path, os.O_CREAT | os.O_WRONLY) try: os.write(fd, contents) finally: os.close(fd) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/log.py0000664000175000017500000000612515171355650015240 0ustar00zuulzuul# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging import os from typing import Any import fixtures _TRUE_VALUES = ('True', 'true', '1', 'yes') _FALSE_VALUES = ('False', 'false', '0', 'no') _BASE_LOG_LEVELS = ('DEBUG', 'INFO', 'WARN', 'WARNING', 'ERROR', 'CRITICAL') _LOG_LEVELS = {n: getattr(logging, n) for n in _BASE_LOG_LEVELS} _LOG_LEVELS.update( { 'TRACE': 5, } ) def _try_int(value: Any) -> int | None: """Try to make some value into an int.""" try: return int(value) except (ValueError, TypeError): return None class ConfigureLogging(fixtures.Fixture): """Configure logging. The behavior is managed through two environment variables. If ``OS_DEBUG`` is true then the logging level is set to debug. If ``OS_LOG_CAPTURE`` is true a FakeLogger is configured. Alternatively, ``OS_DEBUG`` can be set to an explicit log level, such as ``INFO``. "True" values include ``True``, ``true``, ``1`` and ``yes``. Valid log levels include ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR``, ``TRACE`` and ``CRITICAL`` (or any other valid integer logging level). .. py:attribute:: logger The logger fixture, if it is created. .. py:attribute:: level ``logging.DEBUG`` if debug logging is enabled, otherwise the log level specified by ``OS_DEBUG``, otherwise ``None``. :param format: The logging format string to use. """ DEFAULT_FORMAT = "%(levelname)8s [%(name)s] %(message)s" """Default log format""" def __init__(self, format: str = DEFAULT_FORMAT) -> None: super().__init__() self._format = format self.level = 0 _os_debug = os.environ.get('OS_DEBUG') _os_level = _try_int(_os_debug) if _os_debug in _TRUE_VALUES: self.level = logging.DEBUG elif _os_level is not None: self.level = _os_level elif _os_debug in _LOG_LEVELS: self.level = _LOG_LEVELS[_os_debug] elif _os_debug and _os_debug not in _FALSE_VALUES: raise ValueError(f'OS_DEBUG={_os_debug} is invalid.') self.capture_logs = os.environ.get('OS_LOG_CAPTURE') in _TRUE_VALUES self.logger: fixtures.FakeLogger | None = None def setUp(self) -> None: super().setUp() if self.capture_logs: self.logger = self.useFixture( fixtures.FakeLogger( format=self._format, level=self.level, nuke_handlers=True, ) ) else: logging.basicConfig(format=self._format, level=self.level) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/mock_fixture.py0000664000175000017500000001644215171355650017161 0ustar00zuulzuul# Copyright 2017 Cloudbase Solutions Srl # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from __future__ import annotations import functools from typing import Any, TypeVar, TYPE_CHECKING from unittest import mock import fixtures _T = TypeVar('_T') def _lazy_autospec_method( mocked_method: Any, original_method: Any, eat_self: bool, ) -> None: if mocked_method._mock_check_sig.__dict__.get('autospeced'): return _lazy_autospec: Any = mock.create_autospec(original_method) if eat_self: # consume self argument. _lazy_autospec = functools.partial(_lazy_autospec, None) def _autospeced(*args: Any, **kwargs: Any) -> None: _lazy_autospec(*args, **kwargs) # _mock_check_sig is called by the mock's __call__ method. # which means that if a method is not called, _autospeced is not # called. _autospeced.__dict__['autospeced'] = True mocked_method._mock_check_sig = _autospeced class _AutospecMockMixin: """Mock object that lazily autospecs the given spec's methods.""" # These are defined by mock.Mock but we need to declare them for typing return_value: Any def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) autospec = kwargs.get('autospec') self.__dict__['_autospec'] = autospec _mock_methods = self.__dict__['_mock_methods'] if _mock_methods: # this will allow us to be able to set _mock_check_sig if # the spec_set argument has been given. _mock_methods.append('_mock_check_sig') # callable mocks with autospecs (e.g.: the given autospec is a class) # should have their return values autospeced as well. if autospec: self.return_value.__dict__['_autospec'] = autospec def __getattr__(self, name: str) -> Any: attr = super().__getattr__(name) # type: ignore[misc] original_spec = self.__dict__['_autospec'] if not original_spec: return attr if not hasattr(original_spec, name): raise AttributeError(name) # check if the original attribute is callable, and the mock was not # autospeced already. original_attr = getattr(original_spec, name) if callable(original_attr): # lazily autospec callable attribute. # NOTE: _must_skip is a private function in the mock module eat_self = mock._must_skip( # type: ignore[attr-defined] original_spec, name, isinstance(original_spec, type) ) _lazy_autospec_method(attr, original_attr, eat_self) return attr class _AutospecMock(_AutospecMockMixin, mock.Mock): pass class _AutospecMagicMock(_AutospecMockMixin, mock.MagicMock): pass class MockAutospecFixture(fixtures.Fixture): """A fixture to add / fix the autospec feature into the mock library. The current version of the mock library has a few unaddressed issues, which can lead to erroneous unit tests, and can hide actual issues. This fixture is to be removed once these issues have been addressed in the mock library. Issue addressed by the fixture: * mocked method's signature checking: - https://github.com/testing-cabal/mock/issues/393 - mock can only accept a spec object / class, and it makes sure that that attribute exists, but it does not check whether the given attribute is callable, or if its signature is respected in any way. - adds autospec argument. If the autospec argument is given, the mocked method's signature is also checked. """ def setUp(self) -> None: super().setUp() # patch both external and internal usage of Mock / MagicMock. self.useFixture( fixtures.MonkeyPatch('unittest.mock.Mock', _AutospecMock) ) self.useFixture( fixtures.MonkeyPatch('unittest.mock.MagicMock', _AutospecMagicMock) ) if TYPE_CHECKING: Base = mock._patch else: # as of Python 3.13 this is not subscriptable at runtime class Base(mock._patch): def __class_getitem__(cls, _): return cls class _patch(Base[_T]): """Patch class with working autospec functionality. Currently, mock.patch functionality doesn't handle the autospec parameter properly (the self argument is not consumed, causing assertions to fail). Until the issue is addressed in the mock library, this should be used instead. https://github.com/testing-cabal/mock/issues/396 """ def __enter__(self) -> _T: # NOTE(claudiub): we're doing the autospec checks here so unit tests # have a chance to set up mocks in advance (e.g.: mocking platform # specific libraries, which would cause the patch to fail otherwise). # By default, autospec is None. We will consider it as True. autospec = True if self.autospec is None else self.autospec # in some cases, autospec cannot be set to True. skip_autospec = ( getattr(self, attr) for attr in ['new_callable', 'create', 'spec'] ) # NOTE(claudiub): The "new" argument is always mock.DEFAULT, unless # explicitly set otherwise. if self.new is not mock.DEFAULT or any(skip_autospec): # cannot autospec if new, new_callable, or create arguments given. autospec = False elif self.attribute: target = getattr(self.getter(), self.attribute, None) if isinstance(target, mock.Mock): # NOTE(claudiub): shouldn't autospec already mocked targets. # this can cause some issues. There are quite a few tests # which patch mocked methods. autospec = False # NOTE(claudiub): reset the self.autospec property, so we can handle # the autospec scenario ourselves. self.autospec = None if autospec: target = self.getter() original_attr = getattr(target, self.attribute) # NOTE: _must_skip is a private function in the mock module eat_self = mock._must_skip( # type: ignore[attr-defined] target, self.attribute, isinstance(target, type) ) new = super().__enter__() # NOTE(claudiub): mock.patch.multiple will cause new to be a # dict. mocked_method = ( new[self.attribute] if isinstance(new, dict) else new ) _lazy_autospec_method(mocked_method, original_attr, eat_self) return new else: return super().__enter__() def patch_mock_module() -> None: """Replaces the mock.patch class.""" # NOTE: _patch is a private class in the mock module mock._patch = _patch # type: ignore[misc] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/modules.py0000664000175000017500000000352415171355650016127 0ustar00zuulzuul# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from collections.abc import Sequence from importlib.machinery import ModuleSpec import sys from types import ModuleType import fixtures class DisableModuleFixture(fixtures.Fixture): """A fixture to provide support for unloading/disabling modules.""" def __init__(self, module: str): super().__init__() self.module = module def setUp(self) -> None: """Ensure ImportError for the specified module.""" super().setUp() cleared_modules = {} for name in list(sys.modules.keys()): if name == self.module or name.startswith(self.module + '.'): cleared_modules[name] = sys.modules.pop(name) finder = _NoModuleFinder(self.module) sys.meta_path.insert(0, finder) self.addCleanup(sys.meta_path.remove, finder) self.addCleanup(sys.modules.update, cleared_modules) class _NoModuleFinder: """Disallow further imports of 'module'.""" def __init__(self, module: str) -> None: self.module = module def find_spec( self, fullname: str, path: Sequence[str] | None, target: ModuleType | None = None, /, ) -> ModuleSpec | None: if fullname == self.module or fullname.startswith(self.module + '.'): raise ImportError return None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/output.py0000664000175000017500000000506615171355650016022 0ustar00zuulzuul# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os from typing import IO import fixtures _TRUE_VALUES = ('True', 'true', '1', 'yes') class CaptureOutput(fixtures.Fixture): """Optionally capture the output streams. The behavior is managed through arguments to the constructor. The default behavior is controlled via two environment variables. If ``OS_STDOUT_CAPTURE`` is true then stdout is captured and if ``OS_STDERR_CAPTURE`` is true then stderr is captured. "True" values include ``True``, ``true``, ``1``, and ``yes``. :param do_stdout: Whether to capture stdout. :type do_stdout: bool :param do_stderr: Whether to capture stderr. :type do_stderr: bool .. py:attribute:: stdout The ``stream`` attribute from a :class:`StringStream` instance replacing stdout. .. py:attribute:: stderr The ``stream`` attribute from a :class:`StringStream` instance replacing stderr. """ def __init__( self, do_stdout: bool | None = None, do_stderr: bool | None = None ): super().__init__() if do_stdout is None: self.do_stdout = ( os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES ) else: self.do_stdout = do_stdout if do_stderr is None: self.do_stderr = ( os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES ) else: self.do_stderr = do_stderr self.stdout: IO[str] | None = None self.stderr: IO[str] | None = None def setUp(self) -> None: super().setUp() if self.do_stdout: self._stdout_fixture = fixtures.StringStream('stdout') self.stdout = self.useFixture(self._stdout_fixture).stream self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout)) if self.do_stderr: self._stderr_fixture = fixtures.StringStream('stderr') self.stderr = self.useFixture(self._stderr_fixture).stream self.useFixture(fixtures.MonkeyPatch('sys.stderr', self.stderr)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/py.typed0000664000175000017500000000000015171355650015566 0ustar00zuulzuul././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7245426 oslotest-6.1.1/oslotest/tests/0000775000175000017500000000000015171355730015242 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tests/__init__.py0000664000175000017500000000000015171355650017342 0ustar00zuulzuul././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1776671703.728543 oslotest-6.1.1/oslotest/tests/unit/0000775000175000017500000000000015171355730016221 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tests/unit/__init__.py0000664000175000017500000000000015171355650020321 0ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tests/unit/test_base.py0000664000175000017500000001524515171355650020554 0ustar00zuulzuul# Copyright 2014 Deutsche Telekom AG # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging import os from typing import Any import unittest from unittest import mock import fixtures import testtools from oslotest import base class TestBaseTestCase(testtools.TestCase): class FakeTestCase(base.BaseTestCase): def test_fake_test(self): pass @mock.patch('os.environ.get') @mock.patch('oslotest.timeout.Timeout.useFixture') @mock.patch('fixtures.Timeout') def test_timeout(self, fixture_timeout_mock, fixture_mock, env_get_mock): env_get_mock.return_value = 1 tc = self.FakeTestCase("test_fake_test") tc._set_timeout() env_get_mock.assert_called_once_with('OS_TEST_TIMEOUT', 0) fixture_timeout_mock.assert_called_once_with(1, gentle=True) self.assertEqual(1, fixture_mock.call_count) @mock.patch('os.environ.get') def test_fake_logs_default(self, env_get_mock): # without debug and log capture env_get_mock.side_effect = lambda value, default=None: { 'OS_DEBUG': 0, 'OS_LOG_CAPTURE': 0, }.get(value, default) tc = self.FakeTestCase("test_fake_test") tc.setUp() env_get_mock.assert_any_call('OS_LOG_CAPTURE') env_get_mock.assert_any_call('OS_DEBUG') self.assertFalse(tc.log_fixture.capture_logs) self.assertIsNone(tc.log_fixture.logger) @mock.patch('os.environ.get') @mock.patch('logging.basicConfig') def test_fake_logs_with_debug(self, basic_logger_mock, env_get_mock): env_get_mock.side_effect = lambda value, default=None: { 'OS_DEBUG': 'True', 'OS_LOG_CAPTURE': 0, }.get(value, default) tc = self.FakeTestCase("test_fake_test") tc.setUp() env_get_mock.assert_any_call('OS_LOG_CAPTURE') env_get_mock.assert_any_call('OS_DEBUG') basic_logger_mock.assert_called_once_with( format=base._LOG_FORMAT, level=logging.DEBUG ) @mock.patch('os.environ.get') @mock.patch.object(FakeTestCase, 'useFixture') def test_fake_logs_with_log_cap(self, fixture_mock, env_get_mock): env_get_mock.side_effect = lambda value: { 'OS_DEBUG': 0, 'OS_LOG_CAPTURE': 'True', }.get(value) tc = self.FakeTestCase("test_fake_test") tc.setUp() env_get_mock.assert_any_call('OS_LOG_CAPTURE') env_get_mock.assert_any_call('OS_DEBUG') self.assertEqual(5, fixture_mock.call_count) def test_mock_patch_cleanup_on_teardown(self): # create an object and save its reference class Sub: value: Any backup: Any obj = Sub() obj.value = obj.backup = object() # patch the object mock.patch.object(obj, 'value').start() self.assertNotEqual(obj.backup, obj.value) # run a test case loader = unittest.defaultTestLoader suite = loader.loadTestsFromTestCase(self.FakeTestCase) suite.run(unittest.TestResult()) # check that mock patches are cleaned up self.assertEqual(obj.backup, obj.value) @mock.patch('os.environ') def test_capture_output_disabled(self, mock_env): mock_env.get.return_value = '' tc = self.FakeTestCase("test_fake_test") tc.setUp() self.assertIsNone(tc.output_fixture.stdout) self.assertIsNone(tc.output_fixture.stderr) @mock.patch('os.environ') def test_enabled(self, mock_env): mock_env.get.return_value = 'True' tc = self.FakeTestCase("test_fake_test") tc.setUp() self.assertIsNotNone(tc.output_fixture.stdout) self.assertIsNotNone(tc.output_fixture.stderr) class TestManualMock(base.BaseTestCase): def setUp(self): # Create a cleanup to undo a patch() call *before* calling the # base class version of setup(). patcher = mock.patch('os.environ.keys') patcher.start() self.addCleanup(patcher.stop) super().setUp() self.useFixture(fixtures.MockPatch('fixtures.Timeout')) def test_mock_patch_manually(self): # Verify that if a test instance creates its own mock and # calls start/stop itself we don't get an error. patcher = mock.patch('os.environ.get') patcher.start() self.addCleanup(patcher.stop) class TestTempFiles(base.BaseTestCase): def test_create_unicode_files(self): files = [('no_approve', 'ಠ_ಠ')] temps = self.create_tempfiles(files) self.assertEqual(1, len(temps)) with open(temps[0], 'rb') as f: contents = f.read() self.assertEqual('ಠ_ಠ', str(contents, encoding='utf-8')) def test_create_unicode_files_encoding(self): files = [('embarrassed', '⊙﹏⊙', 'utf-8')] temps = self.create_tempfiles(files) self.assertEqual(1, len(temps)) with open(temps[0], 'rb') as f: contents = f.read() self.assertEqual('⊙﹏⊙', str(contents, encoding='utf-8')) def test_create_unicode_files_multi_encoding(self): files = [ ('embarrassed', '⊙﹏⊙', 'utf-8'), ('abc', 'abc', 'ascii'), ] temps = self.create_tempfiles(files) self.assertEqual(2, len(temps)) for i, (basename, raw_contents, raw_encoding) in enumerate(files): with open(temps[i], 'rb') as f: contents = f.read() if not isinstance(raw_contents, str): raw_contents = str(raw_contents, encoding=raw_encoding) self.assertEqual( str(contents, encoding=raw_encoding), raw_contents ) def test_create_bad_encoding(self): files = [['hrm', 'ಠ~ಠ', 'ascii']] self.assertRaises(UnicodeError, self.create_tempfiles, files) def test_prefix(self): files = [('testing', '')] temps = self.create_tempfiles(files) self.assertEqual(1, len(temps)) basename = os.path.basename(temps[0]) self.assertTrue(basename.startswith('testing')) def test_wrong_length(self): files = [('testing',)] self.assertRaises(ValueError, self.create_tempfiles, files) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tests/unit/test_createfile.py0000664000175000017500000000375615171355650021751 0ustar00zuulzuul# Copyright 2014 Deutsche Telekom AG # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os from oslotest import base from oslotest import createfile class CreateFileWithContentTest(base.BaseTestCase): def test_create_unicode_files(self): f = createfile.CreateFileWithContent( "no_approve", 'ಠ_ಠ', ) f.setUp() with open(f.path, 'rb') as fh: contents = fh.read() self.assertEqual('ಠ_ಠ', str(contents, encoding='utf-8')) def test_create_unicode_files_encoding(self): f = createfile.CreateFileWithContent( "embarrassed", '⊙﹏⊙', encoding='utf-8', ) f.setUp() with open(f.path, 'rb') as fh: contents = fh.read() self.assertEqual('⊙﹏⊙', str(contents, encoding='utf-8')) def test_create_bad_encoding(self): f = createfile.CreateFileWithContent( "hrm", 'ಠ~ಠ', encoding='ascii', ) self.assertRaises(UnicodeError, f.setUp) def test_prefix(self): f = createfile.CreateFileWithContent('testing', '') f.setUp() basename = os.path.basename(f.path) self.assertTrue(basename.startswith('testing')) def test_ext(self): f = createfile.CreateFileWithContent('testing', '', ext='.ending') f.setUp() basename = os.path.basename(f.path) self.assertTrue(basename.endswith('.ending')) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tests/unit/test_log.py0000664000175000017500000001000115171355650020404 0ustar00zuulzuul# Copyright 2014 Deutsche Telekom AG # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging from unittest import mock import testtools from oslotest import log class ConfigureLoggingTestCase(testtools.TestCase): @mock.patch('os.environ.get') def test_fake_logs_default(self, env_get_mock): # without debug and log capture env_get_mock.side_effect = lambda value, default=None: { 'OS_DEBUG': 0, 'OS_LOG_CAPTURE': 0, }.get(value, default) f = log.ConfigureLogging() f.setUp() env_get_mock.assert_any_call('OS_LOG_CAPTURE') env_get_mock.assert_any_call('OS_DEBUG') self.assertFalse(f.capture_logs) self.assertIsNone(f.logger) @mock.patch('os.environ.get') @mock.patch('logging.basicConfig') def test_fake_logs_with_debug(self, basic_logger_mock, env_get_mock): env_get_mock.side_effect = lambda value, default=None: { 'OS_DEBUG': 'True', 'OS_LOG_CAPTURE': 0, }.get(value, default) f = log.ConfigureLogging() f.setUp() env_get_mock.assert_any_call('OS_LOG_CAPTURE') env_get_mock.assert_any_call('OS_DEBUG') basic_logger_mock.assert_called_once_with( format=log.ConfigureLogging.DEFAULT_FORMAT, level=logging.DEBUG ) @mock.patch('os.environ.get') @mock.patch('logging.basicConfig') def test_fake_logs_with_warning(self, basic_logger_mock, env_get_mock): env_get_mock.side_effect = lambda value, default=None: { 'OS_DEBUG': 'WARNING', 'OS_LOG_CAPTURE': 0, }.get(value, default) f = log.ConfigureLogging() f.setUp() env_get_mock.assert_any_call('OS_LOG_CAPTURE') env_get_mock.assert_any_call('OS_DEBUG') basic_logger_mock.assert_called_once_with( format=log.ConfigureLogging.DEFAULT_FORMAT, level=logging.WARNING ) @mock.patch('os.environ.get') @mock.patch('logging.basicConfig') def test_fake_logs_with_trace_int(self, basic_logger_mock, env_get_mock): env_get_mock.side_effect = lambda value, default=None: { 'OS_DEBUG': '5', 'OS_LOG_CAPTURE': 0, }.get(value, default) f = log.ConfigureLogging() f.setUp() env_get_mock.assert_any_call('OS_LOG_CAPTURE') env_get_mock.assert_any_call('OS_DEBUG') basic_logger_mock.assert_called_once_with( format=log.ConfigureLogging.DEFAULT_FORMAT, level=5 ) @mock.patch('os.environ.get') @mock.patch('logging.basicConfig') def test_fake_logs_with_debug_int(self, basic_logger_mock, env_get_mock): env_get_mock.side_effect = lambda value, default=None: { 'OS_DEBUG': '10', 'OS_LOG_CAPTURE': 0, }.get(value, default) f = log.ConfigureLogging() f.setUp() env_get_mock.assert_any_call('OS_LOG_CAPTURE') env_get_mock.assert_any_call('OS_DEBUG') basic_logger_mock.assert_called_once_with( format=log.ConfigureLogging.DEFAULT_FORMAT, level=logging.DEBUG ) @mock.patch('os.environ.get') def test_fake_logs_with_log_capture(self, env_get_mock): env_get_mock.side_effect = lambda value: { 'OS_DEBUG': 0, 'OS_LOG_CAPTURE': 'True', }[value] f = log.ConfigureLogging() f.setUp() env_get_mock.assert_any_call('OS_LOG_CAPTURE') env_get_mock.assert_any_call('OS_DEBUG') self.assertIsNotNone(f.logger) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tests/unit/test_mock_fixture.py0000664000175000017500000001133015171355650022330 0ustar00zuulzuul# Copyright 2017 Cloudbase Solutions Srl # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import testtools from unittest import mock from oslotest import mock_fixture # NOTE(claudiub): this needs to be called before any mock.patch calls are # being done, and especially before the test class loads. This fixes # the mock.patch autospec issue: # https://github.com/testing-cabal/mock/issues/396 # TODO(claudiub): Remove this once the fix has been merged and released. mock_fixture.patch_mock_module() class Foo: def bar(self, a, b, c, d=None): pass @classmethod def classic_bar(cls, a, b, c, d=None): pass @staticmethod def static_bar(a, b, c, d=None): pass class MockSanityTestCase(testtools.TestCase): def setUp(self): super().setUp() self.useFixture(mock_fixture.MockAutospecFixture()) def _check_autospeced_foo(self, foo): for method_name in ['bar', 'classic_bar', 'static_bar']: mock_method = getattr(foo, method_name) # check that the methods are callable with correct args. mock_method(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c) mock_method( mock.sentinel.a, mock.sentinel.b, mock.sentinel.c, d=mock.sentinel.d, ) mock_method.assert_has_calls( [ mock.call( mock.sentinel.a, mock.sentinel.b, mock.sentinel.c ), mock.call( mock.sentinel.a, mock.sentinel.b, mock.sentinel.c, d=mock.sentinel.d, ), ] ) # assert that TypeError is raised if the method signature is not # respected. self.assertRaises(TypeError, mock_method) self.assertRaises(TypeError, mock_method, mock.sentinel.a) self.assertRaises(TypeError, mock_method, a=mock.sentinel.a) self.assertRaises( TypeError, mock_method, mock.sentinel.a, mock.sentinel.b, mock.sentinel.c, e=mock.sentinel.e, ) # assert that AttributeError is raised if the method does not exist. self.assertRaises(AttributeError, getattr, foo, 'lish') def _check_mock_autospec_all_members(self, mock_cls): for spec in [Foo, Foo()]: foo = mock_cls(autospec=spec) self._check_autospeced_foo(foo) self._check_autospeced_foo(foo()) def test_mock_autospec_all_members(self): self._check_mock_autospec_all_members(mock.Mock) def test_magic_mock_autospec_all_members(self): self._check_mock_autospec_all_members(mock.MagicMock) @mock.patch.object(Foo, 'static_bar') @mock.patch.object(Foo, 'classic_bar') @mock.patch.object(Foo, 'bar') def test_patch_autospec_class(self, mock_meth, mock_cmeth, mock_smeth): foo = Foo() self._check_autospeced_foo(foo) def test_patch_autospec_multiple(self): with mock.patch.multiple( Foo, bar=mock.DEFAULT, classic_bar=mock.DEFAULT, static_bar=mock.DEFAULT, ): foo = Foo() self._check_autospeced_foo(foo) @mock.patch.object(Foo, 'static_bar', autospec=False) @mock.patch.object(Foo, 'classic_bar', autospec=False) @mock.patch.object(Foo, 'bar', autospec=False) def test_patch_autospec_class_false( self, mock_meth, mock_cmeth, mock_smeth ): foo = Foo() # we're checking that method signature is not enforced. foo.bar() # type: ignore[call-arg] mock_meth.assert_called_once_with() foo.classic_bar() # type: ignore[call-arg] mock_cmeth.assert_called_once_with() foo.static_bar() # type: ignore[call-arg] mock_smeth.assert_called_once_with() @mock.patch.object(Foo, 'lish', create=True) def test_patch_create(self, mock_lish): foo = Foo() foo.lish() # type: ignore[attr-defined] mock_lish.assert_called_once_with() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tests/unit/test_mockpatch.py0000664000175000017500000000173315171355650021610 0ustar00zuulzuul# Copyright 2014 IBM Corp. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import fixtures from oslotest import base class TestMockPatchSymbols(base.BaseTestCase): def test_reference(self): # Applications expect these public symbols to be available until the # deprecated module is removed. self.assertTrue(fixtures.MockPatchObject) self.assertTrue(fixtures.MockPatch) self.assertTrue(fixtures.MockPatchMultiple) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tests/unit/test_modules.py0000664000175000017500000000162415171355650021306 0ustar00zuulzuul# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslotest import base from oslotest import modules class CreateDisableModuleTest(base.BaseTestCase): def test_disable_module(self): s = __import__('sys') self.assertTrue(s) with modules.DisableModuleFixture('sys'): self.assertRaises(ImportError, __import__, 'sys') s = __import__('sys') self.assertTrue(s) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tests/unit/test_output.py0000664000175000017500000000420015171355650021167 0ustar00zuulzuul# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sys from unittest import mock import testtools from oslotest import output class CaptureOutputTest(testtools.TestCase): @mock.patch('os.environ') def test_disabled_env(self, mock_env): mock_env.get.return_value = '' f = output.CaptureOutput() f.setUp() self.assertIsNone(f.stdout) self.assertIsNone(f.stderr) self.assertIsNot(sys.stdout, f.stdout) self.assertIsNot(sys.stderr, f.stderr) @mock.patch('os.environ') def test_enabled_env(self, mock_env): mock_env.get.return_value = 'True' f = output.CaptureOutput() f.setUp() self.assertIsNotNone(f.stdout) self.assertIsNotNone(f.stderr) self.assertIs(sys.stdout, f.stdout) self.assertIs(sys.stderr, f.stderr) @mock.patch('os.environ') def test_disabled_explicit(self, mock_env): mock_env.get.side_effect = AssertionError('should not be called') f = output.CaptureOutput(do_stdout=False, do_stderr=False) f.setUp() self.assertIsNone(f.stdout) self.assertIsNone(f.stderr) self.assertIsNot(sys.stdout, f.stdout) self.assertIsNot(sys.stderr, f.stderr) @mock.patch('os.environ') def test_ensabled_explicit(self, mock_env): mock_env.get.side_effect = AssertionError('should not be called') f = output.CaptureOutput(do_stdout=True, do_stderr=True) f.setUp() self.assertIsNotNone(f.stdout) self.assertIsNotNone(f.stderr) self.assertIs(sys.stdout, f.stdout) self.assertIs(sys.stderr, f.stderr) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tests/unit/test_timeout.py0000664000175000017500000000741115171355650021324 0ustar00zuulzuul# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from unittest import mock import testtools from oslotest import timeout class TimeoutTestCase(testtools.TestCase): @mock.patch('os.environ.get') @mock.patch.object(timeout.Timeout, 'useFixture') @mock.patch('fixtures.Timeout') def test_timeout(self, fixture_timeout_mock, fixture_mock, env_get_mock): env_get_mock.return_value = 1 tc = timeout.Timeout() tc.setUp() env_get_mock.assert_called_once_with('OS_TEST_TIMEOUT', 0) fixture_timeout_mock.assert_called_once_with(1, gentle=True) self.assertEqual(1, fixture_mock.call_count) @mock.patch('os.environ.get') @mock.patch.object(timeout.Timeout, 'useFixture') @mock.patch('fixtures.Timeout') def test_no_timeout( self, fixture_timeout_mock, fixture_mock, env_get_mock ): # Returning 0 means we don't install the timeout env_get_mock.return_value = 0 tc = timeout.Timeout() tc.setUp() env_get_mock.assert_called_once_with('OS_TEST_TIMEOUT', 0) self.assertEqual(0, fixture_timeout_mock.call_count) self.assertEqual(0, fixture_mock.call_count) @mock.patch('os.environ.get') @mock.patch.object(timeout.Timeout, 'useFixture') @mock.patch('fixtures.Timeout') def test_timeout_default( self, fixture_timeout_mock, fixture_mock, env_get_mock ): env_get_mock.return_value = 5 tc = timeout.Timeout(default_timeout=5) tc.setUp() env_get_mock.assert_called_once_with('OS_TEST_TIMEOUT', 5) fixture_timeout_mock.assert_called_once_with(5, gentle=True) self.assertEqual(1, fixture_mock.call_count) @mock.patch('os.environ.get') @mock.patch.object(timeout.Timeout, 'useFixture') @mock.patch('fixtures.Timeout') def test_timeout_bad_default( self, fixture_timeout_mock, fixture_mock, env_get_mock ): env_get_mock.return_value = 'invalid' tc = timeout.Timeout(default_timeout='invalid') # type: ignore tc.setUp() env_get_mock.assert_called_once_with('OS_TEST_TIMEOUT', 0) self.assertEqual(0, fixture_timeout_mock.call_count) self.assertEqual(0, fixture_mock.call_count) @mock.patch('os.environ.get') @mock.patch.object(timeout.Timeout, 'useFixture') @mock.patch('fixtures.Timeout') def test_timeout_scaling( self, fixture_timeout_mock, fixture_mock, env_get_mock ): env_get_mock.return_value = 2 tc = timeout.Timeout(scaling_factor=1.5) tc.setUp() env_get_mock.assert_called_once_with('OS_TEST_TIMEOUT', 0) fixture_timeout_mock.assert_called_once_with(3, gentle=True) self.assertEqual(1, fixture_mock.call_count) @mock.patch('os.environ.get') @mock.patch.object(timeout.Timeout, 'useFixture') @mock.patch('fixtures.Timeout') def test_timeout_bad_scaling( self, fixture_timeout_mock, fixture_mock, env_get_mock ): env_get_mock.return_value = 2 tc = timeout.Timeout(scaling_factor='invalid') # type: ignore tc.setUp() env_get_mock.assert_called_once_with('OS_TEST_TIMEOUT', 0) fixture_timeout_mock.assert_called_once_with(2, gentle=True) self.assertEqual(1, fixture_mock.call_count) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/timeout.py0000664000175000017500000000337615171355650016152 0ustar00zuulzuul# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import fixtures import os class Timeout(fixtures.Fixture): """Set the maximum length of time for the test to run. Uses OS_TEST_TIMEOUT to get the timeout. """ def __init__( self, default_timeout: int | float = 0, scaling_factor: int | float = 1, ) -> None: super().__init__() try: self._default_timeout = int(default_timeout) except ValueError: # If timeout value is invalid do not set a timeout. self._default_timeout = 0 self._scaling_factor = scaling_factor def setUp(self) -> None: super().setUp() test_timeout = os.environ.get('OS_TEST_TIMEOUT', self._default_timeout) try: test_timeout = int(test_timeout) except ValueError: # If timeout value is invalid use the default timeout. test_timeout = self._default_timeout try: scaled_timeout = int(test_timeout * self._scaling_factor) except ValueError: # If scaling factor is invalid, use the basic test timeout. scaled_timeout = test_timeout if scaled_timeout > 0: self.useFixture(fixtures.Timeout(scaled_timeout, gentle=True)) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1776671703.729543 oslotest-6.1.1/oslotest/tools/0000775000175000017500000000000015171355730015240 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tools/__init__.py0000664000175000017500000000000015171355650017340 0ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/oslotest/tools/config.py0000664000175000017500000000267015171355650017065 0ustar00zuulzuul# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Utilities functions for working with oslo.config from the tool scripts.""" import os from typing import TypeVar from oslo_config import cfg DEFAULT_CONFIG_FILES = [ './oslo.conf', os.path.expanduser('~/.oslo.conf'), ] def get_config_parser() -> cfg.ConfigOpts: conf = cfg.ConfigOpts() conf.register_cli_opt( cfg.StrOpt( 'repo_root', default='.', help='directory containing the git repositories', ) ) return conf _ConfigOptT = TypeVar('_ConfigOptT', bound=cfg.ConfigOpts) def parse_arguments(conf: type[_ConfigOptT]) -> _ConfigOptT: # Look for a few configuration files, and load the ones we find. default_config_files = [ f for f in DEFAULT_CONFIG_FILES if os.path.exists(f) ] return conf( # type: ignore project='oslo', default_config_files=default_config_files ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7365434 oslotest-6.1.1/oslotest.egg-info/0000775000175000017500000000000015171355730015572 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671703.0 oslotest-6.1.1/oslotest.egg-info/PKG-INFO0000644000175000017500000000340015171355727016670 0ustar00zuulzuulMetadata-Version: 2.4 Name: oslotest Version: 6.1.1 Summary: Oslo test framework Author-email: OpenStack Project-URL: Homepage, https://docs.openstack.org/oslotest Project-URL: Repository, https://opendev.org/openstack/oslotest Classifier: Environment :: OpenStack Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Information Technology Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Typing :: Typed Requires-Python: >=3.10 Description-Content-Type: text/x-rst License-File: LICENSE Requires-Dist: fixtures>=3.0.0 Requires-Dist: testtools>=2.2.0 Dynamic: license-file Dynamic: requires-dist ===================================================== oslotest -- OpenStack Testing Framework and Utilities ===================================================== .. image:: https://governance.openstack.org/tc/badges/oslotest.svg .. Change things from this point on The Oslo Test framework provides common fixtures, support for debugging, and better support for mocking results. * Free software: Apache license * Documentation: https://docs.openstack.org/oslotest/latest/ * Source: https://opendev.org/openstack/oslotest * Bugs: https://bugs.launchpad.net/oslotest * Release notes: https://docs.openstack.org/releasenotes/oslotest ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671703.0 oslotest-6.1.1/oslotest.egg-info/SOURCES.txt0000664000175000017500000000456215171355727017473 0ustar00zuulzuul.coveragerc .mailmap .pre-commit-config.yaml .stestr.conf .zuul.yaml AUTHORS CONTRIBUTING.rst ChangeLog HACKING.rst LICENSE README.rst pyproject.toml requirements.txt setup.cfg setup.py test-requirements.txt tox.ini doc/requirements.txt doc/source/conf.py doc/source/index.rst doc/source/contributor/index.rst doc/source/install/index.rst doc/source/reference/index.rst doc/source/user/debugging.rst doc/source/user/features.rst doc/source/user/history.rst doc/source/user/index.rst doc/source/user/mock-autospec.rst doc/source/user/resources.rst doc/source/user/testing.rst oslotest/__init__.py oslotest/base.py oslotest/createfile.py oslotest/log.py oslotest/mock_fixture.py oslotest/modules.py oslotest/output.py oslotest/py.typed oslotest/timeout.py oslotest.egg-info/PKG-INFO oslotest.egg-info/SOURCES.txt oslotest.egg-info/dependency_links.txt oslotest.egg-info/not-zip-safe oslotest.egg-info/pbr.json oslotest.egg-info/requires.txt oslotest.egg-info/top_level.txt oslotest/tests/__init__.py oslotest/tests/unit/__init__.py oslotest/tests/unit/test_base.py oslotest/tests/unit/test_createfile.py oslotest/tests/unit/test_log.py oslotest/tests/unit/test_mock_fixture.py oslotest/tests/unit/test_mockpatch.py oslotest/tests/unit/test_modules.py oslotest/tests/unit/test_output.py oslotest/tests/unit/test_timeout.py oslotest/tools/__init__.py oslotest/tools/config.py releasenotes/notes/add-reno-996dd44974d53238.yaml releasenotes/notes/controlling-output-capture-e47c66bbca4a694a.yaml releasenotes/notes/deprecate-functional-module-fbed600d2fa026fc.yaml releasenotes/notes/drop-python-2-7-73d3113c69d724d6.yaml releasenotes/notes/mock-autospec-fix-9042c30dbb74032f.yaml releasenotes/notes/remove-functional-module-4733bc6eff595683.yaml releasenotes/notes/remove-moxstubout-63345dd5d9528e83.yaml releasenotes/notes/remove-py38-py39-24a1ab1e4252ee84.yaml releasenotes/notes/remove_mockpatch-80fec29f28da5d5c.yaml releasenotes/notes/timeout-scaling-52741beadde528e5.yaml releasenotes/source/conf.py releasenotes/source/index.rst releasenotes/source/ocata.rst releasenotes/source/pike.rst releasenotes/source/queens.rst releasenotes/source/rocky.rst releasenotes/source/stein.rst releasenotes/source/train.rst releasenotes/source/unreleased.rst releasenotes/source/ussuri.rst releasenotes/source/victoria.rst releasenotes/source/_static/.placeholder releasenotes/source/_templates/.placeholder tools/oslo_debug_helper././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671703.0 oslotest-6.1.1/oslotest.egg-info/dependency_links.txt0000664000175000017500000000000115171355727021646 0ustar00zuulzuul ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671703.0 oslotest-6.1.1/oslotest.egg-info/not-zip-safe0000664000175000017500000000000115171355727020026 0ustar00zuulzuul ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671703.0 oslotest-6.1.1/oslotest.egg-info/pbr.json0000664000175000017500000000005615171355727017257 0ustar00zuulzuul{"git_version": "1eb1ea8", "is_release": true}././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671703.0 oslotest-6.1.1/oslotest.egg-info/requires.txt0000664000175000017500000000004115171355727020173 0ustar00zuulzuulfixtures>=3.0.0 testtools>=2.2.0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671703.0 oslotest-6.1.1/oslotest.egg-info/top_level.txt0000664000175000017500000000001115171355727020322 0ustar00zuulzuuloslotest ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/pyproject.toml0000664000175000017500000000335715171355650015151 0ustar00zuulzuul[build-system] requires = ["pbr>=6.1.1"] build-backend = "pbr.build" [project] name = "oslotest" description = "Oslo test framework" readme = "README.rst" authors = [ {name = "OpenStack", email = "openstack-discuss@lists.openstack.org"}, ] requires-python = ">=3.10" dynamic = ["version", "dependencies"] classifiers = [ "Environment :: OpenStack", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "License :: OSI Approved :: Apache Software License", "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: Implementation :: CPython", "Typing :: Typed", ] [project.urls] Homepage = "https://docs.openstack.org/oslotest" Repository = "https://opendev.org/openstack/oslotest" [tool.setuptools] packages = [ "oslotest" ] script-files = [ "tools/oslo_debug_helper", ] [tool.mypy] python_version = "3.10" show_column_numbers = true show_error_context = true strict = true disable_error_code = ["import-untyped"] exclude = "(?x)(doc | releasenotes)" [[tool.mypy.overrides]] module = ["oslotest.tests.*"] disallow_untyped_calls = false disallow_untyped_defs = false disallow_subclassing_any = false [tool.ruff] line-length = 79 [tool.ruff.format] quote-style = "preserve" docstring-code-format = true [tool.ruff.lint] select = ["E4", "E5", "E7", "E9", "F", "G", "LOG", "S", "UP"] external = ["H"] ignore = [ # we only use asserts for type narrowing "S101", ] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7095418 oslotest-6.1.1/releasenotes/0000775000175000017500000000000015171355730014715 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7325432 oslotest-6.1.1/releasenotes/notes/0000775000175000017500000000000015171355730016045 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/notes/add-reno-996dd44974d53238.yaml0000664000175000017500000000007215171355650022444 0ustar00zuulzuul--- other: - Introduce reno for deployer release notes. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/notes/controlling-output-capture-e47c66bbca4a694a.yaml0000664000175000017500000000027215171355650026641 0ustar00zuulzuul--- features: - | Change the API for the CaptureOutput fixture so that tests may enable it explicitly instead of purely relying on the environment variables to control it. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/notes/deprecate-functional-module-fbed600d2fa026fc.yaml0000664000175000017500000000015015171355650026727 0ustar00zuulzuul--- deprecations: - | oslotest.functional is deprecated and will be removed with oslotest 3.0.0 . ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/notes/drop-python-2-7-73d3113c69d724d6.yaml0000664000175000017500000000020715171355650023577 0ustar00zuulzuul--- upgrade: - | Python 2.7 support has been dropped. The minimum version of Python now supported by oslotest is Python 3.6. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/notes/mock-autospec-fix-9042c30dbb74032f.yaml0000664000175000017500000000021615171355650024407 0ustar00zuulzuul--- other: - | Oslotest now contains the mock_fixture module, which offers fixes to the autospec functionality in the mock library. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/notes/remove-functional-module-4733bc6eff595683.yaml0000664000175000017500000000025215171355650026027 0ustar00zuulzuul--- upgrade: - | The ``oslotest.functional`` module, which was deprecated in 2.18.1, has now been removed. This module was overly complicated and had no users. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/notes/remove-moxstubout-63345dd5d9528e83.yaml0000664000175000017500000000026715171355650024556 0ustar00zuulzuul--- upgrade: - | The ``oslotest.moxstubout`` module, which was deprecated in 3.5.0, has now been removed. Mox is considered unmaintained and should be replaced by mock. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/notes/remove-py38-py39-24a1ab1e4252ee84.yaml0000664000175000017500000000017615171355650024037 0ustar00zuulzuul--- upgrade: - | Support for Python 3.8 and 3.9 has been removed. Now the minimum Python version supported is 3.10. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/notes/remove_mockpatch-80fec29f28da5d5c.yaml0000664000175000017500000000021715171355650024644 0ustar00zuulzuul--- upgrade: - | As announced in Nov 2015, the oslotest.mockpatch module got removed now. Please use fixtures.Mock* classes instead. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/notes/timeout-scaling-52741beadde528e5.yaml0000664000175000017500000000063215171355650024335 0ustar00zuulzuul--- features: - | New class variable, ``TIMEOUT_SCALING_FACTOR`` was added that allows modifying a test class to have a longer timeout than other tests in the suite without having to raise the default timeout for all tests. - | New class variable, ``DEFAULT_TIMEOUT`` was added that lets test suite authors override the default value of ``OS_TEST_TIMEOUT`` at the test suite level. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7355433 oslotest-6.1.1/releasenotes/source/0000775000175000017500000000000015171355730016215 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7355433 oslotest-6.1.1/releasenotes/source/_static/0000775000175000017500000000000015171355730017643 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/_static/.placeholder0000664000175000017500000000000015171355650022115 0ustar00zuulzuul././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7355433 oslotest-6.1.1/releasenotes/source/_templates/0000775000175000017500000000000015171355730020352 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/_templates/.placeholder0000664000175000017500000000000015171355650022624 0ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/conf.py0000664000175000017500000000326615171355650017524 0ustar00zuulzuul# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # -- General configuration ------------------------------------------------ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'openstackdocstheme', 'reno.sphinxext', ] # The master toctree document. master_doc = 'index' # General information about the project. project = 'oslotest Release Notes' copyright = '2016, oslotest Developers' # Release notes do not need a version in the title, they span # multiple versions. # The full version, including alpha/beta/rc tags. release = '' # The short X.Y version. version = '' # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'openstackdocs' # -- openstackdocstheme configuration ------------------------------------- openstackdocs_repo_name = 'openstack/oslotest' openstackdocs_bug_project = 'oslotest' openstackdocs_bug_tag = '' openstackdocs_auto_name = False ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/index.rst0000664000175000017500000000030315171355650020053 0ustar00zuulzuul======================== oslotest Release Notes ======================== .. toctree:: :maxdepth: 1 unreleased victoria ussuri train stein rocky queens pike ocata ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/ocata.rst0000664000175000017500000000023015171355650020032 0ustar00zuulzuul=================================== Ocata Series Release Notes =================================== .. release-notes:: :branch: origin/stable/ocata ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/pike.rst0000664000175000017500000000021715171355650017700 0ustar00zuulzuul=================================== Pike Series Release Notes =================================== .. release-notes:: :branch: stable/pike ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/queens.rst0000664000175000017500000000022315171355650020245 0ustar00zuulzuul=================================== Queens Series Release Notes =================================== .. release-notes:: :branch: stable/queens ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/rocky.rst0000664000175000017500000000022115171355650020072 0ustar00zuulzuul=================================== Rocky Series Release Notes =================================== .. release-notes:: :branch: stable/rocky ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/stein.rst0000664000175000017500000000022115171355650020065 0ustar00zuulzuul=================================== Stein Series Release Notes =================================== .. release-notes:: :branch: stable/stein ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/train.rst0000664000175000017500000000017615171355650020071 0ustar00zuulzuul========================== Train Series Release Notes ========================== .. release-notes:: :branch: stable/train ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/unreleased.rst0000664000175000017500000000016015171355650021074 0ustar00zuulzuul============================== Current Series Release Notes ============================== .. release-notes:: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/ussuri.rst0000664000175000017500000000020215171355650020274 0ustar00zuulzuul=========================== Ussuri Series Release Notes =========================== .. release-notes:: :branch: stable/ussuri ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/releasenotes/source/victoria.rst0000664000175000017500000000022015171355650020562 0ustar00zuulzuul============================= Victoria Series Release Notes ============================= .. release-notes:: :branch: unmaintained/victoria ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/requirements.txt0000664000175000017500000000007015171355650015506 0ustar00zuulzuulfixtures>=3.0.0 # Apache-2.0/BSD testtools>=2.2.0 # MIT ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7375436 oslotest-6.1.1/setup.cfg0000664000175000017500000000010215171355730014036 0ustar00zuulzuul[metadata] name = oslotest [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/setup.py0000664000175000017500000000127315171355650013742 0ustar00zuulzuul# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. import setuptools setuptools.setup( setup_requires=['pbr>=2.0.0'], pbr=True, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/test-requirements.txt0000664000175000017500000000011215171355650016460 0ustar00zuulzuulcoverage>=4.0 # Apache-2.0 oslo.config>=5.2.0 # Apache-2.0 stestr>=2.0.0 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1776671703.7365434 oslotest-6.1.1/tools/0000775000175000017500000000000015171355730013364 5ustar00zuulzuul././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/tools/oslo_debug_helper0000775000175000017500000000223515171355650016776 0ustar00zuulzuul#!/bin/bash # oslo_debug_helper - Script that allows for debugging tests # # oslo_debug_helper [-t ] [] # # - may be a test suite, class, or function, if no value is # passed, then all tests are run. # -t - the name of the directory that houses the tests # relative to the project directory. If no value is passed, it is assumed # to be packagename/tests. PYTHON=${PYTHON:-python3} TMP_DIR=`mktemp -d debug-$$-XXX` || exit 1 trap "rm -rf $TMP_DIR" EXIT ALL_TESTS=$TMP_DIR/all_tests TESTS_TO_RUN=$TMP_DIR/tests_to_run # Default to packagename/tests, i.e., keystone/tests PACKAGENAME=$(${PYTHON} setup.py --name) TEST_DIR=./$PACKAGENAME/tests # If a specific path is passed, use that one while getopts ":t:" opt; do case $opt in t) TEST_DIR=$OPTARG;; esac done ${PYTHON} -m testtools.run discover -t ./ $TEST_DIR --list > $ALL_TESTS # getopts friendly way of determining if a positional arg has been passed ARG1=${@:$OPTIND:1} if [ "$ARG1" ]; then grep "$ARG1" < $ALL_TESTS > $TESTS_TO_RUN else mv $ALL_TESTS $TESTS_TO_RUN fi ${PYTHON} -m testtools.run discover --load-list $TESTS_TO_RUN ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1776671656.0 oslotest-6.1.1/tox.ini0000664000175000017500000000261015171355650013537 0ustar00zuulzuul[tox] minversion = 4.6.0 envlist = py3,pep8 [testenv] deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/test-requirements.txt -r{toxinidir}/requirements.txt commands = stestr run --slowest {posargs} [testenv:pep8] description = Run style checks. deps = pre-commit {[testenv:mypy]deps} commands = pre-commit run -a {[testenv:mypy]commands} [testenv:mypy] description = Run type checks. deps = {[testenv]deps} mypy commands = mypy --cache-dir="{envdir}/mypy_cache" {posargs:oslotest} [testenv:cover] setenv = PYTHON=coverage run --source oslotest --parallel-mode commands = stestr run {posargs} coverage combine coverage html -d cover coverage xml -o cover/coverage.xml [testenv:venv] commands = {posargs} [testenv:docs] deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/doc/requirements.txt commands = sphinx-build -W --keep-going -b html -d doc/build/doctrees doc/source doc/build/html [testenv:releasenotes] deps = {[testenv:docs]deps} commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html [flake8] # We only enable the hacking (H) checks select = H # H301 Black will put commas after imports that can't fit on one line ignore = H301 show-source = true exclude = .tox,dist,doc,*.egg,build