def test_running_pids(self): if sys.platform in ("win32", "cygwin"): return # This function isn't implemented on Windows yet. executive = Executive() pids = executive.running_pids() self.assertTrue(os.getpid() in pids)
def test_coverage_works(self): # This is awkward; by design, running test-webkitpy -c will # create a .coverage file in tools, so we need to be # careful not to clobber an existing one, and to clean up. # FIXME: This design needs to change since it means we can't actually # run this method itself under coverage properly. filesystem = FileSystem() executive = Executive() module_path = filesystem.path_to_module(self.__module__) script_dir = module_path[0:module_path.find('webkitpy') - 1] coverage_file = filesystem.join(script_dir, '.coverage') coverage_file_orig = None if filesystem.exists(coverage_file): coverage_file_orig = coverage_file + '.orig' filesystem.move(coverage_file, coverage_file_orig) try: proc = executive.popen([sys.executable, filesystem.join(script_dir, 'test-webkitpy'), '-c', STUBS_CLASS + '.test_empty'], stdout=executive.PIPE, stderr=executive.PIPE) out, _ = proc.communicate() retcode = proc.returncode self.assertEqual(retcode, 0) self.assertIn('Cover', out) finally: if coverage_file_orig: filesystem.move(coverage_file_orig, coverage_file) elif filesystem.exists(coverage_file): filesystem.remove(coverage_file)
def test_run_command_with_unicode(self): """Validate that it is safe to pass unicode() objects to Executive.run* methods, and they will return unicode() objects by default unless decode_output=False""" unicode_tor_input = u"WebKit \u2661 Tor Arne Vestb\u00F8!" if sys.platform == 'win32': encoding = 'mbcs' else: encoding = 'utf-8' encoded_tor = unicode_tor_input.encode(encoding) # On Windows, we expect the unicode->mbcs->unicode roundtrip to be # lossy. On other platforms, we expect a lossless roundtrip. if sys.platform == 'win32': unicode_tor_output = encoded_tor.decode(encoding) else: unicode_tor_output = unicode_tor_input executive = Executive() output = executive.run_command(command_line('cat'), input=unicode_tor_input) self.assertEqual(output, unicode_tor_output) output = executive.run_command(command_line('echo', unicode_tor_input)) self.assertEqual(output, unicode_tor_output) output = executive.run_command(command_line('echo', unicode_tor_input), decode_output=False) self.assertEqual(output, encoded_tor) # Make sure that str() input also works. output = executive.run_command(command_line('cat'), input=encoded_tor, decode_output=False) self.assertEqual(output, encoded_tor)
def serial_test_running_pids(self): if sys.platform.startswith('win') or sys.platform == "cygwin": return # This function isn't implemented on Windows yet. executive = Executive() pids = executive.running_pids() self.assertIn(os.getpid(), pids)
def test_kill_process(self): executive = Executive() process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running executive.kill_process(process.pid) # Killing again should fail silently. executive.kill_process(process.pid)
def _run_pylint(self, path): wkf = WebKitFinder(FileSystem()) executive = Executive() return executive.run_command([sys.executable, wkf.path_from_depot_tools_base('pylint.py'), '--output-format=parseable', '--errors-only', '--rcfile=' + wkf.path_from_webkit_base('Tools', 'Scripts', 'webkitpy', 'pylintrc'), path], error_handler=executive.ignore_error)
def integration_test_run_wdiff(self): executive = Executive() # This may fail on some systems. We could ask the port # object for the wdiff path, but since we don't know what # port object to use, this is sufficient for now. try: wdiff_path = executive.run_command(["which", "wdiff"]).rstrip() except Exception, e: wdiff_path = None
def test_kill_all(self): executive = Executive() # FIXME: This may need edits to work right on windows. # We use "yes" because it loops forever. process = subprocess.Popen(["yes"], stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running executive.kill_all("yes") self.assertEqual(process.wait(), -signal.SIGTERM) # Killing again should fail silently. executive.kill_all("yes")
def integration_test_coverage_works(self): filesystem = FileSystem() executive = Executive() module_path = filesystem.path_to_module(self.__module__) script_dir = module_path[0:module_path.find('webkitpy') - 1] proc = executive.popen([sys.executable, filesystem.join(script_dir, 'test-webkitpy'), '-c', STUBS_CLASS + '.test_empty'], stdout=executive.PIPE, stderr=executive.PIPE) out, _ = proc.communicate() retcode = proc.returncode self.assertEqual(retcode, 0) self.assertIn('Cover', out)
def serial_test_kill_process(self): if sys.platform in ("win32", "cygwin"): return # Windows does not return consistent exit codes. executive = Executive() process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running executive.kill_process(process.pid) self.assertEqual(process.wait(), -signal.SIGKILL) # Killing again should fail silently. executive.kill_process(process.pid)
def test_kill_process(self): executive = Executive() process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running executive.kill_process(process.pid) # Note: Can't use a ternary since signal.SIGKILL is undefined for sys.platform == "win32" if sys.platform == "win32": expected_exit_code = 1 else: expected_exit_code = -signal.SIGKILL self.assertEqual(process.wait(), expected_exit_code) # Killing again should fail silently. executive.kill_process(process.pid)
def _run_pylint(self, path): wkf = WebKitFinder(FileSystem()) executive = Executive() env = os.environ.copy() env['PYTHONPATH'] = ('%s%s%s' % (wkf.path_from_webkit_base('Tools', 'Scripts'), os.pathsep, wkf.path_from_webkit_base('Tools', 'Scripts', 'webkitpy', 'thirdparty'))) return executive.run_command([sys.executable, wkf.path_from_depot_tools_base('pylint.py'), '--output-format=parseable', '--errors-only', '--rcfile=' + wkf.path_from_webkit_base('Tools', 'Scripts', 'webkitpy', 'pylintrc'), path], env=env, error_handler=executive.ignore_error)
def test_kill_process(self): executive = Executive() # We use "yes" because it loops forever. process = subprocess.Popen(["yes"], stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running executive.kill_process(process.pid) # Note: Can't use a ternary since signal.SIGKILL is undefined for sys.platform == "win32" if sys.platform == "win32": expected_exit_code = 0 # taskkill.exe results in exit(0) else: expected_exit_code = -signal.SIGKILL self.assertEqual(process.wait(), expected_exit_code) # Killing again should fail silently. executive.kill_process(process.pid)
def test_kill_process(self): executive = Executive() process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running executive.kill_process(process.pid) # Note: Can't use a ternary since signal.SIGKILL is undefined for sys.platform == "win32" if sys.platform == "win32": # FIXME: https://bugs.webkit.org/show_bug.cgi?id=54790 # We seem to get either 0 or 1 here for some reason. self.assertTrue(process.wait() in (0, 1)) else: expected_exit_code = -signal.SIGKILL self.assertEqual(process.wait(), expected_exit_code) # Killing again should fail silently. executive.kill_process(process.pid)
def test_kill_all(self): executive = Executive() # We use "yes" because it loops forever. process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running executive.kill_all(never_ending_command()[0]) # Note: Can't use a ternary since signal.SIGTERM is undefined for sys.platform == "win32" if sys.platform == "cygwin": expected_exit_code = 0 # os.kill results in exit(0) for this process. elif sys.platform == "win32": expected_exit_code = 1 else: expected_exit_code = -signal.SIGTERM self.assertEqual(process.wait(), expected_exit_code) # Killing again should fail silently. executive.kill_all(never_ending_command()[0])
def __init__(self, filesystem=None, webkit_finder=None): self.filesystem = filesystem or FileSystem() self.executive = Executive() self.finder = Finder(self.filesystem) self.printer = Printer(sys.stderr) self.webkit_finder = webkit_finder or WebKitFinder(self.filesystem) self._options = None
def test_default_configuration__standalone(self): # FIXME: This test runs a standalone python script to test # reading the default configuration to work around any possible # caching / reset bugs. See https://bugs.webkit.org/show_bug.cgi?id=49360 # for the motivation. We can remove this test when we remove the # global configuration cache in config.py. e = Executive() fs = FileSystem() c = config.Config(e, fs) script = WebKitFinder(fs).path_from_webkit_base('Tools', 'Scripts', 'webkitpy', 'layout_tests', 'port', 'config_standalone.py') # Note: don't use 'Release' here, since that's the normal default. expected = 'Debug' args = [sys.executable, script, '--mock', expected] actual = e.run_command(args).rstrip() self.assertEqual(actual, expected)
def script_shell_command(cls, script_name): script_path = cls.script_path(script_name) # Win32 does not support shebang. We need to detect the interpreter ourself. if sys.platform == 'win32': interpreter = Executive.interpreter_for_script(script_path) if interpreter: return [interpreter, script_path] return [script_path]
def test_run_command_with_unicode(self): """Validate that it is safe to pass unicode() objects to Executive.run* methods, and they will return unicode() objects by default unless decode_output=False""" executive = Executive() unicode_tor = u"WebKit \u2661 Tor Arne Vestb\u00F8!" utf8_tor = unicode_tor.encode("utf-8") output = executive.run_command(["cat"], input=unicode_tor) self.assertEquals(output, unicode_tor) output = executive.run_command(["echo", "-n", unicode_tor]) self.assertEquals(output, unicode_tor) output = executive.run_command(["echo", "-n", unicode_tor], decode_output=False) self.assertEquals(output, utf8_tor) # Make sure that str() input also works. output = executive.run_command(["cat"], input=utf8_tor, decode_output=False) self.assertEquals(output, utf8_tor) # FIXME: We should only have one run* method to test output = executive.run_and_throw_if_fail(["echo", "-n", unicode_tor], quiet=True) self.assertEquals(output, unicode_tor) output = executive.run_and_throw_if_fail(["echo", "-n", unicode_tor], quiet=True, decode_output=False) self.assertEquals(output, utf8_tor)
def serial_test_kill_all(self): executive = Executive() process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE) self.assertIsNone(process.poll()) # Process is running executive.kill_all(never_ending_command()[0]) # Note: Can't use a ternary since signal.SIGTERM is undefined for sys.platform == "win32" if sys.platform == "cygwin": expected_exit_code = 0 # os.kill results in exit(0) for this process. self.assertEqual(process.wait(), expected_exit_code) elif sys.platform == "win32": # FIXME: https://bugs.webkit.org/show_bug.cgi?id=54790 # We seem to get either 0 or 1 here for some reason. self.assertIn(process.wait(), (0, 1)) else: expected_exit_code = -signal.SIGTERM self.assertEqual(process.wait(), expected_exit_code) # Killing again should fail silently. executive.kill_all(never_ending_command()[0])
def assert_interpreter_for_content(self, intepreter, content): fs = MockFileSystem() tempfile, temp_name = fs.open_binary_tempfile('') tempfile.write(content) tempfile.close() file_interpreter = Executive.interpreter_for_script(temp_name, fs) self.assertEqual(file_interpreter, intepreter)
def test_default_configuration__standalone(self): # FIXME: This test runs a standalone python script to test # reading the default configuration to work around any possible # caching / reset bugs. See https://bugs.webkit.org/show_bug.cgi?id=49360 # for the motivation. We can remove this test when we remove the # global configuration cache in config.py. e = Executive() fs = FileSystem() c = config.Config(e, fs) script = c.path_from_webkit_base("Tools", "Scripts", "webkitpy", "layout_tests", "port", "config_standalone.py") # Note: don't use 'Release' here, since that's the normal default. expected = "Debug" # FIXME: Why are we running a python subprocess here?? args = [sys.executable, script, "--mock", expected] actual = e.run_command(args).rstrip() self.assertEqual(actual, expected)
def diff_diff(cls, diff1, diff2, diff1_suffix, diff2_suffix, executive=None): # Now this is where it gets complicated, we need to compare our diff to the diff at landed_revision. diff1_patch = tempfile.NamedTemporaryFile(suffix=diff1_suffix + '.patch') diff1_patch.write(diff1) diff1_patch.flush() # Check if there are any differences in the patch that don't happen diff2_patch = tempfile.NamedTemporaryFile(suffix=diff2_suffix + '.patch') diff2_patch.write(diff2) diff2_patch.flush() # Diff the two diff's together... if not executive: executive = Executive() try: return executive.run_command( ["interdiff", diff1_patch.name, diff2_patch.name], decode_output=False) except ScriptError, e: _log.warning("Unable to find interdiff util (part of GNU difftools package) which is required.") raise
def serial_test_kill_process(self): executive = Executive() process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running executive.kill_process(process.pid) # Note: Can't use a ternary since signal.SIGKILL is undefined for sys.platform == "win32" if sys.platform == "win32": # FIXME: https://bugs.webkit.org/show_bug.cgi?id=54790 # We seem to get either 0 or 1 here for some reason. self.assertIn(process.wait(), (0, 1)) elif sys.platform == "cygwin": # FIXME: https://bugs.webkit.org/show_bug.cgi?id=98196 # cygwin seems to give us either SIGABRT or SIGKILL # Native Windows (via Cygwin) returns ENOTBLK (-15) self.assertIn(process.wait(), (-signal.SIGABRT, -signal.SIGKILL, -15)) else: expected_exit_code = -signal.SIGTERM self.assertEqual(process.wait(), expected_exit_code) # Killing again should fail silently. executive.kill_process(process.pid)
def __init__(self, lock_path, lock_file_prefix="WebKitHttpd.lock.", guard_lock="WebKit.lock"): self._lock_path = lock_path if not self._lock_path: self._lock_path = tempfile.gettempdir() self._lock_file_prefix = lock_file_prefix self._lock_file_path_prefix = os.path.join(self._lock_path, self._lock_file_prefix) self._guard_lock_file = os.path.join(self._lock_path, guard_lock) self._guard_lock = FileLock(self._guard_lock_file) self._process_lock_file_name = "" self._executive = Executive()
def mock_checkout_for_test(self): executive = Executive() def mock_run(*args, **kwargs): # Note that we use a real Executive here, not a MockExecutive, so we can test that we're # invoking commit-log-editor correctly. env = os.environ.copy() env['CHANGE_LOG_EMAIL_ADDRESS'] = '*****@*****.**' kwargs['env'] = env return executive.run_command(*args, **kwargs) detector = SCMDetector(self.filesystem, executive) real_scm = detector.detect_scm_system(self.webkit_base) mock_scm = MockSCM() mock_scm.run = mock_run real_checkout = Checkout(real_scm) checkout = Checkout(mock_scm) checkout.script_path = real_checkout.script_path checkout.modified_changelogs = lambda git_commit, changed_files=None: self.changelog_paths return checkout
def test_run_command_with_unicode(self): """Validate that it is safe to pass unicode() objects to Executive.run* methods, and they will return unicode() objects by default unless decode_output=False""" unicode_tor_input = u"WebKit \u2661 Tor Arne Vestb\u00F8!" if sys.platform == "win32": encoding = "mbcs" else: encoding = "utf-8" encoded_tor = unicode_tor_input.encode(encoding) # On Windows, we expect the unicode->mbcs->unicode roundtrip to be # lossy. On other platforms, we expect a lossless roundtrip. if sys.platform == "win32": unicode_tor_output = encoded_tor.decode(encoding) else: unicode_tor_output = unicode_tor_input executive = Executive() output = executive.run_command(cat.command_arguments(), input=unicode_tor_input) self.assertEquals(output, unicode_tor_output) output = executive.run_command(echo.command_arguments("-n", unicode_tor_input)) self.assertEquals(output, unicode_tor_output) output = executive.run_command(echo.command_arguments("-n", unicode_tor_input), decode_output=False) self.assertEquals(output, encoded_tor) # Make sure that str() input also works. output = executive.run_command(cat.command_arguments(), input=encoded_tor, decode_output=False) self.assertEquals(output, encoded_tor) # FIXME: We should only have one run* method to test output = executive.run_and_throw_if_fail(echo.command_arguments("-n", unicode_tor_input), quiet=True) self.assertEquals(output, unicode_tor_output) output = executive.run_and_throw_if_fail( echo.command_arguments("-n", unicode_tor_input), quiet=True, decode_output=False ) self.assertEquals(output, encoded_tor)
def serial_test_run_in_parallel(self): # We run this test serially to avoid overloading the machine and throwing off the timing. if sys.platform in ("win32", "cygwin"): return # This function isn't implemented properly on windows yet. import multiprocessing NUM_PROCESSES = 4 DELAY_SECS = 0.25 cmd_line = [ sys.executable, '-c', 'import time; time.sleep(%f); print "hello"' % DELAY_SECS ] cwd = os.getcwd() commands = [tuple([cmd_line, cwd])] * NUM_PROCESSES start = time.time() command_outputs = Executive().run_in_parallel(commands, processes=NUM_PROCESSES) done = time.time() self.assertTrue(done - start < NUM_PROCESSES * DELAY_SECS) self.assertEquals([output[1] for output in command_outputs], ["hello\n"] * NUM_PROCESSES) self.assertEquals([], multiprocessing.active_children())
def __init__(self, cwd=None, executive=None, filesystem=None, platform=None): self._executive = executive or Executive() self._filesystem = filesystem or FileSystem() self._executable_name = self.find_executable_name( self._executive, platform) self.cwd = cwd or self._filesystem.abspath(self._filesystem.getcwd()) if not self.in_working_directory(self.cwd): module_directory = self._filesystem.abspath( self._filesystem.dirname( self._filesystem.path_to_module(self.__module__))) _log.info( 'The current directory (%s) is not in a git repo, trying directory %s.', cwd, module_directory) if self.in_working_directory(module_directory): self.cwd = module_directory _log.error('Failed to find Git repo for %s or %s', cwd, module_directory) self.checkout_root = self.find_checkout_root(self.cwd)
def test_commit_message_for_this_commit(self): executive = Executive() def mock_run(*args, **kwargs): # Note that we use a real Executive here, not a MockExecutive, so we can test that we're # invoking commit-log-editor correctly. env = os.environ.copy() env['CHANGE_LOG_EMAIL_ADDRESS'] = '*****@*****.**' kwargs['env'] = env return executive.run_command(*args, **kwargs) detector = SCMDetector(self.filesystem, executive) real_scm = detector.detect_scm_system(self.old_cwd) mock_scm = MockSCM() mock_scm.run = mock_run mock_scm.script_path = real_scm.script_path checkout = Checkout(mock_scm) checkout.modified_changelogs = lambda git_commit, changed_files=None: self.changelogs commit_message = checkout.commit_message_for_this_commit(git_commit=None, return_stderr=True) # Throw away the first line - a warning about unknown VCS root. commit_message.message_lines = commit_message.message_lines[1:] self.assertMultiLineEqual(commit_message.message(), self.expected_commit_message)
def serial_test_kill_process(self): executive = Executive() with executive.popen(never_ending_command(), stdout=subprocess.PIPE) as process: self.assertEqual(process.poll(), None) # Process is running executive.kill_process(process.pid) # Note: Can't use a ternary since signal.SIGKILL is undefined for sys.platform == "win32" if sys.platform.startswith('win'): # FIXME: https://bugs.webkit.org/show_bug.cgi?id=54790 # We seem to get either 0 or 1 here for some reason. self.assertIn(process.wait(), (0, 1)) elif sys.platform == "cygwin": # FIXME: https://bugs.webkit.org/show_bug.cgi?id=98196 # cygwin seems to give us either SIGABRT or SIGKILL # Native Windows (via Cygwin) returns ENOTBLK (-15) self.assertIn(process.wait(), (-signal.SIGABRT, -signal.SIGKILL, -15)) else: expected_exit_code = -signal.SIGTERM self.assertEqual(process.wait(), expected_exit_code) # Killing again should fail silently. executive.kill_process(process.pid)
def serial_test_kill_process(self): executive = Executive() process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running executive.kill_process(process.pid) # Note: Can't use a ternary since signal.SIGKILL is undefined for sys.platform == "win32" if sys.platform == "win32": # FIXME: https://bugs.webkit.org/show_bug.cgi?id=54790 # We seem to get either 0 or 1 here for some reason. self.assertTrue(process.wait() in (0, 1)) elif sys.platform == "cygwin": # FIXME: https://bugs.webkit.org/show_bug.cgi?id=98196 # cygwin seems to give us either SIGABRT or SIGKILL self.assertTrue(process.wait() in (-signal.SIGABRT, -signal.SIGKILL)) else: expected_exit_code = -signal.SIGKILL self.assertEqual(process.wait(), expected_exit_code) # Killing again should fail silently. executive.kill_process(process.pid)
def test_run_command_with_unicode(self): """Validate that it is safe to pass unicode() objects to Executive.run* methods, and they will return unicode() objects by default unless decode_output=False """ unicode_tor_input = u"WebKit \u2661 Tor Arne Vestb\u00F8!" if sys.platform == 'win32': encoding = 'mbcs' else: encoding = 'utf-8' encoded_tor = unicode_tor_input.encode(encoding) # On Windows, we expect the unicode->mbcs->unicode roundtrip to be # lossy. On other platforms, we expect a lossless roundtrip. if sys.platform == 'win32': unicode_tor_output = encoded_tor.decode(encoding) else: unicode_tor_output = unicode_tor_input executive = Executive() output = executive.run_command(command_line('cat'), input=unicode_tor_input) self.assertEqual(output, unicode_tor_output) output = executive.run_command(command_line('echo', unicode_tor_input)) self.assertEqual(output, unicode_tor_output) output = executive.run_command(command_line('echo', unicode_tor_input), decode_output=False) self.assertEqual(output, encoded_tor) # Make sure that str() input also works. output = executive.run_command(command_line('cat'), input=encoded_tor, decode_output=False) self.assertEqual(output, encoded_tor)
def test_popen_args(self): executive = Executive() # Explicitly naming the 'args' argument should not thow an exception. executive.popen(args=command_line('echo', 1), stdout=executive.PIPE).wait()
def _assert_windows_image_name(self, name, expected_windows_name): executive = Executive() windows_name = executive._windows_image_name(name) self.assertEqual(windows_name, expected_windows_name)
def test_run_command_args_type(self): executive = Executive() self.assertRaises(AssertionError, executive.run_command, "echo") self.assertRaises(AssertionError, executive.run_command, u"echo") executive.run_command(command_line('echo', 'foo')) executive.run_command(tuple(command_line('echo', 'foo')))
def script_shell_command(self, script_name): script_path = self.script_path(script_name) return Executive.shell_command_for_script(script_path)
def serial_test_check_running_pid(self): executive = Executive() self.assertTrue(executive.check_running_pid(os.getpid())) # Maximum pid number on Linux is 32768 by default self.assertFalse(executive.check_running_pid(100000))
def test_popen_args(self): executive = Executive() # Explicitly naming the 'args' argument should not thow an exception. with executive.popen(args=command_line('echo', 1), stdout=executive.PIPE) as process: process.wait()
def test_timeout_exceeded_exit_code(self): executive = Executive() exit_code = executive.run_command(command_line('sleep', 'infinity'), timeout_seconds=0.01, return_exit_code=True) self.assertNotEqual(exit_code, 0)
def test_run_in_parallel_assert_nonempty(self): with self.assertRaises(AssertionError): Executive().run_in_parallel([])
def bindings_tests(output_directory, verbose): executive = Executive() def diff(filename1, filename2): # Python's difflib module is too slow, especially on long output, so # run external diff(1) command cmd = [ 'diff', '-u', # unified format '-N', # treat absent files as empty filename1, filename2 ] # Return output and don't raise exception, even though diff(1) has # non-zero exit if files differ. return executive.run_command(cmd, error_handler=lambda x: None) def delete_cache_files(): # FIXME: Instead of deleting cache files, don't generate them. cache_files = [ os.path.join(output_directory, output_file) for output_file in os.listdir(output_directory) if (output_file in ( 'lextab.py', # PLY lex 'lextab.pyc', 'parsetab.pickle') or # PLY yacc output_file.endswith('.cache')) ] # Jinja for cache_file in cache_files: os.remove(cache_file) def identical_file(reference_filename, output_filename): reference_basename = os.path.basename(reference_filename) if not os.path.isfile(reference_filename): print 'Missing reference file!' print '(if adding new test, update reference files)' print reference_basename print return False if not filecmp.cmp(reference_filename, output_filename): # cmp is much faster than diff, and usual case is "no differance", # so only run diff if cmp detects a difference print 'FAIL: %s' % reference_basename print diff(reference_filename, output_filename) return False if verbose: print 'PASS: %s' % reference_basename return True def identical_output_files(): file_pairs = [(os.path.join(reference_directory, output_file), os.path.join(output_directory, output_file)) for output_file in os.listdir(output_directory)] return all([ identical_file(reference_filename, output_filename) for (reference_filename, output_filename) in file_pairs ]) def no_excess_files(): generated_files = set(os.listdir(output_directory)) generated_files.add('.svn') # Subversion working copy directory excess_files = [ output_file for output_file in os.listdir(reference_directory) if output_file not in generated_files ] if excess_files: print( 'Excess reference files! ' '(probably cruft from renaming or deleting):\n' + '\n'.join(excess_files)) return False return True try: generate_interface_dependencies() idl_compiler = IdlCompilerV8(output_directory, interfaces_info=interfaces_info, only_if_changed=True) idl_basenames = [ filename for filename in os.listdir(test_input_directory) if (filename.endswith('.idl') and # Dependencies aren't built # (they are used by the dependent) filename not in DEPENDENCY_IDL_FILES) ] for idl_basename in idl_basenames: idl_path = os.path.realpath( os.path.join(test_input_directory, idl_basename)) idl_compiler.compile_file(idl_path) if verbose: print 'Compiled: %s' % filename finally: delete_cache_files() # Detect all changes passed = identical_output_files() passed &= no_excess_files() if passed: if verbose: print print PASS_MESSAGE return 0 print print FAIL_MESSAGE return 1
def timestamp_of_revision(self, path, revision): # We use --xml to get timestamps like 2013-02-08T08:18:04.964409Z repository_root = self.value_from_svn_info(self.checkout_root, 'Repository Root') info_output = Executive().run_command([self.executable_name, 'log', '-r', revision, '--xml', repository_root], cwd=path).rstrip() match = re.search(r"^<date>(?P<value>.+)</date>\r?$", info_output, re.MULTILINE) return match.group('value')
class Bisector(object): def __init__(self, tests, is_debug): self.executive = Executive() self.tests = tests self.expected_failure = tests[-1] self.is_debug = is_debug self.webkit_finder = WebKitFinder(FileSystem()) def bisect(self): if self.test_fails_in_isolation(): self.buckets = [Bucket([self.expected_failure])] print '%s fails when run in isolation.' % self.expected_failure self.print_result() return 0 if not self.test_fails(self.tests): _log.error('%s does not fail', self.expected_failure) return 1 # Split the list of test into buckets. Each bucket has at least one test required to cause # the expected failure at the end. Split buckets in half until there are only buckets left # with one item in them. self.buckets = [ Bucket(self.tests[:-1]), Bucket([self.expected_failure]) ] while not self.is_done(): self.print_progress() self.split_largest_bucket() self.print_result() self.verify_non_flaky() return 0 def test_fails_in_isolation(self): return self.test_bucket_list_fails([Bucket([self.expected_failure])]) def verify_non_flaky(self): print 'Verifying the failure is not flaky by running 10 times.' count_failures = 0 for _ in range(0, 10): if self.test_bucket_list_fails(self.buckets): count_failures += 1 print 'Failed %d/10 times' % count_failures def print_progress(self): count = 0 for bucket in self.buckets: count += len(bucket.tests) print '%d tests left, %d buckets' % (count, len(self.buckets)) def print_result(self): tests = [] for bucket in self.buckets: tests += bucket.tests extra_args = ' --debug' if self.is_debug else '' print 'run-webkit-tests%s --child-processes=1 --order=none %s' % ( extra_args, ' '.join(tests)) def is_done(self): for bucket in self.buckets: if bucket.size() > 1: return False return True def split_largest_bucket(self): index = 0 largest_index = 0 largest_size = 0 for bucket in self.buckets: if bucket.size() > largest_size: largest_index = index largest_size = bucket.size() index += 1 bucket_to_split = self.buckets[largest_index] halfway_point = int(largest_size / 2) first_half = Bucket(bucket_to_split.tests[:halfway_point]) second_half = Bucket(bucket_to_split.tests[halfway_point:]) buckets_before = self.buckets[:largest_index] buckets_after = self.buckets[largest_index + 1:] # Do the second half first because it tends to be faster because the http tests are front-loaded and slow. new_buckets = buckets_before + [second_half] + buckets_after if self.test_bucket_list_fails(new_buckets): self.buckets = new_buckets return new_buckets = buckets_before + [first_half] + buckets_after if self.test_bucket_list_fails(new_buckets): self.buckets = new_buckets return self.buckets = buckets_before + [first_half, second_half ] + buckets_after def test_bucket_list_fails(self, buckets): tests = [] for bucket in buckets: tests += bucket.tests return self.test_fails(tests) def test_fails(self, tests): extra_args = ['--debug'] if self.is_debug else [] path_to_run_webkit_tests = self.webkit_finder.path_from_webkit_base( 'Tools', 'Scripts', 'run-webkit-tests') output = self.executive.popen([ path_to_run_webkit_tests, '--child-processes', '1', '--order', 'none', '--no-retry', '--no-show-results', '--verbose' ] + extra_args + tests, stdout=subprocess.PIPE, stderr=subprocess.PIPE) failure_string = self.expected_failure + ' failed' if failure_string in output.stderr.read(): return True return False
def test_auto_stringify_args(self): executive = Executive() executive.run_command(command_line('echo', 1)) with executive.popen(command_line('echo', 1), stdout=executive.PIPE) as process: process.wait() self.assertEqual('echo 1', executive.command_for_printing(['echo', 1]))
def test_timeout_satisfied(self): executive = Executive() executive.run_command(command_line('sleep', '0'), timeout_seconds=1000)
def test_check_running_pid(self): executive = Executive() self.assertTrue(executive.check_running_pid(os.getpid())) # According to the proc(5) man page, on 64-bit linux systems, # pid_max can be set to any value up to 2^22 (approximately 4 million). self.assertFalse(executive.check_running_pid(5000000))
def test_run_in_parallel_assert_nonempty(self): self.assertRaises(AssertionError, Executive().run_in_parallel, [])
def test_running_pids(self): executive = Executive() pids = executive.running_pids() self.assertIn(os.getpid(), pids)
def makeArgs(self): # FIXME: This shouldn't use a static Executive(). args = '--makeargs="-j%s"' % Executive().cpu_count() if os.environ.has_key('MAKEFLAGS'): args = '--makeargs="%s"' % os.environ['MAKEFLAGS'] return args
def run_bad_command(): Executive().run_command(["foo_bar_command_blah"], error_handler=Executive.ignore_error, return_exit_code=True)
def check_ruby(self): executive = Executive() try: result = executive.run_command(['ruby', '--version']) except OSError, e: return False
def __init__(self, platforminfo=None): # We cannot get the PlatformInfo object from a SystemHost because # User is part of SystemHost itself. self._platforminfo = platforminfo or PlatformInfo( sys, platform, Executive())
def test_check_running_pid(self): executive = Executive() self.assertTrue(executive.check_running_pid(os.getpid())) # Maximum pid number on Linux is 32768 by default self.assertFalse(executive.check_running_pid(100000))
def test_run_command_with_bad_command(self): self.assertRaises(OSError, lambda: Executive().run_command(["foo_bar_command_blah"], ignore_errors=True, return_exit_code=True)) self.assertRaises(OSError, lambda: Executive().run_and_throw_if_fail(["foo_bar_command_blah"], quiet=True)) self.assertRaises(ScriptError, lambda: Executive().run_command(['python', '-c', 'import sys; sys.exit(1)'])) self.assertRaises(ScriptError, lambda: Executive().run_and_throw_if_fail(['python', '-c', 'import sys; sys.exit(1)'], quiet=True))
def bindings_tests(output_directory, verbose): executive = Executive() def list_files(directory): files = [] for component in os.listdir(directory): if component not in COMPONENT_DIRECTORY: continue directory_with_component = os.path.join(directory, component) for filename in os.listdir(directory_with_component): files.append(os.path.join(directory_with_component, filename)) return files def diff(filename1, filename2): # Python's difflib module is too slow, especially on long output, so # run external diff(1) command cmd = ['diff', '-u', # unified format '-N', # treat absent files as empty filename1, filename2] # Return output and don't raise exception, even though diff(1) has # non-zero exit if files differ. return executive.run_command(cmd, error_handler=lambda x: None) def is_cache_file(filename): return filename.endswith('.cache') def delete_cache_files(): # FIXME: Instead of deleting cache files, don't generate them. cache_files = [path for path in list_files(output_directory) if is_cache_file(os.path.basename(path))] for cache_file in cache_files: os.remove(cache_file) def identical_file(reference_filename, output_filename): reference_basename = os.path.basename(reference_filename) if not os.path.isfile(reference_filename): print 'Missing reference file!' print '(if adding new test, update reference files)' print reference_basename print return False if not filecmp.cmp(reference_filename, output_filename): # cmp is much faster than diff, and usual case is "no difference", # so only run diff if cmp detects a difference print 'FAIL: %s' % reference_basename print diff(reference_filename, output_filename) return False if verbose: print 'PASS: %s' % reference_basename return True def identical_output_files(output_files): reference_files = [os.path.join(reference_directory, os.path.relpath(path, output_directory)) for path in output_files] return all([identical_file(reference_filename, output_filename) for (reference_filename, output_filename) in zip(reference_files, output_files)]) def no_excess_files(output_files): generated_files = set([os.path.relpath(path, output_directory) for path in output_files]) # Add subversion working copy directories in core and modules. for component in COMPONENT_DIRECTORY: generated_files.add(os.path.join(component, '.svn')) excess_files = [] for path in list_files(reference_directory): relpath = os.path.relpath(path, reference_directory) if relpath not in generated_files: excess_files.append(relpath) if excess_files: print ('Excess reference files! ' '(probably cruft from renaming or deleting):\n' + '\n'.join(excess_files)) return False return True try: generate_interface_dependencies() for component in COMPONENT_DIRECTORY: output_dir = os.path.join(output_directory, component) if not os.path.exists(output_dir): os.makedirs(output_dir) options = IdlCompilerOptions( output_directory=output_dir, impl_output_directory=output_dir, cache_directory=None, target_component=component) if component == 'core': partial_interface_output_dir = os.path.join(output_directory, 'modules') if not os.path.exists(partial_interface_output_dir): os.makedirs(partial_interface_output_dir) partial_interface_options = IdlCompilerOptions( output_directory=partial_interface_output_dir, impl_output_directory=None, cache_directory=None, target_component='modules') idl_filenames = [] dictionary_impl_filenames = [] partial_interface_filenames = [] input_directory = os.path.join(test_input_directory, component) for filename in os.listdir(input_directory): if (filename.endswith('.idl') and # Dependencies aren't built # (they are used by the dependent) filename not in DEPENDENCY_IDL_FILES): idl_path = os.path.realpath( os.path.join(input_directory, filename)) idl_filenames.append(idl_path) idl_basename = os.path.basename(idl_path) definition_name, _ = os.path.splitext(idl_basename) if definition_name in interfaces_info: interface_info = interfaces_info[definition_name] if interface_info['is_dictionary']: dictionary_impl_filenames.append(idl_path) if component == 'core' and interface_info[ 'dependencies_other_component_full_paths']: partial_interface_filenames.append(idl_path) info_provider = component_info_providers[component] partial_interface_info_provider = component_info_providers['modules'] generate_union_type_containers(CodeGeneratorUnionType, info_provider, options) generate_callback_function_impl(CodeGeneratorCallbackFunction, info_provider, options) generate_bindings( CodeGeneratorV8, info_provider, options, idl_filenames) generate_bindings( CodeGeneratorWebModule, info_provider, options, idl_filenames) generate_bindings( CodeGeneratorV8, partial_interface_info_provider, partial_interface_options, partial_interface_filenames) generate_dictionary_impl( CodeGeneratorDictionaryImpl, info_provider, options, dictionary_impl_filenames) finally: delete_cache_files() # Detect all changes output_files = list_files(output_directory) passed = identical_output_files(output_files) passed &= no_excess_files(output_files) if passed: if verbose: print print PASS_MESSAGE return 0 print print FAIL_MESSAGE return 1
def __init__(self, tests, is_debug): self.executive = Executive() self.tests = tests self.expected_failure = tests[-1] self.is_debug = is_debug self.webkit_finder = WebKitFinder(FileSystem())