def assertTest(self, test_name, pixel_tests, expected_checksum=None, drt_output=None, host=None, expected_text=None): port_name = 'test' host = host or MockSystemHost() test.add_unit_tests_to_mock_filesystem(host.filesystem) port = PortFactory(host).get(port_name) drt_input, drt_output = self.make_input_output( port, test_name, pixel_tests, expected_checksum, drt_output, drt_input=None, expected_text=expected_text) args = ['--platform', port_name] + self.extra_args(pixel_tests) stdin = StringIO(drt_input) stdout = StringIO() stderr = StringIO() options, args = mock_drt.parse_options(args) drt = self.make_drt(options, args, host, stdin, stdout, stderr) res = drt.run() self.assertEqual(res, 0) self.assertEqual(stdout.getvalue(), ''.join(drt_output)) self.assertEqual(stderr.getvalue(), '#EOF\n')
def test_simple_tee(self): file1, file2 = StringIO(), StringIO() tee = Tee(file1, file2) tee.write("foo bar\n") tee.write("baz\n") self.assertEqual(file1.getvalue(), "foo bar\nbaz\n") self.assertEqual(file2.getvalue(), file1.getvalue())
class SkipTest(unittest.TestCase): def setUp(self): self.logger = logging.getLogger(__name__) self.old_level = self.logger.level self.logger.setLevel(logging.INFO) self.old_propagate = self.logger.propagate self.logger.propagate = False self.log_stream = StringIO() self.handler = logging.StreamHandler(self.log_stream) self.logger.addHandler(self.handler) self.foo_was_called = False def tearDown(self): self.logger.removeHandler(self.handler) self.propagate = self.old_propagate self.logger.setLevel(self.old_level) def create_fixture_class(self): class TestSkipFixture(object): def __init__(self, callback): self.callback = callback def test_foo(self): self.callback() return TestSkipFixture def foo_callback(self): self.foo_was_called = True def test_skip_if_false(self): klass = skip_if(self.create_fixture_class(), False, 'Should not see this message.', logger=self.logger) klass(self.foo_callback).test_foo() self.assertEqual(self.log_stream.getvalue(), '') self.assertTrue(self.foo_was_called) def test_skip_if_true(self): klass = skip_if(self.create_fixture_class(), True, 'Should see this message.', logger=self.logger) klass(self.foo_callback).test_foo() self.assertEqual( self.log_stream.getvalue(), 'Skipping webkitpy.test.skip_unittest.TestSkipFixture: Should see this message.\n' ) self.assertFalse(self.foo_was_called)
def test_main(self): host = MockSystemHost() test.add_unit_tests_to_mock_filesystem(host.filesystem) stdin = StringIO() stdout = StringIO() stderr = StringIO() res = mock_drt.main(['--platform', 'test'] + self.extra_args(False), host, stdin, stdout, stderr) self.assertEqual(res, 0) self.assertEqual(stdout.getvalue(), '') self.assertEqual(stderr.getvalue(), '') self.assertEqual(host.filesystem.written_files, {})
def run_and_throw_if_fail(self, args, quiet=False, decode_output=True, **kwargs): # Cache the child's output locally so it can be used for error reports. child_out_file = StringIO() tee_stdout = sys.stdout try: if quiet: dev_null = open(os.devnull, "w") # FIXME: Does this need an encoding? tee_stdout = dev_null child_stdout = Tee(child_out_file, tee_stdout) exit_code = self._run_command_with_teed_output( args, child_stdout, **kwargs) finally: if quiet: dev_null.close() child_output = child_out_file.getvalue() child_out_file.close() if decode_output: child_output = string_utils.decode( child_output, encoding=self._child_process_encoding()) else: child_output = string_utils.encode( child_output, encoding=self._child_process_encoding()) if exit_code: raise ScriptError(script_args=args, exit_code=exit_code, output=child_output) return child_output
class _CaptureAndPassThroughStream(object): def __init__(self, stream): self._buffer = StringIO() self._stream = stream def write(self, msg): self._stream.write(msg) # Note that we don't want to capture any output generated by the debugger # because that could cause the results of capture_output() to be invalid. if not self._message_is_from_pdb(): self._buffer.write(msg) def _message_is_from_pdb(self): # We will assume that if the pdb module is in the stack then the output # is being generated by the python debugger (or the user calling something # from inside the debugger). import inspect import pdb stack = inspect.stack() return any(frame[1] == pdb.__file__.replace('.pyc', '.py') for frame in stack) def flush(self): self._stream.flush() def getvalue(self): return self._buffer.getvalue()
def set_reviewer(self, reviewer): latest_entry = self.latest_entry() latest_entry_contents = latest_entry.contents() reviewer_text = latest_entry.reviewer() found_nobody = re.search("NOBODY\s*\(OOPS!\)", latest_entry_contents, re.MULTILINE) found_reviewer_or_unreviewed = latest_entry.has_valid_reviewer() if not found_nobody and not found_reviewer_or_unreviewed and not reviewer_text: bug_url_number_of_items = len( re.findall(config_urls.bug_url_long, latest_entry_contents, re.MULTILINE)) bug_url_number_of_items += len( re.findall(config_urls.bug_url_short, latest_entry_contents, re.MULTILINE)) result = StringIO() with self._filesystem.open_text_file_for_reading( self.path) as file: for line in file: found_bug_url = re.search(config_urls.bug_url_long, line) if not found_bug_url: found_bug_url = re.search(config_urls.bug_url_short, line) result.write(line) if found_bug_url: if bug_url_number_of_items == 1: result.write("\n Reviewed by %s.\n" % reviewer) bug_url_number_of_items -= 1 self._filesystem.write_text_file(self.path, result.getvalue()) else: data = self._filesystem.read_text_file(self.path) newdata = data.replace("NOBODY (OOPS!)", reviewer) self._filesystem.write_text_file(self.path, newdata)
def test_lint_test_files__errors(self): options = optparse.Values({'platform': 'test', 'debug_rwt_logging': False}) host = MockHost() # FIXME: incorrect complaints about spacing pylint: disable=C0322 port = host.port_factory.get(options.platform, options=options) port.expectations_dict = lambda: {'foo': '-- syntax error1', 'bar': '-- syntax error2'} host.port_factory.get = lambda platform, options=None: port host.port_factory.all_port_names = lambda platform=None: [port.name()] logging_stream = StringIO() res = lint_test_expectations.lint(host, options, logging_stream) self.assertEqual(res, -1) self.assertIn('Lint failed', logging_stream.getvalue()) self.assertIn('foo:1', logging_stream.getvalue()) self.assertIn('bar:1', logging_stream.getvalue())
def set_short_description_and_bug_url(self, short_description, bug_url): result = StringIO() with self._filesystem.open_text_file_for_reading(self.path) as file: short_description_placeholder = "Need a short description (OOPS!)." bug_url_placeholder = "Need the bug URL (OOPS!)." for line in file: stripped = line.strip() if stripped == short_description_placeholder: line = self._changelog_indent + short_description + "\n" if stripped == bug_url_placeholder: line = self._changelog_indent + bug_url + "\n" result.write(line) self._filesystem.write_text_file(self.path, result.getvalue())
def test_lint_test_files(self): logging_stream = StringIO() options = optparse.Values({'platform': 'test-mac-leopard'}) host = MockHost() # pylint appears to complain incorrectly about the method overrides pylint: disable=E0202,C0322 # FIXME: incorrect complaints about spacing pylint: disable=C0322 host.port_factory.all_port_names = lambda platform=None: [platform] res = lint_test_expectations.lint(host, options, logging_stream) self.assertEqual(res, 0) self.assertIn('Lint succeeded', logging_stream.getvalue())
def delete_entries(self, num_entries): date_line_regexp = re.compile(ChangeLogEntry.date_line_regexp) rolled_over_regexp = re.compile(ChangeLogEntry.rolled_over_regexp) entries = 0 result = StringIO() with self._filesystem.open_text_file_for_reading(self.path) as file: for line in file: if date_line_regexp.match(line): entries += 1 elif rolled_over_regexp.match(line): entries = num_entries + 1 if entries > num_entries: result.write(line) self._filesystem.write_text_file(self.path, result.getvalue())
def test_no_tests_found(self): tester = Tester() errors = StringIO() # Here we need to remove any existing log handlers so that they # don't log the messages webkitpy.test while we're testing it. root_logger = logging.getLogger() root_handlers = root_logger.handlers root_logger.handlers = [] tester.printer.stream = errors tester.finder.find_names = lambda args, run_all: [] with OutputCapture(level=logging.INFO) as captured: self.assertFalse(tester.run()) root_logger.handlers = root_handlers self.assertIn('No tests to run', errors.getvalue()) self.assertIn('No tests to run', captured.root.log.getvalue())
def update_with_unreviewed_message(self, message): first_boilerplate_line_regexp = re.compile( "%sNeed a short description \(OOPS!\)\." % self._changelog_indent) removing_boilerplate = False result = StringIO() with self._filesystem.open_text_file_for_reading(self.path) as file: for line in file: if first_boilerplate_line_regexp.search(line): message_lines = self._wrap_lines(message) result.write(first_boilerplate_line_regexp.sub(message_lines, line)) # Remove all the ChangeLog boilerplate, except the first line (date, name, e-mail). removing_boilerplate = True elif removing_boilerplate: if re.search("^[1-9]", line): # each changelog entry is preceded by a date removing_boilerplate = False if not removing_boilerplate: result.write(line) self._filesystem.write_text_file(self.path, result.getvalue())
def test_no_tests_found(self): tester = Tester() errors = StringIO() # Here we need to remove any existing log handlers so that they # don't log the messages webkitpy.test while we're testing it. root_logger = logging.getLogger() root_handlers = root_logger.handlers root_logger.handlers = [] tester.printer.stream = errors tester.finder.find_names = lambda args, run_all: [] oc = OutputCapture() try: oc.capture_output() self.assertFalse(tester.run()) finally: _, _, logs = oc.restore_output() root_logger.handlers = root_handlers self.assertIn('No tests to run', errors.getvalue()) self.assertIn('No tests to run', logs)
class OutputCapture(object): # By default we capture the output to a stream. Other modules may override # this function in order to do things like pass through the output. See # webkitpy.test.main for an example. @staticmethod def stream_wrapper(stream): return StringIO() def __init__(self, log_level=logging.INFO): self.saved_outputs = dict() self._log_level = log_level def set_log_level(self, log_level): self._log_level = log_level if hasattr(self, '_logs_handler'): self._logs_handler.setLevel(self._log_level) def _capture_output_with_name(self, output_name): stream = getattr(sys, output_name) captured_output = self.stream_wrapper(stream) self.saved_outputs[output_name] = stream setattr(sys, output_name, captured_output) return captured_output def _restore_output_with_name(self, output_name): captured_output = getattr(sys, output_name).getvalue() setattr(sys, output_name, self.saved_outputs[output_name]) del self.saved_outputs[output_name] return captured_output def capture_output(self): self._logs = StringIO() self._logs_handler = logging.StreamHandler(self._logs) self._logs_handler.setLevel(self._log_level) self._logger = logging.getLogger() self._orig_log_level = self._logger.level self._logger.addHandler(self._logs_handler) self._logger.setLevel(min(self._log_level, self._orig_log_level)) return (self._capture_output_with_name("stdout"), self._capture_output_with_name("stderr")) def restore_output(self): self._logger.removeHandler(self._logs_handler) self._logger.setLevel(self._orig_log_level) self._logs_handler.flush() self._logs.flush() logs_string = self._logs.getvalue() delattr(self, '_logs_handler') delattr(self, '_logs') return (self._restore_output_with_name("stdout"), self._restore_output_with_name("stderr"), logs_string) def assert_outputs(self, testcase, function, args=[], kwargs={}, expected_stdout="", expected_stderr="", expected_exception=None, expected_logs=None): self.capture_output() try: if expected_exception: return_value = testcase.assertRaises(expected_exception, function, *args, **kwargs) else: return_value = function(*args, **kwargs) finally: (stdout_string, stderr_string, logs_string) = self.restore_output() if hasattr(testcase, 'assertMultiLineEqual'): testassert = testcase.assertMultiLineEqual else: testassert = testcase.assertEqual testassert(stdout_string, expected_stdout) testassert(stderr_string, expected_stderr) if expected_logs is not None: testassert(logs_string, expected_logs) # This is a little strange, but I don't know where else to return this information. return return_value
def _log_exception(self): s = StringIO() traceback.print_exc(file=s) for l in s.getvalue().splitlines(): _log.error(' ' + l.rstrip())
def test_stringio(self): stream = StringIO() stream.write('string data') self.assertEqual(stream.getvalue(), 'string data')
def filter_branch(self, range, identifier_template=None, environment_shell=None): # We can't effectively mock the bash script in the command, but we can mock the python code that # script calls, which is where the program logic is. head, start = range.split('...') head = self.find(head) start = self.find(start) commits_to_edit = [] for commit in reversed(self.commits[head.branch]): if commit.branch == start.branch and commit.identifier <= start.identifier: break commits_to_edit.insert(0, commit) if head.branch != self.default_branch: for commit in reversed( self.commits[self.default_branch][:head.branch_point]): if commit.identifier <= start.identifier: break commits_to_edit.insert(0, commit) stdout = StringIO() original_env = { key: os.environ.get('OLDPWD') for key in [ 'OLDPWD', 'GIT_COMMIT', 'GIT_AUTHOR_NAME', 'GIT_AUTHOR_EMAIL', 'GIT_COMMITTER_NAME', 'GIT_COMMITTER_EMAIL', ] } try: count = 0 os.environ['OLDPWD'] = self.path for commit in commits_to_edit: count += 1 os.environ['GIT_COMMIT'] = commit.hash os.environ['GIT_AUTHOR_NAME'] = commit.author.name os.environ['GIT_AUTHOR_EMAIL'] = commit.author.email os.environ['GIT_COMMITTER_NAME'] = commit.author.name os.environ['GIT_COMMITTER_EMAIL'] = commit.author.email stdout.write( 'Rewrite {hash} ({count}/{total}) (--- seconds passed, remaining --- predicted)\n' .format( hash=commit.hash, count=count, total=len(commits_to_edit), )) if identifier_template: messagefile = StringIO() messagefile.write(commit.message) messagefile.seek(0) with OutputCapture() as captured: message_main(messagefile, identifier_template) lines = captured.stdout.getvalue().splitlines() if lines[-1].startswith('git-svn-id: https://svn'): lines.pop(-1) commit.message = '\n'.join(lines) if not environment_shell: continue if re.search(r'echo "Overwriting', environment_shell): stdout.write('Overwriting {}\n'.format(commit.hash)) match = re.search(r'(?P<json>\S+\.json)', environment_shell) if match: with OutputCapture() as captured: committer_main(match.group('json')) captured.stdout.seek(0) for line in captured.stdout.readlines(): line = line.rstrip() os.environ[line.split(' ')[0]] = ' '.join( line.split(' ')[1:]) commit.author = Contributor( name=os.environ['GIT_AUTHOR_NAME'], emails=[os.environ['GIT_AUTHOR_EMAIL']]) if re.search(r'echo "\s+', environment_shell): for key in [ 'GIT_AUTHOR_NAME', 'GIT_AUTHOR_EMAIL', 'GIT_COMMITTER_NAME', 'GIT_COMMITTER_EMAIL' ]: stdout.write(' {}={}\n'.format( key, os.environ[key])) finally: for key, value in original_env.items(): if value is not None: os.environ[key] = value else: del os.environ[key] return mocks.ProcessCompletion( returncode=0, stdout=stdout.getvalue(), )