]> git.apps.os.sepia.ceph.com Git - ceph-ansible.git/commitdiff
tests: create the conftest file that does all the magic
authorAlfredo Deza <adeza@redhat.com>
Thu, 27 Oct 2016 19:39:12 +0000 (15:39 -0400)
committerAlfredo Deza <adeza@redhat.com>
Fri, 4 Nov 2016 17:59:33 +0000 (13:59 -0400)
Signed-off-by: Alfredo Deza <adeza@redhat.com>
Resolves: pytest#harness

tests/conftest.py [new file with mode: 0644]

diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644 (file)
index 0000000..0c05405
--- /dev/null
@@ -0,0 +1,101 @@
+import os
+
+import pytest
+import imp
+
+
+def pytest_addoption(parser):
+    default = 'scenario.py'
+    parser.addoption(
+        "--scenario",
+        action="store",
+        default=default,
+        help="YAML file defining scenarios to test. Currently defaults to: %s" % default
+    )
+
+
+def load_scenario_config(filepath, **kw):
+    '''
+    Creates a configuration dictionary from a file.
+
+    :param filepath: The path to the file.
+    '''
+
+    abspath = os.path.abspath(os.path.expanduser(filepath))
+    conf_dict = {}
+    if not os.path.isfile(abspath):
+        raise RuntimeError('`%s` is not a file.' % abspath)
+
+    # First, make sure the code will actually compile (and has no SyntaxErrors)
+    with open(abspath, 'rb') as f:
+        compiled = compile(f.read(), abspath, 'exec')
+
+    # Next, attempt to actually import the file as a module.
+    # This provides more verbose import-related error reporting than exec()
+    absname, _ = os.path.splitext(abspath)
+    basepath, module_name = absname.rsplit(os.sep, 1)
+    imp.load_module(
+        module_name,
+        *imp.find_module(module_name, [basepath])
+    )
+
+    # If we were able to import as a module, actually exec the compiled code
+    exec(compiled, globals(), conf_dict)
+    conf_dict['__file__'] = abspath
+    return conf_dict
+
+
+def pytest_configure_node(node):
+    node_id = node.slaveinput['slaveid']
+    scenario_path = os.path.abspath(node.config.getoption('--scenario'))
+    scenario = load_scenario_config(scenario_path)
+    node.slaveinput['node_config'] = scenario['nodes'][node_id]
+    node.slaveinput['scenario_config'] = scenario
+
+
+@pytest.fixture(scope='session')
+def node_config(request):
+    return request.config.slaveinput['node_config']
+
+
+@pytest.fixture(scope="session")
+def scenario_config(request):
+    return request.config.slaveinput['scenario_config']
+
+
+def pytest_report_header(config):
+    """
+    Hook to add extra information about the execution environment and to be
+    able to debug what did the magical args got expanded to
+    """
+    lines = []
+    scenario_path = str(config.rootdir.join(config.getoption('--scenario')))
+    if not config.remote_execution:
+        lines.append('execution environment: local')
+    else:
+        lines.append('execution environment: remote')
+        lines.append('loaded scenario: %s' % scenario_path)
+    lines.append('expanded args: %s' % config.extended_args)
+    return lines
+
+
+def pytest_cmdline_preparse(args, config):
+    # Note: we can only do our magical args expansion if we aren't already in
+    # a remote node via xdist/execnet so return quickly if we can't do magic.
+    # TODO: allow setting an environment variable that helps to skip this kind
+    # of magical argument expansion
+    if os.getcwd().endswith('pyexecnetcache'):
+        return
+
+    scenario_path = os.path.abspath(config.getoption('--scenario'))
+
+    scenarios = load_scenario_config(scenario_path, args=args)
+    rsync_dir = os.path.dirname(str(config.rootdir.join('functional')))
+    test_path = str(config.rootdir.join('functional/tests'))
+    nodes = []
+    config.remote_execution = True
+    for node in scenarios.get('nodes', []):
+        nodes.append('--tx')
+        nodes.append('vagrant_ssh={node_name}//id={node_name}'.format(node_name=node))
+    args[:] = args + ['--max-slave-restart', '0', '--dist=each'] + nodes + ['--rsyncdir', rsync_dir, test_path]
+    config.extended_args = ' '.join(args)