You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildstream.apache.org by tv...@apache.org on 2021/02/04 08:18:38 UTC

[buildstream] 02/06: Original commit required additional functionality to test

This is an automated email from the ASF dual-hosted git repository.

tvb pushed a commit to branch issue-21_Caching_build_trees
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit db7c916f80c1a5fe49dba0ec9df6ced5a02b0b86
Author: Phillip Smyth <ph...@codethink.co.uk>
AuthorDate: Mon Mar 26 15:38:26 2018 +0000

    Original commit required additional functionality to test
    
    resolves issue #311
    https://gitlab.com/BuildStream/buildstream/issues/311
    "Opening a workspace with a cached build"
    
    * app.py: modified Open_workspace to allow use of cached build tree
    * cli.py: added additional flag to workspace open
    * element.py: Added function to return cached build tree dir
---
 buildstream/_artifactcache/ostreecache.py          |   4 +
 buildstream/_frontend/app.py                       | 122 +++++++++++++++++++++
 buildstream/_frontend/cli.py                       |  12 +-
 buildstream/element.py                             |  15 ++-
 tests/cachekey/project/elements/build1.expected    |   2 +-
 tests/cachekey/project/elements/build2.expected    |   2 +-
 tests/cachekey/project/elements/compose1.expected  |   2 +-
 tests/cachekey/project/elements/compose2.expected  |   2 +-
 tests/cachekey/project/elements/compose3.expected  |   2 +-
 tests/cachekey/project/elements/compose4.expected  |   2 +-
 tests/cachekey/project/elements/compose5.expected  |   2 +-
 tests/cachekey/project/elements/import1.expected   |   2 +-
 tests/cachekey/project/elements/import2.expected   |   2 +-
 tests/cachekey/project/elements/import3.expected   |   2 +-
 tests/cachekey/project/elements/script1.expected   |   2 +-
 tests/cachekey/project/sources/bzr1.expected       |   2 +-
 tests/cachekey/project/sources/git1.expected       |   2 +-
 tests/cachekey/project/sources/git2.expected       |   2 +-
 tests/cachekey/project/sources/local1.expected     |   2 +-
 tests/cachekey/project/sources/local2.expected     |   2 +-
 tests/cachekey/project/sources/ostree1.expected    |   2 +-
 tests/cachekey/project/sources/patch1.expected     |   2 +-
 tests/cachekey/project/sources/patch2.expected     |   2 +-
 tests/cachekey/project/sources/patch3.expected     |   2 +-
 tests/cachekey/project/sources/tar1.expected       |   2 +-
 tests/cachekey/project/sources/tar2.expected       |   2 +-
 tests/cachekey/project/sources/zip1.expected       |   2 +-
 tests/cachekey/project/sources/zip2.expected       |   2 +-
 tests/cachekey/project/target.expected             |   2 +-
 tests/frontend/workspace.py                        |   1 +
 .../Makefile                                       |   2 +
 .../files/workspace-use-cached-build-tree/Makefile |   2 +
 tests/integration/workspace.py                     | 116 +++++++++++++++++++-
 33 files changed, 285 insertions(+), 39 deletions(-)

diff --git a/buildstream/_artifactcache/ostreecache.py b/buildstream/_artifactcache/ostreecache.py
index 39e7efb..d27f4ea 100644
--- a/buildstream/_artifactcache/ostreecache.py
+++ b/buildstream/_artifactcache/ostreecache.py
@@ -162,6 +162,10 @@ class OSTreeCache(ArtifactCache):
 
         return modified, removed, added
 
+    def does_artifact_directory_exist(self, element, key, directory):
+        _, a, _ = self.repo.read_commit(self.get_artifact_fullname(element, key))
+        return bool(a.get_child(directory))
+
     def pull(self, element, key, *, progress=None):
         project = element._get_project()
 
