summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Maat <tristan.maat@codethink.co.uk>2017-12-20 12:09:47 +0000
committerTristan Maat <tristan.maat@codethink.co.uk>2018-02-07 13:03:28 +0000
commitcb71d0f69c62679b1ce9dd5e8256e4cea86f6cf6 (patch)
tree6010a4d518972975d6be1f0026cc1a5955181c1a
parente4e713ee0860f3de5a7dec4487e01f5d1d6dd0bb (diff)
downloadbuildstream-cb71d0f69c62679b1ce9dd5e8256e4cea86f6cf6.tar.gz
Migrate element test files
-rw-r--r--integration-tests/elements/autotools.py48
-rw-r--r--integration-tests/elements/cmake.py59
-rw-r--r--integration-tests/elements/compose.py100
-rw-r--r--integration-tests/elements/import.py56
-rw-r--r--integration-tests/elements/manual.py130
-rw-r--r--integration-tests/elements/pip.py63
-rw-r--r--integration-tests/elements/project/elements/autotools/amhello.bst10
-rw-r--r--integration-tests/elements/project/elements/base.bst6
-rw-r--r--integration-tests/elements/project/elements/base/base-sdk.bst18
-rw-r--r--integration-tests/elements/project/elements/base/usermerge.bst6
-rw-r--r--integration-tests/elements/project/elements/cmake/step7.bst10
-rw-r--r--integration-tests/elements/project/elements/compose/amhello.bst11
-rw-r--r--integration-tests/elements/project/elements/compose/test.bst10
-rw-r--r--integration-tests/elements/project/elements/script/script-layout.bst23
-rw-r--r--integration-tests/elements/project/elements/script/script.bst10
-rw-r--r--integration-tests/elements/project/elements/stack/another-hi.bst11
-rw-r--r--integration-tests/elements/project/elements/stack/hi.bst8
-rw-r--r--integration-tests/elements/project/elements/stack/stack.bst5
-rw-r--r--integration-tests/elements/project/files/amhello.tar.gzbin0 -> 30555 bytes
-rw-r--r--integration-tests/elements/project/files/hello.tar.xzbin0 -> 628 bytes
-rw-r--r--integration-tests/elements/project/files/import-source/subdir/test.txt1
-rw-r--r--integration-tests/elements/project/files/import-source/test.txt1
-rw-r--r--integration-tests/elements/project/files/step7.tar.gzbin0 -> 2742 bytes
-rw-r--r--integration-tests/elements/project/files/usrmerge.tar.xzbin0 -> 252 bytes
-rw-r--r--integration-tests/elements/project/keys/gnome-sdk.gpgbin0 -> 629 bytes
-rw-r--r--integration-tests/elements/project/project.conf16
-rw-r--r--integration-tests/elements/script.py156
-rw-r--r--integration-tests/elements/stack.py36
28 files changed, 794 insertions, 0 deletions
diff --git a/integration-tests/elements/autotools.py b/integration-tests/elements/autotools.py
new file mode 100644
index 000000000..d9ee6a831
--- /dev/null
+++ b/integration-tests/elements/autotools.py
@@ -0,0 +1,48 @@
+import os
+import pytest
+
+from tests.testutils import cli_integration as cli
+from tests.testutils.integration import format_files, assert_contains
+
+
+DATA_DIR = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ "project"
+)
+
+
+# Test that an autotools build 'works' - we use the autotools sample
+# amhello project for this.
+@pytest.mark.datafiles(DATA_DIR)
+def test_autotools_build(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ checkout = os.path.join(cli.directory, 'checkout')
+ element_path = os.path.join(project, 'elements')
+ element_name = 'autotools/amhello.bst'
+
+ result = cli.run(project=project, args=['build', element_name])
+ assert result.exit_code == 0
+
+ result = cli.run(project=project, args=['checkout', element_name, checkout])
+ assert result.exit_code == 0
+
+ assert_contains(checkout, ['/usr', '/usr/lib', '/usr/bin',
+ '/usr/share', '/usr/lib/debug',
+ '/usr/lib/debug/hello', '/usr/bin/hello',
+ '/usr/share/doc', '/usr/share/doc/amhello',
+ '/usr/share/doc/amhello/README'])
+
+
+# Test running an executable built with autotools
+@pytest.mark.datafiles(DATA_DIR)
+def test_autotools_run(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element_path = os.path.join(project, 'elements')
+ element_name = 'autotools/amhello.bst'
+
+ result = cli.run(project=project, args=['build', element_name])
+ assert result.exit_code == 0
+
+ result = cli.run(project=project, args=['shell', element_name, '/usr/bin/hello'])
+ assert result.exit_code == 0
+ assert result.output == 'Hello World!\nThis is amhello 1.0.\n'
diff --git a/integration-tests/elements/cmake.py b/integration-tests/elements/cmake.py
new file mode 100644
index 000000000..17b8f8f8a
--- /dev/null
+++ b/integration-tests/elements/cmake.py
@@ -0,0 +1,59 @@
+import os
+import pytest
+
+from tests.testutils import cli_integration as cli
+from tests.testutils.integration import format_files, assert_contains
+
+
+DATA_DIR = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ "project"
+)
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_cmake_build(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ checkout = os.path.join(cli.directory, 'checkout')
+ element_path = os.path.join(project, 'elements')
+ element_name = 'cmake/step7.bst'
+
+ result = cli.run(project=project, args=['build', element_name])
+ assert result.exit_code == 0
+
+ result = cli.run(project=project, args=['checkout', element_name, checkout])
+ assert result.exit_code == 0
+
+ assert_contains(checkout, ['/usr', '/usr/bin', '/usr/include',
+ '/usr/lib', '/usr/bin/libMathFunctions.a',
+ '/usr/bin/Tutorial',
+ '/usr/include/MathFunctions.h',
+ '/usr/include/TutorialConfig.h',
+ '/usr/lib/debug',
+ '/usr/lib/debug/Tutorial'])
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_cmake_run(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element_path = os.path.join(project, 'elements')
+ element_name = 'cmake/step7.bst'
+
+ result = cli.run(project=project, args=['build', element_name])
+ assert result.exit_code == 0
+
+ result = cli.run(project=project, args=['shell', element_name, '/usr/bin/Tutorial', '9'])
+ assert result.exit_code == 0
+
+ assert result.output == """Computing sqrt of 9 to be 3
+Computing sqrt of 9 to be 3
+Computing sqrt of 9 to be 3
+Computing sqrt of 9 to be 3
+Computing sqrt of 9 to be 3
+Computing sqrt of 9 to be 3
+Computing sqrt of 9 to be 3
+Computing sqrt of 9 to be 3
+Computing sqrt of 9 to be 3
+Computing sqrt of 9 to be 3
+The square root of 9 is 3
+"""
diff --git a/integration-tests/elements/compose.py b/integration-tests/elements/compose.py
new file mode 100644
index 000000000..b7d96f979
--- /dev/null
+++ b/integration-tests/elements/compose.py
@@ -0,0 +1,100 @@
+import io
+import os
+import sys
+import pytest
+
+from buildstream import _yaml
+
+from tests.testutils import cli_integration as cli
+from tests.testutils.integration import format_files, walk_dir
+
+
+DATA_DIR = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ "project"
+)
+
+
+def create_compose_element(name, path, config={}):
+ element = {
+ 'kind': 'compose',
+ 'depends': [{
+ 'filename': 'compose/amhello.bst',
+ 'type': 'build'
+ }, {
+ 'filename': 'compose/test.bst',
+ 'type': 'build'
+ }],
+ 'config': config
+ }
+ os.makedirs(os.path.dirname(os.path.join(path, name)), exist_ok=True)
+ _yaml.dump(element, os.path.join(path, name))
+
+
+@pytest.mark.datafiles(DATA_DIR)
+@pytest.mark.parametrize("include_domains,exclude_domains,expected", [
+ # Test flat inclusion
+ ([], [], ['/usr', '/usr/lib', '/usr/bin',
+ '/usr/share', '/usr/lib/debug',
+ '/usr/lib/debug/hello', '/usr/bin/hello',
+ '/usr/share/doc', '/usr/share/doc/amhello',
+ '/usr/share/doc/amhello/README',
+ '/tests', '/tests/test']),
+ # Test only runtime
+ (['runtime'], [], ['/usr', '/usr/lib', '/usr/share',
+ '/usr/bin', '/usr/bin/hello']),
+ # Test with runtime and doc
+ (['runtime', 'doc'], [], ['/usr', '/usr/lib', '/usr/share',
+ '/usr/bin', '/usr/bin/hello',
+ '/usr/share/doc', '/usr/share/doc/amhello',
+ '/usr/share/doc/amhello/README']),
+ # Test with only runtime excluded
+ ([], ['runtime'], ['/usr', '/usr/lib', '/usr/share',
+ '/usr/lib/debug', '/usr/lib/debug/hello',
+ '/usr/share/doc', '/usr/share/doc/amhello',
+ '/usr/share/doc/amhello/README',
+ '/tests', '/tests/test']),
+ # Test with runtime and doc excluded
+ ([], ['runtime', 'doc'], ['/usr', '/usr/lib', '/usr/share',
+ '/usr/lib/debug', '/usr/lib/debug/hello',
+ '/tests', '/tests/test']),
+ # Test with runtime simultaneously in- and excluded
+ (['runtime'], ['runtime'], ['/usr', '/usr/lib', '/usr/share']),
+ # Test with runtime included and doc excluded
+ (['runtime'], ['doc'], ['/usr', '/usr/lib', '/usr/share',
+ '/usr/bin', '/usr/bin/hello']),
+ # Test including a custom 'test' domain
+ (['test'], [], ['/usr', '/usr/lib', '/usr/share',
+ '/tests', '/tests/test']),
+ # Test excluding a custom 'test' domain
+ ([], ['test'], ['/usr', '/usr/lib', '/usr/bin',
+ '/usr/share', '/usr/lib/debug',
+ '/usr/lib/debug/hello', '/usr/bin/hello',
+ '/usr/share/doc', '/usr/share/doc/amhello',
+ '/usr/share/doc/amhello/README'])
+])
+def test_compose_include(cli, tmpdir, datafiles, include_domains,
+ exclude_domains, expected):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ checkout = os.path.join(cli.directory, 'checkout')
+ element_path = os.path.join(project, 'elements')
+ element_name = 'compose/compose-amhello.bst'
+
+ # Create a yaml configuration from the specified include and
+ # exclude domains
+ config = {
+ 'include': include_domains,
+ 'exclude': exclude_domains
+ }
+ create_compose_element(element_name, element_path, config=config)
+
+ result = cli.run(project=project, args=['track', 'compose/amhello.bst'])
+ assert result.exit_code == 0
+
+ result = cli.run(project=project, args=['build', element_name])
+ assert result.exit_code == 0
+
+ result = cli.run(project=project, args=['checkout', element_name, checkout])
+ assert result.exit_code == 0
+
+ assert set(walk_dir(checkout)) == set(expected)
diff --git a/integration-tests/elements/import.py b/integration-tests/elements/import.py
new file mode 100644
index 000000000..3a79daef2
--- /dev/null
+++ b/integration-tests/elements/import.py
@@ -0,0 +1,56 @@
+import os
+import pytest
+
+from buildstream import _yaml
+
+from tests.testutils import cli_integration as cli
+from tests.testutils.integration import format_files, walk_dir
+
+
+DATA_DIR = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ "project"
+)
+
+
+def create_import_element(name, path, source, target, source_path):
+ element = {
+ 'kind': 'import',
+ 'sources': [{
+ 'kind': 'local',
+ 'path': source_path
+ }],
+ 'config': {
+ 'source': source,
+ 'target': target
+ }
+ }
+ os.makedirs(os.path.dirname(os.path.join(path, name)), exist_ok=True)
+ _yaml.dump(element, os.path.join(path, name))
+
+
+@pytest.mark.datafiles(DATA_DIR)
+@pytest.mark.parametrize("source,target,path,expected", [
+ ('/', '/', 'files/import-source', ['/test.txt', '/subdir',
+ '/subdir/test.txt']),
+ ('/subdir', '/', 'files/import-source', ['/test.txt']),
+ ('/', '/', 'files/import-source/subdir', ['/test.txt']),
+ ('/', '/output', 'files/import-source', ['/output', '/output/test.txt',
+ '/output/subdir',
+ '/output/subdir/test.txt']),
+])
+def test_import(cli, tmpdir, datafiles, source, target, path, expected):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ checkout = os.path.join(cli.directory, 'checkout')
+ element_path = os.path.join(project, 'elements')
+ element_name = 'import/import.bst'
+
+ create_import_element(element_name, element_path, source, target, path)
+
+ res = cli.run(project=project, args=['build', element_name])
+ assert res.exit_code == 0
+
+ cli.run(project=project, args=['checkout', element_name, checkout])
+ assert res.exit_code == 0
+
+ assert set(walk_dir(checkout)) == set(expected)
diff --git a/integration-tests/elements/manual.py b/integration-tests/elements/manual.py
new file mode 100644
index 000000000..76b5a010a
--- /dev/null
+++ b/integration-tests/elements/manual.py
@@ -0,0 +1,130 @@
+import os
+import pytest
+
+from buildstream import _yaml
+
+from tests.testutils import cli_integration as cli
+from tests.testutils.integration import format_files, walk_dir
+
+
+DATA_DIR = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ "project"
+)
+
+
+def create_manual_element(name, path, config, variables, environment):
+ element = {
+ 'kind': 'manual',
+ 'depends': [{
+ 'filename': 'base.bst',
+ 'type': 'build'
+ }],
+ 'config': config,
+ 'variables': variables,
+ 'environment': environment
+ }
+ os.makedirs(os.path.dirname(os.path.join(path, name)), exist_ok=True)
+ _yaml.dump(element, os.path.join(path, name))
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_manual_element(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ checkout = os.path.join(cli.directory, 'checkout')
+ element_path = os.path.join(project, 'elements')
+ element_name = 'import/import.bst'
+
+ create_manual_element(element_name, element_path, {
+ 'configure-commands': ["echo './configure' >> test"],
+ 'build-commands': ["echo 'make' >> test"],
+ 'install-commands': [
+ "echo 'make install' >> test",
+ "cp test %{install-root}"
+ ],
+ 'strip-commands': ["echo 'strip' >> %{install-root}/test"]
+ }, {}, {})
+
+ res = cli.run(project=project, args=['build', element_name])
+ assert res.exit_code == 0
+
+ cli.run(project=project, args=['checkout', element_name, checkout])
+ assert res.exit_code == 0
+
+ with open(os.path.join(checkout, 'test')) as f:
+ text = f.read()
+
+ assert text == """./configure
+make
+make install
+strip
+"""
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_manual_element_noparallel(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ checkout = os.path.join(cli.directory, 'checkout')
+ element_path = os.path.join(project, 'elements')
+ element_name = 'import/import.bst'
+
+ create_manual_element(element_name, element_path, {
+ 'install-commands': [
+ "echo $MAKEFLAGS >> test",
+ "echo $V >> test",
+ "cp test %{install-root}"
+ ]
+ }, {
+ 'max-jobs': 2,
+ 'notparallel': True
+ }, {
+ 'MAKEFLAGS': '-j%{max-jobs} -Wall',
+ 'V': 2
+ })
+
+ res = cli.run(project=project, args=['build', element_name])
+ assert res.exit_code == 0
+
+ cli.run(project=project, args=['checkout', element_name, checkout])
+ assert res.exit_code == 0
+
+ with open(os.path.join(checkout, 'test')) as f:
+ text = f.read()
+
+ assert text == """-j1 -Wall
+2
+"""
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_manual_element_environment(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ checkout = os.path.join(cli.directory, 'checkout')
+ element_path = os.path.join(project, 'elements')
+ element_name = 'import/import.bst'
+
+ create_manual_element(element_name, element_path, {
+ 'install-commands': [
+ "echo $MAKEFLAGS >> test",
+ "echo $V >> test",
+ "cp test %{install-root}"
+ ]
+ }, {
+ 'max-jobs': 2
+ }, {
+ 'MAKEFLAGS': '-j%{max-jobs} -Wall',
+ 'V': 2
+ })
+
+ res = cli.run(project=project, args=['build', element_name])
+ assert res.exit_code == 0
+
+ cli.run(project=project, args=['checkout', element_name, checkout])
+ assert res.exit_code == 0
+
+ with open(os.path.join(checkout, 'test')) as f:
+ text = f.read()
+
+ assert text == """-j2 -Wall
+2
+"""
diff --git a/integration-tests/elements/pip.py b/integration-tests/elements/pip.py
new file mode 100644
index 000000000..c1fd656ec
--- /dev/null
+++ b/integration-tests/elements/pip.py
@@ -0,0 +1,63 @@
+import os
+import sys
+import pytest
+
+from buildstream import _yaml
+
+from tests.testutils import cli_integration as cli
+from tests.testutils.integration import assert_contains
+
+
+DATA_DIR = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ "project"
+)
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_pip_build(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ checkout = os.path.join(cli.directory, 'checkout')
+ element_path = os.path.join(project, 'elements')
+ element_name = 'pip/hello.bst'
+
+ element = {
+ 'kind': 'pip',
+ 'variables': {
+ 'pip': 'pip3'
+ },
+ 'depends': [{
+ 'filename': 'base.bst'
+ }],
+ 'sources': [{
+ 'kind': 'tar',
+ 'url': 'file://{}/files/hello.tar.xz'.format(project),
+ 'ref': 'ad96570b552498807abec33c06210bf68378d854ced6753b77916c5ed517610d'
+
+ }]
+ }
+ 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))
+
+ result = cli.run(project=project, args=['build', element_name])
+ assert result.exit_code == 0
+
+ result = cli.run(project=project, args=['checkout', element_name, checkout])
+ assert result.exit_code == 0
+
+ assert_contains(checkout, ['/usr', '/usr/lib', '/usr/bin',
+ '/usr/bin/hello', '/usr/lib/python3.5'])
+
+
+# Test running an executable built with pip
+@pytest.mark.datafiles(DATA_DIR)
+def test_pip_run(cli, tmpdir, datafiles):
+ # Create and build our test element
+ test_pip_build(cli, tmpdir, datafiles)
+
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element_name = 'pip/hello.bst'
+
+ result = cli.run(project=project, args=['shell', element_name, '/usr/bin/hello'])
+ assert result.exit_code == 0
+ assert result.output == 'Hello, world!\n'
diff --git a/integration-tests/elements/project/elements/autotools/amhello.bst b/integration-tests/elements/project/elements/autotools/amhello.bst
new file mode 100644
index 000000000..ee3a029d8
--- /dev/null
+++ b/integration-tests/elements/project/elements/autotools/amhello.bst
@@ -0,0 +1,10 @@
+kind: autotools
+description: Autotools test
+
+depends:
+- base.bst
+
+sources:
+- kind: tar
+ url: project_dir:/files/amhello.tar.gz
+ ref: 9ba123fa4e660929e9a0aa99f0c487b7eee59c5e7594f3284d015640b90f5590
diff --git a/integration-tests/elements/project/elements/base.bst b/integration-tests/elements/project/elements/base.bst
new file mode 100644
index 000000000..6f2c56fa9
--- /dev/null
+++ b/integration-tests/elements/project/elements/base.bst
@@ -0,0 +1,6 @@
+# elements/base.bst
+
+kind: stack
+depends:
+ - base/base-sdk.bst
+ - base/usermerge.bst
diff --git a/integration-tests/elements/project/elements/base/base-sdk.bst b/integration-tests/elements/project/elements/base/base-sdk.bst
new file mode 100644
index 000000000..6b7418e99
--- /dev/null
+++ b/integration-tests/elements/project/elements/base/base-sdk.bst
@@ -0,0 +1,18 @@
+kind: import
+description: Import the base freedesktop SDK
+(?):
+ - linux == True:
+ sources:
+ - kind: ostree
+ url: gnomesdk:repo/
+ gpg-key: keys/gnome-sdk.gpg
+ track: runtime/org.freedesktop.BaseSdk/x86_64/1.6
+ ref: 48b8c907522d3edeb0fb9f36c6515ce1ef5fb80a6e4e5dd54033b3fd6ad784d0
+ - linux == False:
+ sources:
+ - kind: tar
+ url: gnome7:tarballs/gnome-sdk.tar.xz
+ ref: 96d5062a19fa9ac3439f8a502664f8d46860bad7efd28e7909b03ddbcdbe66e6
+config:
+ source: files
+ target: usr
diff --git a/integration-tests/elements/project/elements/base/usermerge.bst b/integration-tests/elements/project/elements/base/usermerge.bst
new file mode 100644
index 000000000..d21702c12
--- /dev/null
+++ b/integration-tests/elements/project/elements/base/usermerge.bst
@@ -0,0 +1,6 @@
+kind: import
+description: Some symlinks for the flatpak runtime environment
+sources:
+ - kind: tar
+ url: project_dir:/files/usrmerge.tar.xz
+ ref: 14dd149ad8b177b0d8e42f1a4e522cb99a00ed666e2d70777e031a1ee6348265
diff --git a/integration-tests/elements/project/elements/cmake/step7.bst b/integration-tests/elements/project/elements/cmake/step7.bst
new file mode 100644
index 000000000..625bb8583
--- /dev/null
+++ b/integration-tests/elements/project/elements/cmake/step7.bst
@@ -0,0 +1,10 @@
+kind: cmake
+description: Cmake test
+
+depends:
+ - base.bst
+
+sources:
+ - kind: tar
+ url: project_dir:/files/step7.tar.gz
+ ref: 9591707afbae77751730b4af4c52a18b1cdc4378237bc64055f099bc95c330db
diff --git a/integration-tests/elements/project/elements/compose/amhello.bst b/integration-tests/elements/project/elements/compose/amhello.bst
new file mode 100644
index 000000000..bec7e312a
--- /dev/null
+++ b/integration-tests/elements/project/elements/compose/amhello.bst
@@ -0,0 +1,11 @@
+kind: autotools
+description: Autotools test
+
+depends:
+ - filename: base.bst
+ type: build
+
+sources:
+ - kind: tar
+ url: project_dir:/files/amhello.tar.gz
+ ref: 9ba123fa4e660929e9a0aa99f0c487b7eee59c5e7594f3284d015640b90f5590
diff --git a/integration-tests/elements/project/elements/compose/test.bst b/integration-tests/elements/project/elements/compose/test.bst
new file mode 100644
index 000000000..870dc7daa
--- /dev/null
+++ b/integration-tests/elements/project/elements/compose/test.bst
@@ -0,0 +1,10 @@
+kind: script
+
+depends:
+ - filename: base.bst
+ type: build
+
+config:
+ commands:
+ - "mkdir -p %{install-root}/tests"
+ - "echo 'This is a test' > %{install-root}/tests/test"
diff --git a/integration-tests/elements/project/elements/script/script-layout.bst b/integration-tests/elements/project/elements/script/script-layout.bst
new file mode 100644
index 000000000..11ca353e3
--- /dev/null
+++ b/integration-tests/elements/project/elements/script/script-layout.bst
@@ -0,0 +1,23 @@
+kind: script
+description: Write to root using a script element
+
+variables:
+ install-root: /buildstream/nstall
+ build-root: /buildstream/uild
+
+depends:
+ - filename: base.bst
+ type: build
+ - filename: script/script.bst
+ type: build
+
+config:
+ layout:
+ - element: base.bst
+ destination: /
+
+ - element: script/script.bst
+ destination: /buildstream/uild
+
+ commands:
+ - "cp %{build-root}/test %{install-root}"
diff --git a/integration-tests/elements/project/elements/script/script.bst b/integration-tests/elements/project/elements/script/script.bst
new file mode 100644
index 000000000..ffca23ab7
--- /dev/null
+++ b/integration-tests/elements/project/elements/script/script.bst
@@ -0,0 +1,10 @@
+kind: script
+description: Script test
+
+depends:
+ - filename: base.bst
+ type: build
+
+config:
+ commands:
+ - "echo 'Hi' > %{install-root}/test"
diff --git a/integration-tests/elements/project/elements/stack/another-hi.bst b/integration-tests/elements/project/elements/stack/another-hi.bst
new file mode 100644
index 000000000..eb98dea36
--- /dev/null
+++ b/integration-tests/elements/project/elements/stack/another-hi.bst
@@ -0,0 +1,11 @@
+kind: script
+description: Another hi test
+
+depends:
+ - filename: base.bst
+ type: build
+
+config:
+ commands:
+ - "mkdir -p /buildstream/install"
+ - "echo 'Another hi' > /buildstream/install/another-hi"
diff --git a/integration-tests/elements/project/elements/stack/hi.bst b/integration-tests/elements/project/elements/stack/hi.bst
new file mode 100644
index 000000000..adbf81537
--- /dev/null
+++ b/integration-tests/elements/project/elements/stack/hi.bst
@@ -0,0 +1,8 @@
+kind: script
+depends:
+ - filename: base.bst
+ type: build
+config:
+ commands:
+ - "mkdir -p /buildstream/install"
+ - "echo 'Hi' > /buildstream/install/hi"
diff --git a/integration-tests/elements/project/elements/stack/stack.bst b/integration-tests/elements/project/elements/stack/stack.bst
new file mode 100644
index 000000000..bbfc31ad4
--- /dev/null
+++ b/integration-tests/elements/project/elements/stack/stack.bst
@@ -0,0 +1,5 @@
+kind: stack
+description: Stack test
+depends:
+ - stack/hi.bst
+ - stack/another-hi.bst
diff --git a/integration-tests/elements/project/files/amhello.tar.gz b/integration-tests/elements/project/files/amhello.tar.gz
new file mode 100644
index 000000000..afe189908
--- /dev/null
+++ b/integration-tests/elements/project/files/amhello.tar.gz
Binary files differ
diff --git a/integration-tests/elements/project/files/hello.tar.xz b/integration-tests/elements/project/files/hello.tar.xz
new file mode 100644
index 000000000..72ec9b399
--- /dev/null
+++ b/integration-tests/elements/project/files/hello.tar.xz
Binary files differ
diff --git a/integration-tests/elements/project/files/import-source/subdir/test.txt b/integration-tests/elements/project/files/import-source/subdir/test.txt
new file mode 100644
index 000000000..d73906c87
--- /dev/null
+++ b/integration-tests/elements/project/files/import-source/subdir/test.txt
@@ -0,0 +1 @@
+This is another test
diff --git a/integration-tests/elements/project/files/import-source/test.txt b/integration-tests/elements/project/files/import-source/test.txt
new file mode 100644
index 000000000..0527e6bd2
--- /dev/null
+++ b/integration-tests/elements/project/files/import-source/test.txt
@@ -0,0 +1 @@
+This is a test
diff --git a/integration-tests/elements/project/files/step7.tar.gz b/integration-tests/elements/project/files/step7.tar.gz
new file mode 100644
index 000000000..f9643afce
--- /dev/null
+++ b/integration-tests/elements/project/files/step7.tar.gz
Binary files differ
diff --git a/integration-tests/elements/project/files/usrmerge.tar.xz b/integration-tests/elements/project/files/usrmerge.tar.xz
new file mode 100644
index 000000000..fa6131af8
--- /dev/null
+++ b/integration-tests/elements/project/files/usrmerge.tar.xz
Binary files differ
diff --git a/integration-tests/elements/project/keys/gnome-sdk.gpg b/integration-tests/elements/project/keys/gnome-sdk.gpg
new file mode 100644
index 000000000..8434b686c
--- /dev/null
+++ b/integration-tests/elements/project/keys/gnome-sdk.gpg
Binary files differ
diff --git a/integration-tests/elements/project/project.conf b/integration-tests/elements/project/project.conf
new file mode 100644
index 000000000..a677129fb
--- /dev/null
+++ b/integration-tests/elements/project/project.conf
@@ -0,0 +1,16 @@
+# Project config for frontend build test
+name: test
+element-path: elements
+aliases:
+ gnome7: https://gnome7.codethink.co.uk/
+ gnomesdk: https://sdk.gnome.org/
+ project_dir: file://{project_dir}
+options:
+ linux:
+ type: bool
+ description: Whether to expect a linux platform
+ default: True
+split-rules:
+ test:
+ - |
+ /tests/*
diff --git a/integration-tests/elements/script.py b/integration-tests/elements/script.py
new file mode 100644
index 000000000..f720d1ebb
--- /dev/null
+++ b/integration-tests/elements/script.py
@@ -0,0 +1,156 @@
+import os
+import pytest
+
+from buildstream import _yaml
+
+from tests.testutils import cli_integration as cli
+from tests.testutils.integration import format_files, walk_dir
+
+
+DATA_DIR = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ "project"
+)
+
+
+def create_script_element(name, path, config={}, 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.dump(element, os.path.join(path, name))
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_script(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ 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 /buildstream/install",
+ "echo 'Hi' > /buildstream/install/test"
+ ],
+ })
+
+ res = cli.run(project=project, args=['build', element_name])
+ assert res.exit_code == 0
+
+ res = cli.run(project=project, args=['checkout', element_name, checkout])
+ assert res.exit_code == 0
+
+ with open(os.path.join(checkout, 'test')) as f:
+ text = f.read()
+
+ assert text == "Hi\n"
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_script_root(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ 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 /buildstream/install",
+ "echo 'I can write to root' > /test",
+ "cp /test /buildstream/install"
+ ],
+ })
+
+ res = cli.run(project=project, args=['build', element_name])
+ assert res.exit_code == 0
+
+ res = cli.run(project=project, args=['checkout', element_name, checkout])
+ assert res.exit_code == 0
+
+ with open(os.path.join(checkout, 'test')) as f:
+ text = f.read()
+
+ assert text == "I can write to root\n"
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_script_no_root(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ 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 /buildstream/install",
+ "echo 'I can not write to root' > /test",
+ "cp /test /buildstream/install"
+ ],
+ })
+
+ res = cli.run(project=project, args=['build', element_name])
+ assert res.exit_code != 0
+
+ assert "sh: /test: Read-only file system" in res.stderr
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_script_cwd(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ 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=['checkout', element_name, checkout])
+ assert res.exit_code == 0
+
+ with open(os.path.join(checkout, 'test')) as f:
+ text = f.read()
+
+ assert text == "test\n"
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_script_layout(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ checkout = os.path.join(cli.directory, 'checkout')
+ element_path = os.path.join(project, 'elements')
+ 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=['checkout', element_name, checkout])
+ assert res.exit_code == 0
+
+ with open(os.path.join(checkout, 'test')) as f:
+ text = f.read()
+
+ assert text == "Hi\n"
diff --git a/integration-tests/elements/stack.py b/integration-tests/elements/stack.py
new file mode 100644
index 000000000..9650578de
--- /dev/null
+++ b/integration-tests/elements/stack.py
@@ -0,0 +1,36 @@
+import os
+import pytest
+
+from buildstream import _yaml
+
+from tests.testutils import cli_integration as cli
+from tests.testutils.integration import format_files, walk_dir
+
+
+DATA_DIR = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ "project"
+)
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_stack(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ checkout = os.path.join(cli.directory, 'checkout')
+ element_path = os.path.join(project, 'elements')
+ element_name = 'stack/stack.bst'
+
+ res = cli.run(project=project, args=['build', element_name])
+ assert res.exit_code == 0
+
+ cli.run(project=project, args=['checkout', element_name, checkout])
+ assert res.exit_code == 0
+
+ with open(os.path.join(checkout, 'hi')) as f:
+ hi = f.read()
+
+ with open(os.path.join(checkout, 'another-hi')) as f:
+ another_hi = f.read()
+
+ assert hi == "Hi\n"
+ assert another_hi == "Another hi\n"