blob: 494b7e9927f9cc4051d783f13369e54555738eb8 [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_integration as cli # pylint: disable=unused-import
from buildstream._testing._utils.site import HAVE_SANDBOX, BUILDBOX_RUN
pytestmark = pytest.mark.integration
DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project")
def create_script_element(name, path, config=None, variables=None):
if config is None:
config = {}
if variables is None:
variables = {}
element = {
"kind": "script",
"depends": [{"filename": "base.bst", "type": "build"}],
"config": config,
"variables": variables,
}
os.makedirs(os.path.dirname(os.path.join(path, name)), exist_ok=True)
_yaml.roundtrip_dump(element, os.path.join(path, name))
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
def test_script(cli, datafiles):
project = str(datafiles)
checkout = os.path.join(cli.directory, "checkout")
element_path = os.path.join(project, "elements")
element_name = "script/script-layout.bst"
create_script_element(
element_name,
element_path,
config={
"commands": ["mkdir -p %{install-root}", "echo 'Hi' > %{install-root}/test"],
},
)
res = cli.run(project=project, args=["build", element_name])
assert res.exit_code == 0
res = cli.run(project=project, args=["artifact", "checkout", element_name, "--directory", checkout])
assert res.exit_code == 0
with open(os.path.join(checkout, "test"), encoding="utf-8") as f:
text = f.read()
assert text == "Hi\n"
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
@pytest.mark.xfail(
HAVE_SANDBOX == "buildbox-run" and BUILDBOX_RUN == "buildbox-run-userchroot",
reason="Root directory not writable with userchroot",
)
def test_script_root(cli, datafiles):
project = str(datafiles)
checkout = os.path.join(cli.directory, "checkout")
element_path = os.path.join(project, "elements")
element_name = "script/script-layout.bst"
create_script_element(
element_name,
element_path,
config={
# Root-read only is False by default, we
# want to check the default here
# 'root-read-only': False,
"commands": ["mkdir -p %{install-root}", "echo 'I can write to root' > /test", "cp /test %{install-root}"],
},
)
res = cli.run(project=project, args=["build", element_name])
assert res.exit_code == 0
res = cli.run(project=project, args=["artifact", "checkout", element_name, "--directory", checkout])
assert res.exit_code == 0
with open(os.path.join(checkout, "test"), encoding="utf-8") as f:
text = f.read()
assert text == "I can write to root\n"
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
def test_script_no_root(cli, datafiles):
project = str(datafiles)
element_path = os.path.join(project, "elements")
element_name = "script/script-layout.bst"
create_script_element(
element_name,
element_path,
config={
"root-read-only": True,
"commands": [
"mkdir -p %{install-root}",
"echo 'I can not write to root' > /test",
"cp /test %{install-root}",
],
},
)
res = cli.run(project=project, args=["build", element_name])
assert res.exit_code != 0
assert "/test: Read-only file system" in res.stderr or "/test: Permission denied" in res.stderr
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
def test_script_cwd(cli, datafiles):
project = str(datafiles)
checkout = os.path.join(cli.directory, "checkout")
element_path = os.path.join(project, "elements")
element_name = "script/script-layout.bst"
create_script_element(
element_name,
element_path,
config={
"commands": ["echo 'test' > test", "cp /buildstream/test %{install-root}"],
},
variables={"cwd": "/buildstream"},
)
res = cli.run(project=project, args=["build", element_name])
assert res.exit_code == 0
res = cli.run(project=project, args=["artifact", "checkout", element_name, "--directory", checkout])
assert res.exit_code == 0
with open(os.path.join(checkout, "test"), encoding="utf-8") as f:
text = f.read()
assert text == "test\n"
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
def test_script_layout(cli, datafiles):
project = str(datafiles)
checkout = os.path.join(cli.directory, "checkout")
element_name = "script/script-layout.bst"
res = cli.run(project=project, args=["build", element_name])
assert res.exit_code == 0
cli.run(project=project, args=["artifact", "checkout", element_name, "--directory", checkout])
assert res.exit_code == 0
with open(os.path.join(checkout, "test"), encoding="utf-8") as f:
text = f.read()
assert text == "Hi\n"
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
@pytest.mark.xfail(
HAVE_SANDBOX == "buildbox-run" and BUILDBOX_RUN == "buildbox-run-userchroot",
reason="Root directory not writable with userchroot",
)
def test_regression_cache_corruption(cli, datafiles):
project = str(datafiles)
checkout_original = os.path.join(cli.directory, "checkout-original")
checkout_after = os.path.join(cli.directory, "checkout-after")
element_name = "script/corruption.bst"
canary_element_name = "script/corruption-image.bst"
res = cli.run(project=project, args=["build", canary_element_name])
assert res.exit_code == 0
res = cli.run(
project=project, args=["artifact", "checkout", canary_element_name, "--directory", checkout_original]
)
assert res.exit_code == 0
with open(os.path.join(checkout_original, "canary"), encoding="utf-8") as f:
assert f.read() == "alive\n"
res = cli.run(project=project, args=["build", element_name])
assert res.exit_code == 0
res = cli.run(project=project, args=["artifact", "checkout", canary_element_name, "--directory", checkout_after])
assert res.exit_code == 0
with open(os.path.join(checkout_after, "canary"), encoding="utf-8") as f:
assert f.read() == "alive\n"
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
def test_regression_tmpdir(cli, datafiles):
project = str(datafiles)
element_name = "script/tmpdir.bst"
res = cli.run(project=project, args=["build", element_name])
assert res.exit_code == 0
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
@pytest.mark.xfail(
HAVE_SANDBOX == "buildbox-run" and BUILDBOX_RUN == "buildbox-run-userchroot",
reason="Root directory not writable with userchroot",
)
def test_regression_cache_corruption_2(cli, datafiles):
project = str(datafiles)
checkout_original = os.path.join(cli.directory, "checkout-original")
checkout_after = os.path.join(cli.directory, "checkout-after")
element_name = "script/corruption-2.bst"
canary_element_name = "script/corruption-image.bst"
res = cli.run(project=project, args=["build", canary_element_name])
assert res.exit_code == 0
res = cli.run(
project=project, args=["artifact", "checkout", canary_element_name, "--directory", checkout_original]
)
assert res.exit_code == 0
with open(os.path.join(checkout_original, "canary"), encoding="utf-8") as f:
assert f.read() == "alive\n"
res = cli.run(project=project, args=["build", element_name])
assert res.exit_code == 0
res = cli.run(project=project, args=["artifact", "checkout", canary_element_name, "--directory", checkout_after])
assert res.exit_code == 0
with open(os.path.join(checkout_after, "canary"), encoding="utf-8") as f:
assert f.read() == "alive\n"