diff --git a/buildstream/_frontend/app.py b/buildstream/_frontend/app.py
index 2ee6a77..8a14008 100644
--- a/buildstream/_frontend/app.py
+++ b/buildstream/_frontend/app.py
@@ -373,6 +373,128 @@ class App():
             self.stream.cleanup()
 
     ############################################################
+    #                   Workspace Commands                     #
+    ############################################################
+
+    # open_workspace
+    #
+    # Open a project workspace - this requires full initialization
+    #
+    # Args:
+    #    target (Element): The element to open the workspace for
+    #    directory (str): The directory to stage the source in
+    #    no_checkout (bool): Whether to skip checking out the source
+    #    track_first (bool): Whether to track and fetch first
+    #    force (bool): Whether to ignore contents in an existing directory
+    #
+    def open_workspace(self, target, directory, no_checkout, track_first, force, no_cache=False):
+
+        workdir = os.path.abspath(directory)
+
+        if target._cached():
+            with target.timed_activity("Extracting cached build tree"):
+                build_tree_path = target._build_tree_path(target._get_cache_key())
+            if build_tree_path is None:
+                no_cache = True
+        else:
+            no_cache = True
+
+        # Check for workspace config
+        if self.project.workspaces.get_workspace(target):
+            raise AppError("Workspace '{}' is already defined.".format(target.name))
+
+        if no_cache:
+            if not list(target.sources()):
+                build_depends = [x.name for x in target.dependencies(Scope.BUILD, recurse=False)]
+                if not build_depends:
+                    raise AppError("The given element has no sources")
+                detail = "Try opening a workspace on one of its dependencies instead:\n"
+                detail += "  \n".join(build_depends)
+                raise AppError("The given element has no sources", detail=detail)
+                # If we're going to checkout, we need at least a fetch,
+                # if we were asked to track first, we're going to fetch anyway.
+
+            if not no_checkout or track_first:
+                self.pipeline.fetch(self.scheduler, [target])
+
+            if not no_checkout and target._get_consistency() != Consistency.CACHED:
+                raise PipelineError("Could not stage uncached source. " +
+                                    "Use `--track` to track and " +
+                                    "fetch the latest version of the " +
+                                    "source.")
+
+            try:
+                os.makedirs(directory, exist_ok=True)
+            except OSError as e:
+                raise AppError("Failed to create workspace directory: {}".format(e)) from e
+
+            self.project.workspaces.create_workspace(target.name, workdir)
+
+            if not no_checkout:
+                with target.timed_activity("Staging sources to {}".format(directory)):
+                    target._open_workspace()
+        else:
+            with target.timed_activity("Staging cached build tree to {}".format(workdir)):
+                shutil.copytree(build_tree_path, workdir)
+
+        self.project.workspaces.save_config()
+        self._message(MessageType.INFO, "Saved workspace configuration")
+
+    # close_workspace
+    #
+    # Close a project workspace
+    #
+    # Args:
+    #    remove_dir (bool) - Whether to remove the associated directory
+    #
+    def close_workspace(self, element_name, remove_dir):
+
+        workspace = self.project.workspaces.get_workspace(element_name)
+
+        if workspace is None:
+            raise AppError("Workspace '{}' does not exist".format(element_name))
+
+        if self.interactive and remove_dir:
+            if not click.confirm('This will remove all your changes, are you sure?'):
+                click.echo('Aborting', err=True)
+                sys.exit(-1)
+
+        # Remove workspace directory if prompted
+        if remove_dir:
+            with self.context.timed_activity("Removing workspace directory {}"
+                                             .format(workspace.path)):
+                try:
+                    shutil.rmtree(workspace.path)
+                except OSError as e:
+                    raise AppError("Could not remove  '{}': {}"
+                                   .format(workspace.path, e)) from e
+
+        # Delete the workspace and save the configuration
+        self.project.workspaces.delete_workspace(element_name)
+        self.project.workspaces.save_config()
+        self._message(MessageType.INFO, "Saved workspace configuration")
+
+    # reset_workspace
+    #
+    # Reset a workspace to its original state, discarding any user
+    # changes.
+    #
+    # Args:
+    #    target (Element): The element to reset the workspace for
+    #    track (bool): Whether to also track the source
+    #
+    def reset_workspace(self, target, track, no_cache):
+        workspace = self.project.workspaces.get_workspace(target.name)
+
+        if workspace is None:
+            raise AppError("Workspace '{}' is currently not defined"
+                           .format(target.name))
+
+        self.close_workspace(target.name, True)
+        self.open_workspace(target, workspace.path, False, track, False, no_cache)
+>>>>>>> Original commit required additional functionality to test
+
+    ############################################################
     #                      Local Functions                     #
     ############################################################
 
