1# Copyright (c) 2017 Ultimaker B.V. 2# Uranium is released under the terms of the LGPLv3 or higher. 3 4import os 5import platform 6import unittest 7from unittest import TestCase 8from unittest.mock import patch, PropertyMock 9import tempfile 10import pytest 11 12from UM.Resources import Resources, ResourceTypeError, UnsupportedStorageTypeError 13 14 15class TestResources(TestCase): 16 17 # 18 # getConfigStorageRootPath() tests 19 # 20 @unittest.skipIf(platform.system() != "Windows", "Not on Windows") 21 def test_getConfigStorageRootPath_Windows(self): 22 config_root_path = Resources._getConfigStorageRootPath() 23 expected_config_root_path = os.getenv("APPDATA") 24 self.assertEqual(expected_config_root_path, config_root_path, 25 "expected %s, got %s" % (expected_config_root_path, config_root_path)) 26 27 @unittest.skipIf(platform.system() != "Linux", "Not on linux") 28 def test_getConfigStorageRootPath_Linux(self): 29 # no XDG_CONFIG_HOME defined 30 if "XDG_CONFIG_HOME" in os.environ: 31 del os.environ["XDG_CONFIG_HOME"] 32 config_root_path = Resources._getConfigStorageRootPath() 33 expected_config_root_path = os.path.expanduser("~/.config") 34 self.assertEqual(expected_config_root_path, config_root_path, 35 "expected %s, got %s" % (expected_config_root_path, config_root_path)) 36 37 # XDG_CONFIG_HOME defined 38 os.environ["XDG_CONFIG_HOME"] = "/tmp" 39 config_root_path = Resources._getConfigStorageRootPath() 40 expected_config_root_path = "/tmp" 41 self.assertEqual(expected_config_root_path, config_root_path, 42 "expected %s, got %s" % (expected_config_root_path, config_root_path)) 43 44 @unittest.skipIf(platform.system() != "Darwin", "Not on mac") 45 def test_getConfigStorageRootPath_Mac(self): 46 config_root_path = Resources._getConfigStorageRootPath() 47 expected_config_root_path = os.path.expanduser("~/Library/Application Support") 48 self.assertEqual(expected_config_root_path, config_root_path, 49 "expected %s, got %s" % (expected_config_root_path, config_root_path)) 50 51 @unittest.skipIf(platform.system() != "Windows", "Not on Windows") 52 def test_getDataStorageRootPath_Windows(self): 53 data_root_path = Resources._getDataStorageRootPath() 54 self.assertIsNone(data_root_path, "expected None, got %s" % data_root_path) 55 56 @unittest.skipIf(platform.system() != "Linux", "Not on linux") 57 def test_getDataStorageRootPath_Linux(self): 58 # no XDG_CONFIG_HOME defined 59 if "XDG_DATA_HOME" in os.environ: 60 del os.environ["XDG_DATA_HOME"] 61 data_root_path = Resources._getDataStorageRootPath() 62 expected_data_root_path = os.path.expanduser("~/.local/share") 63 self.assertEqual(expected_data_root_path, data_root_path, 64 "expected %s, got %s" % (expected_data_root_path, data_root_path)) 65 66 # XDG_CONFIG_HOME defined 67 os.environ["XDG_DATA_HOME"] = "/tmp" 68 data_root_path = Resources._getDataStorageRootPath() 69 expected_data_root_path = "/tmp" 70 self.assertEqual(expected_data_root_path, data_root_path, 71 "expected %s, got %s" % (expected_data_root_path, data_root_path)) 72 73 @unittest.skipIf(platform.system() != "Darwin", "Not on mac") 74 def test_getDataStorageRootPath_Mac(self): 75 data_root_path = Resources._getDataStorageRootPath() 76 self.assertIsNone(data_root_path, "expected None, got %s" % data_root_path) 77 78 @unittest.skipIf(platform.system() != "Windows", "Not on Windows") 79 def test_getCacheStorageRootPath_Windows(self): 80 if platform.system() != "Windows": 81 self.skipTest("not on Windows") 82 83 cache_root_path = Resources._getCacheStorageRootPath() 84 expected_cache_root_path = os.getenv("LOCALAPPDATA") 85 self.assertEqual(expected_cache_root_path, cache_root_path, 86 "expected %s, got %s" % (expected_cache_root_path, cache_root_path)) 87 88 @unittest.skipIf(platform.system() != "Linux", "Not on linux") 89 def test_getCacheStorageRootPath_Linux(self): 90 cache_root_path = Resources._getCacheStorageRootPath() 91 expected_cache_root_path = os.path.expanduser("~/.cache") 92 self.assertEqual(expected_cache_root_path, cache_root_path, 93 "expected %s, got %s" % (expected_cache_root_path, cache_root_path)) 94 95 @unittest.skipIf(platform.system() != "Darwin", "Not on mac") 96 def test_getCacheStorageRootPath_Mac(self): 97 cache_root_path = Resources._getCacheStorageRootPath() 98 self.assertIsNone("expected None, got %s" % cache_root_path) 99 100 @unittest.skipIf(platform.system() != "Linux", "Not on linux") 101 def test_getPossibleConfigStorageRootPathList_Linux(self): 102 # We didn't add any paths, so it will use defaults 103 assert Resources._getPossibleConfigStorageRootPathList() == ['/tmp/test'] 104 105 @unittest.skipIf(platform.system() != "Linux", "Not on linux") 106 def test_getPossibleDataStorageRootPathList_Linux(self): 107 # We didn't add any paths, so it will use defaults 108 assert Resources._getPossibleDataStorageRootPathList() == ['/tmp/test'] 109 110 def test_factoryReset(self): 111 # FIXME: This is a temporary workaround. A proper fix should be to make the home directory configurable so a 112 # unique temporary directory can be used for each test and it can removed afterwards. 113 # HACK: Record the number of files and directories in the data storage directory before the factory reset, 114 # so after the reset, we can compare if there's a new ZIP file being created. Note that this will not always 115 # work, especially when there are multiple tests running on the same host at the same time. 116 original_filenames = os.listdir(os.path.dirname(Resources.getDataStoragePath())) 117 118 Resources.factoryReset() 119 # Check if the data is deleted! 120 assert len(os.listdir(Resources.getDataStoragePath())) == 0 121 122 # The data folder should still be there, but it should also have created a zip with the data it deleted. 123 new_filenames = os.listdir(os.path.dirname(Resources.getDataStoragePath())) 124 assert len(new_filenames) - len(original_filenames) == 1 125 126 # Clean up after our ass. 127 folder = os.path.dirname(Resources.getDataStoragePath()) 128 for file in os.listdir(folder): 129 file_path = os.path.join(folder, file) 130 try: 131 os.unlink(file_path) 132 except: 133 pass 134 folder = os.path.dirname(Resources.getDataStoragePath()) 135 for file in os.listdir(folder): 136 file_path = os.path.join(folder, file) 137 try: 138 os.unlink(file_path) 139 except: 140 pass 141 142 def test_copyLatestDirsIfPresent(self): 143 # Just don't fail. 144 Resources._copyLatestDirsIfPresent() 145 146 @unittest.skipIf(platform.system() != "Linux", "Not on linux") 147 def test_getStoragePathForType_Linux(self): 148 with pytest.raises(ResourceTypeError): 149 # No types have been added, so this should break! 150 Resources.getAllResourcesOfType(0) 151 with pytest.raises(UnsupportedStorageTypeError): 152 # We still haven't added it, so it should fail (again) 153 Resources.getStoragePathForType(0) 154 155 Resources.addStorageType(0, "/test") 156 assert Resources.getStoragePathForType(0) == "/test" 157 158 def test_getAllResourcesOfType(self): 159 resouce_folder = tempfile.mkdtemp("test_folder_origin") 160 resource_file = tempfile.mkstemp(dir=str(resouce_folder)) 161 Resources.addStorageType(111, resouce_folder) 162 assert Resources.getAllResourcesOfType(111) == [resource_file[1]] 163 164 def test_copyVersionFolder(self): 165 166 import os 167 folder_to_copy = tempfile.mkdtemp("test_folder_origin") 168 file_to_copy = tempfile.mkstemp(dir=str(folder_to_copy)) 169 170 folder_to_move_to = tempfile.mkdtemp("test_folder_destination") 171 172 Resources.copyVersionFolder(str(folder_to_copy), str(folder_to_move_to) + "/target") 173 # We put a temp file in the folder to copy, check if it arrived there. 174 assert len(os.listdir(str(folder_to_move_to) + "/target")) == 1 175 176 # The app version is "dev", and this is considered as the latest version possible. It will upgrade from the highest 177 # "<major>.<minor>" directory that's available. 178 def test_findLatestDirInPathsDevAppVersion(self): 179 test_folder = tempfile.mkdtemp("test_folder") 180 for folder in ("whatever", "2.1", "3.4", "4.2", "5.1", "10.2", "50.7"): 181 os.mkdir(os.path.join(test_folder, folder)) 182 183 with patch("UM.Resources.Resources.ApplicationVersion", new_callable = PropertyMock(return_value = "dev")): 184 # We should obviously find the folder that was created by means of the ApplicationVersion. 185 assert Resources._findLatestDirInPaths([test_folder]) == os.path.join(test_folder, "50.7") 186 187 # Tests _findLatestDirInPaths() with a normal application version, that is a version like "<major>.<minor>". 188 # In this case, it should get the highest available "<major>.<minor>" directory but no higher than the application 189 # version itself. 190 def test_findLatestDirInPathsNormalAppVersion(self): 191 test_folder = tempfile.mkdtemp("test_folder") 192 for folder in ("whatever", "2.1", "3.4", "4.2", "5.1", "10.2", "50.7"): 193 os.mkdir(os.path.join(test_folder, folder)) 194 195 with patch("UM.Resources.Resources.ApplicationVersion", new_callable = PropertyMock(return_value = "4.3")): 196 # We should obviously find the folder that was created by means of the ApplicationVersion. 197 assert Resources._findLatestDirInPaths([test_folder]) == os.path.join(test_folder, "4.2") 198 199 # In this case, our app version is 4.3, but all the available directories do not have names "<major>.<minor>". 200 # _findLatestDirInPaths() should return None. 201 def test_findLatestDirInPathsNormalAppVersionNoValidUpgrade(self): 202 test_folder = tempfile.mkdtemp("test_folder") 203 for folder in ("whatever1", "whatever2", "foobar1", "dev", "master", "test"): 204 os.mkdir(os.path.join(test_folder, folder)) 205 206 with patch("UM.Resources.Resources.ApplicationVersion", new_callable = PropertyMock(return_value = "4.3")): 207 # There is no folder that matches what we're looking for! 208 assert Resources._findLatestDirInPaths([test_folder]) is None 209 210 # In this case, our app version is 4.3, but all there's no available directory named as "<major>.<minor>". 211 # _findLatestDirInPaths() should return None. 212 def test_findLatestDirInPathsNormalAppVersionEmptySearchFolder(self): 213 test_folder = tempfile.mkdtemp("test_folder") 214 215 with patch("UM.Resources.Resources.ApplicationVersion", new_callable = PropertyMock(return_value = "4.3")): 216 # There is no folder that matches what we're looking for! 217 assert Resources._findLatestDirInPaths([test_folder]) is None 218 219 def test_addRemoveStorageType(self): 220 Resources.addStorageType(9901, "YAY") 221 Resources.addType(9902, "whoo") 222 Resources.addStorageType(100, "herpderp") 223 224 with pytest.raises(ResourceTypeError): 225 # We can't add the same type again 226 Resources.addStorageType(9901, "nghha") 227 228 Resources.removeType(9001) 229 Resources.removeType(9902) 230 231 with pytest.raises(ResourceTypeError): 232 # We can't do that, since it's in the range of user types. 233 Resources.removeType(100) 234 235 with pytest.raises(ResourceTypeError): 236 # We can't do that, since it's in the range of user types. 237 Resources.addType(102, "whoo") 238 239