diff options
author | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-03-06 18:08:02 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-03-06 18:28:26 +0900 |
commit | 06ac03d4d4330fed7d0dfa75c918dcf2e285bb03 (patch) | |
tree | 11f7445dad683e0164c321ae918ccadc94e2dc95 | |
parent | 2e13d61e5fc684b6d32aa95b1e913ba2c59a3e63 (diff) | |
download | buildstream-06ac03d4d4330fed7d0dfa75c918dcf2e285bb03.tar.gz |
integration tests: Refactoring for dynamic project configurations
o CliIntegration.run() now takes a `project_config` option, this
will be composited on top of the existing, substituted project.conf
o Removing gnomesdk alias from integration tests project.conf
o Using `sysroot` alias instead of `gnome7` alias
o Make base-alpine.bst use the `sysroot` alias now
o Removed `create_project_config()` from shell.py tests, now
use the new built-in feature for this which is cleaner.
-rw-r--r-- | tests/integration/project/elements/base/base-alpine.bst | 2 | ||||
-rw-r--r-- | tests/integration/project/project.conf | 3 | ||||
-rw-r--r-- | tests/integration/shell.py | 64 | ||||
-rw-r--r-- | tests/testutils/runcli.py | 70 |
4 files changed, 83 insertions, 56 deletions
diff --git a/tests/integration/project/elements/base/base-alpine.bst b/tests/integration/project/elements/base/base-alpine.bst index 91327bc73..6a2313018 100644 --- a/tests/integration/project/elements/base/base-alpine.bst +++ b/tests/integration/project/elements/base/base-alpine.bst @@ -7,6 +7,6 @@ description: | sources: - kind: tar - url: https://gnome7.codethink.co.uk/tarballs/integration-tests-base.v1.x86_64.tar.xz + url: sysroot:tarballs/integration-tests-base.v1.x86_64.tar.xz base-dir: '' ref: 3eb559250ba82b64a68d86d0636a6b127aa5f6d25d3601a79f79214dc9703639 diff --git a/tests/integration/project/project.conf b/tests/integration/project/project.conf index a677129fb..c1a1c62ce 100644 --- a/tests/integration/project/project.conf +++ b/tests/integration/project/project.conf @@ -2,8 +2,7 @@ name: test element-path: elements aliases: - gnome7: https://gnome7.codethink.co.uk/ - gnomesdk: https://sdk.gnome.org/ + sysroot: https://gnome7.codethink.co.uk/ project_dir: file://{project_dir} options: linux: diff --git a/tests/integration/shell.py b/tests/integration/shell.py index 98e485f41..210db4251 100644 --- a/tests/integration/shell.py +++ b/tests/integration/shell.py @@ -15,24 +15,6 @@ DATA_DIR = os.path.join( ) -def create_project_conf(project_dir, config): - project_file = os.path.join(project_dir, 'project.conf') - config['name'] = 'test' - config['element-path'] = 'elements' - config['aliases'] = { - 'gnome7': 'https://gnome7.codethink.co.uk/', - 'project_dir': 'file://{}'.format(project_dir), - } - config['options'] = { - 'linux': { - 'type': 'bool', - 'description': 'Whether to expect a linux platform', - 'default': 'True' - } - } - _yaml.dump(config, project_file) - - # execute_shell() # # Helper to run `bst shell` and first ensure that the element is built @@ -41,13 +23,14 @@ def create_project_conf(project_dir, config): # cli (Cli): The cli runner fixture # project (str): The project directory # command (list): The command argv list +# config (dict): A project.conf dictionary to composite over the default # mount (tuple): A (host, target) tuple for the `--mount` option # element (str): The element to build and run a shell with # isolate (bool): Whether to pass --isolate to `bst shell` # -def execute_shell(cli, project, command, mount=None, element='base.bst', isolate=False): +def execute_shell(cli, project, command, *, config=None, mount=None, element='base.bst', isolate=False): # Ensure the element is built - result = cli.run(project=project, args=['build', element]) + result = cli.run(project=project, project_config=config, args=['build', element]) assert result.exit_code == 0 args = ['shell'] @@ -58,7 +41,7 @@ def execute_shell(cli, project, command, mount=None, element='base.bst', isolate args += ['--mount', host_path, target_path] args += [element, '--'] + command - return cli.run(project=project, args=args) + return cli.run(project=project, project_config=config, args=args) # Test running something through a shell, allowing it to find the @@ -87,17 +70,17 @@ def test_executable(cli, tmpdir, datafiles): @pytest.mark.datafiles(DATA_DIR) def test_inherit(cli, tmpdir, datafiles, animal): project = os.path.join(datafiles.dirname, datafiles.basename) - create_project_conf(project, { - 'shell': { - 'environment-inherit': ['ANIMAL'] - } - }) # Set the env var, and expect the same with added newline os.environ['ANIMAL'] = animal expected = animal + '\n' - result = execute_shell(cli, project, ['/bin/sh', '-c', 'echo ${ANIMAL}']) + result = execute_shell(cli, project, ['/bin/sh', '-c', 'echo ${ANIMAL}'], config={ + 'shell': { + 'environment-inherit': ['ANIMAL'] + } + }) + assert result.exit_code == 0 assert result.output == expected @@ -107,16 +90,15 @@ def test_inherit(cli, tmpdir, datafiles, animal): @pytest.mark.datafiles(DATA_DIR) def test_isolated_no_inherit(cli, tmpdir, datafiles, animal): project = os.path.join(datafiles.dirname, datafiles.basename) - create_project_conf(project, { - 'shell': { - 'environment-inherit': ['ANIMAL'] - } - }) # Set the env var, but expect that it is not applied os.environ['ANIMAL'] = animal - result = execute_shell(cli, project, ['/bin/sh', '-c', 'echo ${ANIMAL}'], isolate=True) + result = execute_shell(cli, project, ['/bin/sh', '-c', 'echo ${ANIMAL}'], isolate=True, config={ + 'shell': { + 'environment-inherit': ['ANIMAL'] + } + }) assert result.exit_code == 0 assert result.output == '\n' @@ -159,8 +141,7 @@ def test_no_shell(cli, tmpdir, datafiles): def test_host_files(cli, tmpdir, datafiles, path): project = os.path.join(datafiles.dirname, datafiles.basename) ponyfile = os.path.join(project, 'files', 'shell-mount', 'pony.txt') - - create_project_conf(project, { + result = execute_shell(cli, project, ['cat', path], config={ 'shell': { 'host-files': [ { @@ -170,8 +151,6 @@ def test_host_files(cli, tmpdir, datafiles, path): ] } }) - - result = execute_shell(cli, project, ['cat', path]) assert result.exit_code == 0 assert result.output == 'pony\n' @@ -182,8 +161,7 @@ def test_host_files(cli, tmpdir, datafiles, path): def test_isolated_no_mount(cli, tmpdir, datafiles, path): project = os.path.join(datafiles.dirname, datafiles.basename) ponyfile = os.path.join(project, 'files', 'shell-mount', 'pony.txt') - - create_project_conf(project, { + result = execute_shell(cli, project, ['cat', path], isolate=True, config={ 'shell': { 'host-files': [ { @@ -193,8 +171,6 @@ def test_isolated_no_mount(cli, tmpdir, datafiles, path): ] } }) - - result = execute_shell(cli, project, ['cat', path], isolate=True) assert result.exit_code != 0 @@ -211,7 +187,8 @@ def test_host_files_missing(cli, tmpdir, datafiles, optional): else: option = False - create_project_conf(project, { + # Assert that we did successfully run something in the shell anyway + result = execute_shell(cli, project, ['echo', 'Hello'], config={ 'shell': { 'host-files': [ { @@ -222,9 +199,6 @@ def test_host_files_missing(cli, tmpdir, datafiles, optional): ] } }) - - # Assert that we did successfully run something in the shell anyway - result = execute_shell(cli, project, ['echo', 'Hello']) assert result.exit_code == 0 assert result.output == 'Hello\n' diff --git a/tests/testutils/runcli.py b/tests/testutils/runcli.py index d18fa279d..e424756e7 100644 --- a/tests/testutils/runcli.py +++ b/tests/testutils/runcli.py @@ -2,6 +2,7 @@ import os import re import sys import shutil +import tempfile import itertools import traceback import subprocess @@ -384,17 +385,70 @@ class Cli(): class CliIntegration(Cli): - def run(self, *args, **kwargs): - # Set the project_dir variable in our project.conf for - # relative tar imports - project_conf = os.path.join(kwargs['project'], 'project.conf') + # run() + # + # This supports the same arguments as Cli.run() and additionally + # it supports the project_config keyword argument. + # + # This will first load the project.conf file from the specified + # project directory ('project' keyword argument) and perform substitutions + # of any {project_dir} specified in the existing project.conf. + # + # If the project_config parameter is specified, it is expected to + # be a dictionary of additional project configuration options, and + # will be composited on top of the already loaded project.conf + # + def run(self, *args, project_config=None, **kwargs): - with open(project_conf) as f: + # First load the project.conf and substitute {project_dir} + # + # Save the original project.conf, because we will run more than + # once in the same temp directory + # + project_directory = kwargs['project'] + project_filename = os.path.join(project_directory, 'project.conf') + project_backup = os.path.join(project_directory, 'project.conf.backup') + project_load_filename = project_filename + + if not os.path.exists(project_backup): + shutil.copy(project_filename, project_backup) + else: + project_load_filename = project_backup + + with open(project_load_filename) as f: config = f.read() - config = config.format(project_dir=kwargs['project']) - with open(project_conf, 'w') as f: - f.write(config) + config = config.format(project_dir=project_directory) + + if project_config is not None: + + # If a custom project configuration dictionary was + # specified, composite it on top of the already + # substituted base project configuration + # + base_config = _yaml.load_data(config) + + # In order to leverage _yaml.composite_dict(), both + # dictionaries need to be loaded via _yaml.load_data() first + # + with tempfile.TemporaryDirectory(dir=project_directory) as scratchdir: + + temp_project = os.path.join(scratchdir, 'project.conf') + with open(temp_project, 'w') as f: + yaml.safe_dump(project_config, f) + + project_config = _yaml.load(temp_project) + + _yaml.composite_dict(base_config, project_config) + + base_config = _yaml.node_sanitize(base_config) + _yaml.dump(base_config, project_filename) + + else: + + # Otherwise, just dump it as is + with open(project_filename, 'w') as f: + f.write(config) return super().run(*args, **kwargs) |