diff --git a/buildstream/_frontend/cli.py b/buildstream/_frontend/cli.py
index 6c9adb7..1d9cafc 100644
--- a/buildstream/_frontend/cli.py
+++ b/buildstream/_frontend/cli.py
@@ -579,11 +579,13 @@ def workspace():
               help="Overwrite files existing in checkout directory")
 @click.option('--track', 'track_', default=False, is_flag=True,
               help="Track and fetch new source references before checking out the workspace")
+@click.option('--no-cache', 'no_cache', default=False, is_flag=True,
+              help="Use Cached build tree if available")
 @click.argument('element',
                 type=click.Path(dir_okay=False, readable=True))
 @click.argument('directory', type=click.Path(file_okay=False))
 @click.pass_obj
-def workspace_open(app, no_checkout, force, track_, element, directory):
+def workspace_open(app, no_checkout, force, track_, no_cache, element, directory):
     """Open a workspace for manual source modification"""
 
     if os.path.exists(directory):
@@ -600,7 +602,8 @@ def workspace_open(app, no_checkout, force, track_, element, directory):
         app.stream.workspace_open(element, directory,
                                   no_checkout=no_checkout,
                                   track_first=track_,
-                                  force=force)
+                                  force=force,
+                                  no_cache)
 
 
 ##################################################################
@@ -660,8 +663,7 @@ def workspace_close(app, remove_dir, all_, elements):
 @click.argument('elements', nargs=-1,
                 type=click.Path(dir_okay=False, readable=True))
 @click.pass_obj
-def workspace_reset(app, track_, all_, element, no_cache):
-                type=click.Path(dir_okay=False, readable=True))
+def workspace_reset(app, track_, all_, elements, no_cache):
     """Reset a workspace to its original state"""
 
     # Check that the workspaces in question exist
@@ -688,7 +690,7 @@ def workspace_reset(app, track_, all_, element, no_cache):
         if all_:
             elements = tuple(element_name for element_name, _ in app.project.workspaces.list())
 
-        app.stream.workspace_reset(elements, track_first=track_)
+        app.stream.workspace_reset(elements, track_first=track_, no_cache)
 
 
 ##################################################################
diff --git a/buildstream/element.py b/buildstream/element.py
index 64a3f79..7d228bc 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -929,15 +929,14 @@ class Element(Plugin):
         return cls.__redundant_source_refs
 
     # _build_tree_path():
-    #    
+    #
     # Returns the path of the cached build tree if it exists
-    #    
-    def _build_tree_path(self):
-        build_tree_path = os.path.join(self.__extract()[0], 'buildtree')
-        if os.path.isdir(build_tree_path):
-            return build_tree_path
+    #
+    def _build_tree_path(self, key):
+        if self.__artifacts.does_artifact_directory_exist(self, key, "buildtree"):
+            return os.path.join(self.__extract()[0], 'buildtree')
         else:
-            return None 
+            return None
 
     # _reset_load_state()
     #
@@ -1492,7 +1491,7 @@ class Element(Plugin):
 
                 # Copy build tree contents
                 if self.get_variable('cache-build-tree'):
-                    sandbox_build_dir = os.path.join(sandbox_root, self.get_variable('build-root'))
+                    sandbox_build_dir = os.path.join(sandbox_root, self.get_variable('build-root').lstrip(os.sep))
                     if os.path.isdir(sandbox_build_dir):
                         shutil.copytree(sandbox_build_dir, os.path.join(assembledir, 'buildtree'))
 
