def test_min_python_error(self, pymajor, pyminor, exception):
        with mock.patch("azext_iot.common.utility.sys.version_info") as version_mock:
            version_mock.major = 2
            version_mock.minor = 6

            with pytest.raises(exception):
                validate_min_python_version(pymajor, pyminor)
Ejemplo n.º 2
0
    def test_min_python(self, pymajor, pyminor):
        with mock.patch(
                "azext_iot.common.utility.sys.version_info") as version_mock:
            version_mock.major = pymajor
            version_mock.minor = pyminor

            assert validate_min_python_version(2, 7)
Ejemplo n.º 3
0
    def test_min_python(self, mocker, pymajor, pyminor):
        version_mock = mocker.patch(
            'azext_iot.common.utility.sys.version_info')
        version_mock.major = pymajor
        version_mock.minor = pyminor

        assert validate_min_python_version(2, 7)
        payload = None
        if not command_payload[0]:
            payload = command_payload[1]
        else:
            payload = str(
                read_file_content(_device_digitaltwin_invoke_command_payload))
        with pytest.raises(CLIError):
            subject.iot_digitaltwin_invoke_command(fixture_cmd,
                                                   device_id=device_id,
                                                   interface=interface,
                                                   command_name=command,
                                                   command_payload=payload,
                                                   login=mock_target['cs'])


@pytest.mark.skipif(not validate_min_python_version(3, 5, exit_on_fail=False),
                    reason="minimum python version not satisfied")
class TestDTMonitorEvents(object):
    @pytest.fixture(params=[200])
    def serviceclient(self, mocker, fixture_ghcs, fixture_monitor_events,
                      request):
        service_client = mocker.patch(path_service_client)
        output = generate_device_interfaces_payload()
        payload_list = generate_pnp_interface_list_payload()
        payload_show = generate_pnp_interface_show_payload()
        test_side_effect = [
            build_mock_response(mocker, request.param, payload=output),
            build_mock_response(mocker, request.param, payload=payload_list),
            build_mock_response(mocker, request.param, payload=payload_show)
        ]
        service_client.side_effect = test_side_effect
