| # 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 %{shared_inputs} |
| |
| import json |
| import logging |
| import sys |
| import unittest |
| |
| import lnt.server.db.migrate |
| import lnt.server.ui.app |
| from V4Pages import check_json |
| |
| logging.basicConfig(level=logging.INFO) |
| |
| |
| class _hashabledict(dict): |
| """See https://stackoverflow.com/questions/1151658.""" |
| def __hash__(self): |
| return hash(tuple(sorted(self.items()))) |
| |
| |
| class JSONAPIDeleteTester(unittest.TestCase): |
| """Test the REST api.""" |
| |
| def setUp(self): |
| """Bind to the LNT test instance.""" |
| _, instance_path, shared_inputs = sys.argv |
| app = lnt.server.ui.app.App.create_standalone(instance_path) |
| app.testing = True |
| self.client = app.test_client() |
| self.shared_inputs = shared_inputs |
| |
| def test_00_update_machine(self): |
| """Check PUT request to /machines/n""" |
| client = self.client |
| |
| # We are going to set the 'os' field to none, remove the 'uname' |
| # parameter and add the 'new_parameter' parameter. |
| # Make sure none of those things happened yet: |
| machine_before = check_json(client, 'api/db_default/v4/nts/machines/1') |
| machine_before = machine_before['machine'] |
| self.assertIsNotNone(machine_before.get('os', None)) |
| self.assertIsNone(machine_before.get('new_parameter', None)) |
| self.assertIsNotNone(machine_before.get('uname', None)) |
| |
| data = { |
| 'machine': { |
| 'hardware': 'hal 9000', |
| 'os': None, |
| 'hostname': 'localhost', |
| 'new_parameter': True, |
| }, |
| } |
| json_data = json.dumps(data) |
| resp = client.put('api/db_default/v4/nts/machines/1', data=json_data, |
| headers={'AuthToken': 'test_token'}) |
| self.assertEqual(resp.status_code, 200) |
| |
| machine_after = check_json(client, 'api/db_default/v4/nts/machines/1') |
| machine_after = machine_after['machine'] |
| for key in ('hardware', 'os', 'hostname', 'new_parameter', 'uname'): |
| self.assertEqual(machine_after.get(key, None), |
| data['machine'].get(key, None)) |
| |
| def test_00_rename_machine(self): |
| """Check rename POST request to /machines/n""" |
| client = self.client |
| |
| # Make sure the environment is as expected. |
| j = check_json(client, 'api/db_default/v4/nts/machines/1') |
| self.assertEqual(j['machine']['name'], 'localhost__clang_DEV__x86_64') |
| |
| data = { |
| 'action': 'rename', |
| 'name': 'new_machine_name', |
| } |
| resp = client.post('api/db_default/v4/nts/machines/1', data=data) |
| self.assertEqual(resp.status_code, 401) |
| |
| resp = client.post('api/db_default/v4/nts/machines/1', data=data, |
| headers={'AuthToken': 'wrong token'}) |
| self.assertEqual(resp.status_code, 401) |
| |
| resp = client.post('api/db_default/v4/nts/machines/1', data=data, |
| headers={'AuthToken': 'test_token'}) |
| self.assertEqual(resp.status_code, 200) |
| |
| # Machine should be renamed now. |
| j = check_json(client, 'api/db_default/v4/nts/machines/1') |
| self.assertEqual(j['machine']['name'], 'new_machine_name') |
| |
| def test_01_delete_run(self): |
| """Check /runs/n can be deleted.""" |
| client = self.client |
| |
| j = check_json(client, 'api/db_default/v4/nts/runs/1') |
| sample_ids = [s['id'] for s in j['tests']] |
| self.assertNotEqual(len(sample_ids), 0) |
| for sid in sample_ids: |
| resp = client.get('api/db_default/v4/nts/samples/{}'.format(sid)) |
| self.assertEqual(resp.status_code, 200) |
| |
| resp = client.delete('api/db_default/v4/nts/runs/1') |
| self.assertEqual(resp.status_code, 401) |
| |
| resp = client.delete('api/db_default/v4/nts/runs/1', |
| headers={'AuthToken': 'wrong token'}) |
| self.assertEqual(resp.status_code, 401) |
| |
| resp = client.delete('api/db_default/v4/nts/runs/1', |
| headers={'AuthToken': 'test_token'}) |
| self.assertEqual(resp.status_code, 200) |
| |
| resp = client.get('api/db_default/v4/nts/runs/1') |
| self.assertEqual(resp.status_code, 404) |
| |
| for sid in sample_ids: |
| resp = client.get('api/db_default/v4/nts/samples/{}'.format(sid)) |
| self.assertEqual(resp.status_code, 404) |
| |
| def test_02_delete_machine(self): |
| """Check /machines/n can be deleted.""" |
| client = self.client |
| |
| j = check_json(client, 'api/db_default/v4/nts/machines/2') |
| run_ids = [s['id'] for s in j['runs']] |
| self.assertNotEqual(len(run_ids), 0) |
| sample_ids = [] |
| for run_id in run_ids: |
| resp = check_json(client, |
| 'api/db_default/v4/nts/runs/{}'.format(run_id)) |
| sample_ids.append([s['id'] for s in resp['tests']]) |
| self.assertNotEqual(len(sample_ids), 0) |
| |
| resp = client.delete('api/db_default/v4/nts/machines/2') |
| self.assertEqual(resp.status_code, 401) |
| |
| resp = client.delete('api/db_default/v4/nts/machines/2', |
| headers={'AuthToken': 'wrong token'}) |
| self.assertEqual(resp.status_code, 401) |
| |
| resp = client.delete('api/db_default/v4/nts/machines/2', |
| headers={'AuthToken': 'test_token'}) |
| self.assertEqual(resp.status_code, 200) |
| self.assertEqual(resp.get_data(as_text=True), |
| '''Deleting runs 3 5 6 7 8 9 (6/6) |
| Deleted machine machine2:2 |
| ''') |
| |
| resp = client.get('api/db_default/v4/nts/machines/2') |
| self.assertEqual(resp.status_code, 404) |
| |
| for run_id in run_ids: |
| resp = client.get('api/db_default/v4/nts/runs/{}'.format(run_id)) |
| self.assertEqual(resp.status_code, 404) |
| |
| for sid in sample_ids: |
| resp = client.get('api/db_default/v4/nts/samples/{}'.format(sid)) |
| self.assertEqual(resp.status_code, 404) |
| |
| def test_03_post_run(self): |
| """Check POST to /runs.""" |
| client = self.client |
| |
| resp = client.get('api/db_default/v4/nts/runs/5') |
| self.assertEqual(resp.status_code, 404) |
| |
| data = open('%s/sample-report.json' % self.shared_inputs).read() |
| |
| resp = client.post('api/db_default/v4/nts/runs', data=data) |
| self.assertEqual(resp.status_code, 401) |
| |
| resp = client.post('api/db_default/v4/nts/runs', data=data, |
| headers={'AuthToken': 'test_token'}) |
| self.assertEqual(resp.status_code, 301) |
| self.assertIn('http://localhost/api/db_default/v4/nts/runs/', resp.headers['Location']) |
| resp_json = json.loads(resp.data) |
| self.assertEqual(resp_json['run_id'], 5) |
| |
| # Provoke a failing submission. |
| resp = client.post('api/db_default/v4/nts/runs?merge=reject', |
| data=data, |
| headers={'AuthToken': 'test_token'}) |
| self.assertEqual(resp.status_code, 400) |
| resp_json = json.loads(resp.data) |
| self.assertEqual(resp_json['error'], |
| "import failure: Duplicate submission for '1'") |
| self.assertEqual(resp_json['success'], False) |
| |
| def test_04_merge_into(self): |
| """Check POST/merge into request for /machines.""" |
| client = self.client |
| |
| # Download existing machines. |
| machine_1 = check_json(client, 'api/db_default/v4/nts/machines/1') |
| machine_3 = check_json(client, 'api/db_default/v4/nts/machines/3') |
| # The test is boring if we don't have at least 1 run in each machine. |
| self.assertTrue(len(machine_1['runs']) > 0) |
| self.assertTrue(len(machine_3['runs']) > 0) |
| |
| data = { |
| 'action': 'merge', |
| 'into': '3', |
| } |
| resp = client.post('api/db_default/v4/nts/machines/1', data=data, |
| headers={'AuthToken': 'test_token'}) |
| self.assertEqual(resp.status_code, 200) |
| |
| # Old machine should have disappeared. |
| resp_2 = client.get('api/db_default/v4/nts/machines/1') |
| self.assertEqual(resp_2.status_code, 404) |
| |
| # The other machine should have the union of all runs. |
| machine_1['runs'] = [_hashabledict(run) for run in machine_1['runs']] |
| machine_3['runs'] = [_hashabledict(run) for run in machine_3['runs']] |
| allruns = set(machine_1['runs']).union(machine_3['runs']) |
| resp_3 = check_json(client, 'api/db_default/v4/nts/machines/3') |
| resp_3['runs'] = [_hashabledict(run) for run in resp_3['runs']] |
| self.assertEqual(set(resp_3['runs']), allruns) |
| |
| |
| if __name__ == '__main__': |
| unittest.main(argv=[sys.argv[0], ]) |