Commit b5aad70f authored by Dylan Baker's avatar Dylan Baker

framework: allow loading a piglit.conf from more locations

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
v3: - fix external integration tests
    - fix comment about loading order
Reviewed-by: default avatarChad Versace <chad.versace@linux.intel.com>
Signed-off-by: Dylan Baker's avatarDylan Baker <baker.dylan.c@gmail.com>
parent 972b638d
......@@ -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,28 @@ 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:
# Load the piglit.conf. First try looking in the current directory,
# then trying the XDG_CONFIG_HOME, then $HOME/.config/, finally try the
# piglit root dir
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)
......@@ -27,15 +27,20 @@ errors and to ensure that the API hasn't changed without fixing these modules
"""
import importlib
import ConfigParser
from nose.plugins.skip import SkipTest
from framework.programs.run import _get_config
_get_config(None)
def _import(name):
""" Helper for importing modules """
try:
return importlib.import_module(name)
except SystemExit:
raise SkipTest('Missing symlink, unable to test')
except (ConfigParser.NoOptionError, SystemExit):
raise SkipTest('No config section for {}'.format(name))
def test_xts_import():
......
# 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')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment