def setUp(self): change_dir() if self._testMethodName == "test_interface_life_cycle": interface = str(read_file_content(_interface_payload)) _interface_id = "{}{}".format( json.loads(interface)["@id"], TestPnPModel.rand_val) self.kwargs.update({"interface_id": _interface_id}) interface_newContent = interface.replace( json.loads(interface)["@id"], self.kwargs["interface_id"]) interface_newContent = interface_newContent.replace("\n", "") fo = open(self.kwargs["interface"], "w+", encoding="utf-8") fo.write(interface_newContent) fo.close() if self._testMethodName == "test_model_life_cycle": model = str(read_file_content(_capability_model_payload)) _model_id = "{}{}".format( json.loads(model)["@id"], TestPnPModel.rand_val) self.kwargs.update({"model_id": _model_id}) model_newContent = model.replace( json.loads(model)["@id"], self.kwargs["model_id"]) model_newContent = model_newContent.replace("\n", "") fo = open(self.kwargs["model"], "w+", encoding="utf-8") fo.write(model_newContent) fo.close()
def sample_config_metrics(set_cwd, request): path = "test_config_generic_metrics.json" payload = None if request.param == "inlineA": payload = json.dumps(json.loads(read_file_content(path))) elif request.param == "inlineB": payload = json.dumps(json.loads(read_file_content(path))["metrics"]) elif request.param == "file": payload = get_context_path(__file__, path) return (request.param, payload)
def sample_config_adm(set_cwd, request): path_device = "test_adm_device_content.json" path_module = "test_adm_module_content.json" payload = None if request.param == "moduleFile": payload = get_context_path(__file__, path_module) elif request.param == "moduleInline": payload = json.dumps(json.loads(read_file_content(path_module))) elif request.param == "deviceFile": payload = get_context_path(__file__, path_device) elif request.param == "deviceInline": payload = json.dumps(json.loads(read_file_content(path_device))) return (request.param, payload)
def test_iot_digitaltwin_invoke_command(self, fixture_cmd, serviceclient, command_payload): payload = None interface = "environmentalSensor" command = "blink" # If file path provided if not command_payload[0]: payload = command_payload[1] else: payload = str( read_file_content(_device_digitaltwin_invoke_command_payload)) subject.iot_digitaltwin_invoke_command( fixture_cmd, device_id=device_id, interface=interface, command_name=command, command_payload=payload, login=mock_target["cs"], ) args = serviceclient.call_args url = args[0][0].url method = args[0][0].method assert method == "POST" assert ("{}/digitalTwins/{}/interfaces/{}/commands/{}?".format( mock_target["entity"], device_id, interface, command) in url)
def test_interface_create(self, fixture_cmd, serviceclient, payload_scenario): payload = None # If file path provided if not payload_scenario[0]: payload = payload_scenario[1] else: payload = str( read_file_content(_pnp_create_interface_payload_file)) subject.iot_pnp_interface_create(fixture_cmd, interface_definition=payload, login=mock_target["cs"]) args = serviceclient.call_args url = args[0][0].url method = args[0][0].method data = args[0][0].data headers = args[0][0].headers assert method == "PUT" assert ("{}/models/{}?".format( _repo_endpoint, url_encode_str(_pnp_generic_interface_id, plus=True)) in url) assert "repositoryId={}".format(_repo_id) in url assert json.dumps(data) assert headers.get("Authorization")
def iot_digitaltwin_property_update( cmd, interface_payload, device_id, hub_name=None, resource_group_name=None, login=None, ): if exists(interface_payload): interface_payload = str(read_file_content(interface_payload)) target_json = None try: target_json = shell_safe_json_parse(interface_payload) except ValueError: pass if target_json: interface_payload = target_json target = get_iot_hub_connection_string(cmd, hub_name, resource_group_name, login=login) service_sdk, errors = _bind_sdk(target, SdkType.service_sdk) try: result = service_sdk.update_interfaces(device_id, interfaces=interface_payload) return result except errors.CloudError as e: raise CLIError(unpack_msrest_error(e))
def test_config_create_adm( self, fixture_cmd, serviceclient, sample_config_adm, sample_config_metrics, config_id, hub_name, target_condition, priority, labels, ): contentKey = ( "moduleContent" if sample_config_adm[0].startswith("module") else "deviceContent" ) if contentKey == "moduleContent": # Enforce the query prefix for success the case target_condition = "FROM devices.modules WHERE {}".format(target_condition) subject.iot_hub_configuration_create( cmd=fixture_cmd, config_id=config_id, hub_name=hub_name, content=sample_config_adm[1], target_condition=target_condition, priority=priority, labels=labels, metrics=sample_config_metrics[1], ) args = serviceclient.call_args url = args[0][0].url method = args[0][0].method body = json.loads(args[0][0].body) assert "{}/configurations/{}?".format(hub_name, config_id.lower()) in url assert method == "PUT" assert body["id"] == config_id.lower() assert body.get("targetCondition") == target_condition assert body.get("priority") == priority assert body.get("labels") == evaluate_literal(labels, dict) if sample_config_adm[0].endswith("Inline"): assert ( body["content"][contentKey] == json.loads(sample_config_adm[1])["content"][contentKey] ) elif sample_config_adm[0].endswith("File"): assert ( body["content"][contentKey] == json.loads(read_file_content(sample_config_adm[1]))["content"][ contentKey ] ) self._assert_config_metrics_request(sample_config_metrics, body)
def test_config_create_edge( self, fixture_cmd, serviceclient, sample_config_edge, sample_config_metrics, config_id, hub_name, target_condition, priority, labels, ): subject.iot_edge_deployment_create( cmd=fixture_cmd, config_id=config_id, hub_name=hub_name, content=sample_config_edge[1], target_condition=target_condition, priority=priority, labels=labels, metrics=sample_config_metrics[1], layered=(sample_config_edge[0] == "layered"), ) args = serviceclient.call_args url = args[0][0].url method = args[0][0].method body = json.loads(args[0][0].body) assert "{}/configurations/{}?".format(hub_name, config_id.lower()) in url assert method == "PUT" assert body["id"] == config_id.lower() assert body.get("targetCondition") == target_condition assert body.get("priority") == priority assert body.get("labels") == evaluate_literal(labels, dict) if sample_config_edge[0] == "inlineB": assert ( body["content"]["modulesContent"] == json.loads(sample_config_edge[1])["modulesContent"] ) elif sample_config_edge[0] == "file": assert ( body["content"]["modulesContent"] == json.loads(read_file_content(sample_config_edge[1]))["content"][ "modulesContent" ] ) elif sample_config_edge[0] == "v1": assert ( body["content"]["modulesContent"] == json.loads(sample_config_edge[1])["content"]["moduleContent"] ) else: assert ( body["content"]["modulesContent"] == json.loads(sample_config_edge[1])["content"]["modulesContent"] ) self._assert_config_metrics_request(sample_config_metrics, body)
def iot_digitaltwin_invoke_command(cmd, interface, device_id, command_name, command_payload=None, timeout=10, hub_name=None, resource_group_name=None, login=None): device_interfaces = _iot_digitaltwin_interface_list(cmd, device_id, hub_name, resource_group_name, login) interface_list = _get_device_default_interface_dict(device_interfaces) target_interface = next((item for item in interface_list if item['name'] == interface), None) if not target_interface: raise CLIError('Target interface is not implemented by the device!') if command_payload: if exists(command_payload): command_payload = str(read_file_content(command_payload)) target_json = None try: target_json = shell_safe_json_parse(command_payload) except ValueError: pass if target_json or isinstance(target_json, bool): command_payload = target_json target = get_iot_hub_connection_string(cmd, hub_name, resource_group_name, login=login) service_sdk, errors = _bind_sdk(target, SdkType.service_sdk) try: result = service_sdk.invoke_interface_command(device_id, interface, command_name, command_payload, connect_timeout_in_seconds=timeout, response_timeout_in_seconds=timeout) return result except errors.CloudError as e: raise CLIError(unpack_msrest_error(e))
def test_iot_digitaltwin_property_update(self, fixture_cmd, serviceclient, payload_scenario): payload = None # If file path provided if not payload_scenario[0]: payload = payload_scenario[1] else: payload = str( read_file_content( _device_digitaltwin_property_update_payload_file)) subject.iot_digitaltwin_property_update( fixture_cmd, device_id=device_id, interface_payload=payload, login=mock_target["cs"], ) args = serviceclient.call_args url = args[0][0].url method = args[0][0].method assert method == "PATCH" assert ("{}/digitalTwins/{}/interfaces?".format( mock_target["entity"], device_id) in url)
def test_config_apply_edge( self, fixture_cmd, serviceclient, device_id, hub_name, sample_config_edge ): # Not yet supporting layered deployments if sample_config_edge[0] == "layered": return result = subject.iot_edge_set_modules( cmd=fixture_cmd, device_id=device_id, hub_name=mock_target["entity"], content=sample_config_edge[1], ) # For the actual apply configuration call args = serviceclient.call_args_list[0] url = args[0][0].url method = args[0][0].method body = json.loads(args[0][0].body) assert method == "POST" assert ( "{}/devices/{}/applyConfigurationContent?".format( mock_target["entity"], device_id ) in url ) if sample_config_edge[0] == "inlineB": assert ( body["modulesContent"] == json.loads(sample_config_edge[1])["modulesContent"] ) elif sample_config_edge[0] == "file": assert ( body["modulesContent"] == json.loads(read_file_content(sample_config_edge[1]))["content"][ "modulesContent" ] ) elif sample_config_edge[0] == "v1": assert ( body["modulesContent"] == json.loads(sample_config_edge[1])["content"]["moduleContent"] ) else: assert ( body["modulesContent"] == json.loads(sample_config_edge[1])["content"]["modulesContent"] ) # For returning the set of module identities applied to the device args = serviceclient.call_args_list[1] url = args[0][0].url method = args[0][0].method assert method == "GET" assert "{}/devices/{}/modules?".format(mock_target["entity"], device_id) in url assert result is not None
def test_model_create_invalid_payload(self, serviceclient): payload = str(read_file_content(_pnp_create_model_payload_file)) payload = json.loads(payload) del payload["@id"] payload = json.dumps(payload) with pytest.raises(CLIError): dataplane.iot_pnp_model_create(fixture_cmd, model=payload)
def generate_pnp_model_create_payload(content_from_file=False): if content_from_file: return (None, _pnp_create_model_payload_file) return ( str(read_file_content(_pnp_create_model_payload_file)), _pnp_create_model_payload_file, )
def sample_config_edge(set_cwd, request): path = "test_edge_deployment.json" layered_path = "test_edge_deployment_layered.json" v1_path = "test_edge_deployment_v1.json" v11_path = "test_edge_deployment_v11.json" ea_v11_eh_v12_path = "test_edge_deployment_ea_v11_eh_v12.json" ea_v90_eh_v91_path = "test_edge_deployment_ea_v90_eh_v91.json" payload = None if request.param == "inlineA": payload = json.dumps(json.loads(read_file_content(path))) elif request.param == "inlineB": payload = json.dumps(json.loads(read_file_content(path))["content"]) elif request.param == "file": payload = get_context_path(__file__, path) elif request.param == "layered": payload = json.dumps(json.loads(read_file_content(layered_path))) elif request.param == "v1": payload = json.dumps(json.loads(read_file_content(v1_path))) elif request.param == "v11": payload = json.dumps(json.loads(read_file_content(v11_path))) elif request.param == "ea_v11_eh_v12": payload = json.dumps(json.loads(read_file_content(ea_v11_eh_v12_path))) elif request.param == "ea_v90_eh_v91": payload = json.dumps(json.loads(read_file_content(ea_v90_eh_v91_path))) return (request.param, payload)
def generate_device_digitaltwin_invoke_command_payload(content_from_file=False): change_dir() if content_from_file: return (None, _device_digitaltwin_invoke_command_payload) return ( str(read_file_content(_device_digitaltwin_invoke_command_payload)), _device_digitaltwin_invoke_command_payload, )
def generate_device_digitaltwin_property_update_payload(content_from_file=False): change_dir() if content_from_file: return (None, _device_digitaltwin_property_update_payload_file) return ( str(read_file_content(_device_digitaltwin_property_update_payload_file)), _device_digitaltwin_property_update_payload_file, )
def generate_pnp_interface_create_payload(content_from_file=False): change_dir() if content_from_file: return (None, _pnp_create_interface_payload_file) return ( str(read_file_content(_pnp_create_interface_payload_file)), _pnp_create_interface_payload_file, )
def test_model_create_invalid_payload(self, serviceclient): payload = str(read_file_content(_pnp_create_model_payload_file)) payload = json.loads(payload) del payload["@id"] payload = json.dumps(payload) with pytest.raises(CLIError): subject.iot_pnp_model_create(fixture_cmd, login=mock_target["cs"], model_definition=payload)
def _assert_config_metrics_request(self, sample_config_metrics, body): if sample_config_metrics[0]: if sample_config_metrics[0] == "inlineA": assert (body["metrics"] == json.loads( sample_config_metrics[1])["metrics"]) elif sample_config_metrics[0] == "inlineB": assert body["metrics"] == json.loads(sample_config_metrics[1]) else: assert (body["metrics"] == json.loads( read_file_content(sample_config_metrics[1]))["metrics"]) else: assert body["metrics"] == {}
def test_model_update_invalid_payload(self, serviceclient): payload = str(read_file_content(_pnp_create_model_payload_file)) payload = json.loads(payload) payload["@id"] = "fake_invalid_id" payload = json.dumps(payload) with pytest.raises(CLIError): subject.iot_pnp_model_update( fixture_cmd, model_definition=payload, repo_endpoint=mock_target["entity"], repo_id=mock_target["repository_id"], )
def test_model_update_error(self, fixture_cmd, serviceclient_generic_error, payload_scenario): if not payload_scenario[0]: payload = payload_scenario[1] else: payload = str(read_file_content(_pnp_create_model_payload_file)) with pytest.raises(CLIError): subject.iot_pnp_model_update( fixture_cmd, model_definition=payload, repo_endpoint=mock_target["entity"], repo_id=mock_target["repository_id"], )
def test_model_create_error(self, fixture_cmd, serviceclient_generic_error, content_from_file): payload = None payload_scenario = generate_pnp_model_create_payload(content_from_file) if not payload_scenario[0]: payload = payload_scenario[1] payload = str(read_file_content(_pnp_create_model_payload_file)) payload = json.loads(payload) del payload["@id"] payload = json.dumps(payload) with pytest.raises(CLIError): dataplane.iot_pnp_model_create( fixture_cmd, model=payload, )
def test_iot_digitaltwin_property_update_error( self, fixture_cmd, serviceclient_error, command_payload, interface, command ): 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"], )
def _validate_model_definition(model_def): if exists(model_def): model_def = str(read_file_content(model_def)) else: logger.info('Definition not from file path or incorrect path given.') try: return shell_safe_json_parse(model_def) except ValueError as e: logger.debug('Received definition: %s', model_def) if looks_like_file(model_def): raise CLIError( 'The definition content looks like its from a file. Please ensure the path is correct.' ) raise CLIError( 'Malformed capability model definition. ' 'Use --debug to see what was received. Error details: {}'.format( e))
def test_edge_set_modules(self): edge_device_count = 1 edge_device_ids = self.generate_device_names(edge_device_count, True) self.cmd( "iot hub device-identity create -d {} -n {} -g {} --ee".format( edge_device_ids[0], LIVE_HUB, LIVE_RG ) ) self.kwargs["edge_content"] = read_file_content(edge_content_path) # Content from file self.cmd( "iot edge set-modules -d {} -n {} -g {} -k '{}'".format( edge_device_ids[0], LIVE_HUB, LIVE_RG, edge_content_path ), checks=[self.check("length([*])", 3)], ) # Content inline self.cmd( "iot edge set-modules -d {} -n {} -g {} --content '{}'".format( edge_device_ids[0], LIVE_HUB, LIVE_RG, "{edge_content}" ), self.check("length([*])", 3), ) # Using connection string - content from file self.cmd( "iot edge set-modules -d {} --login {} -k '{}'".format( edge_device_ids[0], self.connection_string, edge_content_v1_path ), checks=[self.check("length([*])", 4)], ) # Error schema validation - Malformed deployment self.cmd( "iot edge set-modules -d {} -n {} -g {} -k '{}'".format( edge_device_ids[0], LIVE_HUB, LIVE_RG, edge_content_malformed_path ), expect_failure=True, )
def _process_models_directory(from_directory): from azext_iot.common.utility import scantree, process_json_arg, read_file_content # we need to double-encode the JSON string from json import dumps models = [] if os.path.isfile(from_directory) and (from_directory.endswith(".json") or from_directory.endswith(".dtdl")): models.append(dumps(read_file_content(file_path=from_directory))) return models for entry in scantree(from_directory): if not any([entry.name.endswith(".json"), entry.name.endswith(".dtdl")]): logger.debug( "Skipping {} - model file must end with .json or .dtdl".format( entry.path ) ) continue entry_json = process_json_arg(content=entry.path, argument_name=entry.name) models.append(dumps(entry_json)) return models
def setUp(self): if self._testMethodName == "test_model_lifecycle": roles = self.cmd( "iot pnp role-assignment list --resource-id {repo_id} --resource-type Tenant --subject-id {user_id} " "--pnp-dns-suffix {pnp_dns_suffix}") # check for TenantAdministrator try: roles = roles.get_output_in_json() role_assignments = list( map(lambda role: role["subject"]["role"], roles)) if RoleIdentifier.tenantAdmin.value not in role_assignments: self.skipTest("Need TenantAdmin role to perform tests") except CLIError as e: self.skipTest(e) # Assign roles for model test self.cmd( "iot pnp role-assignment create --resource-id {repo_id} --resource-type Tenant --subject-id {user_id} " "--subject-type {user_type} --role ModelsCreator --pnp-dns-suffix {pnp_dns_suffix}" ) self.cmd( "iot pnp role-assignment create --resource-id {repo_id} --resource-type Tenant --subject-id {user_id} " "--subject-type {user_type} --role ModelsPublisher --pnp-dns-suffix {pnp_dns_suffix}" ) # Generate model ID model = str(read_file_content(_capability_model_payload)) _model_id = self._generate_model_id(json.loads(model)["@id"]) self.kwargs.update({"model_id": _model_id}) model_newContent = model.replace( json.loads(model)["@id"], self.kwargs["model_id"]) model_newContent = model_newContent.replace("\n", "") fo = open(self.kwargs["model"], "w+", encoding="utf-8") fo.write(model_newContent) fo.close()
def test_model_create(self, fixture_cmd, serviceclient, content_from_file, set_cwd): payload = None payload_scenario = generate_pnp_model_create_payload(content_from_file) # If file path provided if not payload_scenario[0]: payload = payload_scenario[1] payload = str(read_file_content(_pnp_create_model_payload_file)) model_id = json.loads(payload)["@id"] dataplane.iot_pnp_model_create( cmd=fixture_cmd, model=payload, ) args = serviceclient.call_args url = args[0][0].url method = args[0][0].method data = args[0][0].data assert method == "PUT" assert "/models/{}?".format(url_encode_str(model_id, plus=True)) in url assert json.dumps(data)
def test_file_json(self, content, argname, set_cwd): result = process_json_arg(content, argument_name=argname) assert result == json.loads(read_file_content(content))
def test_edge_deployments(self): config_count = 5 config_ids = self.generate_config_names(config_count) self.kwargs["generic_metrics"] = read_file_content(generic_metrics_path) self.kwargs["edge_content"] = read_file_content(edge_content_path) self.kwargs["edge_content_layered"] = read_file_content( edge_content_layered_path ) self.kwargs["edge_content_v1"] = read_file_content(edge_content_v1_path) self.kwargs["edge_content_malformed"] = read_file_content( edge_content_malformed_path ) self.kwargs["labels"] = '{"key0": "value0"}' priority = random.randint(1, 10) condition = "tags.building=9 and tags.environment='test'" # Content inline # Note: $schema is included as a nested property in the sample content. self.cmd( """iot edge deployment create --deployment-id {} --hub-name {} --resource-group {} --priority {} --target-condition \"{}\" --labels '{}' --content '{}'""".format( config_ids[0], LIVE_HUB, LIVE_RG, priority, condition, "{labels}", "{edge_content}", ), checks=[ self.check("id", config_ids[0]), self.check("priority", priority), self.check("targetCondition", condition), self.check("labels", json.loads(self.kwargs["labels"])), self.check( "content.modulesContent", json.loads(self.kwargs["edge_content"])["content"][ "modulesContent" ], ), self.check("metrics.queries", {}), ], ) # Using connection string - content + metrics from file. Configurations must be lowercase and will be lower()'ed. # Note: $schema is included as a nested property in the sample content. self.cmd( "iot edge deployment create -d {} --login {} --pri {} --tc \"{}\" --lab '{}' -k '{}' --metrics '{}'".format( config_ids[1].upper(), self.connection_string, priority, condition, "{labels}", edge_content_path, edge_content_path, ), checks=[ self.check("id", config_ids[1].lower()), self.check("priority", priority), self.check("targetCondition", condition), self.check("labels", json.loads(self.kwargs["labels"])), self.check( "content.modulesContent", json.loads(self.kwargs["edge_content"])["content"][ "modulesContent" ], ), self.check( "metrics.queries", json.loads(self.kwargs["edge_content"])["metrics"]["queries"], ), ], ) # Using connection string - layered deployment with content + metrics from file. # No labels, target-condition or priority self.cmd( "iot edge deployment create -d {} --login {} -k '{}' --metrics '{}' --layered".format( config_ids[2].upper(), self.connection_string, edge_content_layered_path, generic_metrics_path, ), checks=[ self.check("id", config_ids[2].lower()), self.check("priority", 0), self.check("targetCondition", ""), self.check("labels", None), self.check( "content.modulesContent", json.loads(self.kwargs["edge_content_layered"])["content"][ "modulesContent" ], ), self.check( "metrics.queries", json.loads(self.kwargs["generic_metrics"])["metrics"]["queries"], ), ], ) # Content inline - Edge v1 format self.cmd( """iot edge deployment create --deployment-id {} --hub-name {} --resource-group {} --priority {} --target-condition \"{}\" --labels '{}' --content '{}' --metrics '{}'""".format( config_ids[3], LIVE_HUB, LIVE_RG, priority, condition, "{labels}", "{edge_content_v1}", "{generic_metrics}", ), checks=[ self.check("id", config_ids[3]), self.check("priority", priority), self.check("targetCondition", condition), self.check("labels", json.loads(self.kwargs["labels"])), self.check( "content.modulesContent", json.loads(self.kwargs["edge_content_v1"])["content"][ "moduleContent" ], ), self.check( "metrics.queries", json.loads(self.kwargs["generic_metrics"])["metrics"]["queries"], ), ], ) # Error schema validation - Malformed deployment content causes validation error self.cmd( """iot edge deployment create --deployment-id {} --hub-name {} --resource-group {} --priority {} --target-condition \"{}\" --labels '{}' --content '{}'""".format( config_ids[1], LIVE_HUB, LIVE_RG, priority, condition, "{labels}", "{edge_content_malformed}", ), expect_failure=True, ) # Error schema validation - Layered deployment without flag causes validation error self.cmd( """iot edge deployment create --deployment-id {} --hub-name {} --resource-group {} --priority {} --target-condition \"{}\" --labels '{}' --content '{}'""".format( config_ids[1], LIVE_HUB, LIVE_RG, priority, condition, "{labels}", "{edge_content_layered}", ), expect_failure=True, ) # Uses IoT Edge hub schema version 1.1 self.cmd( """iot edge deployment create --deployment-id {} --hub-name {} --resource-group {} --priority {} --target-condition \"{}\" --labels '{}' --content '{}'""".format( config_ids[4], LIVE_HUB, LIVE_RG, priority, condition, "{labels}", edge_content_v11_path, ), checks=[ self.check("id", config_ids[4]), self.check("priority", priority), self.check("targetCondition", condition), self.check("labels", json.loads(self.kwargs["labels"])), self.check( "content.modulesContent", json.loads(read_file_content(edge_content_v11_path))["modulesContent"], ), self.check("metrics.queries", {}), ], ) # Show deployment self.cmd( "iot edge deployment show --deployment-id {} --hub-name {} --resource-group {}".format( config_ids[0], LIVE_HUB, LIVE_RG ), checks=[ self.check("id", config_ids[0]), self.check("priority", priority), self.check("targetCondition", condition), self.check("labels", json.loads(self.kwargs["labels"])), ], ) # Show deployment - using connection string self.cmd( "iot edge deployment show -d {} --login {}".format( config_ids[1], self.connection_string ), checks=[ self.check("id", config_ids[1]), self.check("priority", priority), self.check("targetCondition", condition), self.check("labels", json.loads(self.kwargs["labels"])), ], ) # Update deployment new_priority = random.randint(1, 10) new_condition = "tags.building=43 and tags.environment='dev'" self.kwargs["new_labels"] = '{"key": "super_value"}' self.cmd( "iot edge deployment update -d {} -n {} -g {} --set priority={} targetCondition=\"{}\" labels='{}'".format( config_ids[0], LIVE_HUB, LIVE_RG, new_priority, new_condition, "{new_labels}", ), checks=[ self.check("id", config_ids[0]), self.check("priority", new_priority), self.check("targetCondition", new_condition), self.check("labels", json.loads(self.kwargs["new_labels"])), ], ) # Update deployment - using connection string new_priority = random.randint(1, 10) new_condition = "tags.building=40 and tags.environment='kindaprod'" self.kwargs["new_labels"] = '{"key": "legit_value"}' self.cmd( "iot edge deployment update -d {} -n {} -g {} --set priority={} targetCondition=\"{}\" labels='{}'".format( config_ids[0], LIVE_HUB, LIVE_RG, new_priority, new_condition, "{new_labels}", ), checks=[ self.check("id", config_ids[0]), self.check("priority", new_priority), self.check("targetCondition", new_condition), self.check("labels", json.loads(self.kwargs["new_labels"])), ], ) # Evaluate metrics of a deployment user_metric_name = "mymetric" system_metric_name = "appliedCount" config_output = self.cmd( "iot edge deployment show --login {} --deployment-id {}".format( self.connection_string, config_ids[1] ) ).get_output_in_json() # Default metric type is user self.cmd( "iot edge deployment show-metric --metric-id {} --deployment-id {} --hub-name {}".format( user_metric_name, config_ids[1], LIVE_HUB ), checks=[ self.check("metric", user_metric_name), self.check( "query", config_output["metrics"]["queries"][user_metric_name] ), ], ) # System metric - using connection string self.cmd( "iot edge deployment show-metric --metric-id {} --login '{}' --deployment-id {} --metric-type {}".format( system_metric_name, self.connection_string, config_ids[1], "system" ), checks=[ self.check("metric", system_metric_name), self.check( "query", config_output["systemMetrics"]["queries"][system_metric_name], ), ], ) # Error - metric does not exist, using connection string self.cmd( "iot edge deployment show-metric -m {} --login {} -d {}".format( "doesnotexist", self.connection_string, config_ids[0] ), expect_failure=True, ) config_list_check = [ self.check("length([*])", config_count), self.exists("[?id=='{}']".format(config_ids[0])), self.exists("[?id=='{}']".format(config_ids[1])), self.exists("[?id=='{}']".format(config_ids[2])), self.exists("[?id=='{}']".format(config_ids[3])) ] # List all edge deployments self.cmd( "iot edge deployment list -n {} -g {}".format(LIVE_HUB, LIVE_RG), checks=config_list_check, ) # List all edge deployments - using connection string self.cmd( "iot edge deployment list --login {}".format(self.connection_string), checks=config_list_check, ) # Explicitly delete an edge deployment self.cmd( "iot edge deployment delete -d {} -n {} -g {}".format( config_ids[0], LIVE_HUB, LIVE_RG ) ) del self.config_ids[0] # Explicitly delete an edge deployment - using connection string self.cmd( "iot edge deployment delete -d {} --login {}".format( config_ids[1], self.connection_string ) ) del self.config_ids[0]