2013-08-01 17:32:44 +00:00
|
|
|
# -*- python -*-
|
|
|
|
# ex: set syntax=python:
|
|
|
|
|
2014-12-20 00:07:14 +00:00
|
|
|
|
2014-12-20 19:07:23 +00:00
|
|
|
## TODO:
|
|
|
|
##
|
|
|
|
## - Add comments on every function/class
|
|
|
|
## - License stuff (on all files)
|
|
|
|
## - Cross testing (needed?)
|
|
|
|
## - Improve way to store and compare testcases
|
|
|
|
|
|
|
|
|
2014-12-20 00:07:14 +00:00
|
|
|
from buildbot.schedulers.basic import SingleBranchScheduler, AnyBranchScheduler
|
|
|
|
from buildbot.schedulers.forcesched import ForceScheduler
|
|
|
|
from buildbot.process import factory
|
|
|
|
from buildbot.process.properties import WithProperties
|
|
|
|
from buildbot.steps.shell import Compile
|
|
|
|
from buildbot.steps.shell import Configure
|
|
|
|
from buildbot.steps.shell import ShellCommand
|
|
|
|
from buildbot.steps.shell import SetPropertyFromCommand
|
2014-12-22 22:51:13 +00:00
|
|
|
from buildbot.steps.transfer import FileUpload
|
2014-12-20 00:07:14 +00:00
|
|
|
from buildbot.steps.source.git import Git
|
2014-12-22 22:51:13 +00:00
|
|
|
from buildbot.steps.slave import RemoveDirectory
|
2014-12-20 00:07:14 +00:00
|
|
|
from buildbot.changes.filter import ChangeFilter
|
|
|
|
from buildbot.buildslave import BuildSlave
|
2015-01-21 05:02:02 +00:00
|
|
|
from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, EXCEPTION
|
2014-12-20 00:07:14 +00:00
|
|
|
from gdbcommand import GdbCatSumfileCommand
|
2015-01-15 07:10:02 +00:00
|
|
|
from gdbgitdb import SaveGDBResults, get_builder_commit_id
|
2015-01-21 17:59:55 +00:00
|
|
|
from urllib import quote
|
2014-12-20 00:07:14 +00:00
|
|
|
|
2013-08-01 17:32:44 +00:00
|
|
|
from sumfiles import DejaResults, set_web_base
|
|
|
|
import os.path
|
|
|
|
import urllib
|
2014-12-20 00:07:14 +00:00
|
|
|
from json import load
|
|
|
|
import random
|
2013-08-01 17:32:44 +00:00
|
|
|
|
2014-12-20 00:07:14 +00:00
|
|
|
####################################
|
|
|
|
####################################
|
|
|
|
#### GDB BuildBot Configuration ####
|
|
|
|
####################################
|
|
|
|
####################################
|
2013-08-01 17:32:44 +00:00
|
|
|
|
2014-12-20 00:07:14 +00:00
|
|
|
###############################
|
|
|
|
#### General Configuration ####
|
|
|
|
###############################
|
2013-08-01 17:32:44 +00:00
|
|
|
|
2014-12-20 00:07:14 +00:00
|
|
|
# This is the dictionary that the buildmaster pays attention to. We
|
|
|
|
# also use a shorter alias to save typing.
|
|
|
|
c = BuildmasterConfig = {}
|
2013-08-01 17:32:44 +00:00
|
|
|
|
2014-12-20 00:07:14 +00:00
|
|
|
# Base directory for the web server. This is needed in order to
|
|
|
|
# compare the test results.
|
2015-01-11 23:25:48 +00:00
|
|
|
gdb_web_base = os.path.expanduser (os.path.join (basedir,
|
|
|
|
'public_html',
|
|
|
|
'results'))
|
2013-08-01 17:32:44 +00:00
|
|
|
set_web_base (gdb_web_base)
|
|
|
|
|
2014-12-13 08:45:56 +00:00
|
|
|
# 'protocols' contains information about protocols which master will use for
|
|
|
|
# communicating with slaves.
|
2015-01-18 18:16:22 +00:00
|
|
|
c['protocols'] = {'pb': {'port': 16123}}
|
2014-12-13 08:45:56 +00:00
|
|
|
|
|
|
|
# the 'change_source' setting tells the buildmaster how it should find out
|
2014-12-20 00:07:14 +00:00
|
|
|
# about source code changes.
|
2014-12-13 08:45:56 +00:00
|
|
|
|
|
|
|
from buildbot.changes.gitpoller import GitPoller
|
|
|
|
c['change_source'] = []
|
|
|
|
c['change_source'].append(GitPoller(
|
2014-12-26 20:58:07 +00:00
|
|
|
repourl = r'git://sourceware.org/git/binutils-gdb.git',
|
2015-01-14 00:08:31 +00:00
|
|
|
workdir = os.path.expanduser (os.path.join ('~/', 'buildbot-master-binutils-gdb')),
|
2014-12-26 20:58:07 +00:00
|
|
|
branches = [ r'master' ],
|
2014-12-23 03:29:12 +00:00
|
|
|
pollinterval = 60 * 3))
|
2014-12-13 08:45:56 +00:00
|
|
|
|
2013-08-01 17:32:44 +00:00
|
|
|
# 'status' is a list of Status Targets. The results of each build will be
|
|
|
|
# pushed to these targets. buildbot/status/*.py has a variety to choose from,
|
|
|
|
# including web pages, email senders, and IRC bots.
|
|
|
|
|
|
|
|
c['status'] = []
|
|
|
|
|
|
|
|
# Catch things like PR gdb/42, PR16, PR 16 or bug #11,
|
|
|
|
# and turn them into gdb bugzilla URLs.
|
|
|
|
cc_re_tuple = (r'(PR [a-z]+/|PR ?|#)(\d+)',
|
2014-12-13 08:45:56 +00:00
|
|
|
r'http://sourceware.org/bugzilla/show_bug.cgi?id=\2')
|
2013-08-01 17:32:44 +00:00
|
|
|
|
2014-12-13 08:45:56 +00:00
|
|
|
from buildbot.status import html
|
|
|
|
from buildbot.status.web import authz, auth
|
|
|
|
|
2014-12-24 04:01:04 +00:00
|
|
|
## The following class is a hack. It is needed because Builbot's
|
|
|
|
## webserver treats everything it doesn't know as text/html. Sigh...
|
2015-01-14 22:36:57 +00:00
|
|
|
# class WebStatusWithTextDefault(html.WebStatus):
|
|
|
|
# def __init__ (self, http_port, authz, **kwargs):
|
|
|
|
# html.WebStatus.__init__ (self, http_port = http_port,
|
|
|
|
# authz = authz, **kwargs)
|
2014-12-26 21:36:15 +00:00
|
|
|
|
2015-01-14 22:36:57 +00:00
|
|
|
# def setupSite(self):
|
|
|
|
# result = html.WebStatus.setupSite(self)
|
|
|
|
# self.site.resource.defaultType = r"text/plain"
|
|
|
|
# return result
|
2014-12-24 04:01:04 +00:00
|
|
|
|
2014-12-13 08:45:56 +00:00
|
|
|
authz_cfg=authz.Authz(
|
|
|
|
# change any of these to True to enable; see the manual for more
|
|
|
|
# options
|
|
|
|
# auth=auth.BasicAuth([("t","t")]),
|
|
|
|
gracefulShutdown = False,
|
|
|
|
forceBuild = True, # use this to test your slave once it is set up
|
2014-12-14 22:09:22 +00:00
|
|
|
forceAllBuilds = True, # ..or this
|
2014-12-13 08:45:56 +00:00
|
|
|
pingBuilder = False,
|
|
|
|
stopBuild = True,
|
|
|
|
stopAllBuilds = True,
|
|
|
|
cancelPendingBuild = True,
|
|
|
|
)
|
2015-01-14 22:36:57 +00:00
|
|
|
#c['status'].append(WebStatusWithTextDefault (http_port=8010, authz=authz_cfg))
|
|
|
|
c['status'].append (html.WebStatus (http_port = 8010, authz = authz_cfg))
|
2014-12-13 08:45:56 +00:00
|
|
|
|
|
|
|
#c['status'].append(html.WebStatus(http_port=8010,
|
|
|
|
# forceBuild = True,
|
|
|
|
# allowForce=False,
|
|
|
|
# order_console_by_time=True,
|
|
|
|
# changecommentlink=cc_re_tuple))
|
|
|
|
|
|
|
|
#from buildbot.status import words
|
|
|
|
#c['status'].append(words.IRC(host="irc.yyz.redhat.com", nick="sdj-gdbbot",
|
|
|
|
# channels=["#gdbbuild"]))
|
|
|
|
|
2014-12-22 00:38:24 +00:00
|
|
|
def MessageGDBTesters (mode, name, build, results, master_status):
|
|
|
|
"""This function is responsible for composing the message that will be
|
|
|
|
send to the gdb-testers mailing list."""
|
2015-01-15 00:45:36 +00:00
|
|
|
git_url = "http://gdb-build.sergiodj.net/cgit"
|
|
|
|
|
2014-12-24 01:02:31 +00:00
|
|
|
# Subject
|
2014-12-26 21:13:25 +00:00
|
|
|
subj = "Failures on %s" % name
|
2014-12-24 01:02:31 +00:00
|
|
|
|
|
|
|
# Body
|
2014-12-26 21:13:25 +00:00
|
|
|
text = ""
|
2014-12-24 01:02:31 +00:00
|
|
|
|
|
|
|
# Buildslave name, useful for knowing the exact configuration.
|
2015-01-15 00:45:36 +00:00
|
|
|
text += "Buildslave:\n"
|
2014-12-26 21:13:25 +00:00
|
|
|
text += "\t%s\n" % build.getSlavename ()
|
2014-12-24 01:02:31 +00:00
|
|
|
|
|
|
|
# Commits that were tested. Usually we should be dealing with
|
|
|
|
# only one commit
|
2014-12-26 21:13:25 +00:00
|
|
|
text += "Commit(s) tested:\n"
|
2014-12-24 01:02:31 +00:00
|
|
|
ss_list = build.getSourceStamps ()
|
2014-12-22 00:38:24 +00:00
|
|
|
for ss in ss_list:
|
2015-01-09 23:58:38 +00:00
|
|
|
for chg in ss.changes:
|
|
|
|
text += "\t%s\n" % chg.revision
|
2014-12-24 01:02:31 +00:00
|
|
|
|
2015-01-20 22:06:22 +00:00
|
|
|
# Who's to blame?
|
|
|
|
text += "Author(s) (in the same order as the commits):\n"
|
|
|
|
for ss in ss_list:
|
|
|
|
for chg in ss.changes:
|
|
|
|
text += "\t%s\n" % chg.who
|
|
|
|
|
2014-12-24 01:02:31 +00:00
|
|
|
# URL to find more info about what went wrong.
|
2014-12-26 21:13:25 +00:00
|
|
|
text += "Log URL(s):\n"
|
2014-12-24 01:02:31 +00:00
|
|
|
for ss in ss_list:
|
2015-01-15 06:43:34 +00:00
|
|
|
commit_id = get_builder_commit_id (name, ss.revision)
|
|
|
|
if commit_id:
|
|
|
|
text += "\t<%s/%s/.git/tree/?id=%s>\n" % (git_url, name, commit_id)
|
|
|
|
else:
|
|
|
|
text += "\t<Error fetching commit ID for %s>\n" % ss.revision
|
2014-12-24 01:02:31 +00:00
|
|
|
|
|
|
|
# Including the 'regressions' log. This is the 'diff' of what
|
|
|
|
# went wrong.
|
2014-12-26 21:13:25 +00:00
|
|
|
text += "\n"
|
2015-01-20 22:06:22 +00:00
|
|
|
print_xfail = False
|
2014-12-22 05:06:44 +00:00
|
|
|
for log in build.getLogs ():
|
2015-01-20 22:06:22 +00:00
|
|
|
st = log.getStep ()
|
2015-01-21 05:02:02 +00:00
|
|
|
if st.getResults ()[0] == FAILURE:
|
2015-01-20 22:06:22 +00:00
|
|
|
n = st.getName ()
|
|
|
|
if n == 'update gdb master repo' or n == 'update gdb repo':
|
|
|
|
text += "*** Failed to update GDB git repository. This is probably a timeout problem with sourceware. ***\n"
|
|
|
|
break
|
|
|
|
elif n == 'configure gdb':
|
|
|
|
text += "*** Failed to configure GDB. ***\n"
|
|
|
|
text += "============================\n"
|
|
|
|
text += log.getText ()
|
|
|
|
text += "============================\n"
|
|
|
|
break
|
|
|
|
elif n == 'compile gdb':
|
|
|
|
text += "*** Failed to compiled GDB. ***\n"
|
|
|
|
text += "============================\n"
|
|
|
|
text += log.getText ()
|
|
|
|
text += "============================\n"
|
|
|
|
break
|
|
|
|
elif n == 'make tags':
|
|
|
|
# We do not want to break here, because if this step
|
|
|
|
# fails the test will continue.
|
|
|
|
text += "*** Failed to make TAGS ***\n"
|
2015-01-21 17:28:29 +00:00
|
|
|
text += "Log URL: %s/steps/%s/logs/%s\n\n" % (master_status.getURLForThing (build),
|
2015-01-21 17:59:55 +00:00
|
|
|
quote (n), quote (log.getName ()))
|
2015-01-20 22:06:22 +00:00
|
|
|
continue
|
|
|
|
elif n == 'regressions' and log.getName () == 'regressions':
|
|
|
|
text += "*** Regressions found ***\n"
|
|
|
|
text += "============================\n"
|
2014-12-24 04:50:41 +00:00
|
|
|
text += log.getText ()
|
2015-01-20 22:06:22 +00:00
|
|
|
text += "============================\n"
|
|
|
|
print_xfail = True
|
|
|
|
break
|
2014-12-24 01:02:31 +00:00
|
|
|
|
|
|
|
# Including the 'xfail' log. It is important to say which tests
|
|
|
|
# we are ignoring.
|
2015-01-20 22:06:22 +00:00
|
|
|
if print_xfail:
|
|
|
|
xfail = os.path.join (gdb_web_base, name, 'xfail')
|
|
|
|
if os.path.exists (xfail):
|
|
|
|
text += "\n"
|
|
|
|
text += "Failures that are being ignored:\n\n"
|
|
|
|
with open (xfail, 'r') as f:
|
|
|
|
text += f.read ()
|
2014-12-26 21:13:25 +00:00
|
|
|
text += "\n"
|
2014-12-22 00:38:24 +00:00
|
|
|
return { 'body' : text,
|
2014-12-26 21:13:25 +00:00
|
|
|
'type' : 'plain',
|
2014-12-22 00:38:24 +00:00
|
|
|
'subject' : subj }
|
|
|
|
|
|
|
|
from buildbot.status import mail
|
2015-01-18 18:16:22 +00:00
|
|
|
mn = mail.MailNotifier(fromaddr = "sergiodj@redhat.com",
|
2014-12-22 00:38:24 +00:00
|
|
|
sendToInterestedUsers = False,
|
2015-01-14 21:56:12 +00:00
|
|
|
extraRecipients = ['gdb-testers@sourceware.org'],
|
2014-12-26 21:13:25 +00:00
|
|
|
mode = ('failing'),
|
2014-12-25 18:48:23 +00:00
|
|
|
messageFormatter = MessageGDBTesters,
|
|
|
|
extraHeaders = { 'X-GDB-Buildbot' : '1' })
|
2014-12-22 00:38:24 +00:00
|
|
|
|
|
|
|
c['status'].append (mn)
|
2013-08-01 17:32:44 +00:00
|
|
|
|
2014-12-13 08:45:56 +00:00
|
|
|
c['title'] = "GDB"
|
|
|
|
c['titleURL'] = "https://gnu.org/s/gdb"
|
2013-08-01 17:32:44 +00:00
|
|
|
|
2015-01-18 18:16:22 +00:00
|
|
|
c['buildbotURL'] = "http://gdb-build.sergiodj.net/"
|
2014-12-13 08:45:56 +00:00
|
|
|
|
|
|
|
c['db'] = {
|
|
|
|
'db_url' : "sqlite:///state.sqlite",
|
|
|
|
}
|
|
|
|
|
2014-12-20 00:07:14 +00:00
|
|
|
#####################
|
|
|
|
#### Build steps ####
|
|
|
|
#####################
|
|
|
|
|
|
|
|
## This is where we define our build steps. A build step is some
|
|
|
|
## command/action that buildbot will perform while building GDB. See
|
|
|
|
## the documentation on each build step class to understand what it
|
|
|
|
## does.
|
|
|
|
|
|
|
|
class RandomWaitForClone (ShellCommand):
|
|
|
|
"""This build step is responsible for waiting a random number of
|
|
|
|
seconds before trying to update the local git repository. This is a
|
|
|
|
hack, and is needed because sourceware imposes a load average when one
|
|
|
|
tries to update more than 3 repositories at the same time. An obvious
|
|
|
|
FIXME for this would be to have a git mirror somewhere where we could
|
|
|
|
do more than 3 updates at a time."""
|
2015-01-20 22:06:22 +00:00
|
|
|
name = "random wait for clone"
|
2014-12-26 20:58:07 +00:00
|
|
|
description = r"randomly waiting before git fetching"
|
|
|
|
descriptionDone = r"waited before git fetching"
|
|
|
|
command = ['sleep', WithProperties (r"%ss", r'randomWait')]
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
class CloneOrUpdateGDBMasterRepo (Git):
|
|
|
|
"""This build step updates the so-called "master" git repository. For
|
|
|
|
each buildslave, we have one master GDB git repository, which is then
|
|
|
|
used to create each builder's GDB git repository. In other words,
|
|
|
|
each builder inside a buildslave will have something like:
|
|
|
|
|
|
|
|
-- master GDB git repo
|
|
|
|
|
|
|
|
|
|---- builder X
|
|
|
|
|
|
|
|
|
|-- GDB git repo (clone from the master above)
|
|
|
|
|
|
|
|
|
|----- builder Y
|
|
|
|
|
|
|
|
|
|-- GDB git repo (clone from the master above)
|
|
|
|
|
|
|
|
and so on. This layout helps us to save some when fetching changes
|
|
|
|
from the principal repository."""
|
2015-01-20 22:06:22 +00:00
|
|
|
name = "update gdb master repo"
|
2014-12-26 20:58:07 +00:00
|
|
|
description = r"fetching GDB master sources"
|
|
|
|
descriptionDone = r"fetched GDB master sources"
|
2014-12-20 00:07:14 +00:00
|
|
|
def __init__ (self):
|
|
|
|
Git.__init__ (self,
|
2014-12-26 20:58:07 +00:00
|
|
|
repourl = r'git://sourceware.org/git/binutils-gdb.git',
|
|
|
|
workdir = WithProperties (r"%s/../binutils-gdb-master/",
|
|
|
|
r'builddir'),
|
2014-12-20 00:07:14 +00:00
|
|
|
retryFetch = True,
|
2014-12-26 20:58:07 +00:00
|
|
|
mode = r'incremental')
|
2014-12-20 00:07:14 +00:00
|
|
|
self.haltOnFailure = False
|
|
|
|
self.flunkOnFailure = False
|
|
|
|
|
|
|
|
class CloneOrUpdateGDBRepo (Git):
|
|
|
|
"""This build step is used to clone the GDB git repository that will
|
|
|
|
be used by an specific builder (inside a buildslave). The trick here
|
|
|
|
is to use the "reference" parameter to initialize the class, which
|
|
|
|
makes BuildBot clone the git repository mostly using the objects
|
|
|
|
present at the reference repository (i.e., locally)."""
|
2015-01-20 22:06:22 +00:00
|
|
|
name = "clone gdb repo"
|
2014-12-20 00:07:14 +00:00
|
|
|
description = "fetching GDB sources"
|
|
|
|
descriptionDone = "fetched GDB sources"
|
|
|
|
def __init__ (self):
|
|
|
|
Git.__init__ (self,
|
|
|
|
repourl = 'git://sourceware.org/git/binutils-gdb.git',
|
|
|
|
workdir = WithProperties ('%s/binutils-gdb/', 'builddir'),
|
|
|
|
reference = WithProperties ("%s/../binutils-gdb-master/",
|
|
|
|
'builddir'),
|
|
|
|
retryFetch = True)
|
|
|
|
|
|
|
|
class ConfigureGDB (Configure):
|
|
|
|
"""This build step runs the GDB "configure" command, providing extra
|
|
|
|
flags for it if needed."""
|
2015-01-20 22:06:22 +00:00
|
|
|
name = "configure gdb"
|
2014-12-26 20:58:07 +00:00
|
|
|
description = r"configure GDB"
|
|
|
|
descriptionDone = r"configured GDB"
|
2014-12-20 00:07:14 +00:00
|
|
|
def __init__ (self, extra_conf_flags, **kwargs):
|
|
|
|
Configure.__init__ (self, **kwargs)
|
2014-12-26 20:58:07 +00:00
|
|
|
self.workdir = WithProperties (r"%s", r'builddir')
|
2014-12-20 00:07:14 +00:00
|
|
|
self.command = ['../binutils-gdb/configure',
|
|
|
|
'--enable-targets=all',
|
|
|
|
'--disable-binutils',
|
|
|
|
'--disable-ld',
|
|
|
|
'--disable-gold',
|
|
|
|
'--disable-gas',
|
|
|
|
'--disable-sim',
|
|
|
|
'--disable-gprof'] + extra_conf_flags
|
|
|
|
|
|
|
|
class CompileGDB (Compile):
|
|
|
|
"""This build step runs "make" to compile the GDB sources. It
|
|
|
|
provides extra "make" flags to "make" if needed. It also uses the
|
|
|
|
"jobs" properties to figure out how many parallel jobs we can use when
|
|
|
|
compiling GDB; this is the "-j" flag for "make". The value of the
|
|
|
|
"jobs" property is set at the "config.json" file, for each
|
|
|
|
buildslave."""
|
2015-01-20 22:06:22 +00:00
|
|
|
name = "compile gdb"
|
2014-12-26 20:58:07 +00:00
|
|
|
description = r"compile GDB"
|
|
|
|
descriptionDone = r"compiled GDB"
|
2014-12-20 00:07:14 +00:00
|
|
|
def __init__ (self, extra_make_flags = [], **kwargs):
|
|
|
|
Compile.__init__ (self, **kwargs)
|
2014-12-26 20:58:07 +00:00
|
|
|
self.workdir = WithProperties (r"%s", r'builddir')
|
2014-12-20 00:07:14 +00:00
|
|
|
self.command = ['make',
|
2014-12-26 20:58:07 +00:00
|
|
|
WithProperties (r"-j%s", r'jobs'),
|
2014-12-20 00:07:14 +00:00
|
|
|
'all'] + extra_make_flags
|
|
|
|
|
2015-01-20 22:06:22 +00:00
|
|
|
class MakeTAGSGDB (ShellCommand):
|
|
|
|
name = 'make tags'
|
|
|
|
description = 'running make TAGS'
|
|
|
|
descriptionDone = 'ran make TAGS'
|
|
|
|
def __init__ (self, **kwargs):
|
|
|
|
ShellCommand.__init__ (self, **kwargs)
|
|
|
|
self.workdir = WithProperties ("%s/build/gdb", 'builddir')
|
|
|
|
self.command = [ 'make', 'TAGS' ]
|
|
|
|
# We do not want to stop testing when this command fails.
|
|
|
|
self.haltOnFailure = False
|
|
|
|
self.flunkOnFailure = False
|
|
|
|
self.flunkOnWarnings = False
|
|
|
|
|
2014-12-26 21:50:31 +00:00
|
|
|
class TestGDB (ShellCommand):
|
2014-12-20 00:07:14 +00:00
|
|
|
"""This build step runs the full testsuite for GDB. It can run in
|
|
|
|
parallel mode (see BuildAndTestGDBFactory below), and it will also
|
|
|
|
provide any extra flags for "make" if needed. Unfortunately, because
|
|
|
|
our testsuite is not perfect (yet), this command must not make
|
|
|
|
BuildBot halt on failure."""
|
2015-01-20 22:06:22 +00:00
|
|
|
name = "test gdb"
|
2014-12-26 20:58:07 +00:00
|
|
|
description = r"testing GDB"
|
|
|
|
descriptionDone = r"tested GDB"
|
2014-12-20 00:07:14 +00:00
|
|
|
def __init__ (self, extra_make_check_flags = [], test_env = {},
|
|
|
|
**kwargs):
|
2015-01-09 23:44:54 +00:00
|
|
|
ShellCommand.__init__ (self, decodeRC = { 0 : SUCCESS,
|
|
|
|
1 : SUCCESS,
|
|
|
|
2 : SUCCESS },
|
|
|
|
**kwargs)
|
2014-12-20 00:07:14 +00:00
|
|
|
|
2014-12-26 20:58:07 +00:00
|
|
|
self.workdir = WithProperties (r"%s/build/gdb/testsuite", r'builddir')
|
2014-12-20 00:07:14 +00:00
|
|
|
self.command = ['make',
|
|
|
|
'-k',
|
|
|
|
'check'] + extra_make_check_flags
|
|
|
|
|
|
|
|
self.env = test_env
|
|
|
|
# Needed because of dejagnu
|
|
|
|
self.haltOnFailure = False
|
|
|
|
self.flunkOnFailure = False
|
2014-12-26 18:08:24 +00:00
|
|
|
self.flunkOnWarnings = False
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
#######################
|
|
|
|
#### Build Factory ####
|
|
|
|
#######################
|
|
|
|
|
|
|
|
## This is where our Build Factory is defined. A build factory is a
|
|
|
|
## description of the build process, which is made in terms of build
|
|
|
|
## steps. The BuildAndTestGDBFactory is the main build factory for
|
|
|
|
## GDB; it is configurable and should be more than enough to describe
|
|
|
|
## most builds.
|
|
|
|
|
|
|
|
class BuildAndTestGDBFactory (factory.BuildFactory):
|
2014-12-24 01:02:31 +00:00
|
|
|
"""This is the main build factory for the GDB project. It was made to
|
|
|
|
be very configurable, and should be enough to describe most builds.
|
|
|
|
The parameters of the class are:
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
- ConfigureClass: set this to be the class (i.e., build step) that
|
|
|
|
will be called to configure GDB. It needs to accept the same
|
|
|
|
arguments as the ConfigureGDB class above. The default is to
|
|
|
|
use ConfigureGDB.
|
|
|
|
|
|
|
|
- CompileClass: set this to be the class (i.e., build step) that
|
|
|
|
will be called to compile GDB. It needs to accept the same
|
|
|
|
arguments as the CompileGDB class above. The default is to use
|
|
|
|
CompileGDB.
|
|
|
|
|
|
|
|
- TestClass: set this to be the class (i.e., build step) that will
|
|
|
|
be called to test GDB. It needs to accept the same arguments as
|
|
|
|
the TestGDB class above. The default is to use TestGDB.
|
|
|
|
|
|
|
|
- extra_conf_flags: extra flags to be passed to "configure".
|
|
|
|
Should be a list (i.e., []). The default is None.
|
|
|
|
|
|
|
|
- extra_make_flags: extra flags to be passed to "make", when
|
|
|
|
compiling. Should be a list (i.e., []). The default is None.
|
|
|
|
|
|
|
|
- extra_make_check_flags: extra flags to be passed to "make
|
|
|
|
check", when testing. Should be a list (i.e., []). The default
|
|
|
|
is None.
|
|
|
|
|
|
|
|
- test_env: extra environment variables to be passed to "make
|
|
|
|
check", when testing. Should be a dictionary (i.e., {}). The
|
|
|
|
default is None.
|
|
|
|
|
2014-12-25 23:22:05 +00:00
|
|
|
- test_parallel: set to True if the test shall be parallelized.
|
|
|
|
Default is False. Beware that parallelizing tests may cause
|
|
|
|
some failures due to limited system resources.
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
- use_system_debuginfo: set to False if GDB should be compiled
|
|
|
|
with the "--with-separate-debug-dir" option set to
|
|
|
|
"/usr/lib/debug". Default is True.
|
|
|
|
"""
|
|
|
|
ConfigureClass = ConfigureGDB
|
|
|
|
CompileClass = CompileGDB
|
|
|
|
TestClass = TestGDB
|
|
|
|
|
|
|
|
extra_conf_flags = None
|
|
|
|
extra_make_flags = None
|
|
|
|
extra_make_check_flags = None
|
|
|
|
test_env = None
|
|
|
|
|
|
|
|
# Set this to false to disable parallel testing (i.e., do not use
|
|
|
|
# FORCE_PARALLEL)
|
2014-12-25 23:22:05 +00:00
|
|
|
test_parallel = False
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
# Set this to False to disable using system's debuginfo files
|
|
|
|
# (i.e., do not use '--with-separate-debug-dir')
|
|
|
|
use_system_debuginfo = True
|
|
|
|
|
|
|
|
def __init__ (self, architecture_triplet = []):
|
|
|
|
factory.BuildFactory.__init__ (self)
|
2014-12-26 20:58:07 +00:00
|
|
|
self.addStep (RemoveDirectory (dir = WithProperties (r"%s/build",
|
|
|
|
r'builddir'),
|
|
|
|
description = r"removing old build dir",
|
|
|
|
descriptionDone = r"removed old build dir"))
|
2014-12-20 00:07:14 +00:00
|
|
|
# Unfortunately we need to have this random wait, otherwise
|
|
|
|
# git fetch won't work
|
|
|
|
self.addStep (RandomWaitForClone ())
|
|
|
|
self.addStep (CloneOrUpdateGDBMasterRepo ())
|
|
|
|
self.addStep (CloneOrUpdateGDBRepo ())
|
|
|
|
|
|
|
|
if not self.extra_conf_flags:
|
|
|
|
self.extra_conf_flags = []
|
|
|
|
|
|
|
|
if self.use_system_debuginfo:
|
2014-12-26 20:58:07 +00:00
|
|
|
self.extra_conf_flags.append (r'--with-separate-debug-dir=/usr/lib/debug')
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
self.addStep (self.ConfigureClass (self.extra_conf_flags + architecture_triplet))
|
|
|
|
|
|
|
|
if not self.extra_make_flags:
|
|
|
|
self.extra_make_flags = []
|
|
|
|
self.addStep (self.CompileClass (self.extra_make_flags))
|
|
|
|
|
2015-01-20 22:06:22 +00:00
|
|
|
self.addStep (MakeTAGSGDB ())
|
|
|
|
|
2014-12-20 00:07:14 +00:00
|
|
|
if not self.extra_make_check_flags:
|
|
|
|
self.extra_make_check_flags = []
|
|
|
|
if not self.test_env:
|
|
|
|
self.test_env = {}
|
|
|
|
|
2014-12-25 23:22:05 +00:00
|
|
|
if self.test_parallel:
|
2014-12-26 20:58:07 +00:00
|
|
|
self.extra_make_check_flags.append (WithProperties (r"-j%s", r'jobs'))
|
|
|
|
self.extra_make_check_flags.append (r'FORCE_PARALLEL=1')
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
self.addStep (self.TestClass (self.extra_make_check_flags, self.test_env))
|
|
|
|
|
2014-12-26 20:58:07 +00:00
|
|
|
self.addStep (GdbCatSumfileCommand (workdir = WithProperties (r'%s/build/gdb/testsuite',
|
|
|
|
r'builddir'),
|
|
|
|
description = r'analyze test results'))
|
|
|
|
self.addStep (FileUpload (slavesrc = WithProperties (r"%s/build/gdb/testsuite/gdb.log",
|
|
|
|
r'builddir'),
|
2015-01-12 02:41:38 +00:00
|
|
|
masterdest = WithProperties (r"public_html/results/%s/gdb.log",
|
2015-01-11 23:27:05 +00:00
|
|
|
r'buildername')))
|
2015-01-11 23:25:48 +00:00
|
|
|
# masterdest = WithProperties (r"public_html/results/%s/%s/gdb.log",
|
|
|
|
# r'buildername',
|
|
|
|
# r'got_revision')))
|
|
|
|
self.addStep (SaveGDBResults ())
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
##################
|
|
|
|
#### Builders ####
|
|
|
|
##################
|
|
|
|
|
|
|
|
## This section describes our builders. The builders are instances of
|
|
|
|
## a build factory, and they will be used to do a specific build of
|
|
|
|
## the project.
|
|
|
|
##
|
|
|
|
## The nomenclature here is important. Every builder should start
|
|
|
|
## with the prefix "RunTestGDB", and then be followed by the testing
|
|
|
|
## scenario that the build will test, followed by "_cXXtYY", where XX
|
|
|
|
## is the bitness of the compilation, and YY is the bitness of the
|
|
|
|
## testing. So, for example, if we are specifically testing GDB
|
|
|
|
## running the native-gdbserver tests, compiling GDB on a 64-bit
|
|
|
|
## machine, but running the tests in 32-bit mode, our builder would be called:
|
|
|
|
##
|
|
|
|
## RunTestGDBNativeGDBServer_c64t32
|
|
|
|
|
|
|
|
class RunTestGDBPlain_c64t64 (BuildAndTestGDBFactory):
|
|
|
|
"""Compiling for 64-bit, testing on 64-bit."""
|
|
|
|
pass
|
|
|
|
|
|
|
|
class RunTestGDBPlain_c32t32 (BuildAndTestGDBFactory):
|
|
|
|
"""Compiling on 32-bit, testing on 32-bit."""
|
2014-12-26 20:58:07 +00:00
|
|
|
extra_conf_flags = [ r'CFLAGS=-m32' ]
|
|
|
|
extra_make_check_flags = [ r'RUNTESTFLAGS=--target_board unix/-m32' ]
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
class RunTestGDBm32_c64t32 (BuildAndTestGDBFactory):
|
|
|
|
"""Compiling on 64-bit, testing on 32-bit."""
|
2014-12-26 20:58:07 +00:00
|
|
|
extra_make_check_flags = [ r'RUNTESTFLAGS=--target_board unix/-m32' ]
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
class RunTestGDBNativeGDBServer_c64t64 (BuildAndTestGDBFactory):
|
|
|
|
"""Compiling on 64-bit, testing native-gdbserver on 64-bit."""
|
2014-12-26 20:58:07 +00:00
|
|
|
extra_make_check_flags = [ r'RUNTESTFLAGS=--target_board native-gdbserver' ]
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
class RunTestGDBNativeGDBServer_c64t32 (BuildAndTestGDBFactory):
|
|
|
|
"""Compiling on 64-bit, testing native-gdbserver on 32-bit."""
|
2014-12-26 20:58:07 +00:00
|
|
|
extra_make_check_flags = [ r'RUNTESTFLAGS=--target_board native-gdbserver/-m32' ]
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
class RunTestGDBNativeExtendedGDBServer_c64t64 (BuildAndTestGDBFactory):
|
|
|
|
"""Compiling on 64-bit, testing native-extended-gdbserver on 64-bit."""
|
2014-12-26 20:58:07 +00:00
|
|
|
extra_make_check_flags = [ r'RUNTESTFLAGS=--target_board native-extended-gdbserver' ]
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
class RunTestGDBNativeExtendedGDBServer_c64t32 (BuildAndTestGDBFactory):
|
|
|
|
"""Compiling on 64-bit, testing native-extended-gdbserver on 32-bit."""
|
2014-12-26 20:58:07 +00:00
|
|
|
extra_make_check_flags = [ r'RUNTESTFLAGS=--target_board native-extended-gdbserver/-m32' ]
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
class RunTestGDBIndexBuild (BuildAndTestGDBFactory):
|
|
|
|
"""Testing with the "cc-with-tweaks.sh" passing -i. FIXME: include bitness here."""
|
2014-12-26 20:58:07 +00:00
|
|
|
extra_make_check_flags = [ WithProperties (r'CC_FOR_TARGET=/bin/sh %s/binutils-gdb/gdb/contrib/cc-with-tweaks.sh -i gcc', r'builddir'),
|
|
|
|
WithProperties (r'CXX_FOR_TARGET=/bin/sh %s/binutils-gdb/gdb/contrib/cc-with-tweaks.sh -i g++', r'builddir') ]
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
# For now, we only support testing the "master" branch.
|
2014-12-26 20:58:07 +00:00
|
|
|
master_filter = ChangeFilter (branch = [ r'master' ])
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
###############################
|
|
|
|
#### Configuration loading ####
|
|
|
|
###############################
|
|
|
|
|
|
|
|
## This is "the heart" of this file. This function is responsible for
|
|
|
|
## loading the configuration present in the "lib/config.json" file,
|
|
|
|
## and initializing everything needed for BuildBot to work. Most of
|
|
|
|
## this function was copied from WebKit's BuildBot configuration, with
|
|
|
|
## lots of tweaks.
|
|
|
|
|
|
|
|
def load_config (c):
|
2014-12-20 01:41:29 +00:00
|
|
|
config = load (open ("lib/config.json"))
|
|
|
|
passwd = load (open ("lib/passwords.json"))
|
2014-12-20 00:07:14 +00:00
|
|
|
|
|
|
|
random.seed ()
|
|
|
|
c['slaves'] = [BuildSlave (slave['name'], passwd[slave['name']],
|
|
|
|
max_builds = 1,
|
|
|
|
properties = { 'jobs' : slave['jobs'],
|
|
|
|
'randomWait' : "%d" % random.randrange (1, 30) })
|
|
|
|
for slave in config['slaves']]
|
|
|
|
|
|
|
|
c['schedulers'] = []
|
|
|
|
for s in config['schedulers']:
|
|
|
|
if "change_filter" in s:
|
|
|
|
s['change_filter'] = globals ()[s['change_filter']]
|
|
|
|
kls = globals ()[s.pop ('type')]
|
|
|
|
s = dict (map (lambda key_value_pair : (str (key_value_pair[0]),
|
|
|
|
key_value_pair[1]),
|
|
|
|
s.items ()))
|
|
|
|
c['schedulers'].append (kls (**s))
|
|
|
|
|
|
|
|
c['builders'] = []
|
|
|
|
for b in config['builders']:
|
|
|
|
if 'arch_triplet' in b:
|
|
|
|
arch_triplet = [ b.pop ('arch_triplet') ]
|
|
|
|
else:
|
|
|
|
arch_triplet = []
|
|
|
|
btype = b.pop ('type')
|
|
|
|
factory = globals ()[ "RunTestGDB%s" % btype ]
|
|
|
|
b['factory'] = factory (arch_triplet)
|
|
|
|
c['builders'].append (b)
|
|
|
|
|
2014-12-13 08:45:56 +00:00
|
|
|
load_config (c)
|