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

Side by Side Diff: functional/nacl_sdk.py

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

Powered by Google App Engine
This is Rietveld 408576698