Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Testing: MayaPy Default #5903

Closed
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions openpype/hooks/pre_new_console_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ def execute(self):
# Set `stdout` and `stderr` to None so new created console does not
# have redirected output to DEVNULL in build
self.launch_context.kwargs.update({
"creationflags": subprocess.CREATE_NEW_CONSOLE,
"stdout": None,
"stderr": None
"creationflags": subprocess.CREATE_NEW_CONSOLE
})

if self.launch_context.kwargs["stdout"] == subprocess.DEVNULL:
self.launch_context.kwargs["stdout"] = None

if self.launch_context.kwargs["stderr"] == subprocess.DEVNULL:
self.launch_context.kwargs["stderr"] = None
tokejepsen marked this conversation as resolved.
Show resolved Hide resolved
14 changes: 12 additions & 2 deletions openpype/lib/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,9 @@ def __init__(

self.env_group = env_group

stdout = data.pop("stdout", None)
tokejepsen marked this conversation as resolved.
Show resolved Hide resolved
stderr = data.pop("stderr", None)

self.data = dict(data)

launch_args = []
Expand Down Expand Up @@ -1013,8 +1016,15 @@ def __init__(
self.kwargs["creationflags"] = flags

if not sys.stdout:
self.kwargs["stdout"] = subprocess.DEVNULL
self.kwargs["stderr"] = subprocess.DEVNULL
if stdout is None:
tokejepsen marked this conversation as resolved.
Show resolved Hide resolved
stdout = subprocess.DEVNULL
if stderr is None:
stderr = subprocess.DEVNULL

if stdout is not None:
tokejepsen marked this conversation as resolved.
Show resolved Hide resolved
self.kwargs["stdout"] = stdout
if stderr is not None:
self.kwargs["stderr"] = stderr

self.prelaunch_hooks = None
self.postlaunch_hooks = None
Expand Down
56 changes: 46 additions & 10 deletions tests/integration/hosts/maya/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@


class MayaHostFixtures(HostFixtures):

def running_in_mayapy(self, app_group):
app_group = app_group or self.APP_GROUP

# Running in mayapy.
if app_group == "mayapy":
return True

# Running in maya.
return False

@pytest.fixture(scope="module")
def start_last_workfile(self, app_group):
"""Returns url of workfile"""
return not self.running_in_mayapy(app_group)

@pytest.fixture(scope="module")
def last_workfile_path(self, download_test_data, output_folder_url):
"""Get last_workfile_path from source data.
Expand Down Expand Up @@ -40,26 +56,46 @@ def last_workfile_path(self, download_test_data, output_folder_url):
yield dest_path

@pytest.fixture(scope="module")
def startup_scripts(self, monkeypatch_session, download_test_data):
def startup_scripts(
self, monkeypatch_session, download_test_data, app_group
):
"""Points Maya to userSetup file from input data"""
startup_path = os.path.join(
download_test_data, "input", "startup"
)
original_pythonpath = os.environ.get("PYTHONPATH")
monkeypatch_session.setenv(
"PYTHONPATH",
"{}{}{}".format(startup_path, os.pathsep, original_pythonpath)
)

monkeypatch_session.setenv(
"MAYA_CMD_FILE_OUTPUT",
os.path.join(download_test_data, "output.log")
)

if not self.running_in_mayapy(app_group):
# Not needed for running MayaPy since the testing userSetup.py will
# be passed in directly to the executable.
startup_path = os.path.join(
download_test_data, "input", "startup"
)
original_pythonpath = os.environ.get("PYTHONPATH")
monkeypatch_session.setenv(
"PYTHONPATH",
"{}{}{}".format(startup_path, os.pathsep, original_pythonpath)
)

@pytest.fixture(scope="module")
def skip_compare_folders(self):
yield []

@pytest.fixture(scope="module")
def app_args(self, download_test_data, app_group):
args = []

if self.running_in_mayapy(app_group):
# MayaPy can only be passed a python script, so Maya scene opening
# will happen post launch.
args.append(
os.path.join(
download_test_data, "input", "startup", "userSetup.py"
)
)

yield args


class MayaLocalPublishTestClass(MayaHostFixtures, PublishTest):
"""Testing class for local publishes."""
Expand Down
17 changes: 16 additions & 1 deletion tests/integration/hosts/maya/test_publish_in_maya.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ class TestPublishInMaya(MayaLocalPublishTestClass):
("test_publish_in_maya", "", "")
]

APP_GROUP = "maya"
# By default run through mayapy. For interactive mode, change to "maya" or
# input `--app_group maya` in cli.
APP_GROUP = "mayapy"

# keep empty to locate latest installed variant or explicit
APP_VARIANT = ""

Expand All @@ -46,6 +49,9 @@ def test_publish(
):
"""Testing Pyblish and Python logs within Maya."""

# We should have some output from publish_finished.
tokejepsen marked this conversation as resolved.
Show resolved Hide resolved
assert publish_finished, "No output of publish found."

# All maya output via MAYA_CMD_FILE_OUTPUT env var during test run
logging_path = os.path.join(download_test_data, "output.log")
with open(logging_path, "r") as f:
Expand All @@ -54,16 +60,25 @@ def test_publish(
print(("-" * 50) + "LOGGING" + ("-" * 50))
print(logging_output)

print(("-" * 50) + "STDOUT" + ("-" * 50))
print(publish_finished)

# Check for pyblish errors.
error_regex = r"pyblish \(ERROR\)((.|\n)*?)((pyblish \())"
matches = re.findall(error_regex, logging_output)
assert not matches, matches[0][0]

matches = re.findall(error_regex, publish_finished)
assert not matches, matches[0][0]

# Check for python errors.
error_regex = r"// Error((.|\n)*)"
matches = re.findall(error_regex, logging_output)
assert not matches, matches[0][0]

matches = re.findall(error_regex, publish_finished)
assert not matches, matches[0][0]

def test_db_asserts(self, dbcon, publish_finished):
"""Host and input data dependent expected results in DB."""
print("test_db_asserts")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import logging
import sys
import os

from maya import cmds
MAYA_STANDALONE = False
try:
import maya.standalone
maya.standalone.initialize()
MAYA_STANDALONE = True
print("maya standalone initialized")
except RuntimeError:
pass

import pyblish.util
import pyblish.util # noqa: E402
from maya import cmds # noqa: E402


def setup_pyblish_logging():
Expand All @@ -20,6 +29,13 @@ def setup_pyblish_logging():
def _run_publish_test_deferred():
try:
setup_pyblish_logging()

if MAYA_STANDALONE:
print("Opening " + os.environ["AVALON_LAST_WORKFILE"])
cmds.file(
os.environ["AVALON_LAST_WORKFILE"], open=True, force=True
)

pyblish.util.publish()
finally:
cmds.quit(force=True)
Expand Down
39 changes: 34 additions & 5 deletions tests/lib/testing_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,10 +304,24 @@ def app_args(self, download_test_data):

yield app_args

@pytest.fixture(scope="module")
def start_last_workfile(self):
"""Start last workfile or not."""
return True

@pytest.fixture(scope="module")
def stdout_path(self, download_test_data):
return os.path.join(download_test_data, "stdout.txt")

@pytest.fixture(scope="module")
def stderr_path(self, download_test_data):
return os.path.join(download_test_data, "stderr.txt")

@pytest.fixture(scope="module")
def launched_app(self, dbcon, download_test_data, last_workfile_path,
startup_scripts, app_args, app_name, output_folder_url,
setup_only):
setup_only, start_last_workfile, stdout_path,
stderr_path):
"""Launch host app"""
if setup_only or self.SETUP_ONLY:
print("Creating only setup for test, not launching app")
Expand All @@ -325,13 +339,17 @@ def launched_app(self, dbcon, download_test_data, last_workfile_path,
os.environ["OPENPYPE_EXECUTABLE"] = sys.executable
from openpype.lib import ApplicationManager

stdout = open(stdout_path, "w")
stderr = open(stderr_path, "w")
application_manager = ApplicationManager()
data = {
"last_workfile_path": last_workfile_path,
"start_last_workfile": True,
"start_last_workfile": start_last_workfile,
"project_name": self.PROJECT,
"asset_name": self.ASSET,
"task_name": self.TASK
"task_name": self.TASK,
"stdout": stdout,
"stderr": stderr
}
if app_args:
data["app_args"] = app_args
Expand All @@ -341,7 +359,7 @@ def launched_app(self, dbcon, download_test_data, last_workfile_path,

@pytest.fixture(scope="module")
def publish_finished(self, dbcon, launched_app, download_test_data,
timeout, setup_only):
timeout, setup_only, stdout_path, stderr_path):
"""Dummy fixture waiting for publish to finish"""
if setup_only or self.SETUP_ONLY:
print("Creating only setup for test, not launching app")
Expand All @@ -359,7 +377,18 @@ def publish_finished(self, dbcon, launched_app, download_test_data,

# some clean exit test possible?
print("Publish finished")
yield True

if launched_app.returncode != 0:
stderr = None
with open(stderr_path, "r") as f:
stderr = f.read()
raise ValueError("Launched app errored:\n{}".format(stderr))

stdout = None
with open(stdout_path, "r") as f:
stdout = f.read()

yield stdout

def test_folder_structure_same(self, dbcon, publish_finished,
download_test_data, output_folder_url,
Expand Down
Loading