2006-08-26 17:44:06 +02:00
#!/usr/bin/python
"""
The general idea is that tests to run are defined as a list of
actions . Each action has a unique name and can depend on other
actions to have run successfully before .
Most work is executed in directories defined and owned by these
actions . The framework only manages one directory which represents
the result of each action :
- an overview file which lists the result of each action
- for each action a directory with stderr / out and additional files
that the action can put there
"""
2008-02-11 22:28:32 +01:00
import os , sys , popen2 , traceback , re , time , smtplib , optparse , stat , shutil
2006-09-11 19:40:51 +02:00
try :
import gzip
havegzip = True
except :
havegzip = False
2006-08-26 17:44:06 +02:00
def cd ( path ) :
""" Enter directories, creating them if necessary. """
if not os . access ( path , os . F_OK ) :
os . makedirs ( path )
os . chdir ( path )
def abspath ( path ) :
""" Absolute path after expanding vars and user. """
return os . path . abspath ( os . path . expanduser ( os . path . expandvars ( path ) ) )
def del_dir ( path ) :
if not os . access ( path , os . F_OK ) :
return
for file in os . listdir ( path ) :
file_or_dir = os . path . join ( path , file )
2007-01-20 15:19:09 +01:00
# ensure directory is writable
os . chmod ( path , os . stat ( path ) [ stat . ST_MODE ] | stat . S_IRWXU )
2006-08-26 17:44:06 +02:00
if os . path . isdir ( file_or_dir ) and not os . path . islink ( file_or_dir ) :
2007-01-20 15:19:09 +01:00
del_dir ( file_or_dir ) #it's a directory recursive call to function again
2006-08-26 17:44:06 +02:00
else :
os . remove ( file_or_dir ) #it's a file, delete it
os . rmdir ( path )
2006-09-11 19:40:51 +02:00
2006-10-28 10:52:18 +02:00
def copyLog ( filename , dirname , htaccess , lineFilter = None ) :
2006-09-11 19:40:51 +02:00
""" Make a gzipped copy (if possible) with the original time stamps and find the most severe problem in it.
That line is then added as description in a . htaccess AddDescription .
"""
info = os . stat ( filename )
outname = os . path . join ( dirname , os . path . basename ( filename ) )
if True :
outname = outname + " .gz "
out = gzip . open ( outname , " wb " )
else :
out = file ( outname , " w " )
error = None
for line in file ( filename , " r " ) . readlines ( ) :
if not error and line . find ( " ERROR " ) > = 0 :
error = line
2006-10-28 10:52:18 +02:00
if lineFilter :
line = lineFilter ( line )
2006-09-11 19:40:51 +02:00
out . write ( line )
out . close ( )
os . utime ( outname , ( info [ stat . ST_ATIME ] , info [ stat . ST_MTIME ] ) )
if error :
htaccess . write ( " AddDescription \" %s \" %s \n " %
( error . strip ( ) . replace ( " \" " , " ' " ) . replace ( " < " , " < " ) . replace ( " > " , " > " ) ,
os . path . basename ( filename ) ) )
2006-08-26 17:44:06 +02:00
class Action :
""" Base class for all actions to be performed. """
2006-08-27 22:11:21 +02:00
DONE = " 0 DONE "
WARNINGS = " 1 WARNINGS "
FAILED = " 2 FAILED "
TODO = " 3 TODO "
SKIPPED = " 4 SKIPPED "
COMPLETED = ( DONE , WARNINGS )
2006-08-26 17:44:06 +02:00
def __init__ ( self , name ) :
self . name = name
self . status = self . TODO
self . summary = " "
self . dependencies = [ ]
def execute ( self ) :
""" Runs action. Throws an exeception if anything fails.
Will be called by tryexecution ( ) with stderr / stdout redirected into a file
and the current directory set to an empty temporary directory .
"""
raise Exception ( " not implemented " )
2006-08-27 22:38:39 +02:00
def tryexecution ( self , step , logs ) :
2006-08-26 17:44:06 +02:00
""" wrapper around execute which handles exceptions, directories and stdout """
if logs :
fd = - 1
oldstdout = os . dup ( 1 )
oldstderr = os . dup ( 2 )
oldout = sys . stdout
olderr = sys . stderr
cwd = os . getcwd ( )
try :
2006-08-27 22:38:39 +02:00
subdirname = " %d - %s " % ( step , self . name )
del_dir ( subdirname )
2006-08-26 17:44:06 +02:00
sys . stderr . flush ( )
sys . stdout . flush ( )
2006-08-27 22:38:39 +02:00
cd ( subdirname )
2006-08-26 17:44:06 +02:00
if logs :
fd = os . open ( " output.txt " , os . O_WRONLY | os . O_CREAT | os . O_TRUNC )
os . dup2 ( fd , 1 )
os . dup2 ( fd , 2 )
sys . stdout = os . fdopen ( fd , " w " )
sys . stderr = sys . stdout
2006-08-27 22:11:21 +02:00
print " === starting %s === " % ( self . name )
self . execute ( )
self . status = Action . DONE
2006-08-26 17:44:06 +02:00
self . summary = " okay "
except Exception , inst :
traceback . print_exc ( )
self . status = Action . FAILED
self . summary = str ( inst )
2006-08-27 22:11:21 +02:00
print " \n === %s : %s === " % ( self . name , self . status )
2006-08-26 17:44:06 +02:00
sys . stdout . flush ( )
os . chdir ( cwd )
if logs :
if fd > = 0 :
os . close ( fd )
os . dup2 ( oldstdout , 1 )
os . dup2 ( oldstderr , 2 )
sys . stderr = olderr
sys . stdout = oldout
os . close ( oldstdout )
os . close ( oldstderr )
return self . status
class Context :
""" Provides services required by actions and handles running them. """
2009-07-14 17:33:40 +02:00
def __init__ ( self , tmpdir , resultdir , uri , workdir , mailtitle , sender , recipients , mailhost , enabled , skip , nologs , setupcmd , make ) :
2006-08-26 17:44:06 +02:00
# preserve normal stdout because stdout/stderr will be redirected
2006-09-11 19:40:51 +02:00
self . out = os . fdopen ( os . dup ( 1 ) , " w " )
2006-08-26 17:44:06 +02:00
self . todo = [ ]
2006-08-27 22:11:21 +02:00
self . actions = { }
2006-08-26 17:44:06 +02:00
self . tmpdir = abspath ( tmpdir )
self . resultdir = abspath ( resultdir )
2007-07-09 22:29:00 +02:00
self . uri = uri
2006-08-26 17:44:06 +02:00
self . workdir = abspath ( workdir )
self . summary = [ ]
self . mailtitle = mailtitle
self . sender = sender
self . recipients = recipients
2009-06-26 08:30:09 +02:00
self . mailhost = mailhost
2006-08-26 17:44:06 +02:00
self . enabled = enabled
2006-08-27 22:11:21 +02:00
self . skip = skip
2006-08-26 17:44:06 +02:00
self . nologs = nologs
2008-07-10 20:09:36 +02:00
self . setupcmd = setupcmd
2009-07-14 17:33:40 +02:00
self . make = make
2006-08-26 17:44:06 +02:00
def runCommand ( self , cmd ) :
""" Log and run the given command, throwing an exception if it fails. """
print " %s : %s " % ( os . getcwd ( ) , cmd )
sys . stdout . flush ( )
2006-08-27 22:11:21 +02:00
result = os . system ( cmd )
if result != 0 :
raise Exception ( " %s : failed (return code %d ) " % ( cmd , result ) )
2006-08-26 17:44:06 +02:00
def add ( self , action ) :
""" Add an action for later execution. Order is important, fifo... """
self . todo . append ( action )
2006-08-27 22:11:21 +02:00
self . actions [ action . name ] = action
2006-08-26 17:44:06 +02:00
def required ( self , actionname ) :
""" Returns true if the action is required by one which is enabled. """
if actionname in self . enabled :
return True
for action in self . todo :
if actionname in action . dependencies and self . required ( action . name ) :
return True
return False
def execute ( self ) :
cd ( self . resultdir )
2006-09-11 19:40:51 +02:00
s = file ( " output.txt " , " w+ " )
2006-08-26 17:44:06 +02:00
status = Action . DONE
2006-08-27 22:38:39 +02:00
step = 0
2006-08-26 17:44:06 +02:00
while len ( self . todo ) > 0 :
try :
2006-08-27 22:38:39 +02:00
step = step + 1
2006-08-27 22:11:21 +02:00
# get action
2006-08-26 17:44:06 +02:00
action = self . todo . pop ( 0 )
2006-08-27 22:11:21 +02:00
# check whether it actually needs to be executed
2006-08-26 17:44:06 +02:00
if self . enabled and \
not action . name in self . enabled and \
not self . required ( action . name ) :
2006-08-27 22:11:21 +02:00
# disabled
action . status = Action . SKIPPED
self . summary . append ( " %s skipped: disabled in configuration " % ( action . name ) )
elif action . name in self . skip :
# assume that it was done earlier
action . status = Action . SKIPPED
self . summary . append ( " %s assumed to be done: requested by configuration " % ( action . name ) )
else :
# check dependencies
for depend in action . dependencies :
if not self . actions [ depend ] . status in Action . COMPLETED :
action . status = Action . SKIPPED
2006-09-11 19:40:51 +02:00
self . summary . append ( " %s skipped: required %s has not been executed " % ( action . name , depend ) )
2006-08-27 22:11:21 +02:00
break
if action . status == Action . SKIPPED :
2006-08-26 17:44:06 +02:00
continue
# execute it
2006-08-27 22:38:39 +02:00
action . tryexecution ( step , not self . nologs )
2006-08-26 17:44:06 +02:00
if action . status > status :
status = action . status
if action . status == Action . FAILED :
2006-08-27 22:11:21 +02:00
self . summary . append ( " %s : %s " % ( action . name , action . summary ) )
elif action . status == Action . WARNINGS :
2006-08-26 17:44:06 +02:00
self . summary . append ( " %s done, but check the warnings " % action . name )
else :
self . summary . append ( " %s successful " % action . name )
except Exception , inst :
traceback . print_exc ( )
self . summary . append ( " %s failed: %s " % ( action . name , inst ) )
2007-07-09 22:29:00 +02:00
# append all parameters to summary
self . summary . append ( " " )
self . summary . extend ( sys . argv )
2006-08-26 17:44:06 +02:00
# update summary
s . write ( " %s \n " % ( " \n " . join ( self . summary ) ) )
s . close ( )
# report result by email
if self . recipients :
2009-06-26 08:30:09 +02:00
server = smtplib . SMTP ( self . mailhost )
2007-07-09 22:29:00 +02:00
msg = " From: %s \r \n To: %s \r \n Subject: %s : %s \r \n \r \n %s \n \n %s " % \
2006-08-26 17:44:06 +02:00
( self . sender ,
" , " . join ( self . recipients ) ,
2007-07-09 22:29:00 +02:00
self . mailtitle , os . path . basename ( self . resultdir ) ,
self . uri or self . resultdir ,
2006-08-26 17:44:06 +02:00
" \n " . join ( self . summary ) )
failed = server . sendmail ( self . sender , self . recipients , msg )
if failed :
print " could not send to: %s " % ( failed )
sys . exit ( 1 )
else :
print " \n " . join ( self . summary ) , " \n "
2006-08-27 22:11:21 +02:00
if status in Action . COMPLETED :
sys . exit ( 0 )
else :
sys . exit ( 1 )
2006-08-26 17:44:06 +02:00
# must be set before instantiating some of the following classes
context = None
class CVSCheckout ( Action ) :
""" Does a CVS checkout (if directory does not exist yet) or an update (if it does). """
2006-08-27 22:11:21 +02:00
def __init__ ( self , name , workdir , runner , cvsroot , module , revision ) :
2006-08-26 17:44:06 +02:00
""" workdir defines the directory to do the checkout in,
cvsroot the server , module the path to the files ,
revision the tag to checkout """
Action . __init__ ( self , name )
self . workdir = workdir
2006-08-27 22:11:21 +02:00
self . runner = runner
2006-08-26 17:44:06 +02:00
self . cvsroot = cvsroot
self . module = module
self . revision = revision
self . basedir = os . path . join ( abspath ( workdir ) , module )
def execute ( self ) :
cd ( self . workdir )
if os . access ( self . module , os . F_OK ) :
os . chdir ( self . module )
context . runCommand ( " cvs update -d -r %s " % ( self . revision ) )
elif self . revision == " HEAD " :
context . runCommand ( " cvs -d %s checkout %s " % ( self . cvsroot , self . module ) )
os . chdir ( self . module )
else :
context . runCommand ( " cvs -d %s checkout -r %s %s " % ( self . cvsroot , self . revision , self . module ) )
os . chdir ( self . module )
if os . access ( " autogen.sh " , os . F_OK ) :
2006-08-27 22:11:21 +02:00
context . runCommand ( " %s ./autogen.sh " % ( self . runner ) )
2006-08-26 17:44:06 +02:00
2008-02-13 23:28:53 +01:00
class SVNCheckout ( Action ) :
""" Does a Subversion checkout (if directory does not exist yet) or a switch (if it does). """
def __init__ ( self , name , workdir , runner , url , module ) :
""" workdir defines the directory to do the checkout in,
URL the server and path inside repository ,
module the path to the files in the checked out copy """
Action . __init__ ( self , name )
self . workdir = workdir
self . runner = runner
self . url = url
self . module = module
self . basedir = os . path . join ( abspath ( workdir ) , module )
def execute ( self ) :
cd ( self . workdir )
if os . access ( self . module , os . F_OK ) :
cmd = " switch "
else :
cmd = " checkout "
context . runCommand ( " svn %s %s %s " % ( cmd , self . url , self . module ) )
os . chdir ( self . module )
if os . access ( " autogen.sh " , os . F_OK ) :
context . runCommand ( " %s ./autogen.sh " % ( self . runner ) )
2009-06-26 08:30:09 +02:00
class GitCheckout ( Action ) :
""" Does a git clone (if directory does not exist yet) or a fetch+checkout (if it does). """
def __init__ ( self , name , workdir , runner , url , revision ) :
""" workdir defines the directory to do the checkout in with ' name ' as name of the sub directory,
URL the server and repository ,
revision the desired branch or tag """
Action . __init__ ( self , name )
self . workdir = workdir
self . runner = runner
self . url = url
self . revision = revision
self . basedir = os . path . join ( abspath ( workdir ) , name )
2006-08-26 17:44:06 +02:00
def execute ( self ) :
2009-06-26 08:30:09 +02:00
if os . access ( self . basedir , os . F_OK ) :
cmd = " cd %s && git fetch %s && git checkout %s && git pull " % ( self . basedir , self . url , self . revision )
else :
cmd = " git clone %s %s && cd %s && git checkout %s " % ( self . url , self . basedir , self . basedir , self . revision )
context . runCommand ( cmd )
os . chdir ( self . basedir )
if os . access ( " autogen.sh " , os . F_OK ) :
context . runCommand ( " %s ./autogen.sh " % ( self . runner ) )
2006-08-26 17:44:06 +02:00
class AutotoolsBuild ( Action ) :
def __init__ ( self , name , src , configargs , runner , dependencies ) :
""" Runs configure from the src directory with the given arguments.
runner is a prefix for the configure command and can be used to setup the
environment . """
Action . __init__ ( self , name )
self . src = src
self . configargs = configargs
self . runner = runner
self . dependencies = dependencies
2006-11-12 13:42:11 +01:00
self . installdir = os . path . join ( context . tmpdir , " install " )
self . builddir = os . path . join ( context . tmpdir , " build " )
2006-08-26 17:44:06 +02:00
def execute ( self ) :
del_dir ( self . builddir )
cd ( self . builddir )
2007-11-30 21:14:01 +01:00
context . runCommand ( " %s %s /configure %s " % ( self . runner , self . src , self . configargs ) )
2009-07-14 17:33:40 +02:00
context . runCommand ( " %s %s install DESTDIR= %s " % ( self . runner , context . make , self . installdir ) )
2006-08-26 17:44:06 +02:00
class SyncEvolutionTest ( Action ) :
2007-12-01 22:07:43 +01:00
def __init__ ( self , name , build , serverlogs , runner , tests , testenv = " " , lineFilter = None , testPrefix = " " ) :
2006-09-11 19:40:51 +02:00
""" Execute TestEvolution for all (empty tests) or the
2006-08-26 17:44:06 +02:00
selected tests . """
Action . __init__ ( self , name )
self . srcdir = os . path . join ( build . builddir , " src " )
self . serverlogs = serverlogs
self . runner = runner
self . tests = tests
self . testenv = testenv
2008-06-26 22:29:56 +02:00
if build . name :
self . dependencies . append ( build . name )
2006-10-28 10:52:18 +02:00
self . lineFilter = lineFilter
2007-12-01 22:07:43 +01:00
self . testPrefix = testPrefix
2006-08-26 17:44:06 +02:00
def execute ( self ) :
resdir = os . getcwd ( )
os . chdir ( self . srcdir )
try :
2008-07-10 20:09:36 +02:00
if context . setupcmd :
context . runCommand ( " %s %s %s %s ./syncevolution " % ( self . testenv , self . runner , context . setupcmd , self . name ) )
2009-07-14 16:20:55 +02:00
basecmd = " %s SYNC_EVOLUTION_EVO_CALENDAR_DELAY=1 CLIENT_TEST_FAILURES=EvolutionCalendarTest::testOpenDefaultMemo CLIENT_TEST_ALARM=1200 CLIENT_TEST_LOG= %s CLIENT_TEST_EVOLUTION_PREFIX=file:// %s /databases %s %s env LD_LIBRARY_PATH=build-synthesis/src/.libs ./client-test " % ( self . testenv , self . serverlogs , context . workdir , self . runner , self . testPrefix ) ;
2009-07-14 17:33:40 +02:00
context . runCommand ( " %s testclean " , context . make )
2006-08-26 17:44:06 +02:00
if self . tests :
2008-08-17 10:19:45 +02:00
context . runCommand ( " %s %s " % ( basecmd , " " . join ( self . tests ) ) )
2006-08-26 17:44:06 +02:00
else :
context . runCommand ( basecmd )
finally :
tocopy = re . compile ( r ' .* \ .log ' )
2006-09-11 19:40:51 +02:00
htaccess = file ( os . path . join ( resdir , " .htaccess " ) , " a " )
2006-08-26 17:44:06 +02:00
for f in os . listdir ( self . srcdir ) :
if tocopy . match ( f ) :
2006-10-28 10:52:18 +02:00
copyLog ( f , resdir , htaccess , self . lineFilter )
2006-08-26 17:44:06 +02:00
###################################################################
# Configuration part
###################################################################
parser = optparse . OptionParser ( )
parser . add_option ( " -e " , " --enable " ,
action = " append " , type = " string " , dest = " enabled " ,
2006-08-27 22:11:21 +02:00
help = " use this to enable specific actions instead of executing all of them (can be used multiple times) " )
2006-08-26 17:44:06 +02:00
parser . add_option ( " -n " , " --no-logs " ,
action = " store_true " , dest = " nologs " ,
help = " print to stdout/stderr directly instead of redirecting into log files " )
parser . add_option ( " -l " , " --list " ,
action = " store_true " , dest = " list " ,
help = " list all available actions " )
2006-08-27 22:11:21 +02:00
parser . add_option ( " -s " , " --skip " ,
action = " append " , type = " string " , dest = " skip " , default = [ ] ,
help = " instead of executing this action assume that it completed earlier (can be used multiple times) " )
2006-08-26 17:44:06 +02:00
parser . add_option ( " " , " --tmp " ,
2006-09-11 19:40:51 +02:00
type = " string " , dest = " tmpdir " , default = " " ,
2006-08-26 17:44:06 +02:00
help = " temporary directory for intermediate files " )
parser . add_option ( " " , " --workdir " ,
2006-09-11 19:40:51 +02:00
type = " string " , dest = " workdir " , default = " " ,
2006-08-26 17:44:06 +02:00
help = " directory for files which might be reused between runs " )
parser . add_option ( " " , " --resultdir " ,
2006-09-11 19:40:51 +02:00
type = " string " , dest = " resultdir " , default = " " ,
2006-08-26 17:44:06 +02:00
help = " directory for log files and results " )
2007-07-09 22:29:00 +02:00
parser . add_option ( " " , " --resulturi " ,
type = " string " , dest = " uri " , default = None ,
help = " URI that corresponds to --resultdir, if given this is used in mails instead of --resultdir " )
2006-08-26 17:44:06 +02:00
parser . add_option ( " " , " --shell " ,
type = " string " , dest = " shell " , default = " " ,
help = " a prefix which is put in front of a command to execute it (can be used for e.g. run_garnome) " )
2007-12-01 22:07:43 +01:00
parser . add_option ( " " , " --test-prefix " ,
type = " string " , dest = " testprefix " , default = " " ,
help = " a prefix which is put in front of client-test (e.g. valgrind) " )
2006-11-01 17:02:59 +01:00
parser . add_option ( " " , " --syncevo-tag " ,
2009-06-26 08:30:09 +02:00
type = " string " , dest = " syncevotag " , default = " master " ,
help = " the tag of SyncEvolution (e.g. syncevolution-0.7, default is ' master ' " )
parser . add_option ( " " , " --synthesis-tag " ,
type = " string " , dest = " synthesistag " , default = " master " ,
help = " the tag of the synthesis library (default = master in the moblin.org repo) " )
2007-07-09 22:29:00 +02:00
parser . add_option ( " " , " --configure " ,
type = " string " , dest = " configure " , default = " " ,
help = " additional parameters for configure " )
2007-01-11 21:34:20 +01:00
parser . add_option ( " " , " --openembedded " ,
type = " string " , dest = " oedir " ,
help = " the build directory of the OpenEmbedded cross-compile environment " )
parser . add_option ( " " , " --host " ,
type = " string " , dest = " host " ,
help = " platform identifier like x86_64-linux; if this and --openembedded is set, then cross-compilation is tested " )
2006-11-12 13:42:11 +01:00
parser . add_option ( " " , " --bin-suffix " ,
type = " string " , dest = " binsuffix " , default = " " ,
2007-12-17 19:58:55 +01:00
help = " string to append to name of binary .tar.gz distribution archive (default empty = no binary distribution built) " )
parser . add_option ( " " , " --package-suffix " ,
type = " string " , dest = " packagesuffix " , default = " " ,
help = " string to insert into package name (default empty = no binary distribution built) " )
2006-08-26 17:44:06 +02:00
parser . add_option ( " " , " --synthesis " ,
2006-09-11 19:40:51 +02:00
type = " string " , dest = " synthesisdir " , default = " " ,
2006-08-26 17:44:06 +02:00
help = " directory with Synthesis installation " )
parser . add_option ( " " , " --funambol " ,
type = " string " , dest = " funamboldir " , default = " /scratch/Funambol " ,
help = " directory with Funambol installation " )
parser . add_option ( " " , " --from " ,
type = " string " , dest = " sender " ,
help = " sender of email if recipients are also specified " )
parser . add_option ( " " , " --to " ,
action = " append " , type = " string " , dest = " recipients " ,
help = " recipient of result email (option can be given multiple times) " )
2009-06-26 08:30:09 +02:00
parser . add_option ( " " , " --mailhost " ,
type = " string " , dest = " mailhost " , default = " localhost " ,
help = " SMTP mail server to be used for outgoing mail " )
2006-08-26 17:44:06 +02:00
parser . add_option ( " " , " --subject " ,
type = " string " , dest = " subject " , default = " SyncML Tests " + time . strftime ( " % Y- % m- %d " ) ,
help = " subject of result email (default is \" SyncML Tests <date> \" " )
2008-02-11 22:28:32 +01:00
parser . add_option ( " " , " --evosvn " ,
action = " append " , type = " string " , dest = " evosvn " , default = [ ] ,
help = " <name>=<path>: compiles Evolution from source under a short name, using Paul Smith ' s Makefile and config as found in <path> " )
2008-06-26 22:29:56 +02:00
parser . add_option ( " " , " --prebuilt " ,
action = " append " , type = " string " , dest = " prebuilt " , default = [ ] ,
help = " a directory where SyncEvolution was build before: enables testing using those binaries (can be used multiple times) " )
2008-07-10 20:09:36 +02:00
parser . add_option ( " " , " --setup-command " ,
type = " string " , dest = " setupcmd " ,
help = " invoked with <test name> <args to start syncevolution>, should setup local account for the test " )
2009-07-14 17:33:40 +02:00
parser . add_option ( " " , " --make-command " ,
type = " string " , dest = " makecmd " , default = " make " ,
help = " command to use instead of plain make, for example ' make -j ' " )
2006-08-26 17:44:06 +02:00
( options , args ) = parser . parse_args ( )
if options . recipients and not options . sender :
print " sending email also requires sender argument "
sys . exit ( 1 )
2007-07-09 22:29:00 +02:00
context = Context ( options . tmpdir , options . resultdir , options . uri , options . workdir ,
2009-06-26 08:30:09 +02:00
options . subject , options . sender , options . recipients , options . mailhost ,
2009-07-14 17:33:40 +02:00
options . enabled , options . skip , options . nologs , options . setupcmd ,
options . makecmd )
2006-08-26 17:44:06 +02:00
2008-02-11 22:28:32 +01:00
class EvoSvn ( Action ) :
""" Builds Evolution from SVN using Paul Smith ' s Evolution Makefile. """
def __init__ ( self , name , workdir , resultdir , makedir , makeoptions ) :
""" workdir defines the directory to do the build in,
makedir is the directory which contains the Makefile and its local . mk ,
makeoptions contain additional parameters for make ( like BRANCH = 2.20 PREFIX = / tmp / runtests / evo ) . """
Action . __init__ ( self , name )
self . workdir = workdir
self . resultdir = resultdir
self . makedir = makedir
self . makeoptions = makeoptions
def execute ( self ) :
cd ( self . workdir )
shutil . copy2 ( os . path . join ( self . makedir , " Makefile " ) , " . " )
shutil . copy2 ( os . path . join ( self . makedir , " local.mk " ) , " . " )
2008-03-16 09:48:11 +01:00
if os . access ( self . resultdir , os . F_OK ) :
shutil . rmtree ( self . resultdir )
os . system ( " rm -f .stamp/*.install " )
2008-02-11 22:28:32 +01:00
localmk = open ( " local.mk " , " a " )
localmk . write ( " PREFIX := %s \n " % self . resultdir )
localmk . close ( )
if os . access ( " .stamp " , os . F_OK ) :
context . runCommand ( " make check-changelog " )
2009-07-14 17:33:40 +02:00
context . runCommand ( " %s %s " % ( context . make , self . makeoptions ) )
2008-02-11 22:28:32 +01:00
for evosvn in options . evosvn :
name , path = evosvn . split ( " = " )
evosvn = EvoSvn ( " evolution " + name ,
os . path . join ( options . tmpdir , " evolution %s -build " % name ) ,
os . path . join ( options . tmpdir , " evolution %s -result " % name ) ,
path ,
" SUDO=true " )
context . add ( evosvn )
2008-06-26 22:29:56 +02:00
for prebuilt in options . prebuilt :
pre = Action ( " " )
pre . builddir = prebuilt
if prebuilt :
context . add ( SyncEvolutionTest ( " evolution-prebuilt- " + os . path . basename ( prebuilt ) , pre ,
" " , options . shell ,
[ " Client::Source " , " SyncEvolution " ] ,
testPrefix = options . testprefix ) )
2009-06-26 08:30:09 +02:00
class SyncEvolutionCheckout ( GitCheckout ) :
2006-08-26 17:44:06 +02:00
def __init__ ( self , name , revision ) :
""" checkout SyncEvolution """
2009-06-26 08:30:09 +02:00
GitCheckout . __init__ ( self ,
2006-08-27 22:11:21 +02:00
name , context . workdir , options . shell ,
2009-06-26 08:30:09 +02:00
" git@git.moblin.org:syncevolution.git " ,
revision )
class SynthesisCheckout ( GitCheckout ) :
def __init__ ( self , name , revision ) :
""" checkout libsynthesis """
GitCheckout . __init__ ( self ,
name , context . workdir , options . shell ,
" git@git.moblin.org:libsynthesis.git " ,
revision )
2006-08-26 17:44:06 +02:00
class SyncEvolutionBuild ( AutotoolsBuild ) :
def execute ( self ) :
AutotoolsBuild . execute ( self )
os . chdir ( " src " )
2009-07-14 17:33:40 +02:00
context . runCommand ( " %s %s test CXXFLAGS=-O0 " % ( self . runner , context . make ) )
2006-08-26 17:44:06 +02:00
2009-06-26 08:30:09 +02:00
libsynthesis = SynthesisCheckout ( " libsynthesis " , options . synthesistag )
context . add ( libsynthesis )
2006-11-01 17:02:59 +01:00
sync = SyncEvolutionCheckout ( " syncevolution " , options . syncevotag )
2006-10-28 10:52:18 +02:00
context . add ( sync )
2009-06-26 08:30:09 +02:00
if options . synthesistag :
synthesis_source = " --with-synthesis-src= %s " % libsynthesis . basedir
2008-10-08 22:53:58 +02:00
else :
2009-06-26 08:30:09 +02:00
synthesis_source = " "
2006-10-28 10:52:18 +02:00
compile = SyncEvolutionBuild ( " compile " ,
sync . basedir ,
2009-06-26 08:30:09 +02:00
" %s %s " % ( options . configure , synthesis_source ) ,
2006-10-28 10:52:18 +02:00
options . shell ,
2009-06-26 08:30:09 +02:00
[ libsynthesis . name , sync . name ] )
2006-10-28 10:52:18 +02:00
context . add ( compile )
2007-01-11 21:34:20 +01:00
class SyncEvolutionCross ( AutotoolsBuild ) :
2009-06-26 08:30:09 +02:00
def __init__ ( self , syncevosrc , synthesissrc , host , oedir , dependencies ) :
2007-01-11 21:34:20 +01:00
""" cross-compile SyncEvolution using a certain OpenEmbedded build dir:
host is the platform identifier ( e . g . x86_64 - linux ) ,
oedir must contain the ' tmp/cross ' and ' tmp/staging/<host> ' directories """
2009-06-26 08:30:09 +02:00
if synthesissrc :
synthesis_source = " --with-funambol-src= %s " % synthesissrc
2008-10-08 22:53:58 +02:00
else :
2009-06-26 08:30:09 +02:00
synthesis_source = " "
2007-01-11 21:34:20 +01:00
AutotoolsBuild . __init__ ( self , " cross-compile " , syncevosrc , \
2008-10-08 22:53:58 +02:00
" --host= %s %s CPPFLAGS=-I %s /tmp/staging/ %s /include/ LDFLAGS= ' -Wl,-rpath-link= %s /tmp/staging/ %s /lib/ -Wl,--allow-shlib-undefined ' " % \
2009-06-26 08:30:09 +02:00
( host , synthesis_source , oedir , host , oedir , host ) , \
2007-01-11 21:34:20 +01:00
" PKG_CONFIG_PATH= %s /tmp/staging/ %s /share/pkgconfig PATH= %s /tmp/cross/bin:$PATH " % \
( oedir , host , oedir ) ,
dependencies )
self . builddir = os . path . join ( context . tmpdir , host )
def execute ( self ) :
AutotoolsBuild . execute ( self )
if options . oedir and options . host :
2009-06-26 08:30:09 +02:00
cross = SyncEvolutionCross ( sync . basedir , libsynthesis . basedir , options . host , options . oedir , [ libsynthesis . name , sync . name , compile . name ] )
2007-01-11 21:34:20 +01:00
context . add ( cross )
2006-11-12 13:42:11 +01:00
class SyncEvolutionDist ( AutotoolsBuild ) :
2007-12-17 19:58:55 +01:00
def __init__ ( self , name , binsuffix , packagesuffix , binrunner , dependencies ) :
2006-11-12 13:42:11 +01:00
""" Builds a normal and a binary distribution archive in a directory where
SyncEvolution was configured and compiled before .
"""
AutotoolsBuild . __init__ ( self , name , " " , " " , binrunner , dependencies )
self . binsuffix = binsuffix
2007-12-17 19:58:55 +01:00
self . packagesuffix = packagesuffix
2006-11-12 13:42:11 +01:00
def execute ( self ) :
cd ( self . builddir )
2007-12-17 19:58:55 +01:00
if self . packagesuffix :
2009-07-14 17:33:40 +02:00
context . runCommand ( " %s %s BINSUFFIX= %s deb " % ( self . runner , context . make , self . packagesuffix ) )
2008-12-07 21:02:14 +01:00
put , get = os . popen4 ( " dpkg-architecture -qDEB_HOST_ARCH " )
for arch in get . readlines ( ) :
if " i386 " in arch :
2009-07-14 17:33:40 +02:00
context . runCommand ( " %s %s BINSUFFIX= %s PKGARCH=lpia deb " % ( self . runner , context . make , self . packagesuffix ) )
2008-12-07 21:02:14 +01:00
break
2006-11-12 13:42:11 +01:00
if self . binsuffix :
2009-07-14 17:33:40 +02:00
context . runCommand ( " %s %s BINSUFFIX= %s distbin " % ( self . runner , context . make , self . binsuffix ) )
context . runCommand ( " %s %s distcheck " % ( self . runner , context . make ) )
context . runCommand ( " %s %s DISTCHECK_CONFIGURE_FLAGS=--enable-gui distcheck " % ( self . runner , context . make ) )
2006-11-12 13:42:11 +01:00
dist = SyncEvolutionDist ( " dist " ,
options . binsuffix ,
2007-12-17 19:58:55 +01:00
options . packagesuffix ,
2006-11-12 13:42:11 +01:00
options . shell ,
[ compile . name ] )
context . add ( dist )
2006-10-28 10:52:18 +02:00
evolutiontest = SyncEvolutionTest ( " evolution " , compile ,
2006-08-26 17:44:06 +02:00
" " , options . shell ,
2008-05-02 19:22:44 +02:00
[ " Client::Source " , " SyncEvolution " ] ,
2007-12-01 22:07:43 +01:00
testPrefix = options . testprefix )
2006-08-26 17:44:06 +02:00
context . add ( evolutiontest )
2008-08-17 10:19:45 +02:00
# ScheduleWorld has a problem when new clients synchronize for the
# first time: all other clients are forced into a slow sync. The
# first test affected by this is Client::Sync::vcard30::testCopy.
# Afterwards tests work as expected again.
2006-10-28 10:52:18 +02:00
scheduleworldtest = SyncEvolutionTest ( " scheduleworld " , compile ,
2006-08-26 17:44:06 +02:00
" " , options . shell ,
2007-07-09 22:29:00 +02:00
[ " Client::Sync " ] ,
2009-07-14 09:52:02 +02:00
" CLIENT_TEST_NUM_ITEMS=10 CLIENT_TEST_SKIP=Client::Sync::ical20::Retry,Client::Sync::ical20::Suspend,Client::Sync::vcard30::Retry,Client::Sync::vcard30::Suspend,Client::Sync::itodo20::Retry,Client::Sync::itodo20::Suspend,Client::Sync::text::Retry,Client::Sync::text::Suspend CLIENT_TEST_FAILURES=Client::Sync::vcard30::testCopy CLIENT_TEST_SOURCES=ical20,vcard30,itodo20,text CLIENT_TEST_SERVER=scheduleworld CLIENT_TEST_DELAY=5 " ,
2007-12-01 22:07:43 +01:00
testPrefix = options . testprefix )
2006-08-26 17:44:06 +02:00
context . add ( scheduleworldtest )
2008-06-29 19:59:27 +02:00
memotootest = SyncEvolutionTest ( " memotoo " , compile ,
" " , options . shell ,
[ " Client::Sync " ] ,
" CLIENT_TEST_NUM_ITEMS=10 CLIENT_TEST_FAILURES= CLIENT_TEST_SOURCES=ical20,vcard21,itodo20,text CLIENT_TEST_SERVER=memotoo CLIENT_TEST_DELAY=15 " ,
testPrefix = options . testprefix )
context . add ( memotootest )
2006-10-28 10:52:18 +02:00
egroupwaretest = SyncEvolutionTest ( " egroupware " , compile ,
2006-09-11 19:40:51 +02:00
" " , options . shell ,
2007-07-09 22:29:00 +02:00
[ " Client::Sync::vcard21 " , " Client::Sync::ical20::testCopy " , " Client::Sync::ical20::testUpdate " , " Client::Sync::ical20::testDelete " , \
" Client::Sync::vcard21_ical20::testCopy " , " Client::Sync::vcard21_ical20::testUpdate " , " Client::Sync::vcard21_ical20::testDelete " \
" Client::Sync::ical20_vcard21::testCopy " , " Client::Sync::ical20_vcard21::testUpdate " , " Client::Sync::ical20_vcard21::testDelete " ] ,
2006-11-12 13:42:11 +01:00
# ContactSync::testRefreshFromServerSync,ContactSync::testRefreshFromClientSync,ContactSync::testDeleteAllRefresh,ContactSync::testRefreshSemantic,ContactSync::testRefreshStatus - refresh-from-client not supported by server
# ContactSync::testOneWayFromClient - not supported by server?
# ContactSync::testItems - loses a lot of information
# ContactSync::testComplexUpdate - only one phone number preserved
# ContactSync::testMaxMsg,ContactSync::testLargeObject,ContactSync::testLargeObjectBin - server fails to parse extra info?
# ContactSync::testTwinning - duplicates contacts
# CalendarSync::testCopy,CalendarSync::testUpdate - shifts time?
2007-07-09 22:29:00 +02:00
" CLIENT_TEST_SOURCES=vcard21,ical20 CLIENT_TEST_SERVER=egroupware CLIENT_TEST_FAILURES=ContactSync::testRefreshFromServerSync,ContactSync::testRefreshFromClientSync,ContactSync::testDeleteAllRefresh,ContactSync::testRefreshSemantic,ContactSync::testRefreshStatus,ContactSync::testOneWayFromClient,ContactSync::testAddUpdate,ContactSync::testItems,ContactSync::testComplexUpdate,ContactSync::testTwinning,ContactSync::testMaxMsg,ContactSync::testLargeObject,ContactSync::testLargeObjectBin,CalendarSync::testCopy,CalendarSync::testUpdate " ,
2006-10-28 10:52:18 +02:00
lambda x : x . replace ( ' oasis.ethz.ch ' , ' <host hidden> ' ) . \
2007-12-01 22:07:43 +01:00
replace ( ' cG9obHk6cWQyYTVtZ1gzZk5GQQ== ' , ' xxx ' ) ,
testPrefix = options . testprefix )
2006-09-11 19:40:51 +02:00
context . add ( egroupwaretest )
2006-08-26 17:44:06 +02:00
class SynthesisTest ( SyncEvolutionTest ) :
2007-12-01 22:07:43 +01:00
def __init__ ( self , name , build , synthesisdir , runner , testPrefix ) :
2007-07-09 22:29:00 +02:00
SyncEvolutionTest . __init__ ( self , name , build , " " , # os.path.join(synthesisdir, "logs")
runner , [ " Client::Sync " ] ,
2007-12-17 19:58:55 +01:00
" CLIENT_TEST_SOURCES=vcard21,text CLIENT_TEST_NUM_ITEMS=20 CLIENT_TEST_SERVER=synthesis CLIENT_TEST_DELAY=2 " ,
2007-12-01 22:07:43 +01:00
testPrefix = testPrefix )
2006-08-26 17:44:06 +02:00
self . synthesisdir = synthesisdir
2006-09-11 19:40:51 +02:00
# self.dependencies.append(evolutiontest.name)
2006-08-26 17:44:06 +02:00
def execute ( self ) :
2007-12-01 22:07:43 +01:00
if self . synthesisdir :
context . runCommand ( " synthesis start \" %s \" " % ( self . synthesisdir ) )
2006-08-26 17:44:06 +02:00
time . sleep ( 5 )
try :
SyncEvolutionTest . execute ( self )
finally :
2007-12-01 22:07:43 +01:00
if self . synthesisdir :
context . runCommand ( " synthesis stop \" %s \" " % ( self . synthesisdir ) )
2006-08-26 17:44:06 +02:00
2006-10-28 10:52:18 +02:00
synthesis = SynthesisTest ( " synthesis " , compile ,
2006-08-26 17:44:06 +02:00
options . synthesisdir ,
2007-12-01 22:07:43 +01:00
options . shell ,
options . testprefix )
2006-08-26 17:44:06 +02:00
context . add ( synthesis )
class FunambolTest ( SyncEvolutionTest ) :
2007-12-01 22:07:43 +01:00
def __init__ ( self , name , build , funamboldir , runner , testPrefix ) :
2007-07-09 22:29:00 +02:00
if funamboldir :
serverlogs = os . path . join ( funamboldir , " ds-server " , " logs " , " funambol_ds.log " )
else :
serverlogs = " "
SyncEvolutionTest . __init__ ( self , name , build , serverlogs ,
runner , [ ] ,
2009-07-14 09:52:02 +02:00
" CLIENT_TEST_SOURCES=vcard21,ical20,itodo20,text CLIENT_TEST_SKIP=Client::Sync::ical20::Retry,Client::Sync::ical20::Suspend,Client::Sync::vcard21::Retry,Client::Sync::vcard21::Suspend,Client::Sync::itodo20::Retry,Client::Sync::itodo20::Suspend,Client::Sync::text::Retry,Client::Sync::text::Suspend CLIENT_TEST_XML=1 CLIENT_TEST_MAX_ITEMSIZE=2048 CLIENT_TEST_DELAY=10 CLIENT_TEST_FAILURES= CLIENT_TEST_SERVER=funambol " ,
2008-06-29 19:59:27 +02:00
lineFilter = lambda x : x . replace ( ' dogfood.funambol.com ' , ' <host hidden> ' ) ,
2007-12-01 22:07:43 +01:00
testPrefix = testPrefix )
2006-08-26 17:44:06 +02:00
self . funamboldir = funamboldir
2006-09-11 19:40:51 +02:00
# self.dependencies.append(evolutiontest.name)
2006-08-26 17:44:06 +02:00
def execute ( self ) :
2006-09-11 19:40:51 +02:00
if self . funamboldir :
context . runCommand ( " %s /tools/bin/funambol.sh start " % ( self . funamboldir ) )
2006-08-26 17:44:06 +02:00
time . sleep ( 5 )
try :
SyncEvolutionTest . execute ( self )
finally :
2006-09-11 19:40:51 +02:00
if self . funamboldir :
context . runCommand ( " %s /tools/bin/funambol.sh stop " % ( self . funamboldir ) )
2006-08-26 17:44:06 +02:00
2006-10-28 10:52:18 +02:00
funambol = FunambolTest ( " funambol " , compile ,
2006-08-26 17:44:06 +02:00
options . funamboldir ,
2007-12-01 22:07:43 +01:00
options . shell ,
options . testprefix )
2006-08-26 17:44:06 +02:00
context . add ( funambol )
if options . list :
for action in context . todo :
print action . name
else :
context . execute ( )