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
2010-10-01 19:45:47 +04:00
from subprocess import call , check_call , Popen , PIPE
2010-10-01 16:25:55 +04:00
import os , tarfile , sys , 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
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 = {
2011-10-13 00:27:55 +04:00
" ctdb " : " ctdb " ,
2012-06-20 15:22:18 +04:00
" samba " : " . " ,
2017-06-30 02:15:40 +03:00
" samba-nt4 " : " . " ,
2018-03-04 11:32:09 +03:00
" samba-fileserver " : " . " ,
2015-05-04 10:21:53 +03:00
" samba-xc " : " . " ,
2016-03-22 20:14:17 +03:00
" samba-o3 " : " . " ,
2012-06-20 16:05:50 +04:00
" samba-ctdb " : " . " ,
2012-06-20 15:23:04 +04:00
" samba-libs " : " . " ,
2015-10-22 00:35:47 +03:00
" samba-static " : " . " ,
2016-07-27 05:28:04 +03:00
" samba-test-only " : " . " ,
2018-03-03 09:51:29 +03:00
" samba-none-env " : " . " ,
2017-06-30 02:13:55 +03:00
" samba-ad-dc " : " . " ,
2018-03-20 21:02:42 +03:00
" samba-ad-dc-2 " : " . " ,
2016-09-26 03:46:56 +03:00
" samba-systemkrb5 " : " . " ,
2017-01-30 17:36:31 +03:00
" samba-nopython " : " . " ,
2011-07-05 04:01:32 +04:00
" ldb " : " lib/ldb " ,
2011-02-07 02:05:32 +03:00
" tdb " : " lib/tdb " ,
" talloc " : " lib/talloc " ,
" replace " : " lib/replace " ,
" tevent " : " lib/tevent " ,
" pidl " : " pidl " ,
" pass " : " . " ,
2011-02-07 03:41:21 +03:00
" fail " : " . " ,
" retry " : " . "
2018-07-30 09:14:37 +03:00
}
2011-02-07 02:05:32 +03:00
2017-07-21 10:54:36 +03:00
defaulttasks = [ " ctdb " ,
" samba " ,
2017-06-30 02:15:40 +03:00
" samba-nt4 " ,
2018-03-04 11:32:09 +03:00
" samba-fileserver " ,
2017-07-21 10:54:36 +03:00
" samba-xc " ,
" samba-o3 " ,
" samba-ctdb " ,
" samba-libs " ,
" samba-static " ,
2018-03-03 09:51:29 +03:00
" samba-none-env " ,
2017-06-30 02:13:55 +03:00
" samba-ad-dc " ,
2018-03-20 21:02:42 +03:00
" samba-ad-dc-2 " ,
2017-07-21 10:54:36 +03:00
" samba-systemkrb5 " ,
" samba-nopython " ,
" ldb " ,
" tdb " ,
" talloc " ,
" replace " ,
" tevent " ,
" pidl " ]
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
2015-08-13 18:34:42 +03:00
samba_libs_envvars = " PYTHONPATH=$ {PYTHON_PREFIX} /site-packages:$PYTHONPATH "
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 = {
2011-10-13 00:27:55 +04: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 " ) ,
( " clean " , " make clean " , " text/plain " ) ] ,
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)'
2015-05-04 10:21:53 +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 "
2017-06-30 02:15:40 +03:00
" TESTS= ' --exclude-env=none "
" --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-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-03-04 11:32:09 +03:00
" --exclude-env=fileserver ' " ,
" 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 " ) ,
( " 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-05 02:09:50 +03:00
" samba-nt4 " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
( " configure " , " ./configure.developer --without-ads --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
( " make " , " make -j " , " text/plain " ) ,
( " test " , " make test FAIL_IMMEDIATELY=1 TESTS= ' --include-env=nt4_dc --include-env=nt4_member ' " , " text/plain " ) ,
( " install " , " make install " , " text/plain " ) ,
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ,
( " 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-05 02:09:50 +03:00
" samba-fileserver " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
2018-07-30 09:16:12 +03:00
( " configure " , " ./configure.developer --without-ad-dc --without-ldap --without-ads --without-json-audit --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
( " make " , " make -j " , " text/plain " ) ,
( " test " , " make test FAIL_IMMEDIATELY=1 TESTS= ' --include-env=fileserver ' " , " text/plain " ) ,
( " 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-05 02:09:50 +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-03-21 22:25:41 +03:00
( " test " , " make test FAIL_IMMEDIATELY=1 TESTS= ' "
" --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-05 02:09:50 +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 " ) ,
( " test " , " make test FAIL_IMMEDIATELY=1 TESTS= ' --include-env=chgdcpass --include-env=vampire_2000_dc --include-env=fl2000dc ' " , " text/plain " ) ,
( " check-clean-tree " , " script/clean-source-tree.sh " , " text/plain " ) ] ,
2018-03-20 21:02:42 +03:00
2016-07-27 05:28:04 +03:00
" samba-test-only " : [ ( " configure " , " ./configure.developer --with-selftest-prefix=./bin/ab --abi-check-disable " + samba_configure_params , " text/plain " ) ,
( " make " , " make -j " , " text/plain " ) ,
2017-12-19 03:14:41 +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-05 02:09:50 +03:00
" samba-xc " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
( " configure-native " , " ./configure.developer --with-selftest-prefix=./bin/ab " + samba_configure_params , " text/plain " ) ,
2015-05-04 10:21:53 +03:00
( " configure-cross-execute " , " ./configure.developer -b ./bin-xe --cross-compile --cross-execute=script/identity_cc.sh " \
" --cross-answers=./bin-xe/cross-answers.txt --with-selftest-prefix=./bin-xe/ab " + samba_configure_params , " text/plain " ) ,
( " configure-cross-answers " , " ./configure.developer -b ./bin-xa --cross-compile " \
" --cross-answers=./bin-xe/cross-answers.txt --with-selftest-prefix=./bin-xa/ab " + samba_configure_params , " text/plain " ) ,
( " compare-results " , " script/compare_cc_results.py ./bin/c4che/default.cache.py ./bin-xe/c4che/default.cache.py ./bin-xa/c4che/default.cache.py " , " text/plain " ) ] ,
2017-06-30 02:11:05 +03:00
# test build with -O3 -- catches extra warnings and bugs, tests the ad_dc environments
2018-07-05 02:09:50 +03:00
" samba-o3 " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
2016-08-26 03:07:34 +03:00
( " configure " , " ADDITIONAL_CFLAGS= ' -O3 ' ./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 " ) ,
2017-06-30 02:11:05 +03:00
( " test " , " make quicktest FAIL_IMMEDIATELY=1 TESTS= ' --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 " ) ,
( " clean " , " make clean " , " text/plain " ) ] ,
2015-05-04 10:21:53 +03:00
2012-06-20 16:05:50 +04:00
" samba-ctdb " : [ ( " random-sleep " , " script/random-sleep.sh 60 600 " , " text/plain " ) ,
# make sure we have tdb around:
( " tdb-configure " , " cd lib/tdb && PYTHONPATH=$ {PYTHON_PREFIX} /site-packages:$PYTHONPATH PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$ {PREFIX_DIR} /lib/pkgconfig ./configure --bundled-libraries=NONE --abi-check --enable-debug -C $ {PREFIX} " , " text/plain " ) ,
( " 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):
2014-12-08 12:30:56 +03:00
( " samba-configure " , " PYTHONPATH=$ {PYTHON_PREFIX} /site-packages:$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 " ) ,
( " ctdb-clean " , " cd ./ctdb && make clean " , " text/plain " ) ] ,
2012-06-20 16:05:50 +04:00
2012-06-20 15:23:04 +04: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-03-03 09:51:29 +03:00
" samba-none-env " : [
( " 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 "
" TESTS= ' --include-env=none ' " ,
" text/plain " ) ] ,
2015-10-22 00:35:47 +03:00
" samba-static " : [
( " 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
2016-09-26 03:46:56 +03:00
" samba-systemkrb5 " : [
( " 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"
2017-06-30 02:11:05 +03:00
( " test " , " make test FAIL_IMMEDIATELY=1 TESTS= ' --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.
" samba-nopython " : [
( " 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
2012-06-20 13:03:48 +04: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 " ) ,
( " clean " , " make clean " , " text/plain " ) ] ,
2010-10-01 14:19:56 +04:00
2012-06-20 13:03:48 +04: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 " ) ,
( " clean " , " make clean " , " text/plain " ) ] ,
2012-03-07 06:32:22 +04:00
2012-06-20 13:03:48 +04: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 " ) ,
( " clean " , " make clean " , " text/plain " ) ] ,
2012-06-20 13:03:48 +04: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 " ) ,
2010-12-23 21:40:08 +03:00
( " clean " , " make clean " , " text/plain " ) ] ,
2010-10-01 14:19:56 +04:00
2012-06-20 13:03:48 +04: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 " ) ,
( " clean " , " make clean " , " text/plain " ) ] ,
2011-01-05 11:30:48 +03:00
2012-06-20 13:03:48 +04:00
" pidl " : [
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 " , " perl Makefile.PL PREFIX=$ {PREFIX_DIR} " , " text/plain " ) ,
2011-01-05 11:30:48 +03:00
( " touch " , " touch *.yp " , " text/plain " ) ,
( " make " , " make " , " text/plain " ) ,
( " test " , " make test " , " text/plain " ) ,
( " install " , " make install " , " text/plain " ) ,
2015-04-14 03:19:56 +03:00
( " checkout-yapp-generated " , " git checkout lib/Parse/Pidl/IDL.pm lib/Parse/Pidl/Expr.pm " , " text/plain " ) ,
2011-01-05 11:30:48 +03:00
( " check-clean-tree " , " ../script/clean-source-tree.sh " , " text/plain " ) ,
( " clean " , " make clean " , " text/plain " ) ] ,
2011-02-07 02:05:32 +03:00
# these are useful for debugging autobuild
' pass ' : [ ( " pass " , ' echo passing && /bin/true ' , " text/plain " ) ] ,
' fail ' : [ ( " fail " , ' echo failing && /bin/false ' , " text/plain " ) ]
2010-09-25 23:51:51 +04: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 ( )
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 :
2010-10-01 19:45:47 +04:00
return Popen ( [ cmd ] , shell = True , stdout = PIPE , cwd = dir ) . communicate ( ) [ 0 ]
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
2016-01-04 04:20:54 +03:00
def __init__ ( self , name , sequence , cp = True ) :
2010-09-25 23:51:51 +04:00
self . name = name
2011-02-07 03:41:21 +03:00
self . dir = builddirs [ name ]
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 ]
2012-04-09 08:52:03 +04:00
self . cmd = self . cmd . replace ( " $ {PYTHON_PREFIX} " , get_python_lib ( standard_lib = 1 , prefix = self . prefix ) )
2010-10-01 14:19:56 +04:00
self . cmd = self . cmd . replace ( " $ {PREFIX} " , " --prefix= %s " % self . prefix )
2016-02-01 14:55:34 +03:00
self . cmd = self . cmd . replace ( " $ {EXTRA_PYTHON} " , " %s " % extra_python )
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"))
2017-01-11 17:02:17 +03:00
do_print ( ' %s : [ %s ] Running %s ' % ( self . name , self . stage , self . cmd ) )
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 ) )
2010-09-25 23:51:51 +04:00
self . proc = Popen ( self . cmd , shell = True ,
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 :
2016-01-04 04:20:54 +03:00
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 "
retry_task = [ ( " retry " ,
''' 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:16:12 +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 ) :
cwd = os . getcwd ( )
2010-09-26 01:09:11 +04:00
cmd = " tail -f *.stdout *.stderr "
2010-10-01 06:41:50 +04:00
os . chdir ( gitroot )
2010-09-25 23:51:51 +04:00
self . tail_proc = Popen ( cmd , shell = True )
os . chdir ( cwd )
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-01-11 17:02:17 +03:00
do_print ( " Cleaning up .... " )
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 '''
2010-09-29 04:38:18 +04:00
p = os . getcwd ( )
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 ( )
if pid == 0 : # Parent
os . setsid ( )
pid = os . fork ( )
if pid != 0 : # Actual daemon
os . _exit ( 0 )
else : # Grandparent
os . _exit ( 0 )
import resource # Resource usage information.
maxfd = resource . getrlimit ( resource . RLIMIT_NOFILE ) [ 1 ]
if maxfd == resource . RLIM_INFINITY :
maxfd = 1024 # Rough guess at maximum number of open file descriptors.
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 )
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
2012-09-22 02:23:21 +04:00
def rebase_tree ( rebase_url , rebase_branch = " master " ) :
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
2012-09-22 04:18:11 +04:00
def push_to ( push_url , push_branch = " master " ) :
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
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
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 " )
do_print ( " the text content would have been: \n \n Subject: %s \n \n Ts " %
( 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
outer [ ' Date ' ] = email . utils . formatdate ( localtime = True )
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
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
2010-09-30 21:41:36 +04:00
user = os . getenv ( " USER " )
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 ' )
log_tail + = " " . join ( f . readlines ( ) [ - ( 50 - num_lines ) : ] )
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
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 '''
user = os . getenv ( " USER " )
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 )