From f4eb685a63239e20b0c2d8fee32d6da54906df86 Mon Sep 17 00:00:00 2001 From: Jonathan Maw Date: Mon, 15 Oct 2018 12:46:28 +0100 Subject: yamlcache.py: Add yaml cache tests --- tests/frontend/yamlcache.py | 119 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 tests/frontend/yamlcache.py (limited to 'tests/frontend/yamlcache.py') diff --git a/tests/frontend/yamlcache.py b/tests/frontend/yamlcache.py new file mode 100644 index 000000000..0bcc423ec --- /dev/null +++ b/tests/frontend/yamlcache.py @@ -0,0 +1,119 @@ +import os +import pytest +import hashlib +import tempfile +from ruamel import yaml + +from tests.testutils import cli, generate_junction, create_element_size, create_repo +from buildstream import _yaml +from buildstream._yamlcache import YamlCache +from buildstream._project import Project +from buildstream._context import Context +from contextlib import contextmanager + + +def generate_project(tmpdir, ref_storage, with_junction, name="test"): + if with_junction == 'junction': + subproject_dir = generate_project( + tmpdir, ref_storage, + 'no-junction', name='test-subproject' + ) + + project_dir = os.path.join(tmpdir, name) + os.makedirs(project_dir) + # project.conf + project_conf_path = os.path.join(project_dir, 'project.conf') + elements_path = 'elements' + project_conf = { + 'name': name, + 'element-path': elements_path, + 'ref-storage': ref_storage, + } + _yaml.dump(project_conf, project_conf_path) + + # elements + if with_junction == 'junction': + junction_name = 'junction.bst' + junction_dir = os.path.join(project_dir, elements_path) + junction_path = os.path.join(project_dir, elements_path, junction_name) + os.makedirs(junction_dir) + generate_junction(tmpdir, subproject_dir, junction_path) + element_depends = [{'junction': junction_name, 'filename': 'test.bst'}] + else: + element_depends = [] + + element_name = 'test.bst' + create_element_size(element_name, project_dir, elements_path, element_depends, 1) + + return project_dir + + +@contextmanager +def with_yamlcache(project_dir): + context = Context() + project = Project(project_dir, context) + cache_file = YamlCache.get_cache_file(project_dir) + with YamlCache.open(context, cache_file) as yamlcache: + yield yamlcache, project + + +def yamlcache_key(yamlcache, in_file, copy_tree=False): + with open(in_file) as f: + key = yamlcache._calculate_key(f.read(), copy_tree) + return key + + +def modified_file(input_file, tmpdir): + with open(input_file) as f: + data = f.read() + assert 'variables' not in data + data += '\nvariables: {modified: True}\n' + _, temppath = tempfile.mkstemp(dir=tmpdir, text=True) + with open(temppath, 'w') as f: + f.write(data) + + return temppath + + +@pytest.mark.parametrize('ref_storage', ['inline', 'project.refs']) +@pytest.mark.parametrize('with_junction', ['no-junction', 'junction']) +@pytest.mark.parametrize('move_project', ['move', 'no-move']) +def test_yamlcache_used(cli, tmpdir, ref_storage, with_junction, move_project): + # Generate the project + project = generate_project(str(tmpdir), ref_storage, with_junction) + if with_junction == 'junction': + result = cli.run(project=project, args=['fetch', '--track', 'junction.bst']) + result.assert_success() + + # bst show to put it in the cache + result = cli.run(project=project, args=['show', 'test.bst']) + result.assert_success() + + element_path = os.path.join(project, 'elements', 'test.bst') + with with_yamlcache(project) as (yc, prj): + # Check that it's in the cache + assert yc.is_cached(prj, element_path) + + # *Absolutely* horrible cache corruption to check it's being used + # Modifying the data from the cache is fraught with danger, + # so instead I'll load a modified version of the original file + temppath = modified_file(element_path, str(tmpdir)) + contents = _yaml.load(temppath, copy_tree=False, project=prj) + key = yamlcache_key(yc, element_path) + yc.put_from_key(prj, element_path, key, contents) + + # Show that a variable has been added + result = cli.run(project=project, args=['show', '--format', '%{vars}', 'test.bst']) + result.assert_success() + data = yaml.safe_load(result.output) + assert 'modified' in data + assert data['modified'] == 'True' + + +@pytest.mark.parametrize('ref_storage', ['inline', 'project.refs']) +@pytest.mark.parametrize('with_junction', ['junction', 'no-junction']) +@pytest.mark.parametrize('move_project', ['move', 'no-move']) +def test_yamlcache_changed_file(cli, ref_storage, with_junction, move_project): + # i.e. a file is cached, the file is changed, loading the file (with cache) returns new data + # inline and junction can only be changed by opening a workspace + pass -- cgit v1.2.1