Skip to content

Commit a8e569c

Browse files
committed
[tests] Updated Tests for including Reloading of a Node
1 parent fbd786b commit a8e569c

File tree

1 file changed

+152
-2
lines changed

1 file changed

+152
-2
lines changed

tests/test_plugins.py

Lines changed: 152 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
""" Test for Meshroom Plugins.
2-
"""
31
#!/usr/bin/env python
42
# coding:utf-8
3+
""" Test for Meshroom Plugins.
4+
"""
5+
# STD
6+
import os
7+
import shutil
8+
import tempfile
59

10+
# Internal
611
from meshroom.core import _plugins
712
from meshroom.core import desc, registerNodeType, unregisterNodeType
13+
from meshroom.core.graph import Graph
14+
from meshroom.core.node import Node, IncompatiblePluginNode
815

916

1017
class SampleNode(desc.Node):
@@ -47,6 +54,7 @@ def test_plugin_management():
4754
assert not pluginManager.registered(name)
4855
assert name not in pluginManager.descriptors
4956

57+
5058
def test_descriptor():
5159
""" Tests the Descriptor and NodeDescriptor instances.
5260
"""
@@ -65,3 +73,145 @@ def test_descriptor():
6573

6674
# Finally unregister the plugin
6775
unregisterNodeType(SampleNode)
76+
77+
78+
def _setup_temp_package(directory, name):
79+
""" Sets up a temporary meshroom package structure which can be loaded as plugins.
80+
"""
81+
package = os.path.join(directory, name)
82+
83+
# Create the base package in the directory
84+
os.makedirs(package)
85+
86+
# The very first file that we need is probably empty __init__.py
87+
init = os.path.join(package, "__init__.py")
88+
89+
# The second thing we need is a directory inside
90+
packageDir = os.path.join(package, "TesingPackage")
91+
92+
# Third would be another init for the package
93+
packinit = os.path.join(packageDir, "__init__.py")
94+
95+
# Then comes the main module which will hold the plugin
96+
pluginMod = os.path.join(packageDir, "TestInput.py")
97+
98+
# Now start constructing stuff here
99+
os.makedirs(packageDir)
100+
101+
with open(init, "w") as f:
102+
f.write("__version__ =\"1.0\"")
103+
104+
with open(packinit, "w") as f:
105+
f.write("__version__ =\"1.0\"")
106+
107+
contents = """
108+
from meshroom.core import desc
109+
110+
111+
class SampleTroubledNode(desc.Node):
112+
\""" Sample Node for unit testing a reload process.
113+
Defaults to having an invalid input param value. Which gets updated later on.
114+
\"""
115+
116+
category = "Sample"
117+
118+
inputs = [
119+
# A Float param having the value as a string will cause the plugin to be loaded in an Error state
120+
desc.FloatParam(name='paramA', label='ParamA', description='', value='4.0')
121+
]
122+
outputs = [
123+
desc.File(name='output', label='Output', description='', value=desc.Node.internalFolder)
124+
]
125+
"""
126+
127+
with open(pluginMod, "w") as f:
128+
f.write(contents)
129+
130+
return package
131+
132+
def _correctify_plugin(pluginPath):
133+
contents = """
134+
from meshroom.core import desc
135+
136+
137+
class SampleTroubledNode(desc.Node):
138+
\""" Sample Node for unit testing a reload process.
139+
Defaults to having an invalid input param value. Which gets updated later on.
140+
\"""
141+
142+
category = "Sample"
143+
144+
inputs = [
145+
# A Float param having the value as a string will cause the plugin to be loaded in an Error state
146+
desc.FloatParam(name='paramA', label='ParamA', description='', value=4.0)
147+
]
148+
outputs = [
149+
desc.File(name='output', label='Output', description='', value=desc.Node.internalFolder)
150+
]
151+
"""
152+
153+
with open(pluginPath, "w") as f:
154+
f.write(contents)
155+
156+
157+
def _cleaup_package(directory):
158+
""" Cleans up the Package
159+
"""
160+
shutil.rmtree(directory)
161+
162+
def test_reload_with_graph():
163+
""" Tests Reloading of a plugin and how does the change propagate to a graph.
164+
"""
165+
# Create a temp directory
166+
directory = tempfile.mkdtemp()
167+
168+
package = _setup_temp_package(directory, "MTest")
169+
170+
# Since the Node Plugin Manager is a singleton instance
171+
# We should still be able to instantiate and have a look at out registered plugins directly
172+
pluginManager = _plugins.NodePluginManager()
173+
174+
pluginManager.load(package)
175+
176+
# Sample Node name
177+
name = "SampleTroubledNode"
178+
179+
# Assert that the plugin we have registered above is indeed registered
180+
assert pluginManager.registered(name)
181+
182+
# But the status of the plugin would be errored
183+
assert pluginManager.status(name) == _plugins.Status.ERRORED
184+
185+
# Graph for usage
186+
g = Graph("")
187+
188+
# Create Nodes in the Graph
189+
n = g.addNewNode(name)
190+
191+
# Assert that the node is of an Incompatible Plugin type as the plugin had errors while loading
192+
assert isinstance(n, IncompatiblePluginNode)
193+
194+
descriptor = pluginManager.descriptors.get(name)
195+
# Test that the plugin would not get reloaded
196+
# unless either the source has been modified or the plugin is forced to be loaded
197+
assert not descriptor.reload()
198+
199+
# Modify the Source of the Troubled Node before we reload the plugin
200+
# This updates the source of the plugin and ensures that the plugin can now be loaded as expected
201+
_correctify_plugin(os.path.join(package, "TesingPackage", "TestInput.py"))
202+
203+
# Reload the plugin as the source has been modified
204+
assert descriptor.reload()
205+
206+
# Now the plugin has been reloaded
207+
assert pluginManager.status(name) == _plugins.Status.LOADED
208+
209+
# Now reload the nodes of the provided type in the graph
210+
g.reloadNodes(name)
211+
212+
# Get all the nodes and assert that they have been upgraded to Standard Nodes
213+
for node in g.nodesOfType(name):
214+
assert isinstance(node, Node)
215+
216+
# Once the tests are concluded -> Cleanup
217+
_cleaup_package(package)

0 commit comments

Comments
 (0)