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())
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))
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))
def ForMissing(cls, location): update_context = updates.Context(OrderedDict(), 'user_input', cls.EventType().UpdateMode(), was_missing=True, location=location) return cls(update_context, [])
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()
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))
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))
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)
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())
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))
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'))
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())
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))
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)
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)
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)
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)
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'])
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)
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))
def FromData(cls, backing_data): return cls( updates.Context(backing_data, 'user_input', cls.EventType().UpdateMode()), backing_data.get('user_input') or [])