diff --git a/tests/cachekey/project/elements/build1.expected b/tests/cachekey/project/elements/build1.expected
index ab8adf2..5d1c8cf 100644
--- a/tests/cachekey/project/elements/build1.expected
+++ b/tests/cachekey/project/elements/build1.expected
@@ -1 +1 @@
-93594f53df6c599598ea9c1d5101a8f7e57bbd82cac521494ce680e6f84de67d
\ No newline at end of file
+aafbda91229c4b3fbaee5395b2c0757e4d6086d805c2ff3700728fa325715b2d
\ No newline at end of file
diff --git a/tests/cachekey/project/elements/build2.expected b/tests/cachekey/project/elements/build2.expected
index 9499017..2eb2e3e 100644
--- a/tests/cachekey/project/elements/build2.expected
+++ b/tests/cachekey/project/elements/build2.expected
@@ -1 +1 @@
-3ae596efed1126d440780ef33d2144a06cb7215a778c4f59b12a2f77fa0ee3b2
\ No newline at end of file
+5d90de6984ce20d7400aaabf8618cad09f90db3560a79a07d515f098641b5416
\ No newline at end of file
diff --git a/tests/cachekey/project/elements/compose1.expected b/tests/cachekey/project/elements/compose1.expected
index e912fbe..3e8aa77 100644
--- a/tests/cachekey/project/elements/compose1.expected
+++ b/tests/cachekey/project/elements/compose1.expected
@@ -1 +1 @@
-d67fccd867504706010f9f36b07cd35b3129e9d79ae287c3dc2bf9ec03e309ea
\ No newline at end of file
+36eced92e2b284c16676d9973c98b0948bdc3eb1c87f618631977afbd34bc74f
\ No newline at end of file
diff --git a/tests/cachekey/project/elements/compose2.expected b/tests/cachekey/project/elements/compose2.expected
index 4c3b901..eb82916 100644
--- a/tests/cachekey/project/elements/compose2.expected
+++ b/tests/cachekey/project/elements/compose2.expected
@@ -1 +1 @@
-743eaac4f261d389d2c12fb9c8605eb70d5e42c8a0bccadef9f651dd137cedde
\ No newline at end of file
+1c3ac59f492bf7ad9ebb5a94dc6cada46caa6efaeba4eadee51b88501d605542
\ No newline at end of file
diff --git a/tests/cachekey/project/elements/compose3.expected b/tests/cachekey/project/elements/compose3.expected
index 85843a1..8bce364 100644
--- a/tests/cachekey/project/elements/compose3.expected
+++ b/tests/cachekey/project/elements/compose3.expected
@@ -1 +1 @@
-5b401864d1d91809f59c258d37f78b410b244fcb20cab4bd0c1da17257515643
\ No newline at end of file
+dd0ebaf34077deb7e444e8933faefbddd15a13b1c667a6e8cd5d498d8d12b567
\ No newline at end of file
diff --git a/tests/cachekey/project/elements/compose4.expected b/tests/cachekey/project/elements/compose4.expected
index 38060ae..19e84b8 100644
--- a/tests/cachekey/project/elements/compose4.expected
+++ b/tests/cachekey/project/elements/compose4.expected
@@ -1 +1 @@
-450664eb37302835e3289b95dfb38cab0b24e6c30c4b7b59a5dc1b5a7f1f01e0
\ No newline at end of file
+599845b4fb6b54b455eec54dbb1a8b5e3fb0c84936f6512e2cc98711d6cfe418
\ No newline at end of file
diff --git a/tests/cachekey/project/elements/compose5.expected b/tests/cachekey/project/elements/compose5.expected
index 2f6307c..89bb1d1 100644
--- a/tests/cachekey/project/elements/compose5.expected
+++ b/tests/cachekey/project/elements/compose5.expected
@@ -1 +1 @@
-fedaf8a315f8a9fb94d11c6f74a409188ff9397eac710e5ba6d9532162bd6973
\ No newline at end of file
+d684e49d057b993bcb45885ba99c785211957b2a298290e56dfe337020ee53f4
\ No newline at end of file
diff --git a/tests/cachekey/project/elements/import1.expected b/tests/cachekey/project/elements/import1.expected
index 4669ed4..14c11b9 100644
--- a/tests/cachekey/project/elements/import1.expected
+++ b/tests/cachekey/project/elements/import1.expected
@@ -1 +1 @@
-20582fab199a8d110fd65b5616f45bc08ae3eccc7bfe8b94ba987f3986b69ce5
\ No newline at end of file
+3414ab09a58064ad2857eece7ff70192c7cdf241e9554cb1e5fe2cb225b8d5c9
\ No newline at end of file
diff --git a/tests/cachekey/project/elements/import2.expected b/tests/cachekey/project/elements/import2.expected
index 2b071ac..15fc944 100644
--- a/tests/cachekey/project/elements/import2.expected
+++ b/tests/cachekey/project/elements/import2.expected
@@ -1 +1 @@
-4fcc04697288b0fdc0785b7350c308c3b40177d2ad0ec47ee4e59afbbe7634a9
\ No newline at end of file
+7860f642f9bcb45de1995d460fb5999fde738ad79635375cc1c4f9c4a3a41318
\ No newline at end of file
diff --git a/tests/cachekey/project/elements/import3.expected b/tests/cachekey/project/elements/import3.expected
index 538daae..f3ae652 100644
--- a/tests/cachekey/project/elements/import3.expected
+++ b/tests/cachekey/project/elements/import3.expected
@@ -1 +1 @@
-203a3749724d461a237f22ff261870616cedfe34bfb59603c935fd05644059b3
\ No newline at end of file
+89cdbce3aeb124dbd7b6334316e7b61e41fce7d930e361d04792df10a0380649
\ No newline at end of file
diff --git a/tests/cachekey/project/elements/script1.expected b/tests/cachekey/project/elements/script1.expected
index cf12139..4ed8069 100644
--- a/tests/cachekey/project/elements/script1.expected
+++ b/tests/cachekey/project/elements/script1.expected
@@ -1 +1 @@
-93de2701d76db777a560e1e531883b7922b07683d4e7c14ea26b0500946f2c62
\ No newline at end of file
+2d6c8fc0c3fe9542edda44253e14cd6068dc114ba54d1b897de2c6a2b6c5e734
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/bzr1.expected b/tests/cachekey/project/sources/bzr1.expected
index 0e2a851..346a9cb 100644
--- a/tests/cachekey/project/sources/bzr1.expected
+++ b/tests/cachekey/project/sources/bzr1.expected
@@ -1 +1 @@
-8509b1e54cc11bc2681425a11498037ad3841295c26fec86ff61a6b09d83e10a
\ No newline at end of file
+13ecf40f3591a881c24d90638ca0e344a94c48acc9e71885287cecfef90f518e
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/git1.expected b/tests/cachekey/project/sources/git1.expected
index 07fc21c..ca2dddf 100644
--- a/tests/cachekey/project/sources/git1.expected
+++ b/tests/cachekey/project/sources/git1.expected
@@ -1 +1 @@
-c1931acaea82971f1fc243dbe035a228c6103d52e09e618c7eda85f141c726cc
\ No newline at end of file
+ef0f79b02127d28c25c4d71b51de8d845e857b2d4e873ae37321df4dadd0c306
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/git2.expected b/tests/cachekey/project/sources/git2.expected
index b08e08c..f21e07d 100644
--- a/tests/cachekey/project/sources/git2.expected
+++ b/tests/cachekey/project/sources/git2.expected
@@ -1 +1 @@
-6d1ee891d29e0af504ed59ccd46c653b74946d3778d7e941f4d8b6e68cf3ca50
\ No newline at end of file
+f40ea93028b5b6d31316711a7463e4cd75ea48c235847efc5aef9c13fe6a5938
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/local1.expected b/tests/cachekey/project/sources/local1.expected
index 4669ed4..14c11b9 100644
--- a/tests/cachekey/project/sources/local1.expected
+++ b/tests/cachekey/project/sources/local1.expected
@@ -1 +1 @@
-20582fab199a8d110fd65b5616f45bc08ae3eccc7bfe8b94ba987f3986b69ce5
\ No newline at end of file
+3414ab09a58064ad2857eece7ff70192c7cdf241e9554cb1e5fe2cb225b8d5c9
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/local2.expected b/tests/cachekey/project/sources/local2.expected
index 4a0796e..171d4eb 100644
--- a/tests/cachekey/project/sources/local2.expected
+++ b/tests/cachekey/project/sources/local2.expected
@@ -1 +1 @@
-527685945072d971075edf6e4a06ce7146ef1cd023da0001c6e1613d525c76aa
\ No newline at end of file
+257b389b6db8e5c827b8e5860692aea02179b7d154bd1708df2c479fa4f44768
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/ostree1.expected b/tests/cachekey/project/sources/ostree1.expected
index 5b4bf12..5fb7420 100644
--- a/tests/cachekey/project/sources/ostree1.expected
+++ b/tests/cachekey/project/sources/ostree1.expected
@@ -1 +1 @@
-b78e79c5ba297cf5cb41d6eaa5f4ca170216c967b84935364d30938021202341
\ No newline at end of file
+f5765ba1a9e62638eb18c09f55aae0dfc19a938ca2b1eefdfe84f52908e5b4d8
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/patch1.expected b/tests/cachekey/project/sources/patch1.expected
index a04b8fd..5508a1c 100644
--- a/tests/cachekey/project/sources/patch1.expected
+++ b/tests/cachekey/project/sources/patch1.expected
@@ -1 +1 @@
-84830ad8577e5fa5a9dab14ce3f995b4dc16699aebc33122aa2dc5fade34528d
\ No newline at end of file
+6f422b3bd744a0e23180542527d6e5d0be57f4fcde29100a11e175578ab9d655
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/patch2.expected b/tests/cachekey/project/sources/patch2.expected
index 3fafb87..1d8b46f 100644
--- a/tests/cachekey/project/sources/patch2.expected
+++ b/tests/cachekey/project/sources/patch2.expected
@@ -1 +1 @@
-1d137c65e7f2f9c8a0a74a46461dfe9ba5c675d53a1ff96a4bf15f0889891883
\ No newline at end of file
+e33a6bd1260cf85434efe55c399429d91dff31d5a11055b7c81ea513017c1406
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/patch3.expected b/tests/cachekey/project/sources/patch3.expected
index 6a62b70..58189d6 100644
--- a/tests/cachekey/project/sources/patch3.expected
+++ b/tests/cachekey/project/sources/patch3.expected
@@ -1 +1 @@
-fd1f209c8f44fd629fb5201d6f299c47567b64828235b470b2ff8ff6edba4478
\ No newline at end of file
+6a345a5135d33d38c553d894c63bdb2f0742980b51ff9650af2cfc6b054ab7d5
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/tar1.expected b/tests/cachekey/project/sources/tar1.expected
index 5b52a4c..9376153 100644
--- a/tests/cachekey/project/sources/tar1.expected
+++ b/tests/cachekey/project/sources/tar1.expected
@@ -1 +1 @@
-003d5c53c81ab4bf7e375c4e9704bdbc260473fecb334c9f78ed24ec5c1a908e
\ No newline at end of file
+b02879274826e5a696d1f4618b6f09bfe40cfe44fa97791e668bc32948924002
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/tar2.expected b/tests/cachekey/project/sources/tar2.expected
index d823bde..13e2bca 100644
--- a/tests/cachekey/project/sources/tar2.expected
+++ b/tests/cachekey/project/sources/tar2.expected
@@ -1 +1 @@
-f501ed7c8df19071712634049fed1a1fb22fbeb6f27973595bc8139e56c6c446
\ No newline at end of file
+8c76b1c844b0fe42ec103d62cb8b1dd9344a1ff27a350000782d42a6f1a11926
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/zip1.expected b/tests/cachekey/project/sources/zip1.expected
index 64c0655..a8d815b 100644
--- a/tests/cachekey/project/sources/zip1.expected
+++ b/tests/cachekey/project/sources/zip1.expected
@@ -1 +1 @@
-6a3c3a788c6a6ddae204a013d0622b6c352a91ff31cdf6d652b96ad0ac5eda52
\ No newline at end of file
+4f99f33d5b33bda8408d85ebc60ce7d45498fba4a850299dac328e267b5f131a
\ No newline at end of file
diff --git a/tests/cachekey/project/sources/zip2.expected b/tests/cachekey/project/sources/zip2.expected
index 64bb772..907d760 100644
--- a/tests/cachekey/project/sources/zip2.expected
+++ b/tests/cachekey/project/sources/zip2.expected
@@ -1 +1 @@
-50a555bf892822b8f5e4d59b940ba4359afe8e6d01dff013d918a3befd9c3d8f
\ No newline at end of file
+2b78c41d3d15756f387ad1ce9509fc11f5be36b44713ed2a142238704dc813c2
\ No newline at end of file
diff --git a/tests/cachekey/project/target.expected b/tests/cachekey/project/target.expected
index dcb6a66..f51a85d 100644
--- a/tests/cachekey/project/target.expected
+++ b/tests/cachekey/project/target.expected
@@ -1 +1 @@
-0de68ec99d39b12857a5350ebfdc7f49fdde9a3457a31b2330896307fb503f7b
\ No newline at end of file
+e164913422997e2c2f5ac103e2af1cb746cc0a5d2d021060ebdb99724b69ce90
\ No newline at end of file
diff --git a/tests/frontend/workspace.py b/tests/frontend/workspace.py
index e45696d..798adb6 100644
--- a/tests/frontend/workspace.py
+++ b/tests/frontend/workspace.py
@@ -1,4 +1,5 @@
 import os
