def display_agent_tutorial(session_coordinator): """ Auxiliary function to show instructions in the Graphical User Interface explaining how to download, configure and run the Agent application. :param session_coordinator: current session coordinator of the testing session. :return: None """ agent_display = ui_reports.InputFormBody( title="Agent configuration tutorial.", tag_key="Agent", tag_value="Instructions") agent_display.add_field( ui_reports.ParagraphField( name="1-Configure the Packet Forwarder on the LoRa Gateway.:", value= 'e.g. Agent UDP port (default 1700) and the host IP on gateway\'s local.conf file' )) if "message-broker" not in session_coordinator.amqp_url: agent_display.add_field( ui_reports.ParagraphField( name="2-Set AMQP Broker URL:", value=f"e.g.: export AMQP_URL={session_coordinator.amqp_url}")) agent_display.add_field( ui_reports.ParagraphField( name="3-Set Packet Forwarder UDP PORT (LoRa Gateway UDP Port): ", value='e.g.: export AGENT_PORT=1700')) agent_display.add_field( ui_reports.ParagraphField(name="4-Start Agent Service:", value='make start_agent')) ui_publisher.display_on_gui( msg_str=str(agent_display), key_prefix=message_broker.service_names.test_session_coordinator)
def handle_error(self, raised_exception, test_name, result_report=None): """ Handles a raised exception, setting a flag to reset the DUT in case of a test failure. """ error_name = type(raised_exception).__name__ error_details = str(raised_exception) if isinstance(raised_exception, test_errors.TestFailError): self.reset_dut = True fail_message = f"Test {test_name} failed with {error_name} error." fail_message_paragraph = ui_reports.ParagraphField(name=test_name, value=fail_message) fail_details_paragraphs = [ ui_reports.ParagraphField(name=":", value=line) for line in error_details.split("\n") ] if result_report: result_report.add_field(fail_message_paragraph) for detail_paragraph in fail_details_paragraphs: result_report.add_field(detail_paragraph) result_report.level = ui_reports.LEVEL_ERR step_error = ui_reports.InputFormBody(title=f"{test_name}: Step Fail", tag_key=test_name, tag_value=" ") step_error.add_field(fail_message_paragraph) for detail_paragraph in fail_details_paragraphs: step_error.add_field(detail_paragraph) step_error.level = ui_reports.LEVEL_ERR ui_publisher.display_on_gui( msg_str=str(step_error), key_prefix=message_broker.service_names.test_session_coordinator)
def wait_press_start(self): """ Publishes the Start button in the GUI.""" logger.debug("Showing start button.") start_request_body = ui_reports.InputFormBody( title="Start LoRaWAN testing tool") start_request_body.add_field( ui_reports.ButtonInputField(name="START", value=1)) request_start = ui_reports.RPCRequest( request_key=routing_keys.ui_all_users + '.request', channel=self.channel, body=str(start_request_body)) start_reply_json = request_start.wait_response( timeout_seconds=120).decode() self.consume_stop()
def ask_configuration_register_device(self): """ Use the GUI to request the configuration parameters of the test session: -List of testcases -DUT personalization parameters """ self.channel.start_consuming() logger.debug("Asking the GUI for configuration.") request_config = ui_reports.RPCRequest( request_key=routing_keys.configuration_request, channel=self.channel, body='{"_api_version": "1.0.0"}') session_configuration_bytes = request_config.wait_response( timeout_seconds=10) logger.debug( f"Received configuration from GUI: \n{json.dumps(session_configuration_bytes.decode(), indent=4, sort_keys=True)}" ) config = ui_reports.SessionConfigurationBody.build_from_json( json_str=session_configuration_bytes.decode()) self.requested_tests = ["td_lorawan_act_01"] if config.testcases: self.requested_tests.extend(config.testcases) else: self.requested_tests.extend(self.get_testcases()) self.requested_tests.append("td_lorawan_deactivate") testcases_display = ui_reports.InputFormBody( title="Test Cases to be excecuted.", tag_key="Configuration", tag_value="Information") testcases_display.add_field( ui_reports.ParagraphField(name="TCs list:", value="\n".join(self.requested_tests))) ui_publisher.display_on_gui( msg_str=str(testcases_display), key_prefix=message_broker.service_names.test_session_coordinator) device_id = self.get_device_from_gui() ######################################################################################### self.device_under_test = device_sessions.EndDevice( ctx_test_tool_service=self, deveui=device_id.deveui, devaddr=device_id.devaddr, appkey=device_id.appkey, nwkskey=device_id.nwkskey, appskey=device_id.appskey) self.last_deviceid = device_id
def step_handler(self, ch, method, properties, body): if not self.received_testscript_msg: self.received_testscript_msg = flora_messages.GatewayMessage( json_ttm_str=body.decode()) frmpayload_response = tests_parameters.FRMPAYLOAD.TEST_DEACTIVATE end_device = self.ctx_test_manager.device_under_test lw_response = end_device.prepare_lorawan_data( frmpayload=frmpayload_response, fport=224) if self.default_rx1_window: json_nwk_response = self.received_testscript_msg.create_nwk_response_str( phypayload=lw_response, delay=end_device.loramac_params.rx1_delay, datr_offset=end_device.loramac_params.rx1_dr_offset) else: json_nwk_response = self.received_testscript_msg.create_nwk_response_str( phypayload=lw_response, delay=end_device.loramac_params.rx2_delay, data_rate=end_device.loramac_params.rx2_dr, frequency=end_device.loramac_params.rx2_frequency) self.send_downlink(routing_key=message_broker.routing_keys.toAgent + '.gw1', msg=json_nwk_response) received_lorawan = self.received_testscript_msg.parse_lorawan_message( ignore_format_errors=True) step_report = ui_reports.InputFormBody( title="{TC}: Print message".format( TC=self.ctx_test_manager.tc_name.upper()), tag_key=self.ctx_test_manager.tc_name, tag_value=" ") step_report.add_field( ui_reports.ParagraphField(name="Received in Step: {}".format( self.name), value=str(received_lorawan))) step_report.add_field( ui_reports.ParagraphField( name="Sent in Step: {}".format(self.name), value=str(lorawan_parser.LoRaWANMessage(lw_response)))) ui_publisher.display_on_gui( msg_str=str(step_report), key_prefix=message_broker.service_names.test_session_coordinator) self.print_step_info( sending=tests_parameters.FRMPAYLOAD.TEST_DEACTIVATE)
def get_testcases(self): """ Request the list of test cases to be run by the test application server. A text box will be displayed in the GUI. """ testcases_request_body = ui_reports.InputFormBody( title="List of test cases.") testnames_template = "" testcases_request_body.add_field( ui_reports.TextInputField(name="TestCases", label="test cases", value=testnames_template)) request_testcases = ui_reports.RPCRequest( request_key=routing_keys.ui_all_users + '.request', channel=self.channel, body=str(testcases_request_body)) device_reply = testcases_request_body.get_parsed_reply( request_testcases.wait_response(timeout_seconds=120)) return device_reply["TestCases"].split()
def __init__(self, test_name, ctx_test_session_coordinator): """ :param ctx_test_session_coordinator: test session coordinator of the current test session. :param test_name: name of the test. """ self.tc_name = test_name self.device_under_test = ctx_test_session_coordinator.device_under_test self.ctx_test_session_coordinator = ctx_test_session_coordinator self.test_label = ui_reports.InputFormBody( title=f"TEST CASE: {self.tc_name}", tag_key=self.tc_name, tag_value=" ") self.ctx_test_session_coordinator.declare_and_consume( queue_name='up_tas', routing_key=routing_keys.fromAgent + '.#', durable=False, auto_delete=True, callback=self.message_handler) logger.debug(f"Init Test Manager, starting test: {test_name}")
def print_step_info(self, received_str=None, sending=None, additional_message=None): """ Handles the display of the information of the current step, logging, printing on standard output or displaying in the GUI the information related to the step of the test under execution. :param received_str: Recieved message string. :param sending: Message to be sent to the user in this step. :param additional_message: Additional message to be presented to the user. :return: None """ if not received_str: received_str = self.received_testscript_msg.get_printable_str( encryption_key=self.ctx_test_manager.device_under_test. loramac_params.appskey) step_report = ui_reports.InputFormBody( title=f"{self.ctx_test_manager.tc_name.upper()}: Step information", tag_key=self.ctx_test_manager.tc_name, tag_value=" ") if self.next_step: step_name = self.next_step.name else: step_name = "No next step." step_info_str = f"\nNext step: {step_name}\nReceived from DUT:\n {received_str}" step_report.add_field( ui_reports.ParagraphField(name=f"Completed Step: {self.name}", value="")) for line in step_info_str.split("\n"): step_report.add_field( ui_reports.ParagraphField(name="", value=line)) if sending: step_report.add_field( ui_reports.ParagraphField(name="Sending to DUT:", value=utils.bytes_to_text(sending))) if additional_message: step_report.add_field( ui_reports.ParagraphField(name="Additional information:", value=additional_message)) ui_publisher.display_on_gui( msg_str=str(step_report), key_prefix=message_broker.service_names.test_session_coordinator)
def testing_app_main(): test_session_coordinator = testingtool_services.TestSessionCoordinator( reset_attemps=TAS_RESET_ATTEMPTS) logger.debug("\nWaiting for configuration.") # >> Display agent instructions: ------------------------------------------------------------- display_agent_tutorial(session_coordinator=test_session_coordinator) # << End agent instructions: ----------------------------------------------------------------- test_session_coordinator.ask_configuration_register_device() test_session_coordinator.wait_press_start() result_report = ui_reports.InputFormBody( title="Results summary of the tests.", tag_key="Test", tag_value="Results") try: # for test_name in test_session_coordinator.requested_tests: while test_session_coordinator.test_available(): try: try: test_name = test_session_coordinator.pop_next_test_name() if test_name is None: break test_module = test_modules[test_name] except KeyError: raise test_errors.UnknownTestError(test_name) logger.debug(f"Selected test: {test_name}") test_session_coordinator.current_test = test_module.TestAppManager( test_session_coordinator) logger.debug(f"Test manager loaded: {test_name}") test_session_coordinator.start_testing() ######################################################################## # Catch Level 3 Errors ######################################################################## except test_errors.TimeOutError as timeout_exception: test_session_coordinator.handle_error( raised_exception=timeout_exception, test_name=test_name, result_report=result_report) ######################################################################## # Catch Level 2 Errors ######################################################################## except test_errors.TestFailError as test_fail_exception: test_session_coordinator.handle_error( raised_exception=test_fail_exception, test_name=test_name, result_report=result_report) except test_errors.UnknownTestError as unknown_test: test_session_coordinator.handle_error( raised_exception=unknown_test, test_name=test_name, result_report=result_report) except test_errors.SessionTerminatedError as session_terminated: test_session_coordinator.handle_error( raised_exception=session_terminated, test_name=test_name, result_report=result_report) break else: result_report.add_field( ui_reports.ParagraphField(name=test_name, value="PASS")) finally: test_session_coordinator.consume_stop() finally: test_session_coordinator.consume_stop() test_session_coordinator.channel.close() if not result_report.level == ui_reports.LEVEL_ERR: result_report.level = ui_reports.LEVEL_HL result_report.add_field( ui_reports.ParagraphField(name="TEST VERDICT: PASS", value=" ")) else: result_report.add_field( ui_reports.ParagraphField(name="TEST VERDICT: FAIL", value=" ")) ui_publisher.display_on_gui( msg_str=str(result_report), key_prefix=message_broker.service_names.test_session_coordinator) test_session_coordinator.testingtool_on = False
def get_device_from_gui(self): """ Requests and validates the Device information using the GUI.""" class InvalidHexStringInFieldError(Exception): pass def validate_bytes(number_of_bytes, field_str): try: field_bytes = bytes.fromhex(field_str) if len(field_bytes) == number_of_bytes: return field_bytes else: raise InvalidHexStringInFieldError( f'The field ({field_str}) must be {number_of_bytes} bytes long.' ) except ValueError: raise InvalidHexStringInFieldError( f'{field_str} is an invalid field') ########################################################################################### while "The user doesn't enter a valid device information": try: device_id = configuration_parser.DeviceID() device_request_body = ui_reports.InputFormBody( title="Enter device information.") device_request_body.add_field( ui_reports.TextInputField(name="DevEUI", label="Device EUI", value="0004a30b001adbe5")) device_request_body.add_field( ui_reports.TextInputField( name="AppKey", label="Application Key", value='2b7e151628aed2a6abf7158809cf4f3c')) device_request_body.add_field( ui_reports.TextInputField(name="DevAddr", label="Short address", value="26011cf1")) logger.debug( f"Requesting device credentials: {str(device_request_body)}." ) request_device = ui_reports.RPCRequest( request_key=routing_keys.ui_all_users + '.request', channel=self.channel, body=str(device_request_body)) device_reply = device_request_body.get_parsed_reply( request_device.wait_response(timeout_seconds=120)) device_id.deveui = validate_bytes( number_of_bytes=8, field_str=device_reply["DevEUI"]) device_id.appkey = validate_bytes( number_of_bytes=16, field_str=device_reply["AppKey"]) device_id.devaddr = validate_bytes( number_of_bytes=4, field_str=device_reply["DevAddr"]) device_id.appskey = bytes.fromhex("ff") + device_id.appkey[1::] device_id.nwkskey = bytes.fromhex("00") + device_id.appkey[1::] except InvalidHexStringInFieldError: continue else: break device_display = ui_reports.InputFormBody( title="Device Personalization Information.", tag_key="Configuration", tag_value="Information") device_display.add_field( ui_reports.ParagraphField(name=" ", value=device_id.to_print_str())) ui_publisher.display_on_gui( msg_str=str(device_display), key_prefix=message_broker.service_names.test_session_coordinator) return device_id