@@ -7,22 +7,218 @@ set -o nounset # undefined variables causes script to fail
77mkdir -p /var/lock/
88mkdir -p /var/log/
99
10- if [ $PKG_MANAGER = " opkg" ]; then
10+ CI_HELPERS=" ${CI_HELPERS:-/ scripts/ ci_helpers.sh} "
11+
12+ source " $CI_HELPERS "
13+
14+ generic_tests_enabled () {
15+ [ " $ENABLE_GENERIC_TESTS " = ' true' ]
16+ }
17+
18+ generic_tests_forced () {
19+ [ " $FORCE_GENERIC_TESTS " = ' true' ]
20+ }
21+
22+ is_exec () {
23+ [ -x " $1 " ] && echo " $1 " | grep -qE ' ^(/bin/|/sbin/|/usr/bin/|/usr/sbin/|/usr/libexec/)'
24+ }
25+
26+ is_lib () {
27+ echo " $1 " | grep -qE ' ^(/lib/|/usr/lib/)'
28+ }
29+
30+ is_apk () {
31+ [ " $PKG_MANAGER " = ' apk' ]
32+ }
33+
34+ is_opkg () {
35+ [ " $PKG_MANAGER " = ' opkg' ]
36+ }
37+
38+ check_hardcoded_paths () {
39+ local file=" $1 "
40+
41+ if strings " $file " | grep -E ' /build_dir/' ; then
42+ status_warn " Binary $file contains a hardcoded build path"
43+ return 1
44+ fi
45+
46+ status_pass " Binary $file does not contain any hardcoded build paths"
47+ return 0
48+ }
49+
50+ check_exec () {
51+ local file=" $1 "
52+ local has_failure=0
53+
54+ if [ -x " $file " ]; then
55+ status_pass " File $file is executable"
56+ else
57+ status_fail " File $file in executable path is not executable"
58+ has_failure=1
59+ fi
60+
61+ local found_version=0
62+ for flag in --version -version version -v -V --help -help -? ; do
63+ if " $file " " $flag " 2>&1 | grep -F " $PKG_VERSION " ; then
64+ status_pass " Found version $PKG_VERSION in $file "
65+ found_version=1
66+ break
67+ fi
68+ done
69+
70+ if [ " $found_version " = 0 ]; then
71+ status_fail " Failed to find version $PKG_VERSION in $file "
72+ has_failure=1
73+ fi
74+
75+ if [ " $has_failure " = 1 ]; then
76+ return 1
77+ fi
78+
79+ return 0
80+ }
81+
82+ check_linked_libs () {
83+ local file=" $1 "
84+ local missing_libs
85+ missing_libs=$( ldd " $file " 2> /dev/null | grep " not found" || true)
86+ if [ -n " $missing_libs " ]; then
87+ status_fail " File $file has missing libraries:"
88+ echo " $missing_libs "
89+ return 1
90+ fi
91+
92+ status_pass " All linked libraries for $file are present"
93+ return 0
94+ }
95+
96+ check_lib () {
97+ local file=" $1 "
98+ local has_failure=0
99+ local soname
100+ soname=$( readelf -d " $file " 2> /dev/null | grep ' SONAME' | sed -E ' s/.*\[(.*)\].*/\1/' )
101+ if [ -n " $soname " ]; then
102+ if [ " $( basename " $file " ) " = " $soname " ]; then
103+ status_warn " Library $file has the same name as its SONAME '$soname '. The library file should have a more specific version."
104+ else
105+ status_pass " Library $file has SONAME '$soname '"
106+ fi
107+
108+ # When a library has a SONAME, there should be a symlink with the SONAME
109+ # pointing to the library file. This is usually in the same directory.
110+ local lib_dir
111+ lib_dir=$( dirname " $file " )
112+ if [ ! -L " $lib_dir /$soname " ]; then
113+ status_fail " Library $file has SONAME '$soname ' but no corresponding symlink was found in $lib_dir "
114+ has_failure=1
115+ elif [ " $( readlink -f " $lib_dir /$soname " ) " != " $( readlink -f " $file " ) " ]; then
116+ status_fail " Symlink for SONAME '$soname ' does not point to $file "
117+ has_failure=1
118+ else
119+ status_pass " SONAME link for $file is correct"
120+ fi
121+ else
122+ status_warn " Library $file doesn't have a SONAME"
123+ fi
124+
125+ if [ " $has_failure " = 1 ]; then
126+ return 1
127+ fi
128+
129+ return 0
130+ }
131+
132+ do_generic_tests () {
133+ local all_files
134+ if is_opkg; then
135+ all_files=$( opkg files " $PKG_NAME " )
136+ elif is_apk; then
137+ all_files=$( apk info --contents " $PKG_NAME " | sed ' s#^#/#' )
138+ fi
139+
140+ local files
141+ files=$( echo " $all_files " | grep -E ' ^(/bin/|/sbin/|/usr/bin/|/usr/libexec/|/usr/sbin/|/lib/|/usr/lib/)' )
142+
143+ local has_failure=0
144+ for file in $files ; do
145+ if [ ! -e " $file " ]; then
146+ # opkg files can list directories
147+ continue
148+ fi
149+
150+ # Check if it is a symlink and if the target exists
151+ if [ -L " $file " ]; then
152+ if [ -e " $( readlink -f " $file " ) " ]; then
153+ status_pass " Symlink $file points to an existing file"
154+ else
155+ status_fail " Symlink $file points to a non-existent file"
156+ has_failure=1
157+ fi
158+
159+ # Skip symlinks
160+ continue
161+ fi
162+
163+ if is_exec " $file " && ! check_exec " $file " ; then
164+ has_failure=1
165+ fi
166+
167+ # Skip non-ELF files
168+ if ! file " $file " | grep -q " ELF" ; then
169+ continue
170+ fi
171+
172+ check_hardcoded_paths " $file "
173+
174+ if file " $file " | grep ' not stripped' ; then
175+ status_warn " Binary $file is not stripped"
176+ else
177+ status_pass " Binary $file is stripped"
178+ fi
179+
180+ if ! check_linked_libs " $file " ; then
181+ has_failure=1
182+ fi
183+
184+ if is_lib " $file " && ! check_lib " $file " ; then
185+ has_failure=1
186+ fi
187+ done
188+
189+ if [ " $has_failure " = 1 ]; then
190+ err " Generic tests failed"
191+ return 1
192+ fi
193+
194+ success " Generic tests passed"
195+ return 0
196+ }
197+
198+ if is_opkg; then
11199 echo " src/gz packages_ci file:///ci" >> /etc/opkg/distfeeds.conf
12200 # Disable checking signature for all opkg feeds, since it doesn't look like
13201 # it's possible to do it for the local feed only, which has signing removed.
14202 # This fixes running CI tests.
15203 sed -i ' /check_signature/d' /etc/opkg.conf
16204 opkg update
17- elif [ $PKG_MANAGER = " apk" ]; then
205+ opkg install binutils file
206+ elif is_apk; then
18207 echo " /ci/packages.adb" >> /etc/apk/repositories.d/distfeeds.list
19208 apk update
209+ apk add binutils file
20210fi
21211
22- CI_HELPERS=" ${CI_HELPERS:-/ scripts/ ci_helpers.sh} "
212+ if generic_tests_enabled && generic_tests_forced; then
213+ warn ' Generic tests are enabled and forced'
214+ elif generic_tests_enabled; then
215+ warn ' Generic tests are enabled'
216+ else
217+ warn ' Generic tests are disabled'
218+ fi
23219
24220for PKG in /ci/* .[ai]pk; do
25- if [ $PKG_MANAGER = " opkg " ] ; then
221+ if is_opkg ; then
26222 tar -xzOf " $PKG " ./control.tar.gz | tar xzf - ./control
27223 # package name including variant
28224 PKG_NAME=$( sed -ne ' s#^Package: \(.*\)$#\1#p' ./control)
@@ -32,7 +228,7 @@ for PKG in /ci/*.[ai]pk; do
32228 # package source containing test.sh script
33229 PKG_SOURCE=$( sed -ne ' s#^Source: \(.*\)$#\1#p' ./control)
34230 PKG_SOURCE=" ${PKG_SOURCE#/ feed/ } "
35- elif [ $PKG_MANAGER = " apk " ] ; then
231+ elif is_apk ; then
36232 # package name including variant
37233 PKG_NAME=$( apk adbdump --format json " $PKG " | jsonfilter -e ' @["info"]["name"]' )
38234 # package version without release
@@ -44,52 +240,62 @@ for PKG in /ci/*.[ai]pk; do
44240 fi
45241
46242 echo
47- echo " Testing package $PKG_NAME in version $PKG_VERSION from $PKG_SOURCE "
243+ info " Testing package version $PKG_VERSION from $PKG_SOURCE "
48244
49245 if ! [ -d " /ci/$PKG_SOURCE " ]; then
50- echo " $PKG_SOURCE is not a directory"
51- exit 1
246+ err_die " $PKG_SOURCE is not a directory"
52247 fi
53248
54249 PRE_TEST_SCRIPT=" /ci/$PKG_SOURCE /pre-test.sh"
55250 TEST_SCRIPT=" /ci/$PKG_SOURCE /test.sh"
56251
57- if ! [ -f " $TEST_SCRIPT " ]; then
58- echo " No test.sh script available"
59- continue
60- fi
61-
62252 export PKG_NAME PKG_VERSION CI_HELPERS
63253
64254 if [ -f " $PRE_TEST_SCRIPT " ]; then
65- echo " Use package specific pre-test.sh"
255+ info ' Use the package- specific pre-test.sh'
66256 if sh " $PRE_TEST_SCRIPT " " $PKG_NAME " " $PKG_VERSION " ; then
67- echo " Pre-test successful "
257+ success ' Pre-test passed '
68258 else
69- echo " Pre-test failed"
70- exit 1
259+ err_die ' Pre-test failed'
71260 fi
72261 else
73- echo " No pre-test.sh script available"
262+ info ' No pre-test.sh script available'
74263 fi
75264
76- if [ $PKG_MANAGER = " opkg " ] ; then
265+ if is_opkg ; then
77266 opkg install " $PKG "
78- elif [ $PKG_MANAGER = " apk " ] ; then
267+ elif is_apk ; then
79268 apk add --allow-untrusted " $PKG "
80269 fi
81270
82- echo " Use package specific test.sh"
83- if sh " $TEST_SCRIPT " " $PKG_NAME " " $PKG_VERSION " ; then
84- echo " Test successful"
85- else
86- echo " Test failed"
87- exit 1
271+ SUCCESS=0
272+
273+ if generic_tests_enabled && ( generic_tests_forced || [ ! -f " $TEST_SCRIPT " ] ); then
274+ warn ' Use generic tests'
275+ if do_generic_tests; then
276+ SUCCESS=1
277+ fi
88278 fi
89279
90- if [ $PKG_MANAGER = " opkg" ]; then
91- opkg remove " $PKG_NAME " --force-removal-of-dependent-packages --force-remove --autoremove || true
92- elif [ $PKG_MANAGER = " apk" ]; then
93- apk del -r " $PKG_NAME "
280+ if [ -f " $TEST_SCRIPT " ]; then
281+ info ' Use the package-specific test.sh'
282+ if sh " $TEST_SCRIPT " " $PKG_NAME " " $PKG_VERSION " ; then
283+ success ' Test passed'
284+ SUCCESS=1
285+ else
286+ err ' Test failed'
287+ fi
288+ fi
289+
290+ if is_opkg; then
291+ opkg remove " $PKG_NAME " \
292+ --autoremove \
293+ --force-removal-of-dependent-packages \
294+ --force-remove \
295+ || true
296+ elif is_apk; then
297+ apk del --rdepends " $PKG_NAME " || true
94298 fi
299+
300+ [ " $SUCCESS " = 1 ] || exit 1
95301done
0 commit comments