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

Side by Side Diff: functional/nacl_sdk.py

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

Powered by Google App Engine
This is Rietveld 408576698