[SCM] build.samba.org - branch master updated

Jelmer Vernooij jelmer at samba.org
Tue Nov 2 03:41:07 MDT 2010


The branch, master has been updated
       via  0176213 Split out html formatting from build status.
       via  126d0ca Remove obsolete build_revision/build_revision_time methods.
       via  c3c648e Move err_count() to Build.
       via  cd99cea Add test for Build.revision_details().
       via  5616abd Kill unused status_info_cmp.
      from  0c4399c Move build_status onto Build.

http://gitweb.samba.org/?p=build-farm.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 0176213d629c1fd5838dd05c2a7cff265952ff7e
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Tue Nov 2 10:40:24 2010 +0100

    Split out html formatting from build status.

commit 126d0ca4e6aafb6ffa7bb62f0d0cee7b92a0869a
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Tue Nov 2 10:25:35 2010 +0100

    Remove obsolete build_revision/build_revision_time methods.

commit c3c648e59309a507bb04bf651f6329f11a766faa
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Tue Nov 2 10:24:30 2010 +0100

    Move err_count() to Build.

commit cd99cea227a717dce746dfd4f52b5a974b035ea7
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Tue Nov 2 10:17:38 2010 +0100

    Add test for Build.revision_details().

commit 5616abd3220519b0ada4eec425bd74877af329ff
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Tue Nov 2 10:12:05 2010 +0100

    Kill unused status_info_cmp.

-----------------------------------------------------------------------

Summary of changes:
 buildfarm/data.py            |  182 +++++++++++++++++-------------------------
 buildfarm/tests/test_data.py |   27 ++++++
 web/build.py                 |    2 +-
 3 files changed, 103 insertions(+), 108 deletions(-)


Changeset truncated at 500 lines:

diff --git a/buildfarm/data.py b/buildfarm/data.py
index 426f50a..303885d 100644
--- a/buildfarm/data.py
+++ b/buildfarm/data.py
@@ -48,26 +48,6 @@ class NoSuchBuildError(Exception):
         self.rev = rev
 
 
-def status_info_cmp(self, s1, s2):
-    a1 = s1["array"]
-    a2 = s2["array"]
-    c1 = 0
-    c2 = 0
-
-    i = 0
-    while True:
-        if i >= len(a1) or i >= len(a2):
-            break
-
-        if c1 != c2:
-            return c2 - c1
-
-        if a1[i] != a2[i]:
-            return a2[i] - a1[i]
-
-    return s2["value"] - s1["value"]
-
-
 class Tree(object):
     """A tree to build."""
 
@@ -124,22 +104,14 @@ class Build(object):
         """read full err file"""
         return util.FileLoad(self._store.build_fname(self.tree, self.host, self.compiler, self.rev)+".err")
 
-    def build_revision_details(self):
+    def revision_details(self):
         """get the revision of build
-        
+
         :return: Tuple with revision id and timestamp (if available)
         """
         file = self._store.build_fname(self.tree, self.host, self.compiler, self.rev)
         cachef = self._store.cache_fname(self.tree, self.host, self.compiler, self.rev)
 
-        # don't fast-path for trees with git repository:
-        # we get the timestamp as rev and want the details
-        if self.rev:
-            if self.tree not in self._store.trees:
-                return self.rev
-            if self.trees[self.tree].scm != "git":
-                return self.rev
-
         st1 = os.stat("%s.log" % file)
 
         try:
@@ -171,7 +143,7 @@ class Build(object):
         finally:
             f.close()
 
-        if not self.readonly:
+        if not self._store.readonly:
             util.FileSave("%s.revision" % cachef, "%s:%s" % (revid, timestamp or ""))
 
         return (revid, timestamp)
@@ -199,13 +171,42 @@ class Build(object):
         log = self.read_log()
         err = self.read_err()
 
-        ret = self._store.build_status_from_logs(log, err)
+        ret = self._store.html_build_status_from_logs(log, err)
 
-        if not self.readonly:
+        if not self._store.readonly:
             util.FileSave(cachefile, ret)
 
         return ret
 
+    def err_count(self):
+        """get status of build"""
+        file = self._store.build_fname(self.tree, self.host, self.compiler, self.rev)
+        cachef = self._store.cache_fname(self.tree, self.host, self.compiler, self.rev)
+
+        st1 = os.stat("%s.err" % file)
+
+        try:
+            st2 = os.stat("%s.errcount" % cachef)
+        except OSError:
+            # File does not exist
+            st2 = None
+
+        if st2 and st1.st_ctime <= st2.st_mtime:
+            return util.FileLoad("%s.errcount" % cachef)
+
+        try:
+            err = util.FileLoad("%s.err" % file)
+        except OSError:
+            # File does not exist
+            return 0
+
+        ret = util.count_lines(err)
+
+        if not self._store.readonly:
+            util.FileSave("%s.errcount" % cachef, str(ret))
+
+        return ret
+
 
 def read_trees_from_conf(path):
     """Read trees from a configuration file."""
