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

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

Powered by Google App Engine
This is Rietveld 408576698