diff --git a/.gitattributes b/.gitattributes index 8d9a4a0c0..369c8ef65 100644 --- a/.gitattributes +++ b/.gitattributes @@ -17,6 +17,3 @@ # The git executable expects packed-refs to always have LF line endings, even on # Windows. **/packed-refs text eol=lf - -# We don't want CRLF conversion or any automatic change in there -tests/python/third_party/** binary diff --git a/.gitignore b/.gitignore index cfa718d02..7da71d8bb 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,6 @@ pip-log.txt coverage.xml coverage_html_report htmlcov -tests/python/third_party #Translations *.mo diff --git a/tests/README.md b/tests/README.md index 04eeb00de..c0683e912 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,47 +1,25 @@ Readme for Tank core tests ========================== -Required packages ------------------ -To install the required dependencies, just run the following command on the `python` directory. - -```shell -cd python -./upgrade_third_party.sh -``` - -Packages will be installed under `tests/python/third_party` - Running the test suite ----------------------- -To run the tests on Windows run the `run_tests.bat`. Also you need to run it as `admin` in `powershell` -with unrestricted execution policy (`Set-ExecutionPolicy Unrestricted`). - -To run on Linux or macOS, run the script `run_tests.sh`. - -Add `-h` to see options. -Add `--with-coverage` to enable coverage. - -To run specific test(s), specify module, or module.class or module.class.test: +The tests run with [pytest](https://docs.pytest.org/) through +[tk-toolchain](https://github.com/shotgunsoftware/tk-toolchain). Install +`tk-toolchain` and run `pytest` from the repository root: ```shell -run_tests.sh test_tank_content.TestValidate.test_valid_path +pip install git+https://github.com/shotgunsoftware/tk-toolchain.git +pytest ``` -To run all the tests from a specific file, you can specify both the module or file path: - -```shell -./run_tests.sh tank_module_test.test_module -``` +To run a specific test file, class, or test: ```shell -./run_tests.sh tank_module_test/test_module.py +pytest tests/core_tests/test_api.py +pytest tests/core_tests/test_api.py::TestApi::test_something ``` -Compile sources with Python 3 ------------------------------ -To make sure the tank source code can be compiled with Python 3, run the `compile_python3.*` scripts. Note that the unit tests cannot -be executed right now with Python 3. +Add `--cov` to enable coverage. Test suite layout ----------------- diff --git a/tests/compile_python3.bat b/tests/compile_python3.bat deleted file mode 100644 index fda86724e..000000000 --- a/tests/compile_python3.bat +++ /dev/null @@ -1,19 +0,0 @@ -:: Copyright (c) 2017 Shotgun Software Inc. -:: -:: CONFIDENTIAL AND PROPRIETARY -:: -:: This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit -:: Source Code License included in this distribution package. See LICENSE. -:: By accessing, using, copying or modifying this work you indicate your -:: agreement to the Shotgun Pipeline Toolkit Source Code License. All rights -:: not expressly granted therein are reserved by Shotgun Software Inc. - -:: -:: Allows to compile all the Toolkit source code with a Python executable. Due to limitations on -:: Windows, you need to make sure the python interpreter in your environment is a Python 3 -:: interpreter in order to actually compile with Python 3. -:: - -python.exe -m compileall ..\python\tank -python.exe -m compileall *.py -python.exe -m compileall authentication_tests bootstrap_tests commands_tests core_tests deploy_tests descriptor_tests folder_tests platform_tests tank_test_tests util_tests python\tank_test diff --git a/tests/compile_python3.sh b/tests/compile_python3.sh deleted file mode 100755 index 819b066fb..000000000 --- a/tests/compile_python3.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2017 Shotgun Software Inc. -# -# CONFIDENTIAL AND PROPRIETARY -# -# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit -# Source Code License included in this distribution package. See LICENSE. -# By accessing, using, copying or modifying this work you indicate your -# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights -# not expressly granted therein are reserved by Shotgun Software Inc. - -# -# Allows to compile all the Toolkit source code with a Python 3 executable. -# - -python3 -m compileall ../python/tank -python3 -m compileall *.py -python3 -m compileall */*.py diff --git a/tests/integration_tests/run_integration_tests.py b/tests/integration_tests/run_integration_tests.py index 86f7d60e3..530cb9bd3 100755 --- a/tests/integration_tests/run_integration_tests.py +++ b/tests/integration_tests/run_integration_tests.py @@ -33,7 +33,6 @@ def main(): environ["PYTHONPATH"] = os.path.pathsep.join( [ os.path.join(current_folder, "..", "python"), - os.path.join(current_folder, "..", "python", "third_party"), os.path.join(current_folder, "..", "..", "python"), ] ) diff --git a/tests/python/README.md b/tests/python/README.md deleted file mode 100644 index 1e7a3dcc4..000000000 --- a/tests/python/README.md +++ /dev/null @@ -1,15 +0,0 @@ -Upgrading the third party modules required for unit testing -=========================================================== - -The Toolkit package embeds all libraries required for unit testing. If you wish to update the -version of any library, update the `requirements.txt` file and then run the `upgrade_third_party.sh` -script. - -The scripts will invoke the version 3 of `python` and `pip`. - -If you wish to use other executables to `pip install` packages and run validation on the new -libraries, you can invoke the upgrade script like this: - -```shell -./upgrade_third_party.sh /usr/local/bin/pip /usr/local/bin/python -``` diff --git a/tests/python/requirements.txt b/tests/python/requirements.txt deleted file mode 100644 index 9cc259378..000000000 --- a/tests/python/requirements.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) 2019 Shotgun Software Inc. -# -# CONFIDENTIAL AND PROPRIETARY -# -# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit -# Source Code License included in this distribution package. See LICENSE. -# By accessing, using, copying or modifying this work you indicate your -# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights -# not expressly granted therein are reserved by Shotgun Software Inc. - -# This file enumerates the various third party libraries Toolkit uses for unit testing. -# They are committed inside this repo. See README.md in this folder for details. - -# IMPORTANT: These requirements should be in sync with tk-toolchain install_requires - -# Required for the --with-coverage option -coverage==7.2.7 - -# The Shotgun Desktop does not include setuptools, which comes with pip. Make -# sure they are installed in case the tests are run with this python. -setuptools==65.5.1 diff --git a/tests/python/upgrade_third_party.sh b/tests/python/upgrade_third_party.sh deleted file mode 100755 index c6911b81a..000000000 --- a/tests/python/upgrade_third_party.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -e -# Copyright (c) 2017 Shotgun Software Inc. -# -# CONFIDENTIAL AND PROPRIETARY -# -# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit -# Source Code License included in this distribution package. See LICENSE. -# By accessing, using, copying or modifying this work you indicate your -# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights -# not expressly granted therein are reserved by Shotgun Software Inc. - -# Read pip and python location from the command-line or use defaults. -if [ -z "$1" ]; then - export PIP=pip3 -else - export PIP=$1 -fi - -if [ -z "$2" ]; then - export PYTHON=python3 -else - export PYTHON=$2 -fi - -echo "Removing all existing third party libraries from the repo." -echo "==========================================================" -rm -rf third_party -echo "Done!" - -echo -echo "Installing all third party libraries into 'third_party' folder." -echo "===============================================================" -echo Launching $PIP -$PIP install -r requirements.txt -t third_party - -echo -echo "Testing installed libraries" -echo "===========================" -echo Launching $PYTHON -$PYTHON - < [core_tests.test_api] - authentication_tests -> [all test_*.py files] - - :param test_names: List of file names and/or module paths. - """ - for test_name in test_names: - # If the user used tab completion there will be an extra path separator at - # the end, so remove it. - if test_name[-1] == os.path.sep: - test_name = test_name[:-1] - - # If a test name looks like a file name, turn the slashes into . and remove the - # extension. - test_name = ( - test_name.replace("/", ".").replace("\\", ".").replace(".py", "") - ) - - # If we have a simple module name, no sub-module, then, run all the tests in that - # module. - if "." not in test_name: - # Grab all the python files named after test_*.py - for filename in self._massage_test_names( - # Generate clean module/submodule.py files without the fully qualified path. - # Skip the extra / - os.path.abspath(filename).replace(self.test_path, "")[1:] - for filename in glob.iglob( - os.path.join(self.test_path, test_name, "test_*.py") - ) - ): - yield filename - else: - yield test_name - - -def _initialize_coverage(test_root): - """ - Starts covering the code inside the tank module. - - :returns: The coverage instance. - """ - try: - import coverage - except ImportError: - print() - print( - "The 'coverage' module is missing. Run 'pip install coverage' to install it." - ) - sys.exit(1) - - if test_root: - coveragerc_location = os.path.abspath( - os.path.join( - test_root, - "..", - ".coveragerc", # /tests # - ) # /.coveragerc - ) - else: - run_tests_py_location = __file__ - coveragerc_location = os.path.abspath( - os.path.join( - os.path.dirname(run_tests_py_location), # /tests - "..", # - ".coveragerc", - ) # /.coveragerc - ) - cov = coverage.coverage(config_file=coveragerc_location) - cov.start() - return cov - - -def _finalize_coverage(cov): - """ - Stops covering code and writes out reports. - """ - cov.stop() - - # Print report to stdout - cov.report() - - # Save report to the .coverage file - cov.save() - - try: - # seems to be some CI issues with html coverage so - # failing gracefully with a warning in case it doesn't work. - cov.html_report(directory="coverage_html_report") - except Exception as e: - print("WARNING: Html coverage report could not be written: %s" % e) - else: - print( - "Note: Full html coverage report can be found in the coverage_html_report folder." - ) - - -def _initialize_logging(): - """ - Sets up a log file for the unit tests and optionally logs everything to the console. - """ - import tank - - tank.LogManager().initialize_base_file_handler("run_tests") - - if options.log_to_console: - tank.LogManager().initialize_custom_handler() - - if options.debug: - tank.LogManager().global_debug = True - - -def _run_tests(test_root, test_names): - """ - Runs the tests. - - :param test_root: Folder where unit tests can be found. - :param test_name: Name of the unit test to run. If None, all tests are run. - """ - if test_root: - # resolve path - test_root = os.path.expanduser(os.path.expandvars(test_root)) - test_root = os.path.abspath(test_root) - tank_test_runner = TankTestRunner(test_root) - else: - tank_test_runner = TankTestRunner() - - return tank_test_runner.run_tests(test_names) - - -def _parse_command_line(): - """ - Parses the command line. - - :returns: The options and the name of the unit test specified on the command line, if any. - """ - parser = OptionParser() - parser.add_option( - "--with-coverage", - action="store_true", - dest="coverage", - help="run with coverage (requires coverage is installed)", - ) - parser.add_option( - "--interactive", - action="store_true", - dest="interactive", - help="run tests that have been decorated with the interactive decorator", - ) - parser.add_option( - "--test-root", - action="store", - dest="test_root", - help="Specify a folder where to look for tests.", - ) - parser.add_option( - "--debug", "-d", action="store_true", help="Enable debug logging." - ) - parser.add_option( - "--log-to-console", - "-l", - action="store_true", - help="Run tests and redirect logging output to the console.", - ) - - options, args = parser.parse_args() - - test_names = args or [] - - return options, test_names - - -if __name__ == "__main__": - exit_val = 0 - - # - # Create our own temporary base storage into which everything - # will be created. Having a single top-level folder will make - # complete deletion very easy. - # - new_base_tempdir = tempfile.mkdtemp(prefix="tankTemporary_") - - try: - # - # Now that we have our global test run subdir created, let's - # re-assign tempfile.temdir() value to be used a new base directory - # - # NOTE: There is no need to save the current value of 'tempfile.tempdir' - # for later restoring. This is not changing value of default - # temporary directory for anything else than this instance of - # the 'tempfile' module. Overall system is not affected. - # - tempfile.tempdir = new_base_tempdir - - options, test_names = _parse_command_line() - - # Do not import Toolkit before coverage or it will tank (pun intended) our coverage - # score. We'll do this test even when we're not running code coverage to make sure - # we don't introduce unintended regressions. - if "tank" in sys.modules or "sgtk" in sys.modules: - raise RuntimeError( - "tank or sgtk was imported before the coverage module. Please fix run_tests.py." - ) - - if options.coverage: - cov = _initialize_coverage(options.test_root) - - _initialize_logging() - - # If we have a custom test root, add its python folder, if it exists, so the user doesn't need - # to set it up themselves. - if options.test_root: - python_test_root = os.path.join(options.test_root, "python") - if os.path.exists(python_test_root): - sys.path.insert(0, python_test_root) - - ret_val = _run_tests(options.test_root, test_names) - - if options.coverage: - _finalize_coverage(cov) - - # Exit value determined by failures and errors - if ret_val.errors or ret_val.failures: - exit_val = 1 - - except Exception as e: - print("Unexpected exception: %s" % e) - # Print the traceback for the raised Exception to allow better debugging. - traceback.print_exc() - # signal failure - exit_val = 1 - - finally: - from tank.util.filesystem import safe_delete_folder - - # Note: Relying on own value rather than tempfile.tempdir - # being global it MIGHT be changed by anyone test - if new_base_tempdir and os.path.isdir(new_base_tempdir): - print("\nCleaning up '%s'" % (new_base_tempdir)) - safe_delete_folder(new_base_tempdir) - - sys.exit(exit_val) diff --git a/tests/run_tests.sh b/tests/run_tests.sh deleted file mode 100755 index 18c6486ad..000000000 --- a/tests/run_tests.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# Copyright (c) 2017 Shotgun Software Inc. -# -# CONFIDENTIAL AND PROPRIETARY -# -# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit -# Source Code License included in this distribution package. See LICENSE. -# By accessing, using, copying or modifying this work you indicate your -# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights -# not expressly granted therein are reserved by Shotgun Software Inc. - -# -# Allows to run the unit tests against the python executable. The actual version is determined -# by the user's environment. -# - -find . -name "*.pyc" -delete -python -Wd `dirname $0`/run_tests.py $*