+import sys
 import pytest
 import shutil
 import subprocess
diff --git a/tests/integration/project/files/workspace-no-existing-cached-build-tree/Makefile b/tests/integration/project/files/workspace-no-existing-cached-build-tree/Makefile
new file mode 100644
index 0000000..ff3fb1e
--- /dev/null
+++ b/tests/integration/project/files/workspace-no-existing-cached-build-tree/Makefile
@@ -0,0 +1,2 @@
+test:
+	touch test.o
diff --git a/tests/integration/project/files/workspace-use-cached-build-tree/Makefile b/tests/integration/project/files/workspace-use-cached-build-tree/Makefile
new file mode 100644
index 0000000..ff3fb1e
--- /dev/null
+++ b/tests/integration/project/files/workspace-use-cached-build-tree/Makefile
@@ -0,0 +1,2 @@
+test:
+	touch test.o
diff --git a/tests/integration/workspace.py b/tests/integration/workspace.py
index 6eae1ef..c272b0b 100644
--- a/tests/integration/workspace.py
+++ b/tests/integration/workspace.py
@@ -5,7 +5,7 @@ from buildstream import _yaml
 from tests.testutils import cli_integration as cli
 from tests.testutils.site import IS_LINUX
 from tests.testutils.integration import walk_dir
-
+from tests.frontend import configure_project
 
 pytestmark = pytest.mark.integration
 
