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

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

Issue 10389188: Revert 137538 - Nacl sdk Nacl sdk automated test(method-testNaClSDK) of new installation process of… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 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/functional/PYAUTO_TESTS ('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) 2011 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 import copy 6 import copy
7 import ctypes 7 import ctypes
8 from distutils import version 8 from distutils import version
9 import fnmatch 9 import fnmatch
10 import glob 10 import glob
11 import hashlib 11 import hashlib
12 import logging 12 import logging
13 import os 13 import os
14 import platform 14 import platform
15 import re
16 import shutil 15 import shutil
17 import subprocess 16 import subprocess
18 import sys 17 import sys
18 import tarfile
19 import tempfile 19 import tempfile
20 import urllib2 20 import urllib2
21 import xml.dom.minidom 21 import xml.dom.minidom
22 import zipfile
23 22
24 import pyauto_functional # Must be imported before pyauto. 23 import pyauto_functional # Must be imported before pyauto.
25 import pyauto 24 import pyauto
26 import pyauto_utils 25 import pyauto_utils
27 26
28 27
29 class NaClSDKTest(pyauto.PyUITest): 28 class NaClSDKTest(pyauto.PyUITest):
30 """Tests for the NaCl SDK.""" 29 """Tests for the NaCl SDK."""
31 _extracted_sdk_path = None 30 _extracted_sdk_path = None
32 _temp_dir = None 31 _temp_dir = None
33 _pepper_versions = []
34 _updated_pepper_versions = []
35 _latest_updated_pepper_versions = []
36 _settings = { 32 _settings = {
33 'release_win_sdk_url': 'http://commondatastorage.googleapis.com/'
34 'nativeclient-mirror/nacl/nacl_sdk/staging/naclsdk_win.exe',
35 'release_mac_sdk_url': 'http://commondatastorage.googleapis.com/'
36 'nativeclient-mirror/nacl/nacl_sdk/staging/naclsdk_mac.tgz',
37 'release_lin_sdk_url': 'http://commondatastorage.googleapis.com/'
38 'nativeclient-mirror/nacl/nacl_sdk/staging/naclsdk_linux.tgz',
39 'expected_md5_url': 'http://commondatastorage.googleapis.com/'
40 'nativeclient-mirror',
41 'release_win_expected_md5_key': 'nacl/nacl_sdk/staging/naclsdk_win.exe',
42 'release_mac_expected_md5_key': 'nacl/nacl_sdk/staging/naclsdk_mac.tgz',
43 'release_lin_expected_md5_key': 'nacl/nacl_sdk/staging/'
44 'naclsdk_linux.tgz',
37 'post_sdk_download_url': 'http://code.google.com/chrome/nativeclient/' 45 'post_sdk_download_url': 'http://code.google.com/chrome/nativeclient/'
38 'docs/download.html', 46 'docs/download.html',
39 'post_sdk_zip': 'http://commondatastorage.googleapis.com/' 47 'post_win_sdk_url': 'http://commondatastorage.googleapis.com/'
40 'nativeclient-mirror/nacl/nacl_sdk/nacl_sdk.zip', 48 'nativeclient-mirror/nacl/nacl_sdk/naclsdk_win.exe',
49 'post_mac_sdk_url': 'http://commondatastorage.googleapis.com/'
50 'nativeclient-mirror/nacl/nacl_sdk/naclsdk_mac.tgz',
51 'post_lin_sdk_url': 'http://commondatastorage.googleapis.com/'
52 'nativeclient-mirror/nacl/nacl_sdk/naclsdk_linux.tgz',
41 'min_required_chrome_build': 14, 53 'min_required_chrome_build': 14,
54 'gallery_examples': {
55 'life': 'http://nacl-gallery.appspot.com/life/life.html',
56 'hello_world': 'http://nacl-gallery.appspot.com/hello_world/'
57 'hello_world.html',
58 'pi_generator': 'http://nacl-gallery.appspot.com/pi_generator/'
59 'pi_generator.html',
60 'sine_synth': 'http://nacl-gallery.appspot.com/sine_synth/'
61 'sine_synth.html'
62 },
63 'prerelease_gallery': {
64 'hello_world': 'http://4.nacl-gallery.appspot.com/hello_world/'
65 'hello_world.html',
66 'hello_world_c': 'http://4.nacl-gallery.appspot.com/hello_world_c/'
67 'hello_world.html',
68 'life': 'http://4.nacl-gallery.appspot.com/life/life.html',
69 'pi_generator': 'http://4.nacl-gallery.appspot.com/pi_generator/'
70 'pi_generator.html',
71 'sine_synth': 'http://4.nacl-gallery.appspot.com/sine_synth/'
72 'sine_synth.html',
73 'geturl': 'http://4.nacl-gallery.appspot.com/geturl/geturl.html'
74 }
42 } 75 }
43 76
44 def tearDown(self): 77 def tearDown(self):
45 pyauto.PyUITest.tearDown(self) 78 pyauto.PyUITest.tearDown(self)
46 self._RemoveDownloadedTestFile() 79 self._RemoveDownloadedTestFile()
47 80
48 def testNaClSDK(self): 81 def testNaClSDK(self):
49 """Verify that NaCl SDK is working properly.""" 82 """Verify that NaCl SDK is working properly."""
50 if not self._HasAllSystemRequirements(): 83 if not self._HasAllSystemRequirements():
51 logging.info('System does not meet the requirements.') 84 logging.info('System does not meet the requirements.')
52 return 85 return
53 self._extracted_sdk_path = tempfile.mkdtemp() 86 self._extracted_sdk_path = tempfile.mkdtemp()
87
54 self._VerifyDownloadLinks() 88 self._VerifyDownloadLinks()
55 self._VerifyNaClSDKInstaller() 89 self._VerifyNaClSDKInstaller()
56 self._VerifyInstall() 90 self._VerifyBuildStubProject()
57 self._VerifyUpdate()
58 self._LaunchServerAndVerifyExamples() 91 self._LaunchServerAndVerifyExamples()
92 self._VerifyRebuildExamples()
93 self._VerifySelldrAndNcval()
94
95 def testVerifyNaClSDKChecksum(self):
96 """Verify NaCl SDK Checksum."""
97 if not self._HasAllSystemRequirements():
98 logging.info('System does not meet the requirements.')
99 return
100
101 self._DownloadNaClSDK()
102
103 if pyauto.PyUITest.IsWin():
104 expected_md5_key = self._settings['release_win_expected_md5_key']
105 file_path = os.path.join(self._temp_dir, 'naclsdk_win.exe')
106 elif pyauto.PyUITest.IsMac():
107 expected_md5_key = self._settings['release_mac_expected_md5_key']
108 file_path = os.path.join(self._temp_dir, 'naclsdk_mac.tgz')
109 elif pyauto.PyUITest.IsLinux():
110 expected_md5_key = self._settings['release_lin_expected_md5_key']
111 file_path = os.path.join(self._temp_dir, 'naclsdk_linux.tgz')
112 else:
113 self.fail(msg='NaCl SDK does not support this OS.')
114
115 # Get expected MD5.
116 expected_md5_url = self._settings['expected_md5_url']
117 response = urllib2.urlopen(expected_md5_url)
118 dom = xml.dom.minidom.parseString(response.read())
119 dom_content = dom.getElementsByTagName('Contents')
120 expected_md5 = None
121 for con in dom_content:
122 if (self._GetXMLNodeData(con.getElementsByTagName('Key')[0].childNodes)
123 == expected_md5_key):
124 node = con.getElementsByTagName('ETag')[0].childNodes
125 expected_md5 = self._GetXMLNodeData(node).strip('"')
126 self.assertTrue(expected_md5,
127 msg='Cannot get expected MD5 from %s.' % expected_md5_url)
128
129 md5 = hashlib.md5()
130 md5.update(open(file_path).read())
131 md5_sum = md5.hexdigest()
132 self.assertEqual(expected_md5, md5_sum,
133 msg='Unexpected checksum. Expected: %s, got: %s'
134 % (expected_md5, md5_sum))
135
136 def testVerifyNaClPlugin(self):
137 """Verify NaCl plugin."""
138 if not self._HasAllSystemRequirements():
139 logging.info('System does not meet the requirements.')
140 return
141 self._OpenExamplesAndStartTest(
142 self._settings['gallery_examples'])
143
144 def testVerifyPrereleaseGallery(self):
145 """Verify Pre-release gallery examples."""
146 if not self._HasAllSystemRequirements():
147 logging.info('System does not meet the requirements.')
148 return
149 self._OpenExamplesAndStartTest(
150 self._settings['prerelease_gallery'])
59 151
60 def _VerifyDownloadLinks(self): 152 def _VerifyDownloadLinks(self):
61 """Verify the download links. 153 """Verify the download links."""
62
63 Simply verify that NaCl download links exist in html page.
64 """
65 html = None 154 html = None
66 for i in xrange(3): 155 for i in xrange(3):
67 try: 156 try:
68 html = urllib2.urlopen(self._settings['post_sdk_download_url']).read() 157 html = urllib2.urlopen(self._settings['post_sdk_download_url']).read()
69 break 158 break
70 except: 159 except:
71 pass 160 pass
72 self.assertTrue(html, 161 self.assertTrue(html,
73 msg='Cannot open URL: %s' % 162 msg='Cannot open URL: %s' %
74 self._settings['post_sdk_download_url']) 163 self._settings['post_sdk_download_url'])
75 sdk_url = self._settings['post_sdk_zip'] 164
76 self.assertTrue(sdk_url in html, 165 # Make sure the correct URL is under the correct label.
77 msg='Missing SDK download URL: %s' % sdk_url) 166 if pyauto.PyUITest.IsWin():
167 win_sdk_url = self._settings['post_win_sdk_url']
168 win_url_index = html.find(win_sdk_url)
169 self.assertTrue(win_url_index > -1,
170 msg='Missing SDK download URL: %s' % win_sdk_url)
171 win_keyword_index = html.rfind('Windows', 0, win_url_index)
172 self.assertTrue(win_keyword_index > -1,
173 msg='Misplaced download link: %s' % win_sdk_url)
174 elif pyauto.PyUITest.IsMac():
175 mac_sdk_url = self._settings['post_mac_sdk_url']
176 mac_url_index = html.find(mac_sdk_url)
177 self.assertTrue(mac_url_index > -1,
178 msg='Missing SDK download URL: %s' % mac_sdk_url)
179 mac_keyword_index = html.rfind('Macintosh', 0, mac_url_index)
180 self.assertTrue(mac_keyword_index > -1,
181 msg='Misplaced download link: %s' % mac_sdk_url)
182 elif pyauto.PyUITest.IsLinux():
183 lin_sdk_url = self._settings['post_lin_sdk_url']
184 lin_url_index = html.find(lin_sdk_url)
185 self.assertTrue(lin_url_index > -1,
186 msg='Missing SDK download URL: %s' % lin_sdk_url)
187 lin_keyword_index = html.rfind('Linux', 0, lin_url_index)
188 self.assertTrue(lin_keyword_index > -1,
189 msg='Misplaced download link: %s' % lin_sdk_url)
190 else:
191 self.fail(msg='NaCl SDK does not support this OS.')
78 192
79 def _VerifyNaClSDKInstaller(self): 193 def _VerifyNaClSDKInstaller(self):
80 """Verify NaCl SDK installer.""" 194 """Verify NaCl SDK installer."""
81 search_list = [ 195 search_list = [
82 'sdk_cache/', 196 'build.scons',
83 'sdk_tools/', 197 'favicon.ico',
84 ] 198 'geturl/',
199 'hello_world/',
200 'hello_world_c/',
201 'httpd.py',
202 'index.html',
203 'nacl_sdk_scons/',
204 'pi_generator/',
205 'scons',
206 'sine_synth/'
207 ]
208
85 mac_lin_additional_search_items = [ 209 mac_lin_additional_search_items = [
86 'naclsdk', 210 'sel_ldr_x86_32',
87 ] 211 'sel_ldr_x86_64',
212 'ncval_x86_32',
213 'ncval_x86_64'
214 ]
215
88 win_additional_search_items = [ 216 win_additional_search_items = [
89 'naclsdk.bat' 217 'httpd.cmd',
90 ] 218 'sel_ldr_x86_32.exe',
219 'sel_ldr_x86_64.exe',
220 'ncval_x86_32.exe',
221 'ncval_x86_64.exe'
222 ]
223
91 self._DownloadNaClSDK() 224 self._DownloadNaClSDK()
92 self._ExtractNaClSDK() 225
93 if pyauto.PyUITest.IsWin(): 226 if pyauto.PyUITest.IsWin():
94 self._SearchNaClSDKFile( 227 self._ExtractNaClSDK()
228 self._SearchNaClSDKFileWindows(
95 search_list + win_additional_search_items) 229 search_list + win_additional_search_items)
96 elif pyauto.PyUITest.IsMac() or pyauto.PyUITest.IsLinux(): 230 elif pyauto.PyUITest.IsMac():
97 self._SearchNaClSDKFile( 231 source_file = os.path.join(self._temp_dir, 'naclsdk_mac.tgz')
98 search_list + mac_lin_additional_search_items) 232 self._SearchNaClSDKTarFile(search_list + mac_lin_additional_search_items,
233 source_file)
234 self._ExtractNaClSDK()
235 elif pyauto.PyUITest.IsLinux():
236 source_file = os.path.join(self._temp_dir, 'naclsdk_linux.tgz')
237 self._SearchNaClSDKTarFile(search_list + mac_lin_additional_search_items,
238 source_file)
239 self._ExtractNaClSDK()
99 else: 240 else:
100 self.fail(msg='NaCl SDK does not support this OS.') 241 self.fail(msg='NaCl SDK does not support this OS.')
101 242
102 def _VerifyInstall(self): 243 def _VerifyBuildStubProject(self):
103 """Install NACL sdk.""" 244 """Build stub project."""
104 # Executing naclsdk(.bat) list 245 stub_project_files = [
105 if pyauto.PyUITest.IsWin(): 246 'build.scons',
106 source_file = os.path.join( 247 'scons'
107 self._extracted_sdk_path, 'nacl_sdk', 'naclsdk.bat') 248 ]
108 elif pyauto.PyUITest.IsMac() or pyauto.PyUITest.IsLinux(): 249 project_template_path = self._GetDirectoryPath('project_templates',
109 source_file = os.path.join( 250 self._extracted_sdk_path)
110 self._extracted_sdk_path, 'nacl_sdk', 'naclsdk') 251 examples_path = self._GetDirectoryPath('examples',
111 subprocess.call(['chmod', '-R', '755', self._extracted_sdk_path]) 252 self._extracted_sdk_path)
112 else: 253 init_project_path = os.path.join(project_template_path, 'init_project.py')
113 self.fail(msg='NaCl SDK does not support this OS.') 254
114 subprocess.Popen([source_file, 'list'], 255 # Build a C project.
115 stdout=subprocess.PIPE, 256 subprocess.call(
116 stderr=subprocess.PIPE).communicate() 257 ['python', init_project_path, '-n', 'hello_c', '-c', '-d',
117 258 examples_path], stdout=subprocess.PIPE)
118 def _VerifyUpdate(self): 259
119 """Update NACL sdk""" 260 hello_c_path = os.path.join(examples_path, 'hello_c')
120 # Executing naclsdk(.bat) update 261 for file in stub_project_files:
121 if pyauto.PyUITest.IsWin(): 262 self.assertTrue(self._HasFile(file, hello_c_path),
122 source_file = os.path.join(self._extracted_sdk_path, 'nacl_sdk', 263 msg='Cannot build C stub project.')
123 'naclsdk.bat') 264
124 elif pyauto.PyUITest.IsMac() or pyauto.PyUITest.IsLinux(): 265 # Build a C++ project.
125 source_file = os.path.join(self._extracted_sdk_path, 'nacl_sdk', 266 subprocess.call(
126 'naclsdk') 267 ['python', init_project_path, '-n', 'hello_cc', '-d',
127 else: 268 examples_path], stdout=subprocess.PIPE)
128 self.fail(msg='NaCl SDK does not support this OS.') 269
129 # Executing nacl_sdk(.bat) update to get the latest version. 270 hello_cc_path = os.path.join(examples_path, 'hello_cc')
130 updated_output = subprocess.Popen([source_file, 'update'], 271 for file in stub_project_files:
131 stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0] 272 self.assertTrue(self._HasFile(file, hello_cc_path),
132 self._updated_pepper_versions.extend( 273 msg='Cannot build C++ stub project.')
133 re.findall('Updating bundle (pepper_[0-9]{2})', updated_output))
134 self._updated_pepper_versions = list(set(self._updated_pepper_versions))
135 self._updated_pepper_versions.sort(key=str.lower)
136 updated_pepper_versions_len = len(self._updated_pepper_versions)
137 self._latest_updated_pepper_versions = filter(
138 lambda x: x >= 'pepper_18', self._updated_pepper_versions)
139 274
140 def _LaunchServerAndVerifyExamples(self): 275 def _LaunchServerAndVerifyExamples(self):
141 """Start local HTTP server and verify examples.""" 276 """Start local HTTP server and verify examples."""
142 if self._ChromeAndPepperVersion(self._latest_updated_pepper_versions[0]): 277 # Make sure server is not open.
143 examples_path = os.path.join(self._extracted_sdk_path, 'nacl_sdk', 278 if self._IsURLAlive('http://localhost:5103'):
144 self._latest_updated_pepper_versions[0], 279 self._CloseHTTPServer()
145 'examples') 280
146 # Close server if it's already open. 281 # Start HTTP server.
147 if self._IsURLAlive('http://localhost:5103'): 282 examples_path = self._GetDirectoryPath('examples',
148 self._CloseHTTPServer() 283 self._extracted_sdk_path)
149 # Launch local http server. 284 if pyauto.PyUITest.IsWin():
150 proc = subprocess.Popen(['make RUN'], shell=True, cwd=examples_path) 285 http_path = os.path.join(examples_path, 'httpd.cmd')
151 self.WaitUntil( 286 proc = subprocess.Popen([http_path], cwd=examples_path)
152 lambda: self._IsURLAlive('http://localhost:5103'), 287 else:
153 timeout=150, retry_sleep=1) 288 http_path = os.path.join(examples_path, 'httpd.py')
154 289 proc = subprocess.Popen(['python', http_path], cwd=examples_path)
155 examples = { 290
156 'dynamic_library_open': 'http://localhost:5103/dlopen/dlopen.html', 291 success = self.WaitUntil(
157 'geturl': 'http://localhost:5103/geturl/geturl.html', 292 lambda: self._IsURLAlive('http://localhost:5103'),
158 'input_events': 'http://localhost:5103/input_events' 293 timeout=30, retry_sleep=1, expect_retval=True)
159 '/input_events.html', 294 self.assertTrue(success,
160 'load_progress': 295 msg='Cannot open HTTP server. %s' %
161 'http://localhost:5103/load_progress/load_progress.html', 296 self.GetActiveTabTitle())
162 'multithreaded_input_events': 297
163 'http://localhost:5103/multithreaded_input_events' 298 examples = {
164 '/mt_input_events.html', 299 'hello_world_c': 'http://localhost:5103/hello_world_c/'
165 'pi_generator': 300 'hello_world.html',
166 'http://localhost:5103/pi_generator/pi_generator.html', 301 'hello_world': 'http://localhost:5103/hello_world/hello_world.html',
167 'sine_synth': 'http://localhost:5103/sine_synth/sine_synth.html', 302 'geturl': 'http://localhost:5103/geturl/geturl.html',
168 'web_socket': 303 'pi_generator': 'http://localhost:5103/pi_generator/pi_generator.html',
169 'http://localhost:5103/websocket/websocket.html', 304 'sine_synth': 'http://localhost:5103/sine_synth/sine_synth.html',
170 } 305 }
171 try: 306 try:
172 self._OpenExamplesAndStartTest(examples) 307 self._OpenExamplesAndStartTest(examples)
173 finally: 308 finally:
174 self._CloseHTTPServer(proc) 309 self._CloseHTTPServer(proc)
175 310
176 else: 311 def _VerifyRebuildExamples(self):
177 self.fail(msg='Pepper Version %s doesnot match the Chrome version %s.' 312 """Re-build the examples and verify they are as expected."""
178 % (self._latest_updated_pepper_versions[0], 313 example_dirs = [
179 self.GetBrowserInfo()['properties']['ChromeVersion'])) 314 'geturl',
180 315 'hello_world',
181 def _ChromeAndPepperVersion(self, pepper_version='pepper_18'): 316 'hello_world_c',
182 """Determine if chrome and pepper version matach""" 317 'pi_generator',
183 version_number = re.findall('pepper_([0-9]{2})', pepper_version) 318 'sine_synth'
184 browser_info = self.GetBrowserInfo() 319 ]
185 chrome_version = browser_info['properties']['ChromeVersion'] 320 examples_path = self._GetDirectoryPath('examples',
186 chrome_build = int(chrome_version.split('.')[0]) 321 self._extracted_sdk_path)
187 return int(chrome_build) == int(version_number[0]) 322
323 scons_path = os.path.join(examples_path, 'scons -c')
324 subprocess.call([scons_path], cwd=examples_path, shell=True)
325 for x in example_dirs:
326 ex_path = os.path.join(examples_path, x)
327 self.assertFalse(self._HasFile('*.nmf', ex_path),
328 msg='Failed running scons -c.')
329
330 scons_path = os.path.join(examples_path, 'scons')
331 proc = subprocess.Popen([scons_path], cwd=examples_path,
332 stdout=subprocess.PIPE, shell=True)
333 proc.communicate()
334
335 # Verify each example directory contains .nmf file.
336 for dir in example_dirs:
337 dir = os.path.join(examples_path, dir)
338 if not self._HasFile('*.nmf', dir):
339 self.fail(msg='Failed running scons.')
340
341 self._LaunchServerAndVerifyExamples()
342
343 def _VerifySelldrAndNcval(self):
344 """Verify sel_ldr and ncval."""
345 architecture = self._GetPlatformArchitecture()
346 scons_arg = None
347 if pyauto.PyUITest.IsWin():
348 if architecture == '64bit':
349 scons_arg = 'test64'
350 else:
351 scons_arg = 'test32'
352 elif pyauto.PyUITest.IsMac():
353 scons_arg = 'test64'
354 elif pyauto.PyUITest.IsLinux():
355 scons_arg = 'test64'
356
357 examples_path = self._GetDirectoryPath('examples',
358 self._extracted_sdk_path)
359 scons_path = os.path.join(examples_path, 'scons ' + scons_arg)
360
361 # Build and run the unit test.
362 proc = subprocess.Popen([scons_path], stdout=subprocess.PIPE,
363 shell=True, cwd=examples_path)
364 lines = proc.communicate()[0].splitlines()
365 test_ran = False
366
367 for line in lines:
368 if 'Check:' in line:
369 self.assertTrue('passed' in line,
370 msg='Nacl-sel_ldr unit test failed.')
371 test_ran = True
372 self.assertTrue(test_ran,
373 msg='Failed to build and run nacl-sel_ldr unit test.')
374
375 if architecture == '64bit':
376 self.assertTrue(
377 self._HasPathInTree('hello_world_x86_64.nexe',
378 True, root=examples_path),
379 msg='Missing file: hello_world_x86_64.nexe.')
380 else:
381 self.assertTrue(
382 self._HasPathInTree('hello_world_x86_32.nexe',
383 True, root=examples_path),
384 msg='Missing file: hello_world_x86_32.nexe.')
385
386 # Verify that a mismatch of sel_ldr and .nexe produces an error.
387 toolchain_path = self._GetDirectoryPath('toolchain',
388 self._extracted_sdk_path)
389 bin_path = self._GetDirectoryPath('bin', toolchain_path)
390 hello_world_path = self._GetDirectoryPath('hello_world', examples_path)
391 sel_32_path = os.path.join(bin_path, 'sel_ldr_x86_32')
392 sel_64_path = os.path.join(bin_path, 'sel_ldr_x86_64')
393 nexe_32_path = os.path.join(hello_world_path, 'hello_world_x86_32.nexe')
394 nexe_64_path = os.path.join(hello_world_path, 'hello_world_x86_64.nexe')
395
396 if architecture == '64bit':
397 success = self._RunProcessAndCheckOutput(
398 [sel_64_path, nexe_32_path], 'Error while loading')
399 else:
400 success = self._RunProcessAndCheckOutput(
401 [sel_32_path, nexe_64_path], 'Error while loading')
402 self.assertTrue(success,
403 msg='Failed to verify sel_ldr and .nexe mismatch.')
404
405 # Run the appropriate ncval for the platform on the matching .nexe.
406 ncval_32_path = os.path.join(bin_path, 'ncval_x86_32')
407 ncval_64_path = os.path.join(bin_path, 'ncval_x86_64')
408
409 if architecture == '64bit':
410 success = self._RunProcessAndCheckOutput(
411 [ncval_64_path, nexe_64_path], 'is safe')
412 else:
413 success = self._RunProcessAndCheckOutput(
414 [ncval_32_path, nexe_32_path], 'is safe')
415 self.assertTrue(success, msg='Failed to verify ncval.')
416
417 # Verify that a mismatch of ncval and .nexe produces an error.
418 if architecture == '64bit':
419 success = self._RunProcessAndCheckOutput(
420 [ncval_64_path, nexe_32_path], 'is safe', is_in=False)
421 else:
422 success = self._RunProcessAndCheckOutput(
423 [ncval_32_path, nexe_64_path], 'is safe', is_in=False)
424 self.assertTrue(success, msg='Failed to verify ncval and .nexe mismatch.')
188 425
189 def _RemoveDownloadedTestFile(self): 426 def _RemoveDownloadedTestFile(self):
190 """Delete downloaded files and dirs from downloads directory.""" 427 """Delete downloaded files and dirs from downloads directory."""
191 if self._extracted_sdk_path and os.path.exists(self._extracted_sdk_path): 428 if self._extracted_sdk_path and os.path.exists(self._extracted_sdk_path):
192 self._CloseHTTPServer() 429 self._CloseHTTPServer()
193 430
194 def _RemoveFile(): 431 def _RemoveFile():
195 shutil.rmtree(self._extracted_sdk_path, ignore_errors=True) 432 shutil.rmtree(self._extracted_sdk_path, ignore_errors=True)
196 return os.path.exists(self._extracted_sdk_path) 433 return os.path.exists(self._extracted_sdk_path)
197 434
198 success = self.WaitUntil(_RemoveFile, retry_sleep=2, 435 success = self.WaitUntil(_RemoveFile, retry_sleep=2, expect_retval=False)
199 expect_retval=False)
200 self.assertTrue(success, 436 self.assertTrue(success,
201 msg='Cannot remove %s' % self._extracted_sdk_path) 437 msg='Cannot remove %s' % self._extracted_sdk_path)
202 438
203 if self._temp_dir: 439 if self._temp_dir:
204 pyauto_utils.RemovePath(self._temp_dir) 440 pyauto_utils.RemovePath(self._temp_dir)
205 441
442 def _RunProcessAndCheckOutput(self, args, look_for, is_in=True):
443 """Run process and look for string in output.
444
445 Args:
446 args: Argument strings to pass to subprocess.
447 look_for: The string to search in output.
448 is_in: True if checking if param look_for is in output.
449 False if checking if param look_for is not in output.
450
451 Returns:
452 True, if output contains parameter |look_for| and |is_in| is True, or
453 False otherwise.
454 """
455 proc = subprocess.Popen(args, stdout=subprocess.PIPE,
456 stderr=subprocess.PIPE)
457 (stdout, stderr) = proc.communicate()
458 lines = (stdout + stderr).splitlines()
459 for line in lines:
460 if look_for in line:
461 return is_in
462 return not is_in
463
206 def _OpenExamplesAndStartTest(self, examples): 464 def _OpenExamplesAndStartTest(self, examples):
207 """Open each example and verify that it's working. 465 """Open each example and verify that it's working.
208 466
209 Args: 467 Args:
210 examples: A dict of name to url of examples. 468 examples: A dict of name to url of examples.
211 """ 469 """
470 self._EnableNaClPlugin()
471
212 # Open all examples. 472 # Open all examples.
213 for name, url in examples.items(): 473 for name, url in examples.items():
214 self.AppendTab(pyauto.GURL(url)) 474 self.AppendTab(pyauto.GURL(url))
215 self._CheckForCrashes() 475 self._CheckForCrashes()
216 476
217 # Verify all examples are working. 477 # Verify all examples are working.
218 for name, url in examples.items(): 478 for name, url in examples.items():
219 self._VerifyAnExample(name, url) 479 self._VerifyAnExample(name, url)
220 self._CheckForCrashes() 480 self._CheckForCrashes()
221 481
482 # Reload all examples.
483 for _ in range(2):
484 for tab_index in range(self.GetTabCount()):
485 self.GetBrowserWindow(0).GetTab(tab_index).Reload()
486 self._CheckForCrashes()
487
488 # Verify all examples are working.
489 for name, url in examples.items():
490 self._VerifyAnExample(name, url)
491 self._CheckForCrashes()
492
222 # Close each tab, check for crashes and verify all open 493 # Close each tab, check for crashes and verify all open
223 # examples operate correctly. 494 # examples operate correctly.
224 tab_count = self.GetTabCount() 495 tab_count = self.GetTabCount()
225 for index in xrange(tab_count - 1, 0, -1): 496 for index in xrange(tab_count - 1, 0, -1):
226 self.GetBrowserWindow(0).GetTab(index).Close(True) 497 self.GetBrowserWindow(0).GetTab(index).Close(True)
227 self._CheckForCrashes() 498 self._CheckForCrashes()
228 499
229 tabs = self.GetBrowserInfo()['windows'][0]['tabs'] 500 tabs = self.GetBrowserInfo()['windows'][0]['tabs']
230 for tab in tabs: 501 for tab in tabs:
231 if tab['index'] > 0: 502 if tab['index'] > 0:
232 for name, url in examples.items(): 503 for name, url in examples.items():
233 if url == tab['url']: 504 if url == tab['url']:
234 self._VerifyAnExample(name, url) 505 self._VerifyAnExample(name, url)
235 break 506 break
236 507
237 def _VerifyAnExample(self, name, url): 508 def _VerifyAnExample(self, name, url):
238 """Verify NaCl example is working. 509 """Verify NaCl example is working.
239 510
240 Args: 511 Args:
241 name: A string name of the example. 512 name: A string name of the example.
242 url: A string url of the example. 513 url: A string url of the example.
243 """ 514 """
244 available_example_tests = { 515 available_example_tests = {
245 'dynamic_library_open': self._VerifyDynamicLibraryOpen, 516 'hello_world_c': self._VerifyHelloWorldExample,
246 'geturl': self._VerifyGetURLExample, 517 'hello_world': self._VerifyHelloWorldExample,
247 'input_events': self._VerifyInputEventsExample, 518 'pi_generator': self._VerifyPiGeneratorExample,
248 'load_progress': self._VerifyLoadProgressExample, 519 'sine_synth': self._VerifySineSynthExample,
249 'multithreaded_input_events': 520 'geturl': self._VerifyGetURLExample,
250 self._VerifyMultithreadedInputEventsExample, 521 'life': self._VerifyConwaysLifeExample
251 'pi_generator': self._VerifyPiGeneratorExample,
252 'sine_synth': self._VerifySineSynthExample,
253 'web_socket':self._VerifyWebSocketExample,
254 } 522 }
255 523
256 if not name in available_example_tests: 524 if not name in available_example_tests:
257 self.fail(msg='No test available for %s.' % name) 525 self.fail(msg='No test available for %s.' % name)
258 526
259 info = self.GetBrowserInfo() 527 info = self.GetBrowserInfo()
260 tabs = info['windows'][0]['tabs'] 528 tabs = info['windows'][0]['tabs']
261 tab_index = None 529 tab_index = None
262 for tab in tabs: 530 for tab in tabs:
263 if url == tab['url']: 531 if url == tab['url']:
264 self.ActivateTab(tab['index']) 532 self.ActivateTab(tab['index'])
265 tab_index = tab['index'] 533 tab_index = tab['index']
266 break 534 break
267 535
268 if tab_index: 536 if tab_index:
269 available_example_tests[name](tab_index, name, url) 537 available_example_tests[name](tab_index, name, url)
270 538
271 def _VerifyElementPresent(self, element_id, expected_value, tab_index, msg, 539 def _VerifyHelloWorldExample(self, tab_index, name, url):
272 attribute='innerHTML', timeout=150): 540 """Verify Hello World Example.
273 """Determine if dom element has the expected value. 541
274 542 Args:
275 Args: 543 tab_index: Tab index integer that the example is on.
276 element_id: Dom element's id. 544 name: A string name of the example.
277 expected_value: String to be matched against the Dom element. 545 url: A string url of the example.
278 tab_index: Tab index to work on. 546 """
279 attribute: Attribute to match |expected_value| against, if 547 success = self.WaitUntil(
280 given. Defaults to 'innerHTML'. 548 lambda: self.GetDOMValue(
281 timeout: The max timeout (in secs) for which to wait. 549 'document.getElementById("statusField").innerHTML',
282 """ 550 tab_index),
551 timeout=60, expect_retval='SUCCESS')
552 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
553
283 js_code = """ 554 js_code = """
284 var output = document.getElementById('%s').%s; 555 window.alert = function(e) {
285 var result; 556 window.domAutomationController.send(String(e));
286 if (output.indexOf('%s') != -1) 557 }
287 result = 'pass'; 558 window.domAutomationController.send("done");
288 else 559 """
289 result = 'fail';
290 window.domAutomationController.send(result);
291 """ % (element_id, attribute, expected_value)
292 success = self.WaitUntil(
293 lambda: self.ExecuteJavascript(js_code, tab_index),
294 timeout=timeout, expect_retval='pass')
295 self.assertTrue(success, msg=msg)
296
297 def _CreateJSToSimulateMouseclick(self):
298 """Create javascript to simulate mouse click event."""
299 js_code = """
300 var rightClick = document.createEvent('MouseEvents');
301 rightClick.initMouseEvent(
302 'mousedown', true, true, document,
303 1, 32, 121, 10, 100,
304 false, false, false, false,
305 2, document.getElementById('event_module')
306 );
307 document.getElementById('event_module').dispatchEvent(rightClick);
308 window.domAutomationController.send('done');
309 """
310 return js_code
311
312 def _VerifyInputEventsExample(self, tab_index, name, url):
313 """Verify Input Events Example.
314
315 Args:
316 tab_index: Tab index integer that the example is on.
317 name: A string name of the example.
318 url: A string url of the example.
319 """
320 success = self._VerifyElementPresent('eventString', 'DidChangeView',
321 tab_index, msg='Example %s failed. URL: %s' % (name, url))
322
323 # Simulate mouse click on event module.
324 js_code = self._CreateJSToSimulateMouseclick()
325 self.ExecuteJavascript(js_code, tab_index) 560 self.ExecuteJavascript(js_code, tab_index)
326 561
327 # Check if 'eventString' has handled above mouse click. 562 result = self.ExecuteJavascript('document.helloForm.elements[1].click();',
328 success = self.WaitUntil( 563 tab_index)
329 lambda: re.search('DidHandleInputEvent', self.GetDOMValue( 564 self.assertEqual(result, '42',
330 'document.getElementById("eventString").innerHTML', 565 msg='Example %s failed. URL: %s' % (name, url))
331 tab_index)).group(), expect_retval='DidHandleInputEvent') 566
332 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url)) 567 result = self.ExecuteJavascript('document.helloForm.elements[2].click();',
333 568 tab_index)
334 def _VerifyMultithreadedInputEventsExample(self, tab_index, name, url): 569 self.assertEqual(result, 'dlrow olleH',
335 """Verify Input Events Example. 570 msg='Example %s failed. URL: %s' % (name, url))
336
337 Args:
338 tab_index: Tab index integer that the example is on.
339 name: A string name of the example.
340 url: A string url of the example.
341 """
342 success = self.WaitUntil(
343 lambda: bool(self.GetDOMValue(
344 'document.getElementById("eventString").innerHTML',
345 tab_index).find('DidChangeView') + 1))
346
347 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
348
349 # Simulate mouse click on event module.
350 js_code = self._CreateJSToSimulateMouseclick()
351 self.ExecuteJavascript(js_code, tab_index)
352
353 # Check if above mouse click is handled.
354 success = self._VerifyElementPresent('eventString', 'Mouse event',
355 tab_index, msg='Example %s failed. URL: %s' % (name, url))
356
357 # Kill worker thread and queue
358 js_code = """
359 document.getElementsByTagName('button')[0].click();
360 window.domAutomationController.send('done');
361 """
362 self.ExecuteJavascript(js_code, tab_index)
363
364 # Check if main thread has cancelled queue.
365 success = self._VerifyElementPresent('eventString', 'Received cancel',
366 tab_index, msg='Example %s failed. URL: %s' % (name, url))
367
368 # Simulate mouse click on event module.
369 js_code = self._CreateJSToSimulateMouseclick()
370 self.ExecuteJavascript(js_code, tab_index)
371
372 # Check if above mouse click is not handled after killing worker thread.
373 def _CheckMouseClickEventStatus():
374 return self.GetDOMValue(
375 'document.getElementById("eventString").innerHTML',
376 tab_index).find('Mouse event', self.GetDOMValue(
377 'document.getElementById("eventString").innerHTML', tab_index).find(
378 'Received cancel'))
379
380 success = self.WaitUntil(_CheckMouseClickEventStatus, expect_retval=-1)
381 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
382
383 def _VerifyWebSocketExample(self, tab_index, name, url):
384 """Verify Web Socket Open Example.
385
386 Args:
387 tab_index: Tab index integer that the example is on.
388 name: A string name of the example.
389 url: A string url of the example.
390 """
391 # Check if example is loaded.
392 success = self.WaitUntil(
393 lambda: self.GetDOMValue(
394 'document.getElementById("statusField").innerHTML', tab_index),
395 expect_retval='SUCCESS')
396 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
397
398 # Simulate clicking on Connect button to establish a connection.
399 js_code = """
400 document.getElementsByTagName('input')[1].click();
401 window.domAutomationController.send('done');
402 """
403 self.ExecuteJavascript(js_code, tab_index)
404
405 # Check if connected
406 success = self._VerifyElementPresent('log', 'connected', tab_index,
407 msg='Example %s failed. URL: %s' %(name, url), attribute='value')
408
409 # Simulate clicking on Send button to send text message in log.
410 js_code = """
411 document.getElementsByTagName('input')[3].click();
412 window.domAutomationController.send('done');
413 """
414 self.ExecuteJavascript(js_code, tab_index)
415 success = self.WaitUntil(
416 lambda: bool(re.search('send:', self.GetDOMValue(
417 'document.getElementById("log").value', tab_index))))
418 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
419
420 def _VerifyDynamicLibraryOpen(self, tab_index, name, url):
421 """Verify Dynamic Library Open Example.
422
423 Args:
424 tab_index: Tab index integer that the example is on.
425 name: A string name of the example.
426 url: A string url of the example.
427 """
428 # Check if example is loaded.
429 success = self._VerifyElementPresent('consolec', 'Eightball loaded',
430 tab_index, msg='Example %s failed. URL: %s' % (name, url))
431
432 # Simulate clicking on ASK button and check answer log for desired answer.
433 js_code = """
434 document.getElementsByTagName('input')[1].click();
435 window.domAutomationController.send('done');
436 """
437 self.ExecuteJavascript(js_code, tab_index)
438 def _CheckAnswerLog():
439 return bool(re.search(r'NO|YES|42|MAYBE NOT|DEFINITELY|'
440 'ASK ME TOMORROW|MAYBE|PARTLY CLOUDY',
441 self.GetDOMValue('document.getElementById("answerlog").innerHTML',
442 tab_index)))
443
444 success = self.WaitUntil(_CheckAnswerLog)
445 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
446
447 def _VerifyLoadProgressExample(self, tab_index, name, url):
448 """Verify Dynamic Library Open Example.
449
450 Args:
451 tab_index: Tab index integer that the example is on.
452 name: A string name of the example.
453 url: A string url of the example.
454 """
455 # Check if example loads and displays loading progress.
456 success = self.WaitUntil(
457 lambda: self.GetDOMValue(
458 'document.getElementById("status_field").innerHTML', tab_index),
459 timeout=150, expect_retval='SUCCESS')
460 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
461
462 def _CheckLoadProgressStatus():
463 return re.search(
464 r'(loadstart).+(progress:).+(load).+(loadend).+(lastError:)',
465 self.GetDOMValue(
466 'document.getElementById("event_log_field").innerHTML', tab_index))
467 success = self.WaitUntil(_CheckLoadProgressStatus)
468 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
469 571
470 def _VerifyPiGeneratorExample(self, tab_index, name, url): 572 def _VerifyPiGeneratorExample(self, tab_index, name, url):
471 """Verify Pi Generator Example. 573 """Verify Pi Generator Example.
472 574
473 Args: 575 Args:
474 tab_index: Tab index integer that the example is on. 576 tab_index: Tab index integer that the example is on.
475 name: A string name of the example. 577 name: A string name of the example.
476 url: A string url of the example. 578 url: A string url of the example.
477 """ 579 """
478 success = self.WaitUntil( 580 success = self.WaitUntil(
479 lambda: self.GetDOMValue('document.form.pi.value', tab_index)[0:3], 581 lambda: self.GetDOMValue('document.form.pi.value', 0, tab_index)[0:3],
480 expect_retval='3.1') 582 timeout=120, expect_retval='3.1')
481 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url)) 583 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
584
585 # Get top corner of Pi image.
586 js_code = """
587 var obj = document.getElementById('piGenerator');
588 var curleft = curtop = 0;
589 do {
590 curleft += obj.offsetLeft;
591 curtop += obj.offsetTop;
592 } while (obj = obj.offsetParent);
593 window.domAutomationController.send(curleft + ", " + curtop);
594 """
595 result = self.ExecuteJavascript(js_code, tab_index)
596 result_split = result.split(', ')
597 x = int(result_split[0])
598 y = int(result_split[1])
599 window = self.GetBrowserInfo()['windows'][0]
600 window_to_content_x = 2
601 window_to_content_y = 80
602 pi_image_x = x + window['x'] + window_to_content_x
603 pi_image_y = y + window['y'] + window_to_content_y
604
605 if self._IsGetPixelSupported():
606 is_animating = self._IsColorChanging(pi_image_x, pi_image_y, 50, 50)
607 self.assertTrue(is_animating,
608 msg='Example %s failed. URL: %s' % (name, url))
482 609
483 def _VerifySineSynthExample(self, tab_index, name, url): 610 def _VerifySineSynthExample(self, tab_index, name, url):
484 """Verify Sine Wave Synthesizer Example. 611 """Verify Sine Wave Synthesizer Example.
485 612
486 Args: 613 Args:
487 tab_index: Tab index integer that the example is on. 614 tab_index: Tab index integer that the example is on.
488 name: A string name of the example. 615 name: A string name of the example.
489 url: A string url of the example. 616 url: A string url of the example.
490 """ 617 """
491 success = self.WaitUntil( 618 success = self.WaitUntil(
492 lambda: self.GetDOMValue( 619 lambda: self.GetDOMValue(
493 'document.getElementById("frequency_field").value', 620 'document.getElementById("frequency_field").value',
494 tab_index),timeout=150, expect_retval='440') 621 tab_index),
495 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url)) 622 timeout=30, expect_retval='440')
623 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
624
496 self.ExecuteJavascript( 625 self.ExecuteJavascript(
497 'document.body.getElementsByTagName("button")[0].click();' 626 'document.body.getElementsByTagName("button")[0].click();'
498 'window.domAutomationController.send("done")', 627 'window.domAutomationController.send("done")',
499 tab_index) 628 tab_index)
500 629
630 # TODO(chrisphan): Verify sound.
631
501 def _VerifyGetURLExample(self, tab_index, name, url): 632 def _VerifyGetURLExample(self, tab_index, name, url):
502 """Verify GetURL Example. 633 """Verify GetURL Example.
503 634
504 Args: 635 Args:
505 tab_index: Tab index integer that the example is on. 636 tab_index: Tab index integer that the example is on.
506 name: A string name of the example. 637 name: A string name of the example.
507 url: A string url of the example. 638 url: A string url of the example.
508 """ 639 """
509 success = self.WaitUntil( 640 success = self.WaitUntil(
510 lambda: self.GetDOMValue( 641 lambda: self.GetDOMValue(
511 'document.getElementById("status_field").innerHTML', 642 'document.getElementById("status_field").innerHTML',
512 tab_index), timeout=150, expect_retval='SUCCESS') 643 tab_index),
513 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url)) 644 timeout=60, expect_retval='SUCCESS')
645 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
646
514 self.ExecuteJavascript( 647 self.ExecuteJavascript(
515 'document.geturl_form.elements[0].click();' 648 'document.geturl_form.elements[0].click();'
516 'window.domAutomationController.send("done")', 649 'window.domAutomationController.send("done")',
517 tab_index) 650 tab_index)
518 success = self._VerifyElementPresent('general_output', 'test passed', 651
519 tab_index, msg='Example %s failed. URL: %s' % (name, url)) 652 js_code = """
520 653 var output = document.getElementById("general_output").innerHTML;
521 def _CheckForCrashes(self): 654 var result;
522 """Check for any browser/tab crashes and hangs.""" 655 if (output.indexOf("test passed") != -1)
656 result = "pass";
657 else
658 result = "fail";
659 window.domAutomationController.send(result);
660 """
661 success = self.WaitUntil(
662 lambda: self.ExecuteJavascript(js_code, tab_index),
663 timeout=30, expect_retval='pass')
664 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
665
666 def _VerifyConwaysLifeExample(self, tab_index, name, url):
667 """Verify Conway's Life Example.
668
669 Args:
670 tab_index: Tab index integer that the example is on.
671 name: A string name of the example.
672 url: A string url of the example.
673 """
674 window = self.GetBrowserInfo()['windows'][0]
675 window_to_content_x = 2
676 window_to_content_y = 80
677 x = window['x'] + window_to_content_x
678 y = window['y'] + window_to_content_y
679 offset_pixel = 100
680 if self._IsGetPixelSupported():
681 success = self.WaitUntil(
682 lambda: self._GetPixel(x + offset_pixel, y + offset_pixel),
683 timeout=30, expect_retval=16777215)
684 self.assertTrue(success, msg='Example %s failed. URL: %s' % (name, url))
685
686 def _GetXMLNodeData(self, nodelist):
687 rc = []
688 for node in nodelist:
689 if node.nodeType == node.TEXT_NODE:
690 rc.append(node.data)
691 return ''.join(rc)
692
693 def _IsColorChanging(self, x, y, width, height):
694 """Check screen for anything that is moving.
695
696 Args:
697 x: X coordinate on the screen.
698 y: Y coordinate on the screen.
699 width: Width of the area to scan.
700 height: Height of the area to scan.
701
702 Returns:
703 True, if pixel color in area is changing, or
704 False otherwise.
705 """
706 color_a = self._GetAreaPixelColor(x, y, width, height)
707 def _HasColorChanged():
708 color_b = self._GetAreaPixelColor(x, y, width, height)
709 return color_a != color_b
710
711 return self.WaitUntil(_HasColorChanged, timeout=6,
712 retry_sleep=2, expect_retval=True)
713
714 def _IsGetPixelSupported(self):
715 """Check if get pixel is supported.
716
717 Returns:
718 True, if get pixel is supported, or
719 False otherwise.
720 """
721 return pyauto.PyUITest.IsWin()
722
723 def _GetAreaPixelColor(self, x, y, width, height):
724 """Get an area of pixel color and return a list of color code values.
725
726 Args:
727 x: X coordinate on the screen.
728 y: Y coordinate on the screen.
729 width: Width of the area to scan.
730 height: Height of the area to scan.
731
732 Returns:
733 A list containing color codes.
734 """
735 if pyauto.PyUITest.IsMac():
736 pass # TODO(chrisphan): Do Mac.
737 elif pyauto.PyUITest.IsWin():
738 return self._GetAreaPixelColorWin(x, y, width, height)
739 elif pyauto.PyUITest.IsLinux():
740 pass # TODO(chrisphan): Do Linux.
741 return None
742
743 def _GetAreaPixelColorWin(self, x, y, width, height):
744 """Get an area of pixel color for Windows and return a list.
745
746 Args:
747 x: X coordinate on the screen.
748 y: Y coordinate on the screen.
749 width: Width of the area to scan.
750 height: Height of the area to scan.
751
752 Returns:
753 A list containing color codes.
754 """
755 colors = []
756 hdc = ctypes.windll.user32.GetDC(0)
757 for x_pos in xrange(x, x + width, 1):
758 for y_pos in xrange(y, y + height, 1):
759 color = ctypes.windll.gdi32.GetPixel(hdc, x_pos, y_pos)
760 colors.append(color)
761 return colors
762
763 def _GetPixel(self, x, y):
764 """Get pixel color at coordinate x and y.
765
766 Args:
767 x: X coordinate on the screen.
768 y: Y coordinate on the screen.
769
770 Returns:
771 An integer color code.
772 """
773 if pyauto.PyUITest.IsMac():
774 pass # TODO(chrisphan): Do Mac.
775 elif pyauto.PyUITest.IsWin():
776 return self._GetPixelWin(x, y)
777 elif pyauto.PyUITest.IsLinux():
778 pass # TODO(chrisphan): Do Linux.
779 return None
780
781 def _GetPixelWin(self, x, y):
782 """Get pixel color at coordinate x and y for Windows
783
784 Args:
785 x: X coordinate on the screen.
786 y: Y coordinate on the screen.
787
788 Returns:
789 An integer color code.
790 """
791 hdc = ctypes.windll.user32.GetDC(0)
792 color = ctypes.windll.gdi32.GetPixel(hdc, x, y)
793 return color
794
795 def _CheckForCrashes(self, last_action=None, last_action_param=None):
796 """Check for any browser/tab crashes and hangs.
797
798 Args:
799 last_action: Specify action taken before checking for crashes.
800 last_action_param: Parameter for last action.
801 """
523 self.assertTrue(self.GetBrowserWindowCount(), 802 self.assertTrue(self.GetBrowserWindowCount(),
524 msg='Browser crashed, no window is open.') 803 msg='Browser crashed, no window is open.')
525 804
526 info = self.GetBrowserInfo() 805 info = self.GetBrowserInfo()
527 breakpad_folder = info['properties']['DIR_CRASH_DUMPS'] 806 breakpad_folder = info['properties']['DIR_CRASH_DUMPS']
528 old_dmp_files = glob.glob(os.path.join(breakpad_folder, '*.dmp')) 807 old_dmp_files = glob.glob(os.path.join(breakpad_folder, '*.dmp'))
529 808
530 # Verify there're no crash dump files. 809 # Verify there're no crash dump files.
531 for dmp_file in glob.glob(os.path.join(breakpad_folder, '*.dmp')): 810 for dmp_file in glob.glob(os.path.join(breakpad_folder, '*.dmp')):
532 self.assertTrue(dmp_file in old_dmp_files, 811 self.assertTrue(dmp_file in old_dmp_files,
533 msg='Crash dump %s found' % dmp_file) 812 msg='Crash dump %s found' % dmp_file)
534 813
535 # Check for any crashed tabs. 814 # Check for any crashed tabs.
536 tabs = info['windows'][0]['tabs'] 815 tabs = info['windows'][0]['tabs']
537 for tab in tabs: 816 for tab in tabs:
538 if tab['url'] != 'about:blank': 817 if tab['url'] != 'about:blank':
539 if not self.GetDOMValue('document.body.innerHTML', tab['index']): 818 if not self.GetDOMValue('document.body.innerHTML', tab['index']):
540 self.fail(msg='Tab crashed on %s' % tab['url']) 819 self.fail(msg='Tab crashed on %s' % tab['url'])
541 820
821 # TODO(chrisphan): Check for tab hangs and browser hangs.
822 # TODO(chrisphan): Handle specific action: close browser, close tab.
823 if last_action == 'close tab':
824 pass
825 elif last_action == 'close browser':
826 pass
827 else:
828 pass
829
542 def _GetPlatformArchitecture(self): 830 def _GetPlatformArchitecture(self):
543 """Get platform architecture. 831 """Get platform architecture.
544 832
833 Args:
834 last_action: Last action taken before checking for crashes.
835 last_action_param: Parameter for last action.
836
545 Returns: 837 Returns:
546 A string representing the platform architecture. 838 A string representing the platform architecture.
547 """ 839 """
548 if pyauto.PyUITest.IsWin(): 840 if pyauto.PyUITest.IsWin():
549 if os.environ['PROGRAMFILES'] == 'C:\\Program Files (x86)': 841 if os.environ['PROGRAMFILES'] == 'C:\\Program Files (x86)':
550 return '64bit' 842 return '64bit'
551 else: 843 else:
552 return '32bit' 844 return '32bit'
553 elif pyauto.PyUITest.IsMac() or pyauto.PyUITest.IsLinux(): 845 elif pyauto.PyUITest.IsMac() or pyauto.PyUITest.IsLinux():
554 if platform.machine() == 'x86_64': 846 if platform.machine() == 'x86_64':
555 return '64bit' 847 return '64bit'
556 else: 848 else:
557 return '32bit' 849 return '32bit'
558 return '32bit' 850 return '32bit'
559 851
852 def _HasFile(self, pattern, root=os.curdir):
853 """Check if a file matching the specified pattern exists in a directory.
854
855 Args:
856 pattern: Pattern of file name.
857 root: Directory to start looking.
858
859 Returns:
860 True, if root contains the file name pattern, or
861 False otherwise.
862 """
863 return len(glob.glob(os.path.join(root, pattern)))
864
560 def _HasPathInTree(self, pattern, is_file, root=os.curdir): 865 def _HasPathInTree(self, pattern, is_file, root=os.curdir):
561 """Recursively checks if a file/directory matching a pattern exists. 866 """Recursively checks if a file/directory matching a pattern exists.
562 867
563 Args: 868 Args:
564 pattern: Pattern of file or directory name. 869 pattern: Pattern of file or directory name.
565 is_file: True if looking for file, or False if looking for directory. 870 is_file: True if looking for file, or False if looking for directory.
566 root: Directory to start looking. 871 root: Directory to start looking.
567 872
568 Returns: 873 Returns:
569 True, if root contains the directory name pattern, or 874 True, if root contains the directory name pattern, or
570 False otherwise. 875 False otherwise.
571 """ 876 """
572 for path, dirs, files in os.walk(os.path.abspath(root)): 877 for path, dirs, files in os.walk(os.path.abspath(root)):
573 if is_file: 878 if is_file:
574 if len(fnmatch.filter(files, pattern)): 879 if len(fnmatch.filter(files, pattern)):
575 return True 880 return True
576 else: 881 else:
577 if len(fnmatch.filter(dirs, pattern)): 882 if len(fnmatch.filter(dirs, pattern)):
578 return True 883 return True
579 return False 884 return False
580 885
886 def _GetDirectoryPath(self, pattern, root=os.curdir):
887 """Get the path of a directory in another directory.
888
889 Args:
890 pattern: Pattern of directory name.
891 root: Directory to start looking.
892
893 Returns:
894 A string of the path.
895 """
896 for path, dirs, files in os.walk(os.path.abspath(root)):
897 result = fnmatch.filter(dirs, pattern)
898 if result:
899 return os.path.join(path, result[0])
900 return None
901
581 def _HasAllSystemRequirements(self): 902 def _HasAllSystemRequirements(self):
582 """Verify NaCl SDK installation system requirements. 903 """Verify NaCl SDK installation system requirements.
583 904
584 Returns: 905 Returns:
585 True, if system passed requirements, or 906 True, if system passed requirements, or
586 False otherwise. 907 False otherwise.
587 """ 908 """
588 # Check python version. 909 # Check python version.
589 if sys.version_info[0:2] < (2, 6): 910 if sys.version_info[0:2] < (2, 6):
590 return False 911 return False
(...skipping 16 matching lines...) Expand all
607 # NaCl supports Chrome 10 and higher builds. 928 # NaCl supports Chrome 10 and higher builds.
608 min_required_chrome_build = self._settings['min_required_chrome_build'] 929 min_required_chrome_build = self._settings['min_required_chrome_build']
609 browser_info = self.GetBrowserInfo() 930 browser_info = self.GetBrowserInfo()
610 chrome_version = browser_info['properties']['ChromeVersion'] 931 chrome_version = browser_info['properties']['ChromeVersion']
611 chrome_build = int(chrome_version.split('.')[0]) 932 chrome_build = int(chrome_version.split('.')[0])
612 return chrome_build >= min_required_chrome_build 933 return chrome_build >= min_required_chrome_build
613 934
614 def _DownloadNaClSDK(self): 935 def _DownloadNaClSDK(self):
615 """Download NaCl SDK.""" 936 """Download NaCl SDK."""
616 self._temp_dir = tempfile.mkdtemp() 937 self._temp_dir = tempfile.mkdtemp()
617 dl_file = urllib2.urlopen(self._settings['post_sdk_zip']) 938 if pyauto.PyUITest.IsWin():
618 file_path = os.path.join(self._temp_dir, 'nacl_sdk.zip') 939 dl_file = urllib2.urlopen(self._settings['release_win_sdk_url'])
940 file_path = os.path.join(self._temp_dir, 'naclsdk_win.exe')
941 elif pyauto.PyUITest.IsMac():
942 dl_file = urllib2.urlopen(self._settings['release_mac_sdk_url'])
943 file_path = os.path.join(self._temp_dir, 'naclsdk_mac.tgz')
944 elif pyauto.PyUITest.IsLinux():
945 dl_file = urllib2.urlopen(self._settings['release_lin_sdk_url'])
946 file_path = os.path.join(self._temp_dir, 'naclsdk_linux.tgz')
947 else:
948 self.fail(msg='NaCl SDK does not support this OS.')
619 949
620 try: 950 try:
621 f = open(file_path, 'wb') 951 f = open(file_path, 'wb')
622 f.write(dl_file.read()) 952 f.write(dl_file.read())
623 except IOError: 953 except IOError:
624 self.fail(msg='Cannot open %s.' % file_path) 954 self.fail(msg='Cannot open %s.' % file_path)
625 finally: 955 finally:
626 f.close() 956 f.close()
627 957
628 def _ExtractNaClSDK(self): 958 def _ExtractNaClSDK(self):
629 """Extract NaCl SDK.""" 959 """Extract NaCl SDK."""
630 source_file = os.path.join(self._temp_dir, 'nacl_sdk.zip') 960 if pyauto.PyUITest.IsWin():
631 if zipfile.is_zipfile(source_file): 961 source_file = os.path.join(self._temp_dir, 'naclsdk_win.exe')
632 zip = zipfile.ZipFile(source_file, 'r') 962 proc = subprocess.Popen([source_file, '/S', '/D=' +
633 zip.extractall(self._extracted_sdk_path) 963 self._extracted_sdk_path],
964 stdout=subprocess.PIPE)
965 proc.communicate()
966 if not os.listdir(self._extracted_sdk_path):
967 self.fail(msg='Failed to extract NaCl SDK.')
968 elif pyauto.PyUITest.IsMac():
969 source_file = os.path.join(self._temp_dir, 'naclsdk_mac.tgz')
970 tar = tarfile.open(source_file, 'r')
971 tar.extractall(self._extracted_sdk_path)
972 elif pyauto.PyUITest.IsLinux():
973 source_file = os.path.join(self._temp_dir, 'naclsdk_linux.tgz')
974 tar = tarfile.open(source_file, 'r')
975 tar.extractall(self._extracted_sdk_path)
634 else: 976 else:
635 self.fail(msg='%s is not a valid zip file' % source_file) 977 self.fail(msg='NaCl SDK does not support this OS.')
636 978
637 def _IsURLAlive(self, url): 979 def _IsURLAlive(self, url):
638 """Test if URL is alive.""" 980 """Test if URL is alive."""
639 try: 981 try:
640 urllib2.urlopen(url) 982 urllib2.urlopen(url)
641 except: 983 except:
642 return False 984 return False
643 return True 985 return True
644 986
645 def _CloseHTTPServer(self, proc=None): 987 def _CloseHTTPServer(self, proc=None):
646 """Close HTTP server. 988 """Close HTTP server.
647 989
648 Args: 990 Args:
649 proc: Process that opened the HTTP server. 991 proc: Process that opened the HTTP server.
650 proc is None when there is no pointer to HTTP server process. 992 proc is None when there is no pointer to HTTP server process.
651 """ 993 """
652 if not self._IsURLAlive('http://localhost:5103'): 994 if not self._IsURLAlive('http://localhost:5103'):
653 return 995 return
654 response = urllib2.urlopen('http://localhost:5103') 996 response = urllib2.urlopen('http://localhost:5103')
655 html = response.read() 997 html = response.read()
656 if not 'Native Client' in html: 998 if not 'Native Client' in html:
657 self.fail(msg='Port 5103 is in use.') 999 self.fail(msg='Port 5103 is in use.')
658 1000
659 urllib2.urlopen('http://localhost:5103?quit=1') 1001 urllib2.urlopen('http://localhost:5103?quit=1')
660 success = self.WaitUntil( 1002 success = self.WaitUntil(
661 lambda: self._IsURLAlive('http://localhost:5103'), 1003 lambda: self._IsURLAlive('http://localhost:5103'),
662 retry_sleep=1, expect_retval=False) 1004 timeout=30, retry_sleep=1, expect_retval=False)
663 if not success: 1005 if not success:
664 if not proc: 1006 if not proc:
665 self.fail(msg='Failed to close HTTP server.') 1007 self.fail(msg='Failed to close HTTP server.')
666 else: 1008 else:
667 if proc.poll() == None: 1009 if proc.poll() == None:
668 try: 1010 try:
669 proc.kill() 1011 proc.kill()
670 except: 1012 except:
671 self.fail(msg='Failed to close HTTP server.') 1013 self.fail(msg='Failed to close HTTP server')
672 1014
673 def _SearchNaClSDKFile(self, search_list): 1015 def _SearchNaClSDKTarFile(self, search_list, source_file):
1016 """Search NaCl SDK tar file for example files and directories.
1017
1018 Args:
1019 search_list: A list of strings, representing file and
1020 directory names for which to search.
1021 source_file: The string name of an NaCl SDK tar file.
1022 """
1023 tar = tarfile.open(source_file, 'r')
1024
1025 # Look for files and directories in examples.
1026 files = copy.deepcopy(search_list)
1027 for tar_info in tar:
1028 file_name = tar_info.name
1029 if tar_info.isdir() and not file_name.endswith('/'):
1030 file_name = file_name + '/'
1031
1032 for name in files:
1033 if file_name.find('examples/' + name):
1034 files.remove(name)
1035 if not files:
1036 break
1037
1038 tar.close()
1039
1040 self.assertEqual(len(files), 0,
1041 msg='Missing files or directories: %s' %
1042 ', '.join(map(str, files)))
1043
1044 def _SearchNaClSDKFileWindows(self, search_list):
674 """Search NaCl SDK file for example files and directories in Windows. 1045 """Search NaCl SDK file for example files and directories in Windows.
675 1046
676 Args: 1047 Args:
677 search_list: A list of strings, representing file and 1048 search_list: A list of strings, representing file and
678 directory names for which to search. 1049 directory names for which to search.
679 """ 1050 """
680 missing_items = [] 1051 missing_items = []
681 for name in search_list: 1052 for name in search_list:
682 is_file = name.find('/') < 0 1053 is_file = name.find('/') < 0
683 if not is_file: 1054 if not is_file:
684 name = name.replace('/', '') 1055 name = name.replace('/', '')
685 if not self._HasPathInTree(name, is_file, self._extracted_sdk_path): 1056 if not self._HasPathInTree(name, is_file, self._extracted_sdk_path):
686 missing_items.append(name) 1057 missing_items.append(name)
687 self.assertEqual(len(missing_items), 0, 1058 self.assertEqual(len(missing_items), 0,
688 msg='Missing files or directories: %s' % 1059 msg='Missing files or directories: %s' %
689 ', '.join(map(str, missing_items))) 1060 ', '.join(map(str, missing_items)))
690 1061
691 def ExtraChromeFlags(self): 1062 def _EnableNaClPlugin(self):
692 """Ensures Nacl is enabled. 1063 """Enable NaCl plugin."""
1064 nacl_plugin = (self.GetPluginsInfo().PluginForName('Chrome NaCl') or
1065 self.GetPluginsInfo().PluginForName('Native Client'))
1066 if not nacl_plugin:
1067 self.fail(msg='No NaCl plugin found.')
1068 self.EnablePlugin(nacl_plugin[0]['path'])
693 1069
694 Returns: 1070 self.NavigateToURL('about:flags')
695 A list of extra flags to pass to Chrome when it is launched. 1071
1072 js_code = """
1073 chrome.send('enableFlagsExperiment', ['enable-nacl', 'true']);
1074 requestFlagsExperimentsData();
1075 window.domAutomationController.send('done');
696 """ 1076 """
697 extra_chrome_flags = [ 1077 self.ExecuteJavascript(js_code)
698 '--enable-nacl', 1078 self.RestartBrowser(False)
699 '--enable-nacl-exception-handling', 1079
700 '--nacl-gdb', 1080 self.NavigateToURL('about://version')
701 ] 1081 self.assertEqual(self.FindInPage('--enable-nacl')['match_count'], 1,
702 return pyauto.PyUITest.ExtraChromeFlags(self) + extra_chrome_flags 1082 msg='Missing expected Chrome flag --enable-nacl.')
1083
703 1084
704 if __name__ == '__main__': 1085 if __name__ == '__main__':
705 pyauto_functional.Main() 1086 pyauto_functional.Main()
OLDNEW
« no previous file with comments | « chrome/test/functional/PYAUTO_TESTS ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698