@@ -259,9 +260,9 @@ class BuildResultStore(object):
 
     def cache_fname(self, tree, host, compiler, rev=None):
         if rev is not None:
-            return os.path.join(self.cachedir, "build.%s.%s.%s-%s" % (tree,host,compiler,rev))
+            return os.path.join(self.cachedir, "build.%s.%s.%s-%s" % (tree, host, compiler, rev))
         else:
-            return os.path.join(self.cachedir, "build.%s.%s.%s" % (tree,host,compiler))
+            return os.path.join(self.cachedir, "build.%s.%s.%s" % (tree, host, compiler))
 
     def build_fname(self, tree, host, compiler, rev=None):
         """get the name of the build file"""
@@ -269,81 +270,82 @@ class BuildResultStore(object):
             return os.path.join(self.datadir, "oldrevs/build.%s.%s.%s-%s" % (tree, host, compiler, rev))
         return os.path.join(self.datadir, "upload/build.%s.%s.%s" % (tree, host, compiler))
 
-
-    def build_revision(self, tree, host, compiler, rev=None):
-        build = self.get_build(tree, host, compiler, rev)
-        return build.revision_details()[0]
-
-    def build_revision_time(self, tree, host, compiler, rev=None):
-        build = self.get_build(tree, host, compiler, rev)
-        return build.revision_details()[1]
-
-    def build_status_from_logs(self, log, err):
-        """get status of build"""
+    def html_build_status_from_logs(self, log, err):
         def span_status(st):
-            if st == 0:
+            if st is None:
+                return span("status unknown", "?")
+            elif st == 0:
                 return span("status passed", "ok")
             else:
                 return span("status failed", st)
+        (cstatus, bstatus, istatus, tstatus, sstatus, other_failures) = self.build_status_from_logs(log, err)
+        ostatus = ""
+        if "panic" in other_failures:
+            ostatus += "/"+span("status panic", "PANIC")
+        if "disk full" in other_failures:
+            ostatus += "/"+span("status failed", "disk full")
+        if "timeout" in other_failures:
+            ostatus += "/"+span("status failed", "timeout")
+        if sstatus is not None:
+            ostatus += "/".span("status checker", sstatus)
+        return "%s/%s/%s/%s%s" % (span_status(cstatus), span_status(bstatus), span_status(istatus), span_status(tstatus), ostatus)
 
+    def build_status_from_logs(self, log, err):
+        """get status of build"""
         m = re.search("TEST STATUS:(.*)", log)
         if m:
-            tstatus = span_status(m.group(1))
+            tstatus = m.group(1)
         else:
             m = re.search("ACTION (PASSED|FAILED): test", log)
             if m:
                 test_failures = len(re.findall("testsuite-(failure|error): ", log))
                 test_successes = len(re.findall("testsuite-success: ", log))
                 if test_successes > 0:
-                    tstatus = span_status(test_failures)
+                    tstatus = test_failures
                 else:
-                    tstatus = span_status(255)
+                    tstatus = 255
             else:
-                tstatus = span("status unknown", "?")
+                tstatus = None
 
         m = re.search("INSTALL STATUS:(.*)", log)
         if m:
-            istatus = span_status(m.group(1))
+            istatus = m.group(1)
         else:
-            istatus = span("status unknown", "?")
+            istatus = None
 
         m = re.search("BUILD STATUS:(.*)", log)
         if m:
-            bstatus = span_status(m.group(1))
+            bstatus = m.group(1)
         else:
-            bstatus = span("status unknown", "?")
+            bstatus = None
 
         m = re.search("CONFIGURE STATUS:(.*)", log)
         if m:
-            cstatus = span_status(m.group(1))
+            cstatus = m.group(1)
         else:
-            cstatus = span("status unknown", "?")
+            cstatus = None
 
+        other_failures = set()
         m = re.search("(PANIC|INTERNAL ERROR):.*", log)
         if m:
-            sstatus = "/"+span("status panic", "PANIC")
-        else:
-            sstatus = ""
+            other_failures.add("panic")
 
         if "No space left on device" in err or "No space left on device" in log:
-            dstatus = "/"+span("status failed", "disk full")
-        else:
-            dstatus = ""
+            other_failures.add("disk full")
 
         if "maximum runtime exceeded" in log:
