Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
164 lines (132 sloc) 5.78 KB
from nose.plugins.base import Plugin
from nose.util import tolist
import os
try:
import ConfigParser
except ImportError:
import configparser as ConfigParser
import logging
import codecs
log = logging.getLogger(__name__)
warning = "Cannot access the test config because the plugin has not \
been activated. Did you specify --tc or any other command line option?"
config = {}
def load_yaml(yaml_file, encoding):
""" Load the passed in yaml configuration file """
try:
import yaml
except (ImportError):
raise Exception('unable to import YAML package. Can not continue.')
global config
config = yaml.load(codecs.open(yaml_file, 'r', encoding).read())
def load_ini(ini_file, encoding):
""" Parse and collapse a ConfigParser-Style ini file into a nested,
eval'ing the individual values, as they are assumed to be valid
python statement formatted """
global config
tmpconfig = ConfigParser.ConfigParser()
with codecs.open(ini_file, 'r', encoding) as f:
tmpconfig.readfp(f)
config = {}
for section in tmpconfig.sections():
config[section] = {}
for option in tmpconfig.options(section):
config[section][option] = tmpconfig.get(section, option)
def load_python(py_file, encoding):
""" This will exec the defined python file into the config variable -
the implicit assumption is that the python is safe, well formed and will
not do anything bad. This is also dangerous. """
exec(codecs.open(py_file, 'r', encoding).read())
def load_json(json_file, encoding):
""" This will use the json module to to read in the config json file.
"""
import json
global config
with codecs.open(json_file, 'r', encoding=encoding) as handle:
config = json.load(handle)
class TestConfig(Plugin):
enabled = False
name = "test_config"
score = 1
env_opt = "NOSE_TEST_CONFIG_FILE"
format = "ini"
encoding = 'utf-8'
valid_loaders = { 'yaml' : load_yaml, 'ini' : load_ini,
'python' : load_python, 'json': load_json }
def options(self, parser, env=os.environ):
""" Define the command line options for the plugin. """
parser.add_option(
"--tc-file", action="store",
default=env.get(self.env_opt),
dest="testconfig",
help="Configuration file to parse and pass to tests"
" [NOSE_TEST_CONFIG_FILE]")
parser.add_option(
"--tc-file-encoding", action="store",
default=env.get('NOSE_TEST_CONFIG_FILE_ENCODING') or self.encoding,
dest="testconfigencoding",
help="Test config file encoding, default is utf-8"
" [NOSE_TEST_CONFIG_FILE_ENCODING]")
parser.add_option(
"--tc-format", action="store",
default=env.get('NOSE_TEST_CONFIG_FILE_FORMAT') or self.format,
dest="testconfigformat",
help="Test config file format, default is configparser ini format"
" [NOSE_TEST_CONFIG_FILE_FORMAT]")
parser.add_option(
"--tc", action="append",
dest="overrides",
default = [],
help="Option:Value specific overrides.")
parser.add_option(
"--tc-exact", action="store_true",
dest="exact",
default = False,
help="Optional: Do not explode periods in override keys to "
"individual keys within the config dict, instead treat them"
" as config[my.toplevel.key] ala sqlalchemy.url in pylons")
def configure(self, options, noseconfig):
""" Call the super and then validate and call the relevant parser for
the configuration file passed in """
if not options.testconfig and not options.overrides:
return
Plugin.configure(self, options, noseconfig)
self.config = noseconfig
if not options.capture:
self.enabled = False
if options.testconfigformat:
self.format = options.testconfigformat
if self.format not in self.valid_loaders.keys():
raise Exception('%s is not a valid configuration file format' \
% self.format)
# Load the configuration file:
if options.testconfig:
self.valid_loaders[self.format](options.testconfig,
options.testconfigencoding)
overrides = tolist(options.overrides) or []
for override in overrides:
keys, val = override.split(":", 1)
if options.exact:
config[keys] = val
else:
# Create all *parent* keys that may not exist in the config
section = config
keys = keys.split('.')
for key in keys[:-1]:
if key not in section:
section[key] = {}
section = section[key]
# Finally assign the value to the last key
key = keys[-1]
section[key] = val
# Use an environment hack to allow people to set a config file to auto-load
# in case they want to put tests they write through pychecker or any other
# syntax thing which does an execute on the file.
if 'NOSE_TESTCONFIG_AUTOLOAD_YAML' in os.environ:
load_yaml(os.environ['NOSE_TESTCONFIG_AUTOLOAD_YAML'], encoding='utf-8')
if 'NOSE_TESTCONFIG_AUTOLOAD_INI' in os.environ:
load_ini(os.environ['NOSE_TESTCONFIG_AUTOLOAD_INI'], encoding='utf-8')
if 'NOSE_TESTCONFIG_AUTOLOAD_PYTHON' in os.environ:
load_python(os.environ['NOSE_TESTCONFIG_AUTOLOAD_PYTHON'], encoding='utf-8')
if 'NOSE_TESTCONFIG_AUTOLOAD_JSON' in os.environ:
load_json(os.environ['NOSE_TESTCONFIG_AUTOLOAD_JSON'], encoding='utf-8')