[pypy-svn] r60734 - in pypy/build/bot2/pypybuildbot: . test
pedronis at codespeak.net
pedronis at codespeak.net
Mon Dec 29 21:52:07 CET 2008
Author: pedronis
Date: Mon Dec 29 21:52:04 2008
New Revision: 60734
Modified:
pypy/build/bot2/pypybuildbot/summary.py
pypy/build/bot2/pypybuildbot/test/test_summary.py
Log:
drill down by builder and builds, in these cases all builds not only the last one are shown for a given revision
Modified: pypy/build/bot2/pypybuildbot/summary.py
==============================================================================
--- pypy/build/bot2/pypybuildbot/summary.py (original)
+++ pypy/build/bot2/pypybuildbot/summary.py Mon Dec 29 21:52:04 2008
@@ -160,7 +160,7 @@
self._skipped = None
self._numpassed = None
self.revision = map.values()[0].revision
-
+
@property
def failed(self):
if self._failed is None:
@@ -231,6 +231,7 @@
def __init__(self):
self.sections = []
self.cur_branch=None
+ self.fixed_builder = False
def make_longrepr_url_for(self, outcome_set, namekey):
cachekey, namekey = outcome_set.get_key_namekey(namekey)
@@ -261,26 +262,43 @@
branch_anchor = html.a(branch, href="/summary?branch=%s" % branch)
self.sections.append(html.h2(branch_anchor))
- def _rev_anchor(self, rev):
- rev_anchor = html.a(str(rev), href="/summary?branch=%s&recentrev=%d" %
- (self.cur_branch, rev))
+ def _builder_num(self, outcome_set):
+ return outcome_set.map.values()[0].key
+
+ def _label(self, outcome_set):
+ if self.fixed_builder:
+ # (rev, buildNumber)
+ buildNumber = self._builder_num(outcome_set)[1]
+ return (outcome_set.revision, buildNumber)
+ else:
+ # rev
+ return outcome_set.revision
+
+ def _label_anchor(self, outcome_set):
+ rev = outcome_set.revision
+ if self.fixed_builder:
+ pick = "builder=%s&builds=%d" % self._builder_num(outcome_set)
+ else:
+ pick = "recentrev=%d" % rev
+ rev_anchor = html.a(str(rev), href="/summary?branch=%s&%s" %
+ (self.cur_branch, pick))
return rev_anchor
def add_section(self, outcome_sets):
if not outcome_sets:
return
- revs = sorted(outcome_set.revision for outcome_set in outcome_sets)
- by_rev = sorted((outcome_set.revision, outcome_set) for outcome_set
+ labels = sorted(self._label(outcome_set) for outcome_set in outcome_sets)
+ by_label = sorted((self._label(outcome_set), outcome_set) for outcome_set
in outcome_sets)
lines = []
- align = 2*len(revs)-1+len(str(revs[-1]))
+ align = 2*len(labels)-1+len(str(labels[-1]))
def bars():
return ' |'*len(lines)
- for rev, outcome_set in by_rev:
+ for label, outcome_set in by_label:
count_failures = len(outcome_set.failed)
count_skipped = len(outcome_set.skipped)
- line = [bars(), ' ', self._rev_anchor(rev)]
+ line = [bars(), ' ', self._label_anchor(outcome_set)]
line.append((align-len(line[0]))*" ")
line.append(self.make_stdio_anchors_for(outcome_set))
line.append('\n')
@@ -289,7 +307,7 @@
failed = set()
exploded = set()
- for rev, outcome_set in by_rev:
+ for label, outcome_set in by_label:
for failure in outcome_set.failed:
letter = outcome_set.get_outcome(failure)
if letter == '!':
@@ -303,7 +321,7 @@
for failure in sorted(failed, key=sorting):
line = []
- for rev, outcome_set in by_rev:
+ for label, outcome_set in by_label:
letter = outcome_set.get_outcome(failure)
failed = letter not in ('s', '.')
if outcome_set.get_longrepr(failure):
@@ -418,7 +436,12 @@
trunk_name = make_subst(None, "<trunk>")
trunk_value = make_subst("<trunk>", None)
-
+def safe_int(v):
+ try:
+ return int(v)
+ except ValueError:
+ return None
+
class Summary(HtmlResource):
def __init__(self):
@@ -431,20 +454,35 @@
N)
@staticmethod
- def _prune_revs(revs, cutnum):
- if len(revs) > cutnum:
- for rev in sorted(revs.keys())[:-cutnum]:
- del revs[rev]
+ def _prune_runs(runs, cutnum):
+ if len(runs) > cutnum:
+ for rev in sorted(runs.keys())[:-cutnum]:
+ del runs[rev]
- def recentRevisions(self, status, only_recentrevs=None, only_branches=None):
+ def recentRuns(self, status, only_recentrevs=None, only_branches=None,
+ only_builder=None, only_builds=None):
test_rev = make_test(only_recentrevs)
test_branch = make_test(only_branches)
+ test_builder = make_test(only_builder)
+ fixed_builder = bool(only_builder)
branches = {}
for builderName in status.getBuilderNames():
+ if not test_builder(builderName):
+ continue
builderStatus = status.getBuilder(builderName)
- for build in builderStatus.generateFinishedBuilds(num_builds=5*N):
+ if only_builds:
+ def builditer():
+ for num in only_builds:
+ b = builderStatus.getBuild(num)
+ if b is not None:
+ yield b
+ builditer = builditer()
+ else:
+ builditer = builderStatus.generateFinishedBuilds(num_builds=5*N)
+
+ for build in builditer:
branch = getProp(build, 'branch')
if not test_branch(branch):
continue
@@ -452,27 +490,49 @@
if not test_rev(got_rev):
continue
- revs, no_revision_builds = branches.setdefault(branch,
+ runs, no_revision_builds = branches.setdefault(branch,
({}, []))
if got_rev is None:
no_revision_builds.append(build)
else:
rev = int(got_rev)
- revBuilds = revs.setdefault(rev, {})
- # pick the most recent or ?
- if builderName not in revBuilds:
- revBuilds[builderName] = build.getNumber()
-
- for branch, (revs, no_revision_builds) in branches.items():
- self._prune_revs(revs, N)
- for rev, revBuilds in revs.iteritems():
- for builderName, buildNumber in revBuilds.items():
+ buildNumber = build.getNumber()
+ if fixed_builder:
+ builds = runs.setdefault((rev, buildNumber), {})
+ else:
+ builds = runs.setdefault(rev, {})
+ # pick the most recent or ?
+
+ if builderName not in builds:
+ builds[builderName] = build.getNumber()
+
+ for branch, (runs, no_revision_builds) in branches.items():
+ self._prune_runs(runs, N)
+ for label, runBuilds in runs.iteritems():
+ for builderName, buildNumber in runBuilds.items():
key = (builderName, buildNumber)
outcome_set = outcome_set_cache.get(status, key)
- revBuilds[builderName] = outcome_set
+ runBuilds[builderName] = outcome_set
return branches
+
+ @staticmethod
+ def _parse_builds(build_select):
+ builds = set()
+ for sel in build_select:
+ for onesel in sel.split(','):
+ build = safe_int(onesel)
+ if build is not None:
+ builds.add(build)
+ continue
+ build_start_end = onesel.split('-')
+ if len(build_start_end) == 2:
+ build_start = safe_int(build_start_end[0])
+ build_end = safe_int(build_start_end[1])
+ if (build_start is not None and build_end is not None):
+ builds.update(range(build_start, build_end+1))
+ return builds
def body(self, request):
t0 = time.time()
@@ -487,14 +547,24 @@
only_recentrevs = request.args.get('recentrev', None)
if only_branches is not None:
only_branches = map(trunk_value, only_branches)
-
- branches = self.recentRevisions(status,
- only_recentrevs=only_recentrevs,
- only_branches=only_branches)
+ only_builder = request.args.get('builder', None)
+ only_builds = None
+ if only_builder is not None:
+ only_builder = only_builder[-1:] # pick exactly one
+ page.fixed_builder = True
+ build_select = request.args.get('builds', None)
+ if build_select is not None:
+ only_builds = self._parse_builds(build_select)
+
+ branches = self.recentRuns(status,
+ only_recentrevs=only_recentrevs,
+ only_branches=only_branches,
+ only_builder=only_builder,
+ only_builds=only_builds)
- for branch, (revs, no_revision_builds) in sorted(branches.iteritems()):
+ for branch, (runs, no_revision_builds) in sorted(branches.iteritems()):
outcome_sets = []
- for rev, by_build in revs.items():
+ for label, by_build in runs.items():
outcome_sets.append(GatherOutcomeSet(by_build))
branch = trunk_name(branch)
page.start_branch(branch)
Modified: pypy/build/bot2/pypybuildbot/test/test_summary.py
==============================================================================
--- pypy/build/bot2/pypybuildbot/test/test_summary.py (original)
+++ pypy/build/bot2/pypybuildbot/test/test_summary.py Mon Dec 29 21:52:04 2008
@@ -3,6 +3,7 @@
from buildbot.status import builder as status_builder
from pypybuildbot import summary
from StringIO import StringIO
+import re
class TestOutcomes(object):
@@ -215,14 +216,14 @@
assert res == [2,3,2]
-def test__prune_revs():
- revs = dict(zip(range(100), range(100, 200)))
+def test__prune_runs():
+ runs = dict(zip(range(100), range(100, 200)))
- summary.Summary._prune_revs(revs, 4)
+ summary.Summary._prune_runs(runs, 4)
- assert len(revs) == 4
+ assert len(runs) == 4
- assert revs == {99: 199, 98: 198, 97: 197, 96: 196}
+ assert runs == {99: 199, 98: 198, 97: 197, 96: 196}
class _BuilderToStatus(object):
@@ -254,12 +255,12 @@
def witness_branches(summary):
ref = [None]
- recentRevisions = summary.recentRevisions
+ recentRuns = summary.recentRuns
def witness(*args, **kwds):
- branches = recentRevisions(*args, **kwds)
+ branches = recentRuns(*args, **kwds)
ref[0] = branches
return branches
- summary.recentRevisions = witness
+ summary.recentRuns = witness
return lambda: ref[0]
@@ -328,7 +329,7 @@
def test_one_build(self):
builder = status_builder.BuilderStatus('builder0')
- add_builds(builder, [(60000, ". a")])
+ add_builds(builder, [(60000, "F a\n. b")])
s = summary.Summary()
res = witness_branches(s)
@@ -344,13 +345,13 @@
def test_two_builds(self):
builder = status_builder.BuilderStatus('builder0')
- add_builds(builder, [(60000, ". a"),
- (60001, ". a")])
+ add_builds(builder, [(60000, "F a\n. b"),
+ (60001, "F a\n. b")])
s = summary.Summary()
res = witness_branches(s)
req = FakeRequest([builder])
- s.body(req)
+ out = s.body(req)
branches = res()
revs = branches[None][0]
@@ -360,12 +361,18 @@
assert outcome.key == ('builder0', 0)
outcome = revs[60001]['builder0']
assert outcome.revision == 60001
- assert outcome.key == ('builder0', 1)
+ assert outcome.key == ('builder0', 1)
+
+ revs = []
+ for m in re.finditer(r'recentrev=(\d+)', out):
+ revs.append(int(m.group(1)))
+
+ assert revs == [60000, 60001]
def test_two_builds_samerev(self):
builder = status_builder.BuilderStatus('builder0')
- add_builds(builder, [(60000, ". a"),
- (60000, ". a")])
+ add_builds(builder, [(60000, "F a\n. b"),
+ (60000, "F a\n. b")])
s = summary.Summary()
res = witness_branches(s)
@@ -381,8 +388,8 @@
def test_two_builds_recentrev(self):
builder = status_builder.BuilderStatus('builder0')
- add_builds(builder, [(60000, ". a"),
- (60001, ". a")])
+ add_builds(builder, [(60000, "F a\n. b"),
+ (60001, "F a\n. b")])
s = summary.Summary()
res = witness_branches(s)
@@ -397,4 +404,66 @@
assert outcome.revision == 60000
assert outcome.key == ('builder0', 0)
-
+ def test_many_builds_query_builder(self):
+ builder = status_builder.BuilderStatus('builder0')
+ add_builds(builder, [(60000, "F a\n. b"),
+ (60000, ". a\n. b"),
+ (60001, "F a\n. b")])
+
+ s = summary.Summary()
+ res = witness_branches(s)
+ req = FakeRequest([builder])
+ req.args={'builder': ['builder0']}
+ out = s.body(req)
+ branches = res()
+
+ runs = branches[None][0]
+ assert sorted(runs.keys()) == [(60000,0), (60000,1), (60001,2)]
+ outcome = runs[(60000,0)]['builder0']
+ assert outcome.revision == 60000
+ assert outcome.key == ('builder0', 0)
+ outcome = runs[(60000,1)]['builder0']
+ assert outcome.revision == 60000
+ assert outcome.key == ('builder0', 1)
+ outcome = runs[(60001,2)]['builder0']
+ assert outcome.revision == 60001
+ assert outcome.key == ('builder0', 2)
+
+ runs = []
+ for m in re.finditer(r'builder=(\w+)&builds=(\d+)', out):
+ runs.append((m.group(1), int(m.group(2))))
+
+ assert runs == [('builder0', 0),
+ ('builder0', 1),
+ ('builder0', 2)]
+
+
+ def test_many_builds_query_builder_builds(self):
+ builder = status_builder.BuilderStatus('builder0')
+ add_builds(builder, [(60000, "F a\n. b"),
+ (60000, ". a\n. b"),
+ (60001, "F a\n. b")])
+
+ s = summary.Summary()
+ res = witness_branches(s)
+ req = FakeRequest([builder])
+ req.args={'builder': ['builder0'],
+ 'builds': ['0','2-2', '7']}
+ out = s.body(req)
+ branches = res()
+
+ runs = branches[None][0]
+ assert sorted(runs.keys()) == [(60000,0), (60001,2)]
+ outcome = runs[(60000,0)]['builder0']
+ assert outcome.revision == 60000
+ assert outcome.key == ('builder0', 0)
+ outcome = runs[(60001,2)]['builder0']
+ assert outcome.revision == 60001
+ assert outcome.key == ('builder0', 2)
+
+ runs = []
+ for m in re.finditer(r'builder=(\w+)&builds=(\d+)', out):
+ runs.append((m.group(1), int(m.group(2))))
+
+ assert runs == [('builder0', 0),
+ ('builder0', 2)]
More information about the Pypy-commit
mailing list