예제 #1
0
  def testAttributes(self):
    backing_data = {'foo': 'bar'}
    field = 'field'
    context = updates.Context(backing_data, field, updates.Mode.RESULT)
    self.assertEqual(backing_data, context.BackingData())
    self.assertEqual(field, context.Field())
    self.assertFalse(context.WasMissing())
    self.assertEqual(('?', '?'), context.Location())

    context = updates.Context(backing_data, field, updates.Mode.RESULT,
                              was_missing=True, location='asdf')
    self.assertEqual(backing_data, context.BackingData())
    self.assertEqual(field, context.Field())
    self.assertTrue(context.WasMissing())
    self.assertEqual('asdf', context.Location())
예제 #2
0
 def ForMissing(cls, location):
   backing_data = {
       'api_call':
           collections.OrderedDict([('expect_request',
                                     collections.OrderedDict([('uri', ''),
                                                              ('method', ''),
                                                              ('headers', {}),
                                                              ('body', {
                                                                  'text': None,
                                                                  'json': {}
                                                              })])),
                                    ('return_response',
                                     collections.OrderedDict([
                                         ('status', int(httplib.OK)),
                                         ('headers', {}),
                                         ('body', None)]))])
   }
   update_context = updates.Context(
       backing_data,
       'api_call',
       cls.EventType().UpdateMode(),
       was_missing=True,
       location=location)
   return cls(
       update_context, None, None, False,
       RequestAssertion.ForMissing(),
       None,
       HTTPResponsePayload.FromBackingData(backing_data))
예제 #3
0
  def testBlockText(self):
    data_string = """\
a:
  b: "this\\nis\\nsomething\\nwith\\nnewlines"
  c: d
"""
    data = yaml.load(data_string, round_trip=True, version=yaml.VERSION_1_2)
    self.assertEqual(
        'a:\n  b: "this\\nis\\nsomething\\nwith\\nnewlines"\n  c: d\n',
        yaml.dump(data, round_trip=True))
    context = updates.Context(data, 'a', updates.Mode.RESULT)
    context.ForKey('b').Update('this\nis\na\ndifferent\nthing\nwith\nnewlines',
                               [updates.Mode.RESULT])
    self.assertEqual("""\
a:
  b: |-
    this
    is
    a
    different
    thing
    with
    newlines
  c: d
""", yaml.dump(context.BackingData(), round_trip=True))
예제 #4
0
 def ForMissing(cls, location):
     update_context = updates.Context(OrderedDict(),
                                      'user_input',
                                      cls.EventType().UpdateMode(),
                                      was_missing=True,
                                      location=location)
     return cls(update_context, [])
예제 #5
0
    def Execute(self, scenario_context):
        original_data = scenario_context.resource_ref_resolver.Resolve(
            self._original_data)
        original_data.setdefault('expect_exit', {})
        exit_event = events.ExitEvent.FromData(original_data)
        stdout_event = events.StdoutEvent.FromData(original_data)
        stderr_event = events.StderrEvent.FromData(original_data)

        stdout = io.StringIO()
        stderr = io.StringIO()
        return_code = execution_utils.Exec(self._args,
                                           no_exit=True,
                                           in_str=self._stdin,
                                           out_func=stdout.write,
                                           err_func=stderr.write)

        action_location = updates.Context(self._original_data, None,
                                          None).Location()
        try:
            with assertions.FailureCollector(
                    scenario_context.update_modes,
                    spec_name=scenario_context.spec_name,
                    action_location=action_location,
                    execution_mode=scenario_context.execution_mode.name
            ) as failures:
                failures.AddAll(exit_event.HandleReturnCode(return_code))
                failures.AddAll(stdout_event.Handle(stdout.getvalue()))
                failures.AddAll(stderr_event.Handle(stderr.getvalue()))
        finally:
            if scenario_context.update_modes:
                scenario_context.RewriteScenario()
예제 #6
0
 def ForMissing(cls, location):
   update_context = updates.Context({'expect_exit': collections.OrderedDict()},
                                    'expect_exit',
                                    cls.EventType().UpdateMode(),
                                    was_missing=True,
                                    location=location)
   return cls(update_context, 0, assertions.EqualsAssertion(None),
              assertions.EqualsAssertion(None))
