def test_parse_bad_type_and_bad_payload_should_error(self): # setup encoded_payload = self.bad_payload.encode() properties = MessageProperties(content_type=self.bad_content_type, content_encoding=self.encoding) message = Message( body=encoded_payload, properties=properties, annotations={ common_parser.DEVICE_ID_IDENTIFIER: self.device_id.encode() }, ) args = CommonParserArguments(content_type="application/json") parser = common_parser.CommonParser(message=message, common_parser_args=args) # act parsed_msg = parser.parse_message() # verify # since the content_encoding header is not present, just dump the raw payload payload = str(encoded_payload, "utf8") assert parsed_msg["event"]["payload"] == payload expected_details_1 = strings.content_type_mismatch( self.bad_content_type, "application/json") _validate_issues(parser, Severity.warning, 2, 1, [expected_details_1]) expected_details_2 = strings.invalid_json() _validate_issues(parser, Severity.error, 2, 1, [expected_details_2])
def test_parse_message_bad_content_type_should_warn(self): # setup encoded_payload = json.dumps(self.payload).encode() properties = MessageProperties(content_type=self.bad_content_type) message = Message( body=encoded_payload, properties=properties, annotations={ common_parser.DEVICE_ID_IDENTIFIER: self.device_id.encode() }, ) args = CommonParserArguments(content_type="application/json") parser = common_parser.CommonParser(message=message, common_parser_args=args) # act parsed_msg = parser.parse_message() # verify assert parsed_msg["event"]["payload"] == self.payload expected_details_1 = strings.invalid_encoding_none_found() expected_details_2 = strings.content_type_mismatch( self.bad_content_type, "application/json") _validate_issues( parser, Severity.warning, 2, 2, [expected_details_1, expected_details_2], )
def _parse_content_type(self, expected_content_type: str, system_properties: dict) -> str: actual_content_type = system_properties.get("content_type", "") # Device data is not expected to be of a certain type # Continue parsing per rules that the device is sending if not expected_content_type: return actual_content_type.lower() # Device is expected to send data in a certain format. # Data from device implies the data is in an incorrect format. # Log the issue, and continue parsing as if device is in expected format. if actual_content_type.lower() != expected_content_type.lower(): details = strings.content_type_mismatch(actual_content_type, expected_content_type) self._add_issue(severity=Severity.warning, details=details) return expected_content_type.lower() return actual_content_type
def test_central_validate_messages_issues_detected(self): expected_messages = [] (template_id, _) = self._create_device_template() (device_id, _) = self._create_device(instance_of=template_id) credentials = self._get_credentials(device_id) device_client = helpers.dps_connect_device(device_id, credentials) enqueued_time = utility.calculate_millisec_since_unix_epoch_utc( ) - 10000 # Invalid encoding payload = {"Bool": True} msg = Message(data=json.dumps(payload), content_type="application/json") device_client.send_message(msg) expected_messages.append(strings.invalid_encoding("")) # Content type mismatch (e.g. non application/json) payload = {"Bool": True} msg = Message(data=json.dumps(payload), content_encoding="utf-8") device_client.send_message(msg) expected_messages.append( strings.content_type_mismatch("", "application/json")) # Invalid type payload = {"Bool": 123} msg = Message( data=json.dumps(payload), content_encoding="utf-8", content_type="application/json", ) device_client.send_message(msg) expected_messages.append( strings.invalid_primitive_schema_mismatch_template( "Bool", "boolean", 123)) # Telemetry not defined payload = {"NotPresentInTemplate": True} msg = Message( data=json.dumps(payload), content_encoding="utf-8", content_type="application/json", ) device_client.send_message(msg) # this error is harder to build from strings because we have to construct a whole template for it expected_messages.append( "Following capabilities have NOT been defined in the device template '['NotPresentInTemplate']'" ) # Invalid JSON payload = '{"asd":"def}' msg = Message( data=payload, content_encoding="utf-8", content_type="application/json", ) device_client.send_message(msg) expected_messages.append(strings.invalid_json()) # Validate the messages output = self._get_validate_messages_output( device_id, enqueued_time, max_messages=len(expected_messages)) self._delete_device(device_id) self._delete_device_template(template_id) assert output expected_issues = [ "No encoding found. Expected encoding 'utf-8' to be present in message header.", "Content type '' is not supported. Expected Content type is 'application/json'.", "Datatype of telemetry field 'Bool' does not match the datatype boolean.", "Data sent by the device : 123.", "For more information, see: https://aka.ms/iotcentral-payloads", "Following capabilities have NOT been defined in the device template '['NotPresentInTemplate']'", "Invalid JSON format", ] for issue in expected_issues: assert issue in output