blob: 3c6f700754aaac9da8bc2ad4cf046d5c24496f38 [file] [log] [blame]
Zdenek Behan12ad1c52010-08-03 16:34:37 -07001# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2# Distributed under the terms of the GNU General Public License v2
3
4#
5# Original Author: The Chromium OS Authors <chromium-os-dev@chromium.org>
6# Purpose: Eclass for handling autotest test packages
7#
8
Zdenek Behan9e98f322010-08-26 18:56:54 -07009RDEPEND="( autotest? ( >=chromeos-base/autotest-0.0.1-r3 ) )"
Zdenek Behan12ad1c52010-08-03 16:34:37 -070010
Zdenek Behan302e7482011-02-01 21:58:52 +010011IUSE="+buildcheck autotest opengles"
Zdenek Behan12ad1c52010-08-03 16:34:37 -070012
13# Ensure the configures run by autotest pick up the right config.site
Zdenek Behan99bf5842010-08-04 17:23:38 -070014export CONFIG_SITE="/usr/share/config.site"
15export AUTOTEST_WORKDIR="${WORKDIR}/autotest-work"
Zdenek Behan12ad1c52010-08-03 16:34:37 -070016
Zdenek Behancd997a32010-08-20 12:55:44 -070017# @ECLASS-VARIABLE: AUTOTEST_CLIENT_*
18# @DESCRIPTION:
19# Location of the appropriate test directory inside ${S}
20: ${AUTOTEST_CLIENT_TESTS:=client/tests}
21: ${AUTOTEST_CLIENT_SITE_TESTS:=client/site_tests}
22: ${AUTOTEST_SERVER_TESTS:=server/tests}
23: ${AUTOTEST_SERVER_SITE_TESTS:=server/site_tests}
Zdenek Behan41463c92010-08-23 12:12:31 -070024: ${AUTOTEST_CONFIG:=client/config}
25: ${AUTOTEST_DEPS:=client/deps}
26: ${AUTOTEST_PROFILERS:=client/profilers}
27
28# @ECLASS-VARIABLE: AUTOTEST_*_LIST
29# @DESCRIPTION:
30# The list of deps/configs/profilers provided with this package
31: ${AUTOTEST_CONFIG_LIST:=*}
32: ${AUTOTEST_DEPS_LIST:=*}
33: ${AUTOTEST_PROFILERS_LIST:=*}
Zdenek Behancd997a32010-08-20 12:55:44 -070034
Zdenek Behand012b762010-09-01 21:22:26 -070035# @ECLASS-VARIABLE: AUTOTEST_FORCE_LIST
36# @DESCRIPTION:
37# Sometimes we just want to forget about useflags and build what's inside
38: ${AUTOTEST_FORCE_TEST_LIST:=}
39
Zdenek Behanb1f7c892010-09-22 12:25:38 -070040# @ECLASS-VARIABLE: AUTOTEST_FILE_MASK
41# @DESCRIPTION:
42# The list of 'find' expressions to find in the resulting image and delete
43: ${AUTOTEST_FILE_MASK:=}
44
Zdenek Behan7922d132010-09-24 14:18:05 -070045function fast_cp() {
46 cp -l "$@" || cp "$@"
47}
48
Zdenek Behand012b762010-09-01 21:22:26 -070049function get_test_list() {
50 if [ -n "${AUTOTEST_FORCE_TEST_LIST}" ]; then
51 # list forced
52 echo "${AUTOTEST_FORCE_TEST_LIST}"
53 return
54 fi
55
56 # we cache the result of this operation in AUTOTEST_TESTS,
57 # because it's expensive and does not change over the course of one ebuild run
58 local result="${IUSE_TESTS//[+-]tests_/}"
59 result="${result//tests_/}"
60
61 result=$(for test in ${result}; do use tests_${test} && echo -n "${test} "; done)
62 echo "${result}"
63}
64
Zdenek Behan12ad1c52010-08-03 16:34:37 -070065# Pythonify the list of packages
66function pythonify_test_list() {
67 local result
Zdenek Behand012b762010-09-01 21:22:26 -070068 result=$(for test in $*; do echo -n "${test},"; done)
Zdenek Behan31315b32010-08-05 16:34:39 -070069 echo ${result}
Zdenek Behan12ad1c52010-08-03 16:34:37 -070070}
71
72# Create python package init files for top level test case dirs.
73function touch_init_py() {
74 local dirs=${1}
75 for base_dir in $dirs
76 do
77 local sub_dirs="$(find ${base_dir} -maxdepth 1 -type d)"
78 for sub_dir in ${sub_dirs}
79 do
80 touch ${sub_dir}/__init__.py
81 done
82 touch ${base_dir}/__init__.py
83 done
84}
85
86function setup_cross_toolchain() {
87 if tc-is-cross-compiler ; then
88 tc-export CC CXX AR RANLIB LD NM STRIP
89 export PKG_CONFIG_PATH="${ROOT}/usr/lib/pkgconfig/"
90 export CCFLAGS="$CFLAGS"
91 fi
92
93 # TODO(fes): Check for /etc/hardened for now instead of the hardened
94 # use flag because we aren't enabling hardened on the target board.
95 # Rather, right now we're using hardened only during toolchain compile.
96 # Various tests/etc. use %ebx in here, so we have to turn off PIE when
97 # using the hardened compiler
98 if use x86 ; then
99 if use hardened ; then
100 #CC="${CC} -nopie"
101 append-flags -nopie
102 fi
103 fi
104}
105
106function create_autotest_workdir() {
107 local dst=${1}
108
109 # create a working enviroment for pre-building
Chris Masone21512432010-11-15 16:18:57 -0800110 ln -sf "${SYSROOT}"/usr/local/autotest/{conmux,tko,global_config.ini,shadow_config.ini} "${dst}"/
Zdenek Behan99bf5842010-08-04 17:23:38 -0700111
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700112 # NOTE: in order to make autotest not notice it's running from /usr/local/, we need
113 # to make sure the binaries are real, because they do the path magic
114 local root_path base_path
Chris Masone21512432010-11-15 16:18:57 -0800115 for base_path in utils server; do
116 root_path="${SYSROOT}/usr/local/autotest/${base_path}"
117 mkdir -p "${dst}/${base_path}"
118 for entry in $(ls "${root_path}"); do
Zdenek Behan7e9e32f2012-02-28 03:15:46 +0100119 # Take all important binaries from SYSROOT install, make a copy.
120 if [ -d "${root_path}/${entry}" ]; then
121 # Ignore anything that has already been put in place by
122 # something else. This will typically be server/{site_tests,tests}.
123 if ! [ -e "${dst}/${base_path}/${entry}" ]; then
124 ln -sf "${root_path}/${entry}" "${dst}/${base_path}/"
125 fi
Chris Masone21512432010-11-15 16:18:57 -0800126 else
127 cp -f ${root_path}/${entry} ${dst}/${base_path}/
128 fi
129 done
130 done
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700131 for base_path in client client/bin; do
132 root_path="${SYSROOT}/usr/local/autotest/${base_path}"
133 mkdir -p "${dst}/${base_path}"
134
Zdenek Behan451e07f2010-08-06 11:25:37 -0700135 # Skip bin, because it is processed separately, and test-provided dirs
136 # Also don't symlink to packages, because that kills the build
Zdenek Behan41463c92010-08-23 12:12:31 -0700137 for entry in $(ls "${root_path}" | \
138 grep -v "\(bin\|tests\|site_tests\|config\|deps\|profilers\|packages\)$"); do
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700139 ln -sf "${root_path}/${entry}" "${dst}/${base_path}/"
140 done
141 done
142 # replace the important binaries with real copies
143 for base_path in autotest autotest_client; do
144 root_path="${SYSROOT}/usr/local/autotest/client/bin/${base_path}"
145 rm "${dst}/client/bin/${base_path}"
146 cp -f ${root_path} "${dst}/client/bin/${base_path}"
147 done
Zdenek Behan448ddaa2010-08-24 11:18:50 -0700148
149 # Selectively pull in deps that are not provided by the current test package
150 for base_path in config deps profilers; do
151 for dir in "${SYSROOT}/usr/local/autotest/client/${base_path}"/*; do
152 if [ -d "${dir}" ] && \
153 ! [ -d "${AUTOTEST_WORKDIR}/client/${base_path}/$(basename ${dir})" ]; then
154 # directory does not exist, create a symlink
155 ln -sf "${dir}" "${AUTOTEST_WORKDIR}/client/${base_path}/$(basename ${dir})"
156 fi
157 done
158 done
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700159}
160
161function print_test_dirs() {
162 local testroot="${1}"
163
164 pushd "${testroot}" 1> /dev/null
165 for test in *; do
166 if [ -d "${test}" ] && [ -f "${test}/${test}".py ]; then
167 echo "${test}"
168 fi
169 done
170 popd 1> /dev/null
171}
172
Zdenek Behaneee7bc22010-08-20 18:33:13 -0700173# checks IUSE_TESTS and sees if at least one of these is enabled
174function are_we_used() {
Zdenek Behan14ae4892010-08-26 15:25:30 -0700175 if ! use autotest; then
176 # unused
177 return 1
178 fi
179
Zdenek Behand012b762010-09-01 21:22:26 -0700180 [ -n "$(get_test_list)" ] && return 0
Zdenek Behaneee7bc22010-08-20 18:33:13 -0700181
182 # unused
183 return 1
184}
185
Zdenek Behan99bf5842010-08-04 17:23:38 -0700186function autotest_src_prepare() {
Zdenek Behaneee7bc22010-08-20 18:33:13 -0700187 are_we_used || return 0
188 einfo "Preparing tests"
189
190 # FIXME: These directories are needed, autotest quietly dies if
191 # they don't even exist. They may, however, stay empty.
Zdenek Behanc02fc472010-08-13 12:55:07 -0700192 mkdir -p "${AUTOTEST_WORKDIR}"/client/tests
193 mkdir -p "${AUTOTEST_WORKDIR}"/client/site_tests
Zdenek Behan41463c92010-08-23 12:12:31 -0700194 mkdir -p "${AUTOTEST_WORKDIR}"/client/config
195 mkdir -p "${AUTOTEST_WORKDIR}"/client/deps
196 mkdir -p "${AUTOTEST_WORKDIR}"/client/profilers
Zdenek Behanc02fc472010-08-13 12:55:07 -0700197 mkdir -p "${AUTOTEST_WORKDIR}"/server/tests
198 mkdir -p "${AUTOTEST_WORKDIR}"/server/site_tests
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700199
Zdenek Behand012b762010-09-01 21:22:26 -0700200 TEST_LIST=$(get_test_list)
201
Zdenek Behan448ddaa2010-08-24 11:18:50 -0700202 # Pull in the individual test cases.
Zdenek Behan31315b32010-08-05 16:34:39 -0700203 for l1 in client server; do
204 for l2 in site_tests tests; do
Zdenek Behancd997a32010-08-20 12:55:44 -0700205 # pick up the indicated location of test sources
206 eval srcdir=${WORKDIR}/${P}/\${AUTOTEST_${l1^^*}_${l2^^*}}
207
Zdenek Behand012b762010-09-01 21:22:26 -0700208 # test does have this directory
209 for test in ${TEST_LIST}; do
210 if [ -d "${srcdir}/${test}" ]; then
Zdenek Behan7922d132010-09-24 14:18:05 -0700211 fast_cp -fpr "${srcdir}/${test}" "${AUTOTEST_WORKDIR}/${l1}/${l2}"/ || die
Zdenek Behand012b762010-09-01 21:22:26 -0700212 fi
213 done
Zdenek Behan31315b32010-08-05 16:34:39 -0700214 done
215 done
Zdenek Behan99bf5842010-08-04 17:23:38 -0700216
Zdenek Behan448ddaa2010-08-24 11:18:50 -0700217 # Pull in all the deps provided by this package, selectively.
Zdenek Behan41463c92010-08-23 12:12:31 -0700218 for l2 in config deps profilers; do
219 # pick up the indicated location of test sources
220 eval srcdir=${WORKDIR}/${P}/\${AUTOTEST_${l2^^*}}
221
222 if [ -d "${srcdir}" ]; then # test does have this directory
223 pushd "${srcdir}" 1> /dev/null
224 eval deplist=\${AUTOTEST_${l2^^*}_LIST}
225
226 if [ "${deplist}" = "*" ]; then
Zdenek Behan7922d132010-09-24 14:18:05 -0700227 fast_cp -fpr * "${AUTOTEST_WORKDIR}/client/${l2}"
Zdenek Behan41463c92010-08-23 12:12:31 -0700228 else
229 for dir in ${deplist}; do
Zdenek Behan7922d132010-09-24 14:18:05 -0700230 fast_cp -fpr "${dir}" "${AUTOTEST_WORKDIR}/client/${l2}"/ || die
Zdenek Behan41463c92010-08-23 12:12:31 -0700231 done
232 fi
233 popd 1> /dev/null
234 fi
235 done
236
Zdenek Behan474fbae2010-08-20 21:13:22 -0700237 # FIXME: We'd like if this were not necessary, and autotest supported out-of-tree build
Zdenek Behan99bf5842010-08-04 17:23:38 -0700238 create_autotest_workdir "${AUTOTEST_WORKDIR}"
Zdenek Behaneee7bc22010-08-20 18:33:13 -0700239
Zdenek Behanf93c208a2010-09-21 18:53:58 -0700240 # Each test directory needs to be visited and have an __init__.py created.
241 # However, that only applies to the directories which have a main .py file.
Zdenek Behanedb527a2010-09-22 12:24:14 -0700242 pushd "${AUTOTEST_WORKDIR}" > /dev/null || die "AUTOTEST_WORKDIR does not exist?!"
Zdenek Behanf93c208a2010-09-21 18:53:58 -0700243 for dir in client/tests client/site_tests server/tests server/site_tests; do
Zdenek Behanedb527a2010-09-22 12:24:14 -0700244 pushd "${dir}" > /dev/null || continue
Zdenek Behanf93c208a2010-09-21 18:53:58 -0700245 for sub in *; do
246 [ -f "${sub}/${sub}.py" ] || continue
Zdenek Behan1ec164a2010-08-17 19:06:31 -0700247
Zdenek Behanf93c208a2010-09-21 18:53:58 -0700248 touch_init_py ${sub}
249 done
Zdenek Behanedb527a2010-09-22 12:24:14 -0700250 popd > /dev/null
Zdenek Behan1ec164a2010-08-17 19:06:31 -0700251 done
Zdenek Behanedb527a2010-09-22 12:24:14 -0700252 popd > /dev/null
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700253
254 # Cleanup checked-in binaries that don't support the target architecture
255 [[ ${E_MACHINE} == "" ]] && return 0;
Zdenek Behan092f4632010-09-21 19:34:01 -0700256 rm -fv $( scanelf -RmyBF%a "${AUTOTEST_WORKDIR}" | grep -v -e ^${E_MACHINE} )
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700257}
258
259function autotest_src_compile() {
Zdenek Behan48096a82010-09-23 19:39:26 -0700260 if ! are_we_used; then
261 ewarn "***************************************************************"
262 ewarn "* Not building any tests, because the requested list is empty *"
263 ewarn "***************************************************************"
264 return 0
265 fi
Zdenek Behaneee7bc22010-08-20 18:33:13 -0700266 einfo "Compiling tests"
267
Zdenek Behan31315b32010-08-05 16:34:39 -0700268 pushd "${AUTOTEST_WORKDIR}" 1> /dev/null
Zdenek Behan99bf5842010-08-04 17:23:38 -0700269
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700270 setup_cross_toolchain
271
272 if use opengles ; then
273 graphics_backend=OPENGLES
274 else
275 graphics_backend=OPENGL
276 fi
277
Zdenek Behan9e979bb2010-09-23 17:32:05 -0700278 # HACK: Some of the autotests depend on SYSROOT being defined, and die
279 # a gruesome death if it isn't. But SYSROOT does not need to exist, for
280 # example on the host, it doesn't. Let's define a compatible variable
281 # here in case we have none.
282 export SYSROOT=${SYSROOT:-"/"}
283
Zdenek Behan8ad65252010-09-07 12:35:19 -0700284 # This only prints the tests that have the associated .py
285 # (and therefore a setup function)
286 local prebuild_test_dirs="
287 client/tests client/site_tests
288 server/tests server/site_tests"
289 TESTS=$(\
290 for dir in ${prebuild_test_dirs}; do
291 print_test_dirs "${AUTOTEST_WORKDIR}/${dir}"
292 done | sort | uniq
293 )
Zdenek Behan9afd0a32011-01-21 01:47:02 +0100294 NR_TESTS=$(echo ${TESTS}|wc -w)
295 if ! [ "${NR_TESTS}" = "0" ]; then
296 einfo "Building tests (${NR_TESTS}):"
297 einfo "${TESTS}"
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700298
Zdenek Behan9afd0a32011-01-21 01:47:02 +0100299 NORMAL=$(echo -e "\e[0m")
300 GREEN=$(echo -e "\e[1;32m")
301 RED=$(echo -e "\e[1;31m")
Zdenek Behan402fea02010-09-14 13:50:09 -0700302
Zdenek Behan9afd0a32011-01-21 01:47:02 +0100303 # Call autotest to prebuild all test cases.
304 # Parse output through a colorifying sed script
305 ( GRAPHICS_BACKEND="$graphics_backend" LOGNAME=${SUDO_USER} \
306 client/bin/autotest_client --quiet \
307 --client_test_setup=$(pythonify_test_list ${TESTS}) \
308 || ! use buildcheck || die "Tests failed to build."
309 ) | sed -e "s/\(INFO:root:setup\)/${GREEN}* \1${NORMAL}/" \
310 -e "s/\(ERROR:root:\[.*\]\)/${RED}\1${NORMAL}/"
311 else
312 einfo "No tests to prebuild, skipping"
313 fi
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700314
315 # Cleanup some temp files after compiling
Zdenek Behanb1f7c892010-09-22 12:25:38 -0700316 for mask in '*.[do]' ${AUTOTEST_FILE_MASK}; do
317 einfo "Purging ${mask}"
318 find . -name "${mask}" -delete
319 done
Zdenek Behan31315b32010-08-05 16:34:39 -0700320
321 popd 1> /dev/null
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700322}
323
324function autotest_src_install() {
Zdenek Behaneee7bc22010-08-20 18:33:13 -0700325 are_we_used || return 0
326 einfo "Installing tests"
327
Zdenek Behan448ddaa2010-08-24 11:18:50 -0700328 # Install all test cases, after setup has been called on them.
329 # We install everything, because nothing else is copied into the
330 # testcase directories besides what this package provides.
Zdenek Behan1ec164a2010-08-17 19:06:31 -0700331 local instdirs="
332 client/tests
333 client/site_tests
Zdenek Behan1ec164a2010-08-17 19:06:31 -0700334 server/tests
335 server/site_tests"
336
337 for dir in ${instdirs}; do
Zdenek Behancd997a32010-08-20 12:55:44 -0700338 [ -d "${AUTOTEST_WORKDIR}/${dir}" ] || continue
Zdenek Behan1ec164a2010-08-17 19:06:31 -0700339
340 insinto /usr/local/autotest/$(dirname ${dir})
341 doins -r "${AUTOTEST_WORKDIR}/${dir}"
342 done
343
Zdenek Behan448ddaa2010-08-24 11:18:50 -0700344 # Install the deps, configs, profilers.
345 # Difference from above is, we don't install the whole thing, just
346 # the stuff provided by this package, by looking at AUTOTEST_*_LIST.
347 instdirs="
348 config
349 deps
350 profilers"
351
352 for dir in ${instdirs}; do
353 [ -d "${AUTOTEST_WORKDIR}/client/${dir}" ] || continue
354
355 insinto /usr/local/autotest/client/${dir}
356
357 eval provided=\${AUTOTEST_${dir^^*}_LIST}
358 # * means provided all, figure out the list from ${S}
359 if [ "${provided}" = "*" ]; then
360 if eval pushd "${WORKDIR}/${P}/\${AUTOTEST_${dir^^*}}" &> /dev/null; then
361 provided=$(ls)
362 popd 1> /dev/null
363 else
364 provided=""
365 fi
366 fi
367
368 for item in ${provided}; do
369 doins -r "${AUTOTEST_WORKDIR}/client/${dir}/${item}"
370 done
371 done
372
Zdenek Behan1ec164a2010-08-17 19:06:31 -0700373 # TODO: Not all needs to be executable, but it's hard to pick selectively.
374 # The source repo should already contain stuff with the right permissions.
375 chmod -R a+x "${D}"/usr/local/autotest/*
Zdenek Behan12ad1c52010-08-03 16:34:37 -0700376}
377
Chris Sosaccb6c8b2012-03-09 10:47:32 -0800378# Sets up autotest packages in build root for use by developers when running
379# tests.
380function autotest_pkg_postinst() {
Chris Masone21512432010-11-15 16:18:57 -0800381 are_we_used || return 0
Chris Sosaccb6c8b2012-03-09 10:47:32 -0800382 einfo "Creating autotest packages."
383 local autotest_dir="${ROOT}/usr/local/autotest"
384 local packages_dir="${autotest_dir}/packages"
385 local checksum_file="${packages_dir}/packages.checksum"
Chris Masone21512432010-11-15 16:18:57 -0800386
Chris Sosaccb6c8b2012-03-09 10:47:32 -0800387 mkdir -p "${packages_dir}"
388 touch "${checksum_file}"
389
390 # Build packages from the workdir and install them into the buildroot.
391 flock "${checksum_file}" \
392 -c "${autotest_dir}/utils/packager.py \
393 -r ${packages_dir} --all upload" ||
394 die "Could not create packages."
Chris Masone21512432010-11-15 16:18:57 -0800395}
396
Chris Sosaccb6c8b2012-03-09 10:47:32 -0800397EXPORT_FUNCTIONS src_compile src_prepare src_install pkg_postinst