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 2022/02/23 05:38:05 UTC

[buildstream] 01/01: tests/frontend/buildcheckout.py: Testing strict/non-strict scenario

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

tvb pushed a commit to branch tristan/weak-cache-key-test
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit aaa0053e7205edcd2b93c6063aa9e7e15bb8bc24
Author: Tristan van Berkom <tr...@codethink.co.uk>
AuthorDate: Wed Feb 23 14:20:07 2022 +0900

    tests/frontend/buildcheckout.py: Testing strict/non-strict scenario
    
    Added a test to check the expected behaviors after building and changing
    the strictness of a dependency in the build graph.
    
    This ensures stronger reliability of the behavior change resulting from
    the fix of #1270
---
 tests/frontend/buildcheckout.py                    | 67 ++++++++++++++++++++++
 tests/frontend/strict-scenario/elements/base.bst   |  5 ++
 tests/frontend/strict-scenario/elements/target.bst |  9 +++
 tests/frontend/strict-scenario/files/base.txt      |  1 +
 tests/frontend/strict-scenario/files/target.txt    |  1 +
 tests/frontend/strict-scenario/project.conf        |  3 +
 6 files changed, 86 insertions(+)

diff --git a/tests/frontend/buildcheckout.py b/tests/frontend/buildcheckout.py
index b25e313..2734f75 100644
--- a/tests/frontend/buildcheckout.py
+++ b/tests/frontend/buildcheckout.py
@@ -5,6 +5,7 @@ import os
 import tarfile
 import hashlib
 import re
+import shutil
 
 import pytest
 
@@ -1108,3 +1109,69 @@ def test_fail_no_args(datafiles, cli):
     result = cli.run(project=project, args=["artifact", "checkout"])
     result.assert_main_error(ErrorDomain.APP, None)
     assert "Missing argument" in result.stderr
+
+
+# This test reproduces a scenario where BuildStream can get confused
+# if the strictness of a dependency is not taken into account in the
+# strong artifact cache key, as reported in issue #1270.
+#
+# While we were unable to reproduce the exact experience, we can test
+# the expected behavior.
+#
+STRICT_DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "strict-scenario",)
+
+
+@pytest.mark.datafiles(STRICT_DATA_DIR)
+def test_changing_strict_dependency_scenario(datafiles, cli):
+    project = str(datafiles)
+    checkout = os.path.join(cli.directory, "checkout")
+    target_path = os.path.join(project, "elements", "target.bst")
+
+    # Function to (re)write the target element so that it depends
+    # on the base.bst element strictly or non-strictly
+    #
+    def configure_target(strict):
+        dependency = {"filename": "base.bst"}
+        if strict:
+            dependency["strict"] = True
+        config = {
+            "kind": "import",
+            "depends": [dependency],
+            "sources": [{"kind": "local", "path": "files/target.txt"}],
+        }
+        _yaml.roundtrip_dump(config, target_path)
+
+    # First build where the target normally depends on the base element
+    configure_target(False)
+    result = cli.run(project=project, args=["build", "target.bst"])
+    result.assert_success()
+
+    # Now configure the target to *strictly* depend on the base, try to check it out
+    #
+    # This will fail in both strict more or non-strict mode, as the strictness of the
+    # dependency will affect both keys.
+    configure_target(True)
+    result = cli.run(project=project, args=["artifact", "checkout", "--directory", checkout, "target.bst"])
+    result.assert_main_error(ErrorDomain.STREAM, "uncached-checkout-attempt")
+    shutil.rmtree(checkout)
+
+    result = cli.run(
+        project=project, args=["--no-strict", "artifact", "checkout", "--directory", checkout, "target.bst"]
+    )
+    result.assert_main_error(ErrorDomain.STREAM, "uncached-checkout-attempt")
+    shutil.rmtree(checkout)
+
+    # Now perform a build on the newly strict dependency, which should cause it to be
+    # available under both strict and non-strict checkout scenarios
+    result = cli.run(project=project, args=["build", "target.bst"])
+    result.assert_success()
+
+    result = cli.run(project=project, args=["artifact", "checkout", "--directory", checkout, "target.bst"])
+    result.assert_success()
+    shutil.rmtree(checkout)
+
+    result = cli.run(
+        project=project, args=["--no-strict", "artifact", "checkout", "--directory", checkout, "target.bst"]
+    )
+    result.assert_success()
+    shutil.rmtree(checkout)
diff --git a/tests/frontend/strict-scenario/elements/base.bst b/tests/frontend/strict-scenario/elements/base.bst
new file mode 100644
index 0000000..4e55b7c
--- /dev/null
+++ b/tests/frontend/strict-scenario/elements/base.bst
@@ -0,0 +1,5 @@
+kind: import
+
+sources:
+- kind: local
+  path: files/base.txt
diff --git a/tests/frontend/strict-scenario/elements/target.bst b/tests/frontend/strict-scenario/elements/target.bst
new file mode 100644
index 0000000..fbb090e
--- /dev/null
+++ b/tests/frontend/strict-scenario/elements/target.bst
@@ -0,0 +1,9 @@
+kind: import
+
+depends:
+- filename: base.bst
+  strict: true
+
+sources:
+- kind: local
+  path: files/target.txt
diff --git a/tests/frontend/strict-scenario/files/base.txt b/tests/frontend/strict-scenario/files/base.txt
new file mode 100644
index 0000000..f621448
--- /dev/null
+++ b/tests/frontend/strict-scenario/files/base.txt
@@ -0,0 +1 @@
+pony
diff --git a/tests/frontend/strict-scenario/files/target.txt b/tests/frontend/strict-scenario/files/target.txt
new file mode 100644
index 0000000..063dad6
--- /dev/null
+++ b/tests/frontend/strict-scenario/files/target.txt
@@ -0,0 +1 @@
+horsy
diff --git a/tests/frontend/strict-scenario/project.conf b/tests/frontend/strict-scenario/project.conf
new file mode 100644
index 0000000..1e02cb8
--- /dev/null
+++ b/tests/frontend/strict-scenario/project.conf
@@ -0,0 +1,3 @@
+name: test
+element-path: elements
+min-version: 2.0