Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(693)

Side by Side Diff: chrome/test/pyautolib/pyauto.py

Issue 9104022: Reduced logging and better log format for PyAuto WaitUntil(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge. Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """PyAuto: Python Interface to Chromium's Automation Proxy. 6 """PyAuto: Python Interface to Chromium's Automation Proxy.
7 7
8 PyAuto uses swig to expose Automation Proxy interfaces to Python. 8 PyAuto uses swig to expose Automation Proxy interfaces to Python.
9 For complete documentation on the functionality available, 9 For complete documentation on the functionality available,
10 run pydoc on this file. 10 run pydoc on this file.
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 self.CloseChromeOnChromeOS() 470 self.CloseChromeOnChromeOS()
471 self.EnableChromeTestingOnChromeOS() 471 self.EnableChromeTestingOnChromeOS()
472 self.SetUp() 472 self.SetUp()
473 return 473 return
474 # Not chromeos 474 # Not chromeos
475 orig_clear_state = self.get_clear_profile() 475 orig_clear_state = self.get_clear_profile()
476 self.CloseBrowserAndServer() 476 self.CloseBrowserAndServer()
477 self.set_clear_profile(clear_profile) 477 self.set_clear_profile(clear_profile)
478 if pre_launch_hook: 478 if pre_launch_hook:
479 pre_launch_hook() 479 pre_launch_hook()
480 logging.debug('Restarting browser with clear_profile=%s' % 480 logging.debug('Restarting browser with clear_profile=%s',
481 self.get_clear_profile()) 481 self.get_clear_profile())
482 self.LaunchBrowserAndServer() 482 self.LaunchBrowserAndServer()
483 self.set_clear_profile(orig_clear_state) # Reset to original state. 483 self.set_clear_profile(orig_clear_state) # Reset to original state.
484 484
485 @staticmethod 485 @staticmethod
486 def DataDir(): 486 def DataDir():
487 """Returns the path to the data dir chrome/test/data.""" 487 """Returns the path to the data dir chrome/test/data."""
488 return os.path.normpath( 488 return os.path.normpath(
489 os.path.join(os.path.dirname(__file__), os.pardir, "data")) 489 os.path.join(os.path.dirname(__file__), os.pardir, "data"))
490 490
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 debug: if True, displays debug info at each retry. 711 debug: if True, displays debug info at each retry.
712 712
713 Returns: 713 Returns:
714 True, if returning when |function| evaluated to True 714 True, if returning when |function| evaluated to True
715 False, when returning due to timeout 715 False, when returning due to timeout
716 """ 716 """
717 if timeout == -1: # Default 717 if timeout == -1: # Default
718 timeout = self.action_max_timeout_ms() / 1000.0 718 timeout = self.action_max_timeout_ms() / 1000.0
719 assert callable(function), "function should be a callable" 719 assert callable(function), "function should be a callable"
720 begin = time.time() 720 begin = time.time()
721 debug_begin = begin
721 while timeout is None or time.time() - begin <= timeout: 722 while timeout is None or time.time() - begin <= timeout:
722 retval = function(*args) 723 retval = function(*args)
723 if (expect_retval is None and retval) or expect_retval == retval: 724 if (expect_retval is None and retval) or expect_retval == retval:
724 return True 725 return True
725 if debug: 726 if debug and time.time() - debug_begin > 5:
726 logging.debug('WaitUntil(%s) still waiting. ' 727 debug_begin += 5
727 'Expecting %s. Last returned %s.' % ( 728 if function.func_name == (lambda: True).func_name:
728 function, expect_retval, retval)) 729 function_info = inspect.getsource(function).strip()
730 else:
731 function_info = '%s()' % function.func_name
732 logging.debug('WaitUntil(%s:%d %s) still waiting. '
733 'Expecting %s. Last returned %s.',
734 os.path.basename(inspect.getsourcefile(function)),
735 inspect.getsourcelines(function)[1],
736 function_info,
737 True if expect_retval is None else expect_retval,
738 retval)
729 time.sleep(retry_sleep) 739 time.sleep(retry_sleep)
730 return False 740 return False
731 741
732 def StartSyncServer(self): 742 def StartSyncServer(self):
733 """Start a local sync server. 743 """Start a local sync server.
734 744
735 Adds a dictionary attribute 'ports' in returned object. 745 Adds a dictionary attribute 'ports' in returned object.
736 746
737 Returns: 747 Returns:
738 A handle to Sync Server, an instance of TestServer 748 A handle to Sync Server, an instance of TestServer
739 """ 749 """
740 sync_server = pyautolib.TestServer(pyautolib.TestServer.TYPE_SYNC, 750 sync_server = pyautolib.TestServer(pyautolib.TestServer.TYPE_SYNC,
741 pyautolib.FilePath('')) 751 pyautolib.FilePath(''))
742 assert sync_server.Start(), 'Could not start sync server' 752 assert sync_server.Start(), 'Could not start sync server'
743 sync_server.ports = dict(port=sync_server.GetPort(), 753 sync_server.ports = dict(port=sync_server.GetPort(),
744 xmpp_port=sync_server.GetSyncXmppPort()) 754 xmpp_port=sync_server.GetSyncXmppPort())
745 logging.debug('Started sync server at ports %s.' % sync_server.ports) 755 logging.debug('Started sync server at ports %s.', sync_server.ports)
746 return sync_server 756 return sync_server
747 757
748 def StopSyncServer(self, sync_server): 758 def StopSyncServer(self, sync_server):
749 """Stop the local sync server.""" 759 """Stop the local sync server."""
750 assert sync_server, 'Sync Server not yet started' 760 assert sync_server, 'Sync Server not yet started'
751 assert sync_server.Stop(), 'Could not stop sync server' 761 assert sync_server.Stop(), 'Could not stop sync server'
752 logging.debug('Stopped sync server at ports %s.' % sync_server.ports) 762 logging.debug('Stopped sync server at ports %s.', sync_server.ports)
753 763
754 def StartFTPServer(self, data_dir): 764 def StartFTPServer(self, data_dir):
755 """Start a local file server hosting data files over ftp:// 765 """Start a local file server hosting data files over ftp://
756 766
757 Args: 767 Args:
758 data_dir: path where ftp files should be served 768 data_dir: path where ftp files should be served
759 769
760 Returns: 770 Returns:
761 handle to FTP Server, an instance of TestServer 771 handle to FTP Server, an instance of TestServer
762 """ 772 """
763 ftp_server = pyautolib.TestServer(pyautolib.TestServer.TYPE_FTP, 773 ftp_server = pyautolib.TestServer(pyautolib.TestServer.TYPE_FTP,
764 pyautolib.FilePath(data_dir)) 774 pyautolib.FilePath(data_dir))
765 assert ftp_server.Start(), 'Could not start ftp server' 775 assert ftp_server.Start(), 'Could not start ftp server'
766 logging.debug('Started ftp server at "%s".' % data_dir) 776 logging.debug('Started ftp server at "%s".', data_dir)
767 return ftp_server 777 return ftp_server
768 778
769 def StopFTPServer(self, ftp_server): 779 def StopFTPServer(self, ftp_server):
770 """Stop the local ftp server.""" 780 """Stop the local ftp server."""
771 assert ftp_server, 'FTP Server not yet started' 781 assert ftp_server, 'FTP Server not yet started'
772 assert ftp_server.Stop(), 'Could not stop ftp server' 782 assert ftp_server.Stop(), 'Could not stop ftp server'
773 logging.debug('Stopped ftp server.') 783 logging.debug('Stopped ftp server.')
774 784
775 def StartHTTPServer(self, data_dir): 785 def StartHTTPServer(self, data_dir):
776 """Starts a local HTTP TestServer serving files from |data_dir|. 786 """Starts a local HTTP TestServer serving files from |data_dir|.
777 787
778 Args: 788 Args:
779 data_dir: path where the TestServer should serve files from. This will be 789 data_dir: path where the TestServer should serve files from. This will be
780 appended to the source dir to get the final document root. 790 appended to the source dir to get the final document root.
781 791
782 Returns: 792 Returns:
783 handle to the HTTP TestServer 793 handle to the HTTP TestServer
784 """ 794 """
785 http_server = pyautolib.TestServer(pyautolib.TestServer.TYPE_HTTP, 795 http_server = pyautolib.TestServer(pyautolib.TestServer.TYPE_HTTP,
786 pyautolib.FilePath(data_dir)) 796 pyautolib.FilePath(data_dir))
787 assert http_server.Start(), 'Could not start HTTP server' 797 assert http_server.Start(), 'Could not start HTTP server'
788 logging.debug('Started HTTP server at "%s".' % data_dir) 798 logging.debug('Started HTTP server at "%s".', data_dir)
789 return http_server 799 return http_server
790 800
791 def StopHTTPServer(self, http_server): 801 def StopHTTPServer(self, http_server):
792 assert http_server, 'HTTP server not yet started' 802 assert http_server, 'HTTP server not yet started'
793 assert http_server.Stop(), 'Cloud not stop the HTTP server' 803 assert http_server.Stop(), 'Cloud not stop the HTTP server'
794 logging.debug('Stopped HTTP server.') 804 logging.debug('Stopped HTTP server.')
795 805
796 class ActionTimeoutChanger(object): 806 class ActionTimeoutChanger(object):
797 """Facilitate temporary changes to action_timeout_ms. 807 """Facilitate temporary changes to action_timeout_ms.
798 808
(...skipping 3717 matching lines...) Expand 10 before | Expand all | Expand 10 after
4516 4526
4517 def _StartHTTPServer(self): 4527 def _StartHTTPServer(self):
4518 """Start a local file server hosting data files over http://""" 4528 """Start a local file server hosting data files over http://"""
4519 global _HTTP_SERVER 4529 global _HTTP_SERVER
4520 assert not _HTTP_SERVER, 'HTTP Server already started' 4530 assert not _HTTP_SERVER, 'HTTP Server already started'
4521 http_data_dir = _OPTIONS.http_data_dir 4531 http_data_dir = _OPTIONS.http_data_dir
4522 http_server = pyautolib.TestServer(pyautolib.TestServer.TYPE_HTTP, 4532 http_server = pyautolib.TestServer(pyautolib.TestServer.TYPE_HTTP,
4523 pyautolib.FilePath(http_data_dir)) 4533 pyautolib.FilePath(http_data_dir))
4524 assert http_server.Start(), 'Could not start http server' 4534 assert http_server.Start(), 'Could not start http server'
4525 _HTTP_SERVER = http_server 4535 _HTTP_SERVER = http_server
4526 logging.debug('Started http server at "%s".' % http_data_dir) 4536 logging.debug('Started http server at "%s".', http_data_dir)
4527 4537
4528 def _StopHTTPServer(self): 4538 def _StopHTTPServer(self):
4529 """Stop the local http server.""" 4539 """Stop the local http server."""
4530 global _HTTP_SERVER 4540 global _HTTP_SERVER
4531 assert _HTTP_SERVER, 'HTTP Server not yet started' 4541 assert _HTTP_SERVER, 'HTTP Server not yet started'
4532 assert _HTTP_SERVER.Stop(), 'Could not stop http server' 4542 assert _HTTP_SERVER.Stop(), 'Could not stop http server'
4533 _HTTP_SERVER = None 4543 _HTTP_SERVER = None
4534 logging.debug('Stopped http server.') 4544 logging.debug('Stopped http server.')
4535 4545
4536 def _ConnectToRemoteHosts(self, addresses): 4546 def _ConnectToRemoteHosts(self, addresses):
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
4755 obj = getattr(obj, part) 4765 obj = getattr(obj, part)
4756 4766
4757 if type(obj) == types.ModuleType: 4767 if type(obj) == types.ModuleType:
4758 return _GetTestsFromModule(obj) 4768 return _GetTestsFromModule(obj)
4759 elif (isinstance(obj, (type, types.ClassType)) and 4769 elif (isinstance(obj, (type, types.ClassType)) and
4760 issubclass(obj, PyUITest) and obj != PyUITest): 4770 issubclass(obj, PyUITest) and obj != PyUITest):
4761 return [module.__name__ + '.' + x for x in _GetTestsFromTestCase(obj)] 4771 return [module.__name__ + '.' + x for x in _GetTestsFromTestCase(obj)]
4762 elif type(obj) == types.UnboundMethodType: 4772 elif type(obj) == types.UnboundMethodType:
4763 return [name] 4773 return [name]
4764 else: 4774 else:
4765 logging.warn('No tests in "%s"' % name) 4775 logging.warn('No tests in "%s"', name)
4766 return [] 4776 return []
4767 4777
4768 def _ListMissingTests(self): 4778 def _ListMissingTests(self):
4769 """Print tests missing from PYAUTO_TESTS.""" 4779 """Print tests missing from PYAUTO_TESTS."""
4770 # Fetch tests from all test scripts 4780 # Fetch tests from all test scripts
4771 all_test_files = filter(lambda x: x.endswith('.py'), 4781 all_test_files = filter(lambda x: x.endswith('.py'),
4772 os.listdir(self.TestsDir())) 4782 os.listdir(self.TestsDir()))
4773 all_tests_modules = [os.path.splitext(x)[0] for x in all_test_files] 4783 all_tests_modules = [os.path.splitext(x)[0] for x in all_test_files]
4774 all_tests = reduce(lambda x, y: x + y, 4784 all_tests = reduce(lambda x, y: x + y,
4775 map(self._ImportTestsFromName, all_tests_modules)) 4785 map(self._ImportTestsFromName, all_tests_modules))
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4816 ] 4826 ]
4817 """ 4827 """
4818 if not args: # Load tests ourselves 4828 if not args: # Load tests ourselves
4819 if self._HasTestCases('__main__'): # we are running a test script 4829 if self._HasTestCases('__main__'): # we are running a test script
4820 module_name = os.path.splitext(os.path.basename(sys.argv[0]))[0] 4830 module_name = os.path.splitext(os.path.basename(sys.argv[0]))[0]
4821 args.append(module_name) # run the test cases found in it 4831 args.append(module_name) # run the test cases found in it
4822 else: # run tests from the test description file 4832 else: # run tests from the test description file
4823 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename) 4833 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename)
4824 logging.debug("Reading %s", pyauto_tests_file) 4834 logging.debug("Reading %s", pyauto_tests_file)
4825 if not os.path.exists(pyauto_tests_file): 4835 if not os.path.exists(pyauto_tests_file):
4826 logging.warn("%s missing. Cannot load tests." % pyauto_tests_file) 4836 logging.warn("%s missing. Cannot load tests.", pyauto_tests_file)
4827 else: 4837 else:
4828 args = self._ExpandTestNamesFrom(pyauto_tests_file, 4838 args = self._ExpandTestNamesFrom(pyauto_tests_file,
4829 self._options.suite) 4839 self._options.suite)
4830 return args 4840 return args
4831 4841
4832 def _ExpandTestNamesFrom(self, filename, suite): 4842 def _ExpandTestNamesFrom(self, filename, suite):
4833 """Load test names from the given file. 4843 """Load test names from the given file.
4834 4844
4835 Args: 4845 Args:
4836 filename: the file to read the tests from 4846 filename: the file to read the tests from
4837 suite: the name of the suite to load from |filename|. 4847 suite: the name of the suite to load from |filename|.
4838 4848
4839 Returns: 4849 Returns:
4840 a list of test names 4850 a list of test names
4841 [module.testcase.testX, module.testcase.testY, ..] 4851 [module.testcase.testX, module.testcase.testY, ..]
4842 """ 4852 """
4843 suites = PyUITest.EvalDataFrom(filename) 4853 suites = PyUITest.EvalDataFrom(filename)
4844 platform = sys.platform 4854 platform = sys.platform
4845 if PyUITest.IsChromeOS(): # check if it's chromeos 4855 if PyUITest.IsChromeOS(): # check if it's chromeos
4846 platform = 'chromeos' 4856 platform = 'chromeos'
4847 assert platform in self._platform_map, '%s unsupported' % platform 4857 assert platform in self._platform_map, '%s unsupported' % platform
4848 def _NamesInSuite(suite_name): 4858 def _NamesInSuite(suite_name):
4849 logging.debug('Expanding suite %s' % suite_name) 4859 logging.debug('Expanding suite %s', suite_name)
4850 platforms = suites.get(suite_name) 4860 platforms = suites.get(suite_name)
4851 names = platforms.get('all', []) + \ 4861 names = platforms.get('all', []) + \
4852 platforms.get(self._platform_map[platform], []) 4862 platforms.get(self._platform_map[platform], [])
4853 ret = [] 4863 ret = []
4854 # Recursively include suites if any. Suites begin with @. 4864 # Recursively include suites if any. Suites begin with @.
4855 for name in names: 4865 for name in names:
4856 if name.startswith('@'): # Include another suite 4866 if name.startswith('@'): # Include another suite
4857 ret.extend(_NamesInSuite(name[1:])) 4867 ret.extend(_NamesInSuite(name[1:]))
4858 else: 4868 else:
4859 ret.append(name) 4869 ret.append(name)
4860 return ret 4870 return ret
4861 4871
4862 assert suite in suites, '%s: No such suite in %s' % (suite, filename) 4872 assert suite in suites, '%s: No such suite in %s' % (suite, filename)
4863 all_names = _NamesInSuite(suite) 4873 all_names = _NamesInSuite(suite)
4864 args = [] 4874 args = []
4865 excluded = [] 4875 excluded = []
4866 # Find all excluded tests. Excluded tests begin with '-'. 4876 # Find all excluded tests. Excluded tests begin with '-'.
4867 for name in all_names: 4877 for name in all_names:
4868 if name.startswith('-'): # Exclude 4878 if name.startswith('-'): # Exclude
4869 excluded.extend(self._ImportTestsFromName(name[1:])) 4879 excluded.extend(self._ImportTestsFromName(name[1:]))
4870 else: 4880 else:
4871 args.extend(self._ImportTestsFromName(name)) 4881 args.extend(self._ImportTestsFromName(name))
4872 for name in excluded: 4882 for name in excluded:
4873 if name in args: 4883 if name in args:
4874 args.remove(name) 4884 args.remove(name)
4875 else: 4885 else:
4876 logging.warn('Cannot exclude %s. Not included. Ignoring' % name) 4886 logging.warn('Cannot exclude %s. Not included. Ignoring', name)
4877 if excluded: 4887 if excluded:
4878 logging.debug('Excluded %d test(s): %s' % (len(excluded), excluded)) 4888 logging.debug('Excluded %d test(s): %s', len(excluded), excluded)
4879 return args 4889 return args
4880 4890
4881 def _Run(self): 4891 def _Run(self):
4882 """Run the tests.""" 4892 """Run the tests."""
4883 if self._options.wait_for_debugger: 4893 if self._options.wait_for_debugger:
4884 raw_input('Attach debugger to process %s and hit <enter> ' % os.getpid()) 4894 raw_input('Attach debugger to process %s and hit <enter> ' % os.getpid())
4885 4895
4886 suite_args = [sys.argv[0]] 4896 suite_args = [sys.argv[0]]
4887 chrome_flags = self._options.chrome_flags 4897 chrome_flags = self._options.chrome_flags
4888 # Set CHROME_HEADLESS. It enables crash reporter on posix. 4898 # Set CHROME_HEADLESS. It enables crash reporter on posix.
(...skipping 18 matching lines...) Expand all
4907 successful = result.wasSuccessful() 4917 successful = result.wasSuccessful()
4908 if not successful: 4918 if not successful:
4909 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename) 4919 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename)
4910 print >>sys.stderr, 'Tests can be disabled by editing %s. ' \ 4920 print >>sys.stderr, 'Tests can be disabled by editing %s. ' \
4911 'Ref: %s' % (pyauto_tests_file, _PYAUTO_DOC_URL) 4921 'Ref: %s' % (pyauto_tests_file, _PYAUTO_DOC_URL)
4912 sys.exit(not successful) 4922 sys.exit(not successful)
4913 4923
4914 4924
4915 if __name__ == '__main__': 4925 if __name__ == '__main__':
4916 Main() 4926 Main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698