This allows us to encapsulate a lot of the error handling logic into a single place with easy to use methods. This should reduce the amount of code in consumers of PIGLIT_CONFIG.
It adds two new methods, safe_get and required_get, which operate on NoOptionError or NoSectionError. With safe_get, if either of these is raised None will be return, for required_get a PiglitFatalError will be raised. Signed-off-by: Dylan Baker <[email protected]> --- framework/core.py | 56 +++++++++++++++++++++++++++++++++++++++++-- framework/tests/core_tests.py | 53 +++++++++++++++++++++++++++++++++++----- 2 files changed, 101 insertions(+), 8 deletions(-) diff --git a/framework/core.py b/framework/core.py index 3ee2870..f9cdbfe 100644 --- a/framework/core.py +++ b/framework/core.py @@ -30,17 +30,69 @@ import subprocess import sys import ConfigParser +from framework import exceptions + __all__ = [ 'PIGLIT_CONFIG', 'PLATFORMS', + 'PiglitConfig', 'Options', 'collect_system_info', 'parse_listfile', ] - PLATFORMS = ["glx", "x11_egl", "wayland", "gbm", "mixed_glx_egl"] -PIGLIT_CONFIG = ConfigParser.SafeConfigParser(allow_no_value=True) + + +class PiglitConfig(ConfigParser.SafeConfigParser): + """Custom Config parser that provides a few extra helpers.""" + def __init__(self, *args, **kwargs): + # In Python2 the ConfigParser classes are old style, you can't use + # super() on them. sigh + ConfigParser.SafeConfigParser.__init__(self, *args, **kwargs) + self.filename = None + + def readfp(self, fp, filename=None): + # In Python2 the ConfigParser classes are old style, you can't use + # super() on them. sigh + ConfigParser.SafeConfigParser.readfp(self, fp, filename) + self.filename = os.path.abspath(filename or fp.name) + + def safe_get(self, *args, **kwargs): + """A version of self.get that doesn't raise NoSectionError or + NoOptionError. + + This is equivalent to passing if the option isn't found. It will return + None if an error is caught + + """ + try: + return self.get(*args, **kwargs) + except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): + return None + + def required_get(self, section, option, **kwargs): + """A version fo self.get that raises PiglitFatalError. + + If self.get returns NoSectionError or NoOptionError then this will + raise a PiglitFatalException, aborting the program. + + """ + try: + return self.get(section, option, **kwargs) + except ConfigParser.NoSectionError: + raise exceptions.PiglitFatalError( + 'No Section "{}" in file "{}".\n' + 'This section is required.'.format( + section, self.filename)) + except ConfigParser.NoOptionError: + raise exceptions.PiglitFatalError( + 'No option "{}" from section "{}" in file "{}".\n' + 'This option is required.'.format( + option, section, self.filename)) + + +PIGLIT_CONFIG = PiglitConfig(allow_no_value=True) def get_config(arg=None): diff --git a/framework/tests/core_tests.py b/framework/tests/core_tests.py index 108d5ee..3a605f7 100644 --- a/framework/tests/core_tests.py +++ b/framework/tests/core_tests.py @@ -24,13 +24,14 @@ from __future__ import print_function, absolute_import import os import collections import shutil -import ConfigParser import textwrap import nose.tools as nt +from framework import core, exceptions import framework.tests.utils as utils -import framework.core as core + +# pylint: disable=line-too-long,invalid-name _CONF_FILE = textwrap.dedent("""\ [nose-test] @@ -66,7 +67,7 @@ class GetConfigFixture(object): if os.path.exists('piglit.conf'): shutil.move('piglit.conf', 'piglit.conf.restore') self.restore = True - core.PIGLIT_CONFIG = ConfigParser.SafeConfigParser( + core.PIGLIT_CONFIG = core.PiglitConfig( allow_no_value=True) except Exception as e: raise utils.UtilsError(e) @@ -82,7 +83,7 @@ class GetConfigFixture(object): if self.restore: shutil.move('piglit.conf.restore', 'piglit.conf') - core.PIGLIT_CONFIG = ConfigParser.SafeConfigParser( + core.PIGLIT_CONFIG = core.PiglitConfig( allow_no_value=True) except Exception as e: raise utils.UtilsError(e) @@ -90,7 +91,7 @@ class GetConfigFixture(object): def _reset_piglit_config(): """ Set core.PIGLIT_CONFIG back to pristine """ - core.PIGLIT_CONFIG = ConfigParser.SafeConfigParser() + core.PIGLIT_CONFIG = core.PiglitConfig(allow_no_value=True) def check_initialize(target): @@ -113,7 +114,7 @@ def test_generate_initialize(): """ yieldable = check_initialize - for target in [core.Options]: + for target in [core.Options, core.PiglitConfig]: yieldable.description = "Test that {} initializes".format( target.__name__) yield yieldable, target @@ -237,3 +238,43 @@ def test_piglit_root(): nt.ok_(core.PIGLIT_CONFIG.has_section('nose-test'), msg='$PIGLIT_ROOT not found') + + +class TestPiglitConfig(object): + """Tests for PiglitConfig methods.""" + @classmethod + def setup_class(cls): + cls.conf = core.PiglitConfig() + cls.conf.add_section('set') + cls.conf.set('set', 'options', 'bool') + + def test_safe_get_valid(self): + """core.PiglitConfig: safe_get returns a value if its in the Config""" + nt.assert_equal(self.conf.safe_get('set', 'options'), 'bool') + + def test_PiglitConfig_required_get_valid(self): + """core.PiglitConfig: required_get returns a value if its in the Config + """ + nt.assert_equal(self.conf.required_get('set', 'options'), 'bool') + + def test_safe_get_missing_option(self): + """core.PiglitConfig: safe_get returns None if the option is missing + """ + nt.assert_equal(self.conf.safe_get('set', 'invalid'), None) + + def test_safe_get_missing_section(self): + """core.PiglitConfig: safe_get returns None if the section is missing + """ + nt.assert_equal(self.conf.safe_get('invalid', 'invalid'), None) + + @nt.raises(exceptions.PiglitFatalError) + def test_required_get_missing_option(self): + """core.PiglitConfig: required_get raises PiglitFatalError if the option is missing + """ + self.conf.required_get('set', 'invalid') + + @nt.raises(exceptions.PiglitFatalError) + def test_required_get_missing_section(self): + """core.PiglitConfig: required_get raises PiglitFatalError if the section is missing + """ + self.conf.required_get('invalid', 'invalid') -- 2.3.5 _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
