def test_json_back_and_forth(self) -> None: """ test converting back and forth from and to json """ # GIVEN input_dict = TestCoordinationInputValidation.get_default_inputs() # WHEN offset = Offset(**input_dict) # THEN converting back and forth should in the end give the same result offset_dict = offset.to_json() offset_from_json = Offset.from_json(offset_dict=offset_dict) self.assertDictEqual(offset_dict, offset_from_json.to_json())
def test_incorrect_offset(self) -> None: """ Test that validation of incorrect offset raises SafetyViolation. :return: """ # GIVEN offset = Offset(from_id="sg3", to_id="sg4", seconds=20) fts_org = FixedTimeSchedule(greenyellow_intervals=dict( sg1=[GreenYellowInterval(start_greenyellow=15, end_greenyellow=35)], sg2=[GreenYellowInterval(start_greenyellow=45, end_greenyellow=65)], sg3=[GreenYellowInterval(start_greenyellow=10, end_greenyellow=40), GreenYellowInterval(start_greenyellow=50, end_greenyellow=70)], sg4=[GreenYellowInterval(start_greenyellow=30, end_greenyellow=40), GreenYellowInterval(start_greenyellow=69, end_greenyellow=90)]), period=100) signalgroup3 = TestFTSOtherSGRelationValidation.get_default_signalgroup(name="sg3") signalgroup4 = TestFTSOtherSGRelationValidation.get_default_signalgroup(name="sg4") intersection = TestFTSOtherSGRelationValidation.get_default_intersection( additional_signalgroups=[signalgroup3, signalgroup4], offsets=[offset]) for interval_shift in range(2): with self.subTest(f"interval_shift={interval_shift}"): fts = deepcopy(fts_org) fts._greenyellow_intervals["sg4"] = fts._greenyellow_intervals["sg4"][:interval_shift] + \ fts._greenyellow_intervals["sg4"][interval_shift:] with self.assertRaises(SafetyViolation): # WHEN validating validate_other_sg_relations(intersection=intersection, fts=fts)
def test_successful_validation(self) -> None: """ Test initializing Coordination object with correct input """ # GIVEN input_dict = TestCoordinationInputValidation.get_default_inputs() # WHEN Offset(**input_dict)
def test_non_unique_ids(self) -> None: """ Test giving two identical ids to initialize a Coordination """ # GIVEN input_dict = TestCoordinationInputValidation.get_default_inputs() input_dict["from_id"] = "1" input_dict["to_id"] = "1" with self.assertRaises(ValueError): Offset(**input_dict)
def test_wrong_datatype_for_ids(self) -> None: """ Test giving wrong datatype to Coordionation for ids """ # GIVEN input_dict = TestCoordinationInputValidation.get_default_inputs() input_dict["from_id"] = 1 input_dict["to_id"] = 2 # WHEN initializing the offset offset = Offset(**input_dict) # Should not give an error (datatype is converted to string) self.assertEqual(offset.from_id, "1") self.assertEqual(offset.to_id, "2")
def get_default_inputs() -> Dict: """ Function to get default (valid) inputs for Intersection() """ signalgroups = [SignalGroup(id=f"sg{i+1}", traffic_lights=[TrafficLight(capacity=1800, lost_time=1)], min_greenyellow=10, max_greenyellow=80, min_red=10, max_red=80) for i in range(6)] conflicts = [Conflict(id1="sg1", id2="sg2", setup12=1, setup21=2), Conflict(id1="sg1", id2="sg6", setup12=1, setup21=2), Conflict(id1="sg2", id2="sg6", setup12=1, setup21=2)] sync_starts = [SyncStart(from_id="sg1", to_id="sg3")] offsets = [Offset(from_id="sg1", to_id="sg4", seconds=10)] periodic_orders = [PeriodicOrder(order=["sg1", "sg2", "sg6"])] greenyellow_leads = [GreenyellowLead(from_id="sg1", to_id="sg5", min_seconds=1, max_seconds=10)] greenyellow_trails = [GreenyellowTrail(from_id="sg5", to_id="sg1", min_seconds=2, max_seconds=8)] return dict(signalgroups=signalgroups, conflicts=conflicts, sync_starts=sync_starts, offsets=offsets, greenyellow_leads=greenyellow_leads, greenyellow_trails=greenyellow_trails, periodic_orders=periodic_orders)
def from_json(intersection_dict: Dict) -> Intersection: """ Loading intersection from json (expected same json structure as generated with to_json) :param intersection_dict: :return: intersection object """ # load signal groups signalgroups = [ SignalGroup.from_json(signalgroup_dict=signalgroup_dict) for signalgroup_dict in intersection_dict["signalgroups"] ] if "periodic_orders" in intersection_dict: periodic_orders = [ PeriodicOrder.from_json(order_dict=order_dict) for order_dict in intersection_dict["periodic_orders"] ] else: periodic_orders = [] # load conflicts conflicts = [ Conflict.from_json(conflict_dict=conflict_dict) for conflict_dict in intersection_dict["conflicts"] ] # load other relations (synchronous starts, offsets and greenyellow_lead) sync_starts = [] offsets = [] greenyellow_leads = [] greenyellow_trails = [] for other_relation_dict in intersection_dict["other_relations"]: assert other_relation_dict["from_start_gy"] == other_relation_dict["to_start_gy"], \ "besides conflicts, at the moment the cloud api can only handle synchronous starts, offsets, " \ "greenyellow-leads and greenyellow-trails." if other_relation_dict[ "from_start_gy"] is True and other_relation_dict[ "to_start_gy"] is True: if other_relation_dict["min_time"] == other_relation_dict[ "max_time"]: if other_relation_dict["min_time"] == 0: # sync start sync_starts.append( SyncStart.from_json( sync_start_dict=other_relation_dict)) else: # offset offsets.append( Offset.from_json(offset_dict=other_relation_dict)) else: # greenyellow-leads greenyellow_leads.append( GreenyellowLead.from_json( json_dict=other_relation_dict)) elif other_relation_dict[ "from_start_gy"] is False and other_relation_dict[ "to_start_gy"] is False: greenyellow_trails.append( GreenyellowTrail.from_json(json_dict=other_relation_dict)) return Intersection(signalgroups=signalgroups, conflicts=conflicts, sync_starts=sync_starts, offsets=offsets, greenyellow_leads=greenyellow_leads, greenyellow_trails=greenyellow_trails, periodic_orders=periodic_orders)