def test_central_monitor_events(self): (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 payload = {"Bool": True} msg = Message( data=json.dumps(payload), content_encoding="utf-8", content_type="application/json", ) device_client.send_message(msg) # Test with invalid app-id self.cmd( "iot central diagnostics monitor-events --app-id {} -y".format( APP_ID + "zzz"), expect_failure=True, ) # Ensure no failure output = self._get_monitor_events_output(device_id, enqueued_time) self._delete_device(device_id) self._delete_device_template(template_id) assert '"Bool": true' in output assert device_id in output
def test_central_validate_messages_success(self): (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 payload = {"Bool": True} msg = Message( data=json.dumps(payload), content_encoding="utf-8", content_type="application/json", ) device_client.send_message(msg) # Validate the messages output = self._get_validate_messages_output(device_id, enqueued_time) self._delete_device(device_id) self._delete_device_template(template_id) assert output assert "Successfully parsed 1 message(s)" in output assert "No errors detected" in output
def test_iothub_c2d_messages(self): device_count = 1 device_ids = self.generate_device_names(device_count) self.cmd( f"iot hub device-identity create -d {device_ids[0]} -n {LIVE_HUB} -g {LIVE_RG}" ) for auth_phase in DATAPLANE_AUTH_TYPES: test_ce = "utf-16" if auth_phase == AuthenticationTypeDataplane.login.value else "utf-8" test_body = f"{uuid4()} шеллы 😁" # Mixed unicode blocks test_props = f"key0={str(uuid4())};key1={str(uuid4())}" test_cid = str(uuid4()) test_mid = str(uuid4()) test_ct = "text/plain" test_et = calculate_millisec_since_unix_epoch_utc( 3600) # milliseconds since epoch self.kwargs["c2d_json_send_data"] = json.dumps( {"data": str(uuid4())}) # Send C2D message self.cmd( self.set_cmd_auth_type( f"iot device c2d-message send -d {device_ids[0]} -n {LIVE_HUB} -g {LIVE_RG} --data '{test_body}' " f"--cid {test_cid} --mid {test_mid} --ct {test_ct} --expiry {test_et} --ce {test_ce} -p '{test_props}'", auth_type=auth_phase), checks=self.is_empty(), ) c2d_receive_result = self.cmd( f"iot device c2d-message receive -d {device_ids[0]} --hub-name {LIVE_HUB} -g {LIVE_RG} --complete", ).get_output_in_json() assert c2d_receive_result["data"] == test_body # Assert system properties received_system_props = c2d_receive_result["properties"]["system"] assert received_system_props["ContentEncoding"] == test_ce assert received_system_props["ContentType"] == test_ct assert received_system_props["iothub-correlationid"] == test_cid assert received_system_props["iothub-messageid"] == test_mid assert received_system_props["iothub-expiry"] assert received_system_props[ "iothub-to"] == f"/devices/{device_ids[0]}/messages/devicebound" # Ack is tested in message feedback tests assert received_system_props["iothub-ack"] == "none" # Assert app properties received_app_props = c2d_receive_result["properties"]["app"] assert received_app_props == validate_key_value_pairs(test_props) assert c2d_receive_result["etag"]
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, )
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