-            tostatus = "/"+span("status failed", "timeout")
-        else:
-            tostatus = ""
+            other_failures.add("timeout")
 
         m = re.search("CC_CHECKER STATUS: (.*)", log)
-        if m and int(m.group(1)) > 0:
-            sstatus += "/".span("status checker", m.group(1))
+        if m:
+            sstatus = m.group(1)
+        else:
+            sstatus = None
 
-        return "%s/%s/%s/%s%s%s%s" % (
-                cstatus, bstatus, istatus, tstatus, sstatus, dstatus, tostatus)
+        return (cstatus, bstatus, istatus, tstatus, sstatus, other_failures)
 
     def build_status_info_from_string(self, rev_seq, rev, status_raw):
-        """find the build status as an perl object
+        """find the build status as an object
 
         the 'value' gets one point for passing each stage"""
         status_split = status_raw.split("/")
@@ -426,38 +428,6 @@ class BuildResultStore(object):
             util.FileSave(cachefile, ret)
         return ret
 
-    def err_count(self, tree, host, compiler, rev):
-        """get status of build"""
-        file = self.build_fname(tree, host, compiler, rev)
-        cachef = self.cache_fname(tree, host, compiler, rev)
-
-        try:
-            st1 = os.stat("%s.err" % file)
-        except OSError:
-            # File does not exist
-            return 0
-        try:
-            st2 = os.stat("%s.errcount" % cachef)
-        except OSError:
-            # File does not exist
-            st2 = None
-
-        if st2 and st1.st_ctime <= st2.st_mtime:
-            return util.FileLoad("%s.errcount" % cachef)
-
-        try:
-            err = util.FileLoad("%s.err" % file)
-        except OSError:
-            # File does not exist
-            return 0
-
-        ret = util.count_lines(err)
-
-        if not self.readonly:
-            util.FileSave("%s.errcount" % cachef, str(ret))
-
-        return ret
-
     def get_old_revs(self, tree, host, compiler):
         """get a list of old builds and their status."""
         ret = []
@@ -488,15 +458,13 @@ class BuildResultStore(object):
 
     def host_age(self, host):
         """get the overall age of a host"""
-        ret = -1
+        ret = None
         for compiler in self.compilers:
             for tree in self.trees:
                 try:
                     build = self.get_build(tree, host, compiler)
-                    age = build.age_mtime()
                 except NoSuchBuildError:
                     pass
                 else:
-                    if (age < ret or ret == -1):
-                        ret = age
+                    ret = min(ret, build.age_mtime())
         return ret
diff --git a/buildfarm/tests/test_data.py b/buildfarm/tests/test_data.py
index d54206e..f882ef1 100755
--- a/buildfarm/tests/test_data.py
+++ b/buildfarm/tests/test_data.py
@@ -90,3 +90,30 @@ class BuildResultStoreTests(BuildFarmTestCase):
             contents="This is what an stderr file looks like.")
         build = self.x.get_build("tdb", "charis", "cc")
         self.assertEquals("This is what an stderr file looks like.", build.read_err())
+
+    def test_revision_details(self):
+        self.create_mock_logfile("tdb", "charis", "cc", contents="""
+BUILD COMMIT REVISION: 43
+bla
+BUILD REVISION: 42
+BUILD COMMIT TIME: 3 August 2010
+""")
+        build = self.x.get_build("tdb", "charis", "cc")
+        self.assertEquals(("42", "3 August 2010"), build.revision_details())
+
+    def test_revision_details_no_timestamp(self):
+        self.create_mock_logfile("tdb", "charis", "cc", contents="""
+BUILD COMMIT REVISION: 43
+BUILD REVISION: 42
+BLA
+""")
+        build = self.x.get_build("tdb", "charis", "cc")
+        self.assertEquals(("42", None), build.revision_details())
+
+    def test_err_count(self):
+        self.create_mock_logfile("tdb", "charis", "cc")
+        self.create_mock_logfile("tdb", "charis", "cc", kind="stderr", contents="""error1
+error2
+error3""")
+        build = self.x.get_build("tdb", "charis", "cc")
+        self.assertEquals(3, build.err_count())
diff --git a/web/build.py b/web/build.py
index 71d4bae..29cb741 100755
--- a/web/build.py
+++ b/web/build.py
@@ -466,7 +466,7 @@ def view_host(myself, output_type, *requested_hosts):
                     revision, revision_time = build.revision_details()
                     age_mtime = build.age_mtime()
                     age_ctime = build.age_ctime()
-                    warnings = db.err_count(tree, host, compiler)
+                    warnings = build.err_count()
                     status = build_status(myself, tree, host, compiler)
                     if row == 0:
                         if output_type == 'text':


-- 
build.samba.org


More information about the samba-cvs mailing list