blob: f9a4ffe5a6dc257728befd0ab054a4a45d64bd5e [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Stess Tests for Google Chrome.
This script runs 4 different stress tests:
1. Plugin stress.
2. Back and forward stress.
3. Download stress.
4. Preference stress.
After every cycle (running all 4 stress tests) it checks for crashes.
If there are any crashes, the script generates a report, uploads it to
a server and mails about the crash and the link to the report on the server.
Apart from this whenever the test stops on mac it looks for and reports
zombies.
Prerequisites:
Test needs the following files/folders in the Data dir.
1. A crash_report tool in "pyauto_private/stress/mac" folder for use on Mac.
2. A "downloads" folder containing stress_downloads and all the files
referenced in it.
3. A pref_dict file in "pyauto_private/stress/mac" folder.
4. A "plugin" folder containing doubleAnimation.xaml, flash.swf, FlashSpin.swf,
generic.html, get_flash_player.gif, js-invoker.swf, mediaplayer.wmv,
NavigatorTicker11.class, Plugins_page.html, sample5.mov, silverlight.xaml,
silverlight.js, embed.pdf, plugins_page.html and test6.swf.
5. A stress_pref file in "pyauto_private/stress".
"""
import commands
import glob
import logging
import os
import random
import re
import shutil
import sys
import time
import urllib
import test_utils
import subprocess
import pyauto_functional
import pyauto
import pyauto_utils
CRASHES = 'crashes' # Name of the folder to store crashes
class StressTest(pyauto.PyUITest):
"""Run all the stress tests."""
flash_url1 = pyauto.PyUITest.GetFileURLForPath(
os.path.join(pyauto.PyUITest.DataDir(), 'plugin', 'flash.swf'))
flash_url2 = pyauto.PyUITest.GetFileURLForPath(
os.path.join(pyauto.PyUITest.DataDir(),'plugin', 'js-invoker.swf'))
flash_url3 = pyauto.PyUITest.GetFileURLForPath(
os.path.join(pyauto.PyUITest.DataDir(), 'plugin', 'generic.html'))
plugin_url = pyauto.PyUITest.GetFileURLForPath(
os.path.join(pyauto.PyUITest.DataDir(), 'plugin', 'plugins_page.html'))
empty_url = pyauto.PyUITest.GetFileURLForPath(
os.path.join(pyauto.PyUITest.DataDir(), 'empty.html'))
download_url1 = pyauto.PyUITest.GetFileURLForPath(
os.path.join(pyauto.PyUITest.DataDir(), 'downloads', 'a_zip_file.zip'))
download_url2 = pyauto.PyUITest.GetFileURLForPath(
os.path.join(pyauto.PyUITest.DataDir(),'zip', 'test.zip'))
file_list = pyauto.PyUITest.EvalDataFrom(
os.path.join(pyauto.PyUITest.DataDir(), 'downloads', 'stress_downloads'))
symbols_dir = os.path.join(os.getcwd(), 'Build_Symbols')
stress_pref = pyauto.PyUITest.EvalDataFrom(
os.path.join(pyauto.PyUITest.DataDir(), 'pyauto_private', 'stress',
'stress_pref'))
breakpad_dir = None
chrome_version = None
bookmarks_list = []
def _FuncDir(self):
"""Returns the path to the functional dir chrome/test/functional."""
return os.path.dirname(__file__)
def _DownloadSymbols(self):
"""Downloads the symbols for the build being tested."""
download_location = os.path.join(os.getcwd(), 'Build_Symbols')
if os.path.exists(download_location):
shutil.rmtree(download_location)
os.makedirs(download_location)
url = self.stress_pref['symbols_dir'] + self.chrome_version
# TODO: Add linux symbol_files
if self.IsWin():
url = url + '/win/'
symbol_files = ['chrome.dll.pdb', 'chrome.exe.pdb']
elif self.IsMac():
url = url + '/mac/'
symbol_files = map(urllib.quote,
['Google Chrome Framework.framework',
'Google Chrome Helper.app',
'Google Chrome.app',
'crash_inspector',
'crash_report_sender',
'ffmpegsumo.so',
'libplugin_carbon_interpose.dylib'])
index = 0
symbol_files = ['%s-%s-i386.breakpad' % (sym_file, self.chrome_version) \
for sym_file in symbol_files]
logging.info(symbol_files)
for sym_file in symbol_files:
sym_url = url + sym_file
logging.info(sym_url)
download_sym_file = os.path.join(download_location, sym_file)
logging.info(download_sym_file)
urllib.urlretrieve(sym_url, download_sym_file)
def setUp(self):
pyauto.PyUITest.setUp(self)
self.breakpad_dir = self._CrashDumpFolder()
self.chrome_version = self.GetBrowserInfo()['properties']['ChromeVersion']
# Plugin stress functions
def _CheckForPluginProcess(self, plugin_name):
"""Checks if a particular plugin process exists.
Args:
plugin_name : plugin process which should be running.
"""
process = self.GetBrowserInfo()['child_processes']
self.assertTrue([x for x in process
if x['type'] == 'Plug-in' and
x['name'] == plugin_name])
def _GetPluginProcessId(self, plugin_name):
"""Get Plugin process id.
Args:
plugin_name: Plugin whose pid is expected.
Eg: "Shockwave Flash"
Returns:
Process id if the plugin process is running.
None otherwise.
"""
for process in self.GetBrowserInfo()['child_processes']:
if process['type'] == 'Plug-in' and \
re.search(plugin_name, process['name']):
return process['pid']
return None
def _CloseAllTabs(self):
"""Close all but one tab in first window."""
tab_count = self.GetTabCount(0)
for tab_index in xrange(tab_count - 1, 0, -1):
self.CloseTab(tab_index)
def _CloseAllWindows(self):
"""Close all windows except one."""
win_count = self.GetBrowserWindowCount()
for windex in xrange(win_count - 1, 0, -1):
self.RunCommand(pyauto.IDC_CLOSE_WINDOW, windex)
def _ReloadAllTabs(self):
"""Reload all the tabs in first window."""
for tab_index in range(self.GetTabCount()):
self.ReloadTab(tab_index)
def _LoadFlashInMultipleTabs(self):
"""Load Flash in multiple tabs in first window."""
self.NavigateToURL(self.empty_url)
# Open 18 tabs with flash
for _ in range(9):
self.AppendTab(pyauto.GURL(self.flash_url1))
self.AppendTab(pyauto.GURL(self.flash_url2))
def _OpenAndCloseMultipleTabsWithFlash(self):
"""Stress test for flash in multiple tabs."""
logging.info("In _OpenAndCloseMultipleWindowsWithFlash.")
self._LoadFlashInMultipleTabs()
self._CheckForPluginProcess('Shockwave Flash')
self._CloseAllTabs()
def _OpenAndCloseMultipleWindowsWithFlash(self):
"""Stress test for flash in multiple windows."""
logging.info('In _OpenAndCloseMultipleWindowsWithFlash.')
# Open 5 Normal and 4 Incognito windows
for tab_index in range(1, 10):
if tab_index < 6:
self.OpenNewBrowserWindow(True)
else:
self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW)
self.NavigateToURL(self.flash_url2, tab_index, 0)
self.AppendTab(pyauto.GURL(self.flash_url2), tab_index)
self._CloseAllWindows()
def _OpenAndCloseMultipleTabsWithMultiplePlugins(self):
"""Stress test using multiple plugins in multiple tabs."""
logging.info('In _OpenAndCloseMultipleTabsWithMultiplePlugins.')
# Append 4 tabs with URL
for _ in range(5):
self.AppendTab(pyauto.GURL(self.plugin_url))
self._CloseAllTabs()
def _OpenAndCloseMultipleWindowsWithMultiplePlugins(self):
"""Stress test using multiple plugins in multiple windows."""
logging.info('In _OpenAndCloseMultipleWindowsWithMultiplePlugins.')
# Open 4 windows with URL
for tab_index in range(1, 5):
if tab_index < 6:
self.OpenNewBrowserWindow(True)
else:
self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW)
self.NavigateToURL(self.plugin_url, tab_index, 0)
self._CloseAllWindows()
def _KillAndReloadFlash(self):
"""Stress test by killing flash process and reloading tabs."""
self._LoadFlashInMultipleTabs()
flash_process_id1 = self._GetPluginProcessId('Shockwave Flash')
self.Kill(flash_process_id1)
self._ReloadAllTabs()
self._CloseAllTabs()
def _KillAndReloadRenderersWithFlash(self):
"""Stress test by killing renderer processes and reloading tabs."""
logging.info('In _KillAndReloadRenderersWithFlash')
self._LoadFlashInMultipleTabs()
info = self.GetBrowserInfo()
# Kill all renderer processes
for tab_index in range(self.GetTabCount(0)):
self.KillRendererProcess(
info['windows'][0]['tabs'][tab_index]['renderer_pid'])
self._ReloadAllTabs()
self._CloseAllTabs()
def _TogglePlugin(self, plugin_name):
"""Toggle plugin status.
Args:
plugin_name: Name of the plugin to toggle.
"""
plugins = self.GetPluginsInfo().Plugins()
for item in range(len(plugins)):
if re.search(plugin_name, plugins[item]['name']):
if plugins[item]['enabled']:
self.DisablePlugin(plugins[item]['path'])
else:
self.EnablePlugin(plugins[item]['path'])
def _ToggleAndReloadFlashPlugin(self):
"""Toggle flash and reload all tabs."""
logging.info('In _ToggleAndReloadFlashPlugin')
for _ in range(10):
self.AppendTab(pyauto.GURL(self.flash_url3))
# Disable Flash Plugin
self._TogglePlugin('Shockwave Flash')
self._ReloadAllTabs()
# Enable Flash Plugin
self._TogglePlugin('Shockwave Flash')
self._ReloadAllTabs()
self._CloseAllTabs()
# Downloads stress functions
def _LoadDownloadsInMultipleTabs(self):
"""Load Downloads in multiple tabs in the same window."""
# Open 15 tabs with downloads
logging.info('In _LoadDownloadsInMultipleTabs')
for tab_index in range(15):
# We open an empty tab and then downlad a file from it.
self.AppendTab(pyauto.GURL(self.empty_url))
self.NavigateToURL(self.download_url1, 0, tab_index + 1)
self.AppendTab(pyauto.GURL(self.empty_url))
self.NavigateToURL(self.download_url2, 0, tab_index + 2)
def _OpenAndCloseMultipleTabsWithDownloads(self):
"""Download items in multiple tabs."""
logging.info('In _OpenAndCloseMultipleTabsWithDownloads')
self._LoadDownloadsInMultipleTabs()
self._CloseAllTabs()
def _OpenAndCloseMultipleWindowsWithDownloads(self):
"""Randomly have downloads in multiple windows."""
logging.info('In _OpenAndCloseMultipleWindowsWithDownloads')
# Open 15 Windows randomly on both regular and incognito with downloads
for window_index in range(15):
tick = round(random.random() * 100)
if tick % 2 != 0:
self.NavigateToURL(self.download_url2, 0, 0)
else:
self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW)
self.AppendTab(pyauto.GURL(self.empty_url), 1)
self.NavigateToURL(self.download_url2, 1, 1)
self._CloseAllWindows()
def _OpenAndCloseMultipleTabsWithMultipleDownloads(self):
"""Download multiple items in multiple tabs."""
logging.info('In _OpenAndCloseMultipleTabsWithMultipleDownloads')
self.NavigateToURL(self.empty_url)
for _ in range(15):
for file in self.file_list:
count = 1
url = self.GetFileURLForPath(
os.path.join(self.DataDir(), 'downloads', file))
self.AppendTab(pyauto.GURL(self.empty_url))
self.NavigateToURL(url, 0, count)
count = count + 1
self._CloseAllTabs()
def _OpenAndCloseMultipleWindowsWithMultipleDownloads(self):
"""Randomly multiple downloads in multiple windows."""
logging.info('In _OpenAndCloseMultipleWindowsWithMultipleDownloads')
for _ in range(15):
for file in self.file_list:
tick = round(random.random() * 100)
url = self.GetFileURLForPath(
os.path.join(self.DataDir(), 'downloads', file))
if tick % 2!= 0:
self.NavigateToURL(url, 0, 0)
else:
self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW)
self.AppendTab(pyauto.GURL(self.empty_url), 1)
self.NavigateToURL(url, 1, 1)
self._CloseAllWindows()
# Back and Forward stress functions
def _BrowserGoBack(self, window_index):
"""Go back in the browser history.
Chrome has limitation on going back and can only go back 49 pages.
Args:
window_index: the index of the browser window to work on.
"""
for nback in range(48): # Go back 48 times.
if nback % 4 == 0: # Bookmark every 5th url when going back.
self._BookMarkEvery5thURL(window_index)
self.TabGoBack(tab_index=0, windex=window_index)
def _BrowserGoForward(self, window_index):
"""Go Forward in the browser history.
Chrome has limitation on going back and can only go back 49 pages.
Args:
window_index: the index of the browser window to work on.
"""
for nforward in range(48): # Go back 48 times.
if nforward % 4 == 0: # Bookmark every 5th url when going Forward
self._BookMarkEvery5thURL(window_index)
self.TabGoForward(tab_index=0, windex=window_index)
def _AddToListAndBookmark(self, newname, url):
"""Bookmark the url to bookmarkbar and to he list of bookmarks.
Args:
newname: the name of the bookmark.
url: the url to bookmark.
"""
bookmarks = self.GetBookmarkModel()
bar_id = bookmarks.BookmarkBar()['id']
self.AddBookmarkURL(bar_id, 0, newname, url)
self.bookmarks_list.append(newname)
def _RemoveFromListAndBookmarkBar(self, name):
"""Remove the bookmark bor and bookmarks list.
Args:
name: the name of bookmark to remove.
"""
bookmarks = self.GetBookmarkModel()
node = bookmarks.FindByTitle(name)
self.RemoveBookmark(node[0]['id'])
self.bookmarks_list.remove(name)
def _DuplicateBookmarks(self, name):
"""Find duplicate bookmark in the bookmarks list.
Args:
name: name of the bookmark.
Returns:
True if it's a duplicate.
"""
for index in (self.bookmarks_list):
if index == name:
return True
return False
def _BookMarkEvery5thURL(self, window_index):
"""Check for duplicate in list and bookmark current url.
If its the first time and list is empty add the bookmark.
If its a duplicate remove the bookmark.
If its new tab page move over.
Args:
window_index: the index of the browser window to work on.
"""
tab_title = self.GetActiveTabTitle(window_index) # get the page title
url = self.GetActiveTabURL(window_index).spec() # get the page url
if not self.bookmarks_list:
self._AddToListAndBookmark(tab_title, url) # first run bookmark the url
return
elif self._DuplicateBookmarks(tab_title):
self._RemoveFromListAndBookmarkBar(tab_title)
return
elif tab_title == 'New Tab': # new tab page pass over
return
else:
# new bookmark add it to bookmarkbar
self._AddToListAndBookmark(tab_title, url)
return
def _ReadFileAndLoadInNormalAndIncognito(self):
"""Read urls and load them in normal and incognito window.
We load 96 urls only as we can go back and forth 48 times.
Uses time to get different urls in normal and incognito window
The source file is taken from stress folder in /data folder.
"""
# URL source from stress folder in data folder
data_file = os.path.join(self.DataDir(), 'pyauto_private', 'stress',
'urls_and_titles')
url_data = self.EvalDataFrom(data_file)
urls = url_data.keys()
i = 0
ticks = int(time.time()) # get the latest time.
for url in urls:
if i <= 96 : # load only 96 urls.
if ticks % 2 == 0: # loading in Incognito and Normal window.
self.NavigateToURL(url)
else:
self.NavigateToURL(url, 1, 0)
else:
break
ticks = ticks - 1
i += 1
return
def _StressTestNavigation(self):
""" This is the method from where various navigations are called.
First we load the urls then call navigete back and forth in
incognito window then in normal window.
"""
self._ReadFileAndLoadInNormalAndIncognito() # Load the urls.
self._BrowserGoBack(1) # Navigate back in incognito window.
self._BrowserGoForward(1) # Navigate forward in incognito window
self._BrowserGoBack(0) # Navigate back in normal window
self._BrowserGoForward(0) # Navigate forward in normal window
# Preference stress functions
def _RandomBool(self):
"""For any preferences bool value, it takes True or False value.
We are generating random True or False value.
"""
return random.randint(0, 1) == 1
def _RandomURL(self):
"""Some of preferences take string url, so generating random url here."""
# Site list
site_list = ['test1.html', 'test2.html','test3.html','test4.html',
'test5.html', 'test7.html', 'test6.html']
random_site = random.choice(site_list)
# Returning a url of random site
return self.GetFileURLForPath(os.path.join(self.DataDir(), random_site))
def _RandomURLArray(self):
"""Returns a list of 10 random URLs."""
return [self._RandomURL() for _ in range(10)]
def _RandomInt(self, max_number):
"""Some of the preferences takes integer value.
Eg: If there are three options, we generate random
value for any option.
Arg:
max_number: The number of options that a preference has.
"""
return random.randrange(1, max_number)
def _RandomDownloadDir(self):
"""Returns a random download directory."""
return random.choice(['dl_dir1', 'dl_dir2', 'dl_dir3',
'dl_dir4', 'dl_dir5'])
def _SetPref(self):
"""Reads the preferences from file and
sets the preferences to Chrome.
"""
raw_dictionary = self.EvalDataFrom(os.path.join(self.DataDir(),
'pyauto_private', 'stress', 'pref_dict'))
value_dictionary = {}
for key, value in raw_dictionary.iteritems():
if value == 'BOOL':
value_dictionary[key] = self._RandomBool()
elif value == 'STRING_URL':
value_dictionary[key] = self._RandomURL()
elif value == 'ARRAY_URL':
value_dictionary[key] = self._RandomURLArray()
elif value == 'STRING_PATH':
value_dictionary[key] = self._RandomDownloadDir()
elif value[0:3] == 'INT':
# Normally we difine INT datatype with number of options,
# so parsing number of options and selecting any of them
# randomly.
value_dictionary[key] = 1
max_number = raw_dictionary[key][3:4]
if not max_number == 1:
value_dictionary[key]= self._RandomInt(int(max_number))
self.SetPrefs(getattr(pyauto,key), value_dictionary[key])
return value_dictionary
# Crash reporting functions
def _CrashDumpFolder(self):
"""Get the breakpad folder.
Returns:
The full path of the Crash Reports folder.
"""
breakpad_folder = self.GetBrowserInfo()['properties']['DIR_CRASH_DUMPS']
self.assertTrue(breakpad_folder, 'Cannot figure crash dir')
return breakpad_folder
def _DeleteDumps(self):
"""Delete all the dump files in teh Crash Reports folder."""
# should be called at the start of stress run
if os.path.exists(self.breakpad_dir):
logging.info('xxxxxxxxxxxxxxxINSIDE DELETE DUMPSxxxxxxxxxxxxxxxxx')
if self.IsMac():
shutil.rmtree(self.breakpad_dir)
elif self.IsWin():
files = os.listdir(self.breakpad_dir)
for file in files:
os.remove(file)
first_crash = os.path.join(os.getcwd(), '1stcrash')
crashes_dir = os.path.join(os.getcwd(), 'crashes')
if (os.path.exists(crashes_dir)):
shutil.rmtree(crashes_dir)
shutil.rmtree(first_crash)
def _SymbolicateCrashDmp(self, dmp_file, symbols_dir, output_file):
"""Generate symbolicated crash report.
Args:
dmp_file: the dmp file to symbolicate.
symbols_dir: the directory containing the symbols.
output_file: the output file.
Returns:
Crash report text.
"""
report = ''
if self.IsWin():
windbg_cmd = [
os.path.join('C:', 'Program Files', 'Debugging Tools for Windows',
'windbg.exe'),
'-Q',
'-y',
'\"',
symbols_dir,
'\"',
'-c',
'\".ecxr;k50;.logclose;q\"',
'-logo',
output_file,
'-z',
'\"',
dmp_file,
'\"']
subprocess.call(windbg_cmd)
# Since we are directly writing the info into output_file,
# we just need to copy that in to report
report = open(output_file, 'r').read()
elif self.IsMac():
crash_report = os.path.join(self.DataDir(), 'pyauto_private', 'stress',
'mac', 'crash_report')
for i in range(5): # crash_report doesn't work sometimes. So we retry
report = test_utils.Shell2(
'%s -S "%s" "%s"' % (crash_report, symbols_dir, dmp_file))[0]
if len(report) < 200:
try_again = 'Try %d. crash_report didn\'t work out. Trying again', i
logging.info(try_again)
else:
break
open(output_file, 'w').write(report)
return report
def _SaveSymbols(self, symbols_dir, dump_dir=' ', multiple_dumps=True):
"""Save the symbolicated files for all crash dumps.
Args:
symbols_dir: the directory containing the symbols.
dump_dir: Path to the directory holding the crash dump files.
multiple_dumps: True if we are processing multiple dump files,
False if we are processing only the first crash.
"""
if multiple_dumps:
dump_dir = self.breakpad_dir
if not os.path.isdir(CRASHES):
os.makedirs(CRASHES)
# This will be sent to the method by the caller.
dmp_files = glob.glob(os.path.join(dump_dir, '*.dmp'))
for dmp_file in dmp_files:
dmp_id = os.path.splitext(os.path.basename(dmp_file))[0]
if multiple_dumps:
report_folder = CRASHES
else:
report_folder = dump_dir
report_fname = os.path.join(report_folder,
'%s.txt' % (dmp_id))
report = self._SymbolicateCrashDmp(dmp_file, symbols_dir,
report_fname)
if report == '':
logging.info('Crash report is empty.')
# This is for copying the original dumps.
if multiple_dumps:
shutil.copy2(dmp_file, CRASHES)
def _GetFirstCrashDir(self):
"""Get first crash file in the crash folder.
Here we create the 1stcrash directory which holds the
first crash report, which will be attached to the mail.
"""
breakpad_folder = self.breakpad_dir
dump_list = glob.glob1(breakpad_folder,'*.dmp')
dump_list.sort(key=lambda s: os.path.getmtime(os.path.join(
breakpad_folder, s)))
first_crash_file = os.path.join(breakpad_folder, dump_list[0])
if not os.path.isdir('1stcrash'):
os.makedirs('1stcrash')
shutil.copy2(first_crash_file, '1stcrash')
first_crash_dir = os.path.join(os.getcwd(), '1stcrash')
return first_crash_dir
def _GetFirstCrashFile(self):
"""Get first crash file in the crash folder."""
first_crash_dir = os.path.join(os.getcwd(), '1stcrash')
for each in os.listdir(first_crash_dir):
if each.endswith('.txt'):
first_crash_file = each
return os.path.join(first_crash_dir, first_crash_file)
def _ProcessOnlyFirstCrash(self):
""" Process only the first crash report for email."""
first_dir = self._GetFirstCrashDir()
self._SaveSymbols(self.symbols_dir, first_dir, False)
def _GetOSName(self):
"""Returns the OS type we are running this script on."""
os_name = ''
if self.IsMac():
os_number = commands.getoutput('sw_vers -productVersion | cut -c 1-4')
if os_number == '10.6':
os_name = 'Snow_Leopard'
elif os_number == '10.5':
os_name = 'Leopard'
elif self.IsWin():
# TODO: Windows team need to find the way to get OS name
os_name = 'Windows'
if platform.version()[0] == '5':
os_name = os_name + '_XP'
else:
os_name = os_name + '_Vista/Win7'
return os_name
def _ProcessUploadAndEmailCrashes(self):
"""Upload the crashes found and email the team about this."""
logging.info('#########INSIDE _ProcessUploadAndEmailCrashes#########')
try:
build_version = self.chrome_version
self._SaveSymbols(self.symbols_dir)
self._ProcessOnlyFirstCrash()
file_to_attach = self._GetFirstCrashFile()
# removing the crash_txt for now,
# since we are getting UnicodeDecodeError
# crash_txt = open(file_to_attach).read()
except ValueError:
test_utils.SendMail(self.stress_pref['mailing_address'],
self.stress_pref['mailing_address'],
"We don't have build version",
"BROWSER CRASHED, PLEASE CHECK",
self.stress_pref['smtp'])
# Move crash reports and dumps to server
os_name = self._GetOSName()
dest_dir = build_version + '_' + os_name
if (test_utils.Shell2(self.stress_pref['script'] % (CRASHES, dest_dir))):
logging.info('Copy Complete')
upload_dir= self.stress_pref['upload_dir'] + dest_dir
num_crashes = '\n \n Number of Crashes :' + \
str(len(glob.glob1(self.breakpad_dir, '*.dmp')))
mail_content = '\n\n Crash Report URL :' + upload_dir + '\n' + \
num_crashes + '\n\n' # + crash_txt
mail_subject = 'Stress Results :' + os_name + '_' + build_version
# Sending mail with first crash report, # of crashes, location of upload
test_utils.SendMail(self.stress_pref['mailing_address'],
self.stress_pref['mailing_address'],
mail_subject, mail_content,
self.stress_pref['smtp'], file_to_attach)
def _ReportCrashIfAny(self):
"""Check for browser crashes and report."""
if os.path.isdir(self.breakpad_dir):
listOfDumps = glob.glob(os.path.join(self.breakpad_dir, '*.dmp'))
if len(listOfDumps) > 0:
logging.info('========== INSIDE REPORT CRASH++++++++++++++')
# inform a method to process the dumps
self._ProcessUploadAndEmailCrashes()
# Test functions
def _PrefStress(self):
"""Stress preferences."""
default_prefs = self.GetPrefsInfo()
pref_dictionary = self._SetPref()
for key, value in pref_dictionary.iteritems():
self.assertEqual(value, self.GetPrefsInfo().Prefs(
getattr(pyauto, key)))
for key, value in pref_dictionary.iteritems():
self.SetPrefs(getattr(pyauto, key),
default_prefs.Prefs(getattr(pyauto, key)))
def _NavigationStress(self):
"""Run back and forward stress in normal and incognito window."""
self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW)
self._StressTestNavigation()
def _DownloadStress(self):
"""Run all the Download stress test."""
org_download_dir = self.GetDownloadDirectory().value()
new_dl_dir = os.path.join(org_download_dir, 'My+Downloads Folder')
os.path.exists(new_dl_dir) and shutil.rmtree(new_dl_dir)
os.makedirs(new_dl_dir)
self.SetPrefs(pyauto.kDownloadDefaultDirectory, new_dl_dir)
self._OpenAndCloseMultipleTabsWithDownloads()
self._OpenAndCloseMultipleWindowsWithDownloads()
self._OpenAndCloseMultipleTabsWithMultipleDownloads()
self._OpenAndCloseMultipleWindowsWithMultipleDownloads()
pyauto_utils.RemovePath(new_dl_dir) # cleanup
self.SetPrefs(pyauto.kDownloadDefaultDirectory, org_download_dir)
def _PluginStress(self):
"""Run all the plugin stress tests."""
self._OpenAndCloseMultipleTabsWithFlash()
self._OpenAndCloseMultipleWindowsWithFlash()
self._OpenAndCloseMultipleTabsWithMultiplePlugins()
self._OpenAndCloseMultipleWindowsWithMultiplePlugins()
self._KillAndReloadRenderersWithFlash()
self._ToggleAndReloadFlashPlugin()
def testStress(self):
"""Run all the stress tests for 24 hrs."""
if self.GetBrowserInfo()['properties']['branding'] != 'Google Chrome':
logging.info('This is not a branded build, so stopping the stress')
return 1
self._DownloadSymbols()
run_number = 1
start_time = time.time()
while True:
logging.info('run %d...' % run_number)
run_number = run_number + 1
if (time.time() - start_time) >= 24*60*60:
logging.info('Its been 24hrs, so we break now.')
break
try:
methods = [self._NavigationStress, self._DownloadStress,
self._PluginStress, self._PrefStress]
random.shuffle(methods)
for method in methods:
method()
logging.info('Method %s done' % method)
except KeyboardInterrupt:
logging.info('----------We got a KeyboardInterrupt-----------')
except Exception, error:
logging.info('-------------There was an ERROR---------------')
logging.info(error)
# Crash Reporting
self._ReportCrashIfAny()
self._DeleteDumps()
if self.IsMac():
zombie = 'ps -el | grep Chrom | grep -v grep | grep Z | wc -l'
zombie_count = int(commands.getoutput(zombie))
if zombie_count > 0:
logging.info('WE HAVE ZOMBIES = %d' % zombie_count)
if __name__ == '__main__':
pyauto_functional.Main()