blob: c75744b2571eb3b3a7ad108e4da6ce6d299e0da7 [file] [log] [blame]
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Pylint doesn't play well with fixtures and dependency injection from pytest
# pylint: disable=redefined-outer-name
import os
import pytest
from buildstream import _yaml
from buildstream._testing import cli # pylint: disable=unused-import
from buildstream.exceptions import ErrorDomain, LoadErrorReason
DATA_DIR = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
"link",
)
#
# Test links to elements, this tests both specifying the link as
# the main target, and also as a dependency of the main target.
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("target", ["target.bst", "hello-link.bst"])
def test_simple_link(cli, tmpdir, datafiles, target):
project = os.path.join(str(datafiles), "simple")
checkoutdir = os.path.join(str(tmpdir), "checkout")
# Build, checkout
result = cli.run(project=project, args=["build", target])
result.assert_success()
result = cli.run(project=project, args=["artifact", "checkout", target, "--directory", checkoutdir])
result.assert_success()
# Check that the checkout contains the expected files from sub-sub-project
assert os.path.exists(os.path.join(checkoutdir, "hello.txt"))
#
# Test links to elements, this tests both specifying the link as
# the main target, and also as a dependency of the main target, while
# also using a conditional statement in the link
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("target", ["target.bst", "target-link.bst"])
@pytest.mark.parametrize("greeting,expected_file", [("hello", "hello.txt"), ("goodbye", "goodbye.txt")])
def test_conditional_link(cli, tmpdir, datafiles, target, greeting, expected_file):
project = os.path.join(str(datafiles), "conditional")
checkoutdir = os.path.join(str(tmpdir), "checkout")
# Build, checkout
result = cli.run(project=project, args=["-o", "greeting", greeting, "build", target])
result.assert_success()
result = cli.run(
project=project, args=["-o", "greeting", greeting, "artifact", "checkout", target, "--directory", checkoutdir]
)
result.assert_success()
# Check that the checkout contains the expected files from sub-sub-project
assert os.path.exists(os.path.join(checkoutdir, expected_file))
#
# Test links to junctions from local projects and subprojects
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
"target", ["target-local.bst", "target-nested.bst", "full-path-link.bst", "target-full-path.bst"]
)
def test_simple_junctions(cli, tmpdir, datafiles, target):
project = os.path.join(str(datafiles), "simple-junctions")
checkoutdir = os.path.join(str(tmpdir), "checkout")
# Build, checkout
result = cli.run(project=project, args=["build", target])
result.assert_success()
result = cli.run(project=project, args=["artifact", "checkout", target, "--directory", checkoutdir])
result.assert_success()
# Check that the checkout contains the expected files from sub-sub-project
assert os.path.exists(os.path.join(checkoutdir, "hello.txt"))
#
# Test links which resolve junction targets conditionally
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("greeting,expected_file", [("hello", "hello.txt"), ("goodbye", "goodbye.txt")])
def test_conditional_junctions(cli, tmpdir, datafiles, greeting, expected_file):
project = os.path.join(str(datafiles), "conditional-junctions")
checkoutdir = os.path.join(str(tmpdir), "checkout")
# Build, checkout
result = cli.run(project=project, args=["-o", "greeting", greeting, "build", "target.bst"])
result.assert_success()
result = cli.run(
project=project,
args=["-o", "greeting", greeting, "artifact", "checkout", "target.bst", "--directory", checkoutdir],
)
result.assert_success()
# Check that the checkout contains the expected files from sub-sub-project
assert os.path.exists(os.path.join(checkoutdir, expected_file))
#
# Tests links which refer to non-existing elements or junctions
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
"target,provenance",
[
# Target is a link to a non-existing local element
("link-target.bst", "link-target.bst [line 4 column 10]"),
# Target is a stack depending on a link to a non-existing local element
(
"depends-on-link-target.bst",
"link-target.bst [line 4 column 10]",
),
# Depends on non-existing subproject element, via a local link
(
"linked-local-junction-target.bst",
"linked-local-junction-target.bst [line 4 column 2]",
),
# Depends on non-existing subsubproject element, via a local link
(
"linked-nested-junction-target.bst",
"linked-nested-junction-target.bst [line 4 column 2]",
),
# Depends on an element via a link to a non-existing local junction
(
"linked-local-junction.bst",
"subproject-link-notfound.bst [line 4 column 10]",
),
# Depends on an element via a link to a non-existing subproject junction
(
"linked-nested-junction.bst",
"subsubproject-link-notfound.bst [line 4 column 10]",
),
# Target is a link to a non-existing nested element referred to with a full path
("link-full-path.bst", "link-full-path.bst [line 4 column 10]"),
# Target depends on a link to a non-existing nested element referred to with a full path
("target-full-path.bst", "link-full-path.bst [line 4 column 10]"),
],
)
def test_link_not_found(cli, tmpdir, datafiles, target, provenance):
project = os.path.join(str(datafiles), "notfound")
result = cli.run(project=project, args=["build", target])
result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.MISSING_FILE)
assert provenance in result.stderr
#
# Tests links with invalid configurations
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize(
"target,expected_error,expected_reason",
[
# Test link which declares sources, either directly of via a dependency
("link-with-sources.bst", ErrorDomain.ELEMENT, "element-forbidden-sources"),
("target-link-with-sources.bst", ErrorDomain.ELEMENT, "element-forbidden-sources"),
# Test link which declares dependencies, either directly of via a dependency
("link-with-dependencies.bst", ErrorDomain.LOAD, LoadErrorReason.LINK_FORBIDDEN_DEPENDENCIES),
],
)
def test_link_invalid_config(cli, tmpdir, datafiles, target, expected_error, expected_reason):
project = os.path.join(str(datafiles), "invalid")
result = cli.run(project=project, args=["show", target])
result.assert_main_error(expected_error, expected_reason)
#
# Test including files across the boundry a link to a subproject's junction
#
@pytest.mark.datafiles(DATA_DIR)
def test_cross_link_junction_include(cli, tmpdir, datafiles):
project = os.path.join(str(datafiles), "cross-link-junction-include")
# Show the variables and parse our test variable from the subsubproject
result = cli.run(project=project, args=["show", "--format", "%{vars}", "target.bst"])
result.assert_success()
# Read back some of our project defaults from the env
variables = _yaml.load_data(result.output)
assert variables.get_str("test") == "the test"