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

Side by Side Diff: install_test/install_test.py

Issue 10384104: Chrome updater test framework (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/chrome/test/
Patch Set: Created 8 years, 2 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 | « install_test/chrome_installer_win.py ('k') | install_test/sample_updater.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Test fixture for tests involving installing/updating Chrome.
6
7 Provides an interface to install or update chrome from within a testcase, and
8 allows users to run tests using installed version of Chrome. User and system
9 level installations are supported, and either one can be used for running the
10 tests. Currently the only platform it supports is Windows.
11 """
12
13 import atexit
14 import logging
15 import optparse
16 import os
17 import platform
18 import re
19 import shutil
20 import stat
21 import sys
22 import tempfile
23 import unittest
24 import urllib
25
26 import chrome_installer_win
27
28 _DIRECTORY = os.path.dirname(os.path.abspath(__file__))
29 sys.path.append(os.path.join(os.path.dirname(_DIRECTORY), 'pyautolib'))
30 sys.path.append(os.path.join(_DIRECTORY, os.path.pardir, os.path.pardir,
31 os.path.pardir, 'third_party', 'webdriver',
32 'pylib'))
33
34 # This import should go after sys.path is set appropriately.
35 import pyauto_utils
36 import selenium.webdriver.chrome.service as service
37 from selenium import webdriver
38
39
40 def MakeTempDir(parent_dir=None):
41 """Creates a temporary directory and returns an absolute path to it.
42
43 The temporary directory is automatically deleted when the python interpreter
44 exits normally.
45
46 Args:
47 parent_dir: the directory to create the temp dir in. If None, the system
48 temp dir is used.
49
50 Returns:
51 The absolute path to the temporary directory.
52 """
53 path = tempfile.mkdtemp(dir=parent_dir)
54 def DeleteDir():
55 # Don't use shutil.rmtree because it can't delete read-only files on Win.
56 for root, dirs, files in os.walk(path, topdown=False):
57 for name in files:
58 filename = os.path.join(root, name)
59 os.chmod(filename, stat.S_IWRITE)
60 os.remove(filename)
61 for name in dirs:
62 os.rmdir(os.path.join(root, name))
63 atexit.register(DeleteDir)
64 return path
65
66
67 class InstallTest(unittest.TestCase):
68 """Base updater test class.
69
70 All dependencies, like Chrome installers and ChromeDriver, are downloaded at
71 the beginning of the test. Dependencies are downloaded in the temp directory.
72 This download occurs only once, before the first test is executed. Each test
73 case starts an instance of ChromeDriver and terminates it upon completion.
74 All updater tests should derive from this class.
75
76 Example:
77
78 class SampleUpdater(InstallTest):
79
80 def testCanOpenGoogle(self):
81 self._driver.get('http://www.google.com/')
82 self.UpdateBuild()
83 self._driver.get('http://www.msn.com/')
84
85 Include the following in your updater test script to make it run standalone.
86
87 from install_test import Main
88
89 if __name__ == '__main__':
90 Main()
91
92 To fire off an updater test, use the command below.
93 python test_script.py --url=<URL> --builds=22.0.1230.0,22.0.1231.0
94 """
95
96 _DIR_PREFIX = '__CHRBLD__'
97 _INSTALLER_NAME = 'mini_installer.exe'
98 _installer_paths = []
99 _chrome_driver = ''
100 _installer_options = []
101
102 def __init__(self, methodName='runTest'):
103 unittest.TestCase.__init__(self, methodName)
104 self._counter = 0
105 current_version = chrome_installer_win.ChromeInstallation.GetCurrent()
106 if current_version:
107 current_version.Uninstall()
108 self._install_type = ('system-level' in self._installer_options and
109 chrome_installer_win.InstallationType.SYSTEM or
110 chrome_installer_win.InstallationType.USER)
111
112 def setUp(self):
113 """Called before each unittest to prepare the test fixture."""
114 self._InstallNext()
115 self._StartChromeDriver()
116
117 def tearDown(self):
118 """Called at the end of each unittest to do any test related cleanup."""
119 self._driver.quit()
120 self._service.stop()
121 self._installation.Uninstall()
122
123 def _StartChromeDriver(self):
124 """Starts ChromeDriver."""
125 self._service = service.Service(InstallTest._chrome_driver)
126 self._service.start()
127 self._driver = webdriver.Remote(
128 self._service.service_url,
129 {'chrome.binary' : self._installation.GetExePath()}
130
131 def _InstallNext(self):
132 """Helper method that installs Chrome."""
133 self._installation = chrome_installer_win.Install(
134 self._installer_paths[self._counter],
135 self._install_type,
136 self._builds[self._counter],
137 self._installer_options)
138 self._counter += 1
139
140 def UpdateBuild(self):
141 """Updates Chrome by installing a newer version."""
142 self._driver.quit()
143 self._InstallNext()
144 self._driver = webdriver.Remote(self._service.service_url,
145 self._capabilities)
146
147 @staticmethod
148 def _Download(url, path):
149 """Downloads a file from the specified URL.
150
151 Args:
152 url: URL where the file is located.
153 path: Location where file will be downloaded.
154 """
155 if not pyauto_utils.DoesUrlExist(url):
156 raise RuntimeError('Either the URL or the file name is invalid.')
157 urllib.urlretrieve(url, path)
158
159 @staticmethod
160 def InitTestFixture(builds, base_url, options):
161 """Static method for passing command options to InstallTest.
162
163 We do not instantiate InstallTest. Therefore, command arguments cannot
164 be passed to its constructor. Since InstallTest needs to use these options
165 and using globals is not an option, this method can be used by the Main
166 class to pass the arguments it parses onto InstallTest.
167 """
168 builds = builds.split(',') if builds else []
169 system = ({'Windows': 'win',
170 'Darwin': 'mac',
171 'Linux': 'linux'}).get(platform.system())
172 InstallTest._installer_options = options.split(',') if options else []
173 InstallTest._builds = builds
174 tempdir = MakeTempDir()
175 for build in builds:
176 url = '%s%s/%s/mini_installer.exe' % (base_url, build, system)
177 installer_path = os.path.join(tempdir, 'mini_installer_%s.exe' % build)
178 InstallTest._installer_paths.append(installer_path)
179 InstallTest._Download(url, installer_path)
180 InstallTest._chrome_driver = os.path.join(tempdir, 'chromedriver.exe')
181 url = '%s%s/%s/%s/chromedriver.exe' % (base_url, build, system,
182 'chrome-win32.test')
183 InstallTest._Download(url, InstallTest._chrome_driver)
184
185
186 class Main(object):
187 """Main program for running Updater tests."""
188
189 def __init__(self):
190 self._SetLoggingConfiguration()
191 self._ParseArgs()
192 self._Run()
193
194 def _ParseArgs(self):
195 """Parses command line arguments."""
196 parser = optparse.OptionParser()
197 parser.add_option(
198 '-b', '--builds', type='string', default='', dest='builds',
199 help='Specifies the two builds needed for testing.')
200 parser.add_option(
201 '-u', '--url', type='string', default='', dest='url',
202 help='Specifies the build url, without the build number.')
203 parser.add_option(
204 '-o', '--options', type='string', default='',
205 help='Specifies any additional Chrome options (i.e. --system-level).')
206 opts, args = parser.parse_args()
207 self._ValidateArgs(opts)
208 InstallTest.InitTestFixture(opts.builds, opts.url, opts.options)
209
210 def _ValidateArgs(self, opts):
211 """Verifies the sanity of the command arguments.
212
213 Confirms that all specified builds have a valid version number, and the
214 build urls are valid.
215
216 Args:
217 opts: An object containing values for all command args.
218 """
219 builds = opts.builds.split(',')
220 for build in builds:
221 if not re.match('\d+\.\d+\.\d+\.\d+', build):
222 raise RuntimeError('Invalid build number: %s' % build)
223 if not pyauto_utils.DoesUrlExist('%s/%s/' % (opts.url, build)):
224 raise RuntimeError('Could not locate build no. %s' % build)
225
226 def _SetLoggingConfiguration(self):
227 """Sets the basic logging configuration."""
228 log_format = '%(asctime)s %(levelname)-8s %(message)s'
229 logging.basicConfig(level=logging.INFO, format=log_format)
230
231 def _GetTests(self):
232 """Returns a list of unittests from the calling script."""
233 mod_name = [os.path.splitext(os.path.basename(sys.argv[0]))[0]]
234 if os.path.dirname(sys.argv[0]) not in sys.path:
235 sys.path.append(os.path.dirname(sys.argv[0]))
236 return unittest.defaultTestLoader.loadTestsFromNames(mod_name)
237
238 def _Run(self):
239 """Runs the unit tests."""
240 tests = self._GetTests()
241 result = pyauto_utils.GTestTextTestRunner(verbosity=1).run(tests)
242 del(tests)
243 if not result.wasSuccessful():
244 print >>sys.stderr, ('Not all tests were successful.')
245 sys.exit(1)
246 sys.exit(0)
OLDNEW
« no previous file with comments | « install_test/chrome_installer_win.py ('k') | install_test/sample_updater.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698