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

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