[Piglit] [Patch v2 1/4] framework: allow loading a piglit.conf from more locations
Dylan Baker
baker.dylan.c at gmail.com
Mon Jul 7 16:20:35 PDT 2014
With this patch piglit.conf can live in a number of different places. It
can live in the current directory, then in XDG_CONFIG_HOME
($HOME/.config by default), and finally in the piglit source directory.
v2: - fix types (chadv)
- change load order to make ./.piglit.conf load first (chadv)
- Add framework tests
Signed-off-by: Dylan Baker <baker.dylan.c at gmail.com>
---
framework/programs/run.py | 39 +++++++--
framework/tests/programs_tests.py | 180 ++++++++++++++++++++++++++++++++++++++
2 files changed, 212 insertions(+), 7 deletions(-)
create mode 100644 framework/tests/programs_tests.py
diff --git a/framework/programs/run.py b/framework/programs/run.py
index c1a2658..8b8aa5a 100644
--- a/framework/programs/run.py
+++ b/framework/programs/run.py
@@ -123,13 +123,7 @@ def run(input_):
args.concurrency = "none"
# Read the config file
- if args.config_file:
- core.PIGLIT_CONFIG.readfp(args.config_file)
- args.config_file.close()
- else:
- core.PIGLIT_CONFIG.read(os.path.abspath(
- os.path.join(
- os.path.dirname(__file__), '..', '..', 'piglit.conf')))
+ _get_config(args.config_file)
# Pass arguments into Options
opts = core.Options(concurrent=args.concurrency,
@@ -203,6 +197,11 @@ def resume(input_):
type=path.realpath,
metavar="<Results Path>",
help="Path to results folder")
+ parser.add_argument("-f", "--config",
+ dest="config_file",
+ type=argparse.FileType("r"),
+ help="Optionally specify a piglit config file to use. "
+ "Default is piglit.conf")
args = parser.parse_args(input_)
results = framework.results.load_results(args.results_path)
@@ -214,6 +213,8 @@ def resume(input_):
dmesg=results.options['dmesg'],
verbose=results.options['verbose'])
+ _get_config(args.config_file)
+
if results.options.get('platform'):
opts.env['PIGLIT_PLATFORM'] = results.options['platform']
@@ -242,3 +243,27 @@ def resume(input_):
print("Thank you for running Piglit!\n"
"Results have ben wrriten to {0}".format(results_path))
+
+
+def _get_config(arg):
+ if arg:
+ core.PIGLIT_CONFIG.readfp(arg)
+ else:
+ # Try XDG_CONFIG_DIR, then try the local directory, finally try the
+ # root of the piglit dir relative to this file
+ for d in ['.',
+ os.environ.get('XDG_CONFIG_HOME',
+ os.path.expandvars('$HOME/.config')),
+ os.path.join(os.path.dirname(__file__), '..', '..')]:
+ try:
+ with open(os.path.join(d, 'piglit.conf'), 'r') as f:
+ core.PIGLIT_CONFIG.readfp(f)
+ break
+ except IOError:
+ pass
+ else:
+ if __debug__:
+ print('Warning: piglit.conf not found!\n'
+ '(searching current dir, $HOME/.config, '
+ '$XDG_CONFIG_HOME, and piglit source dir)',
+ file=sys.stderr)
diff --git a/framework/tests/programs_tests.py b/framework/tests/programs_tests.py
new file mode 100644
index 0000000..c563ef0
--- /dev/null
+++ b/framework/tests/programs_tests.py
@@ -0,0 +1,180 @@
+# Copyright (c) 2014 Intel Corporation
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+""" Tests for the programs package
+
+Currently there aren't very many tests for the modules in this package, so just
+having a single test module seems appropriate
+
+"""
+
+import os
+import shutil
+import ConfigParser
+import framework.core as core
+import framework.programs.run as run
+import framework.tests.utils as utils
+import nose.tools as nt
+
+CONF_FILE = """
+[nose-test]
+; a section for testing behavior
+dir = foo
+"""
+
+
+# Helpers
+class _TestWithEnvClean(object):
+ """ Class that does cleanup with saved state
+
+ This could be done with test fixtures, but this should be cleaner in the
+ specific case of cleaning up environment variables
+
+ Nose will run a method (bound or unbound) at the start of the test called
+ setup() and one at the end called teardown(), we have added a teardown
+ method.
+
+ Using this gives us the assurance that we're not relying on settings from
+ other tests, making ours pass or fail, and that os.enviorn is the same
+ going in as it is going out.
+
+ This is modeled after Go's defer keyword.
+
+ """
+ def __init__(self):
+ self._saved = set()
+ self._teardown_calls = []
+
+ def add_teardown(self, var, restore=True):
+ """ Add os.environ values to remove in teardown """
+ if var in os.environ:
+ self._saved.add((var, os.environ.get(var), restore))
+ del os.environ[var]
+
+ def defer(self, func, *args):
+ """ Add a function (with arguments) to be run durring cleanup """
+ self._teardown_calls.append((func, args))
+
+ def teardown(self):
+ """ Teardown the test
+
+ Restore any variables that were unset at the begining of the test, and
+ run any differed methods.
+
+ """
+ for key, value, restore in self._saved:
+ # If value is None the value was unset previously, put it back
+ if value is None:
+ del os.environ[key]
+ elif restore:
+ os.environ[key] = value
+
+ # Teardown calls is a FIFO stack, the defered calls must be run in
+ # reversed order to make any sense
+ for call, args in reversed(self._teardown_calls):
+ call(*args)
+
+
+# Tests
+class TestGetConfigEnv(_TestWithEnvClean):
+ def test(self):
+ """ _get_config() finds $XDG_CONFIG_HOME/piglit.conf """
+ self.defer(lambda: core.PIGLIT_CONFIG == ConfigParser.SafeConfigParser)
+ self.add_teardown('XDG_CONFIG_HOME')
+ if os.path.exists('piglit.conf'):
+ shutil.move('piglit.conf', 'piglit.conf.restore')
+ self.defer(shutil.move, 'piglit.conf.restore', 'piglit.conf')
+
+ with utils.tempdir() as tdir:
+ os.environ['XDG_CONFIG_HOME'] = tdir
+ with open(os.path.join(tdir, 'piglit.conf'), 'w') as f:
+ f.write(CONF_FILE)
+ run._get_config(None)
+
+ nt.ok_(core.PIGLIT_CONFIG.has_section('nose-test'),
+ msg='$XDG_CONFIG_HOME not found')
+
+
+class TestGetConfigHomeFallback(_TestWithEnvClean):
+ def test(self):
+ """ _get_config() finds $HOME/.config/piglit.conf """
+ self.defer(lambda: core.PIGLIT_CONFIG == ConfigParser.SafeConfigParser)
+ self.add_teardown('HOME')
+ self.add_teardown('XDG_CONFIG_HOME')
+ if os.path.exists('piglit.conf'):
+ shutil.move('piglit.conf', 'piglit.conf.restore')
+ self.defer(shutil.move, 'piglit.conf.restore', 'piglit.conf')
+
+ with utils.tempdir() as tdir:
+ os.environ['HOME'] = tdir
+ os.mkdir(os.path.join(tdir, '.config'))
+ with open(os.path.join(tdir, '.config/piglit.conf'), 'w') as f:
+ f.write(CONF_FILE)
+
+ nt.ok_(core.PIGLIT_CONFIG.has_section('nose-test'),
+ msg='$HOME/.config not found')
+
+
+class TestGetConfigLocal(_TestWithEnvClean):
+ # These need to be empty to force '.' to be used
+ def test(self):
+ """ _get_config() finds ./piglit.conf """
+ self.defer(lambda: core.PIGLIT_CONFIG == ConfigParser.SafeConfigParser)
+ self.add_teardown('HOME')
+ self.add_teardown('XDG_CONFIG_HOME')
+ if os.path.exists('piglit.conf'):
+ shutil.move('piglit.conf', 'piglit.conf.restore')
+ self.defer(shutil.move, 'piglit.conf.restore', 'piglit.conf')
+
+ with utils.tempdir() as tdir:
+ self.defer(os.chdir, os.getcwd())
+ os.chdir(tdir)
+
+ with open(os.path.join(tdir, 'piglit.conf'), 'w') as f:
+ f.write(CONF_FILE)
+
+ run._get_config(None)
+
+ nt.ok_(core.PIGLIT_CONFIG.has_section('nose-test'),
+ msg='./piglit.conf not found')
+
+
+class TestGetConfigRoot(_TestWithEnvClean):
+ def test(self):
+ """ _get_config() finds "piglit root"/piglit.conf """
+ self.defer(lambda: core.PIGLIT_CONFIG == ConfigParser.SafeConfigParser)
+ self.add_teardown('HOME')
+ self.add_teardown('XDG_CONFIG_HOME')
+
+ if os.path.exists('piglit.conf'):
+ shutil.move('piglit.conf', 'piglit.conf.restore')
+ self.defer(shutil.move, 'piglit.conf.restore', 'piglit.conf')
+
+ with open('piglit.conf', 'w') as f:
+ f.write(CONF_FILE)
+ self.defer(os.unlink, 'piglit.conf')
+ self.defer(os.chdir, os.getcwd())
+ os.chdir('..')
+
+ run._get_config(None)
+
+ nt.ok_(core.PIGLIT_CONFIG.has_section('nose-test'),
+ msg='$PIGLIT_ROOT not found')
--
2.0.0
More information about the Piglit
mailing list