예제 #7
0
    def Execute(self, scenario_context):

        if scenario_context.execution_mode == session.ExecutionMode.LOCAL:
            if self.validation_only:
                # If this command is only used to validate the side effects of a
                # previous command, don't bother running it in LOCAL mode since
                # everything is fake anyway.
                return
            ignore_api_calls = False
        else:
            # In remote mode, ignore api_call validation if this is a validation only
            # command or if api_call validation is explicitly disabled.
            ignore_api_calls = (self.validation_only
                                or not self.validate_remote_api_calls)

        update_modes = scenario_context.update_modes
        stream_mocker = scenario_context.stream_mocker
        action_location = updates.Context(self._original_data, None,
                                          None).Location()

        session_obj = None
        try:
            with assertions.FailureCollector(
                    update_modes,
                    spec_name=scenario_context.spec_name,
                    action_location=action_location,
                    execution_mode=scenario_context.execution_mode.name
            ) as failures:
                with session.Session(self._LoadEvents(
                        scenario_context.resource_ref_resolver),
                                     failures,
                                     stream_mocker,
                                     scenario_context.execution_mode,
                                     ignore_api_calls,
                                     scenario_context.resource_ref_resolver,
                                     action_location=action_location,
                                     debug=scenario_context.debug) as s:
                    session_obj = s
                    scenario_context.command_executor(
                        scenario_context.resource_ref_resolver.Resolve(
                            self.command))
        finally:
            if session_obj:
                if update_modes:
                    # Update spec file
                    event_data = session_obj.GetEventSequence()
                    if event_data is not None:
                        self._SetEventData(scenario_context, event_data)
            # If this is a cleanup step, remove the resource ref so it can no longer
            # be used and we know it doesn't require further cleanup.
            if self.cleanup_for:
                scenario_context.resource_ref_resolver.RemoveGeneratedResourceId(
                    self.cleanup_for)

        remaining_stdin = sys.stdin.read()
        if remaining_stdin:
            raise Error(
                'Not all stdin was consumed: [{}]'.format(remaining_stdin))
예제 #8
0
 def FromData(cls, backing_data):
   exit_data = backing_data['expect_exit']
   code = exit_data.get('code')
   has_message = 'message' in exit_data
   message = exit_data.get('message')
   return cls(
       updates.Context(backing_data, 'expect_exit',
                       cls.EventType().UpdateMode()), code,
       assertions.EqualsAssertion(code),
       assertions.Assertion.ForComplex(message) if has_message else None)
예제 #9
0
  def testLastKnownLocation(self):
    data_string = """\
a:
  b:
"""
    data = yaml.load(data_string, round_trip=True, version=yaml.VERSION_1_2)
    data['a']['b'] = {'c': {'d': 'value'}}
    context = updates.Context(data, 'a', updates.Mode.RESULT)
    context = context.ForKey('b.c.d')
    self.assertEqual(('2', '2'), context.Location())
예제 #10
0
 def ForMissing(cls, location):
     update_context = updates.Context(
         {'expect_file_written': OrderedDict()},
         'expect_file_written',
         cls.EventType().UpdateMode(),
         was_missing=True,
         location=location)
     return cls(update_context, assertions.EqualsAssertion(None),
                assertions.EqualsAssertion(None),
                assertions.EqualsAssertion(None),
                assertions.EqualsAssertion(False))
예제 #11
0
  def testUpdateMode(self):
    context = updates.Context({}, 'field', updates.Mode.RESULT)

    # Fail if not in update mode.
    with self.assertRaises(assertions.Error):
      with assertions.FailureCollector([]) as f:
        f.Add(assertions.Failure.ForScalar(context, 'expected', 'actual'))

    # Updates without failures
    with assertions.FailureCollector([updates.Mode.RESULT]) as f:
      f.Add(assertions.Failure.ForScalar(context, 'expected', 'actual'))
