forked from panda3d/panda3d
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_loader_types.py
More file actions
220 lines (161 loc) · 6.77 KB
/
test_loader_types.py
File metadata and controls
220 lines (161 loc) · 6.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
from panda3d.core import LoaderFileTypeRegistry, ModelRoot, Loader, LoaderOptions, Filename
import pytest
import tempfile
import os
from contextlib import contextmanager
@pytest.fixture
def test_filename():
"""Fixture returning a filename to an existent .test file."""
fp = tempfile.NamedTemporaryFile(suffix='.test', delete=False)
fp.write(b"test")
fp.close()
filename = Filename.from_os_specific(fp.name)
filename.make_true_case()
yield filename
os.unlink(fp.name)
@pytest.fixture
def test_pz_filename():
"""Fixture returning a filename to an existent .test.pz file."""
fp = tempfile.NamedTemporaryFile(suffix='.test.pz', delete=False)
fp.write(b"test")
fp.close()
filename = Filename.from_os_specific(fp.name)
filename.make_true_case()
yield filename
os.unlink(fp.name)
@contextmanager
def registered_type(type):
"""Convenience method allowing use of register_type in a with block."""
registry = LoaderFileTypeRegistry.get_global_ptr()
registry.register_type(type)
yield
registry.unregister_type(type)
class DummyLoader:
"""The simplest possible successful LoaderFileType."""
extensions = ["test"]
@staticmethod
def load_file(path, options, record=None):
return ModelRoot("loaded")
def test_loader_invalid():
"""Tests that registering a malformed loader fails."""
class MissingExtensionsLoader:
pass
class InvalidTypeExtensionsLoader:
extensions = "abc"
class EmptyExtensionsLoader:
extensions = []
class InvalidExtensionsLoader:
extensions = [123, None]
registry = LoaderFileTypeRegistry.get_global_ptr()
with pytest.raises(Exception):
registry.register_type("invalid")
with pytest.raises(Exception):
registry.register_type(MissingExtensionsLoader)
with pytest.raises(TypeError):
registry.register_type(InvalidTypeExtensionsLoader)
with pytest.raises(ValueError):
registry.register_type(EmptyExtensionsLoader)
with pytest.raises(TypeError):
registry.register_type(InvalidExtensionsLoader)
def test_loader_success(test_filename):
"""Tests that a normal dummy loader successfully loads."""
with registered_type(DummyLoader):
model = Loader.get_global_ptr().load_sync(test_filename, LoaderOptions(LoaderOptions.LF_no_cache))
assert model is not None
assert model.name == "loaded"
def test_loader_extensions(test_filename):
"""Tests multi-extension loaders."""
class MultiExtensionLoader:
extensions = ["test1", "teSt2"]
@staticmethod
def load_file(path, options, record=None):
return ModelRoot("loaded")
fp1 = tempfile.NamedTemporaryFile(suffix='.test1', delete=False)
fp1.write(b"test1")
fp1.close()
fn1 = Filename.from_os_specific(fp1.name)
fn1.make_true_case()
fp2 = tempfile.NamedTemporaryFile(suffix='.TEST2', delete=False)
fp2.write(b"test2")
fp2.close()
fn2 = Filename.from_os_specific(fp2.name)
fn2.make_true_case()
try:
with registered_type(MultiExtensionLoader):
model1 = Loader.get_global_ptr().load_sync(fn1, LoaderOptions(LoaderOptions.LF_no_cache))
assert model1 is not None
assert model1.name == "loaded"
model2 = Loader.get_global_ptr().load_sync(fn2, LoaderOptions(LoaderOptions.LF_no_cache))
assert model2 is not None
assert model2.name == "loaded"
finally:
os.unlink(fp1.name)
os.unlink(fp2.name)
# Ensure that both were unregistered.
registry = LoaderFileTypeRegistry.get_global_ptr()
assert not registry.get_type_from_extension("test1")
assert not registry.get_type_from_extension("test2")
def test_loader_nonexistent():
"""Verifies that non-existent files fail before calling load_file."""
flag = [False]
class AssertiveLoader:
extensions = ["test"]
@staticmethod
def load_file(path, options, record=None):
flag[0] = True
assert False, "should never get here"
with registered_type(AssertiveLoader):
model = Loader.get_global_ptr().load_sync("/non-existent", LoaderOptions(LoaderOptions.LF_no_cache))
assert model is None
assert not flag[0]
def test_loader_exception(test_filename):
"""Tests for a loader that raises an exception."""
class FailingLoader:
extensions = ["test"]
@staticmethod
def load_file(path, options, record=None):
raise Exception("test error")
with registered_type(FailingLoader):
model = Loader.get_global_ptr().load_sync(test_filename, LoaderOptions(LoaderOptions.LF_no_cache))
assert model is None
def test_loader_compressed(test_pz_filename):
"""Tests for loading .pz files and the supports_compressed flag."""
class TestLoader:
extensions = ["test"]
@staticmethod
def load_file(path, options, record=None):
return ModelRoot("loaded")
# Test with property absent
with registered_type(TestLoader):
model = Loader.get_global_ptr().load_sync(test_pz_filename, LoaderOptions(LoaderOptions.LF_no_cache))
assert model is None
# Test with property False, should give same result
TestLoader.supports_compressed = False
with registered_type(TestLoader):
model = Loader.get_global_ptr().load_sync(test_pz_filename, LoaderOptions(LoaderOptions.LF_no_cache))
assert model is None
# Test with property True, should work
TestLoader.supports_compressed = True
with registered_type(TestLoader):
model = Loader.get_global_ptr().load_sync(test_pz_filename, LoaderOptions(LoaderOptions.LF_no_cache))
assert model is not None
assert model.name == "loaded"
# Test with property invalid type, should not register
TestLoader.supports_compressed = None
with pytest.raises(TypeError):
LoaderFileTypeRegistry.get_global_ptr().register_type(TestLoader)
def test_loader_ram_cache(test_filename):
"""Tests that the Python loader plug-ins write to the RAM cache."""
# Ensure a clean slate.
from panda3d.core import ModelPool
ModelPool.release_all_models()
with registered_type(DummyLoader):
model1 = Loader.get_global_ptr().load_sync(test_filename, LoaderOptions(LoaderOptions.LF_no_disk_cache | LoaderOptions.LF_allow_instance))
assert model1 is not None
assert model1.name == "loaded"
assert ModelPool.has_model(test_filename)
assert ModelPool.get_model(test_filename, True) == model1
model2 = Loader.get_global_ptr().load_sync(test_filename, LoaderOptions(LoaderOptions.LF_cache_only | LoaderOptions.LF_allow_instance))
assert model2 is not None
assert model1 == model2
ModelPool.release_model(model2)