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

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 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=2,
400 expect_retval=False)
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):
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
678 Returns:
679 True, if pixel color in area is changing, or
680 False otherwise.
681 """
682 color_a = self._GetAreaPixelColor(x, y, width, height)
683 def _HasColorChanged():
684 color_b = self._GetAreaPixelColor(x, y, width, height)
685 return color_a != color_b
686
687 return self.WaitUntil(_HasColorChanged, timeout=6,
688 retry_sleep=2, expect_retval=True)
689
690 def _IsGetPixelSupported(self):
691 """Check if get pixel is supported.
692
693 Returns:
694 True, if get pixel is supported, or
695 False otherwise.
696 """
697 return pyauto.PyUITest.IsWin()
698
699 def _GetAreaPixelColor(self, x, y, width, height):
700 """Get an area of pixel color and return a list of color code values.
701
702 Args:
703 x: X coordinate on the screen.
704 y: Y coordinate on the screen.
705 width: Width of the area to scan.
706 height: Height of the area to scan.
707
708 Returns:
709 A list containing color codes.
710 """
711 if pyauto.PyUITest.IsMac():
712 pass # TODO(chrisphan): Do Mac.
713 elif pyauto.PyUITest.IsWin():
714 return self._GetAreaPixelColorWin(x, y, width, height)
715 elif pyauto.PyUITest.IsLinux():
716 pass # TODO(chrisphan): Do Linux.
717 return None
718
719 def _GetAreaPixelColorWin(self, x, y, width, height):
720 """Get an area of pixel color for Windows and return a list.
721
722 Args:
723 x: X coordinate on the screen.
724 y: Y coordinate on the screen.
725 width: Width of the area to scan.
726 height: Height of the area to scan.
727
728 Returns:
729 A list containing color codes.
730 """
731 colors = []
732 hdc = ctypes.windll.user32.GetDC(0)
733 for x_pos in xrange(x, x + width, 1):
734 for y_pos in xrange(y, y + height, 1):
735 color = ctypes.windll.gdi32.GetPixel(hdc, x_pos, y_pos)
736 colors.append(color)
737 return colors
738
739 def _GetPixel(self, x, y):
740 """Get pixel color at coordinate x and y.
741
742 Args:
743 x: X coordinate on the screen.
744 y: Y coordinate on the screen.
745
746 Returns:
747 An integer color code.
748 """
749 if pyauto.PyUITest.IsMac():
750 pass # TODO(chrisphan): Do Mac.
751 elif pyauto.PyUITest.IsWin():
752 return self._GetPixelWin(x, y)
753 elif pyauto.PyUITest.IsLinux():
754 pass # TODO(chrisphan): Do Linux.
755 return None
756
757 def _GetPixelWin(self, x, y):
758 """Get pixel color at coordinate x and y for Windows
759
760 Args:
761 x: X coordinate on the screen.
762 y: Y coordinate on the screen.
763
764 Returns:
765 An integer color code.
766 """
767 hdc = ctypes.windll.user32.GetDC(0)
768 color = ctypes.windll.gdi32.GetPixel(hdc, x, y)
769 return color
770
771 def _CheckForCrashes(self, last_action=None, last_action_param=None):
772 """Check for any browser/tab crashes and hangs.
773
774 Args:
775 last_action: Specify action taken before checking for crashes.
776 last_action_param: Parameter for last action.
777 """
778 self.assertTrue(self.GetBrowserWindowCount(),
779 msg='Browser crashed, no window is open.')
780
781 info = self.GetBrowserInfo()
782 breakpad_folder = info['properties']['DIR_CRASH_DUMPS']
783 old_dmp_files = glob.glob(os.path.join(breakpad_folder, '*.dmp'))
784
785 # Verify there're no crash dump files.
786 for dmp_file in glob.glob(os.path.join(breakpad_folder, '*.dmp')):
787 self.assertTrue(dmp_file in old_dmp_files,
788 msg='Crash dump %s found' % dmp_file)
789
790 # Check for any crashed tabs.
791 tabs = info['windows'][0]['tabs']
792 for tab in tabs:
793 if tab['url'] != 'about:blank':
794 if not self.GetDOMValue('document.body.innerHTML', 0, tab['index']):
795 self.fail(msg='Tab crashed on %s' % tab['url'])
796
797 # TODO(chrisphan): Check for tab hangs and browser hangs.
798 # TODO(chrisphan): Handle specific action: close browser, close tab.
799 if last_action == 'close tab':
800 pass
801 elif last_action == 'close browser':
802 pass
803 else:
804 pass
805
806 def _GetPlatformArchitecture(self):
807 """Get platform architecture.
808
809 Args:
810 last_action: Last action taken before checking for crashes.
811 last_action_param: Parameter for last action.
812
813 Returns:
814 A string representing the platform architecture.
815 """
816 if pyauto.PyUITest.IsWin():
817 if os.environ['PROGRAMFILES'] == 'C:\\Program Files (x86)':
818 return '64bit'
819 else:
820 return '32bit'
821 elif pyauto.PyUITest.IsMac() or pyauto.PyUITest.IsLinux():
822 if platform.machine() == 'x86_64':
823 return '64bit'
824 else:
825 return '32bit'
826 return '32bit'
827
828 def _HasFile(self, pattern, root=os.curdir):
829 """Check if a file matching the specified pattern exists in a directory.
830
831 Args:
832 pattern: Pattern of file name.
833 root: Directory to start looking.
834
835 Returns:
836 True, if root contains the file name pattern, or
837 False otherwise.
838 """
839 return len(glob.glob(os.path.join(root, pattern)))
840
841 def _HasPathInTree(self, pattern, is_file, root=os.curdir):
842 """Recursively checks if a file/directory matching a pattern exists.
843
844 Args:
845 pattern: Pattern of file or directory name.
846 is_file: True if looking for file, or False if looking for directory.
847 root: Directory to start looking.
848
849 Returns:
850 True, if root contains the directory name pattern, or
851 False otherwise.
852 """
853 for path, dirs, files in os.walk(os.path.abspath(root)):
854 if is_file:
855 if len(fnmatch.filter(files, pattern)):
856 return True
857 else:
858 if len(fnmatch.filter(dirs, pattern)):
859 return True
860 return False
861
862 def _GetDirectoryPath(self, pattern, root=os.curdir):
863 """Get the path of a directory in another directory.
864
865 Args:
866 pattern: Pattern of directory name.
867 root: Directory to start looking.
868
869 Returns:
870 A string of the path.
871 """
872 for path, dirs, files in os.walk(os.path.abspath(root)):
873 result = fnmatch.filter(dirs, pattern)
874 if result:
875 return os.path.join(path, result[0])
876 return None
877
878 def _HasAllSystemRequirements(self):
879 """Verify NaCl SDK installation system requirements.
880
881 Returns:
882 True, if system passed requirements, or
883 False otherwise.
884 """
885 # Check python version.
886 if sys.version_info[0:2] < (2, 5):
887 return False
888
889 # Check OS requirements.
890 if pyauto.PyUITest.IsMac():
891 mac_min_version = version.StrictVersion('10.6')
892 mac_version = version.StrictVersion(platform.mac_ver()[0])
893 if mac_version < mac_min_version:
894 return False
895 elif pyauto.PyUITest.IsWin():
896 if not (self.IsWin7() or self.IsWinVista() or self.IsWinXP()):
897 return False
898 elif pyauto.PyUITest.IsLinux():
899 pass # TODO(chrisphan): Check Lin requirements.
900 else:
901 return False
902
903 # Check for Chrome version compatibility.
904 # NaCl supports Chrome 10 and higher builds.
905 settings = self._GetTestSetting()
906 min_required_chrome_build = settings['min_required_chrome_build']
907 browser_info = self.GetBrowserInfo()
908 chrome_version = browser_info['properties']['ChromeVersion']
909 chrome_build = int(chrome_version.split('.')[0])
910 return chrome_build >= min_required_chrome_build
911
912 def _DownloadNaClSDK(self):
913 """Download NaCl SDK."""
914 settings = self._GetTestSetting()
915
916 if pyauto.PyUITest.IsWin():
917 dl_file = urllib2.urlopen(settings['release_win_sdk_url'])
918 file_path = os.path.join(self._download_dir, 'naclsdk_win.exe')
919 elif pyauto.PyUITest.IsMac():
920 dl_file = urllib2.urlopen(settings['release_mac_sdk_url'])
921 file_path = os.path.join(self._download_dir, 'naclsdk_mac.tgz')
922 elif pyauto.PyUITest.IsLinux():
923 dl_file = urllib2.urlopen(settings['release_lin_sdk_url'])
924 file_path = os.path.join(self._download_dir, 'naclsdk_linux.tgz')
925 else:
926 self.fail(msg='NaCl SDK does not support this OS.')
927
928 try:
929 f = open(file_path, 'wb')
930 f.write(dl_file.read())
931 except IOError:
932 self.fail(msg='Cannot open %s.' % file_path)
933 finally:
934 f.close()
935
936 def _ExtractNaClSDK(self):
937 """Extract NaCl SDK."""
938 os.makedirs(self._extracted_sdk_path)
939
940 if pyauto.PyUITest.IsWin():
941 source_file = os.path.join(self._download_dir, 'naclsdk_win.exe')
942 proc = subprocess.Popen([source_file, '/S', '/D=' +
943 self._extracted_sdk_path],
944 stdout=subprocess.PIPE)
945 proc.communicate()
946 if not os.listdir(self._extracted_sdk_path):
947 self.fail(msg='Failed to extract NaCl SDK.')
948 elif pyauto.PyUITest.IsMac():
949 source_file = os.path.join(self._download_dir, 'naclsdk_mac.tgz')
950 tar = tarfile.open(source_file, 'r')
951 tar.extractall(self._extracted_sdk_path)
952 elif pyauto.PyUITest.IsLinux():
953 source_file = os.path.join(self._download_dir, 'naclsdk_linux.tgz')
954 tar = tarfile.open(source_file, 'r')
955 tar.extractall(self._extracted_sdk_path)
956 else:
957 self.fail(msg='NaCl SDK does not support this OS.')
958
959 def _IsURLAlive(self, url):
960 """Test if URL is alive."""
961 try:
962 urllib2.urlopen(url)
963 except:
964 return False
965 return True
966
967 def _CloseHTTPServer(self, proc=None):
968 """Close HTTP server.
969
970 Args:
971 proc: Process that opened the HTTP server.
972 proc is None when there is no pointer to HTTP server process.
973 """
974 if not self._IsURLAlive('http://localhost:5103'):
975 return
976 response = urllib2.urlopen('http://localhost:5103')
977 html = response.read()
978 if not 'Native Client' in html:
979 self.fail(msg='Port 5103 is in use.')
980
981 urllib2.urlopen('http://localhost:5103?quit=1')
982 success = self.WaitUntil(
983 lambda: self._IsURLAlive('http://localhost:5103'),
984 timeout=30, retry_sleep=1, expect_retval=False)
985 if not success:
986 if not proc:
987 self.fail(msg='Failed to close HTTP server.')
988 else:
989 if proc.poll() == None:
990 try:
991 proc.kill()
992 except:
993 self.fail(msg='Failed to close HTTP server')
994
995 def _SearchNaClSDKTarFile(self, search_list, source_file):
996 """Search NaCl SDK tar file for example files and directories.
997
998 Args:
999 search_list: A list of strings, representing file and
1000 directory names for which to search.
1001 source_file: The string name of an NaCl SDK tar file.
1002 """
1003 tar = tarfile.open(source_file, 'r')
1004
1005 # Look for files and directories in examples.
1006 files = copy.deepcopy(search_list)
1007 for tar_info in tar:
1008 file_name = tar_info.name
1009 if tar_info.isdir() and not file_name.endswith('/'):
1010 file_name = file_name + '/'
1011
1012 for name in files:
1013 if file_name.find('examples/' + name):
1014 files.remove(name)
1015 if not files:
1016 break
1017
1018 tar.close()
1019
1020 self.assertEqual(len(files), 0,
1021 msg='Missing files or directories: %s' %
1022 ', '.join(map(str, files)))
1023
1024 def _SearchNaClSDKFileWindows(self, search_list):
1025 """Search NaCl SDK file for example files and directories in Windows.
1026
1027 Args:
1028 search_list: A list of strings, representing file and
1029 directory names for which to search.
1030 """
1031 missing_items = []
1032 for name in search_list:
1033 is_file = name.find('/') < 0
1034 if not is_file:
1035 name = name.replace('/', '')
1036 if not self._HasPathInTree(name, is_file, self._extracted_sdk_path):
1037 missing_items.append(name)
1038 self.assertEqual(len(missing_items), 0,
1039 msg='Missing files or directories: %s' %
1040 ', '.join(map(str, missing_items)))
1041
1042 def _EnableNaClPlugin(self):
1043 """"Enable NaCl plugin."""
1044 nacl_plugin = self.GetPluginsInfo().PluginForName('Chrome NaCl')
Nirnimesh 2011/08/15 23:13:15 lines 1044-1046 can be rewritten as: nacl_plugin
chrisphan 2011/08/18 00:21:04 Done.
1045 if not len(nacl_plugin):
1046 nacl_plugin = self.GetPluginsInfo().PluginForName('Native Client')
1047 if not len(nacl_plugin):
1048 self.fail(msg='No NaCl plugin found.')
1049 self.EnablePlugin(nacl_plugin[0]['path'])
1050
1051 self.NavigateToURL('about:flags')
1052
1053 js_code = """
1054 chrome.send('enableFlagsExperiment', ['enable-nacl', 'true']);
1055 requestFlagsExperimentsData();
1056 window.domAutomationController.send('done');
1057 """
1058 self.ExecuteJavascript(js_code)
1059 self.RestartBrowser(False)
Nirnimesh 2011/08/15 23:13:15 Does this work? Do you see --enable-nacl? I don't
Nirnimesh 2011/08/15 23:13:15 After this line, verify that --enable-nacl is pass
chrisphan 2011/08/17 18:51:01 The doc wanted to enable nacl through about:flags.
chrisphan 2011/08/17 18:51:01 Done.
Nirnimesh 2011/08/17 23:58:45 Are you sure chrome really restarts with --enable-
chrisphan 2011/08/18 00:21:04 Added a check in the latest copy.
1060
1061 def _GetTestSetting(self):
1062 """Read the given data file and return a dictionary of items.
1063
1064 Returns:
1065 A dict mapping of keys/values in the NaCl SDK setting file.
1066 """
1067 data_file = os.path.join(self.DataDir(), 'nacl_sdk', 'nacl_sdk_setting')
1068
1069 try:
1070 f = open(data_file, 'r')
1071 except IOError:
1072 self.fail(msg='Cannot open %s.' % data_file)
1073
1074 try:
1075 dictionary = eval(f.read(), {'__builtins__': None}, None)
1076 except SyntaxError:
1077 self.fail(msg='%s is an invalid setting file.' % data_file)
1078 finally:
1079 f.close()
1080
1081 return dictionary
1082
1083
1084 if __name__ == '__main__':
1085 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