Skip to content

Commit

Permalink
Merge pull request #1313 from tardyp/t2978
Browse files Browse the repository at this point in the history
Fix: Loading the waterfall while a build is in progress return 500

Fixes ticket:2978
  • Loading branch information
Mikhail Sobolev committed Nov 2, 2014
2 parents 060656a + 6d2f209 commit 0132c9a
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
16 changes: 14 additions & 2 deletions master/buildbot/data/resultspec.py
Expand Up @@ -51,6 +51,18 @@ def _apply(self, data):
return (d for d in data if f(d[fld], v))


def nonecmp(a, b):
# Some fields are nullable, and could raise TypeException, when REST is requesting sorting
# I order to fix that, we create a custom cmp function which treats None as smaller than anything
if a is None and b is None:
return 0
if a is None:
return -1
if b is None:
return 1
return cmp(a, b)


class ResultSpec(object):

__slots__ = ['filters', 'fields', 'order', 'limit', 'offset']
Expand Down Expand Up @@ -147,9 +159,9 @@ def includeFields(d):

# precompute the ordering functions and sort
if self.order:
order = [(lambda a, b, k=k[1:]: cmp(b[k], a[k]))
order = [(lambda a, b, k=k[1:]: nonecmp(b[k], a[k]))
if k[0] == '-' else
(lambda a, b, k=k: cmp(a[k], b[k]))
(lambda a, b, k=k: nonecmp(a[k], b[k]))
for k in self.order]

def cmpFunc(a, b):
Expand Down
32 changes: 32 additions & 0 deletions master/buildbot/test/unit/test_data_resultspec.py
Expand Up @@ -13,6 +13,7 @@
#
# Copyright Buildbot Team Members

import datetime
import random

from buildbot.data import base
Expand Down Expand Up @@ -156,6 +157,19 @@ def test_apply_missing_fields(self):
self.assertRaises(KeyError, lambda:
resultspec.ResultSpec(fields=['fn'], order=['ln']).apply(data))

def test_sort_null_datetimefields(self):
data = mklist(('fn', 'ln'),
('albert', datetime.datetime(1, 1, 1)),
('cedric', None))

exp = mklist(('fn', 'ln'),
('cedric', None),
('albert', datetime.datetime(1, 1, 1)))

self.assertListResultEqual(
resultspec.ResultSpec(order=['ln']).apply(data),
base.ListResult(exp, total=2))

def do_test_pagination(self, bareList):
data = mklist('x', *range(101, 131))
if not bareList:
Expand Down Expand Up @@ -247,3 +261,21 @@ def test_popField_not_present(self):
rs = resultspec.ResultSpec(fields=['foo', 'bar'])
self.assertFalse(rs.popField('nosuch'))
self.assertEqual(rs.fields, ['foo', 'bar'])


class NoneCmp(unittest.TestCase):

def test_nonecmp(self):
nonecmp = resultspec.nonecmp
self.assertEqual(nonecmp(None, datetime.datetime(1, 1, 1)),
-1)
self.assertEqual(nonecmp(datetime.datetime(1, 1, 1), None),
1)
self.assertEqual(nonecmp(None, None),
0)
self.assertEqual(nonecmp(datetime.datetime(1, 1, 1), datetime.datetime(1, 1, 1)),
0)
self.assertEqual(nonecmp(datetime.datetime(1, 1, 2), datetime.datetime(1, 1, 1)),
1)
self.assertEqual(nonecmp(datetime.datetime(1, 1, 1), datetime.datetime(1, 1, 2)),
-1)

0 comments on commit 0132c9a

Please sign in to comment.