From 8d4fe973e3721ab8c8baf0049e4c84b2d861b5d3 Mon Sep 17 00:00:00 2001 From: antisch Date: Thu, 16 Jan 2020 15:49:30 -0800 Subject: [PATCH 1/8] Updated iot test to use latest code --- .azure-pipelines/client.test.live.yml | 3 + iot_requirements.txt | 8 + .../test_azure_iothub_cli_extension.py | 342 ++---------------- 3 files changed, 39 insertions(+), 314 deletions(-) create mode 100644 iot_requirements.txt diff --git a/.azure-pipelines/client.test.live.yml b/.azure-pipelines/client.test.live.yml index 0660284e8..f6dad9fb8 100644 --- a/.azure-pipelines/client.test.live.yml +++ b/.azure-pipelines/client.test.live.yml @@ -68,6 +68,7 @@ jobs: python --version Invoke-WebRequest -UseBasicParsing -Uri https://bootstrap.pypa.io/get-pip.py | Select-Object -ExpandProperty Content | python python -m pip install -r dev_requirements.txt + python -m pip install -r iot_requirements.txt displayName: 'Install dependencies' env: PYTHONWARNINGS: ignore:DEPRECATION @@ -185,6 +186,7 @@ jobs: $(PythonBin) --version curl -sS https://bootstrap.pypa.io/get-pip.py | $(PythonBin) - --user $(PythonBin) -m pip install --user -r dev_requirements.txt + $(PythonBin) -m pip install --user -r iot_requirements.txt displayName: 'Install dependencies' - script: $(PythonBin) setup.py bdist_wheel @@ -272,6 +274,7 @@ jobs: python --version curl -sS https://bootstrap.pypa.io/get-pip.py | python - --user python -m pip install --user -r dev_requirements.txt + python -m pip install --user -r iot_requirements.txt displayName: 'Install dependencies' - script: python setup.py bdist_wheel diff --git a/iot_requirements.txt b/iot_requirements.txt new file mode 100644 index 000000000..3edd4fa44 --- /dev/null +++ b/iot_requirements.txt @@ -0,0 +1,8 @@ +azure-cli-core +azure-cli-iot +azure-cli-profile +azure-cli-extension +azure-cli-configure +azure-cli-resource +azure-cli-cloud +https://github.com/Azure/azure-iot-cli-extension/archive/master.zip diff --git a/samples/asynctests/test_azure_iothub_cli_extension.py b/samples/asynctests/test_azure_iothub_cli_extension.py index 4fe92597a..4d6bd60bf 100644 --- a/samples/asynctests/test_azure_iothub_cli_extension.py +++ b/samples/asynctests/test_azure_iothub_cli_extension.py @@ -4,19 +4,11 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -import asyncio -import json import sys import os import logging import pytest -from base64 import b64encode, b64decode -from hashlib import sha256 -from hmac import HMAC -from time import time from datetime import datetime -from uuid import uuid4 -import concurrent import uamqp @@ -31,324 +23,46 @@ def get_logger(level): return uamqp_logger -DEBUG = True logger = get_logger(logging.INFO) -def _generate_sas_token(uri, policy, key, expiry=None): - if not expiry: - expiry = time() + 3600 # Default to 1 hour. - encoded_uri = quote_plus(uri) - ttl = int(expiry) - sign_key = '%s\n%d' % (encoded_uri, ttl) - signature = b64encode(HMAC(b64decode(key), sign_key.encode('utf-8'), sha256).digest()) - result = { - 'sr': uri, - 'sig': signature, - 'se': str(ttl)} - if policy: - result['skn'] = policy - return 'SharedAccessSignature ' + urlencode(result) - - -def _build_iothub_amqp_endpoint_from_target(target): - hub_name = target['entity'].split('.')[0] - username = "{}@sas.root.{}".format(target['policy'], hub_name) - sas_token = _generate_sas_token(target['entity'], target['policy'], - target['primarykey'], time() + 360) - return username, sas_token - - -def _unicode_binary_map(target): - # Assumes no iteritems() - result = {} - for k in target: - key = k - if isinstance(k, bytes): - key = str(k, 'utf8') - if isinstance(target[k], bytes): - result[key] = str(target[k], 'utf8') - else: - result[key] = target[k] - return result - - -def _parse_entity(entity, filter_none=False): +def _get_iot_conn_str(live_iothub_config): result = {} - attributes = [attr for attr in dir(entity) if not attr.startswith('_')] - for attribute in attributes: - value = getattr(entity, attribute, None) - if filter_none and not value: - continue - value_behavior = dir(value) - if '__call__' not in value_behavior: - result[attribute] = value + result['cs'] = "HostName={};SharedAccessKeyName={};SharedAccessKey={}".format( + live_iothub_config['hostname'], + live_iothub_config['key_name'], + live_iothub_config['access_key'] + ) + result['policy'] = live_iothub_config['key_name'] + result['primarykey'] = live_iothub_config['access_key'] + result['entity'] = live_iothub_config['hostname'] return result -def executor(target, consumer_group, enqueued_time, device_id=None, properties=None, timeout=0): - coroutines = [] - coroutines.append(initiate_event_monitor(target, consumer_group, enqueued_time, device_id, properties, timeout)) - - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - - future = asyncio.gather(*coroutines, loop=loop, return_exceptions=True) - result = None - - try: - device_filter_txt = None - if device_id: - device_filter_txt = ' filtering on device: {},'.format(device_id) - - def stop_and_suppress_eloop(): - try: - loop.stop() - except Exception: # pylint: disable=broad-except - pass - - print('Starting event monitor,{} use ctrl-c to stop...'.format(device_filter_txt if device_filter_txt else '')) - result = loop.run_until_complete(future) - except KeyboardInterrupt: - print('Stopping event monitor...') - remaining_tasks = [t for t in asyncio.Task.all_tasks() if not t.done()] - remaining_future = asyncio.gather(*remaining_tasks, loop=loop, return_exceptions=True) - try: - loop.run_until_complete(asyncio.wait_for(remaining_future, 5)) - except concurrent.futures.TimeoutError: - print("Timed out before tasks could finish. Shutting down anyway.") - print("Finished event monitor shutdown.") - finally: - if result: - error = next(res for res in result if result) - if error: - logger.error(error) - raise RuntimeError(error) - - -async def initiate_event_monitor(target, consumer_group, enqueued_time, device_id=None, properties=None, timeout=0): - def _get_conn_props(): - properties = {} - properties["product"] = "az.cli.iot.extension" - properties["framework"] = "Python {}.{}.{}".format(*sys.version_info[0:3]) - properties["platform"] = sys.platform - return properties - - if not target.get('events'): - endpoint = _build_iothub_amqp_endpoint_from_target(target) - _, update = await evaluate_redirect(endpoint) - target['events'] = update['events'] - auth = _build_auth_container(target) - meta_data = await query_meta_data(target['events']['address'], target['events']['path'], auth) - partition_count = meta_data[b'partition_count'] - partition_ids = [] - for i in range(int(partition_count)): - partition_ids.append(str(i)) - target['events']['partition_ids'] = partition_ids - - partitions = target['events']['partition_ids'] - - if not partitions: - logger.debug('No Event Hub partitions found to listen on.') - return - - coroutines = [] - auth = _build_auth_container(target) - async with uamqp.ConnectionAsync(target['events']['endpoint'], sasl=auth, - debug=DEBUG, container_id=str(uuid4()), properties=_get_conn_props()) as conn: - for p in partitions: - coroutines.append(monitor_events(endpoint=target['events']['endpoint'], - connection=conn, - path=target['events']['path'], - auth=auth, - partition=p, - consumer_group=consumer_group, - enqueuedtimeutc=enqueued_time, - properties=properties, - device_id=device_id, - timeout=timeout)) - results = await asyncio.gather(*coroutines, return_exceptions=True) - logger.warning("Finished all event monitors") - logger.warning("Finished initiate_event_monitor") - - -async def monitor_events(endpoint, connection, path, auth, partition, consumer_group, enqueuedtimeutc, - properties, device_id=None, timeout=0): - source = uamqp.address.Source('amqps://{}/{}/ConsumerGroups/{}/Partitions/{}'.format(endpoint, path, - consumer_group, partition)) - source.set_filter( - bytes('amqp.annotation.x-opt-enqueuedtimeutc > ' + str(enqueuedtimeutc), 'utf8')) - - def _output_msg_kpi(msg): - # TODO: Determine if amqp filters can support boolean operators for multiple conditions - origin = str(msg.annotations.get(b'iothub-connection-device-id'), 'utf8') - if device_id and origin != device_id: - return - - event_source = {'event': {}} - - event_source['event']['origin'] = origin - event_source['event']['payload'] = str(next(msg.get_data()), 'utf8') - if 'anno' in properties or 'all' in properties: - event_source['event']['annotations'] = _unicode_binary_map(msg.annotations) - if 'sys' in properties or 'all' in properties: - if not event_source['event'].get('properties'): - event_source['event']['properties'] = {} - event_source['event']['properties']['system'] = _unicode_binary_map(_parse_entity(msg.properties, True)) - if 'app' in properties or 'all' in properties: - if not event_source['event'].get('properties'): - event_source['event']['properties'] = {} - app_prop = msg.application_properties if msg.application_properties else None - - if app_prop: - event_source['event']['properties']['application'] = _unicode_binary_map(app_prop) - - exp_cancelled = False - receive_client = uamqp.ReceiveClientAsync(source, auth=auth, timeout=timeout, prefetch=0, debug=DEBUG) - - try: - await receive_client.open_async(connection=connection) - - msg_iter = receive_client.receive_messages_iter_async() - async for msg in msg_iter: - _output_msg_kpi(msg) - - except asyncio.CancelledError: - exp_cancelled = True - await receive_client.close_async() - except KeyboardInterrupt: - logger.warning("Keyboard interrupt, closing monitor {}.".format(partition)) - exp_cancelled = True - await receive_client.close_async() - raise - except uamqp.errors.LinkDetach as ld: - if isinstance(ld.description, bytes): - ld.description = str(ld.description, 'utf8') - raise RuntimeError(ld.description) - finally: - if not exp_cancelled: - await receive_client.close_async() - logger.warning("Finished MonitorEvents for partition {}".format(partition)) - - -def _build_auth_container(target): - sas_uri = 'sb://{}/{}'.format(target['events']['endpoint'], target['events']['path']) - return uamqp.authentication.SASTokenAsync.from_shared_access_key(sas_uri, target['policy'], target['primarykey']) - - -async def evaluate_redirect(endpoint): - source = uamqp.address.Source('amqps://{}/messages/events/$management'.format(endpoint)) - receive_client = uamqp.ReceiveClientAsync(source, timeout=30000, prefetch=1, debug=DEBUG) - - try: - await receive_client.open_async() - await receive_client.receive_message_batch_async(max_batch_size=1) - except uamqp.errors.LinkRedirect as redirect: - redirect = _unicode_binary_map(_parse_entity(redirect)) - result = {} - result['events'] = {} - result['events']['endpoint'] = redirect['hostname'] - result['events']['path'] = redirect['address'].replace('amqps://', '').split('/')[1] - result['events']['address'] = redirect['address'] - return redirect, result - finally: - await receive_client.close_async() - - -async def query_meta_data(endpoint, path, auth): - source = uamqp.address.Source(endpoint) - receive_client = uamqp.ReceiveClientAsync(source, auth=auth, timeout=30000, debug=DEBUG) - try: - await receive_client.open_async() - message = uamqp.Message(application_properties={'name': path}) - - response = await receive_client.mgmt_request_async( - message, - b'READ', - op_type=b'com.microsoft:eventhub', - status_code_field=b'status-code', - description_fields=b'status-description', - timeout=30000 - ) - test = response.get_data() - return test - finally: - await receive_client.close_async() - - -def monitor_feedback(target, device_id, wait_on_id=None, token_duration=3600): - - def handle_msg(msg): - payload = next(msg.get_data()) - if isinstance(payload, bytes): - payload = str(payload, 'utf8') - # assume json [] based on spec - payload = json.loads(payload) - for p in payload: - if device_id and p.get('deviceId') and p['deviceId'].lower() != device_id.lower(): - return None - if wait_on_id: - msg_id = p['originalMessageId'] - if msg_id == wait_on_id: - return msg_id - return None - - operation = '/messages/servicebound/feedback' - endpoint = _build_iothub_amqp_endpoint_from_target(target, duration=token_duration) - endpoint = endpoint + operation - - device_filter_txt = None - if device_id: - device_filter_txt = ' filtering on device: {},'.format(device_id) - - print('Starting C2D feedback monitor,{} use ctrl-c to stop...'.format(device_filter_txt if device_filter_txt else '')) - +def test_iothub_monitor_events(live_iothub_config): try: - client = uamqp.ReceiveClient('amqps://' + endpoint, debug=DEBUG) - message_generator = client.receive_messages_iter() - for msg in message_generator: - match = handle_msg(msg) - if match: - logger.info('requested msg id has been matched...') - msg.accept() - return match - except uamqp.errors.AMQPConnectionError: - logger.debug('amqp connection has expired...') - finally: - client.close() - -def get_target(config): - target = {} - target['cs'] = 'HostName={};SharedAccessKeyName={};SharedAccessKey={}'.format( - config['hostname'], - config['key_name'], - config['access_key']) - target['entity'] = config['hostname'] - target['policy'] = config['key_name'] - target['primarykey'] = config['access_key'] - events = {} - events['endpoint'] = config['endpoint'] - events['partition_count'] = config.get('partition_count', 4) - events['path'] = config['hub_name'] - events['partition_ids'] = config.get('partition_ids', ["0", "1", "2"])#, "3", "4", "5", "6", "7", "8", "9", "10"]) - target['events'] = events - return target + import azext_iot.operations.events3._events as events3 + import azext_iot.operations.events3._builders as builders + except ImportError: + pytest.skip("Only runs in IoT CLI env.") -def test_iothub_monitor_events(live_iothub_config): - properties = [] - timeout = 30000 + device_ids = {live_iothub_config["device"], True} now = datetime.utcnow() epoch = datetime.utcfromtimestamp(0) enqueued_time = int(1000 * (now - epoch).total_seconds()) - target = get_target(live_iothub_config) - - executor(target, - consumer_group=live_iothub_config['consumer_group'], - enqueued_time=enqueued_time, - properties=properties, - timeout=timeout, - device_id=live_iothub_config['device']) - + target = _get_iot_conn_str(live_iothub_config) + + eventHubTarget = builders.EventTargetBuilder().build_iot_hub_target(target) + events3.executor( + eventHubTarget, + consumer_group=live_iothub_config['consumer_group'], + enqueued_time=enqueued_time, + properties=[], + timeout=30000, + device_id=live_iothub_config["device"], + output='json', + devices=device_ids + ) def test_iothub_monitor_feedback(live_iothub_config): pytest.skip("Not yet implemented") From 3020d7ea603b51bf7ef648804ee75e7843595329 Mon Sep 17 00:00:00 2001 From: antisch Date: Thu, 16 Jan 2020 19:50:13 -0800 Subject: [PATCH 2/8] Skip on Python 3.8 for now --- iot_requirements.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iot_requirements.txt b/iot_requirements.txt index 3edd4fa44..0df5a9cda 100644 --- a/iot_requirements.txt +++ b/iot_requirements.txt @@ -1,8 +1,8 @@ -azure-cli-core -azure-cli-iot -azure-cli-profile -azure-cli-extension -azure-cli-configure -azure-cli-resource -azure-cli-cloud -https://github.com/Azure/azure-iot-cli-extension/archive/master.zip +azure-cli-core; python_version < '3.8' +azure-cli-iot; python_version < '3.8' +azure-cli-profile; python_version < '3.8' +azure-cli-extension; python_version < '3.8' +azure-cli-configure; python_version < '3.8' +azure-cli-resource; python_version < '3.8' +azure-cli-cloud; python_version < '3.8' +https://github.com/Azure/azure-iot-cli-extension/archive/master.zip; python_version < '3.8' From de439de1d3cdc8607b8682ceafa9e67dcef4cfd2 Mon Sep 17 00:00:00 2001 From: antisch Date: Thu, 16 Jan 2020 20:05:23 -0800 Subject: [PATCH 3/8] Added c2d send test --- .../test_azure_iothub_cli_extension.py | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/samples/asynctests/test_azure_iothub_cli_extension.py b/samples/asynctests/test_azure_iothub_cli_extension.py index 4d6bd60bf..a34fe5366 100644 --- a/samples/asynctests/test_azure_iothub_cli_extension.py +++ b/samples/asynctests/test_azure_iothub_cli_extension.py @@ -43,6 +43,8 @@ def test_iothub_monitor_events(live_iothub_config): try: import azext_iot.operations.events3._events as events3 import azext_iot.operations.events3._builders as builders + events3.DEBUG = False + builders.DEBUG = False except ImportError: pytest.skip("Only runs in IoT CLI env.") @@ -69,7 +71,23 @@ def test_iothub_monitor_feedback(live_iothub_config): def test_iothub_c2d_message_send(live_iothub_config): - pytest.skip("Not yet implemented") + try: + import azext_iot.operations.events3._events as events3 + import azext_iot.operations.events3._builders as builders + events3.DEBUG = False + builders.DEBUG = False + except ImportError: + pytest.skip("Only runs in IoT CLI env.") + + target = _get_iot_conn_str(live_iothub_config) + msg_id, errors = events3.send_c2d_message( + target=target, + device_id=live_iothub_config["device"], + data="IoT CLI extension test", + ack='full') + + assert msg_id + assert not errors if __name__ == '__main__': From 01de76fda56936098a0b307f5de0a5cb062f1563 Mon Sep 17 00:00:00 2001 From: antisch Date: Tue, 21 Jan 2020 13:45:55 -0800 Subject: [PATCH 4/8] Trying 3.8 again --- iot_requirements.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iot_requirements.txt b/iot_requirements.txt index 0df5a9cda..3edd4fa44 100644 --- a/iot_requirements.txt +++ b/iot_requirements.txt @@ -1,8 +1,8 @@ -azure-cli-core; python_version < '3.8' -azure-cli-iot; python_version < '3.8' -azure-cli-profile; python_version < '3.8' -azure-cli-extension; python_version < '3.8' -azure-cli-configure; python_version < '3.8' -azure-cli-resource; python_version < '3.8' -azure-cli-cloud; python_version < '3.8' -https://github.com/Azure/azure-iot-cli-extension/archive/master.zip; python_version < '3.8' +azure-cli-core +azure-cli-iot +azure-cli-profile +azure-cli-extension +azure-cli-configure +azure-cli-resource +azure-cli-cloud +https://github.com/Azure/azure-iot-cli-extension/archive/master.zip From 3fd19b9026794bd89b64bf2511be092790fd42f3 Mon Sep 17 00:00:00 2001 From: antisch Date: Tue, 21 Jan 2020 16:15:18 -0800 Subject: [PATCH 5/8] Change dep install order --- .azure-pipelines/client.test.live.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure-pipelines/client.test.live.yml b/.azure-pipelines/client.test.live.yml index f6dad9fb8..d5cc02872 100644 --- a/.azure-pipelines/client.test.live.yml +++ b/.azure-pipelines/client.test.live.yml @@ -67,8 +67,8 @@ jobs: - powershell: | python --version Invoke-WebRequest -UseBasicParsing -Uri https://bootstrap.pypa.io/get-pip.py | Select-Object -ExpandProperty Content | python - python -m pip install -r dev_requirements.txt python -m pip install -r iot_requirements.txt + python -m pip install -r dev_requirements.txt displayName: 'Install dependencies' env: PYTHONWARNINGS: ignore:DEPRECATION @@ -185,8 +185,8 @@ jobs: - script: | $(PythonBin) --version curl -sS https://bootstrap.pypa.io/get-pip.py | $(PythonBin) - --user - $(PythonBin) -m pip install --user -r dev_requirements.txt $(PythonBin) -m pip install --user -r iot_requirements.txt + $(PythonBin) -m pip install --user -r dev_requirements.txt displayName: 'Install dependencies' - script: $(PythonBin) setup.py bdist_wheel @@ -273,8 +273,8 @@ jobs: - script: | python --version curl -sS https://bootstrap.pypa.io/get-pip.py | python - --user - python -m pip install --user -r dev_requirements.txt python -m pip install --user -r iot_requirements.txt + python -m pip install --user -r dev_requirements.txt displayName: 'Install dependencies' - script: python setup.py bdist_wheel From 13fda9639b659148d6fa0c02cd8c4b57e91f16a2 Mon Sep 17 00:00:00 2001 From: antisch Date: Wed, 22 Jan 2020 09:12:19 -0800 Subject: [PATCH 6/8] Added test for monitor feedback --- .../test_azure_iothub_cli_extension.py | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/samples/asynctests/test_azure_iothub_cli_extension.py b/samples/asynctests/test_azure_iothub_cli_extension.py index a34fe5366..9b604e74a 100644 --- a/samples/asynctests/test_azure_iothub_cli_extension.py +++ b/samples/asynctests/test_azure_iothub_cli_extension.py @@ -66,12 +66,10 @@ def test_iothub_monitor_events(live_iothub_config): devices=device_ids ) -def test_iothub_monitor_feedback(live_iothub_config): - pytest.skip("Not yet implemented") - - -def test_iothub_c2d_message_send(live_iothub_config): +def test_iothub_c2d_message_send_and_monitor_feedback(live_iothub_config): try: + from azext_iot.operations.hub import iot_simulate_device + from azext_iot.common.utility import execute_onthread import azext_iot.operations.events3._events as events3 import azext_iot.operations.events3._builders as builders events3.DEBUG = False @@ -80,15 +78,31 @@ def test_iothub_c2d_message_send(live_iothub_config): pytest.skip("Only runs in IoT CLI env.") target = _get_iot_conn_str(live_iothub_config) + msg_id, errors = events3.send_c2d_message( target=target, device_id=live_iothub_config["device"], data="IoT CLI extension test", ack='full') - assert msg_id assert not errors + iot_simulate_device( + cmd=None, + device_id=live_iothub_config["device"], + hub_name=live_iothub_config["hub_name"], + receive_settle='complete', + data="IoT CLI extension test", + msg_count=5, + msg_interval=1, + protocol_type='http', + login=target['cs']) + + events3.monitor_feedback( + target=target, + device_id=live_iothub_config["device"], + wait_on_id=msg_id) + if __name__ == '__main__': try: From 6493bdd72e7a2c030cbfcd3092907be27bcd7938 Mon Sep 17 00:00:00 2001 From: annatisch Date: Mon, 27 Jan 2020 16:45:38 -0800 Subject: [PATCH 7/8] Output test durations in live tests --- .azure-pipelines/client.test.live.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.azure-pipelines/client.test.live.yml b/.azure-pipelines/client.test.live.yml index d5cc02872..1f478a3d2 100644 --- a/.azure-pipelines/client.test.live.yml +++ b/.azure-pipelines/client.test.live.yml @@ -84,8 +84,8 @@ jobs: - powershell: | $whlfile = Get-ChildItem -Filter *.whl dist | Select-Object -First 1 -ExpandProperty Name python -m pip install --ignore-installed ./dist/$whlfile - pytest tests --doctest-modules --junitxml=junit/test-results-c.xml - pytest samples --doctest-modules --junitxml=junit/test-results-live.xml + pytest tests --durations=0 --doctest-modules --junitxml=junit/test-results-c.xml + pytest samples --durations=0 --doctest-modules --junitxml=junit/test-results-live.xml displayName: 'Run tests' env: EVENT_HUB_HOSTNAME: $(python-eh-livetest-event-hub-hostname) @@ -207,8 +207,8 @@ jobs: - script: | $(PythonBin) -m pip install --user --ignore-installed ./dist/*.whl - pytest tests --doctest-modules --junitxml=junit/test-results-c.xml - pytest samples --doctest-modules --junitxml=junit/test-results-live.xml + pytest tests --durations=0 --doctest-modules --junitxml=junit/test-results-c.xml + pytest samples --durations=0 --doctest-modules --junitxml=junit/test-results-live.xml displayName: 'Run tests' env: EVENT_HUB_HOSTNAME: $(python-eh-livetest-event-hub-hostname) @@ -287,8 +287,8 @@ jobs: - script: | python -m pip install --user --ignore-installed ./dist/*.whl - pytest tests --doctest-modules --junitxml=junit/test-results-c.xml - pytest samples --doctest-modules --junitxml=junit/test-results-live.xml + pytest tests --durations=0 --doctest-modules --junitxml=junit/test-results-c.xml + pytest samples --durations=0 --doctest-modules --junitxml=junit/test-results-live.xml displayName: 'Run tests' env: EVENT_HUB_HOSTNAME: $(python-eh-livetest-event-hub-hostname) From cae3c7e0758b8f0baf7c5b4f6211535a114a79a9 Mon Sep 17 00:00:00 2001 From: annatisch Date: Thu, 14 May 2020 16:01:14 -0700 Subject: [PATCH 8/8] Removing feedback monitor --- samples/asynctests/test_azure_iothub_cli_extension.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/samples/asynctests/test_azure_iothub_cli_extension.py b/samples/asynctests/test_azure_iothub_cli_extension.py index 9b604e74a..a0dbd223c 100644 --- a/samples/asynctests/test_azure_iothub_cli_extension.py +++ b/samples/asynctests/test_azure_iothub_cli_extension.py @@ -98,10 +98,11 @@ def test_iothub_c2d_message_send_and_monitor_feedback(live_iothub_config): protocol_type='http', login=target['cs']) - events3.monitor_feedback( - target=target, - device_id=live_iothub_config["device"], - wait_on_id=msg_id) + # TODO: Skipping this for now as it takes 1+ hours sometimes + # events3.monitor_feedback( + # target=target, + # device_id=live_iothub_config["device"], + # wait_on_id=msg_id) if __name__ == '__main__': @@ -118,4 +119,4 @@ def test_iothub_c2d_message_send_and_monitor_feedback(live_iothub_config): except KeyError: pytest.skip("Live IoTHub configuration not found.") else: - test_iothub_monitor_events(config) \ No newline at end of file + test_iothub_monitor_events(config)