blob: 0ea655f196f5d7a575bc7ead5ffb09c97bc4480a [file] [log] [blame] [edit]
# Check that the LNT REST JSON API is working.
# create temporary instance
# RUN: rm -rf %t.instance
# RUN: python %{shared_inputs}/create_temp_instance.py \
# RUN: %s %{shared_inputs}/SmallInstance \
# RUN: %t.instance %S/Inputs/V4Pages_extra_records.sql
#
# RUN: python %s %t.instance
import json
import logging
import sys
import unittest
import lnt.server.db.migrate
import lnt.server.ui.app
import copy
from V4Pages import check_json
logging.basicConfig(level=logging.DEBUG)
def check_code_post(client, url, expected_code=200, data_to_send=None):
resp = client.post(url, follow_redirects=False, data=data_to_send)
assert resp.status_code == expected_code, \
"Post to %s returned: %d, not the expected %d" % (url, resp.status_code,
expected_code)
return resp
class JSONAPIRoundTripTester(unittest.TestCase):
"""Test that LNT can accept its own data.
We want LNT to be able to accept new runs taken from the LNT
API itself. This allows you to do offline data processing and
move runs between instances. This test pulls data out of the api
for a round trip, to make sure it can be inserted again, and
produce a same looking run. Database IDs etc can be different,
but all the meaningful run fields should be the same.
"""
def setUp(self):
"""Bind to the LNT test instance."""
_, instance_path = sys.argv
app = lnt.server.ui.app.App.create_standalone(instance_path)
app.testing = True
self.client = app.test_client()
def test_run_round_trip(self):
"""Output of /runs/n can be fed back to /submitRun
"""
client = self.client
orig_api_run = check_json(client, 'api/db_default/v4/nts/runs/1')
# Do some slight modification to avoid LNT rejecting the new submission
# as a duplicate.
orig_api_run['run']['llvm_project_revision'] = u'154333'
self.assertEqual(orig_api_run['run']['id'], 1)
# Machine and run id should be ignored on submission so we should be
# able to set them to anything without anyone complaining.
self.assertEqual(orig_api_run['machine']['id'], 1)
modified_run = copy.deepcopy(orig_api_run)
modified_run['run']['llvm_project_revision'] = u'666'
new_api_run, result_url = self._resubmit(modified_run)
self.assertEqual(result_url, 'http://localhost/db_default/v4/nts/10')
self.assertEqual(new_api_run['run']['id'], 10)
self.assertEqual(new_api_run['run']['llvm_project_revision'], u'666')
new_api_run['run']['llvm_project_revision'] = orig_api_run['run']['llvm_project_revision']
# We change run id and machine id back to the original and after that
# we should have a perfect match.
self._compare_results(new_api_run, orig_api_run)
def _compare_results(self, after_submit_run, before_submit_run):
"""Take the results from server submission and compare them.
We expect the IDs to change between submissions, so set the IDs to known
values. Check all the top level keys, then check the run and machine dicts
match and the tests data is the same.
"""
an_id = 1234567
before_submit_run['run']['id'] = an_id
before_submit_run['machine']['id'] = an_id
after_submit_run['run']['id'] = an_id
after_submit_run['machine']['id'] = an_id
before_submit_run['run']['order_id'] = an_id
after_submit_run['run']['order_id'] = an_id
self.assertEqual(list(before_submit_run.keys()), list(after_submit_run.keys()))
# Machine and run will be dicts, compare them directly.
for k in ['machine', 'run']:
self.assertEqual(before_submit_run[k], after_submit_run[k])
# The order of the tests might have changed, so sort before they are compared.
before_submit_tests = sorted(before_submit_run['tests'],
key=lambda test: test['id'])
after_submit_tests = sorted(after_submit_run['tests'],
key=lambda test: test['id'])
for i, _ in enumerate(before_submit_tests):
before_submit_tests[i]['run_id'] = 1234
after_submit_tests[i]['run_id'] = 1234
before_submit_tests[i]['id'] = 1234
after_submit_tests[i]['id'] = 1234
self.assertEqual(before_submit_tests[i], after_submit_tests[i])
def _resubmit(self, run_results):
"""Send the results to the server.
Convert the results to json, post them to the server's submitRun
"""
# Submit the data
data_to_send = {
'commit': '1',
'input_data': json.dumps(run_results)
}
response = check_code_post(self.client, 'db_default/v4/nts/submitRun',
data_to_send=data_to_send)
submit_result = json.loads(response.data)
result_url = submit_result.get('result_url')
run_id = result_url.split("/")[-1]
new_api_run = check_json(self.client, 'api/db_default/v4/nts/runs/{}'.format(run_id))
return new_api_run, result_url
if __name__ == '__main__':
unittest.main(argv=[sys.argv[0], ])