diff --git a/azext_iot/operations/hub.py b/azext_iot/operations/hub.py index 597bcf695..31e47fb09 100644 --- a/azext_iot/operations/hub.py +++ b/azext_iot/operations/hub.py @@ -398,11 +398,12 @@ def _parse_auth(parameters): def iot_device_module_list(cmd, device_id, hub_name=None, top=1000, resource_group_name=None, login=None): - query = "select * from devices.modules where devices.deviceId = '{}'".format(device_id) - result = iot_query(cmd, query, hub_name, top, resource_group_name, login=login) - if not result: - logger.info('No modules found on registered device "%s".', device_id) - return result + target = get_iot_hub_connection_string(cmd, hub_name, resource_group_name, login=login) + service_sdk, errors = _bind_sdk(target, SdkType.service_sdk) + try: + return service_sdk.get_modules_on_device(device_id)[:top] + except errors.CloudError as e: + raise CLIError(unpack_msrest_error(e)) def iot_device_module_show(cmd, device_id, module_id, hub_name=None, resource_group_name=None, login=None): @@ -507,7 +508,7 @@ def iot_edge_set_modules(cmd, device_id, content, hub_name=None, resource_group_ content = ConfigurationContent(modules_content=modules_content) service_sdk.apply_configuration_on_device(device_id, content) - return iot_device_module_list(cmd, device_id, hub_name=hub_name, top=-1, login=login) + return iot_device_module_list(cmd, device_id, hub_name=hub_name, login=login) except ValueError as j: raise CLIError('improperly formatted json: {}'.format(j)) except errors.CloudError as e: @@ -773,11 +774,12 @@ def iot_hub_configuration_metric_show(cmd, config_id, metric_id, metric_type='us # Device Twin def iot_device_twin_show(cmd, device_id, hub_name=None, resource_group_name=None, login=None): - query = "select * from devices where devices.deviceId='{}'".format(device_id) - result = iot_query(cmd, query, hub_name, None, resource_group_name, login=login) - if not result: - raise CLIError('No registered device "{}" found.'.format(device_id)) - return result[0] + target = get_iot_hub_connection_string(cmd, hub_name, resource_group_name, login=login) + service_sdk, errors = _bind_sdk(target, SdkType.service_sdk) + try: + return service_sdk.get_twin(device_id) + except errors.CloudError as e: + raise CLIError(unpack_msrest_error(e)) def iot_device_twin_update(cmd, device_id, parameters, hub_name=None, resource_group_name=None, login=None): diff --git a/azext_iot/tests/test_iot_ext_int.py b/azext_iot/tests/test_iot_ext_int.py index 17171161a..608ff5b90 100644 --- a/azext_iot/tests/test_iot_ext_int.py +++ b/azext_iot/tests/test_iot_ext_int.py @@ -629,7 +629,7 @@ def test_hub_modules(self): self.exists("[?moduleId=='$edgeHub']")]) self.cmd('iot hub module-identity list -d {} -n {} -g {} --top -1'.format(edge_device_ids[0], LIVE_HUB, LIVE_RG), - checks=[self.check('length([*])', 4), + checks=[self.check('length([*])', 3), self.exists("[?moduleId=='$edgeAgent']"), self.exists("[?moduleId=='$edgeHub']")]) @@ -1335,6 +1335,10 @@ def test_hub_monitor_events(self): self.command_execute_assert('iot hub monitor-events -n {} -g {} --cg {} --et {} -t 10 -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 diff --git a/azext_iot/tests/test_iot_ext_unit.py b/azext_iot/tests/test_iot_ext_unit.py index 58b4b8310..287c518db 100644 --- a/azext_iot/tests/test_iot_ext_unit.py +++ b/azext_iot/tests/test_iot_ext_unit.py @@ -654,8 +654,7 @@ def serviceclient(self, mocker, fixture_ghcs, fixture_sas, request): service_client.expected_size = size service_client.return_value = build_mock_response(mocker, request.param[0], - result, - {'x-ms-continuation': None}) + result) return service_client @pytest.mark.parametrize("top", [10, 1000]) @@ -664,20 +663,9 @@ def test_device_module_list(self, serviceclient, top): args = serviceclient.call_args url = args[0][0].url method = args[0][0].method - body = args[0][2] - headers = args[0][1] - - assert method == 'POST' - assert '{}/devices/query?'.format(mock_target['entity']) in url - assert body['query'] == "select * from devices.modules where devices.deviceId = '{}'".format(device_id) - assert json.dumps(result) + assert method == 'GET' + assert '{}/devices/{}/modules?'.format(mock_target['entity'], device_id) in url assert len(result) == serviceclient.expected_size - assert headers['x-ms-max-item-count'] == str(top) - - @pytest.mark.parametrize("top", [-2, 0]) - def test_device_module_list_invalid_args(self, serviceclient, top): - with pytest.raises(CLIError): - subject.iot_device_module_list(fixture_cmd, device_id, hub_name=mock_target['entity'], top=top) def test_device_module_list_error(self, serviceclient_generic_error): with pytest.raises(CLIError): @@ -1086,7 +1074,7 @@ class TestConfigApply(): def serviceclient(self, mocker, fixture_ghcs, fixture_sas, request): service_client = mocker.patch(path_service_client) service_client.side_effect = [build_mock_response(mocker), - build_mock_response(mocker, payload=[], headers={'x-ms-continuation': None})] + build_mock_response(mocker, payload=[])] return service_client @pytest.mark.parametrize("req", [ @@ -1116,9 +1104,11 @@ def test_config_apply(self, serviceclient, req): assert body == json.loads(req['content'])['content'] mod_list_args = serviceclient.call_args_list[1] - mod_list_body = mod_list_args[0][2] + url = mod_list_args[0][0].url + method = mod_list_args[0][0].method - assert mod_list_body['query'] == "select * from devices.modules where devices.deviceId = '{}'".format(device_id) + assert method == 'GET' + assert '{}/devices/{}/modules?'.format(mock_target['entity'], device_id) in url assert result is not None @pytest.mark.parametrize('req, arg', [ @@ -1158,16 +1148,18 @@ class TestDeviceTwinShow(): def serviceclient(self, mocker, fixture_ghcs, fixture_sas, request): service_client = mocker.patch(path_service_client) service_client.return_value = build_mock_response(mocker, request.param, - [generate_device_twin_show()], - {'x-ms-continuation': None}) + payload=generate_device_twin_show()) return service_client def test_device_twin_show(self, serviceclient): - result = subject.iot_device_twin_show(None, device_id, mock_target['entity']) + result = subject.iot_device_twin_show(fixture_cmd, device_id, mock_target['entity']) args = serviceclient.call_args - body = args[0][2] + url = args[0][0].url + method = args[0][0].method + assert json.dumps(result) - assert body['query'] == "select * from devices where devices.deviceId='{}'".format(device_id) + assert method == 'GET' + assert '{}/twins/{}?'.format(mock_target['entity'], device_id) in url def test_device_twin_show_error(self, serviceclient_generic_error): with pytest.raises(CLIError): @@ -2348,7 +2340,7 @@ def sc_distributed_tracing_show(self, mocker, fixture_ghcs, fixture_sas, request twin_kvp.setdefault('properties', {'desired': {TRACING_PROPERTY: {"sampling_mode": 1, "sampling_rate": 50}}, 'reported': {}}) test_side_effect = [ - build_mock_response(mocker, request.param[0], [generate_device_twin_show(**twin_kvp)], {'x-ms-continuation': None}) + build_mock_response(mocker, request.param[0], payload=generate_device_twin_show(**twin_kvp)) ] service_client.side_effect = test_side_effect return service_client @@ -2357,8 +2349,8 @@ def test_distributed_tracing_show(self, sc_distributed_tracing_show): result = subject.iot_hub_distributed_tracing_show(fixture_cmd, mock_target['entity'], device_id) args = sc_distributed_tracing_show.call_args url = args[0][0].url - assert '{}/devices/query?'.format(mock_target['entity']) in url - assert args[0][0].method == 'POST' + assert '{}/twins/{}?'.format(mock_target['entity'], device_id) in url + assert args[0][0].method == 'GET' assert result['deviceId'] == device_id assert result['samplingMode'] == 'enabled' assert result['samplingRate'] == '50%' @@ -2377,7 +2369,7 @@ def sc_invalid_args_distributed_tracing_show(self, mocker, fixture_ghcs, fixture if request.param[1] == 2: twin_kvp.setdefault('capabilities', {'iotEdge': True}) test_side_effect = [ - build_mock_response(mocker, request.param[0], [generate_device_twin_show(**twin_kvp)], {'x-ms-continuation': None}) + build_mock_response(mocker, request.param[0], payload=generate_device_twin_show(**twin_kvp)) ] service_client.side_effect = test_side_effect return service_client @@ -2410,7 +2402,7 @@ def sc_distributed_tracing_update(self, mocker, fixture_ghcs, fixture_sas, reque 'reported': {}}) test_side_effect = [ build_mock_response(mocker, request.param[0], - [generate_device_twin_show(**twin_kvp)], {'x-ms-continuation': None}), + payload=generate_device_twin_show(**twin_kvp)), build_mock_response(mocker, request.param[0], generate_device_twin_show(properties={'desired': {TRACING_PROPERTY: {"sampling_mode": 1, @@ -2444,7 +2436,7 @@ def sc_invalid_args_distributed_tracing_update(self, mocker, fixture_ghcs, fixtu if request.param[1] == 2: twin_kvp.setdefault('capabilities', {'iotEdge': True}) test_side_effect = [ - build_mock_response(mocker, request.param[0], [generate_device_twin_show(**twin_kvp)], {'x-ms-continuation': None}) + build_mock_response(mocker, request.param[0], payload=generate_device_twin_show(**twin_kvp)) ] service_client.side_effect = test_side_effect return service_client