示例#1
0
 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)
示例#2
0
 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))
示例#4
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)
示例#5
0
  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))
示例#7
0
  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)
示例#8
0
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)
示例#9
0
 def testSetObjectFieldInMessage(self, obj, field, expected):
   m = fm.FakeMessage()
   arg_utils.SetFieldInMessage(m, field, obj)
   self.assertEqual(m, expected)
示例#10
0
 def testGetFieldValueFromMessageError(self, path, expected):
   with self.assertRaisesRegex(arg_utils.InvalidFieldPathError, expected):
     arg_utils.GetFieldValueFromMessage(fm.FakeMessage(), path)