From 124429c5eece382161231f98853a4398278af2f8 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 3 Sep 2021 18:13:06 +0200 Subject: [PATCH] #1794 - created multiple test classes Refactor --- .../hosts/maya/test_publish_in_maya.py | 85 +----------- ...{testing_wrapper.py => testing_classes.py} | 127 ++++++++++++++++-- .../sync_server/test_site_operations.py | 6 +- 3 files changed, 126 insertions(+), 92 deletions(-) rename tests/lib/{testing_wrapper.py => testing_classes.py} (54%) diff --git a/tests/integration/hosts/maya/test_publish_in_maya.py b/tests/integration/hosts/maya/test_publish_in_maya.py index fd8882c349..86b26ba5e5 100644 --- a/tests/integration/hosts/maya/test_publish_in_maya.py +++ b/tests/integration/hosts/maya/test_publish_in_maya.py @@ -4,10 +4,10 @@ import os import shutil import glob -from tests.lib.testing_wrapper import TestCase +from tests.lib.testing_classes import PublishTest -class TestPublishInMaya(TestCase): +class TestPublishInMaya(PublishTest): """Basic test case for publishing in Maya Uses generic TestCase to prepare fixtures for test data, testing DBs, @@ -64,59 +64,8 @@ class TestPublishInMaya(TestCase): "{};{}".format(original_pythonpath, startup_path)) - @pytest.fixture(scope="module") - def launched_app(self, dbcon, download_test_data, last_workfile_path, - startup_scripts): - """Get sync_server_module from ModulesManager""" - root_key = "config.roots.work.{}".format("windows") # TEMP - dbcon.update_one( - {"type": "project"}, - {"$set": - { - root_key: download_test_data - }} - ) - - from openpype import PACKAGE_DIR - - # Path to OpenPype's schema - schema_path = os.path.join( - os.path.dirname(PACKAGE_DIR), - "schema" - ) - os.environ["AVALON_SCHEMA"] = schema_path # TEMP - - import openpype - openpype.install() - os.environ["OPENPYPE_EXECUTABLE"] = sys.executable - from openpype.lib import ApplicationManager - - application_manager = ApplicationManager() - data = { - "last_workfile_path": last_workfile_path, - "start_last_workfile": True, - "project_name": self.PROJECT, - "asset_name": self.ASSET, - "task_name": self.TASK - } - - yield application_manager.launch(self.APP_NAME, **data) - - @pytest.fixture(scope="module") - def publish_finished(self, dbcon, launched_app): - """Dummy fixture waiting for publish to finish""" - import time - time_start = time.time() - while launched_app.poll() is None: - time.sleep(0.5) - if time.time() - time_start > self.TIMEOUT: - raise ValueError("Timeout reached") - - # some clean exit test possible? - print("Publish finished") - yield True - def test_db_asserts(self, dbcon, publish_finished): + """Host and input data dependent expected results in DB.""" print("test_db_asserts") assert 5 == dbcon.find({"type": "version"}).count(), \ "Not expected no of versions" @@ -146,34 +95,6 @@ class TestPublishInMaya(TestCase): "context.ext": "ma"}).count(), \ "Not expected no of representations with ext 'abc'" - def test_folder_structure_same(self, dbcon, publish_finished, - download_test_data): - """Check if expected and published subfolders contain same files. - - Compares only presence, not size nor content! - """ - published_dir_base = download_test_data - published_dir = os.path.join(published_dir_base, - self.PROJECT, - self.TASK, - "**") - expected_dir_base = os.path.join(published_dir_base, - "expected") - expected_dir = os.path.join(expected_dir_base, - self.PROJECT, - self.TASK, - "**") - - published = set(f.replace(published_dir_base, '') for f in - glob.glob(published_dir, recursive=True) if - f != published_dir_base and os.path.exists(f)) - expected = set(f.replace(expected_dir_base, '') for f in - glob.glob(expected_dir, recursive=True) if - f != expected_dir_base and os.path.exists(f)) - - not_matched = expected.difference(published) - assert not not_matched, "Missing {} files".format(not_matched) - if __name__ == "__main__": test_case = TestPublishInMaya() diff --git a/tests/lib/testing_wrapper.py b/tests/lib/testing_classes.py similarity index 54% rename from tests/lib/testing_wrapper.py rename to tests/lib/testing_classes.py index 0a7c9a382f..6c7bebd469 100644 --- a/tests/lib/testing_wrapper.py +++ b/tests/lib/testing_classes.py @@ -1,3 +1,4 @@ +"""Testing classes for module testing and publishing in hosts.""" import os import sys import six @@ -5,13 +6,18 @@ import json import pytest import tempfile import shutil +import glob from tests.lib.db_handler import DBHandler from tests.lib.file_handler import RemoteFileHandler -class TestCase: - """Generic test class for testing +class BaseTest: + """Empty base test class""" + + +class ModuleUnitTest(BaseTest): + """Generic test class for testing modules Implemented fixtures: monkeypatch_session - fixture for env vars with session scope @@ -22,17 +28,12 @@ class TestCase: dbcon - returns DBConnection to AvalonDB dbcon_openpype - returns DBConnection for OpenpypeMongoDB - Not implemented: - last_workfile_path - returns path to testing workfile - """ TEST_OPENPYPE_MONGO = "mongodb://localhost:27017" TEST_DB_NAME = "test_db" TEST_PROJECT_NAME = "test_project" TEST_OPENPYPE_NAME = "test_openpype" - REPRESENTATION_ID = "60e578d0c987036c6a7b741d" - TEST_FILES = [] PROJECT = "test_project" @@ -85,7 +86,7 @@ class TestCase: for key, value in env_dict.items(): all_vars = globals() - all_vars.update(vars(TestCase)) # TODO check + all_vars.update(vars(ModuleUnitTest)) # TODO check value = value.format(**all_vars) print("Setting {}:{}".format(key, value)) monkeypatch_session.setenv(key, str(value)) @@ -135,6 +136,35 @@ class TestCase: mongo_client = OpenPypeMongoConnection.get_mongo_client() yield mongo_client[self.TEST_OPENPYPE_NAME]["settings"] + +class PublishTest(ModuleUnitTest): + """Test class for publishing in hosts. + + Implemented fixtures: + launched_app - launches APP with last_workfile_path + publish_finished - waits until publish is finished, host must + kill its process when finished publishing. Includes timeout + which raises ValueError + + Not implemented: + last_workfile_path - returns path to testing workfile + startup_scripts - provide script for setup in host + + Implemented tests: + test_folder_structure_same - compares published and expected + subfolders if they contain same files. Compares only on file + presence + + TODO: implement test on file size, file content + """ + + APP = "" + APP_VARIANT = "" + + APP_NAME = "{}/{}".format(APP, APP_VARIANT) + + TIMEOUT = 120 # publish timeout + @pytest.fixture(scope="module") def last_workfile_path(self, download_test_data): raise NotImplementedError @@ -142,3 +172,84 @@ class TestCase: @pytest.fixture(scope="module") def startup_scripts(self, monkeypatch_session, download_test_data): raise NotImplementedError + + @pytest.fixture(scope="module") + def launched_app(self, dbcon, download_test_data, last_workfile_path, + startup_scripts): + """Launch host app""" + # set publishing folders + root_key = "config.roots.work.{}".format("windows") # TEMP + dbcon.update_one( + {"type": "project"}, + {"$set": + { + root_key: download_test_data + }} + ) + + # set schema - for integrate_new + from openpype import PACKAGE_DIR + # Path to OpenPype's schema + schema_path = os.path.join( + os.path.dirname(PACKAGE_DIR), + "schema" + ) + os.environ["AVALON_SCHEMA"] = schema_path + + import openpype + openpype.install() + os.environ["OPENPYPE_EXECUTABLE"] = sys.executable + from openpype.lib import ApplicationManager + + application_manager = ApplicationManager() + data = { + "last_workfile_path": last_workfile_path, + "start_last_workfile": True, + "project_name": self.PROJECT, + "asset_name": self.ASSET, + "task_name": self.TASK + } + + yield application_manager.launch(self.APP_NAME, **data) + + @pytest.fixture(scope="module") + def publish_finished(self, dbcon, launched_app): + """Dummy fixture waiting for publish to finish""" + import time + time_start = time.time() + while launched_app.poll() is None: + time.sleep(0.5) + if time.time() - time_start > self.TIMEOUT: + raise ValueError("Timeout reached") + + # some clean exit test possible? + print("Publish finished") + yield True + + def test_folder_structure_same(self, dbcon, publish_finished, + download_test_data): + """Check if expected and published subfolders contain same files. + + Compares only presence, not size nor content! + """ + published_dir_base = download_test_data + published_dir = os.path.join(published_dir_base, + self.PROJECT, + self.TASK, + "**") + expected_dir_base = os.path.join(published_dir_base, + "expected") + expected_dir = os.path.join(expected_dir_base, + self.PROJECT, + self.TASK, + "**") + + published = set(f.replace(published_dir_base, '') for f in + glob.glob(published_dir, recursive=True) if + f != published_dir_base and os.path.exists(f)) + expected = set(f.replace(expected_dir_base, '') for f in + glob.glob(expected_dir, recursive=True) if + f != expected_dir_base and os.path.exists(f)) + + not_matched = expected.difference(published) + assert not not_matched, "Missing {} files".format(not_matched) \ No newline at end of file diff --git a/tests/unit/openpype/modules/sync_server/test_site_operations.py b/tests/unit/openpype/modules/sync_server/test_site_operations.py index 029f9a9f05..ab15025399 100644 --- a/tests/unit/openpype/modules/sync_server/test_site_operations.py +++ b/tests/unit/openpype/modules/sync_server/test_site_operations.py @@ -13,11 +13,13 @@ """ import pytest -from tests.lib.testing_wrapper import TestCase +from tests.lib.testing_classes import ModuleUnitTest from bson.objectid import ObjectId -class TestSiteOperation(TestCase): +class TestSiteOperation(ModuleUnitTest): + + REPRESENTATION_ID = "60e578d0c987036c6a7b741d" @pytest.fixture(scope="module") def setup_sync_server_module(self, dbcon):