def test_introspection_operation_get(self): ctx = ExecutionContext() input_val = StructValue(OPERATION_INPUT) input_val.set_field('service_id', StringValue('mockup_interface')) input_val.set_field('operation_id', StringValue('mock')) actual_output = self.local_provider.invoke( 'com.vmware.vapi.std.introspection.operation', 'get', input_val, ctx) expected_output = StructValue( name='com.vmware.vapi.std.introspection.operation.info') input_def_value = StructValue( 'com.vmware.vapi.std.introspection.operation.data_definition') input_def_value.set_field('fields', OptionalValue(ListValue(values=[]))) input_def_value.set_field('element_definition', OptionalValue()) input_def_value.set_field('type', StringValue('STRUCTURE')) input_def_value.set_field('name', OptionalValue(StringValue(OPERATION_INPUT))) expected_output.set_field('input_definition', input_def_value) output_def_value = StructValue( 'com.vmware.vapi.std.introspection.operation.data_definition') output_def_value.set_field('fields', OptionalValue()) output_def_value.set_field('element_definition', OptionalValue()) output_def_value.set_field('type', StringValue('VOID')) output_def_value.set_field('name', OptionalValue()) expected_output.set_field('output_definition', output_def_value) expected_output.set_field('error_definitions', error_values) self.assertEqual(actual_output.output, expected_output)
def test_query_params_optionals(self): input_val = StructValue(name='operation-input', values={ 'string_val': StringValue('string1'), 'action1_val': OptionalValue(value=StringValue('start')), 'action2_val': OptionalValue() }) rest_metadata = OperationRestMetadata(http_method='POST', url_template='/foo/bar', query_parameters={ 'action1_val': 'action1', 'action2_val': 'action2' }) url_path, actual_headers, actual_body, _ = RestSerializer.serialize_request( input_value=input_val, ctx=None, rest_metadata=rest_metadata, is_vapi_rest=True) expected_url_path = '/foo/bar?action1=start' expected_headers = {} expected_body = '{"string_val":"string1"}' self.assertEqual(expected_url_path, url_path) self.assertEqual(expected_headers, actual_headers) self.assertEqual(expected_body, actual_body)
def test_all_annotations(self): input_val = StructValue(name='operation-input', values={ 'spec_val': StructValue(name='spec', values={ 'string_val': StringValue('string1'), }), 'string_val_url': StringValue('string2'), 'action_val': StringValue('stop'), }) rest_metadata = OperationRestMetadata( http_method='POST', url_template='/foo/{stringValUrl}', request_body_parameter='spec_val', path_variables={'string_val_url': 'stringValUrl'}, query_parameters={'action_val': 'action'}) url_path, actual_headers, actual_body, _ = RestSerializer.serialize_request( input_value=input_val, ctx=None, rest_metadata=rest_metadata, is_vapi_rest=True) expected_url_path = '/foo/string2?action=stop' expected_headers = {} expected_body = '{"string_val":"string1"}' self.assertEqual(expected_url_path, url_path) self.assertEqual(expected_headers, actual_headers) self.assertEqual(expected_body, actual_body)
def test_list(self): input_val = '["val1","val2"]' expected_val = ListValue( values=[StringValue('val1'), StringValue('val2')]) actual_val = DataValueConverter.convert_to_data_value(input_val) self.assertEqual(expected_val, actual_val)
def test_struct_ref_to_value(self): actual_output = convert_data_def_to_data_value( StructRefDefinition('mock')) expected_output = StructValue(Introspection.DATA_DEFINITION) expected_output.set_field('type', StringValue('STRUCTURE_REF')) expected_output.set_field('fields', OptionalValue()) expected_output.set_field('name', OptionalValue(StringValue('mock'))) expected_output.set_field('element_definition', OptionalValue()) self.assertEqual(actual_output, expected_output)
def test_list_value(self): input_val = ListValue( values=[StringValue('val1'), StringValue('val2')]) actual_val = DataValueConverter.convert_to_json(input_val) expected_val = '["val1","val2"]' self.assertEqual(expected_val, actual_val) # Verify json is valid json.loads(actual_val)
def create_task(self, description, service_id, operation_id, cancelable, error_types, id_=None): """ Creates a task in task manager. :type description: :class:`com.vmware.vapi.std.LocalizableMessage` :param description: Task description. :type service_id: :class:`str` :param service_id: Service Id. :type operation_id: :class:`str` :param operation_id: Operation Id. :type cancelable: :class:`bool` :param cancelable: Is the task cancelable. :type error_types: :class:`list` of :class:`vmware.vapi.bindings.type.ReferenceType` :param error_types: Error definitions describing the errors this operation can report :type id_: :class:`str` :param id_: Base task id """ task_info = StructValue() if description is not None: task_info.set_field( 'description', TypeConverter.convert_to_vapi( description, LocalizableMessage.get_binding_type())) else: desc_value = StructValue() desc_value.set_field('id', StringValue()) desc_value.set_field('default_message', StringValue()) desc_value.set_field('args', ListValue()) task_info.set_field('description', desc_value) user = self._get_user_from_sec_ctx() if user is not None: task_info.set_field('user', StringValue(user)) task_info.set_field('service', StringValue(service_id)) task_info.set_field('operation', StringValue(operation_id)) task_info.set_field('cancelable', BooleanValue(True if cancelable else False)) task_info.set_field('status', PENDING_STRING_VALUE) base_id = id_ if id_ is not None else str(uuid.uuid4()) task_id = self._create_task_id(base_id, service_id) task_summary = TaskSummary(task_info, error_types) with self.lock: self.task_map.setdefault(task_id, task_summary) self._remove_expired_task() return task_id
def test_struct_value_with_optional_set(self): input_val = StructValue(name='name', values={ 'val1': StringValue('val1'), 'val2': OptionalValue(StringValue('val2')) }) actual_val = DataValueConverter.convert_to_json(input_val) self.assertTrue('"val1":"val1"' in actual_val) self.assertTrue('"val2":"val2"' in actual_val) # Verify json is valid json.loads(actual_val)
def test_error_value(self): input_val = ErrorValue(name='name', values={ 'val1': StringValue('val1'), 'val2': StringValue('val2') }) actual_val = DataValueConverter.convert_to_json(input_val) self.assertTrue('"val1":"val1"' in actual_val) self.assertTrue('"val2":"val2"' in actual_val) # Verify json is valid json.loads(actual_val)
def test_create_task_no_desc(self): service_uuid = str(uuid.uuid4()) task_id = self.task_manager.create_task(service_uuid, None, 'test.service1', 'op', False) info = self.task_manager.get_info(task_id) self.assertIn(service_uuid, task_id) self.assertEqual(info.get_field('service'), StringValue('test.service1')) self.assertEqual(info.get_field('operation'), StringValue('op')) self.assertEqual(info.get_field('cancelable'), BooleanValue(False)) self.assertEqual(info.get_field('status'), StringValue('PENDING'))
def test_invoke_long_running_sync(self): ctx = ExecutionContext() input_ = StructValue(method_name) input_.set_field('message', StringValue('hello')) input_.set_field('throw', BooleanValue(False)) actual_method_result = self.provider.invoke(interface_name, task_method_name, input_, ctx) expected_method_result = MethodResult(output=StringValue('hello')) self.assertEqual(actual_method_result.output, expected_method_result.output) self.assertEqual(actual_method_result.error, expected_method_result.error)
def test_struct_value(self): input_status = 200 input_response = '{"id":"vm-100", "name":"Linux VM"}' expected_result = MethodResult(output=StructValue( values={ 'id': StringValue('vm-100'), 'name': StringValue('Linux VM') })) actual_result = RestSerializer.deserialize_response( status=input_status, response_str=input_response, is_vapi_rest=False) self.assertEqual(expected_result.output, actual_result.output) self.assertEqual(expected_result.error, actual_result.error)
def create_task(self, provider_id, description, service_id, operation_id, cancelable, id_=None): """ Creates a task in task manager. :type provider_id: :class:`str` :param provider_id: Service UUID :type description: :class:`com.vmware.vapi.std.LocalizableMessage` :param description: Task description. :type service_id: :class:`str` :param service_id: Service Id. :type operation_id: :class:`str` :param operation_id: Operation Id. :type cancelable: :class:`bool` :param cancelable: Is the task cancelable. :type id_: :class:`str` :param id_: Base task id """ task_info = StructValue() if description is not None: task_info.set_field( 'description', TypeConverter.convert_to_vapi( description, LocalizableMessage.get_binding_type())) else: desc_value = StructValue() desc_value.set_field('id', StringValue()) desc_value.set_field('default_message', StringValue()) desc_value.set_field('args', ListValue()) task_info.set_field('description', desc_value) task_info.set_field('service', StringValue(service_id)) task_info.set_field('operation', StringValue(operation_id)) task_info.set_field('cancelable', BooleanValue(True if cancelable else False)) task_info.set_field('status', StringValue('PENDING')) base_id = id_ if id_ is not None else str(uuid.uuid4()) task_id = self._create_task_id(base_id, provider_id) with self.lock: self.task_map.setdefault(task_id, task_info) self._remove_expired_task() return task_id
def test_error_to_value(self): struct_def = ErrorDefinition('mock', [('field1', StringDefinition())]) actual_output = convert_data_def_to_data_value(struct_def) expected_output = StructValue(Introspection.DATA_DEFINITION) expected_output.set_field('type', StringValue('ERROR')) expected_output.set_field('name', OptionalValue(StringValue('mock'))) expected_output.set_field('element_definition', OptionalValue()) field_value = self.generate_primitive_value('STRING') field_entry = StructValue(MAP_ENTRY) field_entry.set_field('key', StringValue('field1')) field_entry.set_field('value', field_value) field_values = ListValue() field_values.add(field_entry) expected_output.set_field('fields', OptionalValue(field_values)) self.assertEqual(actual_output, expected_output)
def _parse_fail(self, dt_str): dt_str = StringValue(dt_str) self.assertRaises(CoreException, TypeConverter.convert_to_python, dt_str, self.typ, rest_converter_mode=RestConverter.SWAGGER_REST)
def test_create_task(self): service_uuid = str(uuid.uuid4()) task_id = self.task_manager.create_task(service_uuid, self.description, 'test.service1', 'op', False) info = self.task_manager.get_info(task_id) self.assertIn(service_uuid, task_id) self.assertEqual(info.get_field('description'), TypeConverter.convert_to_vapi(self.description, LocalizableMessage.get_binding_type())) self.assertEqual(info.get_field('service'), StringValue('test.service1')) self.assertEqual(info.get_field('operation'), StringValue('op')) self.assertEqual(info.get_field('cancelable'), BooleanValue(False)) self.assertEqual(info.get_field('status'), StringValue('PENDING'))
def test_set_info(self): service_uuid = str(uuid.uuid4()) task_id = self.task_manager.create_task(service_uuid, None, 'test.service', 'op', False) info_val = self.task_manager.get_info(task_id) info = TypeConverter.convert_to_python(info_val, Info.get_binding_type()) info.description = self.description progress = Progress() progress.total = 100 progress.completed = 10 progress.message = self.progress_msg info.progress = progress info.start_time = datetime.utcnow() info.status = Status.RUNNING info.cancelable = True self.task_manager.set_info(task_id, TypeConverter.convert_to_vapi(info, Info.get_binding_type())) result = self.task_manager.get_info(task_id) self.assertEqual(result.get_field('progress'), OptionalValue(TypeConverter.convert_to_vapi(progress, Progress.get_binding_type()))) self.assertEqual(result.get_field('cancelable'), BooleanValue(info.cancelable)) self.assertEqual(result.get_field('status'), StringValue('RUNNING'))
def get_data_values(self): # Data values list_value = ListValue() list_value.add_all([IntegerValue(val) for val in range(1,15)]) data_values = [ VoidValue(), IntegerValue(3), DoubleValue(decimal.Decimal('7.2')), StringValue('blah'), SecretValue(), BooleanValue(True), BlobValue(b"a blob"), BlobValue(b"0\x82\x04\x00"), list_value, OptionalValue(), OptionalValue(IntegerValue(7)), StructValue('name'), self.get_struct_value(), self.get_error_value(), ] struct_value = StructValue('struct') for idx, data_val in enumerate(data_values): struct_value.set_field(str(idx), data_val) data_values.append(struct_value) return data_values
def generate_primitive_value(self, typ): output = StructValue(Introspection.DATA_DEFINITION) output.set_field('type', StringValue(typ)) output.set_field('fields', OptionalValue()) output.set_field('name', OptionalValue()) output.set_field('element_definition', OptionalValue()) return output
def test_string_value(self): input_val = StringValue('val1') actual_val = DataValueConverter.convert_to_json(input_val) expected_val = '"val1"' self.assertEqual(expected_val, actual_val) # Verify json is valid json.loads(actual_val)
def validate(self, data_value, data_type=None): """ Validates a struct value for union consistency :type data_value :class:`vmware.vapi.data.value.DataValue` :param data_value The struct value that needs to be validated :type data_type :class:`vmware.vapi.binding.type.BindingType` :param data_type The Struct binding type :type ctx: :class:`vmware.vapi.core.ExecutionContext` :param ctx: Execution context for this method :rtype: :class:`list` of :class:`vmware.vapi.message.Message` or ``None`` :return List of error messages if validation fails or None """ assert(isinstance(data_value, StructValue)) discriminant = None if data_value.has_field(self._discriminant_name): # Checking if discriminant is present discriminant = data_value.get_field(self._discriminant_name) if isinstance(discriminant, OptionalValue): discriminant = discriminant.value case = None if discriminant: # Discriminant is present. Find the associated case value assert(isinstance(discriminant, StringValue)) for case_ in six.iterkeys(self._case_map): if discriminant == StringValue(case_): case = case_ break
def test_publish(self): info = self.task_handle.get_info() progress = Progress() progress.total = 100 progress.completed = 42 progress.message = self.progress_msg desc2 = LocalizableMessage(id='msg2', default_message='task1', args=[]) info.description = desc2 info.cancelable = False info.status = 'RUNNING' info.start_time = datetime.utcnow() info.progress = progress self.task_handle.publish() result = self.task_manager.get_info(self.task_id) self.assertEqual(result.get_field('status'), StringValue('RUNNING')) progress_val = StructValue('com.vmware.cis.task.progress') progress_val.set_field('total', IntegerValue(100)) progress_val.set_field('completed', IntegerValue(42)) progress_val.set_field( 'message', TypeConverter.convert_to_vapi( self.progress_msg, LocalizableMessage.get_binding_type())) self.assertEqual(result.get_field('progress'), OptionalValue(progress_val)) self.assertEqual(result.get_field('cancelable'), BooleanValue(False))
def set_info(self, task_id, info): """ Set task info. :type task_id: :class:`str` :param task_id: Task Id. :type status: :class:`vmware.vapi.data.value.StructValue` :param status: Task Info. """ self.task_map[task_id] = info if info.get_field('status') in [ StringValue('SUCCEEDED'), StringValue('FAILED') ]: with self.lock: self.tasks_to_remove.append((task_id, datetime.utcnow()))
def _verify_correct(self, dt_str, dt): dt_str = StringValue(dt_str) self.assertEqual( TypeConverter.convert_to_python( dt_str, self.typ, rest_converter_mode=RestConverter.SWAGGER_REST), dt)
def test_check_for_unknown_fields_invalid_1(self): struct_type = StructType( 'test', { 'name': StringType() } ) struct_value = StructValue( name='test', values={ 'name': StringValue('hello'), 'address': StringValue('hello') } ) self.assertIsNotNone( ApiInterfaceSkeleton.check_for_unknown_fields( struct_type, struct_value))
def _get(self, method_def, ctx, input_value): """ Returns information about the vAPI provider :type method_def: :class:`vmware.vapi.core.MethodDefinition` :param method_def: Method definition :type ctx: :class:`vmware.vapi.core.ExecutionContext` :param ctx: Execution context :type input_value: :class:`vmware.vapi.data.value.StructValue` :param input_value: Struct value input :rtype: :class:`vmware.vapi.core.MethodResult` :return: Information about the vAPI provider """ output = method_def.get_output_definition().new_value() output.set_field('id', StringValue(self._name)) output.set_field('checksum', StringValue(self._adapter.get_checksum())) return MethodResult(output=output)
def _execute_int(self, interposer_id, interposer_type, ctx, service_name, operation_name, opeartion_input): """ Execute an interposer :type interposer_id: :class:`str` :param interposer_id: Interposer id :type interposer_type: :class:`InterposerType` :param interposer_type: Interposer type :type ctx: :class:`vmware.vapi.core.ExecutionContext` :param ctx: Execution context for the invocation :type service_name: :class:`str` :param service_name: Name of the service that is being interposed :type operation_name: :class:`str` :param operation_name: Name of the operation that is being interposed :type opeartion_input: :class:`vmware.vapi.data.value.DataValue` :param opeartion_input: Input for the operation that is being interposed :rtype: :class:`vmware.vapi.data.value.ErrorValue` :return: Error is returned if the veto interposer execution reported an error, else None """ in_method_def = self._interposer_def.get(interposer_id) if in_method_def: interposer_input = in_method_def.get_input_definition().new_value() interposer_input.set_field(SERVICE_NAME, StringValue(service_name)) interposer_input.set_field(OPERATION_NAME, StringValue(operation_name)) interposer_input.set_field(OPERATION_INPUT, opeartion_input) in_method_id = in_method_def.get_identifier() method_result = ApiProviderFilter.invoke( self, in_method_id.get_interface_identifier().get_name(), in_method_id.get_name(), interposer_input, ctx) # Only veto interposers can break the control flow if interposer_type == InterposerType.VETO and \ not method_result.success(): return method_result.error
def test_error_value_as_data_value(self): ev = make_error_value_from_msgs(self.error_def, *self.multiple_messages) self.assertTrue(isinstance(ev, StructValue)) self.assertEqual(self.error_name, ev.name) self.assertFalse(ev.get_field_names() is None) self.assertEqual(2, len(ev.get_field_names())) self.assertTrue('messages' in ev.get_field_names()) msg_struct1 = StructValue('localizable_message') msg_struct1.set_field('id', StringValue(self.message1.id)) msg_struct1.set_field('default_message', StringValue(self.message1.def_msg)) args_list = ListValue() args_list.add_all((StringValue(s) for s in self.message1.args)) msg_struct1.set_field('args', args_list) msg_struct2 = StructValue('localizable_message') msg_struct2.set_field('id', StringValue(self.message2.id)) msg_struct2.set_field('default_message', StringValue(self.message2.def_msg)) msg_struct2.set_field('args', ListValue()) msg_struct3 = StructValue('localizable_message') msg_struct3.set_field('id', StringValue(self.message3.id)) msg_struct3.set_field('default_message', StringValue(self.message3.def_msg)) msg_struct3.set_field('args', ListValue()) messages = ListValue() messages.add_all([msg_struct1, msg_struct2, msg_struct3]) expected_data_value = ev = make_error_value_from_msgs(self.error_def) expected_data_value.set_field('messages', messages) self.assertEqual(expected_data_value, ev)
def get_operation_info(self, service_id, operation_id): provider = self._get_provider(service_id) if provider: ctx = ExecutionContext() struct_value = StructValue(name=OPERATION_INPUT, values={ 'service_id': StringValue(service_id), 'operation_id': StringValue(operation_id) }) return provider.invoke(Introspection.OPERATION_SVC, 'get', struct_value, ctx) else: msg = message_factory.get_message( 'vapi.introspection.operation.service.not_found', service_id) error_value = make_error_value_from_msgs(not_found_def, msg) return MethodResult(error=error_value)
def _visit_string(self, obj): # pylint: disable=R0201 """ Visit python string object :type obj: :class:`unicode` for Python 2 and :class:`str` for Python 3 :param obj: Python string object :rtype: :class:`vmware.vapi.data.value.StringValue` :return: String value """ return StringValue(obj)