예제 #12
0
  def testLocationFromYaml(self):
    data_string = """\
a:
  b:
    c: d
    e: f
"""
    data = yaml.load(data_string, round_trip=True, version=yaml.VERSION_1_2)
    context = updates.Context(data, 'a', updates.Mode.RESULT)
    self.assertEqual(('1', '0'), context.Location())

    c = context.ForKey('b.c')
    self.assertEqual(('3', '4'), c.Location())
예제 #13
0
 def _Build(cls,
            backing_data,
            field,
            default=None,
            was_missing=False,
            location=None):
     value = backing_data.get(field, default)
     if value is None:
         value = ''
     update_context = updates.Context(backing_data,
                                      field,
                                      cls.EventType().UpdateMode(),
                                      was_missing=was_missing,
                                      location=location)
     return cls(update_context, assertions.Assertion.ForComplex(value))
예제 #14
0
  def FromData(cls, backing_data):
    """Builds a request event handler from yaml data."""
    call_data = backing_data['api_call']
    update_context = updates.Context(backing_data, 'api_call',
                                     cls.EventType().UpdateMode())

    poll_operation = call_data.get('poll_operation', None)
    is_repeatable = call_data.get('repeatable', None)
    is_optional = call_data.get('optional', False)
    request_assertion = RequestAssertion.FromCallData(call_data)
    response_assertion = ResponseAssertion.FromCallData(call_data)

    response_payload = HTTPResponsePayload.FromBackingData(backing_data)
    return cls(update_context, poll_operation, is_repeatable, is_optional,
               request_assertion, response_assertion, response_payload)
예제 #15
0
    def _Build(cls, backing_data, field, was_missing=False, location=None):
        ux_event_data = backing_data.setdefault(field, OrderedDict())
        update_context = updates.Context(backing_data,
                                         field,
                                         cls.EventType().UpdateMode(),
                                         was_missing=was_missing,
                                         location=location)

        attr_assertions = OrderedDict()
        for a in cls.EventType().UXElementAttributes():
            if was_missing or a in ux_event_data:
                # Only create assertions for things that were specified, or if the event
                # was missing, assert everything so it all gets filled in.
                attr_assertions[a] = assertions.EqualsAssertion(
                    ux_event_data.get(a, None))

        return cls(update_context, attr_assertions, ux_event_data)
예제 #16
0
  def FromData(cls, backing_data):
    file_data = backing_data['expect_file_written']
    update_context = updates.Context(backing_data, 'expect_file_written',
                                     cls.EventType().UpdateMode())

    path_assertion = assertions.EqualsAssertion(file_data.get('path'))
    contents_assertion = assertions.Assertion.ForComplex(
        file_data.get('contents'))
    binary_contents = file_data.get('binary_contents')
    if (binary_contents is not None and
        isinstance(binary_contents, six.text_type)):
      binary_contents = binary_contents.encode('utf-8')
    binary_contents_assertion = assertions.Assertion.ForComplex(binary_contents)
    is_private_assertion = assertions.EqualsAssertion(
        file_data.get('is_private') or False)

    return cls(update_context, path_assertion, contents_assertion,
               binary_contents_assertion, is_private_assertion)
예제 #17
0
  def testForKeyAndUpdate(self):
    backing_data = {'a': {'b': {'c': 'd', 'e': 'f'}}}
    context = updates.Context(backing_data, 'a', updates.Mode.RESULT)

    c = context.ForKey('b.c')

    # No update, because no modes given.
    c.Update('new d', [])
    self.assertEqual({'c': 'd', 'e': 'f'}, c.BackingData())
    self.assertEqual({'a': {'b': {'c': 'd', 'e': 'f'}}}, backing_data)

    # Updates reflected in original data.
    c.Update('new d', [updates.Mode.RESULT])
    self.assertEqual({'c': 'new d', 'e': 'f'}, c.BackingData())
    self.assertEqual({'a': {'b': {'c': 'new d', 'e': 'f'}}}, backing_data)

    # Update with None should remove element
    c.Update(None, [updates.Mode.RESULT])
    self.assertEqual({'e': 'f'}, c.BackingData())
    self.assertEqual({'a': {'b': {'e': 'f'}}}, backing_data)
