summaryrefslogtreecommitdiff
path: root/tests/sourcecache/staging.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/sourcecache/staging.py')
-rw-r--r--tests/sourcecache/staging.py189
1 files changed, 189 insertions, 0 deletions
diff --git a/tests/sourcecache/staging.py b/tests/sourcecache/staging.py
new file mode 100644
index 000000000..b62bc3c2f
--- /dev/null
+++ b/tests/sourcecache/staging.py
@@ -0,0 +1,189 @@
+#
+# Copyright (C) 2019 Bloomberg Finance LP
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Raoul Hidalgo Charman <raoul.hidalgocharman@codethink.co.uk>
+#
+import os
+import shutil
+import pytest
+
+from buildstream._context import Context
+from buildstream._project import Project
+
+from buildstream.plugintestutils.runcli import cli
+from tests.testutils.element_generators import create_element_size
+
+
+DATA_DIR = os.path.dirname(os.path.realpath(__file__))
+
+
+def dummy_message_handler(message, context):
+ pass
+
+
+# walk that removes the root directory from roots
+def relative_walk(rootdir):
+ for root, dirnames, filenames in os.walk(rootdir):
+ relative_root = root.split(rootdir)[1]
+ yield (relative_root, dirnames, filenames)
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_source_staged(tmpdir, cli, datafiles):
+ project_dir = os.path.join(datafiles.dirname, datafiles.basename, 'project')
+ cachedir = os.path.join(str(tmpdir), 'cache')
+
+ cli.configure({
+ 'cachedir': cachedir
+ })
+
+ # set up minimal context
+ context = Context()
+ context.load()
+
+ # load project and sourcecache
+ project = Project(project_dir, context)
+ project.ensure_fully_loaded()
+ context.cachedir = cachedir
+ context.set_message_handler(dummy_message_handler)
+ sourcecache = context.sourcecache
+ cas = context.get_cascache()
+
+ res = cli.run(project=project_dir, args=["build", "import-bin.bst"])
+ res.assert_success()
+
+ # now check that the source is in the refs file, this is pretty messy but
+ # seems to be the only way to get the sources?
+ element = project.load_elements(["import-bin.bst"])[0]
+ source = list(element.sources())[0]
+ assert sourcecache.contains(source)
+ assert element._source_cached()
+
+ # Extract the file and check it's the same as the one we imported
+ ref = source._get_source_name()
+ digest = cas.resolve_ref(ref)
+ extractdir = os.path.join(str(tmpdir), "extract")
+ cas.checkout(extractdir, digest)
+ dir1 = extractdir
+ dir2 = os.path.join(project_dir, "files", "bin-files")
+
+ assert list(relative_walk(dir1)) == list(relative_walk(dir2))
+
+
+# Check sources are staged during a fetch
+@pytest.mark.datafiles(DATA_DIR)
+def test_source_fetch(tmpdir, cli, datafiles):
+ project_dir = os.path.join(datafiles.dirname, datafiles.basename, 'project')
+ cachedir = os.path.join(str(tmpdir), 'cache')
+
+ cli.configure({
+ 'cachedir': cachedir
+ })
+
+ # set up minimal context
+ context = Context()
+ context.load()
+
+ # load project and sourcecache
+ project = Project(project_dir, context)
+ project.ensure_fully_loaded()
+ context.cachedir = cachedir
+ context.set_message_handler(dummy_message_handler)
+ cas = context.get_cascache()
+
+ res = cli.run(project=project_dir, args=["source", "fetch", "import-dev.bst"])
+ res.assert_success()
+
+ element = project.load_elements(["import-dev.bst"])[0]
+ source = list(element.sources())[0]
+ assert element._source_cached()
+
+ # check that the directory structures are idetical
+ ref = source._get_source_name()
+ digest = cas.resolve_ref(ref)
+ extractdir = os.path.join(str(tmpdir), "extract")
+ cas.checkout(extractdir, digest)
+ dir1 = extractdir
+ dir2 = os.path.join(project_dir, "files", "dev-files")
+
+ assert list(relative_walk(dir1)) == list(relative_walk(dir2))
+
+
+# Check that with sources only in the CAS build successfully completes
+@pytest.mark.datafiles(DATA_DIR)
+def test_staged_source_build(tmpdir, datafiles, cli):
+ project_dir = os.path.join(datafiles.dirname, datafiles.basename, 'project')
+ cachedir = os.path.join(str(tmpdir), 'cache')
+ element_path = 'elements'
+ source_refs = os.path.join(str(tmpdir), 'cache', 'cas', 'refs', 'heads', '@sources')
+ source_dir = os.path.join(str(tmpdir), 'cache', 'sources')
+
+ cli.configure({
+ 'cachedir': os.path.join(str(tmpdir), 'cache')
+ })
+
+ create_element_size('target.bst', project_dir, element_path, [], 10000)
+
+ # get the source object
+ context = Context()
+ context.load()
+ project = Project(project_dir, context)
+ project.ensure_fully_loaded()
+ context.cachedir = cachedir
+ context.set_message_handler(dummy_message_handler)
+
+ element = project.load_elements(["import-dev.bst"])[0]
+ source = list(element.sources())[0]
+
+ # check consistency of the source
+ assert not element._source_cached()
+
+ res = cli.run(project=project_dir, args=['build', 'target.bst'])
+ res.assert_success()
+
+ # delete artifacts check state is buildable
+ cli.remove_artifact_from_cache(project_dir, 'target.bst')
+ states = cli.get_element_states(project_dir, ['target.bst'])
+ assert states['target.bst'] == 'buildable'
+
+ # delete source dir and check that state is still buildable
+ shutil.rmtree(source_dir)
+ states = cli.get_element_states(project_dir, ['target.bst'])
+ assert states['target.bst'] == 'buildable'
+
+ # build and check that no fetching was done.
+ res = cli.run(project=project_dir, args=['build', 'target.bst'])
+ res.assert_success()
+ assert 'Fetching from' not in res.stderr
+
+ # assert the source directory is still empty (though there may be
+ # directories from staging etc.)
+ files = []
+ for _, _, filename in os.walk(source_dir):
+ files.extend(filename)
+ assert files == []
+
+ # Now remove the source refs and check the state
+ shutil.rmtree(source_refs)
+ cli.remove_artifact_from_cache(project_dir, 'target.bst')
+ states = cli.get_element_states(project_dir, ['target.bst'])
+ assert states['target.bst'] == 'fetch needed'
+
+ # Check that it now fetches from when building the target
+ res = cli.run(project=project_dir, args=['build', 'target.bst'])
+ res.assert_success()
+ assert 'Fetching from' in res.stderr