@@ -7,18 +7,214 @@ 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 opkg update
13- elif [ $PKG_MANAGER = " apk" ]; then
201+ opkg install binutils file
202+ elif is_apk; then
14203 echo " /ci/packages.adb" >> /etc/apk/repositories.d/distfeeds.list
15204 apk update
205+ apk add binutils file
16206fi
17207
18- CI_HELPERS=" ${CI_HELPERS:-/ scripts/ ci_helpers.sh} "
208+ if generic_tests_enabled && generic_tests_forced; then
209+ warn ' Generic tests are enabled and forced'
210+ elif generic_tests_enabled; then
211+ warn ' Generic tests are enabled'
212+ else
213+ warn ' Generic tests are disabled'
214+ fi
19215
20216for PKG in /ci/* .[ai]pk; do
21- if [ $PKG_MANAGER = " opkg " ] ; then
217+ if is_opkg ; then
22218 tar -xzOf " $PKG " ./control.tar.gz | tar xzf - ./control
23219 # package name including variant
24220 PKG_NAME=$( sed -ne ' s#^Package: \(.*\)$#\1#p' ./control)
@@ -28,7 +224,7 @@ for PKG in /ci/*.[ai]pk; do
28224 # package source containing test.sh script
29225 PKG_SOURCE=$( sed -ne ' s#^Source: \(.*\)$#\1#p' ./control)
30226 PKG_SOURCE=" ${PKG_SOURCE#/ feed/ } "
31- elif [ $PKG_MANAGER = " apk " ] ; then
227+ elif is_apk ; then
32228 # package name including variant
33229 PKG_NAME=$( apk adbdump --format json " $PKG " | jsonfilter -e ' @["info"]["name"]' )
34230 # package version without release
@@ -40,52 +236,62 @@ for PKG in /ci/*.[ai]pk; do
40236 fi
41237
42238 echo
43- echo " Testing package $PKG_NAME in version $PKG_VERSION from $PKG_SOURCE "
239+ info " Testing package version $PKG_VERSION from $PKG_SOURCE "
44240
45241 if ! [ -d " /ci/$PKG_SOURCE " ]; then
46- echo " $PKG_SOURCE is not a directory"
47- exit 1
242+ err_die " $PKG_SOURCE is not a directory"
48243 fi
49244
50245 PRE_TEST_SCRIPT=" /ci/$PKG_SOURCE /pre-test.sh"
51246 TEST_SCRIPT=" /ci/$PKG_SOURCE /test.sh"
52247
53- if ! [ -f " $TEST_SCRIPT " ]; then
54- echo " No test.sh script available"
55- continue
56- fi
57-
58248 export PKG_NAME PKG_VERSION CI_HELPERS
59249
60250 if [ -f " $PRE_TEST_SCRIPT " ]; then
61- echo " Use package specific pre-test.sh"
251+ info ' Use the package- specific pre-test.sh'
62252 if sh " $PRE_TEST_SCRIPT " " $PKG_NAME " " $PKG_VERSION " ; then
63- echo " Pre-test successful "
253+ success ' Pre-test passed '
64254 else
65- echo " Pre-test failed"
66- exit 1
255+ err_die ' Pre-test failed'
67256 fi
68257 else
69- echo " No pre-test.sh script available"
258+ info ' No pre-test.sh script available'
70259 fi
71260
72- if [ $PKG_MANAGER = " opkg " ] ; then
261+ if is_opkg ; then
73262 opkg install " $PKG "
74- elif [ $PKG_MANAGER = " apk " ] ; then
263+ elif is_apk ; then
75264 apk add --allow-untrusted " $PKG "
76265 fi
77266
78- echo " Use package specific test.sh"
79- if sh " $TEST_SCRIPT " " $PKG_NAME " " $PKG_VERSION " ; then
80- echo " Test successful"
81- else
82- echo " Test failed"
83- exit 1
267+ SUCCESS=0
268+
269+ if generic_tests_enabled && ( generic_tests_forced || [ ! -f " $TEST_SCRIPT " ] ); then
270+ warn ' Use generic tests'
271+ if do_generic_tests; then
272+ SUCCESS=1
273+ fi
84274 fi
85275
86- if [ $PKG_MANAGER = " opkg" ]; then
87- opkg remove " $PKG_NAME " --force-removal-of-dependent-packages --force-remove --autoremove || true
88- elif [ $PKG_MANAGER = " apk" ]; then
89- apk del -r " $PKG_NAME "
276+ if [ -f " $TEST_SCRIPT " ]; then
277+ info ' Use the package-specific test.sh'
278+ if sh " $TEST_SCRIPT " " $PKG_NAME " " $PKG_VERSION " ; then
279+ success ' Test passed'
280+ SUCCESS=1
281+ else
282+ err ' Test failed'
283+ fi
284+ fi
285+
286+ if is_opkg; then
287+ opkg remove " $PKG_NAME " \
288+ --autoremove \
289+ --force-removal-of-dependent-packages \
290+ --force-remove \
291+ || true
292+ elif is_apk; then
293+ apk del --rdepends " $PKG_NAME " || true
90294 fi
295+
296+ [ " $SUCCESS " = 1 ] || exit 1
91297done
0 commit comments