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

Side by Side Diff: chrome/test/functional/perf_endure.py

Issue 10803002: Run Chrome Endure tests with network simulation via Web Page Replay. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Adjustments after patching Steve's CL Created 8 years, 4 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 | « chrome/test/data/chrome_endure/webpagereplay/wpr_deterministic.js ('k') | 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 """Performance tests for Chrome Endure (long-running perf tests on Chrome). 6 """Performance tests for Chrome Endure (long-running perf tests on Chrome).
7 7
8 This module accepts the following environment variable inputs: 8 This module accepts the following environment variable inputs:
9 TEST_LENGTH: The number of seconds in which to run each test. 9 TEST_LENGTH: The number of seconds in which to run each test.
10 PERF_STATS_INTERVAL: The number of seconds to wait in-between each sampling 10 PERF_STATS_INTERVAL: The number of seconds to wait in-between each sampling
(...skipping 15 matching lines...) Expand all
26 import time 26 import time
27 27
28 import perf 28 import perf
29 import pyauto_functional # Must be imported before pyauto. 29 import pyauto_functional # Must be imported before pyauto.
30 import pyauto 30 import pyauto
31 import pyauto_errors 31 import pyauto_errors
32 import pyauto_utils 32 import pyauto_utils
33 import remote_inspector_client 33 import remote_inspector_client
34 import selenium.common.exceptions 34 import selenium.common.exceptions
35 from selenium.webdriver.support.ui import WebDriverWait 35 from selenium.webdriver.support.ui import WebDriverWait
36 import webpagereplay
36 37
37 38
38 class NotSupportedEnvironmentError(RuntimeError): 39 class NotSupportedEnvironmentError(RuntimeError):
39 """Represent an error raised since the environment (OS) is not supported.""" 40 """Represent an error raised since the environment (OS) is not supported."""
40 pass 41 pass
41 42
43
42 class ChromeEndureBaseTest(perf.BasePerfTest): 44 class ChromeEndureBaseTest(perf.BasePerfTest):
43 """Implements common functionality for all Chrome Endure tests. 45 """Implements common functionality for all Chrome Endure tests.
44 46
45 All Chrome Endure test classes should inherit from this class. 47 All Chrome Endure test classes should inherit from this class.
46 """ 48 """
47 49
48 _DEFAULT_TEST_LENGTH_SEC = 60 * 60 * 6 # Tests run for 6 hours. 50 _DEFAULT_TEST_LENGTH_SEC = 60 * 60 * 6 # Tests run for 6 hours.
49 _GET_PERF_STATS_INTERVAL = 60 * 5 # Measure perf stats every 5 minutes. 51 _GET_PERF_STATS_INTERVAL = 60 * 5 # Measure perf stats every 5 minutes.
50 # TODO(dennisjeffrey): Do we still need to tolerate errors? 52 # TODO(dennisjeffrey): Do we still need to tolerate errors?
51 _ERROR_COUNT_THRESHOLD = 50 # Number of ChromeDriver errors to tolerate. 53 _ERROR_COUNT_THRESHOLD = 50 # Number of ChromeDriver errors to tolerate.
52 _DEEP_MEMORY_PROFILE = False 54 _DEEP_MEMORY_PROFILE = False
53 _DEEP_MEMORY_PROFILE_INTERVAL = _GET_PERF_STATS_INTERVAL 55 _DEEP_MEMORY_PROFILE_INTERVAL = _GET_PERF_STATS_INTERVAL
54 _DEEP_MEMORY_PROFILE_SAVE = False 56 _DEEP_MEMORY_PROFILE_SAVE = False
55 57
56 _DMPROF_DIR_PATH = os.path.join( 58 _DMPROF_DIR_PATH = os.path.join(
57 os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, 59 os.path.dirname(__file__), os.pardir, os.pardir, os.pardir,
58 'tools', 'deep_memory_profiler') 60 'tools', 'deep_memory_profiler')
59 61
60 _DMPROF_SCRIPT_PATH = os.path.join(_DMPROF_DIR_PATH, 'dmprof') 62 _DMPROF_SCRIPT_PATH = os.path.join(_DMPROF_DIR_PATH, 'dmprof')
61 63
62 _CHROME_BIN_PATH = os.path.join(perf.BasePerfTest.BrowserPath(), 'chrome') 64 _CHROME_BIN_PATH = os.path.join(perf.BasePerfTest.BrowserPath(), 'chrome')
63 65
64 def setUp(self): 66 def setUp(self):
67 # The environment variable for the usage of Web Page Replay.
68 # It must be parsed before perf.BasePerfTest.setUp()
69 self._use_wpr = 'ENDURE_NO_WPR' not in os.environ
70
65 # The environment variables for the Deep Memory Profiler must be set 71 # The environment variables for the Deep Memory Profiler must be set
66 # before perf.BasePerfTest.setUp() to inherit them to Chrome. 72 # before perf.BasePerfTest.setUp() to inherit them to Chrome.
67 self._deep_memory_profile = self._GetDeepMemoryProfileEnv( 73 self._deep_memory_profile = self._GetDeepMemoryProfileEnv(
68 'DEEP_MEMORY_PROFILE', bool, self._DEEP_MEMORY_PROFILE) 74 'DEEP_MEMORY_PROFILE', bool, self._DEEP_MEMORY_PROFILE)
69 75
70 self._deep_memory_profile_interval = self._GetDeepMemoryProfileEnv( 76 self._deep_memory_profile_interval = self._GetDeepMemoryProfileEnv(
71 'DEEP_MEMORY_PROFILE_INTERVAL', int, self._DEEP_MEMORY_PROFILE_INTERVAL) 77 'DEEP_MEMORY_PROFILE_INTERVAL', int, self._DEEP_MEMORY_PROFILE_INTERVAL)
72 78
73 if self._deep_memory_profile: 79 if self._deep_memory_profile:
74 if not self.IsLinux(): 80 if not self.IsLinux():
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 # The same with setUp, but need to fetch the environment variable since 179 # The same with setUp, but need to fetch the environment variable since
174 # ExtraChromeFlags is called before setUp. 180 # ExtraChromeFlags is called before setUp.
175 deep_memory_profile = self._GetDeepMemoryProfileEnv( 181 deep_memory_profile = self._GetDeepMemoryProfileEnv(
176 'DEEP_MEMORY_PROFILE', bool, self._DEEP_MEMORY_PROFILE) 182 'DEEP_MEMORY_PROFILE', bool, self._DEEP_MEMORY_PROFILE)
177 183
178 # Ensure Chrome enables remote debugging on port 9222. This is required to 184 # Ensure Chrome enables remote debugging on port 9222. This is required to
179 # interact with Chrome's remote inspector. 185 # interact with Chrome's remote inspector.
180 extra_flags = ['--remote-debugging-port=9222'] 186 extra_flags = ['--remote-debugging-port=9222']
181 if deep_memory_profile: 187 if deep_memory_profile:
182 extra_flags.append('--no-sandbox') 188 extra_flags.append('--no-sandbox')
183 return (perf.BasePerfTest.ExtraChromeFlags(self) + extra_flags) 189 if self._use_wpr:
190 extra_flags.extend(ChromeEndureReplay.CHROME_FLAGS)
191 return perf.BasePerfTest.ExtraChromeFlags(self) + extra_flags
184 192
185 def _OnTimelineEvent(self, event_info): 193 def _OnTimelineEvent(self, event_info):
186 """Invoked by the Remote Inspector Client when a timeline event occurs. 194 """Invoked by the Remote Inspector Client when a timeline event occurs.
187 195
188 Args: 196 Args:
189 event_info: A dictionary containing raw information associated with a 197 event_info: A dictionary containing raw information associated with a
190 timeline event received from Chrome's remote inspector. Refer to 198 timeline event received from Chrome's remote inspector. Refer to
191 chrome/src/third_party/WebKit/Source/WebCore/inspector/Inspector.json 199 chrome/src/third_party/WebKit/Source/WebCore/inspector/Inspector.json
192 for the format of this dictionary. 200 for the format of this dictionary.
193 """ 201 """
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 try: 541 try:
534 element = self._GetElement(driver.find_element_by_xpath, xpath) 542 element = self._GetElement(driver.find_element_by_xpath, xpath)
535 element.click() 543 element.click()
536 except (selenium.common.exceptions.StaleElementReferenceException, 544 except (selenium.common.exceptions.StaleElementReferenceException,
537 selenium.common.exceptions.TimeoutException) as e: 545 selenium.common.exceptions.TimeoutException) as e:
538 logging.exception('WebDriver exception: %s' % e) 546 logging.exception('WebDriver exception: %s' % e)
539 return False 547 return False
540 548
541 return True 549 return True
542 550
551 def _StartReplayServerIfNecessary(self, archive_name):
552 """Start the Web Page Replay server if ENDURE_NO_WPR is not set.
553
554 This method needs to be called BEFORE any connection (which are supposed
555 to go through the Web Page Replay server) occurs.
556
557 Args:
558 archive_name: a string representing the name of the web page replay
559 archive.
560 """
561 if self._use_wpr:
562 self._wpr_server = ChromeEndureReplay.ReplayServer(archive_name)
563 mode = 'Record' if self._wpr_server.is_record_mode else 'Replay'
564 logging.info('Starting the Web Page Replay server: in %s mode', mode)
565 self._wpr_server.StartServer()
566 logging.info('The Web Page Replay server started.')
Nirnimesh 2012/08/01 01:03:00 Too much logging. Please pick between this line an
fdeng1 2012/08/01 17:14:57 Done.
567
568 def _StopReplayServerIfNecessary(self):
569 """Stop the Web Page Replay server if ENDURE_NO_WPR is not set.
570
571 This method has to be called AFTER all network connections which go
572 through Web Page Replay server have shut down. Otherwise the
573 Web Page Replay server will hang to wait for them. A good
574 place is to call it at the end of the teardown process.
575 """
576 if self._use_wpr:
577 logging.info('Stopping The Web Page Replay server.')
578 self._wpr_server.StopServer()
579 logging.info('The Web Page Replay server stopped.')
580
543 581
544 class ChromeEndureControlTest(ChromeEndureBaseTest): 582 class ChromeEndureControlTest(ChromeEndureBaseTest):
545 """Control tests for Chrome Endure.""" 583 """Control tests for Chrome Endure."""
546 584
547 _WEBAPP_NAME = 'Control' 585 _WEBAPP_NAME = 'Control'
548 _TAB_TITLE_SUBSTRING = 'Chrome Endure Control Test' 586 _TAB_TITLE_SUBSTRING = 'Chrome Endure Control Test'
549 587
550 def testControlAttachDetachDOMTree(self): 588 def testControlAttachDetachDOMTree(self):
551 """Continually attach and detach a DOM tree from a basic document.""" 589 """Continually attach and detach a DOM tree from a basic document."""
552 test_description = 'AttachDetachDOMTree' 590 test_description = 'AttachDetachDOMTree'
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 test_description, lambda: scenario(driver)) 628 test_description, lambda: scenario(driver))
591 629
592 630
593 class ChromeEndureGmailTest(ChromeEndureBaseTest): 631 class ChromeEndureGmailTest(ChromeEndureBaseTest):
594 """Long-running performance tests for Chrome using Gmail.""" 632 """Long-running performance tests for Chrome using Gmail."""
595 633
596 _WEBAPP_NAME = 'Gmail' 634 _WEBAPP_NAME = 'Gmail'
597 _TAB_TITLE_SUBSTRING = 'Gmail' 635 _TAB_TITLE_SUBSTRING = 'Gmail'
598 _FRAME_XPATH = 'id("canvas_frame")' 636 _FRAME_XPATH = 'id("canvas_frame")'
599 637
600 def setUp(self): 638 def _GmailSetUp(self, archive_name):
601 ChromeEndureBaseTest.setUp(self) 639 """Set up before each test runs."""
640 self._StartReplayServerIfNecessary(archive_name)
Nirnimesh 2012/08/01 01:03:00 I thought this was going to be done in ChromeEndur
fdeng1 2012/08/01 17:14:57 When starting a replay server, an "archive_name" n
dennis_jeffrey 2012/08/01 18:35:54 self.id(), as discussed offline
fdeng1 2012/08/01 18:37:31 I just talked to Dennis and we came up a plan to c
602 641
603 # Log into a test Google account and open up Gmail. 642 # Log into a test Google account and open up Gmail.
604 self._LoginToGoogleAccount(account_key='test_google_account_gmail') 643 self._LoginToGoogleAccount(account_key='test_google_account_gmail')
605 self.NavigateToURL('http://www.gmail.com') 644 self.NavigateToURL('http://www.gmail.com')
606 loaded_tab_title = self.GetActiveTabTitle() 645 loaded_tab_title = self.GetActiveTabTitle()
607 self.assertTrue(self._TAB_TITLE_SUBSTRING in loaded_tab_title, 646 self.assertTrue(self._TAB_TITLE_SUBSTRING in loaded_tab_title,
608 msg='Loaded tab title does not contain "%s": "%s"' % 647 msg='Loaded tab title does not contain "%s": "%s"' %
609 (self._TAB_TITLE_SUBSTRING, loaded_tab_title)) 648 (self._TAB_TITLE_SUBSTRING, loaded_tab_title))
610 649
611 self._driver = self.NewWebDriver() 650 self._driver = self.NewWebDriver()
612 # Any call to wait.until() will raise an exception if the timeout is hit. 651 # Any call to wait.until() will raise an exception if the timeout is hit.
613 # TODO(dennisjeffrey): Remove the need for webdriver's wait using the new 652 # TODO(dennisjeffrey): Remove the need for webdriver's wait using the new
614 # DOM mutation observer mechanism. 653 # DOM mutation observer mechanism.
615 self._wait = WebDriverWait(self._driver, timeout=60) 654 self._wait = WebDriverWait(self._driver, timeout=60)
616 655
617 # Wait until Gmail's 'canvas_frame' loads and the 'Inbox' link is present. 656 # Wait until Gmail's 'canvas_frame' loads and the 'Inbox' link is present.
618 # TODO(dennisjeffrey): Check with the Gmail team to see if there's a better 657 # TODO(dennisjeffrey): Check with the Gmail team to see if there's a better
619 # way to tell when the webpage is ready for user interaction. 658 # way to tell when the webpage is ready for user interaction.
620 self._wait.until( 659 self._wait.until(
621 self._SwitchToCanvasFrame) # Raises exception if the timeout is hit. 660 self._SwitchToCanvasFrame) # Raises exception if the timeout is hit.
622 # Wait for the inbox to appear. 661 # Wait for the inbox to appear.
623 self.WaitForDomNode('//a[starts-with(@title, "Inbox")]', 662 self.WaitForDomNode('//a[starts-with(@title, "Inbox")]',
624 frame_xpath=self._FRAME_XPATH) 663 frame_xpath=self._FRAME_XPATH)
625 664
665 def tearDown(self):
666 super(ChromeEndureGmailTest, self).tearDown()
667 # Stop the Web Page Replay server after all connections to WPR closed.
668 self._StopReplayServerIfNecessary()
669
626 def _SwitchToCanvasFrame(self, driver): 670 def _SwitchToCanvasFrame(self, driver):
627 """Switch the WebDriver to Gmail's 'canvas_frame', if it's available. 671 """Switch the WebDriver to Gmail's 'canvas_frame', if it's available.
628 672
629 Args: 673 Args:
630 driver: A selenium.webdriver.remote.webdriver.WebDriver object. 674 driver: A selenium.webdriver.remote.webdriver.WebDriver object.
631 675
632 Returns: 676 Returns:
633 True, if the switch to Gmail's 'canvas_frame' is successful, or 677 True, if the switch to Gmail's 'canvas_frame' is successful, or
634 False if not. 678 False if not.
635 """ 679 """
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 else: 739 else:
696 logging.warning('Could not identify latency value.') 740 logging.warning('Could not identify latency value.')
697 741
698 def testGmailComposeDiscard(self): 742 def testGmailComposeDiscard(self):
699 """Continuously composes/discards an e-mail before sending. 743 """Continuously composes/discards an e-mail before sending.
700 744
701 This test continually composes/discards an e-mail using Gmail, and 745 This test continually composes/discards an e-mail using Gmail, and
702 periodically gathers performance stats that may reveal memory bloat. 746 periodically gathers performance stats that may reveal memory bloat.
703 """ 747 """
704 test_description = 'ComposeDiscard' 748 test_description = 'ComposeDiscard'
749 self._GmailSetUp(test_description)
Nirnimesh 2012/08/01 01:03:00 Why not do this it setUp instead of calling before
fdeng1 2012/08/01 17:14:57 Please see the above comment. On 2012/08/01 01:03
705 750
706 # TODO(dennisjeffrey): Remove following line once crosbug.com/32357 is 751 # TODO(dennisjeffrey): Remove following line once crosbug.com/32357 is
707 # fixed. 752 # fixed.
708 self._test_length_sec = 60 * 60 * 5 # Run test for 5 hours. 753 self._test_length_sec = 60 * 60 * 5 # Run test for 5 hours.
709 754
710 def scenario(): 755 def scenario():
711 # Click the "Compose" button, enter some text into the "To" field, enter 756 # Click the "Compose" button, enter some text into the "To" field, enter
712 # some text into the "Subject" field, then click the "Discard" button to 757 # some text into the "Subject" field, then click the "Discard" button to
713 # discard the message. 758 # discard the message.
714 compose_xpath = '//div[text()="COMPOSE"]' 759 compose_xpath = '//div[text()="COMPOSE"]'
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 791
747 # TODO(dennisjeffrey): Remove this test once the Gmail team is done analyzing 792 # TODO(dennisjeffrey): Remove this test once the Gmail team is done analyzing
748 # the results after the test runs for a period of time. 793 # the results after the test runs for a period of time.
749 def testGmailComposeDiscardSleep(self): 794 def testGmailComposeDiscardSleep(self):
750 """Like testGmailComposeDiscard, but sleeps for 30s between iterations. 795 """Like testGmailComposeDiscard, but sleeps for 30s between iterations.
751 796
752 This is a temporary test requested by the Gmail team to compare against the 797 This is a temporary test requested by the Gmail team to compare against the
753 results from testGmailComposeDiscard above. 798 results from testGmailComposeDiscard above.
754 """ 799 """
755 test_description = 'ComposeDiscardSleep' 800 test_description = 'ComposeDiscardSleep'
801 # Use the same archive_name as testGmailComposeDiscard uses.
802 self._GmailSetUp('ComposeDiscard')
756 803
757 # TODO(dennisjeffrey): Remove following line once crosbug.com/32357 is 804 # TODO(dennisjeffrey): Remove following line once crosbug.com/32357 is
758 # fixed. 805 # fixed.
759 self._test_length_sec = 60 * 60 * 5 # Run test for 5 hours. 806 self._test_length_sec = 60 * 60 * 5 # Run test for 5 hours.
760 807
761 def scenario(): 808 def scenario():
762 # Click the "Compose" button, enter some text into the "To" field, enter 809 # Click the "Compose" button, enter some text into the "To" field, enter
763 # some text into the "Subject" field, then click the "Discard" button to 810 # some text into the "Subject" field, then click the "Discard" button to
764 # discard the message. Finally, sleep for 30 seconds. 811 # discard the message. Finally, sleep for 30 seconds.
765 compose_xpath = '//div[text()="COMPOSE"]' 812 compose_xpath = '//div[text()="COMPOSE"]'
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 frame_xpath=self._FRAME_XPATH) 848 frame_xpath=self._FRAME_XPATH)
802 849
803 def testGmailAlternateThreadlistConversation(self): 850 def testGmailAlternateThreadlistConversation(self):
804 """Alternates between threadlist view and conversation view. 851 """Alternates between threadlist view and conversation view.
805 852
806 This test continually clicks between the threadlist (Inbox) and the 853 This test continually clicks between the threadlist (Inbox) and the
807 conversation view (e-mail message view), and periodically gathers 854 conversation view (e-mail message view), and periodically gathers
808 performance stats that may reveal memory bloat. 855 performance stats that may reveal memory bloat.
809 """ 856 """
810 test_description = 'ThreadConversation' 857 test_description = 'ThreadConversation'
858 self._GmailSetUp(test_description)
811 859
812 def scenario(): 860 def scenario():
813 # Click an e-mail to see the conversation view, wait 1 second, click the 861 # Click an e-mail to see the conversation view, wait 1 second, click the
814 # "Inbox" link to see the threadlist, wait 1 second. 862 # "Inbox" link to see the threadlist, wait 1 second.
815 863
816 # Find the first thread (e-mail) identified by a "span" tag that contains 864 # Find the first thread (e-mail) identified by a "span" tag that contains
817 # an "email" attribute. Then click it and wait for the conversation view 865 # an "email" attribute. Then click it and wait for the conversation view
818 # to appear (assumed to be visible when a particular div exists on the 866 # to appear (assumed to be visible when a particular div exists on the
819 # page). 867 # page).
820 thread_xpath = '//span[@email]' 868 thread_xpath = '//span[@email]'
(...skipping 23 matching lines...) Expand all
844 test_description, scenario, 892 test_description, scenario,
845 frame_xpath=self._FRAME_XPATH) 893 frame_xpath=self._FRAME_XPATH)
846 894
847 def testGmailAlternateTwoLabels(self): 895 def testGmailAlternateTwoLabels(self):
848 """Continuously alternates between two labels. 896 """Continuously alternates between two labels.
849 897
850 This test continually clicks between the "Inbox" and "Sent Mail" labels, 898 This test continually clicks between the "Inbox" and "Sent Mail" labels,
851 and periodically gathers performance stats that may reveal memory bloat. 899 and periodically gathers performance stats that may reveal memory bloat.
852 """ 900 """
853 test_description = 'AlternateLabels' 901 test_description = 'AlternateLabels'
902 self._GmailSetUp(test_description)
854 903
855 def scenario(): 904 def scenario():
856 # Click the "Sent Mail" label, wait for 1 second, click the "Inbox" label, 905 # Click the "Sent Mail" label, wait for 1 second, click the "Inbox" label,
857 # wait for 1 second. 906 # wait for 1 second.
858 907
859 # Click the "Sent Mail" label, then wait for the tab title to be updated 908 # Click the "Sent Mail" label, then wait for the tab title to be updated
860 # with the substring "sent". 909 # with the substring "sent".
861 sent_xpath = '//a[starts-with(text(), "Sent Mail")]' 910 sent_xpath = '//a[starts-with(text(), "Sent Mail")]'
862 self.WaitForDomNode(sent_xpath, frame_xpath=self._FRAME_XPATH) 911 self.WaitForDomNode(sent_xpath, frame_xpath=self._FRAME_XPATH)
863 sent = self._GetElement(self._driver.find_element_by_xpath, sent_xpath) 912 sent = self._GetElement(self._driver.find_element_by_xpath, sent_xpath)
(...skipping 22 matching lines...) Expand all
886 935
887 def testGmailExpandCollapseConversation(self): 936 def testGmailExpandCollapseConversation(self):
888 """Continuously expands/collapses all messages in a conversation. 937 """Continuously expands/collapses all messages in a conversation.
889 938
890 This test opens up a conversation (e-mail thread) with several messages, 939 This test opens up a conversation (e-mail thread) with several messages,
891 then continually alternates between the "Expand all" and "Collapse all" 940 then continually alternates between the "Expand all" and "Collapse all"
892 views, while periodically gathering performance stats that may reveal memory 941 views, while periodically gathering performance stats that may reveal memory
893 bloat. 942 bloat.
894 """ 943 """
895 test_description = 'ExpandCollapse' 944 test_description = 'ExpandCollapse'
945 self._GmailSetUp(test_description)
896 946
897 # Enter conversation view for a particular thread. 947 # Enter conversation view for a particular thread.
898 thread_xpath = '//span[@email]' 948 thread_xpath = '//span[@email]'
899 self.WaitForDomNode(thread_xpath, frame_xpath=self._FRAME_XPATH) 949 self.WaitForDomNode(thread_xpath, frame_xpath=self._FRAME_XPATH)
900 thread = self._GetElement(self._driver.find_element_by_xpath, thread_xpath) 950 thread = self._GetElement(self._driver.find_element_by_xpath, thread_xpath)
901 thread.click() 951 thread.click()
902 self.WaitForDomNode('//div[text()="Click here to "]', 952 self.WaitForDomNode('//div[text()="Click here to "]',
903 frame_xpath=self._FRAME_XPATH) 953 frame_xpath=self._FRAME_XPATH)
904 954
905 def scenario(): 955 def scenario():
(...skipping 30 matching lines...) Expand all
936 test_description, scenario, 986 test_description, scenario,
937 frame_xpath=self._FRAME_XPATH) 987 frame_xpath=self._FRAME_XPATH)
938 988
939 989
940 class ChromeEndureDocsTest(ChromeEndureBaseTest): 990 class ChromeEndureDocsTest(ChromeEndureBaseTest):
941 """Long-running performance tests for Chrome using Google Docs.""" 991 """Long-running performance tests for Chrome using Google Docs."""
942 992
943 _WEBAPP_NAME = 'Docs' 993 _WEBAPP_NAME = 'Docs'
944 _TAB_TITLE_SUBSTRING = 'Google Drive' 994 _TAB_TITLE_SUBSTRING = 'Google Drive'
945 995
946 def setUp(self): 996 def _DocsSetUp(self, archive_name):
947 ChromeEndureBaseTest.setUp(self) 997 """Set up before each test runs."""
998 self._StartReplayServerIfNecessary(archive_name)
948 999
949 # Log into a test Google account and open up Google Docs. 1000 # Log into a test Google account and open up Google Docs.
950 self._LoginToGoogleAccount() 1001 self._LoginToGoogleAccount()
951 self.NavigateToURL('http://docs.google.com') 1002 self.NavigateToURL('http://docs.google.com')
952 self.assertTrue( 1003 self.assertTrue(
953 self.WaitUntil(lambda: self._TAB_TITLE_SUBSTRING in 1004 self.WaitUntil(lambda: self._TAB_TITLE_SUBSTRING in
954 self.GetActiveTabTitle(), 1005 self.GetActiveTabTitle(),
955 timeout=60, expect_retval=True, retry_sleep=1), 1006 timeout=60, expect_retval=True, retry_sleep=1),
956 msg='Timed out waiting for Docs to load. Tab title is: %s' % 1007 msg='Timed out waiting for Docs to load. Tab title is: %s' %
957 self.GetActiveTabTitle()) 1008 self.GetActiveTabTitle())
958 1009
959 self._driver = self.NewWebDriver() 1010 self._driver = self.NewWebDriver()
960 1011
1012 def tearDown(self):
1013 super(ChromeEndureDocsTest, self).tearDown()
1014 # Stop the Web Page Replay server after all connections to it closed.
1015 self._StopReplayServerIfNecessary()
1016
961 def testDocsAlternatelyClickLists(self): 1017 def testDocsAlternatelyClickLists(self):
962 """Alternates between two different document lists. 1018 """Alternates between two different document lists.
963 1019
964 This test alternately clicks the "Shared with me" and "My Drive" buttons in 1020 This test alternately clicks the "Shared with me" and "My Drive" buttons in
965 Google Docs, and periodically gathers performance stats that may reveal 1021 Google Docs, and periodically gathers performance stats that may reveal
966 memory bloat. 1022 memory bloat.
967 """ 1023 """
968 test_description = 'AlternateLists' 1024 test_description = 'AlternateLists'
1025 self._DocsSetUp(test_description)
969 1026
970 def scenario(): 1027 def scenario():
971 # Click the "Shared with me" button, wait for 1 second, click the 1028 # Click the "Shared with me" button, wait for 1 second, click the
972 # "My Drive" button, wait for 1 second. 1029 # "My Drive" button, wait for 1 second.
973 1030
974 # Click the "Shared with me" button and wait for a div to appear. 1031 # Click the "Shared with me" button and wait for a div to appear.
975 if not self._ClickElementByXpath( 1032 if not self._ClickElementByXpath(
976 self._driver, '//span[starts-with(text(), "Shared with me")]'): 1033 self._driver, '//span[starts-with(text(), "Shared with me")]'):
977 self._num_errors += 1 1034 self._num_errors += 1
978 self.WaitForDomNode('//div[text()="Share date"]') 1035 self.WaitForDomNode('//div[text()="Share date"]')
(...skipping 18 matching lines...) Expand all
997 self._RunEndureTest(self._WEBAPP_NAME, self._TAB_TITLE_SUBSTRING, 1054 self._RunEndureTest(self._WEBAPP_NAME, self._TAB_TITLE_SUBSTRING,
998 test_description, scenario) 1055 test_description, scenario)
999 1056
1000 1057
1001 class ChromeEndurePlusTest(ChromeEndureBaseTest): 1058 class ChromeEndurePlusTest(ChromeEndureBaseTest):
1002 """Long-running performance tests for Chrome using Google Plus.""" 1059 """Long-running performance tests for Chrome using Google Plus."""
1003 1060
1004 _WEBAPP_NAME = 'Plus' 1061 _WEBAPP_NAME = 'Plus'
1005 _TAB_TITLE_SUBSTRING = 'Google+' 1062 _TAB_TITLE_SUBSTRING = 'Google+'
1006 1063
1007 def setUp(self): 1064 def _PlusSetUp(self, archive_name):
1008 ChromeEndureBaseTest.setUp(self) 1065 """Set up before each test runs."""
1066 self._StartReplayServerIfNecessary(archive_name)
1009 1067
1010 # Log into a test Google account and open up Google Plus. 1068 # Log into a test Google account and open up Google Plus.
1011 self._LoginToGoogleAccount() 1069 self._LoginToGoogleAccount()
1012 self.NavigateToURL('http://plus.google.com') 1070 self.NavigateToURL('http://plus.google.com')
1013 loaded_tab_title = self.GetActiveTabTitle() 1071 loaded_tab_title = self.GetActiveTabTitle()
1014 self.assertTrue(self._TAB_TITLE_SUBSTRING in loaded_tab_title, 1072 self.assertTrue(self._TAB_TITLE_SUBSTRING in loaded_tab_title,
1015 msg='Loaded tab title does not contain "%s": "%s"' % 1073 msg='Loaded tab title does not contain "%s": "%s"' %
1016 (self._TAB_TITLE_SUBSTRING, loaded_tab_title)) 1074 (self._TAB_TITLE_SUBSTRING, loaded_tab_title))
1017 1075
1018 self._driver = self.NewWebDriver() 1076 self._driver = self.NewWebDriver()
1019 1077
1078 def tearDown(self):
1079 super(ChromeEndurePlusTest, self).tearDown()
1080 # Stop the Web Page Replay server after all connections to it closed.
1081 self._StopReplayServerIfNecessary()
1082
1020 def testPlusAlternatelyClickStreams(self): 1083 def testPlusAlternatelyClickStreams(self):
1021 """Alternates between two different streams. 1084 """Alternates between two different streams.
1022 1085
1023 This test alternately clicks the "Friends" and "Family" buttons using 1086 This test alternately clicks the "Friends" and "Family" buttons using
1024 Google Plus, and periodically gathers performance stats that may reveal 1087 Google Plus, and periodically gathers performance stats that may reveal
1025 memory bloat. 1088 memory bloat.
1026 """ 1089 """
1027 test_description = 'AlternateStreams' 1090 test_description = 'AlternateStreams'
1091 self._PlusSetUp(test_description)
1028 1092
1029 # TODO(dennisjeffrey): Remove following line once crosbug.com/32357 is 1093 # TODO(dennisjeffrey): Remove following line once crosbug.com/32357 is
1030 # fixed. 1094 # fixed.
1031 self._test_length_sec = 60 * 60 * 3 # Run test for 3 hours. 1095 self._test_length_sec = 60 * 60 * 3 # Run test for 3 hours.
1032 1096
1033 def scenario(): 1097 def scenario():
1034 # Click the "Friends" button, wait for 1 second, click the "Family" 1098 # Click the "Friends" button, wait for 1 second, click the "Family"
1035 # button, wait for 1 second. 1099 # button, wait for 1 second.
1036 1100
1037 # Click the "Friends" button and wait for a resulting div to appear. 1101 # Click the "Friends" button and wait for a resulting div to appear.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 except (pyauto_errors.JSONInterfaceError, 1181 except (pyauto_errors.JSONInterfaceError,
1118 pyauto_errors.JavascriptRuntimeError): 1182 pyauto_errors.JavascriptRuntimeError):
1119 self._num_errors += 1 1183 self._num_errors += 1
1120 1184
1121 time.sleep(1) 1185 time.sleep(1)
1122 1186
1123 self._RunEndureTest(self._WEBAPP_NAME, self._TAB_TITLE_SUBSTRING, 1187 self._RunEndureTest(self._WEBAPP_NAME, self._TAB_TITLE_SUBSTRING,
1124 test_description, scenario) 1188 test_description, scenario)
1125 1189
1126 1190
1191 class ChromeEndureReplay(object):
1192 """Run Chrome Endure tests with network simulation via Web Page Replay."""
1193
1194 _PATHS = {
1195 'archive':
1196 'src/chrome/test/data/pyauto_private/webpagereplay/{archive_name}.wpr',
1197 'scripts':
1198 'src/chrome/test/data/chrome_endure/webpagereplay/wpr_deterministic.js',
1199 }
1200 CHROME_FLAGS = webpagereplay.CHROME_FLAGS
1201
1202 @classmethod
1203 def Path(cls, key, **kwargs):
1204 return perf.FormatChromePath(cls._PATHS[key], **kwargs)
1205
1206 @classmethod
1207 def ReplayServer(cls, archive_name):
1208 """Creat a replay server."""
1209 # Inject customized scripts for Google webapps.
1210 # See the java script file for details.
1211 scripts = cls.Path('scripts')
1212 if not os.path.exists(scripts):
1213 raise webpagereplay.ReplayNotFoundError('injected scripts', scripts)
1214 replay_options = ['--inject_scripts', scripts]
1215 archive_path = cls.Path('archive', archive_name=archive_name)
1216 return webpagereplay.ReplayServer(archive_path, replay_options)
1217
1218
1127 if __name__ == '__main__': 1219 if __name__ == '__main__':
1128 pyauto_functional.Main() 1220 pyauto_functional.Main()
OLDNEW
« no previous file with comments | « chrome/test/data/chrome_endure/webpagereplay/wpr_deterministic.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698