""" Test importing ROAR scenarios into our database. """ import sys import os import json from asl_articles.models import Scenario from asl_articles.tests.utils import init_tests sys.path.append( os.path.join( os.path.split(__file__)[0], "../../tools/" ) ) from import_roar_scenarios import import_roar_scenarios #pylint: disable=import-error,wrong-import-order # --------------------------------------------------------------------- def test_import_roar_scenarios( dbconn ): """Test importing ROAR scenarios.""" # initialize session = init_tests( None, None, dbconn ) roar_fname = os.path.join( os.path.split(__file__)[0], "fixtures/roar-scenarios.json" ) with open( roar_fname, "r", encoding="utf-8" ) as fp: roar_data = json.load( fp ) # do the first import _do_import( dbconn, session, roar_fname, { "nInserts": 3, "nUpdates": 0, "nDupes": 0 }, [ [ "1", "1", "Fighting Withdrawal" ], [ "99", "FOO BAR", "test scenario" ], [ "129", "E", "Hill 621" ] ] ) # repeat the import (nothing should happen) _do_import( dbconn, session, roar_fname, { "nInserts": 0, "nUpdates": 0, "nDupes": 3 }, [ [ "1", "1", "Fighting Withdrawal" ], [ "99", "FOO BAR", "test scenario" ], [ "129", "E", "Hill 621" ] ] ) # simulate a scenario's details being updated in ROAR (we should update accordingly) roar_data["1"]["scenario_id"] += "u" roar_data["1"]["name"] += " (updated)" _do_import( dbconn, session, roar_data, { "nInserts": 0, "nUpdates": 1, "nDupes": 2 }, [ [ "1", "1u", "Fighting Withdrawal (updated)" ], [ "99", "FOO BAR", "test scenario" ], [ "129", "E", "Hill 621" ], ], [ "Data mismatch for ROAR ID 1:" ] ) # add a new ROAR scenario (we should import the new scenario) roar_data[ "42" ] = { "scenario_id": "NEW", "name": "new scenario" } _do_import( dbconn, session, roar_data, { "nInserts": 1, "nUpdates": 0, "nDupes": 3 }, [ [ "1", "1u", "Fighting Withdrawal (updated)" ], [ "99", "FOO BAR", "test scenario" ], [ "129", "E", "Hill 621" ], [ "42", "NEW", "new scenario" ] ] ) # delete all ROAR scenarios (nothing should happen) _do_import( dbconn, session, {}, { "nInserts": 0, "nUpdates": 0, "nDupes": 0 }, [ [ "1", "1u", "Fighting Withdrawal (updated)" ], [ "99", "FOO BAR", "test scenario" ], [ "129", "E", "Hill 621" ], [ "42", "NEW", "new scenario" ] ] ) # --------------------------------------------------------------------- def test_scenario_matching( dbconn ): """Test matching ROAR scenarios with scenarios in the database.""" # initialize session = init_tests( None, None, dbconn ) roar_fname = os.path.join( os.path.split(__file__)[0], "fixtures/roar-scenarios.json" ) # put a scenario in the database that has no ROAR ID session.add( Scenario( scenario_display_id="1", scenario_name="Fighting Withdrawal" ) ) session.commit() # do an import # NOTE: The scenario we created above will be matched to the corresponding ROAR scenario, # since the ROAR ID is not considered when matching scenarios. _do_import( dbconn, session, roar_fname, { "nInserts": 2, "nUpdates": 0, "nDupes": 1 }, [ [ None, "1", "Fighting Withdrawal" ], [ "99", "FOO BAR", "test scenario" ], [ "129", "E", "Hill 621" ] ] ) # put a scenario in the database that only has a name session.query( Scenario ).delete() session.add( Scenario( scenario_name="Hill 621" ) ) session.commit() # do an import # NOTE: The scenario we created above will be matched to the corresponding ROAR scenario, # and also updated with the scenario ID (as reported by ROAR). _do_import( dbconn, session, roar_fname, { "nInserts": 2, "nUpdates": 1, "nDupes": 0 }, [ [ "1", "1", "Fighting Withdrawal" ], [ "99", "FOO BAR", "test scenario" ], [ None, "E", "Hill 621" ] ], [ "Data mismatch for ROAR ID 129:" ] ) # --------------------------------------------------------------------- def _do_import( dbconn, session, roar_data, expected_stats, expected_scenarios, expected_warnings=None ): """Import the ROAR scenarios and check the results.""" # import the ROAR scenarios stats, warnings = import_roar_scenarios( dbconn.url, roar_data ) # check that the import went as expected assert stats == expected_stats if expected_warnings: assert warnings[0][0] == expected_warnings[0] else: assert not warnings # check the scenarios in the database rows = [ [ s.scenario_roar_id, s.scenario_display_id, s.scenario_name ] for s in session.query( Scenario ) #pylint: disable=not-an-iterable ] sort_rows = lambda rows: sorted( rows, key=lambda r: r[2] ) assert sort_rows( rows ) == sort_rows( expected_scenarios )