Cura/tests/Settings/TestCuraContainerRegistry.py
Ghostkeeper afbadd9260
Update tests with new required metadata fields
We're changing the validation function of metadata for containers to require the type and name parameters. That needs to be reflected in the tests.

Contributes to issue CURA-3Z4.
2022-06-08 10:44:37 +02:00

328 lines
18 KiB
Python

# Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import os #To find the directory with test files and find the test files.
import pytest #To parameterize tests.
import unittest.mock #To mock and monkeypatch stuff.
from cura.ReaderWriters.ProfileReader import NoProfileException
from cura.Settings.ExtruderStack import ExtruderStack #Testing for returning the correct types of stacks.
from cura.Settings.GlobalStack import GlobalStack #Testing for returning the correct types of stacks.
import UM.Settings.InstanceContainer #Creating instance containers to register.
import UM.Settings.ContainerRegistry #Making empty container stacks.
import UM.Settings.ContainerStack #Setting the container registry here properly.
import cura.CuraApplication
def teardown():
#If the temporary file for the legacy file rename test still exists, remove it.
temporary_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "stacks", "temporary.stack.cfg")
if os.path.isfile(temporary_file):
os.remove(temporary_file)
def test_createUniqueName(container_registry):
from cura.CuraApplication import CuraApplication
assert container_registry.createUniqueName("user", "test", "test2", "nope") == "test2"
# Make a conflict (so that "test2" will no longer be an unique name)
instance = UM.Settings.InstanceContainer.InstanceContainer(container_id="test2")
instance.setMetaDataEntry("type", "user")
instance.setMetaDataEntry("setting_version", CuraApplication.SettingVersion)
container_registry.addContainer(instance)
# It should add a #2 to test2
assert container_registry.createUniqueName("user", "test", "test2", "nope") == "test2 #2"
# The provided suggestion is already correct, so nothing to do
assert container_registry.createUniqueName("user", "test", "test2 #2", "nope") == "test2 #2"
# In case we don't provide a new name, use the fallback
assert container_registry.createUniqueName("user", "test", "", "nope") == "nope"
def test_addContainerExtruderStack(container_registry, definition_container, definition_changes_container):
"""Tests whether addContainer properly converts to ExtruderStack."""
container_registry.addContainer(definition_container)
container_registry.addContainer(definition_changes_container)
container_stack = ExtruderStack("Test Extruder Stack") #A container we're going to convert.
container_stack.setMetaDataEntry("type", "extruder_train") #This is now an extruder train.
container_stack.setDefinition(definition_container) #Add a definition to it so it doesn't complain.
container_stack.setDefinitionChanges(definition_changes_container)
mock_super_add_container = unittest.mock.MagicMock() #Takes the role of the Uranium-ContainerRegistry where the resulting containers get registered.
with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container):
container_registry.addContainer(container_stack)
assert len(mock_super_add_container.call_args_list) == 1 #Called only once.
assert len(mock_super_add_container.call_args_list[0][0]) == 1 #Called with one parameter.
assert type(mock_super_add_container.call_args_list[0][0][0]) == ExtruderStack
def test_addContainerGlobalStack(container_registry, definition_container, definition_changes_container):
"""Tests whether addContainer properly converts to GlobalStack."""
container_registry.addContainer(definition_container)
container_registry.addContainer(definition_changes_container)
container_stack = GlobalStack("Test Global Stack") #A container we're going to convert.
container_stack.setMetaDataEntry("type", "machine") #This is now a global stack.
container_stack.setDefinition(definition_container) #Must have a definition.
container_stack.setDefinitionChanges(definition_changes_container) #Must have a definition changes.
mock_super_add_container = unittest.mock.MagicMock() #Takes the role of the Uranium-ContainerRegistry where the resulting containers get registered.
with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container):
container_registry.addContainer(container_stack)
assert len(mock_super_add_container.call_args_list) == 1 #Called only once.
assert len(mock_super_add_container.call_args_list[0][0]) == 1 #Called with one parameter.
assert type(mock_super_add_container.call_args_list[0][0][0]) == GlobalStack
def test_addContainerGoodSettingVersion(container_registry, definition_container):
from cura.CuraApplication import CuraApplication
definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion
container_registry.addContainer(definition_container)
instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance Right Version")
instance.setMetaDataEntry("setting_version", CuraApplication.SettingVersion)
instance.setDefinition(definition_container.getId())
mock_super_add_container = unittest.mock.MagicMock() #Take the role of the Uranium-ContainerRegistry where the resulting containers get registered.
with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container):
container_registry.addContainer(instance)
mock_super_add_container.assert_called_once_with(instance) #The instance must have been registered now.
def test_addContainerNoSettingVersion(container_registry, definition_container):
from cura.CuraApplication import CuraApplication
definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion
container_registry.addContainer(definition_container)
instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance No Version")
#Don't add setting_version metadata.
instance.setDefinition(definition_container.getId())
mock_super_add_container = unittest.mock.MagicMock() #Take the role of the Uranium-ContainerRegistry where the resulting container should not get registered.
with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container):
container_registry.addContainer(instance)
mock_super_add_container.assert_not_called() #Should not get passed on to UM.Settings.ContainerRegistry.addContainer, because the setting_version is interpreted as 0!
def test_addContainerBadSettingVersion(container_registry, definition_container):
from cura.CuraApplication import CuraApplication
definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion
container_registry.addContainer(definition_container)
instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance Wrong Version")
instance.setMetaDataEntry("setting_version", 9001) #Wrong version!
instance.setDefinition(definition_container.getId())
mock_super_add_container = unittest.mock.MagicMock() #Take the role of the Uranium-ContainerRegistry where the resulting container should not get registered.
with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container):
container_registry.addContainer(instance)
mock_super_add_container.assert_not_called() #Should not get passed on to UM.Settings.ContainerRegistry.addContainer, because the setting_version doesn't match its definition!
test_loadMetaDataValidation_data = [
{
"id": "valid_container",
"is_valid": True,
"metadata": {
"id": "valid_container",
"setting_version": None, #The tests sets this to the current version so it's always correct.
"foo": "bar"
}
},
{
"id": "wrong_setting_version",
"is_valid": False,
"metadata": {
"id": "wrong_setting_version",
"setting_version": "5",
"foo": "bar"
}
},
{
"id": "missing_setting_version",
"is_valid": False,
"metadata": {
"id": "missing_setting_version",
"foo": "bar"
}
},
{
"id": "unparsable_setting_version",
"is_valid": False,
"metadata": {
"id": "unparsable_setting_version",
"setting_version": "Not an integer!",
"foo": "bar"
}
}
]
@pytest.mark.parametrize("parameters", test_loadMetaDataValidation_data)
def test_loadMetadataValidation(container_registry, definition_container, parameters):
from cura.CuraApplication import CuraApplication
definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion
container_registry.addContainer(definition_container)
if "setting_version" in parameters["metadata"] and parameters["metadata"]["setting_version"] is None: #Signal that the setting_version must be set to the currently correct version.
parameters["metadata"]["setting_version"] = CuraApplication.SettingVersion
mock_provider = unittest.mock.MagicMock()
mock_provider.getAllIds = unittest.mock.MagicMock(return_value = [parameters["id"]])
mock_provider.loadMetadata = unittest.mock.MagicMock(return_value = parameters["metadata"])
container_registry._providers = [mock_provider]
container_registry.loadAllMetadata() #Run the test.
if parameters["is_valid"]:
assert parameters["id"] in container_registry.metadata
assert container_registry.metadata[parameters["id"]] == parameters["metadata"]
else:
assert parameters["id"] not in container_registry.metadata
class TestExportQualityProfile:
# This class is just there to provide some grouping for the tests.
def test_exportQualityProfileInvalidFileType(self, container_registry):
# With an invalid file_type, we should get a false for success.
assert not container_registry.exportQualityProfile([], "zomg", "invalid")
def test_exportQualityProfileFailedWriter(self, container_registry):
# Create a writer that always fails.
mocked_writer = unittest.mock.MagicMock(name = "mocked_writer")
mocked_writer.write = unittest.mock.MagicMock(return_value = False)
container_registry._findProfileWriter = unittest.mock.MagicMock("findProfileWriter", return_value = mocked_writer)
# Ensure that it actually fails if the writer did.
with unittest.mock.patch("UM.Application.Application.getInstance"):
assert not container_registry.exportQualityProfile([], "zomg", "test files (*.tst)")
def test_exportQualityProfileExceptionWriter(self, container_registry):
# Create a writer that always fails.
mocked_writer = unittest.mock.MagicMock(name = "mocked_writer")
mocked_writer.write = unittest.mock.MagicMock(return_value = True, side_effect = Exception("Failed :("))
container_registry._findProfileWriter = unittest.mock.MagicMock("findProfileWriter", return_value = mocked_writer)
# Ensure that it actually fails if the writer did.
with unittest.mock.patch("UM.Application.Application.getInstance"):
assert not container_registry.exportQualityProfile([], "zomg", "test files (*.tst)")
def test_exportQualityProfileSuccessWriter(self, container_registry):
# Create a writer that always fails.
mocked_writer = unittest.mock.MagicMock(name="mocked_writer")
mocked_writer.write = unittest.mock.MagicMock(return_value=True)
container_registry._findProfileWriter = unittest.mock.MagicMock("findProfileWriter", return_value=mocked_writer)
# Ensure that it actually fails if the writer did.
with unittest.mock.patch("UM.Application.Application.getInstance"):
assert container_registry.exportQualityProfile([], "zomg", "test files (*.tst)")
def test__findProfileWriterNoPlugins(container_registry):
# Mock it so that no IO plugins are found.
container_registry._getIOPlugins = unittest.mock.MagicMock(return_value = [])
with unittest.mock.patch("UM.PluginRegistry.PluginRegistry.getInstance"):
# Since there are no writers, don't return any
assert container_registry._findProfileWriter(".zomg", "dunno") is None
def test__findProfileWriter(container_registry):
# Mock it so that no IO plugins are found.
container_registry._getIOPlugins = unittest.mock.MagicMock(return_value = [("writer_id", {"profile_writer": [{"extension": ".zomg", "description": "dunno"}]})])
with unittest.mock.patch("UM.PluginRegistry.PluginRegistry.getInstance"):
# In this case it's getting a mocked object (from the mocked_plugin_registry)
assert container_registry._findProfileWriter(".zomg", "dunno") is not None
def test_importProfileEmptyFileName(container_registry):
result = container_registry.importProfile("")
assert result["status"] == "error"
mocked_application = unittest.mock.MagicMock(name = "application")
mocked_plugin_registry = unittest.mock.MagicMock(name = "mocked_plugin_registry")
@unittest.mock.patch("UM.Application.Application.getInstance", unittest.mock.MagicMock(return_value = mocked_application))
@unittest.mock.patch("UM.PluginRegistry.PluginRegistry.getInstance", unittest.mock.MagicMock(return_value = mocked_plugin_registry))
class TestImportProfile:
mocked_global_stack = unittest.mock.MagicMock(name = "global stack")
mocked_global_stack.getId = unittest.mock.MagicMock(return_value = "blarg")
mocked_profile_reader = unittest.mock.MagicMock()
mocked_plugin_registry.getPluginObject = unittest.mock.MagicMock(return_value=mocked_profile_reader)
def test_importProfileWithoutGlobalStack(self, container_registry):
mocked_application.getGlobalContainerStack = unittest.mock.MagicMock(return_value = None)
result = container_registry.importProfile("non_empty")
assert result["status"] == "error"
def test_importProfileNoProfileException(self, container_registry):
container_registry._getIOPlugins = unittest.mock.MagicMock(return_value=[("reader_id", {"profile_reader": [{"extension": "zomg", "description": "dunno"}]})])
mocked_application.getGlobalContainerStack = unittest.mock.MagicMock(return_value=self.mocked_global_stack)
self.mocked_profile_reader.read = unittest.mock.MagicMock(side_effect = NoProfileException)
result = container_registry.importProfile("test.zomg")
# It's not an error, but we also didn't find any profile to read.
assert result["status"] == "ok"
def test_importProfileGenericException(self, container_registry):
container_registry._getIOPlugins = unittest.mock.MagicMock(return_value=[("reader_id", {"profile_reader": [{"extension": "zomg", "description": "dunno"}]})])
mocked_application.getGlobalContainerStack = unittest.mock.MagicMock(return_value=self.mocked_global_stack)
self.mocked_profile_reader.read = unittest.mock.MagicMock(side_effect = Exception)
result = container_registry.importProfile("test.zomg")
assert result["status"] == "error"
def test_importProfileNoDefinitionFound(self, container_registry):
container_registry._getIOPlugins = unittest.mock.MagicMock(return_value=[("reader_id", {"profile_reader": [{"extension": "zomg", "description": "dunno"}]})])
mocked_application.getGlobalContainerStack = unittest.mock.MagicMock(return_value=self.mocked_global_stack)
container_registry.findDefinitionContainers = unittest.mock.MagicMock(return_value = [])
mocked_profile = unittest.mock.MagicMock(name = "Mocked_global_profile")
self.mocked_profile_reader.read = unittest.mock.MagicMock(return_value = [mocked_profile])
result = container_registry.importProfile("test.zomg")
assert result["status"] == "error"
@pytest.mark.skip
def test_importProfileSuccess(self, container_registry):
container_registry._getIOPlugins = unittest.mock.MagicMock(return_value=[("reader_id", {"profile_reader": [{"extension": "zomg", "description": "dunno"}]})])
mocked_application.getGlobalContainerStack = unittest.mock.MagicMock(return_value=self.mocked_global_stack)
mocked_definition = unittest.mock.MagicMock(name = "definition")
container_registry.findContainers = unittest.mock.MagicMock(return_value=[mocked_definition])
container_registry.findDefinitionContainers = unittest.mock.MagicMock(return_value = [mocked_definition])
mocked_profile = unittest.mock.MagicMock(name = "Mocked_global_profile")
self.mocked_profile_reader.read = unittest.mock.MagicMock(return_value = [mocked_profile])
with unittest.mock.patch.object(container_registry, "createUniqueName", return_value="derp"):
with unittest.mock.patch.object(container_registry, "_configureProfile", return_value=None):
result = container_registry.importProfile("test.zomg")
assert result["status"] == "ok"
@pytest.mark.parametrize("metadata,result", [(None, False),
({}, False),
({"setting_version": cura.CuraApplication.CuraApplication.SettingVersion, "type": "some_type", "name": "some_name"}, True),
({"setting_version": 0, "type": "some_type", "name": "some_name"}, False)])
def test_isMetaDataValid(container_registry, metadata, result):
assert container_registry._isMetadataValid(metadata) == result
def test_getIOPlugins(container_registry):
plugin_registry = unittest.mock.MagicMock()
plugin_registry.getActivePlugins = unittest.mock.MagicMock(return_value = ["lizard"])
plugin_registry.getMetaData = unittest.mock.MagicMock(return_value = {"zomg": {"test": "test"}})
with unittest.mock.patch("UM.PluginRegistry.PluginRegistry.getInstance", unittest.mock.MagicMock(return_value = plugin_registry)):
assert container_registry._getIOPlugins("zomg") == [("lizard", {"zomg": {"test": "test"}})]