Skip to content

Commit c111f2d

Browse files
committed
REST etag ordering. Sort the items before performing the MD5 checksum. This puts the items in the same order every time. I was able to restart the roundup-server and get the same etag value on every restart after this patch. Also the etag calculated using python2 and python3 are now the same. I added a disabled test to try to validate that the etag is always the same value. However there is no way to set the creation and activity dates, so these fields are always different. This means the etag is always different. If I can convince the database back end to use a mocked date.Date.__init__ that returns the same date all the time I can finish the test.
1 parent 9136511 commit c111f2d

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

roundup/rest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def calculate_etag (node, classname="Missing", id="0"):
132132
'''
133133

134134
items = node.items(protected=True) # include every item
135-
etag = md5(bs2b(repr(items))).hexdigest()
135+
etag = md5(bs2b(repr(sorted(items)))).hexdigest()
136136
logger.debug("object=%s%s; tag=%s; repr=%s", classname, id,
137137
etag, repr(node.items(protected=True)))
138138
return etag
@@ -1336,7 +1336,7 @@ def summary(self, input):
13361336
summary.setdefault(status_name, []).append(issue_object)
13371337
messages.append((num, issue_object))
13381338

1339-
messages.sort(reverse=True)
1339+
sorted(messages, key=lambda tup: tup[0], reverse=True)
13401340

13411341
result = {
13421342
'created': created,

test/rest_common.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,32 @@ def testPagination(self):
341341
# page_size < 0
342342
# page_index < 0
343343

344+
def notestEtagGeneration(self):
345+
''' Make sure etag generation is stable
346+
347+
FIXME need to mock somehow date.Date() when creating
348+
the target to be mocked. The differening dates makes
349+
this test impossible.
350+
'''
351+
newuser = self.db.user.create(
352+
username='john',
353+
password=password.Password('random1'),
354+
address='[email protected]',
355+
realname='JohnRandom',
356+
roles='User,Admin'
357+
)
358+
359+
node = self.db.user.getnode(self.joeid)
360+
etag = calculate_etag(node)
361+
items = node.items(protected=True) # include every item
362+
print(repr(items))
363+
print(etag)
364+
self.assertEqual(etag, "6adf97f83acf6453d4a6a4b1070f3754")
365+
366+
etag = calculate_etag(self.db.issue.getnode("1"))
367+
print(etag)
368+
self.assertEqual(etag, "6adf97f83acf6453d4a6a4b1070f3754")
369+
344370
def testEtagProcessing(self):
345371
'''
346372
Etags can come from two places:

0 commit comments

Comments
 (0)