Mercurial > p > roundup > code
diff test/db_test_base.py @ 6332:6a6b4651be1f
Use server-side cursor for postgres in some cases
In filter, filter_iter, and _materialize_multilinks, use named cursor
with postgresql. This turns of client-side cursor handling and avoids
*large* roundup process (or wsgi process) in case of large results.
Fixes issue2551114.
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Thu, 04 Mar 2021 12:55:21 +0100 |
| parents | 778a9f455067 |
| children | 0db59cc2cd37 |
line wrap: on
line diff
--- a/test/db_test_base.py Tue Mar 02 12:43:19 2021 -0500 +++ b/test/db_test_base.py Thu Mar 04 12:55:21 2021 +0100 @@ -177,10 +177,20 @@ def iterSetup(self, classname='issue'): cls = getattr(self.db, classname) - def filt_iter(*args, **kw): + def filt_iter_list(*args, **kw): """ for checking equivalence of filter and filter_iter """ return list(cls.filter_iter(*args, **kw)) - return self.assertEqual, cls.filter, filt_iter + def filter_test_iterator(): + """ yield all filter variants with config settings changed + appropriately + """ + self.db.config.RDBMS_SERVERSIDE_CURSOR = False + yield (cls.filter) + yield (filt_iter_list) + self.db.config.RDBMS_SERVERSIDE_CURSOR = True + yield (cls.filter) + yield (filt_iter_list) + return self.assertEqual, filter_test_iterator def filteringSetupTransitiveSearch(self, classname='issue'): u_m = {} @@ -493,10 +503,10 @@ def testDateSort(self): d1 = date.Date('.') - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() nid = self.db.issue.create(title="nodeadline", status='1') self.db.commit() - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {}, ('+','deadline')), ['5', '2', '1', '3', '4']) ae(filt(None, {}, ('+','id'), ('+', 'deadline')), ['5', '2', '1', '3', '4']) @@ -505,7 +515,7 @@ def testDateSortMultilink(self): d1 = date.Date('.') - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() nid = self.db.issue.create(title="nodeadline", status='1') self.db.commit() ae(sorted(self.db.issue.get('1','nosy')), []) @@ -518,12 +528,15 @@ ae(self.db.user.get('3','username'), 'bleep') # filter_iter currently doesn't work for Multilink sort # so testing only filter - ae(filter(None, {}, ('+', 'id'), ('+','nosy')), - ['1', '2', '5', '4', '3']) - ae(filter(None, {}, ('+','deadline'), ('+', 'nosy')), - ['5', '2', '1', '4', '3']) - ae(filter(None, {}, ('+','nosy'), ('+', 'deadline')), - ['5', '2', '1', '3', '4']) + for f in iiter(): + if f.__name__ != 'filter': + continue + ae(f(None, {}, ('+', 'id'), ('+','nosy')), + ['1', '2', '5', '4', '3']) + ae(f(None, {}, ('+','deadline'), ('+', 'nosy')), + ['5', '2', '1', '4', '3']) + ae(f(None, {}, ('+','nosy'), ('+', 'deadline')), + ['5', '2', '1', '3', '4']) # Interval def testIntervalChange(self): @@ -1565,7 +1578,7 @@ self.assertEqual(got, [one, three]) def testFindRevLinkMultilink(self): - ae, filter, filter_iter = self.filteringSetupTransitiveSearch('user') + ae, dummy = self.filteringSetupTransitiveSearch('user') ni = 'nosy_issues' self.db.issue.set('6', nosy=['3', '4', '5']) self.db.issue.set('7', nosy=['5']) @@ -1708,16 +1721,16 @@ return self.iterSetup(classname) def testFilteringID(self): - ae, filter, filter_iter = self.filteringSetup() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + for filt in iiter(): ae(filt(None, {'id': '1'}, ('+','id'), (None,None)), ['1']) ae(filt(None, {'id': '2'}, ('+','id'), (None,None)), ['2']) ae(filt(None, {'id': '100'}, ('+','id'), (None,None)), []) def testFilteringBoolean(self): - ae, filter, filter_iter = self.filteringSetup('user') + ae, iiter = self.filteringSetup('user') a = 'assignable' - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {a: '1'}, ('+','id'), (None,None)), ['3','4']) ae(filt(None, {a: '0'}, ('+','id'), (None,None)), ['5']) ae(filt(None, {a: ['1']}, ('+','id'), (None,None)), ['3','4']) @@ -1743,8 +1756,8 @@ ['3','4','5']) def testFilteringNumber(self): - ae, filter, filter_iter = self.filteringSetup('user') - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup('user') + for filt in iiter(): ae(filt(None, {'age': '1'}, ('+','id'), (None,None)), ['3']) ae(filt(None, {'age': '1.5'}, ('+','id'), (None,None)), ['4']) ae(filt(None, {'age': '2'}, ('+','id'), (None,None)), ['5']) @@ -1754,8 +1767,8 @@ ae(filt(None, {'age': [1,2]}, ('+','id'), (None,None)), ['3','5']) def testFilteringString(self): - ae, filter, filter_iter = self.filteringSetup() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + for filt in iiter(): ae(filt(None, {'title': ['one']}, ('+','id'), (None,None)), ['1']) ae(filt(None, {'title': ['issue one']}, ('+','id'), (None,None)), ['1']) @@ -1771,8 +1784,8 @@ Similar to testFilteringString except the search parameters have different capitalization. """ - ae, filter, filter_iter = self.filteringSetup() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + for filt in iiter(): ae(filt(None, {'title': ['One']}, ('+','id'), (None,None)), ['1']) ae(filt(None, {'title': ['Issue One']}, ('+','id'), (None,None)), ['1']) @@ -1784,12 +1797,12 @@ []) def testFilteringStringExactMatch(self): - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() # Change title of issue2 to 'issue' so we can test substring # search vs exact search self.db.issue.set('2', title='issue') #self.db.commit() - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {}, exact_match_spec = {'title': ['one']}), []) ae(filt(None, {}, exact_match_spec = @@ -1820,23 +1833,23 @@ """ Special characters in SQL search are '%' and '_', some used to lead to a traceback. """ - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() self.db.issue.set('1', title="With % symbol") self.db.issue.set('2', title="With _ symbol") self.db.issue.set('3', title="With \\ symbol") self.db.issue.set('4', title="With ' symbol") d = dict (status = '1') - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, dict(title='%'), ('+','id'), (None,None)), ['1']) ae(filt(None, dict(title='_'), ('+','id'), (None,None)), ['2']) ae(filt(None, dict(title='\\'), ('+','id'), (None,None)), ['3']) ae(filt(None, dict(title="'"), ('+','id'), (None,None)), ['4']) def testFilteringLink(self): - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() a = 'assignedto' grp = (None, None) - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {'status': '1'}, ('+','id'), grp), ['2','3']) ae(filt(None, {a: '-1'}, ('+','id'), grp), ['3','4']) ae(filt(None, {a: None}, ('+','id'), grp), ['3','4']) @@ -1845,7 +1858,7 @@ ae(filt(None, {a: ['1', None]}, ('+','id'), grp), ['1', '3','4']) def testFilteringRevLink(self): - ae, filter, filter_iter = self.filteringSetupTransitiveSearch('user') + ae, iiter = self.filteringSetupTransitiveSearch('user') # We have # issue assignedto # 1: 6 @@ -1856,7 +1869,7 @@ # 6: 10 # 7: 10 # 8: 10 - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {'issues': ['3', '4']}), ['7', '8']) ae(filt(None, {'issues': ['1', '4', '8']}), ['6', '8', '10']) ae(filt(None, {'issues.title': ['ts2']}), ['6']) @@ -1874,7 +1887,7 @@ self.db.issue.retire('2') self.db.issue.retire('3') self.db.commit() - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {'issues': ['3', '4']}), ['8']) ae(filt(None, {'issues': ['1', '4', '8']}), ['6', '8', '10']) ae(filt(None, {'issues.title': ['ts2']}), []) @@ -1885,10 +1898,10 @@ self.assertEqual(ls(self.db.user.get('10', 'issues')), ['7', '8']) def testFilteringLinkSortSearchMultilink(self): - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() a = 'assignedto' grp = (None, None) - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {'status.mls': '1'}, ('+','status')), ['2','3']) ae(filt(None, {'status.mls': '2'}, ('+','status')), ['2','3']) @@ -1897,26 +1910,26 @@ See roundup Bug 1541128: apparently grouping by something and searching a Multilink failed with MySQL 5.0 """ - ae, filter, filter_iter = self.filteringSetup() - for f in filter, filter_iter: + ae, iiter = self.filteringSetup() + for f in iiter(): ae(f(None, {'files': '1'}, ('-','activity'), ('+','status')), ['4']) def testFilteringRetired(self): - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() self.db.issue.retire('2') - for f in filter, filter_iter: + for f in iiter(): ae(f(None, {'status': '1'}, ('+','id'), (None,None)), ['3']) def testFilteringMultilink(self): - ae, filter, filter_iter = self.filteringSetup() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + for filt in iiter(): ae(filt(None, {'nosy': '3'}, ('+','id'), (None,None)), ['4']) ae(filt(None, {'nosy': '-1'}, ('+','id'), (None,None)), ['1', '2']) ae(filt(None, {'nosy': ['1','2']}, ('+', 'status'), ('-', 'deadline')), ['4', '3']) def testFilteringRevMultilink(self): - ae, filter, filter_iter = self.filteringSetupTransitiveSearch('user') + ae, iiter = self.filteringSetupTransitiveSearch('user') ni = 'nosy_issues' self.db.issue.set('6', nosy=['3', '4', '5']) self.db.issue.set('7', nosy=['5']) @@ -1930,7 +1943,7 @@ # 6: 3, 4, 5 # 7: 5 # 8: - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {ni: ['1', '2']}), ['4', '5']) ae(filt(None, {ni: ['6','7']}), ['3', '4', '5']) ae(filt(None, {'nosy_issues.title': ['ts2']}), ['5']) @@ -1946,7 +1959,7 @@ self.db.issue.retire('2') self.db.issue.retire('6') self.db.commit() - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {ni: ['1', '2']}), ['4']) ae(filt(None, {ni: ['6','7']}), ['5']) ae(filt(None, {'nosy_issues.title': ['ts2']}), []) @@ -1958,28 +1971,28 @@ self.assertEqual(ls(self.db.user.get('5', ni)), ['7']) def testFilteringMany(self): - ae, filter, filter_iter = self.filteringSetup() - for f in filter, filter_iter: + ae, iiter = self.filteringSetup() + for f in iiter(): ae(f(None, {'nosy': '2', 'status': '1'}, ('+','id'), (None,None)), ['3']) def testFilteringRangeBasic(self): - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() d = 'deadline' - for f in filter, filter_iter: + for f in iiter(): ae(f(None, {d: 'from 2003-02-10 to 2003-02-23'}), ['1','3']) ae(f(None, {d: '2003-02-10; 2003-02-23'}), ['1','3']) ae(f(None, {d: '; 2003-02-16'}), ['2']) def testFilteringRangeTwoSyntaxes(self): - ae, filter, filter_iter = self.filteringSetup() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + for filt in iiter(): ae(filt(None, {'deadline': 'from 2003-02-16'}), ['1', '3', '4']) ae(filt(None, {'deadline': '2003-02-16;'}), ['1', '3', '4']) def testFilteringRangeYearMonthDay(self): - ae, filter, filter_iter = self.filteringSetup() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + for filt in iiter(): ae(filt(None, {'deadline': '2002'}), []) ae(filt(None, {'deadline': '2003'}), ['1', '2', '3']) ae(filt(None, {'deadline': '2004'}), ['4']) @@ -1987,7 +2000,7 @@ ae(filt(None, {'deadline': '2003-02-17'}), []) def testFilteringRangeMonths(self): - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() for month in range(1, 13): for n in range(1, month+1): i = self.db.issue.create(title='%d.%d'%(month, n), @@ -1995,15 +2008,15 @@ self.db.commit() for month in range(1, 13): - for filt in filter, filter_iter: + for filt in iiter(): r = filt(None, dict(deadline='2001-%02d'%month)) assert len(r) == month, 'month %d != length %d'%(month, len(r)) def testFilteringDateRangeMulti(self): - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() self.db.issue.create(title='no deadline') self.db.commit() - for filt in filter, filter_iter: + for filt in iiter(): r = filt (None, dict(deadline='-')) self.assertEqual(r, ['5']) r = filt (None, dict(deadline=';2003-02-01,2004;')) @@ -2012,15 +2025,15 @@ self.assertEqual(r, ['2', '4', '5']) def testFilteringRangeInterval(self): - ae, filter, filter_iter = self.filteringSetup() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + for filt in iiter(): ae(filt(None, {'foo': 'from 0:50 to 2:00'}), ['1']) ae(filt(None, {'foo': 'from 0:50 to 1d 2:00'}), ['1', '2']) ae(filt(None, {'foo': 'from 5:50'}), ['2']) ae(filt(None, {'foo': 'to 0:05'}), []) def testFilteringRangeGeekInterval(self): - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() # Note: When querying, create date one minute later than the # timespan later queried to avoid race conditions where the # creation of the deadline is more than a second ago when @@ -2033,7 +2046,7 @@ { 'deadline': date.Date('. -8d') + date.Interval ('00:01')}, ): self.db.issue.create(**issue) - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {'deadline': '-2d;'}), ['5', '6']) ae(filt(None, {'deadline': '-1d;'}), ['6']) ae(filt(None, {'deadline': '-1w;'}), ['5', '6']) @@ -2046,8 +2059,8 @@ # 2: '1d' # 3: None # 4: '0:10' - ae, filter, filter_iter = self.filteringSetup() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + for filt in iiter(): # ascending should sort None, 1:10, 1d ae(filt(None, {}, ('+','foo'), (None,None)), ['3', '4', '1', '2']) # descending should sort 1d, 1:10, None @@ -2058,8 +2071,8 @@ # 2: 'issue two' # 3: 'issue three' # 4: 'non four' - ae, filter, filter_iter = self.filteringSetup() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + for filt in iiter(): ae(filt(None, {}, ('+','title')), ['1', '3', '2', '4']) ae(filt(None, {}, ('-','title')), ['4', '2', '3', '1']) # Test string case: For now allow both, w/wo case matching. @@ -2068,7 +2081,7 @@ # 3: 'Issue three' # 4: 'non four' self.db.issue.set('3', title='Issue three') - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {}, ('+','title')), ['1', '3', '2', '4']) ae(filt(None, {}, ('-','title')), ['4', '2', '3', '1']) # Obscure bug in anydbm backend trying to convert to number @@ -2078,7 +2091,7 @@ # 4: 'non four' self.db.issue.set('1', title='1st issue') self.db.issue.set('2', title='2') - for filt in filter, filter_iter: + for filt in iiter(): ae(filt(None, {}, ('+','title')), ['1', '2', '3', '4']) ae(filt(None, {}, ('-','title')), ['4', '3', '2', '1']) @@ -2092,9 +2105,12 @@ # multilink! # Note that we don't test filter_iter here, Multilink sort-order # isn't defined for that. - ae, filt, dummy = self.filteringSetup() - ae(filt(None, {}, ('+','nosy'), (None,None)), ['1', '2', '4', '3']) - ae(filt(None, {}, ('-','nosy'), (None,None)), ['4', '3', '1', '2']) + ae, iiter = self.filteringSetup() + for filt in iiter(): + if filt.__name__ != 'filter': + continue + ae(filt(None, {}, ('+','nosy'), (None,None)), ['1', '2', '4', '3']) + ae(filt(None, {}, ('-','nosy'), (None,None)), ['4', '3', '1', '2']) def testFilteringMultilinkSortGroup(self): # 1: status: 2 "in-progress" nosy: [] @@ -2103,23 +2119,34 @@ # 4: status: 3 "testing" nosy: ['admin','bleep','fred'] # Note that we don't test filter_iter here, Multilink sort-order # isn't defined for that. - ae, filt, dummy = self.filteringSetup() - ae(filt(None, {}, ('+','nosy'), ('+','status')), ['1', '4', '2', '3']) - ae(filt(None, {}, ('-','nosy'), ('+','status')), ['1', '4', '3', '2']) - ae(filt(None, {}, ('+','nosy'), ('-','status')), ['2', '3', '4', '1']) - ae(filt(None, {}, ('-','nosy'), ('-','status')), ['3', '2', '4', '1']) - ae(filt(None, {}, ('+','status'), ('+','nosy')), ['1', '2', '4', '3']) - ae(filt(None, {}, ('-','status'), ('+','nosy')), ['2', '1', '4', '3']) - ae(filt(None, {}, ('+','status'), ('-','nosy')), ['4', '3', '1', '2']) - ae(filt(None, {}, ('-','status'), ('-','nosy')), ['4', '3', '2', '1']) + ae, iiter = self.filteringSetup() + for filt in iiter(): + if filt.__name__ != 'filter': + continue + ae(filt(None, {}, ('+','nosy'), ('+','status')), + ['1', '4', '2', '3']) + ae(filt(None, {}, ('-','nosy'), ('+','status')), + ['1', '4', '3', '2']) + ae(filt(None, {}, ('+','nosy'), ('-','status')), + ['2', '3', '4', '1']) + ae(filt(None, {}, ('-','nosy'), ('-','status')), + ['3', '2', '4', '1']) + ae(filt(None, {}, ('+','status'), ('+','nosy')), + ['1', '2', '4', '3']) + ae(filt(None, {}, ('-','status'), ('+','nosy')), + ['2', '1', '4', '3']) + ae(filt(None, {}, ('+','status'), ('-','nosy')), + ['4', '3', '1', '2']) + ae(filt(None, {}, ('-','status'), ('-','nosy')), + ['4', '3', '2', '1']) def testFilteringLinkSortGroup(self): # 1: status: 2 -> 'i', priority: 3 -> 1 # 2: status: 1 -> 'u', priority: 3 -> 1 # 3: status: 1 -> 'u', priority: 2 -> 3 # 4: status: 3 -> 't', priority: 2 -> 3 - ae, filter, filter_iter = self.filteringSetup() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + for filt in iiter(): ae(filt(None, {}, ('+','status'), ('+','priority')), ['1', '2', '4', '3']) ae(filt(None, {'priority':'2'}, ('+','status'), ('+','priority')), @@ -2136,8 +2163,8 @@ # '2': '2003-01-01.00:00' # '3': '2003-02-18' # '4': '2004-03-08' - ae, filter, filter_iter = self.filteringSetup() - for f in filter, filter_iter: + ae, iiter = self.filteringSetup() + for f in iiter(): # ascending ae(f(None, {}, ('+','deadline'), (None,None)), ['2', '1', '3', '4']) # descending @@ -2148,9 +2175,9 @@ # '2': '2003-01-01.00:00' 3 => 1 # '3': '2003-02-18' 2 => 3 # '4': '2004-03-08' 1 => 2 - ae, filter, filter_iter = self.filteringSetup() - - for filt in filter, filter_iter: + ae, iiter = self.filteringSetup() + + for filt in iiter(): # ascending ae(filt(None, {}, ('+','deadline'), ('+','priority')), ['2', '1', '3', '4']) @@ -2163,8 +2190,8 @@ ['4', '3', '1', '2']) def testFilteringTransitiveLinkUser(self): - ae, filter, filter_iter = self.filteringSetupTransitiveSearch('user') - for f in filter, filter_iter: + ae, iiter = self.filteringSetupTransitiveSearch('user') + for f in iiter(): ae(f(None, {'supervisor.username': 'ceo'}, ('+','username')), ['4', '5']) ae(f(None, {'supervisor.supervisor.username': 'ceo'}, @@ -2184,8 +2211,8 @@ ('+','username')), ['6', '7']) def testFilteringTransitiveLinkUserLimit(self): - ae, filter, filter_iter = self.filteringSetupTransitiveSearch('user') - for f in filter, filter_iter: + ae, iiter = self.filteringSetupTransitiveSearch('user') + for f in iiter(): ae(f(None, {'supervisor.username': 'ceo'}, ('+','username'), limit=1), ['4']) ae(f(None, {'supervisor.supervisor.username': 'ceo'}, @@ -2203,15 +2230,15 @@ ('+','username'), limit=1, offset=5), []) def testFilteringTransitiveLinkSort(self): - ae, filter, filter_iter = self.filteringSetupTransitiveSearch() - ae, ufilter, ufilter_iter = self.iterSetup('user') + ae, iiter = self.filteringSetupTransitiveSearch() + ae, uiter = self.iterSetup('user') # Need to make ceo his own (and first two users') supervisor, # otherwise we will depend on sorting order of NULL values. # Leave that to a separate test. self.db.user.set('1', supervisor = '3') self.db.user.set('2', supervisor = '3') self.db.user.set('3', supervisor = '3') - for ufilt in ufilter, ufilter_iter: + for ufilt in uiter(): ae(ufilt(None, {'supervisor':'3'}, []), ['1', '2', '3', '4', '5']) ae(ufilt(None, {}, [('+','supervisor.supervisor.supervisor'), ('+','supervisor.supervisor'), ('+','supervisor'), @@ -2221,7 +2248,7 @@ ('-','supervisor.supervisor'), ('-','supervisor'), ('+','username')]), ['8', '9', '10', '6', '7', '1', '3', '2', '4', '5']) - for f in filter, filter_iter: + for f in iiter(): ae(f(None, {}, [('+','assignedto.supervisor.supervisor.supervisor'), ('+','assignedto.supervisor.supervisor'), ('+','assignedto.supervisor'), ('+','assignedto')]), @@ -2257,9 +2284,9 @@ def testFilteringTransitiveLinkSortNull(self): """Check sorting of NULL values""" - ae, filter, filter_iter = self.filteringSetupTransitiveSearch() - ae, ufilter, ufilter_iter = self.iterSetup('user') - for ufilt in ufilter, ufilter_iter: + ae, iiter = self.filteringSetupTransitiveSearch() + ae, uiter = self.iterSetup('user') + for ufilt in uiter(): ae(ufilt(None, {}, [('+','supervisor.supervisor.supervisor'), ('+','supervisor.supervisor'), ('+','supervisor'), ('+','username')]), @@ -2268,7 +2295,7 @@ ('-','supervisor.supervisor'), ('-','supervisor'), ('+','username')]), ['8', '9', '10', '6', '7', '4', '5', '1', '3', '2']) - for f in filter, filter_iter: + for f in iiter(): ae(f(None, {}, [('+','assignedto.supervisor.supervisor.supervisor'), ('+','assignedto.supervisor.supervisor'), ('+','assignedto.supervisor'), ('+','assignedto')]), @@ -2279,8 +2306,8 @@ ['4', '5', '6', '7', '8', '1', '2', '3']) def testFilteringTransitiveLinkIssue(self): - ae, filter, filter_iter = self.filteringSetupTransitiveSearch() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetupTransitiveSearch() + for filt in iiter(): ae(filt(None, {'assignedto.supervisor.username': 'grouplead1'}, ('+','id')), ['1', '2', '3']) ae(filt(None, {'assignedto.supervisor.username': 'grouplead2'}, @@ -2295,8 +2322,8 @@ ('+','id')), ['1', '3', '5', '7']) def testFilteringTransitiveMultilink(self): - ae, filter, filter_iter = self.filteringSetupTransitiveSearch() - for filt in filter, filter_iter: + ae, iiter = self.filteringSetupTransitiveSearch() + for filt in iiter(): ae(filt(None, {'messages.author.username': 'grouplead1'}, ('+','id')), []) ae(filt(None, {'messages.author': '6'}, @@ -2332,85 +2359,97 @@ def testFilteringTransitiveMultilinkSort(self): # Note that we don't test filter_iter here, Multilink sort-order # isn't defined for that. - ae, filt, dummy = self.filteringSetupTransitiveSearch() - ae(filt(None, {}, [('+','messages.author')]), - ['1', '2', '3', '4', '5', '8', '6', '7']) - ae(filt(None, {}, [('-','messages.author')]), - ['8', '6', '7', '5', '4', '3', '1', '2']) - ae(filt(None, {}, [('+','messages.date')]), - ['6', '7', '8', '5', '4', '3', '1', '2']) - ae(filt(None, {}, [('-','messages.date')]), - ['1', '2', '3', '4', '8', '5', '6', '7']) - ae(filt(None, {}, [('+','messages.author'),('+','messages.date')]), - ['1', '2', '3', '4', '5', '8', '6', '7']) - ae(filt(None, {}, [('-','messages.author'),('+','messages.date')]), - ['8', '6', '7', '5', '4', '3', '1', '2']) - ae(filt(None, {}, [('+','messages.author'),('-','messages.date')]), - ['1', '2', '3', '4', '5', '8', '6', '7']) - ae(filt(None, {}, [('-','messages.author'),('-','messages.date')]), - ['8', '6', '7', '5', '4', '3', '1', '2']) - ae(filt(None, {}, [('+','messages.author'),('+','assignedto')]), - ['1', '2', '3', '4', '5', '8', '6', '7']) - ae(filt(None, {}, [('+','messages.author'), - ('-','assignedto.supervisor'),('-','assignedto')]), - ['1', '2', '3', '4', '5', '8', '6', '7']) - ae(filt(None, {}, - [('+','messages.author.supervisor.supervisor.supervisor'), - ('+','messages.author.supervisor.supervisor'), - ('+','messages.author.supervisor'), ('+','messages.author')]), - ['1', '2', '3', '4', '5', '6', '7', '8']) + ae, iiter = self.filteringSetupTransitiveSearch() + for filt in iiter(): + if filt.__name__ != 'filter': + continue + ae(filt(None, {}, [('+','messages.author')]), + ['1', '2', '3', '4', '5', '8', '6', '7']) + ae(filt(None, {}, [('-','messages.author')]), + ['8', '6', '7', '5', '4', '3', '1', '2']) + ae(filt(None, {}, [('+','messages.date')]), + ['6', '7', '8', '5', '4', '3', '1', '2']) + ae(filt(None, {}, [('-','messages.date')]), + ['1', '2', '3', '4', '8', '5', '6', '7']) + ae(filt(None, {}, [('+','messages.author'),('+','messages.date')]), + ['1', '2', '3', '4', '5', '8', '6', '7']) + ae(filt(None, {}, [('-','messages.author'),('+','messages.date')]), + ['8', '6', '7', '5', '4', '3', '1', '2']) + ae(filt(None, {}, [('+','messages.author'),('-','messages.date')]), + ['1', '2', '3', '4', '5', '8', '6', '7']) + ae(filt(None, {}, [('-','messages.author'),('-','messages.date')]), + ['8', '6', '7', '5', '4', '3', '1', '2']) + ae(filt(None, {}, [('+','messages.author'),('+','assignedto')]), + ['1', '2', '3', '4', '5', '8', '6', '7']) + ae(filt(None, {}, [('+','messages.author'), + ('-','assignedto.supervisor'),('-','assignedto')]), + ['1', '2', '3', '4', '5', '8', '6', '7']) + ae(filt(None, {}, + [('+','messages.author.supervisor.supervisor.supervisor'), + ('+','messages.author.supervisor.supervisor'), + ('+','messages.author.supervisor'), ('+','messages.author')]), + ['1', '2', '3', '4', '5', '6', '7', '8']) self.db.user.setorderprop('age') self.db.msg.setorderprop('date') - ae(filt(None, {}, [('+','messages'), ('+','messages.author')]), - ['6', '7', '8', '5', '4', '3', '1', '2']) - ae(filt(None, {}, [('+','messages.author'), ('+','messages')]), - ['6', '7', '8', '5', '4', '3', '1', '2']) + for filt in iiter(): + if filt.__name__ != 'filter': + continue + ae(filt(None, {}, [('+','messages'), ('+','messages.author')]), + ['6', '7', '8', '5', '4', '3', '1', '2']) + ae(filt(None, {}, [('+','messages.author'), ('+','messages')]), + ['6', '7', '8', '5', '4', '3', '1', '2']) self.db.msg.setorderprop('author') - # Orderprop is a Link/Multilink: - # messages are sorted by orderprop().labelprop(), i.e. by - # author.username, *not* by author.orderprop() (author.age)! - ae(filt(None, {}, [('+','messages')]), - ['1', '2', '3', '4', '5', '8', '6', '7']) - ae(filt(None, {}, [('+','messages.author'), ('+','messages')]), - ['6', '7', '8', '5', '4', '3', '1', '2']) - # The following will sort by - # author.supervisor.username and then by - # author.username - # I've resited the tempation to implement recursive orderprop - # here: There could even be loops if several classes specify a - # Link or Multilink as the orderprop... - # msg: 4: worker1 (id 5) : grouplead1 (id 4) ceo (id 3) - # msg: 5: worker2 (id 7) : grouplead1 (id 4) ceo (id 3) - # msg: 6: worker3 (id 8) : grouplead2 (id 5) ceo (id 3) - # msg: 7: worker4 (id 9) : grouplead2 (id 5) ceo (id 3) - # msg: 8: worker5 (id 10) : grouplead2 (id 5) ceo (id 3) - # issue 1: messages 4 sortkey:[[grouplead1], [worker1], 1] - # issue 2: messages 4 sortkey:[[grouplead1], [worker1], 2] - # issue 3: messages 5 sortkey:[[grouplead1], [worker2], 3] - # issue 4: messages 6 sortkey:[[grouplead2], [worker3], 4] - # issue 5: messages 7 sortkey:[[grouplead2], [worker4], 5] - # issue 6: messages 8 sortkey:[[grouplead2], [worker5], 6] - # issue 7: messages 8 sortkey:[[grouplead2], [worker5], 7] - # issue 8: messages 7,8 sortkey:[[grouplead2, grouplead2], ...] + for filt in iiter(): + if filt.__name__ != 'filter': + continue + # Orderprop is a Link/Multilink: + # messages are sorted by orderprop().labelprop(), i.e. by + # author.username, *not* by author.orderprop() (author.age)! + ae(filt(None, {}, [('+','messages')]), + ['1', '2', '3', '4', '5', '8', '6', '7']) + ae(filt(None, {}, [('+','messages.author'), ('+','messages')]), + ['6', '7', '8', '5', '4', '3', '1', '2']) + # The following will sort by + # author.supervisor.username and then by + # author.username + # I've resited the tempation to implement recursive orderprop + # here: There could even be loops if several classes specify a + # Link or Multilink as the orderprop... + # msg: 4: worker1 (id 5) : grouplead1 (id 4) ceo (id 3) + # msg: 5: worker2 (id 7) : grouplead1 (id 4) ceo (id 3) + # msg: 6: worker3 (id 8) : grouplead2 (id 5) ceo (id 3) + # msg: 7: worker4 (id 9) : grouplead2 (id 5) ceo (id 3) + # msg: 8: worker5 (id 10) : grouplead2 (id 5) ceo (id 3) + # issue 1: messages 4 sortkey:[[grouplead1], [worker1], 1] + # issue 2: messages 4 sortkey:[[grouplead1], [worker1], 2] + # issue 3: messages 5 sortkey:[[grouplead1], [worker2], 3] + # issue 4: messages 6 sortkey:[[grouplead2], [worker3], 4] + # issue 5: messages 7 sortkey:[[grouplead2], [worker4], 5] + # issue 6: messages 8 sortkey:[[grouplead2], [worker5], 6] + # issue 7: messages 8 sortkey:[[grouplead2], [worker5], 7] + # issue 8: messages 7,8 sortkey:[[grouplead2, grouplead2], ...] self.db.user.setorderprop('supervisor') - ae(filt(None, {}, [('+','messages.author'), ('-','messages')]), - ['3', '1', '2', '6', '7', '5', '4', '8']) + for filt in iiter(): + if filt.__name__ != 'filter': + continue + ae(filt(None, {}, [('+','messages.author'), ('-','messages')]), + ['3', '1', '2', '6', '7', '5', '4', '8']) def testFilteringSortId(self): - ae, filter, filter_iter = self.filteringSetupTransitiveSearch('user') - for filt in filter, filter_iter: + ae, iiter = self.filteringSetupTransitiveSearch('user') + for filt in iiter(): ae(filt(None, {}, ('+','id')), ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']) def testFilteringRetiredString(self): - ae, filter, filter_iter = self.filteringSetup() + ae, iiter = self.filteringSetup() self.db.issue.retire('1') self.db.commit() r = { None: (['1'], ['1'], ['1'], ['1', '2', '3'], []) , True: (['1'], ['1'], ['1'], ['1'], []) , False: ([], [], [], ['2', '3'], []) } - for filt in filter, filter_iter: + for filt in iiter(): for retire in True, False, None: ae(filt(None, {'title': ['one']}, ('+','id'), retired=retire), r[retire][0]) @@ -2438,7 +2477,7 @@ def testImportExport(self): # use the filtering setup to create a bunch of items - ae, dummy1, dummy2 = self.filteringSetup() + ae, dummy = self.filteringSetup() # Get some stuff into the journal for testing import/export of # journal data: self.db.user.set('4', password = password.Password('xyzzy')) @@ -2551,7 +2590,7 @@ import roundup.admin import csv # use the filtering setup to create a bunch of items - ae, dummy1, dummy2 = self.filteringSetup() + ae, dummy = self.filteringSetup() # create large field self.db.priority.create(name = 'X' * 500) self.db.config.CSV_FIELD_SIZE = 400 @@ -2603,7 +2642,7 @@ import roundup.admin # use the filtering setup to create a bunch of items - ae, dummy1, dummy2 = self.filteringSetup() + ae, dummy = self.filteringSetup() # create large field self.db.priority.create(name = 'X' * 500) self.db.config.CSV_FIELD_SIZE = 400 @@ -3228,8 +3267,8 @@ class FilterCacheTest(commonDBTest): def testFilteringTransitiveLinkCache(self): - ae, filter, filter_iter = self.filteringSetupTransitiveSearch() - ae, ufilter, ufilter_iter = self.iterSetup('user') + ae, dummy = self.filteringSetupTransitiveSearch() + ae, dummy = self.iterSetup('user') # Need to make ceo his own (and first two users') supervisor self.db.user.set('1', supervisor = '3') self.db.user.set('2', supervisor = '3')