Ejemplo n.º 5
0
class TestIoTHubMessaging(IoTLiveScenarioTest):
    def __init__(self, test_case):
        super(TestIoTHubMessaging, self).__init__(test_case, LIVE_HUB, LIVE_RG)

    def test_uamqp_device_messaging(self):
        device_count = 1
        device_ids = self.generate_device_names(device_count)

        self.cmd(
            "iot hub device-identity create -d {} -n {} -g {}".format(
                device_ids[0], LIVE_HUB, LIVE_RG),
            checks=[self.check("deviceId", device_ids[0])],
        )

        test_body = str(uuid4())
        test_props = "key0={};key1={}".format(str(uuid4()), str(uuid4()))
        test_cid = str(uuid4())
        test_mid = str(uuid4())
        test_ct = "text/plain"
        test_et = int((time() + 3600) * 1000)  # milliseconds since epoch
        test_ce = "utf8"

        self.kwargs["c2d_json_send_data"] = json.dumps({"data": str(uuid4())})

        # Send C2D message
        self.cmd(
            """iot device c2d-message send -d {} -n {} -g {} --data '{}' --cid {} --mid {} --ct {} --expiry {}
            --ce {} --props {}""".format(
                device_ids[0],
                LIVE_HUB,
                LIVE_RG,
                test_body,
                test_cid,
                test_mid,
                test_ct,
                test_et,
                test_ce,
                test_props,
            ),
            checks=self.is_empty(),
        )

        result = self.cmd(
            "iot device c2d-message receive -d {} --hub-name {} -g {}".format(
                device_ids[0], LIVE_HUB, LIVE_RG)).get_output_in_json()

        assert result["data"] == test_body

        system_props = result["properties"]["system"]
        assert system_props["ContentEncoding"] == test_ce
        assert system_props["ContentType"] == test_ct
        assert system_props["iothub-correlationid"] == test_cid
        assert system_props["iothub-messageid"] == test_mid
        assert system_props["iothub-expiry"]
        assert system_props[
            "iothub-to"] == "/devices/{}/messages/devicebound".format(
                device_ids[0])

        # Ack is tested in message feedback tests
        assert system_props["iothub-ack"] == "none"

        app_props = result["properties"]["app"]
        assert app_props == validate_key_value_pairs(test_props)

        # Implicit etag assertion
        etag = result["etag"]

        self.cmd(
            "iot device c2d-message complete -d {} --hub-name {} -g {} --etag {}"
            .format(device_ids[0], LIVE_HUB, LIVE_RG, etag),
            checks=self.is_empty(),
        )

        # Send C2D message via --login + application/json content ype

        test_ct = "application/json"
        test_mid = str(uuid4())

        self.cmd(
            """iot device c2d-message send -d {} --login {} --data '{}' --cid {} --mid {} --ct {} --expiry {}
            --ce {} --ack positive --props {}""".format(
                device_ids[0],
                self.connection_string,
                "{c2d_json_send_data}",
                test_cid,
                test_mid,
                test_ct,
                test_et,
                test_ce,
                test_props,
            ),
            checks=self.is_empty(),
        )

        result = self.cmd(
            "iot device c2d-message receive -d {} --login {}".format(
                device_ids[0], self.connection_string)).get_output_in_json()

        assert result["data"] == self.kwargs["c2d_json_send_data"]

        system_props = result["properties"]["system"]
        assert system_props["ContentEncoding"] == test_ce
        assert system_props["ContentType"] == test_ct
        assert system_props["iothub-correlationid"] == test_cid
        assert system_props["iothub-messageid"] == test_mid
        assert system_props["iothub-expiry"]
        assert system_props[
            "iothub-to"] == "/devices/{}/messages/devicebound".format(
                device_ids[0])

        assert system_props["iothub-ack"] == "positive"

        app_props = result["properties"]["app"]
        assert app_props == validate_key_value_pairs(test_props)

        etag = result["etag"]

        self.cmd(
            "iot device c2d-message reject -d {} --etag {} --login {}".format(
                device_ids[0], etag, self.connection_string),
            checks=self.is_empty(),
        )

        # Test waiting for ack from c2d send
        from azext_iot.operations.hub import iot_simulate_device
        from azext_iot._factory import iot_hub_service_factory
        from azure.cli.core.mock import DummyCli

        cli_ctx = DummyCli()
        client = iot_hub_service_factory(cli_ctx)

        token, thread = execute_onthread(
            method=iot_simulate_device,
            args=[
                client,
                device_ids[0],
                LIVE_HUB,
                "complete",
                "Ping from c2d ack wait test",
                2,
                5,
                "http",
            ],
            max_runs=4,
            return_handle=True,
        )

        self.cmd(
            "iot device c2d-message send -d {} --ack {} --login {} --wait -y".
            format(device_ids[0], "full", self.connection_string))
        token.set()
        thread.join()

        # Error - invalid wait when no ack requested
        self.cmd(
            "iot device c2d-message send -d {} --login {} --wait -y".format(
                device_ids[0], self.connection_string),
            expect_failure=True,
        )

        # Error - content-type is application/json but data is not.
        self.cmd(
            "iot device c2d-message send -d {} --login {} --ct application/json --data notjson"
            .format(device_ids[0], self.connection_string),
            expect_failure=True,
        )

        # Error - expiry is in the past.
        self.cmd(
            "iot device c2d-message send -d {} --login {} --expiry {}".format(
                device_ids[0], self.connection_string, int(time() * 1000)),
            expect_failure=True,
        )

    def test_device_messaging(self):
        device_count = 1
        device_ids = self.generate_device_names(device_count)

        self.cmd(
            "iot hub device-identity create -d {} -n {} -g {}".format(
                device_ids[0], LIVE_HUB, LIVE_RG),
            checks=[self.check("deviceId", device_ids[0])],
        )

        self.cmd(
            "iot device c2d-message receive -d {} --hub-name {} -g {}".format(
                device_ids[0], LIVE_HUB, LIVE_RG),
            checks=self.is_empty(),
        )

        # With connection string
        self.cmd(
            "iot device c2d-message receive -d {} --login {}".format(
                device_ids[0], self.connection_string),
            checks=self.is_empty(),
        )

        etag = "00000000-0000-0000-0000-000000000000"
        self.cmd(
            "iot device c2d-message complete -d {} --hub-name {} -g {} -e {}".
            format(device_ids[0], LIVE_HUB, LIVE_RG, etag),
            expect_failure=True,
        )

        # With connection string
        self.cmd(
            "iot device c2d-message complete -d {} --login {} -e {}".format(
                device_ids[0], self.connection_string, etag),
            expect_failure=True,
        )

        self.cmd(
            "iot device c2d-message reject -d {} --hub-name {} -g {} -e {}".
            format(device_ids[0], LIVE_HUB, LIVE_RG, etag),
            expect_failure=True,
        )

        # With connection string
        self.cmd(
            "iot device c2d-message reject -d {} --login {} -e {}".format(
                device_ids[0], self.connection_string, etag),
            expect_failure=True,
        )

        self.cmd(
            "iot device c2d-message abandon -d {} --hub-name {} -g {} --etag {}"
            .format(device_ids[0], LIVE_HUB, LIVE_RG, etag),
            expect_failure=True,
        )

        # With connection string
        self.cmd(
            "iot device c2d-message abandon -d {} --login {} --etag {}".format(
                device_ids[0], self.connection_string, etag),
            expect_failure=True,
        )

        self.cmd(
            "iot device simulate -d {} -n {} -g {} --mc {} --mi {} --data '{}' --rs 'complete'"
            .format(device_ids[0], LIVE_HUB, LIVE_RG, 2, 1, "IoT Ext Test"),
            checks=self.is_empty(),
        )

        # With connection string
        self.cmd(
            "iot device simulate -d {} --login {} --mc {} --mi {} --data '{}' --rs 'complete'"
            .format(device_ids[0], self.connection_string, 2, 1,
                    "IoT Ext Test"),
            checks=self.is_empty(),
        )

        self.cmd(
            "iot device simulate -d {} -n {} -g {} --mc {} --mi {} --data '{}' --rs 'abandon' --protocol http"
            .format(device_ids[0], LIVE_HUB, LIVE_RG, 2, 1, "IoT Ext Test"),
            checks=self.is_empty(),
        )

        # With connection string
        self.cmd(
            "iot device simulate -d {} --login {} --mc {} --mi {} --data '{}' --rs 'abandon' --protocol http"
            .format(device_ids[0], self.connection_string, 2, 1,
                    "IoT Ext Test"),
            checks=self.is_empty(),
        )

        self.cmd(
            "iot device simulate -d {} -n {} -g {} --data '{}' --rs 'reject'".
            format(device_ids[0], LIVE_HUB, LIVE_RG, "IoT Ext Test"),
            checks=self.is_empty(),
            expect_failure=True,
        )

        # Send arbitrary properties with device simulation - mqtt
        self.cmd(
            "iot device simulate -d {} -n {} -g {} --mc {} --mi {} --properties '{}'"
            .format(
                device_ids[0],
                LIVE_HUB,
                LIVE_RG,
                2,
                1,
                "myprop=myvalue;$.ct=application/json",
            ),
            checks=self.is_empty(),
        )

        # Send arbitrary properties with device simulation - http
        self.cmd(
            "iot device simulate -d {} -n {} -g {} --mc {} --mi {} --proto http -p '{}'"
            .format(
                device_ids[0],
                LIVE_HUB,
                LIVE_RG,
                2,
                1,
                "iothub-app-myprop=myvalue;iothub-messageid=1",
            ),
            checks=self.is_empty(),
        )

        self.cmd(
            "iot device send-d2c-message -d {} -n {} -g {}".format(
                device_ids[0], LIVE_HUB, LIVE_RG),
            checks=self.is_empty(),
        )

        self.cmd(
            'iot device send-d2c-message -d {} -n {} -g {} --props "MessageId=12345;CorrelationId=54321"'
            .format(device_ids[0], LIVE_HUB, LIVE_RG),
            checks=self.is_empty(),
        )

        # With connection string
        self.cmd(
            'iot device send-d2c-message -d {} --login {} --props "MessageId=12345;CorrelationId=54321"'
            .format(device_ids[0], self.connection_string),
            checks=self.is_empty(),
        )

    @pytest.mark.skipif(
        not validate_min_python_version(3, 5, exit_on_fail=False),
        reason="minimum python version not satisfied",
    )
    def test_hub_monitor_events(self):
        for cg in LIVE_CONSUMER_GROUPS:
            self.cmd(
                "az iot hub consumer-group create --hub-name {} --resource-group {} --name {}"
                .format(LIVE_HUB, LIVE_RG, cg),
                checks=[self.check("name", cg)],
            )

        from azext_iot.operations.hub import iot_device_send_message
        from azext_iot._factory import iot_hub_service_factory
        from azure.cli.core.mock import DummyCli

        cli_ctx = DummyCli()
        client = iot_hub_service_factory(cli_ctx)

        device_count = 10
        device_ids = self.generate_device_names(device_count)

        # Test with invalid connection string
        self.cmd(
            "iot hub monitor-events -t 1 -y --login {}".format(
                self.connection_string + "zzz"),
            expect_failure=True,
        )

        # Create and Simulate Devices
        for i in range(device_count):
            self.cmd(
                "iot hub device-identity create -d {} -n {} -g {}".format(
                    device_ids[i], LIVE_HUB, LIVE_RG),
                checks=[self.check("deviceId", device_ids[i])],
            )

        enqueued_time = calculate_millisec_since_unix_epoch_utc()

        for i in range(device_count):
            execute_onthread(
                method=iot_device_send_message,
                args=[
                    client,
                    device_ids[i],
                    LIVE_HUB,
                    '{\r\n"payload_data1":"payload_value1"\r\n}',
                    "$.mid=12345;key0=value0;key1=1",
                    1,
                    LIVE_RG,
                    None,
                    0,
                ],
                max_runs=1,
            )
        # Monitor events for all devices and include sys, anno, app
        self.command_execute_assert(
            "iot hub monitor-events -n {} -g {} --cg {} --et {} -t 5 -y -p sys anno app"
            .format(LIVE_HUB, LIVE_RG, LIVE_CONSUMER_GROUPS[0], enqueued_time),
            device_ids + [
                "system",
                "annotations",
                "application",
                '"message_id": "12345"',
                '"key0": "value0"',
                '"key1": "1"',
            ],
        )

        # Monitor events for a single device
        self.command_execute_assert(
            "iot hub monitor-events -n {} -g {} -d {} --cg {} --et {} -t 5 -y -p all"
            .format(LIVE_HUB, LIVE_RG, device_ids[0], LIVE_CONSUMER_GROUPS[1],
                    enqueued_time),
            [
                device_ids[0],
                "system",
                "annotations",
                "application",
                '"message_id": "12345"',
                '"key0": "value0"',
                '"key1": "1"',
            ],
        )

        # Monitor events with device-id wildcards
        self.command_execute_assert(
            "iot hub monitor-events -n {} -g {} -d {} --et {} -t 5 -y -p sys anno app"
            .format(LIVE_HUB, LIVE_RG, PREFIX_DEVICE + "*", enqueued_time),
            device_ids,
        )

        # Monitor events for specific devices using query language
        device_subset_include = device_ids[:device_count // 2]
        device_include_string = ", ".join(
            ["'" + deviceId + "'" for deviceId in device_subset_include])
        query_string = "select * from devices where deviceId in [{}]".format(
            device_include_string)

        self.command_execute_assert(
            'iot hub monitor-events -n {} -g {} --device-query "{}" --et {} -t 5 -y -p sys anno app'
            .format(LIVE_HUB, LIVE_RG, query_string, enqueued_time),
            device_subset_include,
        )

        # Expect failure for excluded devices
        device_subset_exclude = device_ids[device_count // 2:]
        with pytest.raises(Exception):
            self.command_execute_assert(
                'iot hub monitor-events -n {} -g {} --device-query "{}" --et {} -t 5 -y -p sys anno app'
                .format(LIVE_HUB, LIVE_RG, query_string, enqueued_time),
                device_subset_exclude,
            )

        # Monitor events with --login parameter
        self.command_execute_assert(
            "iot hub monitor-events -t 5 -y -p all --cg {} --et {} --login {}".
            format(LIVE_CONSUMER_GROUPS[2], enqueued_time,
                   self.connection_string),
            device_ids,
        )

        enqueued_time = calculate_millisec_since_unix_epoch_utc()

        # Send messages that have JSON payload, but do not pass $.ct property
        execute_onthread(
            method=iot_device_send_message,
            args=[
                client,
                device_ids[i],
                LIVE_HUB,
                '{\r\n"payload_data1":"payload_value1"\r\n}',
                "",
                1,
                LIVE_RG,
                None,
                1,
            ],
            max_runs=1,
        )

        # Monitor messages for ugly JSON output
        self.command_execute_assert(
            "iot hub monitor-events -n {} -g {} --cg {} --et {} -t 5 -y".
            format(LIVE_HUB, LIVE_RG, LIVE_CONSUMER_GROUPS[0], enqueued_time),
            ["\\r\\n"],
        )

        # Monitor messages and parse payload as JSON with the --ct parameter
        self.command_execute_assert(
            "iot hub monitor-events -n {} -g {} --cg {} --et {} -t 5 --ct application/json -y"
            .format(LIVE_HUB, LIVE_RG, LIVE_CONSUMER_GROUPS[1], enqueued_time),
            ['"payload_data1": "payload_value1"'],
        )

        enqueued_time = calculate_millisec_since_unix_epoch_utc()

        # Send messages that have JSON payload and have $.ct property
        execute_onthread(
            method=iot_device_send_message,
            args=[
                client,
                device_ids[i],
                LIVE_HUB,
                '{\r\n"payload_data1":"payload_value1"\r\n}',
                "$.ct=application/json",
                1,
                LIVE_RG,
            ],
            max_runs=1,
        )

        # Monitor messages for pretty JSON output
        self.command_execute_assert(
            "iot hub monitor-events -n {} -g {} --cg {} --et {} -t 5 -y".
            format(LIVE_HUB, LIVE_RG, LIVE_CONSUMER_GROUPS[0], enqueued_time),
            ['"payload_data1": "payload_value1"'],
        )

        # Monitor messages with yaml output
        self.command_execute_assert(
            "iot hub monitor-events -n {} -g {} --cg {} --et {} -t 5 -y -o yaml"
            .format(LIVE_HUB, LIVE_RG, LIVE_CONSUMER_GROUPS[1], enqueued_time),
            ["payload_data1: payload_value1"],
        )

        enqueued_time = calculate_millisec_since_unix_epoch_utc()

        # Send messages that have improperly formatted JSON payload and a $.ct property
        execute_onthread(
            method=iot_device_send_message,
            args=[
                client,
                device_ids[i],
                LIVE_HUB,
                '{\r\n"payload_data1""payload_value1"\r\n}',
                "$.ct=application/json",
                1,
                LIVE_RG,
            ],
            max_runs=1,
        )

        # Monitor messages to ensure it returns improperly formatted JSON
        self.command_execute_assert(
            "iot hub monitor-events -n {} -g {} --cg {} --et {} -t 5 -y".
            format(LIVE_HUB, LIVE_RG, LIVE_CONSUMER_GROUPS[0], enqueued_time),
            ['{\\r\\n\\"payload_data1\\"\\"payload_value1\\"\\r\\n}'],
        )

        for cg in LIVE_CONSUMER_GROUPS:
            self.cmd(
                "az iot hub consumer-group delete --hub-name {} --resource-group {} --name {}"
                .format(LIVE_HUB, LIVE_RG, cg),
                expect_failure=False,
            )

    @pytest.mark.skipif(
        not validate_min_python_version(3, 4, exit_on_fail=False),
        reason="minimum python version not satisfied",
    )
    def test_hub_monitor_feedback(self):
        device_count = 1
        device_ids = self.generate_device_names(device_count)

        for i in range(device_count):
            self.cmd(
                "iot hub device-identity create -d {} -n {} -g {}".format(
                    device_ids[i], LIVE_HUB, LIVE_RG),
                checks=[self.check("deviceId", device_ids[i])],
            )

        ack = "full"
        self.cmd(
            "iot device c2d-message send -d {} --hub-name {} -g {} --ack {} -y"
            .format(device_ids[0], LIVE_HUB, LIVE_RG, ack),
            checks=self.is_empty(),
        )

        result = self.cmd(
            "iot device c2d-message receive -d {} --hub-name {} -g {}".format(
                device_ids[0], LIVE_HUB, LIVE_RG)).get_output_in_json()

        system_props = result["properties"]["system"]
        msg_id = system_props["iothub-messageid"]

        etag = result["etag"]
        assert system_props["iothub-ack"] == ack

        self.cmd(
            "iot device c2d-message complete -d {} --hub-name {} -g {} -e {}".
            format(device_ids[0], LIVE_HUB, LIVE_RG, etag))

        self.command_execute_assert(
            "iot hub monitor-feedback -n {} -g {} -w {} -y".format(
                LIVE_HUB, LIVE_RG, msg_id),
            ["description: Success"],
        )

        # With connection string - filter on device
        ack = "positive"
        self.cmd(
            "iot device c2d-message send -d {} --login {} --ack {} -y".format(
                device_ids[0], self.connection_string, ack),
            checks=self.is_empty(),
        )

        result = self.cmd(
            "iot device c2d-message receive -d {} --login {}".format(
                device_ids[0], self.connection_string)).get_output_in_json()

        system_props = result["properties"]["system"]
        msg_id = system_props["iothub-messageid"]

        etag = result["etag"]
        assert system_props["iothub-ack"] == ack

        self.cmd(
            "iot device c2d-message complete -d {} --login {} -e {}".format(
                device_ids[0], self.connection_string, etag))

        self.command_execute_assert(
            "iot hub monitor-feedback --login {} -w {} -d {} -y".format(
                self.connection_string, msg_id, device_ids[0]),
            ["description: Success"],
        )

        # With connection string - dead lettered case + unrelated ack
        ack = "negative"

        # Create some noise
        self.cmd(
            "iot device c2d-message send -d {} --login {} --ack {} -y".format(
                device_ids[0], self.connection_string, ack),
            checks=self.is_empty(),
        )
        result = self.cmd(
            "iot device c2d-message receive -d {} --login {}".format(
                device_ids[0], self.connection_string)).get_output_in_json()
        etag = result["etag"]

        self.cmd("iot device c2d-message reject -d {} --login {} -e {}".format(
            device_ids[0], self.connection_string, etag))

        # Target message
        self.cmd(
            "iot device c2d-message send -d {} --login {} --ack {} -y".format(
                device_ids[0], self.connection_string, ack),
            checks=self.is_empty(),
        )

        result = self.cmd(
            "iot device c2d-message receive -d {} --login {}".format(
                device_ids[0], self.connection_string)).get_output_in_json()

        system_props = result["properties"]["system"]
        msg_id = system_props["iothub-messageid"]

        etag = result["etag"]
        assert system_props["iothub-ack"] == ack

        self.cmd("iot device c2d-message reject -d {} --login {} -e {}".format(
            device_ids[0], self.connection_string, etag))

        self.command_execute_assert(
            "iot hub monitor-feedback --login {} -w {} -y".format(
                self.connection_string, msg_id),
            ["description: Message rejected"],
        )

        # purge messages
        num_messages = 3
        for i in range(num_messages):
            self.cmd(
                "iot device c2d-message send -d {} --login {}".format(
                    device_ids[0], self.connection_string),
                checks=self.is_empty(),
            )
        purge_result = self.cmd(
            "iot device c2d-message purge -d {} --login {}".format(
                device_ids[0], self.connection_string)).get_output_in_json()
        assert purge_result["deviceId"] == device_ids[0]
        assert purge_result["totalMessagesPurged"] == num_messages
        assert not purge_result["moduleId"]

        # Errors with multiple ack arguments
        self.cmd(
            "iot device c2d-message receive -d {} --login {} --complete --abandon"
            .format(device_ids[0], self.connection_string),
            expect_failure=True,
        )
        self.cmd(
            "iot device c2d-message receive -d {} --login {} --reject --abandon"
            .format(device_ids[0], self.connection_string),
            expect_failure=True,
        )
        self.cmd(
            "iot device c2d-message receive -d {} --login {} --reject --complete --abandon"
            .format(device_ids[0], self.connection_string),
            expect_failure=True,
        )

        # Receive with auto-ack
        for ack_test in ["complete", "abandon", "reject"]:
            self.cmd(
                "iot device c2d-message send -d {} --login {}".format(
                    device_ids[0], self.connection_string),
                checks=self.is_empty(),
            )
            result = self.cmd(
                "iot device c2d-message receive -d {} --login {} --{}".format(
                    device_ids[0], self.connection_string,
                    ack_test)).get_output_in_json()
            assert result["ack"] == ack_test
            assert json.dumps(result["data"])
            assert json.dumps(result["properties"]["system"])
Ejemplo n.º 6
0
                                           mocker):
        mocked_util_logger = mocker.patch.object(logger,
                                                 "warning",
                                                 autospec=True)

        with pytest.raises(CLIError) as exc_info:
            process_json_arg(content, argument_name=argname)

        assert str(exc_info.value).startswith(
            "Failed to parse json from file: '{}' for argument '{}' with exception:\n"
            .format(content, argname))
        assert mocked_util_logger.call_count == 0


@pytest.mark.skipif(
    not validate_min_python_version(3, 5, exit_on_fail=False),
    reason="minimum python version not satisfied",
)
class TestEvents3Parser:
    device_id = "some-device-id"
    payload = {"someProperty": "someValue"}
    encoding = "UTF-8"
    content_type = "application/json"

    bad_encoding = "ascii"
    bad_payload = "bad-payload"
    bad_content_type = "bad-content-type"

    def test_parse_message_should_succeed(self):
        # setup
        app_prop_type = "some_app_prop"