Example #1
0
    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])
Example #2
0
    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