@@ -256,3 +256,117 @@ def test_incremental_configure_commands_run_only_once(cli, tmpdir, datafiles):
     res = cli.run(project=project, args=['build', element_name])
     res.assert_success()
     assert not os.path.exists(os.path.join(workspace, 'prepared-again'))
+
+
+@pytest.mark.integration
+@pytest.mark.datafiles(DATA_DIR)
+def test_use_cached_build_tree(cli, tmpdir, datafiles):
+    project = os.path.join(datafiles.dirname, datafiles.basename)
+    workspace = os.path.join(cli.directory, 'workspace')
+    element_path = os.path.join(project, 'elements')
+    element_name = 'workspace/workspace-use-cached-build-tree.bst'
+
+    element = {
+        'kind': 'manual',
+        'depends': [{
+            'filename': 'base.bst',
+            'type': 'build'
+        }],
+        'sources': [{
+            'kind': 'local',
+            'path': 'files/workspace-use-cached-build-tree'
+        }],
+        'config': {
+            'build-commands': [
+                'make'
+            ]
+        }
+    }
+    os.makedirs(os.path.dirname(os.path.join(element_path, element_name)), exist_ok=True)
+    _yaml.dump(element, os.path.join(element_path, element_name))
+
+    res = cli.run(project=project, args=['build', element_name])
+    res.assert_success()
+
+    res = cli.run(project=project, args=['workspace', 'open', element_name, workspace])
+    res.assert_success()
+    assert os.path.isdir(workspace)
+    assert os.path.exists(os.path.join(workspace, "test.o"))
+
+
+@pytest.mark.integration
+@pytest.mark.datafiles(DATA_DIR)
+def test_dont_use_cached_build_tree(cli, tmpdir, datafiles):
+    project = os.path.join(datafiles.dirname, datafiles.basename)
+    workspace = os.path.join(cli.directory, 'workspace')
+    element_path = os.path.join(project, 'elements')
+    element_name = 'workspace/workspace-use-cached-build-tree.bst'
+
+    element = {
+        'kind': 'manual',
+        'depends': [{
+            'filename': 'base.bst',
+            'type': 'build'
+        }],
+        'sources': [{
+            'kind': 'local',
+            'path': 'files/workspace-use-cached-build-tree'
+        }],
+        'config': {
+            'build-commands': [
+                'make'
+            ]
+        }
+    }
+    os.makedirs(os.path.dirname(os.path.join(element_path, element_name)), exist_ok=True)
+    _yaml.dump(element, os.path.join(element_path, element_name))
+
+    res = cli.run(project=project, args=['build', element_name])
+    res.assert_success()
+
+    res = cli.run(project=project, args=['workspace', 'open', '--no-cache', element_name, workspace])
+    res.assert_success()
+    assert os.path.isdir(workspace)
+    assert not os.path.exists(os.path.join(workspace, "test.o"))
+
+
+@pytest.mark.integration
+@pytest.mark.datafiles(DATA_DIR)
+# This tests the output if a build is done with the caching of build trees disabled
+# and then is reenabled and a workspace is opened
+def test_no_existing_cached_build_tree(cli, tmpdir, datafiles):
+    project = os.path.join(datafiles.dirname, datafiles.basename)
+    workspace = os.path.join(cli.directory, 'workspace')
+    element_path = os.path.join(project, 'elements')
+    element_name = 'workspace/workspace-no-existing-cached-build-tree.bst'
+
+    element = {
+        'kind': 'manual',
+        'depends': [{
+            'filename': 'base.bst',
+            'type': 'build'
+        }],
+        'sources': [{
+            'kind': 'local',
+            'path': 'files/workspace-no-existing-cached-build-tree'
+        }],
+        'config': {
+            'build-commands': [
+                'make'
+            ]
+        }
+    }
+    os.makedirs(os.path.dirname(os.path.join(element_path, element_name)), exist_ok=True)
+    _yaml.dump(element, os.path.join(element_path, element_name))
+
+    res = cli.run(project=project,
+                  project_config={'variables': {'cache-build-tree': False}},
+                  args=['build', element_name])
+    res.assert_success()
+
+    res = cli.run(project=project,
+                  project_config={'variables': {'cache-build-trees': True}},
+                  args=['workspace', 'open', element_name, workspace])
+    res.assert_success()
+    assert os.path.isdir(workspace)
+    assert not os.path.exists(os.path.join(workspace, "test.o"))