Skip to content

Commit

Permalink
Added ReBenchDB API version detection
Browse files Browse the repository at this point in the history
ReBenchDB will send a header on an OPTIONS request advertising that version 2.0.0 of the API is supported.

Signed-off-by: Stefan Marr <[email protected]>
  • Loading branch information
smarr committed Feb 18, 2024
1 parent 89a6b91 commit 636aee9
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 4 deletions.
5 changes: 4 additions & 1 deletion rebench/persistence.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,10 @@ def convert_data_to_api_20_format(self, data):

def _send_data(self, cache):
self.ui.debug_output_info("ReBenchDB: Prepare data for sending\n")
all_data, criteria_index, num_measurements = self.convert_data_to_api_format(cache)
if self._rebench_db.is_api_v2():
all_data, criteria_index, num_measurements = self.convert_data_to_api_20_format(cache)
else:
all_data, criteria_index, num_measurements = self.convert_data_to_api_format(cache)

self.ui.debug_output_info(
"ReBenchDB: Sending {num_m} measures. startTime: {st}\n",
Expand Down
25 changes: 23 additions & 2 deletions rebench/rebenchdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from time import sleep

from http.client import HTTPException
from urllib.request import urlopen, Request as PutRequest
from urllib.request import urlopen, Request as HttpRequest

from .ui import UIError

Expand Down Expand Up @@ -33,6 +33,20 @@ def __init__(self, server_base_url, project_name, experiment_name, ui):
self._server_base_url = server_base_url
self._project_name = project_name
self._experiment_name = experiment_name
self._api_v2 = None

def is_api_v2(self):
if self._api_v2 is None:
api_version = self._get_api_version()
if api_version:
major = api_version.split('.')[0]
if int(major) == 2:
self._api_v2 = True

if self._api_v2 is None:
self._api_v2 = False

return self._api_v2

def send_results(self, benchmark_data, num_items):
success, response = self._send_to_rebench_db(benchmark_data, '/results')
Expand Down Expand Up @@ -60,12 +74,19 @@ def send_completion(self, end_time):

@staticmethod
def _send_payload(payload, url):
req = PutRequest(url, payload,
req = HttpRequest(url, payload,
{'Content-Type': 'application/json'}, method='PUT')
with urlopen(req) as socket:
response = socket.read()
return response

def _get_api_version(self):
url = self._server_base_url + '/results'
req = HttpRequest(url, method='OPTIONS')
with urlopen(req) as socket:
response = socket.read()
return socket.getheader('X-ReBenchDB-Result-API-Version')

def convert_data_to_json(self, data):
return json.dumps(data, separators=(',', ':'), ensure_ascii=True)

Expand Down
20 changes: 19 additions & 1 deletion rebench/tests/mock_http_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,23 @@ def do_GET(self):
self.send_response(200)
self.end_headers()
self.send_header("Content-Length", 0)
self.server.get_requests += 1

def do_PUT(self):
self.send_response(200)
self.send_header("Content-Length", 0)
self.end_headers()
self.server.put_requests += 1

def do_OPTIONS(self):
self.send_response(200)
if self.server.api_v2:
self.send_header("X-ReBenchDB-Result-API-Version", "2.0.0")
self.send_header("Allow", "PUT")
self.send_header("Content-Length", 0)
self.end_headers()
self.server.options_requests += 1

def log_request(self, code='-', size='-'):
pass

Expand All @@ -25,15 +35,22 @@ class HTTPServerWithCounter(HTTPServer):
def __init__(self, *args, **kwargs):
super(HTTPServerWithCounter, self).__init__(*args, **kwargs)
self.put_requests = 0
self.get_requests = 0
self.options_requests = 0
self.api_v2 = None

def set_api_v2(self, value):
self.api_v2 = value


class MockHTTPServer(object):

def __init__(self):
def __init__(self, api_v2 = True):
self._port = -1
self._server = None
self._thread = None
self._is_shutdown = False
self.api_v2 = api_v2

def get_free_port(self):
s = socket.socket(socket.AF_INET, type=socket.SOCK_STREAM)
Expand All @@ -46,6 +63,7 @@ def get_free_port(self):

def start(self):
self._server = HTTPServerWithCounter(('localhost', self._port), _RequestHandler)
self._server.set_api_v2(self.api_v2)

self._thread = Thread(target=self._server.serve_forever)
self._thread.daemon = True
Expand Down
27 changes: 27 additions & 0 deletions rebench/tests/rebenchdb_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from .mock_http_server import MockHTTPServer
from .rebench_test_case import ReBenchTestCase
from ..rebenchdb import ReBenchDB


class ReBenchDBTest(ReBenchTestCase):
def test_is_api_v2(self):
server = MockHTTPServer()
try:
port = server.get_free_port()
server.start()

db = ReBenchDB('http://localhost:' + str(port), 'project', 'experiment', self.ui)
self.assertTrue(db.is_api_v2())
finally:
server.process_and_shutdown()

def test_is_api_v2_on_server_without_v2_support(self):
server = MockHTTPServer(False)
try:
port = server.get_free_port()
server.start()

db = ReBenchDB('http://localhost:' + str(port), 'project', 'experiment', self.ui)
self.assertFalse(db.is_api_v2())
finally:
server.process_and_shutdown()

0 comments on commit 636aee9

Please sign in to comment.