예제 #18
0
  def testJsonUpdate(self):
    actual = {
        'foo': 'bar',
        'a': {'b': 'c', 'd': 'e'},
        'h': {
            'i': {'j': 'k', 'l': 'm'},
        },
        'scalar_list': ['s', 't', 'u'],
        'dict_list': [
            {'s': 't', 'u': 'v'},
            {'w': 'x', 'y': 'z'},
        ],
        'diff_len_lists': [{'a': 'b'}, 'b', 'c'],
    }
    assertion_data = {
        'foo': 'X',
        'a': {'b': 'X'},
        'h': {'i': {'j': 'X'}},
        'scalar_list': ['s', 'X', 'u'],
        'dict_list': [{'s': 'X', 'u': 'v'}, {'w': 'x', 'y': 'X'},],
        'diff_len_lists': ['X'],
    }
    assertion = assertions.JsonAssertion()
    for field, struct in assertion_data.items():
      assertion.Matches(field, struct)

    context = updates.Context(
        {'data': assertion_data}, 'data', updates.Mode.RESULT)
    failures = assertion.Check(context, actual)
    self.assertEqual(7, len(failures))

    for f in failures:
      f.Update([updates.Mode.RESULT])
    self.assertEqual('bar', assertion_data['foo'])
    self.assertEqual('c', assertion_data['a']['b'])
    self.assertEqual('k', assertion_data['h']['i']['j'])
    self.assertEqual('t', assertion_data['scalar_list'][1])
    self.assertEqual('t', assertion_data['dict_list'][0]['s'])
    self.assertEqual('z', assertion_data['dict_list'][1]['y'])
    self.assertEqual([{'a': 'b'}, 'b', 'c'], assertion_data['diff_len_lists'])
예제 #19
0
    def FromData(cls, backing_data):
        """Builds a request event handler from yaml data."""
        call_data = backing_data['api_call']
        update_context = updates.Context(backing_data, 'api_call',
                                         cls.EventType().UpdateMode())

        poll_operation = call_data.get('poll_operation', None)
        is_repeatable = call_data.get('repeatable', None)
        is_optional = call_data.get('optional', False)
        request_assertion = HTTPAssertion.ForRequest(
            call_data['expect_request'])
        response_assertion = HTTPAssertion.ForResponse(
            call_data.get('expect_response'))

        response_payload_data = call_data.get(
            'return_response') or OrderedDict()
        response_payload = HTTPResponsePayload(
            headers=response_payload_data.get('headers', {'status': '200'}),
            payload=response_payload_data.get('body', ''),
            omit_fields=response_payload_data.get('omit_fields'))

        return cls(update_context, poll_operation, is_repeatable, is_optional,
                   request_assertion, response_assertion, response_payload)
예제 #20
0
    def ForMissing(cls, location):
        backing_data = {
            'api_call':
            OrderedDict([('expect_request',
                          OrderedDict([('uri', ''), ('method', ''),
                                       ('headers', {}),
                                       ('body', {
                                           'text': None,
                                           'json': {}
                                       })])),
                         ('return_response',
                          OrderedDict([('headers', {
                              'status': '200'
                          }), ('body', None)]))])
        }
        update_context = updates.Context(backing_data,
                                         'api_call',
                                         cls.EventType().UpdateMode(),
                                         was_missing=True,
                                         location=location)
        response = backing_data['api_call']['return_response']

        return cls(
            update_context, None, None, False,
            HTTPAssertion(
                'expect_request',
                assertions.EqualsAssertion(assertions.MISSING_VALUE),
                assertions.EqualsAssertion(assertions.MISSING_VALUE),
                assertions.DictAssertion(),
                assertions.JsonAssertion().Matches('',
                                                   assertions.MISSING_VALUE),
                assertions.EqualsAssertion(assertions.MISSING_VALUE), False,
                {}), None,
            HTTPResponsePayload(headers=response['headers'],
                                payload=response['body'],
                                omit_fields=None))
예제 #21
0
 def FromData(cls, backing_data):
   return cls(
       updates.Context(backing_data, 'user_input',
                       cls.EventType().UpdateMode()),
       backing_data.get('user_input') or [])