abuild/tests/abuild_test
2024-11-14 07:56:32 +00:00

1415 lines
32 KiB
Plaintext
Executable File

#!/usr/bin/env atf-sh
. $(atf_get_srcdir)/test_env.sh
init_tests \
abuild_help \
abuild_invalid_opt \
abuild_version \
abuild_simple_pkg_without_deps \
abuild_build_fail \
abuild_invalid_filename \
abuild_usr_lib64 \
abuild_dbg_subpackage \
abuild_reproducible \
abuild_checksum_generation \
abuild_checksum_duplicates \
abuild_subpkg_dep_leak \
abuild_subpkg_libs \
abuild_py_providers_creation \
abuild_py_dependency_scan \
abuild_py_dependency_scan_conflict \
abuild_rpaths \
abuild_reject_init_with_improper_shebang \
abuild_valid_pkgnames \
abuild_invalid_pkgnames \
abuild_invalid_subpkgnames \
abuild_invalid_subpkg_version \
abuild_provide_pkgname \
abuild_validate_depends \
abuild_subpackage_arch \
abuild_large_doc_subpackage \
abuild_bigdocs \
abuild_pkgver_digit_letter_digit \
abuild_multiline_license \
abuild_license_spdx \
abuild_git_ceiling \
abuild_package_size \
abuild_keepdirs \
abuild_amove \
abuild_doc \
abuild_dev \
abuild_devhelp_warn \
abuild_devhelp \
abuild_check_maintainer \
abuild_cleanoldpkg \
abuild_path_with_spaces \
abuild_pyc_warn \
abuild_pyc \
abuild_setcap_binary \
abuild_setcap_binary_with_option \
abuild_command_provides \
abuild_gocache_dir \
abuild_cargo_home_dir \
abuild_fish_comp_split \
abuild_deps \
abuild_usr_merge
export ABUILD_SHAREDIR=$(atf_get_srcdir)/..
export ABUILD_CONF=/dev/null
export ABUILD_APK_INDEX_OPTS="--allow-untrusted"
export GIT_CONFIG_GLOBAL="$(atf_get_srcdir)/testdata/gitconfig"
export REPODEST="$PWD"/packages
testrepo=$(atf_get_srcdir)/testrepo
# copy keys
init_keys() {
cp -ra "$(atf_get_srcdir)"/testdata/.abuild "$PWD"
}
abuild_help_body() {
atf_check -s exit:0 \
-o match:"usage:" \
abuild -h
}
abuild_invalid_opt_body() {
atf_check -s exit:1 \
-e match:"usage:" \
abuild -@
}
abuild_version_body() {
atf_check -s exit:0 \
-o match:"abuild [0-9]+\.[0-9]+" \
abuild -V
}
abuild_simple_pkg_without_deps_body() {
init_keys
cp -r "$testrepo"/pkg1 .
cd pkg1
atf_check -s exit:0 -o ignore \
-e not-match:"WARNING" \
-e not-match:"fatal" \
abuild
}
abuild_build_fail_body() {
init_keys
mkdir buildfail
cat >buildfail/APKBUILD <<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="buildfail"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package that fails to build"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
subpackages="\$pkgname-dev \$pkgname-doc"
source=""
prepare() {
mkdir -p "\$builddir"
}
build() {
false
}
package() {
true
}
EOF
cd buildfail
atf_check -s exit:1 \
-e match:"ERROR: buildfail: build failed" \
abuild
}
abuild_invalid_filename_body() {
init_keys
mkdir invalid-filename
cd invalid-filename
cat >APKBUILD <<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="invalid-filename"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package that fails to build"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
prepare() {
mkdir -p "\$builddir"
}
build() {
touch $'bad\nfile'
}
check() {
true
}
package() {
mkdir -p "\$pkgdir"
cp -r * "\$pkgdir"/
}
EOF
atf_check -s exit:1 \
-e match:"ERROR:.*: Found filenames with newline" \
abuild
}
abuild_usr_lib64_body() {
init_keys
mkdir lib64test
cd lib64test
cat >APKBUILD <<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="lib64test"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
source=""
prepare() {
mkdir -p "\$builddir"
}
build() {
mkdir -p usr/lib64
}
check() {
true
}
package() {
mkdir -p "\$pkgdir"
cp -r * "\$pkgdir"/
}
EOF
atf_check -s exit:1 \
-e match:"ERROR:.*: Packages must not put anything under /usr/lib64" \
abuild
options=lib64 atf_check -s exit:0 \
-e match:"Build complete" \
abuild
}
abuild_dbg_subpackage_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/dbgpkg
atf_check -s exit:0 \
-o match:"hello world" \
-e match:"Build complete" \
abuild
cd ../..
arch=$(abuild -A)
tar -zxf "$REPODEST"/testrepo/$arch/dbgpkg-1.0-r0.apk \
|| atf_fail "failed to extract dbgpkg-1.0-r0.apk"
if [ -e usr/lib/debug ]; then
atf_fail "usr/lib/debug should not exist"
fi
debuginfo=$(readelf -wk usr/bin/hello | grep '^ Separate debug info file: [^/]*\.debug$')
debuginfo_file=${debuginfo#" Separate debug info file: "}
atf_check -s exit:0 \
-e match:"nm: usr/bin/hello: no symbols" \
nm usr/bin/hello
if ! [ usr/bin/hello -ef usr/bin/hello-hard ]; then
atf_fail 'hello is not a hardlink of hello-hard'
fi
rm -r usr
tar -xf "$REPODEST"/testrepo/$arch/dbgpkg-dbg-1.0-r0.apk
if [ -e usr/bin ]; then
atf_fail "usr/bin should not exist"
fi
find usr
atf_check -s exit:0 \
-o match:"T main" \
nm usr/lib/debug/usr/bin/$debuginfo_file
if [ -e usr/lib/debug/usr/bin/hello-sym.debug ]; then
atf_fail "usr/lib/debug/usr/bin/hello-sym.debug should not exist"
fi
if [ -e usr/lib/debug/usr/bin/hello.debug ] && [ -e usr/lib/debug/usr/bin/hello-hard.debug ]; then
atf_fail "only one of hello.debug and hello-hard.debug should exist"
fi
}
abuild_reproducible_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/pkg1
# set timestamp of APKBUILD to 1 min older than current time
touch -d @$(( $(date -u +%s) - 60)) APKBUILD
arch=$(abuild -A)
pkgs=$(abuild listpkg)
abuild || atf_fail "first build failed"
checksums=$(cd "$REPODEST"/testrepo/$arch && sha512sum $pkgs)
echo "$checksums"
rm -r "$REPODEST"/testrepo
abuild || atf_fail "rebuild failed"
checksums2=$(cd "$REPODEST"/testrepo/$arch && sha512sum $pkgs)
echo "$checksums2"
if [ "$checksums" != "$checksums2" ]; then
atf_fail "checksums does not match"
fi
}
abuild_checksum_generation_body() {
mkdir foo
cat > foo/APKBUILD <<-EOF
pkgname="foo"
pkgver="1.0"
source="test.txt"
EOF
echo "foo" > foo/test.txt
cd foo
abuild checksum || atf_fail "checksum generation failed"
( . ./APKBUILD && echo "$sha512sums" | sed '/^$/d' > sums )
cat sums
sha512sum -c sums || atf_fail "checksum mismatch"
}
abuild_checksum_duplicates_body() {
mkdir -p foo/dir1 foo/dir2
cat > foo/APKBUILD <<-EOF
pkgname="foo"
pkgver="1.0"
source="dir1/testfile dir2/testfile"
EOF
echo "first" > foo/dir1/testfile
echo "second" > foo/dir2/testfile
cd foo
atf_check -s exit:1 \
-e match:"ERROR:.*duplicate found" \
abuild checksum
}
abuild_subpkg_dep_leak_body() {
mkdir -p testrepo/subpkg-dep-leak
cd testrepo/subpkg-dep-leak
cat > APKBUILD <<-EOF
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname="subpkg-dep-leak"
pkgver=1.0
pkgrel=0
pkgdesc="Dummy test package with subpackages and dependencies"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
depends="tar scanelf"
license="MIT"
subpackages="\$pkgname-subpkg"
options="!check"
package() {
mkdir -p "\$pkgdir"
}
subpkg() {
depends="sed"
mkdir -p "\$subpkgdir"
}
EOF
abuild clean unpack prepare build rootpkg
grep 'depend = tar' pkg/.control.subpkg-dep-leak/.PKGINFO \
|| atf_fail "subpkg-dep-leak should depend on tar"
grep 'depend = scanelf' pkg/.control.subpkg-dep-leak/.PKGINFO \
|| atf_fail "subpkg-dep-leak should depend on scanelf"
! grep 'depend = sed' pkg/.control.subpkg-dep-leak/.PKGINFO \
|| atf_fail "subpkg-dep-leak should not depends on sed"
grep 'depend = sed' pkg/.control.subpkg-dep-leak-subpkg/.PKGINFO \
|| atf_fail "subpkg-dep-leak-subpkg should depend on sed"
! grep 'depend = tar' pkg/.control.subpkg-dep-leak-subpkg/.PKGINFO \
|| atf_fail "subpkg-dep-leak-subpkg should not depend on tar"
}
abuild_subpkg_libs_body() {
init_keys
mkdir -p testrepo/pkg
cd testrepo/pkg
cat > APKBUILD <<-EOF
maintainer="Natanael Copa <ncopa@alpinelinux.org>"
pkgname="pkg"
pkgver=1.0
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
subpackages="\$pkgname-libs"
options="!check"
package() {
mkdir -p "\$pkgdir"/usr/lib
touch "\$pkgdir"/usr/lib/libfoo.so.1
}
EOF
abuild clean unpack prepare build rootpkg || atf_fail "abuild failed"
if ! [ -e pkg/pkg-libs/usr/lib/libfoo.so.1 ]; then
find pkg
atf_fail "libfoo.so.1 was not moved"
fi
}
abuild_py_providers_creation_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/py3\ foo\ and\ bar
abuild rootpkg || atf_fail "abuild failed"
atf_check -s exit:0 \
-o match:"provides = py3.9:foo=1.0.0-r0" \
cat pkg/.control.py3-foo-and-bar/.PKGINFO
}
abuild_py_dependency_scan_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/py3\ foo\ and\ bar
abuild rootpkg || atf_fail "abuild failed"
atf_check -s exit:0 \
-o match:"depend = python3~3.9" \
cat pkg/.control.py3-foo-and-bar/.PKGINFO
}
abuild_py_dependency_scan_conflict_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/py3-conflicting-python-versions
atf_check -s exit:1 \
-e match:"ERROR.*package contains python3 modules for conflicting python3 versions" \
abuild rootpkg
}
abuild_rpaths_body() {
init_keys
mkdir -p bin
cat > bin/scanelf <<-EOF
#!/bin/sh
for i; do
[ "\$i" = --rpath ] || continue
echo "\$ABUILD_RPATH" /usr/lib/pkg/base.so
break
done
EOF
chmod +x bin/scanelf
PATH="$PWD/bin:$PATH"
mkdir -p testrepo/pkg
cd testrepo/pkg
cat > APKBUILD <<-EOF
maintainer="Natanael Copa <ncopa@alpinelinux.org>"
pkgname="pkg"
pkgver=1.0
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="all"
license="MIT"
options="!check !strip !textrels !archcheck"
package() {
mkdir -p "\$pkgdir"/usr/lib
touch "\$pkgdir"/usr/lib/libfoo.so.1
}
EOF
ABUILD_RPATH='/usr/lib/foo' abuild rootpkg || atf_fail "abuild failed"
atf_check -s exit:0 \
-o match:"/usr/lib/foo" \
cat pkg/.control.pkg/.rpaths
ABUILD_RPATH='$ORIGIN/bar:${ORIGIN}/../baf' pkgbasedir=$PWD/pkg abuild rootpkg || atf_fail "abuild failed"
atf_check -s exit:0 \
-o match:"/usr/lib/pkg/bar" \
-o match:"/usr/lib/pkg/../baf" \
cat pkg/.control.pkg/.rpaths
ABUILD_RPATH='/home/builder' atf_check -s exit:1 -o ignore \
-e match:"ERROR:.*: Has /home/... in rpath" abuild rootpkg
}
abuild_reject_init_with_improper_shebang_body() {
mkdir invalid-initd
cd invalid-initd
cat >APKBUILD<<-EOF
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname="invalid-initd"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
subpackages=""
source="test.initd"
prepare() {
mkdir -p "\$builddir"
}
EOF
cat >test.initd<<-EOF
#!/bin/sh
command="test"
EOF
abuild checksum
atf_check -s exit:1 \
-o match:"OK" \
-e match:"ERROR.*is not an openrc" \
abuild unpack
}
abuild_valid_pkgnames_body() {
cp -ra "$testrepo"/test-pkgname .
cd test-pkgname
atf_check -s exit:0 \
-e match:"Validating" \
abuild validate
TESTNAME=foo atf_check -s exit:0 \
-e match:"Validating" \
abuild validate
TESTSUBNAME=foo atf_check -s exit:0 \
-e match:"Validating" \
abuild validate
TESTNAME="more_+-2.0-complicated" atf_check -s exit:0 \
-e match:"Validating" \
abuild validate
}
abuild_invalid_pkgnames_body() {
init_keys
cp -ra "$testrepo"/test-pkgname .
cd test-pkgname
TESTNAME="" atf_check -s exit:1 \
-e match:"Validating" \
abuild validate
TESTNAME="-foo" atf_check -s exit:1 \
-e match:"Validating" \
abuild validate
TESTNAME="foo with spaces" atf_check -s exit:1 \
-e match:"Validating" \
abuild validate
TESTNAME="width@at" atf_check -s exit:1 \
-e match:"Validating" \
abuild validate
TESTNAME="width=equal" atf_check -s exit:1 \
-e match:"Validating" \
abuild validate
}
abuild_invalid_subpkgnames_body() {
init_keys
cp -ra "$testrepo"/test-pkgname .
cd test-pkgname
TESTSUBNAME="" atf_check -s exit:1 \
-e match:"Validating" \
abuild validate
TESTSUBNAME="-foo" atf_check -s exit:1 \
-e match:"Validating" \
abuild validate
}
abuild_invalid_subpkg_version_body() {
init_keys
cp -ra "$testrepo"/test-pkgname .
cd test-pkgname
TESTDEPVER="1.0-0" atf_check -s exit:1 \
-e match:"Invalid version" \
abuild all
}
abuild_provide_pkgname_body() {
init_keys
cp -ra "$testrepo"/test-pkgname .
cd test-pkgname
TESTNAME=provided atf_check -s exit:1 \
-e match:"provides must not contain" \
abuild validate
TESTNAME=test TESTPROVIDES='test~1' atf_check -s exit:1 \
-e match:"provides must not contain" \
abuild validate
TESTNAME=test TESTPROVIDES='test=1' atf_check -s exit:1 \
-e match:"provides must not contain" \
abuild validate
TESTNAME=test TESTPROVIDES='test>1' atf_check -s exit:1 \
-e match:"provides must not contain" \
abuild validate
TESTNAME=test TESTPROVIDES='test<=1' atf_check -s exit:1 \
-e match:"provides must not contain" \
abuild validate
}
abuild_validate_depends_body() {
init_keys
cp -ra "$testrepo"/test-pkgname .
cd test-pkgname
TESTDEPENDS="foo" TESTMAKEDEPENDS="bar" \
atf_check -s exit:0 \
-e match:"Validating" \
abuild validate
TESTDEPENDS="foo=1.0 bar>=1.0" TESTMAKEDEPENDS="baz<=1.0 x<2.0 z>1 !blah" \
atf_check -s exit:0 \
-e match:"Validating" \
abuild validate
TESTDEPENDS="foo~1.0 bar>~1.0 baz<~1"
atf_check -s exit:0 \
-e match:"Validating" \
abuild validate
for i in "foo=bar" "foo=~1.0" "foo>1.0_invalid"; do \
TESTDEPENDS="$i" atf_check -s exit:1 \
-e match:"Validating" \
abuild validate
done
}
abuild_subpackage_arch_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/subpackage-arch
arch="$(abuild -A)"
for i in noarch all "$arch"; do
TESTSUBARCH="$i" abuild all
[ -f "$REPODEST/testrepo/$arch/test-pkgname-$i-1.0-r0.apk" ] || \
atf_fail "Failed to place $i arch subpackage correctly"
rm -rf "$REPODEST/testrepo"
done
}
abuild_large_doc_subpackage_body() {
init_keys
cp -ra "$testrepo"/large-doc-subpkg .
cd large-doc-subpkg
atf_check -s exit:0 -o ignore \
-e match:"-doc subpackage is unusually large" \
abuild all
}
abuild_bigdocs_body() {
init_keys
cp -ra "$testrepo"/large-doc-subpkg .
cd large-doc-subpkg
options=bigdocs atf_check -s exit:0 -o ignore \
-e not-match:"-doc subpackage is unusually large" \
abuild all
}
abuild_pkgver_digit_letter_digit_body() {
cp -ra "$testrepo"/test-pkgname .
cd test-pkgname
TESTPKGVER=1.0p1 atf_check -s exit:1 \
-e match:'ERROR.*version' \
abuild validate
}
abuild_multiline_license_body() {
cp -ra "$testrepo"/test-licenses .
cd test-licenses
abuild rootpkg
atf_check -o match:'^license = MIT AND \(GPL-3.0-only OR GPL-3.0-or-later AND BSD-4-Clause\)$' \
cat pkg/.control.test-licenses/.PKGINFO
}
abuild_license_spdx_body() {
cp -ra "$testrepo"/test-licenses .
cd test-licenses
TESTPKGVER=1.0_p1 atf_check -s exit:0 \
-e not-match:'WARNING' \
abuild validate
}
abuild_git_ceiling_body() {
init_keys
git init
mkdir git-pkg
cd git-pkg
cat >APKBUILD<<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="git-pkg"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
prepare() {
mkdir -p "\$builddir"
}
build() {
git status
}
package() {
mkdir -p "\$pkgdir"
}
EOF
atf_check -s exit:1 \
-e match:"not a git repository" \
-e match:"ERROR: git-pkg: build failed" \
abuild
}
abuild_package_size_body() {
init_keys
mkdir -p test-size
cd test-size
cat > APKBUILD <<-EOF
# Maintainer: Test User 123 <123@example.com>
pkgname="test-size"
pkgver="1.0"
pkgrel=0
pkgdesc='Dummy test package that has no files'
url='https://gitlab.alpinelinux.org/alpine/aports'
arch='noarch'
license='MIT'
install="\$pkgname-empty-script.post-install"
trigger="\$pkgname-empty-trigger.trigger=/"
subpackages="
\$pkgname-empty-noscript:_empty
\$pkgname-empty-script:_empty
\$pkgname-empty-trigger:_empty
\$pkgname-dirs:_dirs
\$pkgname-files:_files
\$pkgname-many:_many
\$pkgname-holes:_holes
\$pkgname-hardlink:_hardlink
\$pkgname-symlink:_symlink
"
# Test if multi line bc output is handle properly
export BC_LINE_LENGTH=1
package() {
mkdir -p "\$pkgdir"
}
_empty() {
mkdir -p "\$subpkgdir"
}
_dirs() {
mkdir -p "\$subpkgdir/a/ /v/e/r/y/ /d/e/e/p/ /d/i/r"
mkdir -p "\$subpkgdir"/b "\$subpkgdir"/c
}
_files() {
mkdir -p "\$subpkgdir"
cd "\$subpkgdir"
printf 'test\\n' > test
touch empty
mkdir -p dir
printf 'more\\n' > dir/more
printf 'size leak!\\n' > secret
chmod a-rwx secret
printf 'quoting and stuff\\n' > dir/"\\\$can't \\"touch \\\\this"
}
_many() {
mkdir -p "\$subpkgdir"
for i in \$(seq 10000); do
printf '\\n' > "\$subpkgdir/\$i"
done
}
_holes() {
mkdir -p "\$subpkgdir"
dd if=/dev/zero bs=1 seek=65534 count=1 of="\$subpkgdir"/holes
}
_hardlink() {
mkdir -p "\$subpkgdir"
cd "\$subpkgdir"
printf 'test\\n' > test
ln test link
ln test link2
}
_symlink() {
mkdir -p "\$subpkgdir"
ln -s / "\$subpkgdir"/link
}
EOF
cat > test-size-empty-script.post-install <<-EOF
#!/bin/sh
echo 1
EOF
cat > test-size-empty-trigger.trigger <<-EOF
#!/bin/sh
echo 1
EOF
abuild rootpkg
local i size
for i in \
empty-noscript:0 \
empty-script:1 \
empty-trigger:1 \
dirs:1 \
files:39 \
many:10000 \
holes:65535 \
hardlink:5 \
symlink:1 \
; do \
size=$(awk -F ' = ' '$1 == "size" {print $2}' pkg/.control.test-size-${i%:*}/.PKGINFO)
[ "$size" -eq "${i#*:}" ] ||
atf_fail "$i failed: got $size"
done
}
abuild_keepdirs_body() {
init_keys
mkdir -p test-amove
cd test-amove
cat > APKBUILD <<-EOF
# Maintainer: Test User 123 <123@example.com>
pkgname="test-keepdirs"
pkgver="1.0"
pkgrel=0
pkgdesc='Dummy test package - keepdirs'
url='https://gitlab.alpinelinux.org/alpine/aports'
arch='noarch'
license='MIT'
options='keepdirs'
package() {
mkdir -p "\$pkgdir"/usr/bin
}
EOF
abuild rootpkg || atf_fail "abuild rootpkg failed"
test -d pkg/test-keepdirs/usr/bin || atf_fail "$i failed"
}
abuild_amove_body() {
init_keys
mkdir -p test-amove
cd test-amove
cat > APKBUILD <<-EOF
# Maintainer: Test User 123 <123@example.com>
pkgname="test-amove"
pkgver="1.0"
pkgrel=0
pkgdesc='Dummy test package - amove'
url='https://gitlab.alpinelinux.org/alpine/aports'
arch='noarch'
license='MIT'
subpackages="\$pkgname-file:_file
\$pkgname-etc:_etc
\$pkgname-bin:_bin
\$pkgname-sbin:_sbin
\$pkgname-root:_root
\$pkgname-var:_var
\$pkgname-usr:_usr
\$pkgname-space:_space"
package() {
mkdir -p "\$pkgdir"/etc \
"\$pkgdir"/usr/bin \
"\$pkgdir"/usr/sbin \
"\$pkgdir"/var/lib/\$pkgname \
"\$pkgdir"/usr/share
touch "\$pkgdir"/etc/file \
"\$pkgdir"/etc/\$pkgname.conf \
"\$pkgdir"/usr/bin/hello \
"\$pkgdir"/usr/sbin/shello \
"\$pkgdir"/root \
"\$pkgdir"/usr/sbin/space' ' \
"\$pkgdir"/var/lib/\$pkgname/testfile \
"\$pkgdir"/usr/share/a \
"\$pkgdir"/usr/share/b
ln -s dangling "\$pkgdir"/symlink
}
_file() {
amove etc/file
}
_etc() {
# leading and trailing /
amove ///etc/
}
_bin() {
# trailing /
amove usr/bin///
}
_sbin() {
# no leading and trailing /
amove usr/sbin/shello
}
_root() {
# no /
amove root
# symlink without existing target
amove symlink
}
_var() {
# leading /
amove /var/lib
}
_usr() {
# glob *
amove usr/share/*
! amove no-glob-match/*
}
_space() {
# with space
amove usr/sbin/space' '
}
EOF
abuild rootpkg || atf_fail "abuild rootpkg failed"
for i in \
test-amove-file/etc/file \
test-amove-etc/etc/test-amove.conf \
test-amove-bin/usr/bin/hello \
test-amove-sbin/usr/sbin/shello \
test-amove-root/root \
test-amove-root/symlink \
test-amove-var/var/lib/test-amove/testfile \
test-amove-usr/usr/share/a \
test-amove-usr/usr/share/b \
test-amove-space/usr/sbin/space' ' \
; do \
[ -L pkg/"$i" ] || [ -e pkg/"$i" ] || atf_fail "$i failed"
done
}
abuild_doc_body() {
init_keys
mkdir -p foo
cd foo
cat > APKBUILD <<-EOF
# Maintainer: Test User 123 <123@example.com>
pkgname="foo"
pkgver="1.0"
pkgrel=0
pkgdesc='Dummy test package - doc'
url='https://gitlab.alpinelinux.org/alpine/aports'
arch='noarch'
license='MIT'
subpackages="\$pkgname-doc"
build() {
touch foo foo.1 readme
}
package() {
install -Dt "\$pkgdir"/usr/bin foo
install -Dt "\$pkgdir"/usr/share/man/man1 foo.1
install -Dt "\$pkgdir"/usr/share/doc/foo readme
}
EOF
abuild build rootpkg || atf_fail "abuild rootpkg failed"
find pkg
for i in \
foo/usr/bin/foo \
foo-doc/usr/share/man/man1/foo.1.gz \
foo-doc/usr/share/doc/foo/readme \
; do \
test -f pkg/$i || atf_fail "$i failed"
done
}
abuild_dev_body() {
init_keys
mkdir -p foo
cd foo
cat > APKBUILD <<-EOF
# Maintainer: Test User 123 <123@example.com>
pkgname="foo"
pkgver="1.0"
pkgrel=0
pkgdesc='Dummy test package - dev'
url='https://gitlab.alpinelinux.org/alpine/aports'
arch='noarch'
license='MIT'
subpackages="\$pkgname-dev"
build() {
touch foo foo.h libfoo.so.1
}
package() {
install -Dt "\$pkgdir"/usr/bin foo
install -Dt "\$pkgdir"/usr/include foo.h
install -Dt "\$pkgdir"/usr/lib libfoo.so.1
ln -s libfoo.so.1 "\$pkgdir"/usr/lib/libfoo.so
}
EOF
abuild build rootpkg || atf_fail "abuild rootpkg failed"
find pkg
for i in \
foo/usr/bin/foo \
foo-dev/usr/include/foo.h \
; do \
test -f pkg/$i || atf_fail "$i failed"
done
test -L pkg/foo-dev/usr/lib/libfoo.so || atf_fail "libfoo.so failed"
}
abuild_devhelp_warn_body() {
init_keys
mkdir -p foo
cd foo
cat > APKBUILD <<-EOF
# Maintainer: Test User 123 <123@example.com>
pkgname="foo"
pkgver="1.0"
pkgrel=0
pkgdesc='Dummy test package that has devhelp'
url='https://gitlab.alpinelinux.org/alpine/aports'
arch='noarch'
license='MIT'
package() {
mkdir -p "\$pkgdir"/usr/share/devhelp/book
}
EOF
atf_check -e match:"WARNING:" \
abuild rootpkg
}
abuild_devhelp_body() {
init_keys
mkdir -p foo
cd foo
cat > APKBUILD <<-EOF
# Maintainer: Test User 123 <123@example.com>
pkgname="foo"
pkgver="1.0"
pkgrel=0
pkgdesc='Dummy test package that has devhelp'
url='https://gitlab.alpinelinux.org/alpine/aports'
arch='noarch'
license='MIT'
subpackages="\$pkgname-devhelp"
package() {
mkdir -p "\$pkgdir"/usr/share/devhelp/book
}
EOF
atf_check -e not-match:"WARNING:" \
-o match:'->' \
abuild rootpkg
}
abuild_check_maintainer_body() {
mkdir -p foo && cd foo
for m in "Test User 123 <123example.com>" \
"foo" \
"user@example.com" \
" Leading Space <n@example.com>" \
"Trailing Space <n@example.com> " \
"Foo<u@example.com>" \
'"Quotes <u@example.com>"'; do
printf "# Maintainer: %s\n%s\n" "$m" "pkgname=foo" > APKBUILD
atf_check -s not-exit:0 \
-e match:"ERROR:" \
abuild check_maintainer
done
for m in "Test User <123@example.com>" "Foo O'Brian <n@example.com>" "Łukasz Something <s@example.com>"; do
printf "# Maintainer: %s\n%s\n" "$m" "pkgname=foo" > APKBUILD
atf_check abuild check_maintainer
done
}
abuild_cleanoldpkg_body() {
init_keys
mkdir -p main/foo
cd main/foo
for arch in aarch64 x86_64; do
for v in 0.9 1.0 1.1; do
cat > APKBUILD <<-EOF
# Maintainer: Test User 123 <123@example.com>
pkgname="foo"
pkgver="$v"
pkgrel=0
pkgdesc='Dummy test package - dev'
url='https://gitlab.alpinelinux.org/alpine/aports'
arch='noarch'
license='MIT'
options='!check'
package() {
mkdir -p "\$pkgdir"
}
EOF
CARCH=$arch atf_check -e not-empty abuild clean unpack rootpkg
done
done
CARCH=aarch64 atf_check -e match:"Cleaning" abuild cleanoldpkg
find "$REPODEST"
# should keep the current APKBUILD version
for arch in aarch64 x86_64; do
f="$REPODEST"/main/$arch/foo-1.1-r0.apk
if ! test -e "$f"; then
atf_fail "$f was deleted"
fi
done
# should remove old packages of aarch64
for i in 0.9 1.0; do
f="$REPODEST"/main/aarch64/foo-$i-r0.apk
if test -e "$f"; then
atf_fail "$f was not deleted"
fi
done
# should not delete other arches than aarch64
for i in 0.9 1.0; do
f="$REPODEST"/main/x86_64/foo-$i-r0.apk
if ! test -e "$f"; then
atf_fail "$f was deleted"
fi
done
}
abuild_path_with_spaces_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/pkg\ path\ with\ spaces
atf_check -s exit:0 \
-o match:"hello world" \
-e match:"Build complete" \
abuild
}
abuild_pyc_warn_body() {
init_keys
mkdir -p pycachetest
cd pycachetest
cat >APKBUILD <<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="pycachetest"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
source=""
package() {
mkdir -p "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/
touch "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/main.cpython-311.pyc
}
EOF
atf_check -e match:"WARNING.*pyc*" abuild rootpkg
}
abuild_pyc_body() {
init_keys
mkdir -p foo
cd foo
cat >APKBUILD <<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="foo"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
source=""
subpackages="\$pkgname-pyc"
package() {
mkdir -p "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/
touch "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/main.cpython-311.pyc
}
EOF
atf_check -o match:"->" -e not-match:"WARNING.*pyc*" abuild rootpkg
atf_check -o match:"__pycache__" find pkg/foo-pyc -name '__pycache__'
# verify install_if is correct
atf_check -o match:"foo=1.0-r0" -o match:"pyc" \
grep install_if pkg/.control.foo-pyc/.PKGINFO
}
abuild_setcap_binary_body() {
init_keys
cp -ra "$testrepo"/setcap .
cd setcap
atf_check -s exit:1 \
-e match:"Found binary with extra capabilities" \
-e match:"Found setcap binary executable by others" \
abuild all
}
abuild_setcap_binary_with_option_body() {
init_keys
cp -ra "$testrepo"/setcap .
cd setcap
options=setcap atf_check -s exit:0 \
-e not-match:"Found binary with extra capabilities" \
-e match:"Found setcap binary executable by others" \
abuild all
}
abuild_command_provides_body() {
init_keys
mkdir testprovides
cd testprovides
cat >APKBUILD<<-EOF
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=testprovides
pkgver=1.0
pkgrel=0
pkgdesc="Dummy test package that installs a file and directory in path"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
prepare() { mkdir -p "\$builddir"; }
build() { true; }
check() { true; }
package() {
mkdir -p "\$pkgdir/usr/bin"
printf "%s\n" '#!/bin/sh' >"\$pkgdir/usr/bin/foo"
chmod +x "\$pkgdir/usr/bin/foo"
cp -a "\$pkgdir/usr/bin/foo" "\$pkgdir/usr/bin/foo@"
mkdir -p "\$pkgdir/usr/bin/dir/"
ln -s /usr/bin/not-on-the-host-system-but-in-a-dependency "\$pkgdir/usr/bin/link"
}
EOF
abuild rootpkg
atf_check \
-o match:"provides = cmd:foo=1.0-r0" \
-o not-match:"provides = cmd:foo@=1.0-r0" \
-o match:"provides = cmd:link=1.0-r0" \
-o not-match:"provides = cmd:dir=1.0-r0" \
grep '^provides = ' pkg/.control.testprovides/.PKGINFO
}
abuild_gocache_dir_body() {
init_keys
mkdir gocache-dir
cd gocache-dir
cat >APKBUILD<<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="gocache-dir"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
prepare() {
mkdir -p "\$builddir"
}
build() {
echo "dir:\$GOCACHE"
}
package() {
:
}
EOF
unset GOCACHE
MOVE_CACHES=1 \
atf_check -s exit:0 \
-o match:"dir:.*/tmp/go" \
abuild prepare build
}
abuild_cargo_home_dir_body() {
init_keys
mkdir cargo-home-dir
cd cargo-home-dir
cat >APKBUILD<<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="cargo-home-dir"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
prepare() {
mkdir -p "\$builddir"
}
build() {
echo "dir:\$CARGO_HOME"
}
package() {
:
}
EOF
unset CARGO_HOME
MOVE_CACHES=1 \
atf_check -s exit:0 \
-o match:"dir:.*/tmp/cargo" \
abuild prepare build
}
abuild_fish_comp_split_body() {
init_keys
mkdir fish-split-dir
cd fish-split-dir
cat >APKBUILD<<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="fish-split-dir"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
prepare() {
mkdir -p "\$builddir"
}
package() {
mkdir -p "\$pkgdir"/usr/share/fish/completions/
mkdir -p "\$pkgdir"/usr/share/fish/vendor_completions.d/
echo "comp" > "\$pkgdir"/usr/share/fish/completions/comp.fish
echo "comp" > "\$pkgdir"/usr/share/fish/vendor_completions.d/comp.fish
}
EOF
# test that there is a warning for the legacy dir existing
atf_check -s exit:0 \
-e match:"fish completions for programs should be located in /usr/share/fish/vendor_completions.d" \
abuild prepare build rootpkg
# now add the correct subpackage
echo 'subpackages="$pkgname-fish-completion"' >> APKBUILD
abuild clean prepare build rootpkg
if ! [ -d pkg/fish-split-dir-fish-completion/usr/share/fish/completions ]; then
echo "missing old dir"
exit 1
fi
if ! [ -d pkg/fish-split-dir-fish-completion/usr/share/fish/vendor_completions.d ]; then
echo "missing new dir"
exit 1
fi
}
create_mock_apk() {
mkdir -p usr/bin
cat > usr/bin/apk <<-EOF
#!/bin/sh
if [ "\$1" = "--print-arch" ]; then
echo 'aarch64'
exit 0
fi
printf 'apk %s\n' "\$*" >&2
EOF
chmod +x usr/bin/apk
ln -s apk usr/bin/abuild-apk
PATH="$PWD/usr/bin:$PATH"
}
abuild_deps_body() {
create_mock_apk
mkdir testdeps
cd testdeps
cat >APKBUILD <<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="testdeps"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
depends="foo"
makedepends="bar"
checkdepends="checkdep"
makedepends_host="hostdep"
makedepends_build="builddep"
EOF
# native build. pull in both depends and makedepends
# do not install in any --root
atf_check \
-e match:'Installing for build: foo bar checkdep$' \
-e match:'apk add .*--virtual .makedepends-testdeps foo bar checkdep' \
-e not-match:'apk add .*--root' \
abuild deps
# dont install checkdep with ABUILD_BOOTSTRAP
ABUILD_BOOTSTRAP=1 atf_check \
-e not-match:"apk add.*checkdep" \
abuild deps
# crosscompile:
# install makedepends_build without --root
# install makedepends_host with --root
CTARGET='s390x' CHOST='ppc64le' CBUILDROOT="$PWD/root" atf_check \
-e match:'Installing for build: builddep' \
-e match:'Installing for host: hostdep' \
-e match:'apk add .*--virtual .makedepends-testdeps builddep' \
-e not-match:'apk add.*--root.*builddep' \
-e match:'apk add .*--root.*hostdep' \
-e match:'apk add .*--arch s390x.*hostdep' \
-e not-match:'apk add.*checkdep' \
abuild deps
# crosscompile, set only CHOST
CHOST='armhf' atf_check \
-e match:'apk add.*builddep' \
-e not-match:'apk add.*--root.*builddep' \
-e match:'apk add.*--root.*--arch armhf.*hostdep' \
-e not-match:'apk add.*--arch armhf.*builddep' \
abuild deps
# Check shell_escape
atf_check \
-e match:"apk add .*--repository It's \\\\b'\"\"' \"escaped\"/.*" \
abuild -P "It's \b'\"\"' \"escaped\"" deps
}
abuild_usr_merge_body() {
init_keys
mkdir usrmergetest
cd usrmergetest
cat >APKBUILD <<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="usrmergetest"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
options="!check"
package() {
mkdir -p \
"\$pkgdir"/lib \
"\$pkgdir"/bin \
"\$pkgdir"/sbin
}
EOF
atf_check -s exit:0 \
-e match:"WARNING:.*: Packages must not put anything under /lib, use /usr/lib instead" \
-e match:"WARNING:.*: Packages must not put anything under /bin, use /usr/bin instead" \
-e match:"WARNING:.*: Packages must not put anything under /sbin, use /usr/bin instead" \
abuild
}