def Check(self, arg_spec, cmdline_args, api_field, field_value): arg = arg_spec.Generate(fm.FakeMessage) namespace = self._Parse([arg], cmdline_args) request = fm.FakeMessage() arg_spec.Parse(request, namespace) self.assertEqual(yaml_command_translator._GetAttribute(request, api_field), field_value)
def testParseExistingMessageIntoMessage(self, existing_message, method_request_field, expected_message): message = fm.FakeMessage() method = mock.MagicMock(request_field=method_request_field) parsed_message = arg_utils.ParseExistingMessageIntoMessage( message, existing_message, method) self.assertEqual(parsed_message, expected_message)
def testArgDict(self, loader): data = {'spec': [ {'api_field': 'string1', 'arg_name': 'a'}, {'api_field': 'enum1', 'arg_name': 'b'}, {'api_field': 'bool1', 'arg_name': 'c'}, {'api_field': 'int1', 'arg_name': 'd'}, {'api_field': 'float1', 'arg_name': 'e'} ]} arg_dict = loader(data) dict_type = arg_dict.GenerateType(fm.FakeMessage) result = dict_type('a=foo,b=thing-one,c=True,d=1,e=2.0') self.assertEqual( result, fm.FakeMessage(string1='foo', enum1=fm.FakeMessage.FakeEnum.THING_ONE, bool1=True, int1=1, float1=2.0))
def testParseResourceIntoMessageWithParamsNonMethodParamsRelativeName(self): self.MockCRUDMethods(('foo.projects.locations.instances', False)) method = registry.GetMethod('foo.projects.locations.instances', 'get') method.params = [] message = fm.FakeMessage() ref = resources.REGISTRY.Parse( 'projects/p/locations/l/instances/i', collection=method.request_collection.full_name) arg_utils.ParseResourceIntoMessage( ref, method, message, resource_method_params={ 'string1': '', }) self.assertEqual('projects/p/locations/l/instances/i', message.string1)
def testSetFieldInMessage(self): m = fm.FakeMessage() self.assertEqual(m.string1, None) arg_utils.SetFieldInMessage(m, 'string1', 'a') arg_utils.SetFieldInMessage(m, 'message1.string1', 'b') arg_utils.SetFieldInMessage(m, 'message1.string2', 'c') arg_utils.SetFieldInMessage(m, 'message2.deeper_message.deep_string', 'd') arg_utils.SetFieldInMessage(m, 'repeated_message.string1', 'e') arg_utils.SetFieldInMessage(m, 'repeated_message.string2', 'f') self.assertEqual(m.string1, 'a') self.assertEqual(m.message1.string1, 'b') self.assertEqual(m.message1.string2, 'c') self.assertEqual(m.message2.deeper_message.deep_string, 'd') self.assertEqual(m.repeated_message[0].string1, 'e') self.assertEqual(m.repeated_message[0].string2, 'f')
def testArgDictOptionalKeys(self, loader): data = {'spec': [ {'api_field': 'string1', 'arg_name': 'a', 'required': False}, {'api_field': 'enum1', 'arg_name': 'b', 'required': False, 'choices': [ {'arg_value': 'thing_one', 'enum_value': fm.FakeMessage.FakeEnum.THING_ONE}, {'arg_value': 'thing_two', 'enum_value': fm.FakeMessage.FakeEnum.THING_TWO} ]}, {'api_field': 'bool1', 'arg_name': 'c', 'required': False}, {'api_field': 'int1', 'arg_name': 'd', 'required': False}, {'api_field': 'float1', 'arg_name': 'e', 'required': False} ]} arg_dict = loader(data) dict_type = arg_dict.GenerateType(fm.FakeMessage) result = dict_type('') self.assertEqual( result, fm.FakeMessage(string1=None, enum1=None, bool1=None, int1=None, float1=None))
def testGetFieldValueFromMessage(self): m = fm.FakeMessage( string1='a', enum1=fm.FakeMessage.FakeEnum.THING_ONE, bool1=True, int1=123, float1=123.45, message1=fm.FakeMessage.InnerMessage( string1='b', ), message2=fm.FakeMessage.InnerMessage2( deeper_message=fm.FakeMessage.InnerMessage2.DeeperMessage( deep_string='c', ) ), repeated_message=[ fm.FakeMessage.InnerMessage( enum1=fm.FakeMessage.FakeEnum.THING_ONE), fm.FakeMessage.InnerMessage( enum1=fm.FakeMessage.FakeEnum.THING_TWO) ] ) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'string1'), m.string1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'enum1'), m.enum1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'enum2'), []) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'bool1'), m.bool1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'int1'), m.int1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'float1'), m.float1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'bytes1'), None) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'message1'), m.message1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'message1.string1'), m.message1.string1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'message2'), m.message2) self.assertEqual( arg_utils.GetFieldValueFromMessage(m, 'message2.deeper_message'), m.message2.deeper_message) self.assertEqual( arg_utils.GetFieldValueFromMessage( m, 'message2.deeper_message.deep_string'), m.message2.deeper_message.deep_string) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'repeated_message'), m.repeated_message) self.assertEqual( arg_utils.GetFieldValueFromMessage(m, 'repeated_message[0]'), m.repeated_message[0]) self.assertEqual( arg_utils.GetFieldValueFromMessage(m, 'repeated_message[0].string1'), m.repeated_message[0].string1) self.assertEqual( arg_utils.GetFieldValueFromMessage(m, 'repeated_message[2]'), None) self.assertEqual( arg_utils.GetFieldValueFromMessage(m, 'repeated_message[2].string1'), None) self.assertEqual( arg_utils.GetFieldValueFromMessage( fm.FakeMessage(), 'message2.deeper_message.deep_string'), None)
class ArgUtilTests(base.Base, sdk_test_base.SdkBase, parameterized.TestCase): """Tests for generating args for Get API calls.""" @parameterized.parameters( ('string1', fm.FakeMessage.string1), ('enum1', fm.FakeMessage.enum1), ('bool1', fm.FakeMessage.bool1), ('int1', fm.FakeMessage.int1), ('float1', fm.FakeMessage.float1), ('message1', fm.FakeMessage.message1), ('message1.string2', fm.FakeMessage.InnerMessage.string2), ('message2', fm.FakeMessage.message2), ('message2.deeper_message', fm.FakeMessage.InnerMessage2.deeper_message), ('message2.deeper_message.deep_string', fm.FakeMessage.InnerMessage2.DeeperMessage.deep_string), ('repeated_message.string1', fm.FakeMessage.InnerMessage.string1), ) def testGetFieldFromMessage(self, field_path, result): self.assertEqual(result, arg_utils.GetFieldFromMessage(fm.FakeMessage, field_path)) def testGetFromNamespace(self): ns = mock.MagicMock(foo_bar='baz', qux=None, project=None) value = arg_utils.GetFromNamespace(ns, 'foo-bar') self.assertEqual(value, 'baz') value = arg_utils.GetFromNamespace(ns, 'qux', fallback=lambda: 42) self.assertEqual(value, 42) properties.VALUES.core.project.Set('fake-project') value = arg_utils.GetFromNamespace(ns, 'project') self.assertEqual(value, None) value = arg_utils.GetFromNamespace(ns, 'project', use_defaults=True) self.assertEqual(value, 'fake-project') def testGetFieldFromMessageError(self): with self.assertRaises(arg_utils.UnknownFieldError): arg_utils.GetFieldFromMessage(fm.FakeMessage, 'string3') def testGetFieldValueFromMessage(self): m = fm.FakeMessage( string1='a', enum1=fm.FakeMessage.FakeEnum.THING_ONE, bool1=True, int1=123, float1=123.45, message1=fm.FakeMessage.InnerMessage( string1='b', ), message2=fm.FakeMessage.InnerMessage2( deeper_message=fm.FakeMessage.InnerMessage2.DeeperMessage( deep_string='c', ) ), repeated_message=[ fm.FakeMessage.InnerMessage( enum1=fm.FakeMessage.FakeEnum.THING_ONE), fm.FakeMessage.InnerMessage( enum1=fm.FakeMessage.FakeEnum.THING_TWO) ] ) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'string1'), m.string1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'enum1'), m.enum1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'enum2'), []) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'bool1'), m.bool1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'int1'), m.int1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'float1'), m.float1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'bytes1'), None) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'message1'), m.message1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'message1.string1'), m.message1.string1) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'message2'), m.message2) self.assertEqual( arg_utils.GetFieldValueFromMessage(m, 'message2.deeper_message'), m.message2.deeper_message) self.assertEqual( arg_utils.GetFieldValueFromMessage( m, 'message2.deeper_message.deep_string'), m.message2.deeper_message.deep_string) self.assertEqual(arg_utils.GetFieldValueFromMessage(m, 'repeated_message'), m.repeated_message) self.assertEqual( arg_utils.GetFieldValueFromMessage(m, 'repeated_message[0]'), m.repeated_message[0]) self.assertEqual( arg_utils.GetFieldValueFromMessage(m, 'repeated_message[0].string1'), m.repeated_message[0].string1) self.assertEqual( arg_utils.GetFieldValueFromMessage(m, 'repeated_message[2]'), None) self.assertEqual( arg_utils.GetFieldValueFromMessage(m, 'repeated_message[2].string1'), None) self.assertEqual( arg_utils.GetFieldValueFromMessage( fm.FakeMessage(), 'message2.deeper_message.deep_string'), None) @parameterized.parameters( ('invalid', r'Invalid field path \[invalid\] for message \[FakeMessage\]. Details: ' r'\[Field \[invalid\] not found in message \[FakeMessage\]. Available ' r'fields:'), ('string1[0]', r'Invalid field path \[string1\[0\]\] for message \[FakeMessage\]. ' r'Details: \[Index cannot be specified for non-repeated field ' r'\[string1\]\]'), ('enum1.string1', r'Invalid field path \[enum1.string1\] for message \[FakeMessage\]. ' r'Details: \[\[enum1\] is not a valid field on field \[FakeEnum\]\]'), ('repeated_message.string1', r'Invalid field path \[repeated_message.string1\] for message ' r'\[FakeMessage\]. Details: \[Index needs to be specified for repeated ' r'field \[repeated_message\]\]'), ('repeated_message[2].string1[0]', r'Invalid field path \[repeated_message\[2\].string1\[0\]\] for message ' r'\[FakeMessage\]. Details: \[Index cannot be specified for ' r'non-repeated field \[string1\]\]'), ('repeated_message[2].invalid', r'Invalid field path \[repeated_message\[2\].invalid\] for message ' r'\[FakeMessage\]. Details: \[Field \[invalid\] not found in message ' r'\[InnerMessage\]. Available fields:'), ) def testGetFieldValueFromMessageError(self, path, expected): with self.assertRaisesRegex(arg_utils.InvalidFieldPathError, expected): arg_utils.GetFieldValueFromMessage(fm.FakeMessage(), path) def testSetFieldInMessage(self): m = fm.FakeMessage() self.assertEqual(m.string1, None) arg_utils.SetFieldInMessage(m, 'string1', 'a') arg_utils.SetFieldInMessage(m, 'message1.string1', 'b') arg_utils.SetFieldInMessage(m, 'message1.string2', 'c') arg_utils.SetFieldInMessage(m, 'message2.deeper_message.deep_string', 'd') arg_utils.SetFieldInMessage(m, 'repeated_message.string1', 'e') arg_utils.SetFieldInMessage(m, 'repeated_message.string2', 'f') self.assertEqual(m.string1, 'a') self.assertEqual(m.message1.string1, 'b') self.assertEqual(m.message1.string2, 'c') self.assertEqual(m.message2.deeper_message.deep_string, 'd') self.assertEqual(m.repeated_message[0].string1, 'e') self.assertEqual(m.repeated_message[0].string2, 'f') @parameterized.named_parameters( ('InnerMessageInt', {'int1': 1}, 'message1', fm.FakeMessage(message1=fm.FakeMessage.InnerMessage(int1=1))), ('RepeatedMessage', [{'enum1': 'THING_ONE'}, {'enum1': 'THING_TWO'}], 'repeated_message', fm.FakeMessage(repeated_message=[ fm.FakeMessage.InnerMessage(enum1=fm.FakeMessage.FakeEnum.THING_ONE), fm.FakeMessage.InnerMessage(enum1=fm.FakeMessage.FakeEnum.THING_TWO) ])), ('InnerMessageEnum', {'enum1': 'THING_ONE'}, 'message1', fm.FakeMessage(message1=fm.FakeMessage.InnerMessage( enum1=fm.FakeMessage.FakeEnum.THING_ONE))), ('DeeperMessage', {'deeper_message': {'deep_string': 's'}}, 'message2', fm.FakeMessage( message2=fm.FakeMessage.InnerMessage2( deeper_message=fm.FakeMessage.InnerMessage2.DeeperMessage( deep_string='s')))) ) def testSetObjectFieldInMessage(self, obj, field, expected): m = fm.FakeMessage() arg_utils.SetFieldInMessage(m, field, obj) self.assertEqual(m, expected) @parameterized.named_parameters( ('Same level', fm.FakeMessage(int1=1), '', fm.FakeMessage(int1=1)), ('Field in top level message', fm.FakeMessage.InnerMessage(int1=1), 'message1', fm.FakeMessage(message1=fm.FakeMessage.InnerMessage(int1=1))), ('Field in nested message', fm.FakeMessage.InnerMessage2.DeeperMessage(deep_string='s'), 'message2', fm.FakeMessage( message2=fm.FakeMessage.InnerMessage2( deeper_message=fm.FakeMessage.InnerMessage2.DeeperMessage( deep_string='s')))), ) def testParseExistingMessageIntoMessage(self, existing_message, method_request_field, expected_message): message = fm.FakeMessage() method = mock.MagicMock(request_field=method_request_field) parsed_message = arg_utils.ParseExistingMessageIntoMessage( message, existing_message, method) self.assertEqual(parsed_message, expected_message) @parameterized.parameters( (['GOOD', 'YES'], ['GOOD', 'NO'], ['NO']), (['GOOD'], ['GOOD', 'EXTRA'], ['EXTRA']), (['GOOD', 'YES'], ['GOOD', 'YES', 'EXTRA', 'EXTRA2'], ['EXTRA, EXTRA2']), ) def testValidEnumNamesErrors(self, api_names, choices, bad_choices): with self.assertRaisesRegex( arg_parsers.ArgumentTypeError, '{} is/are not valid enum values.'.format(', '.join(bad_choices))): arg_utils.CheckValidEnumNames(api_names, choices) @parameterized.parameters( (['GOOD', 'YES'], ['GOOD', 'YES']), (['GOOD_ONE'], ['good-one']), (['GOOD_ONE'], ['good_one']), (['GOOD_ONE'], ['GOOD_ONE']), (['GOOD_ONE'], ['GOOD-ONE']), ) def test_one_space(self, api_names, choices): self.assertIsNone(arg_utils.CheckValidEnumNames(api_names, choices)) @parameterized.parameters( ('THING_ONE', 'thing-one'), ('THING-ONE', 'thing-one'), ('thing_one', 'thing-one'), ('thing-one', 'thing-one'), ) def testEnumNameToChoice(self, enum_name, choice): self.assertEqual(choice, arg_utils.EnumNameToChoice(enum_name)) @parameterized.parameters( ('THING_ONE', fm.FakeMessage.FakeEnum.THING_ONE), ('THING-ONE', fm.FakeMessage.FakeEnum.THING_ONE), ('thing_one', fm.FakeMessage.FakeEnum.THING_ONE), ('thing-one', fm.FakeMessage.FakeEnum.THING_ONE), ('THING_TWO', fm.FakeMessage.FakeEnum.THING_TWO), ('THING-TWO', fm.FakeMessage.FakeEnum.THING_TWO), ('thing_two', fm.FakeMessage.FakeEnum.THING_TWO), ('thing-two', fm.FakeMessage.FakeEnum.THING_TWO), (None, None) ) def testChoiceToEnum(self, choice, enum_type): self.assertEqual(enum_type, arg_utils.ChoiceToEnum(choice, fm.FakeMessage.FakeEnum)) def testChoiceToEnumErrors(self): # With valid choices specified, validate against those with self.assertRaisesRegex( arg_parsers.ArgumentTypeError, r'Invalid choice: badchoice. Valid choices are: \[a, b\].'): arg_utils.ChoiceToEnum('badchoice', fm.FakeMessage.FakeEnum, valid_choices=['a', 'b']) # With valid choices specified, and custom item type with self.assertRaisesRegex( arg_parsers.ArgumentTypeError, r'Invalid sproket: badchoice. Valid choices are: \[a, b\].'): arg_utils.ChoiceToEnum('badchoice', fm.FakeMessage.FakeEnum, item_type='sproket', valid_choices=['a', 'b']) # With no valid choices specified, validate against the enum with self.assertRaisesRegex( arg_parsers.ArgumentTypeError, r'Invalid choice: badchoice. Valid choices are: \[thing-one, ' r'thing-two\].'): arg_utils.ChoiceToEnum('badchoice', fm.FakeMessage.FakeEnum) def testConvertValueWithProcessor(self): def P(value): return '!' + value def Q(value): return ['!' + v for v in value] # Non-repeated. self.assertEqual( '!a', arg_utils.ConvertValue(fm.FakeMessage.string1, 'a', processor=P)) # Repeated. self.assertEqual( ['!a', '!b'], arg_utils.ConvertValue(fm.FakeMessage.string2, ['a', 'b'], processor=Q)) # Repeated field, but forced singular arg. self.assertEqual( ['!a'], arg_utils.ConvertValue(fm.FakeMessage.string2, 'a', processor=P, repeated=False)) def testConvertValueWithChoices(self): choices = [ yaml_command_schema_util.Choice({'arg_value': 'a', 'enum_value': 'b'}), yaml_command_schema_util.Choice({'arg_value': 'c', 'enum_value': 'd'})] choices = yaml_command_schema_util.Choice.ToChoiceMap(choices) # Value not provided. self.assertEqual( None, arg_utils.ConvertValue(fm.FakeMessage.string1, None, choices=choices)) # Non-repeated. self.assertEqual( 'b', arg_utils.ConvertValue(fm.FakeMessage.string1, 'a', choices=choices)) self.assertEqual( 'd', arg_utils.ConvertValue(fm.FakeMessage.string1, 'c', choices=choices)) # Make sure case insensitive works. self.assertEqual( 'b', arg_utils.ConvertValue(fm.FakeMessage.string1, 'A', choices=choices)) # Repeated. self.assertEqual( ['b', 'b', 'd', 'd'], arg_utils.ConvertValue( fm.FakeMessage.string2, ['a', 'b', 'c', 'd'], choices=choices)) # Repeated field, but forced singular arg. self.assertEqual( ['b'], arg_utils.ConvertValue( fm.FakeMessage.string2, 'a', repeated=False, choices=choices)) self.assertEqual( ['d'], arg_utils.ConvertValue( fm.FakeMessage.string2, 'c', repeated=False, choices=choices)) def testConvertValueEnum(self): choices = [ yaml_command_schema_util.Choice({'arg_value': 'a', 'enum_value': 'thing-one'}), yaml_command_schema_util.Choice({'arg_value': 'c', 'enum_value': 'thing-two'})] choices = yaml_command_schema_util.Choice.ToChoiceMap(choices) # Non-repeated. self.assertEqual( fm.FakeMessage.FakeEnum.THING_ONE, arg_utils.ConvertValue(fm.FakeMessage.enum1, 'a', choices=choices)) self.assertEqual( fm.FakeMessage.FakeEnum.THING_TWO, arg_utils.ConvertValue(fm.FakeMessage.enum1, 'c', choices=choices)) self.assertEqual( fm.FakeMessage.FakeEnum.THING_ONE, arg_utils.ConvertValue(fm.FakeMessage.enum1, 'thing-one', choices=choices)) self.assertEqual( fm.FakeMessage.FakeEnum.THING_TWO, arg_utils.ConvertValue(fm.FakeMessage.enum1, 'thing-two', choices=choices)) # Repeated. self.assertEqual( [fm.FakeMessage.FakeEnum.THING_ONE, fm.FakeMessage.FakeEnum.THING_TWO], arg_utils.ConvertValue(fm.FakeMessage.enum2, ['a', 'c'], choices=choices)) # Repeated field, but forced singular arg. self.assertEqual( [fm.FakeMessage.FakeEnum.THING_ONE], arg_utils.ConvertValue( fm.FakeMessage.enum2, 'a', repeated=False, choices=choices)) self.assertEqual( [fm.FakeMessage.FakeEnum.THING_TWO], arg_utils.ConvertValue( fm.FakeMessage.enum2, 'c', repeated=False, choices=choices)) self.assertEqual( [fm.FakeMessage.FakeEnum.THING_ONE], arg_utils.ConvertValue( fm.FakeMessage.enum2, 'thing-one', repeated=False, choices=choices)) self.assertEqual( [fm.FakeMessage.FakeEnum.THING_TWO], arg_utils.ConvertValue( fm.FakeMessage.enum2, 'thing-two', repeated=False, choices=choices)) def testHelpExtraction(self): help_texts = arg_utils.FieldHelpDocs(fm.FakeMessage.InnerMessage) self.assertEqual( help_texts, {'string1': 'the first string', 'string2': 'The second string. It also happens to have a really long ' 'description that wraps lines, which is convenient for ' 'testing that capability.', 'int1': 'an integer', 'enum1': 'an enum', }) help_texts = arg_utils.FieldHelpDocs( fm.FakeMessage.InnerMessage2.DeeperMessage) self.assertTrue(arg_utils.IsOutputField(help_texts['output_string'])) self.assertTrue(arg_utils.IsOutputField(help_texts['output_string2'])) self.assertFalse(arg_utils.IsOutputField(help_texts['deep_string'])) help_texts = arg_utils.FieldHelpDocs(fm.FakeMessage.FakeEnum, 'Values') self.assertEqual( help_texts, {'THING_ONE': 'the first thing', 'THING_TWO': 'the second thing' }) def testGetRecursiveMessage(self): self.maxDiff = None # pylint: disable=invalid-name message = arg_utils.GetRecursiveMessageSpec(fm.FakeMessage) self.assertEqual( message, {'bool1': {'description': 'a boolean', 'repeated': False, 'type': _messages.Variant.BOOL}, 'bytes1': {'description': 'a byte string', 'repeated': False, 'type': _messages.Variant.BYTES}, 'enum1': {'choices': {'THING_ONE': 'the first thing', 'THING_TWO': 'the second thing'}, 'description': 'a FakeEnum', 'repeated': False, 'type': _messages.Variant.ENUM}, 'enum2': {'choices': {'THING_ONE': 'the first thing', 'THING_TWO': 'the second thing'}, 'description': 'a repeated FakeEnum', 'repeated': True, 'type': _messages.Variant.ENUM}, 'float1': {'description': 'a float', 'repeated': False, 'type': _messages.Variant.DOUBLE}, 'int1': {'description': 'an int', 'repeated': False, 'type': _messages.Variant.INT64}, 'message1': {'description': 'an InnerMessage message', 'repeated': False, 'type': 'InnerMessage', 'fields': { 'string1': { 'description': 'the first string', 'repeated': False, 'type': _messages.Variant.STRING}, 'string2': { 'description': 'The second string. It also happens to have ' 'a really long description that wraps lines, ' 'which is convenient for testing that ' 'capability.', 'repeated': False, 'type': _messages.Variant.STRING}, 'int1': { 'description': 'an integer', 'repeated': False, 'type': _messages.Variant.INT64}, 'enum1': { 'choices': {'THING_ONE': 'the first thing', 'THING_TWO': 'the second thing'}, 'description': 'an enum', 'repeated': False, 'type': _messages.Variant.ENUM}}}, 'message2': {'description': 'an InnerMessage2 message', 'repeated': False, 'type': 'InnerMessage2', 'fields': { 'deeper_message': { 'description': 'a DeeperMessage message', 'repeated': False, 'type': 'DeeperMessage', 'fields': { 'deep_string': { 'description': 'a string', 'repeated': False, 'type': _messages.Variant.STRING}, 'output_string': { 'description': '[Output Only] a string that cannot ' 'be set.', 'repeated': False, 'type': _messages.Variant.STRING}, 'output_string2': { 'description': 'another string that cannot be ' 'set.@OutputOnly', 'repeated': False, 'type': _messages.Variant.STRING}}}}}, 'repeated_message': { 'description': 'a repeated InnerMessage message.', 'repeated': True, 'type': 'InnerMessage', 'fields': { 'string1': { 'description': 'the first string', 'repeated': False, 'type': _messages.Variant.STRING}, 'string2': { 'description': 'The second string. It also happens to have a really ' 'long description that wraps lines, which is ' 'convenient for testing that capability.', 'repeated': False, 'type': _messages.Variant.STRING}, 'int1': { 'description': 'an integer', 'repeated': False, 'type': _messages.Variant.INT64}, 'enum1': { 'choices': {'THING_ONE': 'the first thing', 'THING_TWO': 'the second thing'}, 'description': 'an enum', 'repeated': False, 'type': _messages.Variant.ENUM}}}, 'string1': {'description': 'the first string', 'repeated': False, 'type': _messages.Variant.STRING}, 'string2': {'description': 'a repeated string', 'repeated': True, 'type': _messages.Variant.STRING}}) def _MakeKwargs(self, **kwargs): """Make Test keyword args to compare against arg_utils generated args.""" k = {'category': None, 'action': 'store', 'completer': None, 'help': 'foo help', 'hidden': False, 'metavar': 'FOO', 'type': six.text_type, 'choices': None, 'required': False} k.update(**kwargs) return k def testGenerateFlagBasics(self): a = yaml_command_schema.Argument('asdf', 'foo', 'foo help') arg = arg_utils.GenerateFlag(fm.FakeMessage.string1, a) self.assertEqual(arg.name, '--foo') self.assertEqual(self._MakeKwargs(), arg.kwargs) arg = arg_utils.GenerateFlag(fm.FakeMessage.string1, a, category='ASDF') self.assertDictContainsSubset(self._MakeKwargs(category='ASDF'), arg.kwargs) a = yaml_command_schema.Argument('foo', 'foo', 'foo help', default='junk') arg = arg_utils.GenerateFlag(fm.FakeMessage.string1, a) self.assertEqual(self._MakeKwargs(default='junk'), arg.kwargs) a = yaml_command_schema.Argument( 'foo', 'foo', 'foo help', choices=[yaml_command_schema_util.Choice({'arg_value': 'a', 'enum_value': 'b'}), yaml_command_schema_util.Choice({'arg_value': 'c', 'enum_value': 'd'})]) arg = arg_utils.GenerateFlag(fm.FakeMessage.string1, a) self.assertEqual(self._MakeKwargs(choices=['a', 'c']), arg.kwargs) a = yaml_command_schema.Argument('foo', 'foo', 'foo help', completer='junk') arg = arg_utils.GenerateFlag(fm.FakeMessage.string1, a) self.assertEqual(self._MakeKwargs(completer='junk'), arg.kwargs) a = yaml_command_schema.Argument('foo', 'foo', 'foo help', hidden=True) arg = arg_utils.GenerateFlag(fm.FakeMessage.string1, a) self.assertEqual(self._MakeKwargs(hidden=True), arg.kwargs) a = yaml_command_schema.Argument('foo', 'foo', 'foo help', required=True) arg = arg_utils.GenerateFlag(fm.FakeMessage.string1, a) self.assertEqual(self._MakeKwargs(required=True), arg.kwargs) # No api_field a = yaml_command_schema.Argument(None, 'foo', 'foo help', repeated=False) arg = arg_utils.GenerateFlag(None, a) self.assertEqual(arg.kwargs['type'], None) # Unknown type a = yaml_command_schema.Argument('foo', 'foo', 'foo help') with self.assertRaisesRegex( arg_utils.ArgumentGenerationError, r'Failed to generate argument for field \[message1\]: The field is of ' r'an unknown type.'): arg_utils.GenerateFlag(fm.FakeMessage.message1, a) def testRepeated(self): # Repeated simple type gets wrapped. a = yaml_command_schema.Argument('foo', 'foo', 'foo help') arg = arg_utils.GenerateFlag(fm.FakeMessage.string2, a) self.assertTrue(isinstance(arg.kwargs['type'], arg_parsers.ArgList)) self.assertEqual(arg.kwargs['type'].element_type, six.text_type) # Repeated complex type doesn't get re-wrapped. a = yaml_command_schema.Argument('foo', 'foo', 'foo help', type=arg_parsers.ArgList()) arg = arg_utils.GenerateFlag(fm.FakeMessage.string2, a) self.assertIsNone(arg.kwargs['type'].element_type) # Repeated with flattened ArgDict. t = yaml_command_schema_util.ParseType( {'arg_dict': {'flatten': True, 'spec': [ {'api_field': 'string1'}, {'api_field': 'string2'}]}}) a = yaml_command_schema.Argument('foo', 'foo', 'foo help', type=t) arg = arg_utils.GenerateFlag(fm.FakeMessage.repeated_message, a) result = arg.kwargs['type']('a=b,c=d') self.assertEqual(len(result), 2) self.assertEqual(result[0], fm.FakeMessage.InnerMessage(string1='a', string2='b')) self.assertEqual(result[1], fm.FakeMessage.InnerMessage(string1='c', string2='d')) # Repeated with ArgDict. t = yaml_command_schema_util.ParseType( {'arg_dict': {'spec': [ {'api_field': 'string1', 'arg_name': 'a'}, {'api_field': 'string2', 'arg_name': 'b'}]}}) a = yaml_command_schema.Argument('foo', 'foo', 'foo help', type=t) arg = arg_utils.GenerateFlag(fm.FakeMessage.repeated_message, a) result = arg.kwargs['type']('a=foo,b=bar') self.assertEqual(result, fm.FakeMessage.InnerMessage(string1='foo', string2='bar')) # Not allowed to use ArgDict with non-repeated field. with self.assertRaisesRegex( arg_utils.ArgumentGenerationError, r'Failed to generate argument for field \[string1\]: The given type ' r'can only be used on repeated fields.'): arg_utils.GenerateFlag(fm.FakeMessage.string1, a) # Force repeated arg to be singular. a = yaml_command_schema.Argument('foo', 'foo', 'foo help', repeated=False) arg = arg_utils.GenerateFlag(fm.FakeMessage.string2, a) self.assertEqual(arg.kwargs['type'], six.text_type) # Repeated with custom action is an error. a = yaml_command_schema.Argument('foo', 'foo', 'foo help', action='foo') with self.assertRaisesRegex( arg_utils.ArgumentGenerationError, r'Failed to generate argument for field \[string2\]: The field is ' r'repeated but is using a custom action. You might want to set ' r'repeated: False in your arg spec.'): arg_utils.GenerateFlag(fm.FakeMessage.string2, a) def testGenerateFlagBoolean(self): a = yaml_command_schema.Argument('asdf', 'foo', 'foo help') arg = arg_utils.GenerateFlag(fm.FakeMessage.bool1, a) self.assertEqual(arg.name, '--foo') self.assertEqual( {'category': None, 'action': 'store_true', 'completer': None, 'help': 'foo help', 'hidden': False, 'required': False}, arg.kwargs) def testGenerateUnspecifiedDefault(self): a = yaml_command_schema.Argument.FromData( {'help_text': 'foo help', 'api_field': 'asdf', 'arg_name': 'foo'}) arg = arg_utils.GenerateFlag(fm.FakeMessage.string2, a) self.assertEqual(a.default, arg_utils.UNSPECIFIED) self.assertNotIn('default', arg.kwargs) def testGenerateFlagEnumChoices(self): a = yaml_command_schema.Argument('asdf', 'foo', 'foo help') arg = arg_utils.GenerateFlag(fm.FakeMessage.enum1, a) self.assertEqual(arg.name, '--foo') self.assertEqual( self._MakeKwargs(choices=['thing-one', 'thing-two'], type=arg_utils.EnumNameToChoice), arg.kwargs) def testGenerateFlagPositional(self): a = yaml_command_schema.Argument('asdf', 'foo', 'foo help', is_positional=True) arg = arg_utils.GenerateFlag(fm.FakeMessage.string1, a) self.assertEqual(arg.name, 'foo') kwargs = self._MakeKwargs() del kwargs['required'] self.assertEqual(kwargs, arg.kwargs) def testParseBasicTypes(self): parser = util.ArgumentParser() def Add(field, name): a = yaml_command_schema.Argument('asdf', name, 'help') arg_utils.GenerateFlag(field, a).AddToParser(parser) Add(fm.FakeMessage.string1, 'string1') Add(fm.FakeMessage.enum1, 'enum1') Add(fm.FakeMessage.bool1, 'bool1') Add(fm.FakeMessage.int1, 'int1') Add(fm.FakeMessage.float1, 'float1') Add(fm.FakeMessage.bytes1, 'bytes1') result = parser.parse_args( ['--string1', 'foo', '--enum1', 'thing-one', '--bool1', '--int1', '1', '--float1', '1.5', '--bytes1', "¢συℓ∂η'т ѕαу ησ"]) self.assertEqual(result.string1, 'foo') # Enums don't get converted until arg processing time. self.assertEqual(result.enum1, 'thing-one') self.assertEqual(result.bool1, True) self.assertEqual(result.int1, 1) self.assertEqual(result.float1, 1.5) self.assertEqual(result.bytes1, b"\xc2\xa2\xcf\x83\xcf\x85\xe2\x84\x93\xe2\x88\x82\xce\xb7" b"'\xd1\x82 \xd1\x95\xce\xb1\xd1\x83 \xce\xb7\xcf\x83") def testParseResourceIntoMessageGet(self): self.MockCRUDMethods(('foo.projects.locations.instances', True)) method = registry.GetMethod('foo.projects.locations.instances', 'get') message = method.GetRequestType()() ref = resources.REGISTRY.Parse( 'projects/p/locations/l/instances/i', collection=method.request_collection.full_name) arg_utils.ParseResourceIntoMessage( ref, method, message) self.assertEqual('projects/p/locations/l/instances/i', message.name) def testParseResourceIntoMessageWithParams(self): self.MockCRUDMethods(('foo.projects.locations.instances', False), ('baz.projects.quxs.quuxs', False)) method = registry.GetMethod('foo.projects.locations.instances', 'get') message = method.GetRequestType()() ref = resources.REGISTRY.Create( 'baz.projects.quxs.quuxs', projectsId='p', quuxsId='quux', quxsId='qux') arg_utils.ParseResourceIntoMessage( ref, method, message, resource_method_params={ 'locationsId': 'quxsId', 'instancesId': 'quuxsId' }) self.assertEqual('p', message.projectsId) self.assertEqual('qux', message.locationsId) self.assertEqual('quux', message.instancesId) def testParseResourceIntoMessageWithParamsNonMethodParams(self): self.MockCRUDMethods(('foo.projects.locations.instances', False)) method = registry.GetMethod('foo.projects.locations.instances', 'get') method.params = [] message = fm.FakeMessage() ref = resources.REGISTRY.Parse( 'projects/p/locations/l/instances/i', collection=method.request_collection.full_name) arg_utils.ParseResourceIntoMessage( ref, method, message, resource_method_params={ 'string1': 'projectsId', 'message1.string1': 'locationsId', 'message1.string2': 'instancesId' }) self.assertEqual('p', message.string1) self.assertEqual('l', message.message1.string1) self.assertEqual('i', message.message1.string2) def testParseResourceIntoMessageWithParamsNonMethodParamsRelativeName(self): self.MockCRUDMethods(('foo.projects.locations.instances', False)) method = registry.GetMethod('foo.projects.locations.instances', 'get') method.params = [] message = fm.FakeMessage() ref = resources.REGISTRY.Parse( 'projects/p/locations/l/instances/i', collection=method.request_collection.full_name) arg_utils.ParseResourceIntoMessage( ref, method, message, resource_method_params={ 'string1': '', }) self.assertEqual('projects/p/locations/l/instances/i', message.string1) def testParseResourceIntoMessageList(self): self.MockCRUDMethods(('foo.projects.locations.instances', True)) method = registry.GetMethod('foo.projects.locations.instances', 'list') message = method.GetRequestType()() ref = resources.REGISTRY.Parse( 'projects/p/locations/l', collection=method.request_collection.full_name) arg_utils.ParseResourceIntoMessage( ref, method, message) self.assertEqual('projects/p/locations/l', message.parent) def testParseResourceIntoMessageCreate(self): self.MockCRUDMethods(('foo.projects.locations.instances', True)) method = registry.GetMethod('foo.projects.locations.instances', 'create') message = method.GetRequestType()() message.field_by_name = mock.MagicMock() ref = resources.REGISTRY.Parse( 'projects/p/locations/l/instances/i', collection=method.resource_argument_collection.full_name) arg_utils.ParseResourceIntoMessage( ref, method, message, request_id_field='name') self.assertEqual('projects/p/locations/l', message.parent) self.assertEqual('i', message.name) def testParseResourceIntoMessageCreateWithParentResource(self): self.MockCRUDMethods(('foo.projects.locations.instances', True)) method = registry.GetMethod('foo.projects.locations.instances', 'create') message = method.GetRequestType()() parent_ref = resources.REGISTRY.Parse( 'projects/p/locations/l', collection='foo.projects.locations') arg_utils.ParseResourceIntoMessage(parent_ref, method, message) self.assertEqual('projects/p/locations/l', message.parent) def testParseStaticFieldsIntoMessage(self): self.MockCRUDMethods(('foo.projects.instances', True)) method = registry.GetMethod('foo.projects.instances', 'list') message_type = method.GetRequestType() message = message_type() static_fields = {'pageSize': 1} arg_utils.ParseStaticFieldsIntoMessage(message, static_fields) self.assertEqual(message.pageSize, 1)
def testSetObjectFieldInMessage(self, obj, field, expected): m = fm.FakeMessage() arg_utils.SetFieldInMessage(m, field, obj) self.assertEqual(m, expected)
def testGetFieldValueFromMessageError(self, path, expected): with self.assertRaisesRegex(arg_utils.InvalidFieldPathError, expected): arg_utils.GetFieldValueFromMessage(fm.FakeMessage(), path)