2010-09-25 23:51:51 +04:00
#!/usr/bin/env python
# run tests on all Samba subprojects and push to a git tree on success
# Copyright Andrew Tridgell 2010
# released under GNU GPL v3 or later
2018-03-09 17:06:21 +03:00
from __future__ import print_function
2018-07-30 09:19:05 +03:00
from subprocess import call , check_call , Popen , PIPE
2018-07-30 09:21:38 +03:00
import os
import tarfile
import sys
import time
2010-09-25 23:51:51 +04:00
from optparse import OptionParser
2010-09-30 21:41:36 +04:00
import smtplib
2015-04-14 08:18:02 +03:00
import email
2010-09-30 21:41:36 +04:00
from email . mime . text import MIMEText
2015-04-14 08:18:02 +03:00
from email . mime . base import MIMEBase
from email . mime . application import MIMEApplication
from email . mime . multipart import MIMEMultipart
2012-04-09 08:52:03 +04:00
from distutils . sysconfig import get_python_lib
2015-04-14 08:18:02 +03:00
import platform
2010-09-25 23:51:51 +04:00
2018-09-03 13:07:23 +03:00
try :
from waflib . Build import CACHE_SUFFIX
except ImportError :
sys . path . insert ( 0 , " ./third_party/waf " )
from waflib . Build import CACHE_SUFFIX
2017-01-11 16:48:45 +03:00
os . environ [ " PYTHONUNBUFFERED " ] = " 1 "
2012-06-22 04:14:36 +04:00
# This speeds up testing remarkably.
os . environ [ ' TDB_NO_FSYNC ' ] = ' 1 '
2010-09-25 23:51:51 +04:00
cleanup_list = [ ]
2011-02-07 02:05:32 +03:00
builddirs = {
2018-07-30 09:17:14 +03:00
" ctdb " : " ctdb " ,
" samba " : " . " ,
2018-08-16 04:50:31 +03:00
" samba-py3 " : " . " ,
2018-07-30 09:17:14 +03:00
" samba-nt4 " : " . " ,
2018-08-16 04:50:31 +03:00
" samba-nt4-py3 " : " . " ,
2018-07-30 09:17:14 +03:00
" samba-fileserver " : " . " ,
" samba-xc " : " . " ,
" samba-o3 " : " . " ,
" samba-ctdb " : " . " ,
" samba-libs " : " . " ,
2018-08-16 04:50:31 +03:00
" samba-libs-py3 " : " . " ,
2018-07-30 09:17:14 +03:00
" samba-static " : " . " ,
" samba-none-env " : " . " ,
" samba-ad-dc " : " . " ,
2018-08-16 04:50:31 +03:00
" samba-ad-dc-py3 " : " . " ,
2018-07-30 09:17:14 +03:00
" samba-ad-dc-2 " : " . " ,
2018-08-16 04:50:31 +03:00
" samba-ad-dc-2-py3 " : " . " ,
2018-07-30 09:17:14 +03:00
" samba-systemkrb5 " : " . " ,
" samba-nopython " : " . " ,
2018-11-29 17:21:27 +03:00
" samba-buildpy2-only " : " . " ,
2018-07-30 09:17:14 +03:00
" ldb " : " lib/ldb " ,
" tdb " : " lib/tdb " ,
" talloc " : " lib/talloc " ,
" replace " : " lib/replace " ,
" tevent " : " lib/tevent " ,
2018-08-16 04:54:14 +03:00
" pidl " : " pidl "
2018-07-30 09:14:37 +03:00
}
2011-02-07 02:05:32 +03:00
2018-08-16 04:54:14 +03:00
defaulttasks = builddirs . keys ( )
2015-05-04 10:21:53 +03:00
2016-08-01 17:48:53 +03:00
if os . environ . get ( " AUTOBUILD_SKIP_SAMBA_O3 " , " 0 " ) == " 1 " :
defaulttasks . remove ( " samba-o3 " )
2017-01-11 10:14:49 +03:00
ctdb_configure_params = " --enable-developer --picky-developer $ {PREFIX} "
2016-02-01 14:55:34 +03:00
samba_configure_params = " --picky-developer $ {PREFIX} $ {EXTRA_PYTHON} --with-profiling-data "
2011-02-07 02:05:32 +03:00
2018-11-24 14:13:47 +03:00
samba_libs_envvars = " PYTHONPATH=$ {PYTHON_PREFIX} :$PYTHONPATH "
2015-08-13 18:34:42 +03:00
samba_libs_envvars + = " PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$ {PREFIX_DIR} /lib/pkgconfig "
2015-08-14 09:40:37 +03:00
samba_libs_envvars + = " ADDITIONAL_CFLAGS= ' -Wmissing-prototypes ' "
2018-05-10 00:09:56 +03:00
samba_libs_configure_base = samba_libs_envvars + " ./configure --abi-check --enable-debug --picky-developer -C $ {PREFIX} "
2018-07-27 06:50:15 +03:00
samba_libs_configure_libs = samba_libs_configure_base + " --bundled-libraries=cmocka,popt,NONE $ {EXTRA_PYTHON} "
samba_libs_configure_bundled_libs = " --bundled-libraries=!talloc,!pytalloc-util,!tdb,!pytdb,!ldb,!pyldb,!pyldb-util,!tevent,!pytevent,!popt "
2018-05-10 00:09:56 +03:00
samba_libs_configure_samba = samba_libs_configure_base + samba_libs_configure_bundled_libs + " $ {EXTRA_PYTHON} "
2015-08-13 18:34:42 +03:00
2016-02-01 14:55:34 +03:00
if os . environ . get ( " AUTOBUILD_NO_EXTRA_PYTHON " , " 0 " ) == " 1 " :
extra_python = " "
else :
extra_python = " --extra-python=/usr/bin/python3 "
2010-09-25 23:51:51 +04:00
tasks = {
2018-07-30 09:17:14 +03:00
" ctdb " : [ ( " random-sleep " , " ../script/random-sleep.sh 60 600 " , " text/plain " ) ,
2017-01-11 10:14:49 +03:00
( " configure " , " ./configure " + ctdb_configure_params , " text/plain " ) ,
2011-10-13 00:27:55 +04:00
( " make " , " make all " , " text/plain " ) ,
( " install " , " make install " , " text/plain " ) ,
2013-11-14 10:38:29 +04:00
( " test " , " make autotest " , " text/plain " ) ,
2011-10-13 00:27:55 +04:00
( " check-clean-tree " , " ../script/clean-source-tree.sh " , " text/plain " ) ,
2018-07-30 09:17:02 +03:00
( " clean " , " make clean " , " text/plain " ) ] ,
2011-10-13 00:27:55 +04:00
2017-06-30 02:15:40 +03:00
# We have 'test' before 'install' because, 'test' should work without 'install (runs ad_dc_ntvfs and all the other envs)'
2018-07-30 09:17:14 +03:00
" samba " : [ ( " configure " , " ./configure.developer --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
2012-06-20 15:22:18 +04:00
( " make " , " make -j " , " text/plain " ) ,
2018-03-03 09:51:29 +03:00
( " test " , " make test FAIL_IMMEDIATELY=1 "
2018-08-16 04:50:31 +03:00
" TESTS= ' $ {PY3_ONLY} "
" --exclude-env=none "
2017-06-30 02:15:40 +03:00
" --exclude-env=nt4_dc "
2017-06-30 02:13:55 +03:00
" --exclude-env=nt4_member "
2018-03-04 11:32:09 +03:00
" --exclude-env=ad_dc "
2018-08-25 10:03:07 +03:00
" --exclude-env=ad_dc_no_nss "
2018-03-21 22:25:41 +03:00
" --exclude-env=fl2003dc "
" --exclude-env=fl2008r2dc "
" --exclude-env=ad_member "
" --exclude-env=ad_member_idmap_rid "
" --exclude-env=ad_member_idmap_ad "
2018-03-20 21:02:42 +03:00
" --exclude-env=chgdcpass "
" --exclude-env=vampire_2000_dc "
" --exclude-env=fl2000dc "
2018-08-25 10:40:12 +03:00
" --exclude-env=fileserver "
" --exclude-env=backupfromdc "
" --exclude-env=restoredc "
" --exclude-env=renamedc "
" --exclude-env=offlinebackupdc "
" --exclude-env=labdc "
" ' " ,
2018-03-04 11:32:09 +03:00
" text/plain " ) ,
2012-06-20 15:22:18 +04:00
( " install " , " make install " , " text/plain " ) ,
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ,
2018-07-30 09:17:02 +03:00
( " clean " , " make clean " , " text/plain " ) ] ,
2011-02-07 02:05:32 +03:00
2017-06-30 02:15:40 +03:00
# We split out this so the isolated nt4_dc tests do not wait for ad_dc or ad_dc_ntvfs tests (which are long)
2018-07-30 09:17:14 +03:00
" samba-nt4 " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
2018-07-05 02:09:50 +03:00
( " configure " , " ./configure.developer --without-ads --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
( " make " , " make -j " , " text/plain " ) ,
2018-08-16 04:50:31 +03:00
( " test " , " make test FAIL_IMMEDIATELY=1 "
" TESTS= ' $ {PY3_ONLY} "
" --include-env=nt4_dc --include-env=nt4_member ' " , " text/plain " ) ,
2018-07-05 02:09:50 +03:00
( " install " , " make install " , " text/plain " ) ,
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ,
2018-07-30 09:17:02 +03:00
( " clean " , " make clean " , " text/plain " ) ] ,
2017-06-30 02:15:40 +03:00
2018-03-04 11:32:09 +03:00
# We split out this so the isolated ad_dc tests do not wait for ad_dc_ntvfs tests (which are long)
2018-07-30 09:17:14 +03:00
" samba-fileserver " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
2018-09-25 15:09:18 +03:00
( " configure " , " ./configure.developer --without-ad-dc --without-ldap --without-ads --without-json --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
2018-07-30 09:16:12 +03:00
( " make " , " make -j " , " text/plain " ) ,
2018-08-16 04:50:31 +03:00
( " test " , " make test FAIL_IMMEDIATELY=1 "
" TESTS= ' $ {PY3_ONLY} "
" --include-env=fileserver ' " , " text/plain " ) ,
2018-07-30 09:16:12 +03:00
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ] ,
2018-03-04 11:32:09 +03:00
2017-06-30 02:13:55 +03:00
# We split out this so the isolated ad_dc tests do not wait for ad_dc_ntvfs tests (which are long)
2018-07-30 09:17:14 +03:00
" samba-ad-dc " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
2017-06-30 02:13:55 +03:00
( " configure " , " ./configure.developer --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
( " make " , " make -j " , " text/plain " ) ,
2018-08-16 04:50:31 +03:00
( " test " , " make test FAIL_IMMEDIATELY=1 "
" TESTS= ' $ {PY3_ONLY} "
2018-03-21 22:25:41 +03:00
" --include-env=ad_dc "
" --include-env=fl2003dc "
" --include-env=fl2008r2dc "
" --include-env=ad_member "
" --include-env=ad_member_idmap_rid "
" --include-env=ad_member_idmap_ad ' " , " text/plain " ) ,
2017-06-30 02:13:55 +03:00
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ] ,
2018-03-20 21:02:42 +03:00
# We split out this so the isolated ad_dc tests do not wait for ad_dc_ntvfs tests (which are long)
2018-07-30 09:17:14 +03:00
" samba-ad-dc-2 " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
2018-07-30 09:16:12 +03:00
( " configure " , " ./configure.developer --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
( " make " , " make -j " , " text/plain " ) ,
2018-08-16 04:50:31 +03:00
( " test " , " make test FAIL_IMMEDIATELY=1 "
" TESTS= ' $ {PY3_ONLY} "
2018-08-25 10:03:07 +03:00
" --include-env=chgdcpass "
" --include-env=vampire_2000_dc "
" --include-env=fl2000dc "
2018-08-25 10:40:12 +03:00
" --include-env=ad_dc_no_nss "
" --include-env=backupfromdc "
" --include-env=restoredc "
" --include-env=renamedc "
" --include-env=offlinebackupdc "
" --include-env=labdc "
" ' " ,
" text/plain " ) ,
2018-07-30 09:16:12 +03:00
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ] ,
2018-03-20 21:02:42 +03:00
2018-07-30 09:17:14 +03:00
" samba-test-only " : [ ( " configure " , " ./configure.developer --with-selftest-prefix=./bin/ab --abi-check-disable " + samba_configure_params , " text/plain " ) ,
2016-07-27 05:28:04 +03:00
( " make " , " make -j " , " text/plain " ) ,
2018-07-30 09:19:05 +03:00
( " test " , ' make test FAIL_IMMEDIATELY=1 TESTS= " $ {TESTS} " ' , " text/plain " ) ] ,
2016-07-27 05:28:04 +03:00
2015-05-04 10:21:53 +03:00
# Test cross-compile infrastructure
2018-07-30 09:17:14 +03:00
" samba-xc " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
2018-07-05 02:09:50 +03:00
( " configure-native " , " ./configure.developer --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
2017-04-13 19:47:50 +03:00
( " configure-cross-execute " , " ./configure.developer --out ./bin-xe --cross-compile --cross-execute=script/identity_cc.sh " \
2015-05-04 10:21:53 +03:00
" --cross-answers=./bin-xe/cross-answers.txt --with-selftest-prefix=./bin-xe/ab " + samba_configure_params , " text/plain " ) ,
2017-04-13 19:47:50 +03:00
( " configure-cross-answers " , " ./configure.developer --out ./bin-xa --cross-compile " \
2015-05-04 10:21:53 +03:00
" --cross-answers=./bin-xe/cross-answers.txt --with-selftest-prefix=./bin-xa/ab " + samba_configure_params , " text/plain " ) ,
2018-09-03 13:07:23 +03:00
( " compare-results " , " script/compare_cc_results.py "
" ./bin/c4che/default {} "
" ./bin-xe/c4che/default {} "
" ./bin-xa/c4che/default {} " . format ( * ( [ CACHE_SUFFIX ] * 3 ) ) , " text/plain " ) ] ,
2015-05-04 10:21:53 +03:00
2017-06-30 02:11:05 +03:00
# test build with -O3 -- catches extra warnings and bugs, tests the ad_dc environments
2018-07-30 09:17:14 +03:00
" samba-o3 " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
2018-11-20 14:11:43 +03:00
( " configure " , " ADDITIONAL_CFLAGS= ' -O3 -Wp,-D_FORTIFY_SOURCE=2 ' ./configure.developer --with-selftest-prefix=./bin/ab --abi-check-disable " + samba_configure_params , " text/plain " ) ,
2016-03-22 20:14:17 +03:00
( " make " , " make -j " , " text/plain " ) ,
2018-08-16 04:50:31 +03:00
( " test " , " make quicktest FAIL_IMMEDIATELY=1 "
" TESTS= ' $ {PY3_ONLY} "
" --include-env=ad_dc ' " , " text/plain " ) ,
2016-03-22 20:14:17 +03:00
( " install " , " make install " , " text/plain " ) ,
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ,
2018-07-30 09:17:02 +03:00
( " clean " , " make clean " , " text/plain " ) ] ,
2015-05-04 10:21:53 +03:00
2018-07-30 09:17:14 +03:00
" samba-ctdb " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
2012-06-20 16:05:50 +04:00
# make sure we have tdb around:
2018-11-24 14:13:47 +03:00
( " tdb-configure " , " cd lib/tdb && PYTHONPATH=$ {PYTHON_PREFIX} :$PYTHONPATH PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$ {PREFIX_DIR} /lib/pkgconfig ./configure --bundled-libraries=NONE --abi-check --enable-debug -C $ {PREFIX} " , " text/plain " ) ,
2012-06-20 16:05:50 +04:00
( " tdb-make " , " cd lib/tdb && make " , " text/plain " ) ,
( " tdb-install " , " cd lib/tdb && make install " , " text/plain " ) ,
2014-12-06 05:01:53 +03:00
# build samba with cluster support (also building ctdb):
2018-11-24 14:13:47 +03:00
( " samba-configure " , " PYTHONPATH=$ {PYTHON_PREFIX} :$PYTHONPATH PKG_CONFIG_PATH=$ {PREFIX_DIR} /lib/pkgconfig:$ {PKG_CONFIG_PATH} ./configure.developer --picky-developer $ {PREFIX} --with-selftest-prefix=./bin/ab --with-cluster-support --bundled-libraries=!tdb " , " text/plain " ) ,
2013-09-26 02:43:56 +04:00
( " samba-make " , " make " , " text/plain " ) ,
( " samba-check " , " ./bin/smbd -b | grep CLUSTER_SUPPORT " , " text/plain " ) ,
( " samba-install " , " make install " , " text/plain " ) ,
2014-10-25 20:01:30 +04:00
( " ctdb-check " , " test -e $ {PREFIX_DIR} /sbin/ctdbd " , " text/plain " ) ,
2013-09-26 02:43:56 +04:00
# clean up:
2012-06-20 16:05:50 +04:00
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ,
2013-09-26 02:43:56 +04:00
( " clean " , " make clean " , " text/plain " ) ,
2018-07-30 09:17:02 +03:00
( " ctdb-clean " , " cd ./ctdb && make clean " , " text/plain " ) ] ,
2012-06-20 16:05:50 +04:00
2018-08-22 00:35:58 +03:00
" samba-libs " : [
2012-06-20 13:03:48 +04:00
( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
2015-08-13 18:34:42 +03:00
( " talloc-configure " , " cd lib/talloc && " + samba_libs_configure_libs , " text/plain " ) ,
2012-06-20 12:36:23 +04:00
( " talloc-make " , " cd lib/talloc && make " , " text/plain " ) ,
2012-04-09 08:52:03 +04:00
( " talloc-install " , " cd lib/talloc && make install " , " text/plain " ) ,
2015-08-13 18:34:42 +03:00
( " tdb-configure " , " cd lib/tdb && " + samba_libs_configure_libs , " text/plain " ) ,
2012-06-20 12:36:23 +04:00
( " tdb-make " , " cd lib/tdb && make " , " text/plain " ) ,
2012-04-09 08:52:03 +04:00
( " tdb-install " , " cd lib/tdb && make install " , " text/plain " ) ,
2015-08-13 18:34:42 +03:00
( " tevent-configure " , " cd lib/tevent && " + samba_libs_configure_libs , " text/plain " ) ,
2012-06-20 12:36:23 +04:00
( " tevent-make " , " cd lib/tevent && make " , " text/plain " ) ,
2012-04-09 08:52:03 +04:00
( " tevent-install " , " cd lib/tevent && make install " , " text/plain " ) ,
2015-08-13 18:34:42 +03:00
( " ldb-configure " , " cd lib/ldb && " + samba_libs_configure_libs , " text/plain " ) ,
2012-06-20 12:36:23 +04:00
( " ldb-make " , " cd lib/ldb && make " , " text/plain " ) ,
2012-04-09 08:52:03 +04:00
( " ldb-install " , " cd lib/ldb && make install " , " text/plain " ) ,
2015-10-22 03:54:41 +03:00
( " nondevel-configure " , " ./configure $ {PREFIX} " , " text/plain " ) ,
( " nondevel-make " , " make -j " , " text/plain " ) ,
( " nondevel-check " , " ./bin/smbd -b | grep WITH_NTVFS_FILESERVER && exit 1; exit 0 " , " text/plain " ) ,
( " nondevel-install " , " make install " , " text/plain " ) ,
( " nondevel-dist " , " make dist " , " text/plain " ) ,
2015-08-13 18:38:43 +03:00
# retry with all modules shared
( " allshared-distclean " , " make distclean " , " text/plain " ) ,
( " allshared-configure " , samba_libs_configure_samba + " --with-shared-modules=ALL " , " text/plain " ) ,
2015-10-22 04:57:10 +03:00
( " allshared-make " , " make -j " , " text/plain " ) ] ,
2015-08-13 18:38:43 +03:00
2018-08-22 00:35:58 +03:00
" samba-none-env " : [
2018-03-03 09:51:29 +03:00
( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
( " configure " , " ./configure.developer --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
( " make " , " make -j " , " text/plain " ) ,
( " test " , " make test "
" FAIL_IMMEDIATELY=1 "
2018-08-16 04:50:31 +03:00
" TESTS= ' $ {PY3_ONLY} "
" --include-env=none ' " ,
2018-03-03 09:51:29 +03:00
" text/plain " ) ] ,
2018-08-22 00:35:58 +03:00
" samba-static " : [
2015-10-22 00:35:47 +03:00
( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
# build with all modules static
( " allstatic-configure " , " ./configure.developer " + samba_configure_params + " --with-static-modules=ALL " , " text/plain " ) ,
2015-10-22 04:57:10 +03:00
( " allstatic-make " , " make -j " , " text/plain " ) ,
2018-07-24 13:30:33 +03:00
( " allstatic-test " , " make test "
" FAIL_IMMEDIATELY=1 "
" TESTS= ' samba3.smb2.create.*nt4_dc ' " ,
" text/plain " ) ,
2015-08-13 18:38:43 +03:00
# retry without any required modules
( " none-distclean " , " make distclean " , " text/plain " ) ,
2015-10-22 00:35:47 +03:00
( " none-configure " , " ./configure.developer " + samba_configure_params + " --with-static-modules=!FORCED,!DEFAULT --with-shared-modules=!FORCED,!DEFAULT " , " text/plain " ) ,
2015-10-22 04:57:10 +03:00
( " none-make " , " make -j " , " text/plain " ) ,
2015-08-13 11:32:46 +03:00
# retry with nonshared smbd and smbtorture
( " nonshared-distclean " , " make distclean " , " text/plain " ) ,
2015-10-22 00:35:47 +03:00
( " nonshared-configure " , " ./configure.developer " + samba_configure_params + " --bundled-libraries=talloc,tdb,pytdb,ldb,pyldb,tevent,pytevent --with-static-modules=ALL --nonshared-binary=smbtorture,smbd/smbd " , " text/plain " ) ,
2015-10-22 04:57:10 +03:00
( " nonshared-make " , " make -j " , " text/plain " ) ] ,
2012-04-09 08:52:03 +04:00
2018-08-22 00:35:58 +03:00
" samba-systemkrb5 " : [
2016-09-26 03:46:56 +03:00
( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
( " configure " , " ./configure.developer " + samba_configure_params + " --with-system-mitkrb5 --without-ad-dc " , " text/plain " ) ,
( " make " , " make -j " , " text/plain " ) ,
# we currently cannot run a full make test, a limited list of tests could be run
# via "make test TESTS=sometests"
2018-08-16 04:50:31 +03:00
( " test " , " make test FAIL_IMMEDIATELY=1 "
" TESTS= ' $ {PY3_ONLY} "
" --include-env=ktest ' " , " text/plain " ) ,
2016-09-26 03:46:56 +03:00
( " install " , " make install " , " text/plain " ) ,
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ,
( " clean " , " make clean " , " text/plain " )
] ,
2017-01-30 17:36:31 +03:00
# Test Samba without python still builds. When this test fails
# due to more use of Python, the expectations is that the newly
# failing part of the code should be disabled when
# --disable-python is set (rather than major work being done to
# support this environment). The target here is for vendors
# shipping a minimal smbd.
2018-08-22 00:35:58 +03:00
" samba-nopython " : [
2017-01-30 17:36:31 +03:00
( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
( " configure " , " ./configure.developer --picky-developer $ {PREFIX} --with-profiling-data --disable-python --without-ad-dc " , " text/plain " ) ,
( " make " , " make -j " , " text/plain " ) ,
( " install " , " make install " , " text/plain " ) ,
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ,
2018-05-10 00:09:56 +03:00
( " clean " , " make clean " , " text/plain " ) ,
( " talloc-configure " , " cd lib/talloc && " + samba_libs_configure_base + " --bundled-libraries=cmocka,NONE --disable-python " , " text/plain " ) ,
( " talloc-make " , " cd lib/talloc && make " , " text/plain " ) ,
( " talloc-install " , " cd lib/talloc && make install " , " text/plain " ) ,
( " tdb-configure " , " cd lib/tdb && " + samba_libs_configure_base + " --bundled-libraries=cmocka,NONE --disable-python " , " text/plain " ) ,
( " tdb-make " , " cd lib/tdb && make " , " text/plain " ) ,
( " tdb-install " , " cd lib/tdb && make install " , " text/plain " ) ,
( " tevent-configure " , " cd lib/tevent && " + samba_libs_configure_base + " --bundled-libraries=cmocka,NONE --disable-python " , " text/plain " ) ,
( " tevent-make " , " cd lib/tevent && make " , " text/plain " ) ,
( " tevent-install " , " cd lib/tevent && make install " , " text/plain " ) ,
( " ldb-configure " , " cd lib/ldb && " + samba_libs_configure_base + " --bundled-libraries=cmocka,NONE --disable-python " , " text/plain " ) ,
( " ldb-make " , " cd lib/ldb && make " , " text/plain " ) ,
( " ldb-install " , " cd lib/ldb && make install " , " text/plain " ) ,
# retry against installed library packages
( " libs-configure " , samba_libs_configure_base + samba_libs_configure_bundled_libs + " --disable-python --without-ad-dc " , " text/plain " ) ,
( " libs-make " , " make -j " , " text/plain " ) ,
( " libs-install " , " make install " , " text/plain " ) ,
( " libs-check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ,
( " libs-clean " , " make clean " , " text/plain " )
2017-01-30 17:36:31 +03:00
] ,
2016-09-26 03:46:56 +03:00
2018-08-22 00:35:58 +03:00
" ldb " : [
2012-06-22 16:58:25 +04:00
( " random-sleep " , " ../../script/random-sleep.sh 60 600 " , " text/plain " ) ,
2016-02-01 14:55:34 +03:00
( " configure " , " ./configure --enable-developer -C $ {PREFIX} $ {EXTRA_PYTHON} " , " text/plain " ) ,
2012-06-20 12:36:23 +04:00
( " make " , " make " , " text/plain " ) ,
2011-02-07 02:05:32 +03:00
( " install " , " make install " , " text/plain " ) ,
2012-06-22 04:14:36 +04:00
( " test " , " make test " , " text/plain " ) ,
2018-05-14 05:34:25 +03:00
( " configure-no-lmdb " , " ./configure --enable-developer --without-ldb-lmdb -C $ {PREFIX} $ {EXTRA_PYTHON} " , " text/plain " ) ,
( " make-no-lmdb " , " make " , " text/plain " ) ,
( " install-no-lmdb " , " make install " , " text/plain " ) ,
2011-07-05 04:01:32 +04:00
( " check-clean-tree " , " ../../script/clean-source-tree.sh " , " text/plain " ) ,
2011-02-07 02:05:32 +03:00
( " distcheck " , " make distcheck " , " text/plain " ) ,
2018-07-30 09:17:02 +03:00
( " clean " , " make clean " , " text/plain " ) ] ,
2010-10-01 14:19:56 +04:00
2018-08-22 00:35:58 +03:00
" tdb " : [
2012-06-22 16:58:25 +04:00
( " random-sleep " , " ../../script/random-sleep.sh 60 600 " , " text/plain " ) ,
2016-02-01 14:55:34 +03:00
( " configure " , " ./configure --enable-developer -C $ {PREFIX} $ {EXTRA_PYTHON} " , " text/plain " ) ,
2012-06-20 12:36:23 +04:00
( " make " , " make " , " text/plain " ) ,
2011-02-07 02:05:32 +03:00
( " install " , " make install " , " text/plain " ) ,
( " test " , " make test " , " text/plain " ) ,
( " check-clean-tree " , " ../../script/clean-source-tree.sh " , " text/plain " ) ,
( " distcheck " , " make distcheck " , " text/plain " ) ,
2018-07-30 09:17:02 +03:00
( " clean " , " make clean " , " text/plain " ) ] ,
2012-03-07 06:32:22 +04:00
2018-08-22 00:35:58 +03:00
" talloc " : [
2012-06-22 16:58:25 +04:00
( " random-sleep " , " ../../script/random-sleep.sh 60 600 " , " text/plain " ) ,
2016-02-01 14:55:34 +03:00
( " configure " , " ./configure --enable-developer -C $ {PREFIX} $ {EXTRA_PYTHON} " , " text/plain " ) ,
2012-06-20 12:36:23 +04:00
( " make " , " make " , " text/plain " ) ,
2011-02-07 02:05:32 +03:00
( " install " , " make install " , " text/plain " ) ,
( " test " , " make test " , " text/plain " ) ,
( " check-clean-tree " , " ../../script/clean-source-tree.sh " , " text/plain " ) ,
( " distcheck " , " make distcheck " , " text/plain " ) ,
2018-07-30 09:17:02 +03:00
( " clean " , " make clean " , " text/plain " ) ] ,
2011-02-07 02:05:32 +03:00
2018-08-22 00:35:58 +03:00
" replace " : [
2012-06-22 16:58:25 +04:00
( " random-sleep " , " ../../script/random-sleep.sh 60 600 " , " text/plain " ) ,
2012-06-20 13:03:48 +04:00
( " configure " , " ./configure --enable-developer -C $ {PREFIX} " , " text/plain " ) ,
2012-06-20 12:36:23 +04:00
( " make " , " make " , " text/plain " ) ,
2010-10-01 14:19:56 +04:00
( " install " , " make install " , " text/plain " ) ,
2010-12-23 21:40:08 +03:00
( " test " , " make test " , " text/plain " ) ,
( " check-clean-tree " , " ../../script/clean-source-tree.sh " , " text/plain " ) ,
2011-01-11 02:54:28 +03:00
( " distcheck " , " make distcheck " , " text/plain " ) ,
2018-07-30 09:17:02 +03:00
( " clean " , " make clean " , " text/plain " ) ] ,
2010-10-01 14:19:56 +04:00
2018-08-22 00:35:58 +03:00
" tevent " : [
2012-06-22 16:58:25 +04:00
( " random-sleep " , " ../../script/random-sleep.sh 60 600 " , " text/plain " ) ,
2016-02-01 14:55:34 +03:00
( " configure " , " ./configure --enable-developer -C $ {PREFIX} $ {EXTRA_PYTHON} " , " text/plain " ) ,
2012-06-20 12:36:23 +04:00
( " make " , " make " , " text/plain " ) ,
2011-02-07 02:05:32 +03:00
( " install " , " make install " , " text/plain " ) ,
( " test " , " make test " , " text/plain " ) ,
( " check-clean-tree " , " ../../script/clean-source-tree.sh " , " text/plain " ) ,
( " distcheck " , " make distcheck " , " text/plain " ) ,
2018-07-30 09:17:02 +03:00
( " clean " , " make clean " , " text/plain " ) ] ,
2011-01-05 11:30:48 +03:00
2018-07-30 09:17:14 +03:00
" pidl " : [
2018-07-30 09:17:02 +03:00
( " random-sleep " , " ../script/random-sleep.sh 60 600 " , " text/plain " ) ,
( " configure " , " perl Makefile.PL PREFIX=$ {PREFIX_DIR} " , " text/plain " ) ,
( " touch " , " touch *.yp " , " text/plain " ) ,
( " make " , " make " , " text/plain " ) ,
( " test " , " make test " , " text/plain " ) ,
( " install " , " make install " , " text/plain " ) ,
( " checkout-yapp-generated " , " git checkout lib/Parse/Pidl/IDL.pm lib/Parse/Pidl/Expr.pm " , " text/plain " ) ,
( " check-clean-tree " , " ../script/clean-source-tree.sh " , " text/plain " ) ,
( " clean " , " make clean " , " text/plain " ) ] ,
2011-02-07 02:05:32 +03:00
2018-11-29 17:21:27 +03:00
" samba-buildpy2-only " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
( " configure " , " PYTHON= ' python ' ./configure.developer --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
( " make " , " PYTHON= ' python ' make -j " , " text/plain " ) ,
( " install " , " PYTHON= ' python ' make install " , " text/plain " ) ,
2018-09-27 12:22:07 +03:00
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ,
2018-11-29 17:21:27 +03:00
( " clean " , " PYTHON= ' python ' make clean " , " text/plain " ) ] ,
2018-09-27 12:22:07 +03:00
2018-10-16 21:25:26 +03:00
2011-02-07 02:05:32 +03:00
# these are useful for debugging autobuild
2018-07-30 09:17:14 +03:00
' pass ' : [ ( " pass " , ' echo passing && /bin/true ' , " text/plain " ) ] ,
' fail ' : [ ( " fail " , ' echo failing && /bin/false ' , " text/plain " ) ]
2018-10-16 21:25:26 +03:00
2010-09-25 23:51:51 +04:00
}
2018-07-30 09:20:39 +03:00
2017-01-11 17:02:17 +03:00
def do_print ( msg ) :
2018-03-09 17:06:21 +03:00
print ( " %s " % msg )
2017-01-11 17:02:17 +03:00
sys . stdout . flush ( )
sys . stderr . flush ( )
2018-07-30 09:20:39 +03:00
2010-09-26 23:50:06 +04:00
def run_cmd ( cmd , dir = " . " , show = None , output = False , checkfail = True ) :
2010-09-25 23:51:51 +04:00
if show is None :
show = options . verbose
if show :
2017-01-11 17:02:17 +03:00
do_print ( " Running: ' %s ' in ' %s ' " % ( cmd , dir ) )
2010-09-26 22:46:01 +04:00
if output :
autobuild: use close_fds=True to avoid *.stderr and *.stdout inheriting into every process
This closes fds other than 0, 1, 2.
This ensures only the correct *.stderr and *.stdout is attached, via
the stdout/stderr parameter to Popen(), but not every other FD
currently open in python at the time Popen is called.
For the tail invocation and other calls to Popen(), because fds 0, 1,
2 are still attached, these function as before.
Per https://docs.python.org/2.6/library/subprocess.html:
"If close_fds is true, all file descriptors except 0, 1 and
2 will be closed before the child process is executed. (Unix only)."
And regarding the passed in parameters:
"stdin, stdout and stderr specify the executed programs’ standard
input,
standard output and standard error file handles, respectively. "
...
"With None (the default), no redirection will occur;
the child’s file handles will be inherited from the parent. "
(The unwanted inherited files would be on a random high FD, where the
program wouldn't know what to do with them, but counting towards the
process FD limit).
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13591
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
2018-08-27 12:00:58 +03:00
return Popen ( [ cmd ] , shell = True , stdout = PIPE , cwd = dir , close_fds = True ) . communicate ( ) [ 0 ]
2010-10-01 19:45:47 +04:00
elif checkfail :
2010-10-01 22:12:24 +04:00
return check_call ( cmd , shell = True , cwd = dir )
2010-10-01 19:45:47 +04:00
else :
2010-10-01 22:12:24 +04:00
return call ( cmd , shell = True , cwd = dir )
2010-10-01 19:45:47 +04:00
2010-09-25 23:51:51 +04:00
2010-10-01 14:19:56 +04:00
class builder ( object ) :
2010-09-25 23:51:51 +04:00
''' handle build of one directory '''
2010-10-01 14:19:56 +04:00
2018-08-16 04:48:21 +03:00
def __init__ ( self , name , sequence , cp = True , py3 = False ) :
2010-09-25 23:51:51 +04:00
self . name = name
2018-08-16 04:48:21 +03:00
self . py3 = py3
2018-08-16 04:54:14 +03:00
if name in builddirs :
self . dir = builddirs [ name ]
else :
self . dir = " . "
2010-09-26 04:35:55 +04:00
2010-09-25 23:51:51 +04:00
self . tag = self . name . replace ( ' / ' , ' _ ' )
self . sequence = sequence
self . next = 0
2010-09-30 21:41:36 +04:00
self . stdout_path = " %s / %s .stdout " % ( gitroot , self . tag )
self . stderr_path = " %s / %s .stderr " % ( gitroot , self . tag )
if options . verbose :
2017-01-11 17:02:17 +03:00
do_print ( " stdout for %s in %s " % ( self . name , self . stdout_path ) )
do_print ( " stderr for %s in %s " % ( self . name , self . stderr_path ) )
2010-09-25 23:51:51 +04:00
run_cmd ( " rm -f %s %s " % ( self . stdout_path , self . stderr_path ) )
self . stdout = open ( self . stdout_path , ' w ' )
self . stderr = open ( self . stderr_path , ' w ' )
self . stdin = open ( " /dev/null " , ' r ' )
2010-09-26 01:09:11 +04:00
self . sdir = " %s / %s " % ( testbase , self . tag )
2016-12-16 15:35:01 +03:00
self . prefix = " %s / %s " % ( test_prefix , self . tag )
2010-09-25 23:51:51 +04:00
run_cmd ( " rm -rf %s " % self . sdir )
2017-01-11 16:42:08 +03:00
run_cmd ( " rm -rf %s " % self . prefix )
2016-01-04 04:20:54 +03:00
if cp :
run_cmd ( " cp --recursive --link --archive %s %s " % ( test_master , self . sdir ) , dir = test_master , show = True )
else :
run_cmd ( " git clone --recursive --shared %s %s " % ( test_master , self . sdir ) , dir = test_master , show = True )
2010-09-25 23:51:51 +04:00
self . start_next ( )
def start_next ( self ) :
if self . next == len ( self . sequence ) :
2017-01-11 16:42:08 +03:00
if not options . nocleanup :
run_cmd ( " rm -rf %s " % self . sdir )
run_cmd ( " rm -rf %s " % self . prefix )
2017-01-11 17:02:17 +03:00
do_print ( ' %s : Completed OK ' % self . name )
2010-09-25 23:51:51 +04:00
self . done = True
return
2010-10-01 14:19:56 +04:00
( self . stage , self . cmd , self . output_mime_type ) = self . sequence [ self . next ]
2018-11-24 14:13:47 +03:00
self . cmd = self . cmd . replace ( " $ {PYTHON_PREFIX} " , get_python_lib ( plat_specific = 1 , standard_lib = 0 , prefix = self . prefix ) )
2010-10-01 14:19:56 +04:00
self . cmd = self . cmd . replace ( " $ {PREFIX} " , " --prefix= %s " % self . prefix )
2018-08-16 04:50:31 +03:00
if self . py3 :
self . cmd = self . cmd . replace ( " $ {EXTRA_PYTHON} " , " %s " % extra_python )
# The trailing space is important
self . cmd = self . cmd . replace ( " $ {PY3_ONLY} " , " python3 " )
else :
self . cmd = self . cmd . replace ( " $ {EXTRA_PYTHON} " , " " )
self . cmd = self . cmd . replace ( " $ {PY3_ONLY} " , " " )
2011-01-05 11:30:48 +03:00
self . cmd = self . cmd . replace ( " $ {PREFIX_DIR} " , " %s " % self . prefix )
2016-07-27 05:28:04 +03:00
self . cmd = self . cmd . replace ( " $ {TESTS} " , options . restrict_tests )
2010-10-01 22:31:28 +04:00
# if self.output_mime_type == "text/x-subunit":
# self.cmd += " | %s --immediate" % (os.path.join(os.path.dirname(__file__), "selftest/format-subunit"))
2010-09-25 23:51:51 +04:00
cwd = os . getcwd ( )
2010-09-26 02:30:13 +04:00
os . chdir ( " %s / %s " % ( self . sdir , self . dir ) )
2017-04-13 19:46:50 +03:00
do_print ( ' %s : [ %s ] Running %s in %r ' % ( self . name , self . stage , self . cmd , os . getcwd ( ) ) )
2010-09-25 23:51:51 +04:00
self . proc = Popen ( self . cmd , shell = True ,
autobuild: use close_fds=True to avoid *.stderr and *.stdout inheriting into every process
This closes fds other than 0, 1, 2.
This ensures only the correct *.stderr and *.stdout is attached, via
the stdout/stderr parameter to Popen(), but not every other FD
currently open in python at the time Popen is called.
For the tail invocation and other calls to Popen(), because fds 0, 1,
2 are still attached, these function as before.
Per https://docs.python.org/2.6/library/subprocess.html:
"If close_fds is true, all file descriptors except 0, 1 and
2 will be closed before the child process is executed. (Unix only)."
And regarding the passed in parameters:
"stdin, stdout and stderr specify the executed programs’ standard
input,
standard output and standard error file handles, respectively. "
...
"With None (the default), no redirection will occur;
the child’s file handles will be inherited from the parent. "
(The unwanted inherited files would be on a random high FD, where the
program wouldn't know what to do with them, but counting towards the
process FD limit).
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13591
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
2018-08-27 12:00:58 +03:00
close_fds = True ,
2010-09-25 23:51:51 +04:00
stdout = self . stdout , stderr = self . stderr , stdin = self . stdin )
os . chdir ( cwd )
self . next + = 1
2010-10-01 14:19:56 +04:00
class buildlist ( object ) :
2010-09-25 23:51:51 +04:00
''' handle build of multiple directories '''
2010-10-01 14:19:56 +04:00
2016-07-27 05:09:08 +03:00
def __init__ ( self , tasknames , rebase_url , rebase_branch = " master " ) :
2010-09-26 03:18:00 +04:00
global tasks
2010-09-25 23:51:51 +04:00
self . tlist = [ ]
self . tail_proc = None
2010-09-26 04:35:55 +04:00
self . retry = None
2010-09-25 23:51:51 +04:00
if tasknames == [ ] :
2016-07-27 05:28:04 +03:00
if options . restrict_tests :
tasknames = [ " samba-test-only " ]
else :
tasknames = defaulttasks
2015-04-14 02:59:57 +03:00
else :
# If we are only running one test,
# do not sleep randomly to wait for it to start
os . environ [ ' AUTOBUILD_RANDOM_SLEEP_OVERRIDE ' ] = ' 1 '
2010-09-25 23:51:51 +04:00
for n in tasknames :
2018-08-27 04:30:37 +03:00
if n not in tasks and n . endswith ( " -py3 " ) :
2018-08-16 04:48:21 +03:00
b = builder ( n ,
tasks [ n [ : - 4 ] ] ,
cp = n is not " pidl " ,
py3 = True )
else :
b = builder ( n , tasks [ n ] , cp = n is not " pidl " )
2010-09-25 23:51:51 +04:00
self . tlist . append ( b )
2010-09-26 04:35:55 +04:00
if options . retry :
2012-09-22 02:23:21 +04:00
rebase_remote = " rebaseon "
2018-07-30 09:16:43 +03:00
retry_task = [ ( " retry " ,
2012-09-22 02:23:21 +04:00
''' set -e
git remote add - t % s % s % s
git fetch % s
while : ; do
sleep 60
git describe % s / % s > old_remote_branch . desc
git fetch % s
git describe % s / % s > remote_branch . desc
diff old_remote_branch . desc remote_branch . desc
done
''' % (
2018-07-30 09:14:13 +03:00
rebase_branch , rebase_remote , rebase_url ,
2012-09-22 02:23:21 +04:00
rebase_remote ,
rebase_remote , rebase_branch ,
rebase_remote ,
rebase_remote , rebase_branch
2018-07-30 09:14:37 +03:00
) ,
2018-07-30 09:17:02 +03:00
" test/plain " ) ]
2012-09-22 02:23:21 +04:00
2016-01-04 04:20:54 +03:00
self . retry = builder ( ' retry ' , retry_task , cp = False )
2010-09-26 04:35:55 +04:00
self . need_retry = False
2010-09-25 23:51:51 +04:00
def kill_kids ( self ) :
2010-09-26 04:35:55 +04:00
if self . tail_proc is not None :
self . tail_proc . terminate ( )
self . tail_proc . wait ( )
self . tail_proc = None
if self . retry is not None :
self . retry . proc . terminate ( )
self . retry . proc . wait ( )
self . retry = None
2010-09-25 23:51:51 +04:00
for b in self . tlist :
if b . proc is not None :
2010-09-26 23:50:06 +04:00
run_cmd ( " killbysubdir %s > /dev/null 2>&1 " % b . sdir , checkfail = False )
2010-09-25 23:51:51 +04:00
b . proc . terminate ( )
b . proc . wait ( )
b . proc = None
def wait_one ( self ) :
while True :
none_running = True
for b in self . tlist :
if b . proc is None :
continue
none_running = False
b . status = b . proc . poll ( )
if b . status is None :
continue
b . proc = None
return b
2010-09-26 04:35:55 +04:00
if options . retry :
ret = self . retry . proc . poll ( )
if ret is not None :
self . need_retry = True
self . retry = None
return None
2010-09-25 23:51:51 +04:00
if none_running :
return None
time . sleep ( 0.1 )
def run ( self ) :
while True :
b = self . wait_one ( )
2010-09-26 04:35:55 +04:00
if options . retry and self . need_retry :
self . kill_kids ( )
2017-01-11 17:02:17 +03:00
do_print ( " retry needed " )
2010-10-02 04:58:47 +04:00
return ( 0 , None , None , None , " retry " )
2010-09-25 23:51:51 +04:00
if b is None :
break
if os . WIFSIGNALED ( b . status ) or os . WEXITSTATUS ( b . status ) != 0 :
self . kill_kids ( )
2010-10-01 14:19:56 +04:00
return ( b . status , b . name , b . stage , b . tag , " %s : [ %s ] failed ' %s ' with status %d " % ( b . name , b . stage , b . cmd , b . status ) )
2010-09-25 23:51:51 +04:00
b . start_next ( )
self . kill_kids ( )
2010-10-01 14:19:56 +04:00
return ( 0 , None , None , None , " All OK " )
2010-09-25 23:51:51 +04:00
2015-07-01 01:45:47 +03:00
def write_system_info ( self ) :
filename = ' system-info.txt '
f = open ( filename , ' w ' )
2018-05-18 06:57:39 +03:00
for cmd in [ ' uname -a ' , ' free ' , ' cat /proc/cpuinfo ' ,
' cc --version ' , ' df -m . ' , ' df -m %s ' % testbase ] :
2018-03-09 17:06:21 +03:00
print ( ' ### %s ' % cmd , file = f )
print ( run_cmd ( cmd , output = True , checkfail = False ) , file = f )
print ( file = f )
2015-07-01 01:45:47 +03:00
f . close ( )
return filename
2010-09-25 23:51:51 +04:00
def tarlogs ( self , fname ) :
tar = tarfile . open ( fname , " w:gz " )
for b in self . tlist :
tar . add ( b . stdout_path , arcname = " %s .stdout " % b . tag )
tar . add ( b . stderr_path , arcname = " %s .stderr " % b . tag )
2010-10-06 13:15:48 +04:00
if os . path . exists ( " autobuild.log " ) :
tar . add ( " autobuild.log " )
2015-07-01 01:45:47 +03:00
sys_info = self . write_system_info ( )
tar . add ( sys_info )
2010-09-25 23:51:51 +04:00
tar . close ( )
def remove_logs ( self ) :
for b in self . tlist :
os . unlink ( b . stdout_path )
os . unlink ( b . stderr_path )
def start_tail ( self ) :
2018-08-27 12:13:29 +03:00
cmd = [ " tail " , " -f " ]
for b in self . tlist :
cmd . append ( b . stdout_path )
cmd . append ( b . stderr_path )
self . tail_proc = Popen ( cmd , close_fds = True )
2010-09-25 23:51:51 +04:00
def cleanup ( ) :
2010-09-26 02:30:13 +04:00
if options . nocleanup :
return
2017-02-21 19:05:08 +03:00
run_cmd ( " stat %s || true " % test_tmpdir , show = True )
2017-01-11 16:13:00 +03:00
run_cmd ( " stat %s " % testbase , show = True )
2017-04-13 19:46:50 +03:00
do_print ( " Cleaning up %r " % cleanup_list )
2010-09-25 23:51:51 +04:00
for d in cleanup_list :
run_cmd ( " rm -rf %s " % d )
def find_git_root ( ) :
''' get to the top of the git repo '''
2018-07-30 09:18:03 +03:00
p = os . getcwd ( )
2010-09-29 04:38:18 +04:00
while p != ' / ' :
if os . path . isdir ( os . path . join ( p , " .git " ) ) :
return p
p = os . path . abspath ( os . path . join ( p , ' .. ' ) )
2010-09-25 23:51:51 +04:00
return None
2010-09-29 04:38:18 +04:00
2010-10-01 04:53:38 +04:00
def daemonize ( logfile ) :
pid = os . fork ( )
2018-07-30 09:19:33 +03:00
if pid == 0 : # Parent
2010-10-01 04:53:38 +04:00
os . setsid ( )
pid = os . fork ( )
2018-07-30 09:19:33 +03:00
if pid != 0 : # Actual daemon
2010-10-01 04:53:38 +04:00
os . _exit ( 0 )
2018-07-30 09:19:33 +03:00
else : # Grandparent
2010-10-01 04:53:38 +04:00
os . _exit ( 0 )
import resource # Resource usage information.
maxfd = resource . getrlimit ( resource . RLIMIT_NOFILE ) [ 1 ]
if maxfd == resource . RLIM_INFINITY :
2018-07-30 09:19:33 +03:00
maxfd = 1024 # Rough guess at maximum number of open file descriptors.
2010-10-01 04:53:38 +04:00
for fd in range ( 0 , maxfd ) :
try :
os . close ( fd )
except OSError :
pass
os . open ( logfile , os . O_RDWR | os . O_CREAT )
os . dup2 ( 0 , 1 )
os . dup2 ( 0 , 2 )
2018-07-30 09:20:39 +03:00
2010-10-20 02:44:03 +04:00
def write_pidfile ( fname ) :
''' write a pid file, cleanup on exit '''
f = open ( fname , mode = ' w ' )
f . write ( " %u \n " % os . getpid ( ) )
f . close ( )
2010-10-01 04:53:38 +04:00
2018-07-30 09:19:21 +03:00
def rebase_tree ( rebase_url , rebase_branch = " master " ) :
2012-09-22 02:23:21 +04:00
rebase_remote = " rebaseon "
2017-01-11 17:02:17 +03:00
do_print ( " Rebasing on %s " % rebase_url )
2011-02-07 03:41:21 +03:00
run_cmd ( " git describe HEAD " , show = True , dir = test_master )
2012-09-22 02:23:21 +04:00
run_cmd ( " git remote add -t %s %s %s " %
( rebase_branch , rebase_remote , rebase_url ) ,
show = True , dir = test_master )
run_cmd ( " git fetch %s " % rebase_remote , show = True , dir = test_master )
2010-09-26 03:18:00 +04:00
if options . fix_whitespace :
2014-02-17 12:15:30 +04:00
run_cmd ( " git rebase --force-rebase --whitespace=fix %s / %s " %
2012-09-22 02:23:21 +04:00
( rebase_remote , rebase_branch ) ,
show = True , dir = test_master )
2010-09-26 03:18:00 +04:00
else :
2014-02-17 12:15:30 +04:00
run_cmd ( " git rebase --force-rebase %s / %s " %
2012-09-22 02:23:21 +04:00
( rebase_remote , rebase_branch ) ,
show = True , dir = test_master )
diff = run_cmd ( " git --no-pager diff HEAD %s / %s " %
( rebase_remote , rebase_branch ) ,
dir = test_master , output = True )
2010-09-26 22:46:01 +04:00
if diff == ' ' :
2017-01-11 17:02:17 +03:00
do_print ( " No differences between HEAD and %s / %s - exiting " %
2018-07-30 09:16:12 +03:00
( rebase_remote , rebase_branch ) )
2010-09-26 22:46:01 +04:00
sys . exit ( 0 )
2012-09-22 02:23:21 +04:00
run_cmd ( " git describe %s / %s " %
( rebase_remote , rebase_branch ) ,
show = True , dir = test_master )
2011-02-07 03:41:21 +03:00
run_cmd ( " git describe HEAD " , show = True , dir = test_master )
2012-09-22 02:23:21 +04:00
run_cmd ( " git --no-pager diff --stat HEAD %s / %s " %
( rebase_remote , rebase_branch ) ,
show = True , dir = test_master )
2010-09-26 01:09:11 +04:00
2018-07-30 09:20:39 +03:00
2018-07-30 09:19:21 +03:00
def push_to ( push_url , push_branch = " master " ) :
2012-09-22 04:18:11 +04:00
push_remote = " pushto "
2017-01-11 17:02:17 +03:00
do_print ( " Pushing to %s " % push_url )
2010-09-26 02:30:13 +04:00
if options . mark :
2010-10-03 18:53:45 +04:00
run_cmd ( " git config --replace-all core.editor script/commit_mark.sh " , dir = test_master )
run_cmd ( " git commit --amend -c HEAD " , dir = test_master )
2010-10-01 01:42:02 +04:00
# the notes method doesn't work yet, as metze hasn't allowed refs/notes/* in master
# run_cmd("EDITOR=script/commit_mark.sh git notes edit HEAD", dir=test_master)
2012-09-22 04:18:11 +04:00
run_cmd ( " git remote add -t %s %s %s " %
( push_branch , push_remote , push_url ) ,
show = True , dir = test_master )
run_cmd ( " git push %s +HEAD: %s " %
( push_remote , push_branch ) ,
show = True , dir = test_master )
2010-09-26 02:30:13 +04:00
2018-07-30 09:21:29 +03:00
2010-09-26 01:09:11 +04:00
def_testbase = os . getenv ( " AUTOBUILD_TESTBASE " , " /memdisk/ %s " % os . getenv ( ' USER ' ) )
2010-09-25 23:51:51 +04:00
2012-09-24 13:53:22 +04:00
gitroot = find_git_root ( )
if gitroot is None :
raise Exception ( " Failed to find git root " )
2010-09-25 23:51:51 +04:00
parser = OptionParser ( )
parser . add_option ( " " , " --tail " , help = " show output while running " , default = False , action = " store_true " )
parser . add_option ( " " , " --keeplogs " , help = " keep logs " , default = False , action = " store_true " )
2010-09-26 02:30:13 +04:00
parser . add_option ( " " , " --nocleanup " , help = " don ' t remove test tree " , default = False , action = " store_true " )
2010-09-25 23:51:51 +04:00
parser . add_option ( " " , " --testbase " , help = " base directory to run tests in (default %s ) " % def_testbase ,
default = def_testbase )
2010-09-26 02:30:13 +04:00
parser . add_option ( " " , " --passcmd " , help = " command to run on success " , default = None )
2010-09-25 23:51:51 +04:00
parser . add_option ( " " , " --verbose " , help = " show all commands as they are run " ,
default = False , action = " store_true " )
2010-09-26 01:09:11 +04:00
parser . add_option ( " " , " --rebase " , help = " rebase on the given tree before testing " ,
default = None , type = ' str ' )
2010-09-26 02:30:13 +04:00
parser . add_option ( " " , " --pushto " , help = " push to a git url on success " ,
default = None , type = ' str ' )
parser . add_option ( " " , " --mark " , help = " add a Tested-By signoff before pushing " ,
default = False , action = " store_true " )
2010-09-26 03:18:00 +04:00
parser . add_option ( " " , " --fix-whitespace " , help = " fix whitespace on rebase " ,
default = False , action = " store_true " )
2010-09-26 04:35:55 +04:00
parser . add_option ( " " , " --retry " , help = " automatically retry if master changes " ,
default = False , action = " store_true " )
2010-09-30 21:41:36 +04:00
parser . add_option ( " " , " --email " , help = " send email to the given address on failure " ,
type = ' str ' , default = None )
2015-04-14 08:18:02 +03:00
parser . add_option ( " " , " --email-from " , help = " send email from the given address " ,
type = ' str ' , default = " autobuild@samba.org " )
parser . add_option ( " " , " --email-server " , help = " send email via the given server " ,
type = ' str ' , default = ' localhost ' )
2010-10-01 13:28:48 +04:00
parser . add_option ( " " , " --always-email " , help = " always send email, even on success " ,
action = " store_true " )
2010-10-01 04:53:38 +04:00
parser . add_option ( " " , " --daemon " , help = " daemonize after initial setup " ,
action = " store_true " )
2012-09-22 04:26:10 +04:00
parser . add_option ( " " , " --branch " , help = " the branch to work on (default=master) " ,
default = " master " , type = ' str ' )
2012-09-22 04:40:19 +04:00
parser . add_option ( " " , " --log-base " , help = " location where the logs can be found (default=cwd) " ,
2012-09-24 13:53:22 +04:00
default = gitroot , type = ' str ' )
2015-04-14 08:18:02 +03:00
parser . add_option ( " " , " --attach-logs " , help = " Attach logs to mails sent on success/failure? " ,
default = False , action = " store_true " )
2016-07-27 05:28:04 +03:00
parser . add_option ( " " , " --restrict-tests " , help = " run as make test with this TESTS= regex " ,
default = ' ' )
2015-04-14 08:18:02 +03:00
2018-07-30 09:20:39 +03:00
2015-04-14 08:18:02 +03:00
def send_email ( subject , text , log_tar ) :
2018-03-23 01:24:16 +03:00
if options . email is None :
do_print ( " not sending email because the recipient is not set " )
2018-09-03 13:20:31 +03:00
do_print ( " the text content would have been: \n \n Subject: %s \n \n %s " %
2018-03-23 01:24:16 +03:00
( subject , text ) )
return
2015-04-14 08:18:02 +03:00
outer = MIMEMultipart ( )
outer [ ' Subject ' ] = subject
outer [ ' To ' ] = options . email
outer [ ' From ' ] = options . email_from
2018-07-30 09:19:21 +03:00
outer [ ' Date ' ] = email . utils . formatdate ( localtime = True )
2015-04-14 08:18:02 +03:00
outer . preamble = ' Autobuild mails are now in MIME because we optionally attach the logs. \n '
outer . attach ( MIMEText ( text , ' plain ' ) )
if options . attach_logs :
fp = open ( log_tar , ' rb ' )
msg = MIMEApplication ( fp . read ( ) , ' gzip ' , email . encoders . encode_base64 )
fp . close ( )
# Set the filename parameter
msg . add_header ( ' Content-Disposition ' , ' attachment ' , filename = os . path . basename ( log_tar ) )
outer . attach ( msg )
content = outer . as_string ( )
s = smtplib . SMTP ( options . email_server )
s . sendmail ( options . email_from , [ options . email ] , content )
s . set_debuglevel ( 1 )
s . quit ( )
2010-09-30 21:41:36 +04:00
2018-07-30 09:20:39 +03:00
2015-05-28 04:46:23 +03:00
def email_failure ( status , failed_task , failed_stage , failed_tag , errstr ,
2016-03-14 04:18:54 +03:00
elapsed_time , log_base = None , add_log_tail = True ) :
2010-09-30 21:41:36 +04:00
''' send an email to options.email about the failure '''
2015-05-28 04:46:23 +03:00
elapsed_minutes = elapsed_time / 60.0
2012-09-22 04:34:38 +04:00
if log_base is None :
2012-09-24 13:53:22 +04:00
log_base = gitroot
2010-09-30 21:41:36 +04:00
text = '''
Dear Developer ,
2015-05-28 04:46:23 +03:00
Your autobuild on % s failed after % .1 f minutes
when trying to test % s with the following error :
2010-09-30 21:41:36 +04:00
% s
the autobuild has been abandoned . Please fix the error and resubmit .
2010-10-12 06:06:43 +04:00
A summary of the autobuild process is here :
2012-09-22 04:34:38 +04:00
% s / autobuild . log
2015-05-28 04:46:23 +03:00
''' % (platform.node(), elapsed_minutes, failed_task, errstr, log_base)
2015-05-04 10:21:53 +03:00
2016-07-27 05:28:04 +03:00
if options . restrict_tests :
text + = """
The build was restricted to tests matching % s \n """ % o ptions.restrict_tests
2010-10-12 06:06:43 +04:00
if failed_task != ' rebase ' :
text + = '''
2010-09-30 21:41:36 +04:00
You can see logs of the failed task here :
2010-09-25 23:51:51 +04:00
2012-09-22 04:34:38 +04:00
% s / % s . stdout
% s / % s . stderr
2010-09-30 21:41:36 +04:00
or you can get full logs of all tasks in this job here :
2012-09-22 04:34:38 +04:00
% s / logs . tar . gz
2010-09-30 21:41:36 +04:00
2010-10-02 06:53:34 +04:00
The top commit for the tree that was built was :
% s
2012-09-22 04:34:38 +04:00
''' % (log_base, failed_tag, log_base, failed_tag, log_base, top_commit_msg)
2015-04-14 08:18:02 +03:00
2016-03-14 04:18:54 +03:00
if add_log_tail :
f = open ( " %s / %s .stdout " % ( gitroot , failed_tag ) , ' r ' )
lines = f . readlines ( )
log_tail = " " . join ( lines [ - 50 : ] )
num_lines = len ( lines )
if num_lines < 50 :
# Also include stderr (compile failures) if < 50 lines of stdout
f = open ( " %s / %s .stderr " % ( gitroot , failed_tag ) , ' r ' )
2018-07-30 09:18:25 +03:00
log_tail + = " " . join ( f . readlines ( ) [ - ( 50 - num_lines ) : ] )
2016-03-14 04:18:54 +03:00
text + = '''
The last 50 lines of log messages :
% s
''' % lo g_tail
f . close ( )
2015-04-14 08:18:02 +03:00
logs = os . path . join ( gitroot , ' logs.tar.gz ' )
2016-08-10 13:44:26 +03:00
send_email ( ' autobuild[ %s ] failure on %s for task %s during %s '
% ( options . branch , platform . node ( ) , failed_task , failed_stage ) ,
2015-04-14 08:18:02 +03:00
text , logs )
2010-09-25 23:51:51 +04:00
2018-07-30 09:20:39 +03:00
2015-05-28 04:46:23 +03:00
def email_success ( elapsed_time , log_base = None ) :
2010-10-01 13:28:48 +04:00
''' send an email to options.email about a successful build '''
2012-09-22 04:34:38 +04:00
if log_base is None :
2012-09-24 13:53:22 +04:00
log_base = gitroot
2010-10-01 13:28:48 +04:00
text = '''
Dear Developer ,
2015-05-28 04:46:23 +03:00
Your autobuild on % s has succeeded after % .1 f minutes .
2010-10-01 13:28:48 +04:00
2015-05-28 04:46:23 +03:00
''' % (platform.node(), elapsed_time / 60.)
2010-10-01 13:28:48 +04:00
2016-07-27 05:28:04 +03:00
if options . restrict_tests :
text + = """
The build was restricted to tests matching % s \n """ % o ptions.restrict_tests
2010-10-01 13:28:48 +04:00
if options . keeplogs :
text + = '''
you can get full logs of all tasks in this job here :
2012-09-22 04:34:38 +04:00
% s / logs . tar . gz
2010-10-01 13:28:48 +04:00
2012-09-22 04:34:38 +04:00
''' % lo g_base
2010-10-02 06:53:34 +04:00
text + = '''
The top commit for the tree that was built was :
% s
''' % top_commit_msg
2015-04-14 08:18:02 +03:00
logs = os . path . join ( gitroot , ' logs.tar.gz ' )
2016-08-10 13:44:26 +03:00
send_email ( ' autobuild[ %s ] success on %s ' % ( options . branch , platform . node ( ) ) ,
2015-04-14 08:18:02 +03:00
text , logs )
2010-10-01 13:28:48 +04:00
2010-09-25 23:51:51 +04:00
( options , args ) = parser . parse_args ( )
2010-09-26 04:35:55 +04:00
if options . retry :
2012-09-23 02:50:48 +04:00
if options . rebase is None :
2010-09-26 04:35:55 +04:00
raise Exception ( ' You can only use --retry if you also rebase ' )
2010-09-30 21:41:36 +04:00
testbase = " %s /b %u " % ( options . testbase , os . getpid ( ) )
2010-09-26 01:09:11 +04:00
test_master = " %s /master " % testbase
2016-12-16 15:35:01 +03:00
test_prefix = " %s /prefix " % testbase
2016-12-16 15:35:36 +03:00
test_tmpdir = " %s /tmp " % testbase
os . environ [ ' TMPDIR ' ] = test_tmpdir
2010-09-25 23:51:51 +04:00
2010-10-02 06:53:34 +04:00
# get the top commit message, for emails
top_commit_msg = run_cmd ( " git log -1 " , dir = gitroot , output = True )
2010-09-25 23:51:51 +04:00
try :
2010-09-26 01:09:11 +04:00
os . makedirs ( testbase )
2018-02-14 00:35:53 +03:00
except Exception as reason :
2010-09-26 01:09:11 +04:00
raise Exception ( " Unable to create %s : %s " % ( testbase , reason ) )
cleanup_list . append ( testbase )
2010-09-25 23:51:51 +04:00
2010-10-01 04:53:38 +04:00
if options . daemon :
logfile = os . path . join ( testbase , " log " )
2017-01-11 17:02:17 +03:00
do_print ( " Forking into the background, writing progress to %s " % logfile )
2010-10-01 04:53:38 +04:00
daemonize ( logfile )
2010-10-20 02:44:03 +04:00
write_pidfile ( gitroot + " /autobuild.pid " )
2015-05-28 04:46:23 +03:00
start_time = time . time ( )
2010-09-26 04:35:55 +04:00
while True :
try :
2017-01-11 16:13:00 +03:00
run_cmd ( " rm -rf %s " % test_tmpdir , show = True )
2016-12-16 15:35:36 +03:00
os . makedirs ( test_tmpdir )
2017-03-20 06:49:34 +03:00
# The waf uninstall code removes empty directories all the way
# up the tree. Creating a file in test_tmpdir stops it from
# being removed.
run_cmd ( " touch %s " % os . path . join ( test_tmpdir ,
" .directory-is-not-empty " ) , show = True )
2017-01-11 16:13:00 +03:00
run_cmd ( " stat %s " % test_tmpdir , show = True )
run_cmd ( " stat %s " % testbase , show = True )
2015-03-28 19:15:03 +03:00
run_cmd ( " git clone --recursive --shared %s %s " % ( gitroot , test_master ) , show = True , dir = gitroot )
2012-01-24 04:43:46 +04:00
except Exception :
2010-09-26 04:35:55 +04:00
cleanup ( )
raise
try :
2010-10-12 06:06:43 +04:00
try :
if options . rebase is not None :
2012-09-23 02:50:48 +04:00
rebase_tree ( options . rebase , rebase_branch = options . branch )
2012-01-24 04:43:46 +04:00
except Exception :
2012-01-21 12:29:35 +04:00
cleanup_list . append ( gitroot + " /autobuild.pid " )
cleanup ( )
2015-05-28 04:46:23 +03:00
elapsed_time = time . time ( ) - start_time
2012-09-22 04:26:10 +04:00
email_failure ( - 1 , ' rebase ' , ' rebase ' , ' rebase ' ,
2012-09-22 04:40:19 +04:00
' rebase on %s failed ' % options . branch ,
2015-05-28 04:46:23 +03:00
elapsed_time , log_base = options . log_base )
2010-10-12 06:06:43 +04:00
sys . exit ( 1 )
2016-07-27 05:09:08 +03:00
blist = buildlist ( args , options . rebase , rebase_branch = options . branch )
2010-09-26 04:35:55 +04:00
if options . tail :
blist . start_tail ( )
2010-10-01 14:19:56 +04:00
( status , failed_task , failed_stage , failed_tag , errstr ) = blist . run ( )
2010-09-26 04:35:55 +04:00
if status != 0 or errstr != " retry " :
break
cleanup ( )
2012-01-24 04:43:46 +04:00
except Exception :
2010-09-26 04:35:55 +04:00
cleanup ( )
raise
2010-09-25 23:51:51 +04:00
2010-10-21 13:41:06 +04:00
cleanup_list . append ( gitroot + " /autobuild.pid " )
2017-01-11 16:13:00 +03:00
do_print ( errstr )
2010-09-25 23:51:51 +04:00
blist . kill_kids ( )
if options . tail :
2017-01-11 17:02:17 +03:00
do_print ( " waiting for tail to flush " )
2010-09-25 23:51:51 +04:00
time . sleep ( 1 )
2015-05-28 04:46:23 +03:00
elapsed_time = time . time ( ) - start_time
2010-09-25 23:51:51 +04:00
if status == 0 :
2010-09-26 02:30:13 +04:00
if options . passcmd is not None :
2017-01-11 17:02:17 +03:00
do_print ( " Running passcmd: %s " % options . passcmd )
2010-09-26 02:30:13 +04:00
run_cmd ( options . passcmd , dir = test_master )
if options . pushto is not None :
2012-09-22 04:26:10 +04:00
push_to ( options . pushto , push_branch = options . branch )
2015-04-14 08:18:02 +03:00
if options . keeplogs or options . attach_logs :
2010-09-25 23:51:51 +04:00
blist . tarlogs ( " logs.tar.gz " )
2017-01-11 17:02:17 +03:00
do_print ( " Logs in logs.tar.gz " )
2010-10-01 13:28:48 +04:00
if options . always_email :
2015-05-28 04:46:23 +03:00
email_success ( elapsed_time , log_base = options . log_base )
2010-09-25 23:51:51 +04:00
blist . remove_logs ( )
cleanup ( )
2017-01-11 17:02:17 +03:00
do_print ( errstr )
2010-09-25 23:51:51 +04:00
sys . exit ( 0 )
# something failed, gather a tar of the logs
blist . tarlogs ( " logs.tar.gz " )
2010-09-30 21:41:36 +04:00
if options . email is not None :
2015-05-28 04:46:23 +03:00
email_failure ( status , failed_task , failed_stage , failed_tag , errstr ,
elapsed_time , log_base = options . log_base )
2015-10-21 04:35:33 +03:00
else :
elapsed_minutes = elapsed_time / 60.0
2018-03-09 17:06:21 +03:00
print ( '''
2015-10-21 04:35:33 +03:00
####################################################################
AUTOBUILD FAILURE
2016-08-10 13:44:26 +03:00
Your autobuild [ % s ] on % s failed after % .1 f minutes
2015-10-21 04:35:33 +03:00
when trying to test % s with the following error :
% s
the autobuild has been abandoned . Please fix the error and resubmit .
####################################################################
2018-03-09 17:06:21 +03:00
''' % (options.branch, platform.node(), elapsed_minutes, failed_task, errstr))
2010-09-30 21:41:36 +04:00
2010-09-25 23:51:51 +04:00
cleanup ( )
2017-01-11 17:02:17 +03:00
do_print ( errstr )
do_print ( " Logs in logs.tar.gz " )
2010-09-30 20:37:42 +04:00
sys . exit ( status )