@@ -180,7 +180,11 @@ class ServerClient(bb.asyncrpc.AsyncServerConnection):
'get-stats': self.handle_get_stats,
})
- if not read_only:
+ if read_only:
+ self.handlers.update({
+ 'report': self.handle_readonly_report,
+ })
+ else:
self.handlers.update({
'report': self.handle_report,
'report-equiv': self.handle_equivreport,
@@ -453,6 +457,45 @@ class ServerClient(bb.asyncrpc.AsyncServerConnection):
self.write_message(d)
+
+ async def handle_readonly_report(self, data):
+ with closing(self.db.cursor()) as cursor:
+
+ # Check if outhash is known
+ cursor.execute(
+ '''
+ SELECT outhashes_v2.taskhash AS taskhash, unihashes_v2.unihash AS unihash FROM outhashes_v2
+ INNER JOIN unihashes_v2 ON unihashes_v2.method=outhashes_v2.method AND unihashes_v2.taskhash=outhashes_v2.taskhash
+ -- Select any matching output hash
+ WHERE outhashes_v2.method=:method AND outhashes_v2.outhash=:outhash
+ -- Pick the oldest hash
+ ORDER BY outhashes_v2.created ASC
+ LIMIT 1
+ ''',
+ {
+ 'method': data['method'],
+ 'outhash': data['outhash'],
+ 'taskhash': data['taskhash'],
+ }
+ )
+ row = cursor.fetchone()
+ if row is not None:
+ # outhash is known => corrects unihash
+ unihash = row['unihash']
+ else:
+ # outhash is unknown => nothing to do
+ unihash = data['taskhash']
+
+
+ d = {
+ 'taskhash': data['taskhash'],
+ 'method': data['method'],
+ 'unihash': unihash,
+ }
+
+ self.write_message(d)
+
+
async def handle_equivreport(self, data):
with closing(self.db.cursor()) as cursor:
insert_data = {
@@ -312,13 +312,12 @@ class HashEquivalenceCommonTests(object):
# Check the hash via the read-only server
self.assertClientGetHash(ro_client, taskhash, unihash)
- # Ensure that reporting via the read-only server fails
+ # Ensure that reporting via the read-only server doesn't modify the database
taskhash2 = 'c665584ee6817aa99edfc77a44dd853828279370'
outhash2 = '3c979c3db45c569f51ab7626a4651074be3a9d11a84b1db076f5b14f7d39db44'
unihash2 = '90e9bc1d1f094c51824adca7f8ea79a048d68824'
- with self.assertRaises(ConnectionError):
- ro_client.report_unihash(taskhash2, self.METHOD, outhash2, unihash2)
+ ro_client.report_unihash(taskhash2, self.METHOD, outhash2, unihash2)
# Ensure that the database was not modified
self.assertClientGetHash(self.client, taskhash2, None)
TCP read-only hash equivalence server is not working: the connection is prematurely closed without even notifying the value of the unihash. Expected behaviour is: 1. the client sends a ‘report’ message indicating the 'taskhash', 'method', 'outhash' and a proposed value of 'unihash'. 2.the server sends back the 'taskhash', 'method' and actual value of 'unihash' to use. The problem is that in read-only mode, the server rejects 'report' messages (connexion is closed). hashserv.tests.TestHashEquivalenceUnixServer.test_ro_server test modified accordingly Signed-off-by: Karim Ben Houcine <karim.benhoucine@landisgyr.com> --- lib/hashserv/server.py | 45 +++++++++++++++++++++++++++++++++++++++++- lib/hashserv/tests.py | 5 ++--- 2 files changed, 46 insertions(+), 4 deletions(-)