00001
00002
00003
00004 """
00005 The general idea is that tests to run are defined as a list of
00006 actions. Each action has a unique name and can depend on other
00007 actions to have run successfully before.
00008
00009 Most work is executed in directories defined and owned by these
00010 actions. The framework only manages one directory which represents
00011 the result of each action:
00012 - an overview file which lists the result of each action
00013 - for each action a directory with stderr/out and additional files
00014 that the action can put there
00015 """
00016
00017 import os, sys, popen2, traceback, re, time, smtplib, optparse, stat, shutil
00018
00019 try:
00020 import gzip
00021 havegzip = True
00022 except:
00023 havegzip = False
00024
00025 def cd(path):
00026 """Enter directories, creating them if necessary."""
00027 if not os.access(path, os.F_OK):
00028 os.makedirs(path)
00029 os.chdir(path)
00030
00031 def abspath(path):
00032 """Absolute path after expanding vars and user."""
00033 return os.path.abspath(os.path.expanduser(os.path.expandvars(path)))
00034
00035 def del_dir(path):
00036 if not os.access(path, os.F_OK):
00037 return
00038 for file in os.listdir(path):
00039 file_or_dir = os.path.join(path,file)
00040
00041 os.chmod(path, os.stat(path)[stat.ST_MODE] | stat.S_IRWXU)
00042 if os.path.isdir(file_or_dir) and not os.path.islink(file_or_dir):
00043 del_dir(file_or_dir)
00044 else:
00045 os.remove(file_or_dir)
00046 os.rmdir(path)
00047
00048
00049 def copyLog(filename, dirname, htaccess, lineFilter=None):
00050 """Make a gzipped copy (if possible) with the original time stamps and find the most severe problem in it.
00051 That line is then added as description in a .htaccess AddDescription.
00052 """
00053 info = os.stat(filename)
00054 outname = os.path.join(dirname, os.path.basename(filename))
00055 if True:
00056 outname = outname + ".gz"
00057 out = gzip.open(outname, "wb")
00058 else:
00059 out = file(outname, "w")
00060 error = None
00061 for line in file(filename, "r").readlines():
00062 if not error and line.find("ERROR") >= 0:
00063 error = line
00064 if lineFilter:
00065 line = lineFilter(line)
00066 out.write(line)
00067 out.close()
00068 os.utime(outname, (info[stat.ST_ATIME], info[stat.ST_MTIME]))
00069 if error:
00070 htaccess.write("AddDescription \"%s\" %s\n" %
00071 (error.strip().replace("\"", "'").replace("<", "<").replace(">",">"),
00072 os.path.basename(filename)))
00073
00074 class Action:
00075 """Base class for all actions to be performed."""
00076
00077 DONE = "0 DONE"
00078 WARNINGS = "1 WARNINGS"
00079 FAILED = "2 FAILED"
00080 TODO = "3 TODO"
00081 SKIPPED = "4 SKIPPED"
00082 COMPLETED = (DONE, WARNINGS)
00083
00084 def __init__(self, name):
00085 self.name = name
00086 self.status = self.TODO
00087 self.summary = ""
00088 self.dependencies = []
00089
00090 def execute(self):
00091 """Runs action. Throws an exeception if anything fails.
00092 Will be called by tryexecution() with stderr/stdout redirected into a file
00093 and the current directory set to an empty temporary directory.
00094 """
00095 raise Exception("not implemented")
00096
00097 def tryexecution(self, step, logs):
00098 """wrapper around execute which handles exceptions, directories and stdout"""
00099 if logs:
00100 fd = -1
00101 oldstdout = os.dup(1)
00102 oldstderr = os.dup(2)
00103 oldout = sys.stdout
00104 olderr = sys.stderr
00105 cwd = os.getcwd()
00106 try:
00107 subdirname = "%d-%s" % (step, self.name)
00108 del_dir(subdirname)
00109 sys.stderr.flush()
00110 sys.stdout.flush()
00111 cd(subdirname)
00112 if logs:
00113 fd = os.open("output.txt", os.O_WRONLY|os.O_CREAT|os.O_TRUNC)
00114 os.dup2(fd, 1)
00115 os.dup2(fd, 2)
00116 sys.stdout = os.fdopen(fd, "w")
00117 sys.stderr = sys.stdout
00118 print "=== starting %s ===" % (self.name)
00119 self.execute()
00120 self.status = Action.DONE
00121 self.summary = "okay"
00122 except Exception, inst:
00123 traceback.print_exc()
00124 self.status = Action.FAILED
00125 self.summary = str(inst)
00126
00127 print "\n=== %s: %s ===" % (self.name, self.status)
00128 sys.stdout.flush()
00129 os.chdir(cwd)
00130 if logs:
00131 if fd >= 0:
00132 os.close(fd)
00133 os.dup2(oldstdout, 1)
00134 os.dup2(oldstderr, 2)
00135 sys.stderr = olderr
00136 sys.stdout = oldout
00137 os.close(oldstdout)
00138 os.close(oldstderr)
00139 return self.status
00140
00141 class Context:
00142 """Provides services required by actions and handles running them."""
00143
00144 def __init__(self, tmpdir, resultdir, uri, workdir, mailtitle, sender, recipients, enabled, skip, nologs, setupcmd):
00145
00146 self.out = os.fdopen(os.dup(1), "w")
00147 self.todo = []
00148 self.actions = {}
00149 self.tmpdir = abspath(tmpdir)
00150 self.resultdir = abspath(resultdir)
00151 self.uri = uri
00152 self.workdir = abspath(workdir)
00153 self.summary = []
00154 self.mailtitle = mailtitle
00155 self.sender = sender
00156 self.recipients = recipients
00157 self.enabled = enabled
00158 self.skip = skip
00159 self.nologs = nologs
00160 self.setupcmd = setupcmd
00161
00162 def runCommand(self, cmd):
00163 """Log and run the given command, throwing an exception if it fails."""
00164 print "%s: %s" % (os.getcwd(), cmd)
00165 sys.stdout.flush()
00166 result = os.system(cmd)
00167 if result != 0:
00168 raise Exception("%s: failed (return code %d)" % (cmd, result))
00169
00170 def add(self, action):
00171 """Add an action for later execution. Order is important, fifo..."""
00172 self.todo.append(action)
00173 self.actions[action.name] = action
00174
00175 def required(self, actionname):
00176 """Returns true if the action is required by one which is enabled."""
00177 if actionname in self.enabled:
00178 return True
00179 for action in self.todo:
00180 if actionname in action.dependencies and self.required(action.name):
00181 return True
00182 return False
00183
00184 def execute(self):
00185 cd(self.resultdir)
00186 s = file("output.txt", "w+")
00187 status = Action.DONE
00188
00189 step = 0
00190 while len(self.todo) > 0:
00191 try:
00192 step = step + 1
00193
00194
00195 action = self.todo.pop(0)
00196
00197
00198 if self.enabled and \
00199 not action.name in self.enabled and \
00200 not self.required(action.name):
00201
00202 action.status = Action.SKIPPED
00203 self.summary.append("%s skipped: disabled in configuration" % (action.name))
00204 elif action.name in self.skip:
00205
00206 action.status = Action.SKIPPED
00207 self.summary.append("%s assumed to be done: requested by configuration" % (action.name))
00208 else:
00209
00210 for depend in action.dependencies:
00211 if not self.actions[depend].status in Action.COMPLETED:
00212 action.status = Action.SKIPPED
00213 self.summary.append("%s skipped: required %s has not been executed" % (action.name, depend))
00214 break
00215
00216 if action.status == Action.SKIPPED:
00217 continue
00218
00219
00220 action.tryexecution(step, not self.nologs)
00221 if action.status > status:
00222 status = action.status
00223 if action.status == Action.FAILED:
00224 self.summary.append("%s: %s" % (action.name, action.summary))
00225 elif action.status == Action.WARNINGS:
00226 self.summary.append("%s done, but check the warnings" % action.name)
00227 else:
00228 self.summary.append("%s successful" % action.name)
00229 except Exception, inst:
00230 traceback.print_exc()
00231 self.summary.append("%s failed: %s" % (action.name, inst))
00232
00233
00234 self.summary.append("")
00235 self.summary.extend(sys.argv)
00236
00237
00238 s.write("%s\n" % ("\n".join(self.summary)))
00239 s.close()
00240
00241
00242 if self.recipients:
00243 server = smtplib.SMTP("localhost")
00244 msg = "From: %s\r\nTo: %s\r\nSubject: %s: %s\r\n\r\n%s\n\n%s" % \
00245 (self.sender,
00246 ", ".join(self.recipients),
00247 self.mailtitle, os.path.basename(self.resultdir),
00248 self.uri or self.resultdir,
00249 "\n".join(self.summary))
00250 failed = server.sendmail(self.sender, self.recipients, msg)
00251 if failed:
00252 print "could not send to: %s" % (failed)
00253 sys.exit(1)
00254 else:
00255 print "\n".join(self.summary), "\n"
00256
00257 if status in Action.COMPLETED:
00258 sys.exit(0)
00259 else:
00260 sys.exit(1)
00261
00262
00263 context = None
00264
00265 class CVSCheckout(Action):
00266 """Does a CVS checkout (if directory does not exist yet) or an update (if it does)."""
00267
00268 def __init__(self, name, workdir, runner, cvsroot, module, revision):
00269 """workdir defines the directory to do the checkout in,
00270 cvsroot the server, module the path to the files,
00271 revision the tag to checkout"""
00272 Action.__init__(self,name)
00273 self.workdir = workdir
00274 self.runner = runner
00275 self.cvsroot = cvsroot
00276 self.module = module
00277 self.revision = revision
00278 self.basedir = os.path.join(abspath(workdir), module)
00279
00280 def execute(self):
00281 cd(self.workdir)
00282 if os.access(self.module, os.F_OK):
00283 os.chdir(self.module)
00284 context.runCommand("cvs update -d -r %s" % (self.revision))
00285 elif self.revision == "HEAD":
00286 context.runCommand("cvs -d %s checkout %s" % (self.cvsroot, self.module))
00287 os.chdir(self.module)
00288 else:
00289 context.runCommand("cvs -d %s checkout -r %s %s" % (self.cvsroot, self.revision, self.module))
00290 os.chdir(self.module)
00291 if os.access("autogen.sh", os.F_OK):
00292 context.runCommand("%s ./autogen.sh" % (self.runner))
00293
00294 class SVNCheckout(Action):
00295 """Does a Subversion checkout (if directory does not exist yet) or a switch (if it does)."""
00296
00297 def __init__(self, name, workdir, runner, url, module):
00298 """workdir defines the directory to do the checkout in,
00299 URL the server and path inside repository,
00300 module the path to the files in the checked out copy"""
00301 Action.__init__(self,name)
00302 self.workdir = workdir
00303 self.runner = runner
00304 self.url = url
00305 self.module = module
00306 self.basedir = os.path.join(abspath(workdir), module)
00307
00308 def execute(self):
00309 cd(self.workdir)
00310 if os.access(self.module, os.F_OK):
00311 cmd = "switch"
00312 else:
00313 cmd = "checkout"
00314 context.runCommand("svn %s %s %s" % (cmd, self.url, self.module))
00315 os.chdir(self.module)
00316 if os.access("autogen.sh", os.F_OK):
00317 context.runCommand("%s ./autogen.sh" % (self.runner))
00318
00319 class ClientCheckout(CVSCheckout):
00320 def __init__(self, name, revision):
00321 """checkout C++ client source code and apply all patches"""
00322 CVSCheckout.__init__(self,
00323 name, context.workdir, options.shell,
00324 ":ext:pohly@cvs.forge.objectweb.org:/cvsroot/sync4j",
00325 "3x/client-api/native",
00326 revision)
00327 if not revision:
00328
00329 self.basedir = ""
00330
00331 def execute(self):
00332 if self.revision:
00333
00334 try:
00335 os.chdir(self.basedir)
00336 context.runCommand("patcher -B")
00337 except:
00338 pass
00339
00340 CVSCheckout.execute(self)
00341
00342 context.runCommand("echo $PATH; which patcher; patcher -A")
00343
00344 class AutotoolsBuild(Action):
00345 def __init__(self, name, src, configargs, runner, dependencies):
00346 """Runs configure from the src directory with the given arguments.
00347 runner is a prefix for the configure command and can be used to setup the
00348 environment."""
00349 Action.__init__(self, name)
00350 self.src = src
00351 self.configargs = configargs
00352 self.runner = runner
00353 self.dependencies = dependencies
00354 self.installdir = os.path.join(context.tmpdir, "install")
00355 self.builddir = os.path.join(context.tmpdir, "build")
00356
00357 def execute(self):
00358 del_dir(self.builddir)
00359 cd(self.builddir)
00360 context.runCommand("%s %s/configure %s" % (self.runner, self.src, self.configargs))
00361 context.runCommand("%s make install DESTDIR=%s" % (self.runner, self.installdir))
00362
00363
00364 class SyncEvolutionTest(Action):
00365 def __init__(self, name, build, serverlogs, runner, tests, testenv="", lineFilter=None, testPrefix=""):
00366 """Execute TestEvolution for all (empty tests) or the
00367 selected tests."""
00368 Action.__init__(self, name)
00369 self.srcdir = os.path.join(build.builddir, "src")
00370 self.serverlogs = serverlogs
00371 self.runner = runner
00372 self.tests = tests
00373 self.testenv = testenv
00374 if build.name:
00375 self.dependencies.append(build.name)
00376 self.lineFilter = lineFilter
00377 self.testPrefix = testPrefix
00378
00379 def execute(self):
00380 resdir = os.getcwd()
00381 os.chdir(self.srcdir)
00382 try:
00383 if context.setupcmd:
00384 context.runCommand("%s %s %s %s ./syncevolution" % (self.testenv, self.runner, context.setupcmd, self.name))
00385 basecmd = "%s SYNC_EVOLUTION_EVO_CALENDAR_DELAY=1 CLIENT_TEST_ALARM=1200 CLIENT_TEST_LOG=%s CLIENT_TEST_EVOLUTION_PREFIX=file://%s/databases %s %s ./client-test" % (self.testenv, self.serverlogs, context.workdir, self.runner, self.testPrefix);
00386 context.runCommand("make testclean")
00387 if self.tests:
00388 context.runCommand("%s %s" % (basecmd, " ".join(self.tests)))
00389 else:
00390 context.runCommand(basecmd)
00391 finally:
00392 tocopy = re.compile(r'.*\.log')
00393 htaccess = file(os.path.join(resdir, ".htaccess"), "a")
00394 for f in os.listdir(self.srcdir):
00395 if tocopy.match(f):
00396 copyLog(f, resdir, htaccess, self.lineFilter)
00397
00398
00399
00400
00401
00402
00403
00404 parser = optparse.OptionParser()
00405 parser.add_option("-e", "--enable",
00406 action="append", type="string", dest="enabled",
00407 help="use this to enable specific actions instead of executing all of them (can be used multiple times)")
00408 parser.add_option("-n", "--no-logs",
00409 action="store_true", dest="nologs",
00410 help="print to stdout/stderr directly instead of redirecting into log files")
00411 parser.add_option("-l", "--list",
00412 action="store_true", dest="list",
00413 help="list all available actions")
00414 parser.add_option("-s", "--skip",
00415 action="append", type="string", dest="skip", default=[],
00416 help="instead of executing this action assume that it completed earlier (can be used multiple times)")
00417 parser.add_option("", "--tmp",
00418 type="string", dest="tmpdir", default="",
00419 help="temporary directory for intermediate files")
00420 parser.add_option("", "--workdir",
00421 type="string", dest="workdir", default="",
00422 help="directory for files which might be reused between runs")
00423 parser.add_option("", "--resultdir",
00424 type="string", dest="resultdir", default="",
00425 help="directory for log files and results")
00426 parser.add_option("", "--resulturi",
00427 type="string", dest="uri", default=None,
00428 help="URI that corresponds to --resultdir, if given this is used in mails instead of --resultdir")
00429 parser.add_option("", "--shell",
00430 type="string", dest="shell", default="",
00431 help="a prefix which is put in front of a command to execute it (can be used for e.g. run_garnome)")
00432 parser.add_option("", "--test-prefix",
00433 type="string", dest="testprefix", default="",
00434 help="a prefix which is put in front of client-test (e.g. valgrind)")
00435 parser.add_option("", "--syncevo-tag",
00436 type="string", dest="syncevotag", default="trunk",
00437 help="the tag of SyncEvolution (e.g. tags/syncevolution-0.7, default trunk")
00438 parser.add_option("", "--client-tag",
00439 type="string", dest="clienttag", default="",
00440 help="the tag of the client library (default empty = not checkout out)")
00441 parser.add_option("", "--configure",
00442 type="string", dest="configure", default="",
00443 help="additional parameters for configure")
00444 parser.add_option("", "--openembedded",
00445 type="string", dest="oedir",
00446 help="the build directory of the OpenEmbedded cross-compile environment")
00447 parser.add_option("", "--host",
00448 type="string", dest="host",
00449 help="platform identifier like x86_64-linux; if this and --openembedded is set, then cross-compilation is tested")
00450 parser.add_option("", "--bin-suffix",
00451 type="string", dest="binsuffix", default="",
00452 help="string to append to name of binary .tar.gz distribution archive (default empty = no binary distribution built)")
00453 parser.add_option("", "--package-suffix",
00454 type="string", dest="packagesuffix", default="",
00455 help="string to insert into package name (default empty = no binary distribution built)")
00456
00457 parser.add_option("", "--synthesis",
00458 type="string", dest="synthesisdir", default="",
00459 help="directory with Synthesis installation")
00460 parser.add_option("", "--funambol",
00461 type="string", dest="funamboldir", default="/scratch/Funambol",
00462 help="directory with Funambol installation")
00463 parser.add_option("", "--from",
00464 type="string", dest="sender",
00465 help="sender of email if recipients are also specified")
00466 parser.add_option("", "--to",
00467 action="append", type="string", dest="recipients",
00468 help="recipient of result email (option can be given multiple times)")
00469 parser.add_option("", "--subject",
00470 type="string", dest="subject", default="SyncML Tests " + time.strftime("%Y-%m-%d"),
00471 help="subject of result email (default is \"SyncML Tests <date>\"")
00472 parser.add_option("", "--evosvn",
00473 action="append", type="string", dest="evosvn", default=[],
00474 help="<name>=<path>: compiles Evolution from source under a short name, using Paul Smith's Makefile and config as found in <path>")
00475 parser.add_option("", "--prebuilt",
00476 action="append", type="string", dest="prebuilt", default=[],
00477 help="a directory where SyncEvolution was build before: enables testing using those binaries (can be used multiple times)")
00478 parser.add_option("", "--setup-command",
00479 type="string", dest="setupcmd",
00480 help="invoked with <test name> <args to start syncevolution>, should setup local account for the test")
00481
00482 (options, args) = parser.parse_args()
00483 if options.recipients and not options.sender:
00484 print "sending email also requires sender argument"
00485 sys.exit(1)
00486
00487 context = Context(options.tmpdir, options.resultdir, options.uri, options.workdir,
00488 options.subject, options.sender, options.recipients,
00489 options.enabled, options.skip, options.nologs, options.setupcmd)
00490
00491 class EvoSvn(Action):
00492 """Builds Evolution from SVN using Paul Smith's Evolution Makefile."""
00493
00494 def __init__(self, name, workdir, resultdir, makedir, makeoptions):
00495 """workdir defines the directory to do the build in,
00496 makedir is the directory which contains the Makefile and its local.mk,
00497 makeoptions contain additional parameters for make (like BRANCH=2.20 PREFIX=/tmp/runtests/evo)."""
00498 Action.__init__(self,name)
00499 self.workdir = workdir
00500 self.resultdir = resultdir
00501 self.makedir = makedir
00502 self.makeoptions = makeoptions
00503
00504 def execute(self):
00505 cd(self.workdir)
00506 shutil.copy2(os.path.join(self.makedir, "Makefile"), ".")
00507 shutil.copy2(os.path.join(self.makedir, "local.mk"), ".")
00508 if os.access(self.resultdir, os.F_OK):
00509 shutil.rmtree(self.resultdir)
00510 os.system("rm -f .stamp/*.install")
00511 localmk = open("local.mk", "a")
00512 localmk.write("PREFIX := %s\n" % self.resultdir)
00513 localmk.close()
00514 if os.access(".stamp", os.F_OK):
00515 context.runCommand("make check-changelog")
00516 context.runCommand("make %s" % self.makeoptions)
00517
00518 for evosvn in options.evosvn:
00519 name, path = evosvn.split("=")
00520 evosvn = EvoSvn("evolution" + name,
00521 os.path.join(options.tmpdir, "evolution%s-build" % name),
00522 os.path.join(options.tmpdir, "evolution%s-result" % name),
00523 path,
00524 "SUDO=true")
00525 context.add(evosvn)
00526
00527 for prebuilt in options.prebuilt:
00528 pre = Action("")
00529 pre.builddir = prebuilt
00530 if prebuilt:
00531 context.add(SyncEvolutionTest("evolution-prebuilt-" + os.path.basename(prebuilt), pre,
00532 "", options.shell,
00533 [ "Client::Source", "SyncEvolution" ],
00534 testPrefix=options.testprefix))
00535
00536 class SyncEvolutionCheckout(SVNCheckout):
00537 def __init__(self, name, revision):
00538 """checkout SyncEvolution"""
00539 SVNCheckout.__init__(self,
00540 name, context.workdir, options.shell,
00541 "https://zeitsenke.de/svn/SyncEvolution/%s" % revision,
00542 "SyncEvolution")
00543
00544 class SyncEvolutionBuild(AutotoolsBuild):
00545 def execute(self):
00546 AutotoolsBuild.execute(self)
00547 os.chdir("src")
00548 context.runCommand("%s make test CXXFLAGS=-O0" % (self.runner))
00549
00550 client = ClientCheckout("client-api", options.clienttag)
00551 context.add(client)
00552 sync = SyncEvolutionCheckout("syncevolution", options.syncevotag)
00553 context.add(sync)
00554 if options.clienttag:
00555 client_source = "--with-funambol-src=%s" % client.basedir
00556 else:
00557 client_source = ""
00558 compile = SyncEvolutionBuild("compile",
00559 sync.basedir,
00560 "%s %s" % (options.configure, client_source),
00561 options.shell,
00562 [ client.name, sync.name ])
00563 context.add(compile)
00564
00565 class SyncEvolutionCross(AutotoolsBuild):
00566 def __init__(self, syncevosrc, syncclientsrc, host, oedir, dependencies):
00567 """cross-compile SyncEvolution using a certain OpenEmbedded build dir:
00568 host is the platform identifier (e.g. x86_64-linux),
00569 oedir must contain the 'tmp/cross' and 'tmp/staging/<host>' directories"""
00570 if syncclientsrc:
00571 client_source = "--with-funambol-src=%s" % syncclientsrc
00572 else:
00573 client_source = ""
00574 AutotoolsBuild.__init__(self, "cross-compile", syncevosrc, \
00575 "--host=%s %s CPPFLAGS=-I%s/tmp/staging/%s/include/ LDFLAGS='-Wl,-rpath-link=%s/tmp/staging/%s/lib/ -Wl,--allow-shlib-undefined'" % \
00576 ( host, client_source, oedir, host, oedir, host ), \
00577 "PKG_CONFIG_PATH=%s/tmp/staging/%s/share/pkgconfig PATH=%s/tmp/cross/bin:$PATH" % \
00578 ( oedir, host, oedir ),
00579 dependencies)
00580 self.builddir = os.path.join(context.tmpdir, host)
00581
00582 def execute(self):
00583 AutotoolsBuild.execute(self)
00584
00585 if options.oedir and options.host:
00586 cross = SyncEvolutionCross(sync.basedir, client.basedir, options.host, options.oedir, [ client.name, sync.name, compile.name ])
00587 context.add(cross)
00588
00589 class SyncEvolutionDist(AutotoolsBuild):
00590 def __init__(self, name, binsuffix, packagesuffix, binrunner, dependencies):
00591 """Builds a normal and a binary distribution archive in a directory where
00592 SyncEvolution was configured and compiled before.
00593 """
00594 AutotoolsBuild.__init__(self, name, "", "", binrunner, dependencies)
00595 self.binsuffix = binsuffix
00596 self.packagesuffix = packagesuffix
00597
00598 def execute(self):
00599 cd(self.builddir)
00600 if self.packagesuffix:
00601 context.runCommand("%s make BINSUFFIX=%s deb" % (self.runner, self.packagesuffix))
00602 if self.binsuffix:
00603 context.runCommand("%s make BINSUFFIX=%s distbin distcheck" % (self.runner, self.binsuffix))
00604 else:
00605 context.runCommand("%s make distcheck" % (self.runner))
00606
00607 dist = SyncEvolutionDist("dist",
00608 options.binsuffix,
00609 options.packagesuffix,
00610 options.shell,
00611 [ compile.name ])
00612 context.add(dist)
00613
00614 evolutiontest = SyncEvolutionTest("evolution", compile,
00615 "", options.shell,
00616 [ "Client::Source", "SyncEvolution" ],
00617 testPrefix=options.testprefix)
00618 context.add(evolutiontest)
00619
00620
00621
00622
00623
00624 scheduleworldtest = SyncEvolutionTest("scheduleworld", compile,
00625 "", options.shell,
00626 [ "Client::Sync" ],
00627 "CLIENT_TEST_NUM_ITEMS=10 CLIENT_TEST_FAILURES=Client::Sync::vcard30::testCopy CLIENT_TEST_SOURCES=ical20,vcard30,itodo20,text CLIENT_TEST_SERVER=scheduleworld CLIENT_TEST_DELAY=5",
00628 testPrefix=options.testprefix)
00629 context.add(scheduleworldtest)
00630
00631 memotootest = SyncEvolutionTest("memotoo", compile,
00632 "", options.shell,
00633 [ "Client::Sync" ],
00634 "CLIENT_TEST_NUM_ITEMS=10 CLIENT_TEST_FAILURES= CLIENT_TEST_SOURCES=ical20,vcard21,itodo20,text CLIENT_TEST_SERVER=memotoo CLIENT_TEST_DELAY=15",
00635 testPrefix=options.testprefix)
00636 context.add(memotootest)
00637
00638 egroupwaretest = SyncEvolutionTest("egroupware", compile,
00639 "", options.shell,
00640 [ "Client::Sync::vcard21", "Client::Sync::ical20::testCopy", "Client::Sync::ical20::testUpdate", "Client::Sync::ical20::testDelete", \
00641 "Client::Sync::vcard21_ical20::testCopy", "Client::Sync::vcard21_ical20::testUpdate", "Client::Sync::vcard21_ical20::testDelete" \
00642 "Client::Sync::ical20_vcard21::testCopy", "Client::Sync::ical20_vcard21::testUpdate", "Client::Sync::ical20_vcard21::testDelete" ],
00643
00644
00645
00646
00647
00648
00649
00650 "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",
00651 lambda x: x.replace('oasis.ethz.ch','<host hidden>').\
00652 replace('cG9obHk6cWQyYTVtZ1gzZk5GQQ==','xxx'),
00653 testPrefix=options.testprefix)
00654 context.add(egroupwaretest)
00655
00656 class SynthesisTest(SyncEvolutionTest):
00657 def __init__(self, name, build, synthesisdir, runner, testPrefix):
00658 SyncEvolutionTest.__init__(self, name, build, "",
00659 runner, [ "Client::Sync" ],
00660 "CLIENT_TEST_SOURCES=vcard21,text CLIENT_TEST_NUM_ITEMS=20 CLIENT_TEST_SERVER=synthesis CLIENT_TEST_DELAY=2",
00661 testPrefix=testPrefix)
00662 self.synthesisdir = synthesisdir
00663
00664
00665 def execute(self):
00666 if self.synthesisdir:
00667 context.runCommand("synthesis start \"%s\"" % (self.synthesisdir))
00668 time.sleep(5)
00669 try:
00670 SyncEvolutionTest.execute(self)
00671 finally:
00672 if self.synthesisdir:
00673 context.runCommand("synthesis stop \"%s\"" % (self.synthesisdir))
00674
00675 synthesis = SynthesisTest("synthesis", compile,
00676 options.synthesisdir,
00677 options.shell,
00678 options.testprefix)
00679 context.add(synthesis)
00680
00681 class FunambolTest(SyncEvolutionTest):
00682 def __init__(self, name, build, funamboldir, runner, testPrefix):
00683 if funamboldir:
00684 serverlogs = os.path.join(funamboldir, "ds-server", "logs", "funambol_ds.log")
00685 else:
00686 serverlogs = ""
00687 SyncEvolutionTest.__init__(self, name, build, serverlogs,
00688 runner, [ ],
00689 "CLIENT_TEST_SOURCES=vcard21,text CLIENT_TEST_DELAY=10 CLIENT_TEST_FAILURES= CLIENT_TEST_SERVER=funambol",
00690 lineFilter=lambda x: x.replace('dogfood.funambol.com','<host hidden>'),
00691 testPrefix=testPrefix)
00692 self.funamboldir = funamboldir
00693
00694
00695 def execute(self):
00696 if self.funamboldir:
00697 context.runCommand("%s/tools/bin/funambol.sh start" % (self.funamboldir))
00698 time.sleep(5)
00699 try:
00700 SyncEvolutionTest.execute(self)
00701 finally:
00702 if self.funamboldir:
00703 context.runCommand("%s/tools/bin/funambol.sh stop" % (self.funamboldir))
00704
00705 funambol = FunambolTest("funambol", compile,
00706 options.funamboldir,
00707 options.shell,
00708 options.testprefix)
00709 context.add(funambol)
00710
00711 if options.list:
00712 for action in context.todo:
00713 print action.name
00714 else:
00715 context.execute()