build_test.fns: use --with-perl-{lib,arch}-install-dir= for samba_4_*
[build-farm.git] / import-and-analyse.py
index 05c8a874f0de234d518e95dc095b66256f44d3f6..2318cc1351874ab161501b72a9ee10a94c91fc7c 100755 (executable)
@@ -10,11 +10,16 @@ some mail chastising the possible culprits when the build fails, based
 on recent commits.
 """
 
-from buildfarm import data
-from buildfarm.sqldb import StormCachingBuildFarm
+from buildfarm.build import (
+    BuildDiff,
+    MissingRevisionInfo,
+    NoSuchBuildError,
+    )
+from buildfarm import BuildFarm
+from buildfarm.web import build_uri
 from email.mime.text import MIMEText
-import logging
 import optparse
+import resource
 import smtplib
 
 parser = optparse.OptionParser("import-and-analyse [options]")
@@ -23,29 +28,36 @@ parser.add_option("--verbose", help="Be verbose", action="count")
 
 (opts, args) = parser.parse_args()
 
-buildfarm = StormCachingBuildFarm()
+resource.setrlimit(resource.RLIMIT_RSS, (300000, 300000))
+resource.setrlimit(resource.RLIMIT_DATA, (300000, 300000))
+
+buildfarm = BuildFarm(timeout=40.0)
 
 smtp = smtplib.SMTP()
 smtp.connect()
 
-def check_and_send_mails(tree, host, compiler, cur, old):
-    t = buildfarm.trees[tree]
+def check_and_send_mails(cur, old):
+
+    if cur.tree is "waf":
+        # no point sending emails, as the email addresses are invalid
+        return
 
-    (cur_rev, cur_rev_timestamp) = cur.revision_details()
-    cur_status = cur.status()
+    if cur.tree is "samba_3_waf":
+        # no emails for this until it stabilises a bit
+        return
 
-    (old_rev, old_rev_timestamp) = old.revision_details()
-    old_status = old.status()
+    t = buildfarm.trees[cur.tree]
+    diff = BuildDiff(t, old, cur)
 
-    if not cur_status.regressed_since(old_status):
-        if opts.verbose >= 1:
-            print "the build didn't get worse since %r" % old_status
+    if not diff.is_regression():
+        if opts.verbose >= 3:
+            print "... hasn't regressed since %s: %s" % (diff.old_rev, diff.old_status)
         return
 
     recipients = set()
     change_log = ""
 
-    for rev in t.get_branch().log(from_rev=cur.rev, exclude_revs=set([old.rev])):
+    for rev in diff.revisions():
         recipients.add(rev.author)
         recipients.add(rev.committer)
         change_log += """
@@ -64,53 +76,70 @@ Tree %(tree)s is %(scm)s branch %(branch)s.
 Build status for new revision %(cur_rev)s is %(cur_status)s
 Build status for old revision %(old_rev)s was %(old_status)s
 
-See http://build.samba.org/?function=View+Build;host=%(host)s;tree=%(tree)s;compiler=%(compiler)s
+See %(build_link)s
 
 The build may have been broken by one of the following commits:
 
 %(change_log)s
-    """ % {"tree": tree, "host": host, "compiler": compiler, "change_log": change_log, "scm": t.scm, "branch": t.branch,
-            "cur_rev": cur_rev, "old_rev": old_rev, "cur_status": cur_status, "old_status": old_status }
+    """ % {
+        "tree": cur.tree, "host": cur.host, "compiler": cur.compiler,
+        "change_log": change_log,
+        "scm": t.scm,
+        "branch": t.branch,
+        "cur_rev": diff.new_rev,
+        "old_rev": diff.old_rev,
+        "cur_status": diff.new_status,
+        "old_status": diff.old_status,
+        "build_link": build_uri("http://build.samba.org/build.cgi", cur)
+        }
 
     msg = MIMEText(body)
-    msg["Subject"] = "BUILD of %s:%s BROKEN on %s with %s AT REVISION %s" % (tree, t.branch, host, compiler, cur_rev)
+    msg["Subject"] = "BUILD of %s:%s BROKEN on %s with %s AT REVISION %s" % (cur.tree, t.branch, cur.host, cur.compiler, diff.new_rev)
     msg["From"] = "\"Build Farm\" <build@samba.org>"
-    msg["To"] = ",".join(recipients.keys())
+    msg["To"] = ",".join(recipients)
     if not opts.dry_run:
-        smtp.send(msg["From"], [msg["To"]], msg.as_string())
+        smtp.sendmail(msg["From"], [msg["To"]], msg.as_string())
     else:
         print msg.as_string()
 
 
 for build in buildfarm.get_new_builds():
-    if opts.verbose >= 1:
-        print "Processing %s..." % build,
+    if build in buildfarm.builds:
+        continue
 
     if not opts.dry_run:
-        buildfarm.builds.upload_build(build)
+        old_build = build
+        try:
+            build = buildfarm.builds.upload_build(old_build)
+        except MissingRevisionInfo:
+            print "No revision info in %r, skipping" % build
+            continue
 
-    (rev, rev_timestamp) = build.revision_details()
+    try:
+        rev = build.revision_details()
+    except MissingRevisionInfo:
+        print "No revision info in %r, skipping" % build
+        continue
 
-    if opts.verbose >= 1:
+    if opts.verbose >= 2:
+        print "%s... " % build,
         print str(build.status())
 
     try:
-        prev_rev = buildfarm.builds.get_previous_revision(build.tree, build.host, build.compiler, rev)
-    except data.NoSuchBuildError:
-        try:
+        if opts.dry_run:
             # Perhaps this is a dry run and rev is not in the database yet?
-            prev_rev = buildfarm.builds.get_latest_revision(build.tree, build.host, build.compiler)
-        except data.NoSuchBuildError:
-            if opts.verbose >= 1:
-                print "Unable to find previous build for %s,%s,%s" % (build.tree, build.host, build.compiler)
-            # Can't send a nastygram until there are 2 builds..
-            continue
+            prev_build = buildfarm.builds.get_latest_build(build.tree, build.host, build.compiler)
+        else:
+            prev_build = buildfarm.builds.get_previous_build(build.tree, build.host, build.compiler, rev)
+    except NoSuchBuildError:
+        if opts.verbose >= 1:
+            print "Unable to find previous build for %s,%s,%s" % (build.tree, build.host, build.compiler)
+        # Can't send a nastygram until there are 2 builds..
     else:
-        prev_build = buildfarm.get_build(build.tree, build.host, build.compiler, prev_rev)
-        check_and_send_mails(build.tree, build.host, build.compiler, build, prev_build)
+        check_and_send_mails(build, prev_build)
 
     if not opts.dry_run:
-        build.remove()
+        old_build.remove()
         buildfarm.commit()
 
 smtp.quit()