| # 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 datetime |
| import logging |
| import sys |
| import unittest |
| |
| from sqlalchemy import or_ |
| from sqlalchemy.orm import joinedload |
| |
| from lnt.server.config import Config |
| from lnt.server.db import v4db |
| from lnt.server.db.fieldchange import delete_fieldchange |
| from lnt.server.db.fieldchange import is_overlaping, identify_related_changes |
| from lnt.server.db.regression import rebuild_title, RegressionState |
| from lnt.server.db.rules import rule_update_fixed_regressions |
| |
| logging.basicConfig(level=logging.DEBUG) |
| |
| |
| def _mkorder(session, ts, rev): |
| order = ts.Order() |
| order.llvm_project_revision = rev |
| session.add(order) |
| return order |
| |
| |
| class ChangeProcessingTests(unittest.TestCase): |
| """Test fieldchange and regression building.""" |
| |
| def setUp(self): |
| """Bind to the LNT test instance.""" |
| |
| self.db = v4db.V4DB("sqlite:///:memory:", Config.dummy_instance()) |
| session = self.session = self.db.make_session() |
| |
| # Get the test suite wrapper. |
| ts_db = self.ts_db = self.db.testsuite['nts'] |
| |
| order1234 = self.order1234 = _mkorder(session, ts_db, "1234") |
| order1235 = self.order1235 = _mkorder(session, ts_db, "1235") |
| order1236 = self.order1236 = _mkorder(session, ts_db, "1236") |
| order1237 = self.order1237 = _mkorder(session, ts_db, "1237") |
| order1238 = self.order1238 = _mkorder(session, ts_db, "1238") |
| |
| start_time = end_time = datetime.datetime.utcnow() |
| machine = self.machine = ts_db.Machine("test-machine") |
| session.add(machine) |
| |
| test = self.test = ts_db.Test("foo") |
| session.add(test) |
| |
| machine2 = self.machine2 = ts_db.Machine("test-machine2") |
| session.add(machine2) |
| |
| test2 = self.test2 = ts_db.Test("bar") |
| session.add(test2) |
| |
| run = self.run = ts_db.Run(None, machine, order1235, start_time, |
| end_time) |
| session.add(run) |
| |
| run2 = self.run2 = ts_db.Run(None, machine2, order1235, start_time, |
| end_time) |
| session.add(run2) |
| |
| sample = ts_db.Sample(run, test, compile_time=1.0, |
| score=4.2) |
| session.add(sample) |
| |
| a_field = self.a_field = list(sample.get_primary_fields())[0] |
| self.a_field2 = list(sample.get_primary_fields())[1] |
| |
| field_change = self.field_change = ts_db.FieldChange(order1234, |
| order1236, |
| machine, |
| test, |
| a_field.id) |
| field_change.run = run |
| session.add(field_change) |
| |
| fc_mach2 = ts_db.FieldChange(order1234, |
| order1236, |
| machine2, |
| test, |
| a_field.id) |
| fc_mach2.run = run2 |
| session.add(fc_mach2) |
| |
| field_change2 = self.field_change2 = ts_db.FieldChange(order1235, order1236, machine, |
| test, |
| a_field.id) |
| |
| field_change2.run = run |
| session.add(field_change2) |
| |
| field_change3 = self.field_change3 = ts_db.FieldChange(order1237, order1238, machine, |
| test, |
| a_field.id) |
| session.add(field_change3) |
| |
| regression = self.regression = ts_db.Regression("Regression of 1 benchmarks:", "PR1234", |
| RegressionState.DETECTED) |
| session.add(self.regression) |
| |
| self.regression_indicator1 = ts_db.RegressionIndicator(regression, |
| field_change) |
| self.regression_indicator2 = ts_db.RegressionIndicator(regression, |
| field_change2) |
| |
| session.add(self.regression_indicator1) |
| session.add(self.regression_indicator2) |
| |
| # All the regressions we detected. |
| self.regressions = [regression] |
| session.commit() |
| |
| def tearDown(self): |
| self.db.close() |
| |
| def test_startup(self): |
| pass |
| |
| def test_change_grouping_criteria(self): |
| session = self.session |
| ts_db = self.ts_db |
| |
| # Check simple overlap checks work. |
| self.assertTrue(is_overlaping(self.field_change, self.field_change2), |
| "Should be overlapping") |
| self.assertFalse(is_overlaping(self.field_change, self.field_change3), |
| "Should not be overlapping") |
| |
| active_indicators = session.query(ts_db.FieldChange) \ |
| .join(ts_db.RegressionIndicator) \ |
| .join(ts_db.Regression) \ |
| .filter(or_(ts_db.Regression.state == RegressionState.DETECTED, |
| ts_db.Regression.state == RegressionState.DETECTED_FIXED)) \ |
| .options(joinedload(ts_db.FieldChange.start_order), |
| joinedload(ts_db.FieldChange.end_order), |
| joinedload(ts_db.FieldChange.test), |
| joinedload(ts_db.FieldChange.machine)) \ |
| .all() |
| |
| # Check non-overlapping changes are always False. |
| ret, reg = identify_related_changes(session, ts_db, self.field_change3, active_indicators) |
| |
| self.assertFalse(ret, "Ranges don't overlap, should not match") |
| self.regressions.append(reg) |
| # Check a regression matches if all fields match. |
| ret, _ = identify_related_changes(session, ts_db, self.field_change, active_indicators) |
| self.assertTrue(ret, "Should Match.") |
| |
| field_change7 = ts_db.FieldChange(self.order1234, |
| self.order1235, |
| self.machine2, |
| self.test2, |
| self.a_field.id) |
| session.add(field_change7) |
| |
| active_indicators = session.query(ts_db.FieldChange) \ |
| .join(ts_db.RegressionIndicator) \ |
| .join(ts_db.Regression) \ |
| .filter(or_(ts_db.Regression.state == RegressionState.DETECTED, |
| ts_db.Regression.state == RegressionState.DETECTED_FIXED)) \ |
| .options(joinedload(ts_db.FieldChange.start_order), |
| joinedload(ts_db.FieldChange.end_order), |
| joinedload(ts_db.FieldChange.test), |
| joinedload(ts_db.FieldChange.machine)) \ |
| .all() |
| |
| ret, reg = identify_related_changes(session, ts_db, field_change7, active_indicators) |
| self.assertNotEqual(self.regression, reg) |
| self.assertFalse(ret, "No match with different machine and tests.") |
| self.regressions.append(reg) |
| field_change4 = ts_db.FieldChange(self.order1234, |
| self.order1235, |
| self.machine2, |
| self.test, |
| self.a_field.id) |
| |
| # Check a regression matches if all fields match. |
| ret, _ = identify_related_changes(session, ts_db, field_change4, active_indicators) |
| self.assertTrue(ret, "Should Match with different machine.") |
| |
| field_change5 = ts_db.FieldChange(self.order1234, |
| self.order1235, |
| self.machine, |
| self.test2, |
| self.a_field.id) |
| |
| # Check a regression matches if all fields match. |
| ret, _ = identify_related_changes(session, ts_db, field_change5, active_indicators) |
| self.assertTrue(ret, "Should Match with different tests.") |
| field_change6 = ts_db.FieldChange(self.order1234, |
| self.order1235, |
| self.machine, |
| self.test, |
| self.a_field2.id) |
| |
| # Check a regression matches if all fields match. |
| ret, _ = identify_related_changes(session, ts_db, field_change6, active_indicators) |
| self.assertTrue(ret, "Should Match with different fields.") |
| |
| session.commit() |
| |
| r2 = rebuild_title(session, ts_db, self.regression) |
| # The list of benchmark regressing is guaranteed to be sorted. |
| expected_title = "Regression of 6 benchmarks: bar, foo" |
| self.assertEqual(r2.title, expected_title) |
| |
| def test_regression_evolution(self): |
| session = self.session |
| ts_db = self.ts_db |
| rule_update_fixed_regressions.regression_evolution( |
| session, ts_db, self.run.id) |
| |
| def test_fc_deletion(self): |
| session = self.session |
| ts_db = self.ts_db |
| delete_fieldchange(session, ts_db, self.field_change) |
| delete_fieldchange(session, ts_db, self.field_change2) |
| delete_fieldchange(session, ts_db, self.field_change3) |
| |
| def test_run_deletion(self): |
| """Do the FC and RIs get cleaned up when runs are deleted?""" |
| session = self.session |
| ts_db = self.ts_db |
| run_idsq = session.query(ts_db.Run.id).all() |
| fc_ids = session.query(ts_db.FieldChange.id).all() |
| ri_ids = session.query(ts_db.RegressionIndicator.id).all() |
| |
| run_ids = [row[0] for row in run_idsq] |
| runs = session.query(ts_db.Run).filter(ts_db.Run.id.in_(run_ids)).all() |
| for run in runs: |
| session.delete(run) |
| |
| run_ids_new = session.query(ts_db.Run.id).all() |
| fc_ids_new = session.query(ts_db.FieldChange.id).all() |
| ri_ids_new = session.query(ts_db.RegressionIndicator.id).all() |
| # Make sure there was some runs. |
| self.assertNotEqual(len(run_idsq), 0) |
| self.assertNotEqual(len(fc_ids), 0) |
| self.assertNotEqual(len(ri_ids), 0) |
| |
| # Now make sure there were all deleted. |
| self.assertEqual(len(run_ids_new), 0) |
| |
| # Not all the FCs are covered by the runs. |
| self.assertEqual(len(fc_ids_new), 1) |
| |
| self.assertEqual(len(ri_ids_new), 0) |
| |
| |
| if __name__ == '__main__': |
| unittest.main(argv=[sys.argv[0], ]) |