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

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

Powered by Google App Engine
This is Rietveld 408576698