MediaPlane/test/test_plugin.py

497 lines
17 KiB
Python

# Maya Image Plane Node Plugin Test Script
# This script tests the plugin functionality using mayapy.exe
# Usage: mayapy.exe test_plugin.py
import sys
import os
# Test Results Storage
test_results = {
"passed": [],
"failed": [],
"errors": []
}
def log_test(test_name, passed, message=""):
"""Log test result"""
if passed:
test_results["passed"].append(test_name)
print(f"[PASS] {test_name}")
else:
test_results["failed"].append(test_name)
print(f"[FAIL] {test_name}: {message}")
if message:
print(f" {message}")
def setup_maya_module_path():
"""Setup Maya module path"""
module_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya")
module_path = os.path.normpath(module_path)
os.environ["MAYA_MODULE_PATH"] = module_path
print(f"MAYA_MODULE_PATH set to: {module_path}")
return module_path
def test_plugin_loading():
"""Test 1: Plugin Loading Test"""
print("\n" + "="*50)
print("TEST 1: Plugin Loading Test")
print("="*50)
try:
import maya.standalone
maya.standalone.initialize()
print("Maya standalone initialized")
except Exception as e:
log_test("Initialize Maya Standalone", False, str(e))
return False
try:
import maya.cmds as cmds
# Get plugin path
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
plugin_path = os.path.normpath(plugin_path)
print(f"Plugin path: {plugin_path}")
print(f"Plugin exists: {os.path.exists(plugin_path)}")
# Load plugin
result = cmds.loadPlugin(plugin_path)
log_test("Load Plugin MayaImagePlaneNode", result is not None, f"Result: {result}")
# Check if plugin is loaded
plugins = cmds.pluginInfo(q=True, listPlugins=True)
plugin_loaded = "MayaImagePlaneNode" in plugins
log_test("Plugin in plugin list", plugin_loaded, f"Plugins: {plugins}")
return plugin_loaded
except Exception as e:
log_test("Load Plugin", False, str(e))
import traceback
traceback.print_exc()
return False
def test_plugin_unloading():
"""Test 1b: Plugin Unloading Test"""
print("\n" + "="*50)
print("TEST 1b: Plugin Unloading Test")
print("="*50)
try:
import maya.cmds as cmds
# Unload plugin
cmds.unloadPlugin("MayaImagePlaneNode")
log_test("Unload Plugin MayaImagePlaneNode", True)
# Verify unloaded
plugins = cmds.pluginInfo(q=True, listPlugins=True)
plugin_unloaded = "MayaImagePlaneNode" not in plugins
log_test("Plugin removed from list", plugin_unloaded)
return plugin_unloaded
except Exception as e:
log_test("Unload Plugin", False, str(e))
return False
def test_node_creation():
"""Test 2: Node Creation Test"""
print("\n" + "="*50)
print("TEST 2: Node Creation Test")
print("="*50)
try:
import maya.cmds as cmds
# Load plugin first if not loaded
if "MayaImagePlaneNode" not in cmds.pluginInfo(q=True, listPlugins=True):
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
cmds.loadPlugin(plugin_path)
# Create node
node_name = cmds.createNode("imagePlaneVideo")
node_created = node_name is not None
log_test("Create Node imagePlaneVideo", node_created, f"Node: {node_name}")
# Verify node type
node_type = cmds.nodeType(node_name)
correct_type = node_type == "imagePlaneVideo"
log_test("Node type is imagePlaneVideo", correct_type, f"Type: {node_type}")
return node_created and correct_type
except Exception as e:
log_test("Create Node", False, str(e))
import traceback
traceback.print_exc()
return False
def test_node_attributes():
"""Test 3: Node Attributes Test"""
print("\n" + "="*50)
print("TEST 3: Node Attributes Test")
print("="*50)
try:
import maya.cmds as cmds
# Load plugin first
if "MayaImagePlaneNode" not in cmds.pluginInfo(q=True, listPlugins=True):
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
cmds.loadPlugin(plugin_path)
# Create node if not exists
if not cmds.objExists("imagePlaneVideo1"):
cmds.createNode("imagePlaneVideo")
node_name = "imagePlaneVideo1"
# List all attributes
attrs = cmds.listAttr(node_name)
print(f"Attributes: {attrs}")
# Required input attributes
required_attrs = [
"videoFile",
"currentTime",
"frameRate",
"playbackRate",
"useMayaFrameRate",
"loop",
"postEffectCrop",
"postEffectResize",
"postEffectFlip",
"cacheSize"
]
# Output attributes
output_attrs = [
"outFrameWidth",
"outFrameHeight",
"outFrameTimestamp",
"outFrameCount",
"outIsValid",
"outCacheHitRatio"
]
# Test input attributes
for attr in required_attrs:
attr_exists = cmds.attributeQuery(attr, node=node_name, exists=True)
log_test(f"Attribute: {attr}", attr_exists)
# Test output attributes
for attr in output_attrs:
attr_exists = cmds.attributeQuery(attr, node=node_name, exists=True)
log_test(f"Output Attribute: {attr}", attr_exists)
return True
except Exception as e:
log_test("List Attributes", False, str(e))
import traceback
traceback.print_exc()
return False
def test_attribute_functionality():
"""Test 4: Attribute Functionality Test"""
print("\n" + "="*50)
print("TEST 4: Attribute Functionality Test")
print("="*50)
try:
import maya.cmds as cmds
# Load plugin first
if "MayaImagePlaneNode" not in cmds.pluginInfo(q=True, listPlugins=True):
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
cmds.loadPlugin(plugin_path)
# Create node if not exists
if not cmds.objExists("imagePlaneVideo1"):
cmds.createNode("imagePlaneVideo")
node_name = "imagePlaneVideo1"
# Test video file attribute
test_video_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_video.mp4")
test_video_path = os.path.normpath(test_video_path)
try:
cmds.setAttr(f"{node_name}.videoFile", test_video_path, type="string")
video_file = cmds.getAttr(f"{node_name}.videoFile")
log_test("Set videoFile attribute", video_file == test_video_path, f"Set: {video_file}")
except Exception as e:
log_test("Set videoFile attribute", False, str(e))
# Test currentTime attribute
try:
cmds.setAttr(f"{node_name}.currentTime", 1.0)
current_time = cmds.getAttr(f"{node_name}.currentTime")
log_test("Set currentTime attribute", current_time == 1.0, f"Value: {current_time}")
except Exception as e:
log_test("Set currentTime attribute", False, str(e))
# Test frameRate attribute
try:
cmds.setAttr(f"{node_name}.frameRate", 24.0)
frame_rate = cmds.getAttr(f"{node_name}.frameRate")
log_test("Set frameRate attribute", frame_rate == 24.0, f"Value: {frame_rate}")
except Exception as e:
log_test("Set frameRate attribute", False, str(e))
# Test playbackRate attribute (0.25x to 4.0x)
playback_rates = [0.25, 0.5, 1.0, 2.0, 4.0]
for rate in playback_rates:
try:
cmds.setAttr(f"{node_name}.playbackRate", rate)
actual_rate = cmds.getAttr(f"{node_name}.playbackRate")
log_test(f"Set playbackRate={rate}", abs(actual_rate - rate) < 0.01, f"Value: {actual_rate}")
except Exception as e:
log_test(f"Set playbackRate={rate}", False, str(e))
# Test useMayaFrameRate attribute
try:
cmds.setAttr(f"{node_name}.useMayaFrameRate", True)
use_maya = cmds.getAttr(f"{node_name}.useMayaFrameRate")
log_test("Set useMayaFrameRate=True", use_maya == True)
cmds.setAttr(f"{node_name}.useMayaFrameRate", False)
use_maya = cmds.getAttr(f"{node_name}.useMayaFrameRate")
log_test("Set useMayaFrameRate=False", use_maya == False)
except Exception as e:
log_test("Set useMayaFrameRate attribute", False, str(e))
# Test loop attribute
try:
cmds.setAttr(f"{node_name}.loop", True)
loop = cmds.getAttr(f"{node_name}.loop")
log_test("Set loop=True", loop == True)
except Exception as e:
log_test("Set loop attribute", False, str(e))
# Test postEffectCrop attribute (4 values)
try:
cmds.setAttr(f"{node_name}.postEffectCrop", 10, 20, 30, 40)
crop = cmds.getAttr(f"{node_name}.postEffectCrop")
log_test("Set postEffectCrop", crop == [10, 20, 30, 40], f"Value: {crop}")
except Exception as e:
log_test("Set postEffectCrop attribute", False, str(e))
# Test postEffectResize attribute (2 values)
try:
cmds.setAttr(f"{node_name}.postEffectResize", 800, 600)
resize = cmds.getAttr(f"{node_name}.postEffectResize")
log_test("Set postEffectResize", resize == [800, 600], f"Value: {resize}")
except Exception as e:
log_test("Set postEffectResize attribute", False, str(e))
# Test postEffectFlip attribute (2 values)
try:
cmds.setAttr(f"{node_name}.postEffectFlip", 1, 0) # Horizontal flip
flip = cmds.getAttr(f"{node_name}.postEffectFlip")
log_test("Set postEffectFlip", flip == [1, 0], f"Value: {flip}")
except Exception as e:
log_test("Set postEffectFlip attribute", False, str(e))
# Test cacheSize attribute
try:
cmds.setAttr(f"{node_name}.cacheSize", 100)
cache_size = cmds.getAttr(f"{node_name}.cacheSize")
log_test("Set cacheSize", cache_size == 100, f"Value: {cache_size}")
except Exception as e:
log_test("Set cacheSize attribute", False, str(e))
return True
except Exception as e:
log_test("Attribute Functionality Test", False, str(e))
import traceback
traceback.print_exc()
return False
def test_output_attributes():
"""Test 5: Output Attributes Test"""
print("\n" + "="*50)
print("TEST 5: Output Attributes Test")
print("="*50)
try:
import maya.cmds as cmds
# Load plugin first
if "MayaImagePlaneNode" not in cmds.pluginInfo(q=True, listPlugins=True):
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
cmds.loadPlugin(plugin_path)
# Create node if not exists
if not cmds.objExists("imagePlaneVideo1"):
cmds.createNode("imagePlaneVideo")
node_name = "imagePlaneVideo1"
# Set video file
test_video_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_video.mp4")
test_video_path = os.path.normpath(test_video_path)
cmds.setAttr(f"{node_name}.videoFile", test_video_path, type="string")
# Force recompute
cmds.getAttr(f"{node_name}.outFrameWidth")
# Test output attributes
output_attrs = {
"outFrameWidth": None,
"outFrameHeight": None,
"outFrameTimestamp": None,
"outFrameCount": None,
"outIsValid": None,
"outCacheHitRatio": None
}
for attr in output_attrs.keys():
try:
value = cmds.getAttr(f"{node_name}.{attr}")
output_attrs[attr] = value
log_test(f"Get {attr}", value is not None, f"Value: {value}")
except Exception as e:
log_test(f"Get {attr}", False, str(e))
# Validate output values
if output_attrs["outFrameWidth"]:
log_test("outFrameWidth > 0", output_attrs["outFrameWidth"] > 0)
if output_attrs["outFrameHeight"]:
log_test("outFrameHeight > 0", output_attrs["outFrameHeight"] > 0)
if output_attrs["outFrameCount"]:
log_test("outFrameCount > 0", output_attrs["outFrameCount"] > 0)
if output_attrs["outIsValid"] is not None:
# Note: May be False if video not properly loaded
log_test("outIsValid accessible", True)
if output_attrs["outCacheHitRatio"] is not None:
log_test("outCacheHitRatio in range [0,1]", 0 <= output_attrs["outCacheHitRatio"] <= 1)
return True
except Exception as e:
log_test("Output Attributes Test", False, str(e))
import traceback
traceback.print_exc()
return False
def test_ffmpeg_dll_dependencies():
"""Test 6: FFmpeg DLL Dependencies Test"""
print("\n" + "="*50)
print("TEST 6: FFmpeg DLL Dependencies Test")
print("="*50)
try:
import maya.cmds as cmds
# Load plugin first
if "MayaImagePlaneNode" not in cmds.pluginInfo(q=True, listPlugins=True):
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
cmds.loadPlugin(plugin_path)
# Check FFmpeg DLLs
plugin_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins")
required_dlls = [
"avcodec-62.dll",
"avformat-62.dll",
"avutil-60.dll",
"swscale-9.dll"
]
for dll in required_dlls:
dll_path = os.path.join(plugin_dir, dll)
dll_exists = os.path.exists(dll_path)
log_test(f"FFmpeg DLL: {dll}", dll_exists, f"Path: {dll_path}")
return True
except Exception as e:
log_test("FFmpeg DLL Dependencies Test", False, str(e))
import traceback
traceback.print_exc()
return False
def print_test_summary():
"""Print test summary"""
print("\n" + "="*50)
print("TEST SUMMARY")
print("="*50)
print(f"Passed: {len(test_results['passed'])}")
print(f"Failed: {len(test_results['failed'])}")
print(f"Errors: {len(test_results['errors'])}")
if test_results['failed']:
print("\nFailed Tests:")
for test in test_results['failed']:
print(f" - {test}")
if test_results['errors']:
print("\nErrors:")
for error in test_results['errors']:
print(f" - {error}")
return len(test_results['failed']) == 0 and len(test_results['errors']) == 0
def main():
"""Main test function"""
print("Maya Image Plane Node Plugin Test")
print("="*50)
# Setup module path
setup_maya_module_path()
# Run tests
all_passed = True
# Test 1: Plugin Loading
if not test_plugin_loading():
all_passed = False
# Test 1b: Plugin Unloading
if not test_plugin_unloading():
all_passed = False
# Reload plugin for subsequent tests
try:
import maya.cmds as cmds
plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "maya", "2023", "plug-ins", "MayaImagePlaneNode.mll")
cmds.loadPlugin(plugin_path)
except:
pass
# Test 2: Node Creation
if not test_node_creation():
all_passed = False
# Test 3: Node Attributes
if not test_node_attributes():
all_passed = False
# Test 4: Attribute Functionality
if not test_attribute_functionality():
all_passed = False
# Test 5: Output Attributes
if not test_output_attributes():
all_passed = False
# Test 6: FFmpeg DLL Dependencies
if not test_ffmpeg_dll_dependencies():
all_passed = False
# Print summary
print_test_summary()
return 0 if all_passed else 1
if __name__ == "__main__":
sys.exit(main())