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

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