Order get_tests_run_dicts_from_run_id response by date

Previously the output from sql2subunit had an arbitrary order of tests
returned. (when not run with --average) While technically not an issue
for the protocol, some programs which analyze the subunit stream (like
subunit-trace) assume tests were added to the stream in chronological
order. To address this issue this commit adds an order_by() call to
the DB query that gets the values to generate the dicts in the
response list. Then to ensure the insertion order is remembered when
the dict is iterated over in sql2subunit later it is switched to an
OrderedDict, which since it's a subclass of dict should retain
backwards compat for any existing code out there. The backwards compat
concern is why the response isn't changed to a list, which would be
the normal way to ensure a series of dicts were treated in order.

Change-Id: Idc21f968f210908f061e663b1d40ddaf7b37204c
This commit is contained in:
Matthew Treinish 2015-08-15 15:48:31 -04:00
parent a2c496f775
commit b6e1c826d3
No known key found for this signature in database
GPG Key ID: FD12A0F214C9E177
2 changed files with 34 additions and 9 deletions

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import collections
import datetime
from oslo_config import cfg
@ -680,16 +681,18 @@ def get_tests_run_dicts_from_run_id(run_id, session=None):
session = session or get_session()
query = db_utils.model_query(models.Test, session=session).join(
models.TestRun).filter(models.TestRun.run_id == run_id).outerjoin(
models.TestRunMetadata).values(
models.Test.test_id,
models.TestRun.status,
models.TestRunMetadata).order_by(
models.TestRun.start_time,
models.TestRun.start_time_microsecond,
models.TestRun.stop_time,
models.TestRun.stop_time_microsecond,
models.TestRunMetadata.key,
models.TestRunMetadata.value)
test_runs = {}
models.TestRun.start_time_microsecond).values(
models.Test.test_id,
models.TestRun.status,
models.TestRun.start_time,
models.TestRun.start_time_microsecond,
models.TestRun.stop_time,
models.TestRun.stop_time_microsecond,
models.TestRunMetadata.key,
models.TestRunMetadata.value)
test_runs = collections.OrderedDict()
for test_run in query:
if test_run[0] not in test_runs:
# If there is no start_time set to None

View File

@ -145,3 +145,25 @@ class TestDatabaseAPI(base.TestCase):
all_test_runs = api.get_all_test_runs()
self.assertEqual(len(all_test_runs), 1)
self.assertEqual(test_run.id, all_test_runs[0].id)
def test_get_test_runs_dicts_from_run_id_are_in_chrono_order(self):
run = api.create_run()
test_a = api.create_test('fake_test')
test_b = api.create_test('fake_test_2')
test_c = api.create_test('fake_test_3')
api.create_test_run(test_a.id, run.id, 'success',
datetime.datetime.utcnow())
api.create_test_run(test_b.id, run.id, 'success',
datetime.datetime(1914, 6, 28, 10, 45, 0))
api.create_test_run(test_c.id, run.id, 'success',
datetime.datetime(2014, 8, 26, 20, 00, 00))
test_run_dicts = api.get_tests_run_dicts_from_run_id(run.id)
self.assertEqual(len(test_run_dicts), 3)
prev = None
for test_run in test_run_dicts:
if prev == None:
prev = test_run
continue
self.assertTrue(test_run_dicts[test_run]['start_time'] >
test_run_dicts[prev]['start_time'])
prev = test_run