Adapt unittests to deal with graph saving

This commit is contained in:
Fabien Castan 2025-04-13 18:50:46 +02:00
parent cd219fd70e
commit 346d78df30
4 changed files with 45 additions and 31 deletions

View file

@ -167,6 +167,19 @@ def blockNodeCallbacks(func):
return inner
def generateTempProjectFilepath(tmpFolder=None):
"""
Generate a temporary project filepath.
This method is used to generate a temporary project file for the current graph.
"""
from datetime import datetime
if tmpFolder is None:
from meshroom.env import EnvVar
tmpFolder = EnvVar.get(EnvVar.MESHROOM_TEMP_PATH)
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M")
return os.path.join(tmpFolder, f"meshroom_{timestamp}.mg")
class Graph(BaseObject):
"""
_________________ _________________ _________________
@ -1316,7 +1329,7 @@ class Graph(BaseObject):
def _save(self, filepath=None, setupProjectFile=True, template=False):
path = filepath or self._filepath
if not path:
raise ValueError("filepath must be specified for unsaved files.")
path = generateTempProjectFilepath()
data = self.serialize(template)
@ -1329,6 +1342,21 @@ class Graph(BaseObject):
# update the file date version
self._fileDateVersion = os.path.getmtime(path)
def saveAsTemp(self, tmpFolder=None):
"""
Save the current Meshroom graph as a temporary project file.
"""
# Update the saving flag indicating that the current graph is being saved
self._saving = True
try:
self._saveAsTemp(tmpFolder)
finally:
self._saving = False
def _saveAsTemp(self, tmpFolder=None):
projectPath = generateTempProjectFilepath(tmpFolder)
self._save(projectPath)
def _setFilepath(self, filepath):
"""
Set the internal filepath of this Graph.
@ -1594,6 +1622,8 @@ def executeGraph(graph, toNodes=None, forceCompute=False, forceStatus=False):
print('Nodes to execute: ', str([n.name for n in nodes]))
graph.save()
for node in nodes:
node.beginSequence(forceCompute)

View file

@ -24,7 +24,7 @@ from PySide6.QtCore import (
from meshroom.core import sessionUid
from meshroom.common.qt import QObjectListModel
from meshroom.core.attribute import Attribute, ListAttribute
from meshroom.core.graph import Graph, Edge
from meshroom.core.graph import Graph, Edge, generateTempProjectFilepath
from meshroom.core.graphIO import GraphIO
from meshroom.core.taskManager import TaskManager
@ -516,11 +516,8 @@ class UIGraph(QObject):
@Slot()
def saveAsTemp(self):
from meshroom.env import EnvVar
from datetime import datetime
tempFolder = EnvVar.get(EnvVar.MESHROOM_TEMP_PATH)
timestamp = datetime.now().strftime("%Y-%m-%d_%H:%M")
self._saveAs(os.path.join(tempFolder, f"meshroom_{timestamp}.mg"))
projectPath = generateTempProjectFilepath()
self._saveAs(projectPath)
@Slot()
def save(self):

View file

@ -6,19 +6,6 @@ import pytest
from meshroom.core.graph import Graph
@pytest.fixture
def graphWithIsolatedCache():
"""
Yield a Graph instance using a unique temporary cache directory.
Can be used for testing graph computation in isolation, without having to save the graph to disk.
"""
with tempfile.TemporaryDirectory() as cacheDir:
graph = Graph("")
graph.cacheDir = cacheDir
yield graph
@pytest.fixture
def graphSavedOnDisk():
"""
@ -27,6 +14,6 @@ def graphSavedOnDisk():
Can be used for testing graph IO and computation in isolation.
"""
with tempfile.TemporaryDirectory() as cacheDir:
graph = Graph("")
graph.save(Path(cacheDir) / "test_graph.mg")
graph = Graph()
graph.saveAsTemp(cacheDir)
yield graph

View file

@ -5,7 +5,7 @@ from meshroom.core import desc, registerNodeType, unregisterNodeType
from meshroom.core.node import Node
class NodeWithAttributeChangedCallback(desc.Node):
class NodeWithAttributeChangedCallback(desc.BaseNode):
"""
A Node containing an input Attribute with an 'on{Attribute}Changed' method,
called whenever the value of this attribute is changed explicitly.
@ -182,7 +182,7 @@ class TestAttributeCallbackTriggerInGraph:
assert loadedNodeB.affectedInput.value == 2
class NodeWithCompoundAttributes(desc.Node):
class NodeWithCompoundAttributes(desc.BaseNode):
"""
A Node containing a variation of compound attributes (List/Groups),
called whenever the value of this attribute is changed explicitly.
@ -311,7 +311,7 @@ class TestAttributeCallbackBehaviorWithUpstreamCompoundAttributes:
assert nodeB.affectedInput.value == 20
class NodeWithDynamicOutputValue(desc.Node):
class NodeWithDynamicOutputValue(desc.BaseNode):
"""
A Node containing an output attribute which value is computed dynamically during graph execution.
"""
@ -363,9 +363,9 @@ class TestAttributeCallbackBehaviorWithUpstreamDynamicOutputs:
assert nodeB.affectedInput.value == 0
def test_connectingComputedDynamicOutputTriggersDownstreamAttributeChangedCallback(
self, graphWithIsolatedCache
self, graphSavedOnDisk
):
graph: Graph = graphWithIsolatedCache
graph: Graph = graphSavedOnDisk
nodeA = graph.addNewNode(NodeWithDynamicOutputValue.__name__)
nodeB = graph.addNewNode(NodeWithAttributeChangedCallback.__name__)
@ -377,9 +377,9 @@ class TestAttributeCallbackBehaviorWithUpstreamDynamicOutputs:
assert nodeB.affectedInput.value == 40
def test_dynamicOutputValueComputeDoesNotTriggerDownstreamAttributeChangedCallback(
self, graphWithIsolatedCache
self, graphSavedOnDisk
):
graph: Graph = graphWithIsolatedCache
graph: Graph = graphSavedOnDisk
nodeA = graph.addNewNode(NodeWithDynamicOutputValue.__name__)
nodeB = graph.addNewNode(NodeWithAttributeChangedCallback.__name__)
@ -392,9 +392,9 @@ class TestAttributeCallbackBehaviorWithUpstreamDynamicOutputs:
def test_clearingDynamicOutputValueDoesNotTriggerDownstreamAttributeChangedCallback(
self, graphWithIsolatedCache
self, graphSavedOnDisk
):
graph: Graph = graphWithIsolatedCache
graph: Graph = graphSavedOnDisk
nodeA = graph.addNewNode(NodeWithDynamicOutputValue.__name__)
nodeB = graph.addNewNode(NodeWithAttributeChangedCallback.__name__)