framework/replay: Update simpler integrity unit tests
[piglit.git] / unittests / framework / test / test_glsl_parser_test.py
blob4aa72dd63ea3e01d5af3e46356684d374ed420bb
1 # coding=utf-8
2 # Copyright (c) 2014-2016, 2019 Intel Corporation
4 # Permission is hereby granted, free of charge, to any person obtaining a copy
5 # of this software and associated documentation files (the "Software"), to deal
6 # in the Software without restriction, including without limitation the rights
7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 # copies of the Software, and to permit persons to whom the Software is
9 # furnished to do so, subject to the following conditions:
11 # The above copyright notice and this permission notice shall be included in
12 # all copies or substantial portions of the Software.
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 # SOFTWARE.
22 """Tests for framework.test.glsl_parser_test."""
24 import itertools
25 import os
26 import textwrap
27 from unittest import mock
29 import pytest
31 from framework import exceptions
32 from framework.test import glsl_parser_test as glsl
33 from framework.test.piglit_test import TEST_BIN_DIR as _TEST_BIN_DIR
34 from framework.test.base import TestIsSkip as _TestIsSkip
36 # pylint: disable=invalid-name
39 class _Setup(object):
40 """A class holding setup and teardown methods.
42 These methods need to share data, and a class is a nice way to encapsulate
43 that.
45 """
46 def __init__(self):
47 self.patchers = [
48 mock.patch('framework.test.glsl_parser_test._HAS_GL_BIN', True),
49 mock.patch('framework.test.glsl_parser_test._HAS_GLES_BIN', True),
50 mock.patch.dict('framework.wflinfo.OPTIONS.env',
51 {'PIGLIT_PLATFORM': 'foo'}),
54 def setup(self, _):
55 for p in self.patchers:
56 p.start()
58 def teardown(self, _):
59 for p in self.patchers:
60 p.stop()
63 _setup = _Setup()
64 setup_module = _setup.setup
65 teardown_module = _setup.teardown
68 def test_no_config_start(tmpdir):
69 """test.glsl_parser_test.GLSLParserTest: exception is raised if [config]
70 section is missing."""
71 p = tmpdir.join('test.frag')
72 p.write(textwrap.dedent("""
73 // expect_result: pass
74 // glsl_version: 1.10
75 // [end config]"""))
77 with pytest.raises(glsl.GLSLParserNoConfigError):
78 glsl.GLSLParserTest.new(str(p))
81 def test_find_config_start(tmpdir):
82 """test.glsl_parser_test.GLSLParserTest: successfully finds [config]
83 section."""
84 p = tmpdir.join('test.frag')
85 p.write(textwrap.dedent("""
86 // [config]
87 // expect_result: pass
88 // glsl_version: 1.10"""))
90 with pytest.raises(exceptions.PiglitFatalError):
91 glsl.GLSLParserTest.new(str(p))
94 def test_no_config_end(tmpdir):
95 """test.glsl_parser_test.GLSLParserTest: exception is raised if [end
96 config] section is missing."""
97 p = tmpdir.join('test.frag')
98 p.write('// [config]')
100 with pytest.raises(exceptions.PiglitFatalError):
101 glsl.GLSLParserTest.new(str(p))
104 def test_no_expect_result(tmpdir):
105 """test.glsl_parser_test.GLSLParserTest: exception is raised if
106 "expect_result" key is missing."""
107 p = tmpdir.join('test.frag')
108 p.write(textwrap.dedent("""\
109 // [config]
110 // glsl_version: 1.10
111 // [end config]"""))
113 with pytest.raises(exceptions.PiglitFatalError):
114 glsl.GLSLParserTest.new(str(p))
117 def test_no_glsl_version(tmpdir):
118 """test.glsl_parser_test.GLSLParserTest: exception is raised if
119 "glsl_version" key is missing."""
120 p = tmpdir.join('test.frag')
121 p.write(textwrap.dedent("""\
122 // [config]
123 // expect_result: pass
124 // [end config]"""))
126 with pytest.raises(exceptions.PiglitFatalError):
127 glsl.GLSLParserTest.new(str(p))
130 def test_cpp_comments(tmpdir):
131 """test.glsl_parser_test.GLSLParserTest: parses C++ style comments ('//').
133 p = tmpdir.join('test.frag')
134 p.write(textwrap.dedent("""\
135 // [config]
136 // expect_result: pass
137 // glsl_version: 1.10
138 // [end config]"""))
139 test = glsl.GLSLParserTest.new(str(p))
141 assert test.command == [os.path.join(_TEST_BIN_DIR, 'glslparsertest'),
142 str(p), 'pass', '1.10']
145 def test_c_comments(tmpdir):
146 """test.glsl_parser_test.GLSLParserTest: parses C++ style comments ('/* */')
148 p = tmpdir.join('test.frag')
149 p.write(textwrap.dedent("""\
150 /* [config]
151 * expect_result: pass
152 * glsl_version: 1.10
153 * [end config]
154 */"""))
156 test = glsl.GLSLParserTest.new(str(p))
158 assert test.command == [os.path.join(_TEST_BIN_DIR, 'glslparsertest'),
159 str(p), 'pass', '1.10']
162 def test_blank_in_config_cpp(tmpdir):
163 """test.glsl_parser_test.GLSLParserTest: C++ style comments can have
164 uncommented newlines."""
165 p = tmpdir.join('test.frag')
166 p.write(textwrap.dedent("""\
167 // [config]
169 // expect_result: pass
170 // glsl_version: 1.10
171 // [end config]"""))
172 test = glsl.GLSLParserTest.new(str(p))
174 assert test.command == [os.path.join(_TEST_BIN_DIR, 'glslparsertest'),
175 str(p), 'pass', '1.10']
178 def test_empty_in_config_cpp(tmpdir):
179 """test.glsl_parser_test.GLSLParserTest: C++ style comments can have blank
180 commented lines."""
181 p = tmpdir.join('test.frag')
182 p.write(textwrap.dedent("""\
183 // [config]
185 // expect_result: pass
186 // glsl_version: 1.10
187 // [end config]"""))
188 test = glsl.GLSLParserTest.new(str(p))
190 assert test.command == [os.path.join(_TEST_BIN_DIR, 'glslparsertest'),
191 str(p), 'pass', '1.10']
194 def test_blank_in_config_c(tmpdir):
195 """test.glsl_parser_test.GLSLParserTest: C style comments can have
196 uncommented newlines."""
197 p = tmpdir.join('test.frag')
198 p.write(textwrap.dedent("""\
199 /* [config]
201 * expect_result: pass
202 * glsl_version: 1.10
203 * [end config]
204 */"""))
205 test = glsl.GLSLParserTest.new(str(p))
207 assert test.command == [os.path.join(_TEST_BIN_DIR, 'glslparsertest'),
208 str(p), 'pass', '1.10']
211 def test_empty_in_config_c(tmpdir):
212 """test.glsl_parser_test.GLSLParserTest: C style comments can have blank
213 commented lines."""
214 p = tmpdir.join('test.frag')
215 p.write(textwrap.dedent("""\
216 /* [config]
218 * expect_result: pass
219 * glsl_version: 1.10
220 * [end config]
221 */"""))
222 test = glsl.GLSLParserTest.new(str(p))
224 assert test.command == [os.path.join(_TEST_BIN_DIR, 'glslparsertest'),
225 str(p), 'pass', '1.10']
228 @pytest.mark.parametrize(
229 "config,expected",
230 # pylint: disable=line-too-long
231 [('// [config]\n// expect_result: pass\n// glsl_version: 1.10\n// [end config]\n',
232 [os.path.join(_TEST_BIN_DIR, 'glslparsertest'), 'pass', '1.10']),
233 ('// [config]\n// expect_result: pass\n// glsl_version: 1.10\n//check_link: true\n// [end config]\n',
234 [os.path.join(_TEST_BIN_DIR, 'glslparsertest'), 'pass', '1.10', '--check-link']),
235 ('// [config]\n// expect_result: pass\n// glsl_version: 1.10\n//check_link: false\n// [end config]\n',
236 [os.path.join(_TEST_BIN_DIR, 'glslparsertest'), 'pass', '1.10']),
237 ('// [config]\n// expect_result: pass\n// glsl_version: 1.10\n//require_extensions: ARB_foo\n// [end config]\n',
238 [os.path.join(_TEST_BIN_DIR, 'glslparsertest'), 'pass', '1.10', 'ARB_foo']),
239 ('// [config]\n// expect_result: pass\n// glsl_version: 1.10\n//require_extensions: ARB_foo ARB_bar\n// [end config]\n',
240 [os.path.join(_TEST_BIN_DIR, 'glslparsertest'), 'pass', '1.10', 'ARB_foo', 'ARB_bar'])],
241 # pylint: enable=line-too-long
242 ids=['all required options', 'check_link true', 'check_link false',
243 'one required_extension', 'multiple required_exetension'])
244 def test_config_to_command(config, expected, tmpdir):
245 """Test that config blocks are converted into the expected commands."""
246 p = tmpdir.join('test.frag')
247 p.write(config)
248 test = glsl.GLSLParserTest.new(str(p))
249 # add the filename, which isn't known util now
250 expected.insert(1, str(p))
252 assert test.command == expected
255 def test_bad_section_name(tmpdir):
256 """test.glsl_parser_test.GLSLParserTest: Unknown config keys cause an
257 error."""
258 p = tmpdir.join('test.frag')
259 p.write(textwrap.dedent("""\
260 // [config]
261 // expect_result: pass
262 // glsl_version: 1.10
263 // new_awesome_key: foo
264 // [end config]"""))
266 with pytest.raises(exceptions.PiglitFatalError):
267 glsl.GLSLParserTest.new(str(p))
270 @pytest.mark.parametrize(
271 "extra",
272 ['expect_result: pass', 'glsl_version: 1.10',
273 'require_extensions: ARB_ham_sandwhich', 'check_link: false'],
274 ids=['expect_result', 'glsl_version', 'require_extensions', 'check_link'])
275 def test_duplicate_entry(extra, tmpdir):
276 """Test that duplicate entries are an error."""
277 p = tmpdir.join('test.vert')
278 p.write(textwrap.dedent("""\
279 // [config]
280 // expect_result: pass
281 // glsl_version: 1.10
282 // require_extensions: ARB_foobar
283 // check_link: True
284 // {}
285 // [end config]""".format(extra)))
287 with pytest.raises(exceptions.PiglitFatalError):
288 glsl.GLSLParserTest.new(str(p))
291 @pytest.mark.parametrize(
292 "separator",
293 ['ARB_ham, ARB_turkey', 'ARB_pork; ARB_chicken', 'ARB_foo;'],
294 ids=['comma separated', 'semicolon separated', 'trailing semicolon'])
295 def test_invalid_extensions_separator(separator, tmpdir):
296 """Test that invalid extension separators are rejected."""
297 p = tmpdir.join('test.vert')
298 p.write(textwrap.dedent("""\
299 // [config]
300 // expect_result: pass
301 // glsl_version: 1.10
302 // require_extensions: ARB_foobar
303 // check_link: True
304 // require_extensions: {}
305 // [end config]""".format(separator)))
307 with pytest.raises(exceptions.PiglitFatalError):
308 glsl.GLSLParserTest.new(str(p))
311 @pytest.mark.parametrize(
312 "ext",
313 ['GL_EXT_foo', '!GL_EXT_foo', 'GL_EXT_foo GL_ARB_foo',
314 '!GL_EXT_foo !GL_ARB_foo', '!GL_EXT_foo GL_ARB_foo'],
315 ids=['single require', 'single exclude', 'multiple require',
316 'multiple exclude', 'mixed require and exclude'])
317 def test_valid_extensions(ext, tmpdir):
318 """Test that invalid extension separators are rejected."""
319 p = tmpdir.join('test.vert')
320 p.write(textwrap.dedent("""\
321 // [config]
322 // expect_result: pass
323 // glsl_version: 1.10
324 // require_extensions: {}
325 // [end config]""".format(ext)))
327 expected = ext.split(' ')
328 test = glsl.GLSLParserTest.new(str(p))
330 assert test.command[-len(expected):] == expected
333 @pytest.mark.parametrize(
334 "version,forced",
335 itertools.product(
336 ['1.00', '3.00', '3.10', '3.20', '3.00 es', '3.10 es', '3.20 es'],
337 [True, False]))
338 def test_get_glslparsertest_gles2(version, forced, tmpdir, mocker):
339 """Tests for assigning the correct binary for GLES tests.
341 Tests with and without the gles binary and with and without the force
342 desktop mode.
344 if forced:
345 expected = 'glslparsertest'
346 else:
347 expected = 'glslparsertest_gles2'
349 mocker.patch('framework.test.glsl_parser_test._FORCE_DESKTOP_VERSION',
350 forced)
352 p = tmpdir.join('test.frag')
353 p.write(textwrap.dedent("""\
354 /* [config]
355 * expect_result: pass
356 * glsl_version: {}
357 * [end config]
358 */""".format(version)))
359 inst = glsl.GLSLParserTest.new(str(p))
361 assert os.path.basename(inst.command[0]) == expected
364 class TestGLSLParserTestSkipRequirements(object):
365 """Tests for setting FastSkip parameters."""
366 @staticmethod
367 def write_config(filename, version='4.3', extra=''):
368 filename.write(textwrap.dedent("""\
369 // [config]
370 // expect_result: pass
371 // glsl_version: {}
372 // {}
373 // [end config]""".format(version, extra)))
375 class TestShaderVersions:
377 @staticmethod
378 def write_config(filename, version='4.3', extra=''):
379 filename.write(textwrap.dedent("""\
380 // [config]
381 // expect_result: pass
382 // glsl_version: {}
383 // {}
384 // [end config]""".format(version, extra)))
386 def test_glsl(self, tmpdir):
387 p = tmpdir.join('test.frag')
388 self.write_config(p)
389 assert glsl.GLSLParserTest.new(str(p)).require_shader == 4.3
391 def test_glsl_es(self, tmpdir):
392 p = tmpdir.join('test.frag')
393 self.write_config(p, version='3.0')
394 assert glsl.GLSLParserTest.new(str(p)).require_shader == 3.0
397 @pytest.mark.parametrize(
398 "value,expected",
399 [('3.0', 'gles3'), ('1.0', 'gles2'), ('4.3', 'core'),
400 ('4.3 compatibility', 'compat')])
401 def test_apis(self, tmpdir, value, expected):
402 p = tmpdir.join('test.frag')
403 self.write_config(p, version=value)
404 assert glsl.GLSLParserTest.new(str(p)).require_api == expected
406 def test_require_extensions(self, tmpdir):
407 p = tmpdir.join('test.frag')
408 self.write_config(p, extra="require_extensions: GL_ARB_foo GL_ARB_bar")
409 assert glsl.GLSLParserTest.new(str(p)).require_extensions == \
410 {'GL_ARB_foo', 'GL_ARB_bar'}
412 def test_exclude_not_added_to_require_extensions(self, tmpdir):
413 p = tmpdir.join('test.frag')
414 self.write_config(p, extra="require_extensions: GL_ARB_foo !GL_ARB_bar")
415 assert glsl.GLSLParserTest.new(str(p)).require_extensions == \
416 {'GL_ARB_foo'}
419 def test_skip_desktop_without_binary(tmpdir, mocker):
420 """There is no way to run desktop tests with only GLES compiled make sure
421 we don't try.
423 mocker.patch('framework.test.glsl_parser_test._HAS_GL_BIN', False)
425 p = tmpdir.join('test.frag')
426 p.write(textwrap.dedent("""\
427 /* [config]
428 * expect_result: pass
429 * glsl_version: 1.10
430 * [end config]
431 */"""))
432 test = glsl.GLSLParserTest.new(str(p))
434 with pytest.raises(_TestIsSkip):
435 test.is_skip()
438 @pytest.mark.parametrize("version,extension", [
439 ('1.00', 'ARB_ES2_compatibility'),
440 ('3.00', 'ARB_ES3_compatibility'),
441 ('3.10', 'ARB_ES3_1_compatibility'),
442 ('3.20', 'ARB_ES3_2_compatibility'),
444 def test_add_compatibility_requirement_fastskip(version, extension, tmpdir,
445 mocker):
446 """When running GLES tests using the GL binary ensure that the proper
447 ARB_ES<ver> compatibility extension is added to the requirements.
449 This test checks the fast skipping variable
451 mocker.patch('framework.test.glsl_parser_test._FORCE_DESKTOP_VERSION', True)
453 p = tmpdir.join('test.frag')
454 p.write(textwrap.dedent("""\
455 /* [config]
456 * expect_result: pass
457 * glsl_version: {}
458 * require_extensions: GL_ARB_ham_sandwhich
459 * [end config]
460 */""".format(version)))
461 test = glsl.GLSLParserTest.new(str(p))
463 # The arb_compat extension was added to the fast skipping arguments
464 assert extension in test.require_extensions
468 @pytest.mark.parametrize("version,extension", [
469 ('1.00', 'ARB_ES2_compatibility'),
470 ('3.00', 'ARB_ES3_compatibility'),
471 ('3.10', 'ARB_ES3_1_compatibility'),
472 ('3.20', 'ARB_ES3_2_compatibility'),
474 def test_add_compatibility_requirement_binary(version, extension, tmpdir,
475 mocker):
476 """When running GLES tests using the GL binary ensure that the proper
477 ARB_ES<ver> compatibility extension is added to the requirements.
479 This test checks the glslparsertest binary command line.
481 mocker.patch('framework.test.glsl_parser_test._FORCE_DESKTOP_VERSION', True)
483 p = tmpdir.join('test.frag')
484 p.write(textwrap.dedent("""\
485 /* [config]
486 * expect_result: pass
487 * glsl_version: {}
488 * require_extensions: GL_ARB_ham_sandwhich
489 * [end config]
490 */""".format(version)))
491 test = glsl.GLSLParserTest.new(str(p))
493 # The compat extension was added to the slow skipping (C level)
494 # requirements
495 assert extension in test.command