| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 import logging | 6 from handler import Handler |
| 7 from local_renderer import LocalRenderer |
| 7 import optparse | 8 import optparse |
| 8 import os | 9 import os |
| 9 import sys | 10 import sys |
| 10 from StringIO import StringIO | 11 import time |
| 11 import re | |
| 12 import unittest | 12 import unittest |
| 13 | 13 |
| 14 # Run build_server so that files needed by tests are copied to the local | 14 # Arguments set up if __main__ specifies them. |
| 15 # third_party directory. | 15 _BASE_PATH = os.path.join( |
| 16 import build_server | 16 os.path.abspath(os.path.dirname(__file__)), os.pardir, os.pardir) |
| 17 build_server.main() | 17 _EXPLICIT_TEST_FILES = None |
| 18 | 18 |
| 19 BASE_PATH = None | 19 def _GetPublicFiles(): |
| 20 EXPLICIT_TEST_FILES = None | 20 '''Gets all public files mapped to their contents. |
| 21 | 21 ''' |
| 22 from fake_fetchers import ConfigureFakeFetchers | 22 public_path = os.path.join(_BASE_PATH, 'docs', 'templates', 'public', '') |
| 23 ConfigureFakeFetchers(os.path.join(sys.path[0], os.pardir)) | 23 public_files = {} |
| 24 | 24 for path, dirs, files in os.walk(public_path): |
| 25 # Import Handler later because it immediately makes a request to github. We need | 25 relative_path = path[len(public_path):] |
| 26 # the fake urlfetch to be in place first. | 26 for filename in files: |
| 27 from handler import Handler | 27 with open('%s/%s' % (path, filename), 'r') as f: |
| 28 | 28 public_files['%s/%s' % (relative_path, filename)] = f.read() |
| 29 class _MockResponse(object): | 29 return public_files |
| 30 def __init__(self): | |
| 31 self.status = 200 | |
| 32 self.out = StringIO() | |
| 33 self.headers = {} | |
| 34 | |
| 35 def set_status(self, status): | |
| 36 self.status = status | |
| 37 | |
| 38 class _MockRequest(object): | |
| 39 def __init__(self, path): | |
| 40 self.headers = {} | |
| 41 self.path = path | |
| 42 self.url = 'http://localhost' + path | |
| 43 | 30 |
| 44 class IntegrationTest(unittest.TestCase): | 31 class IntegrationTest(unittest.TestCase): |
| 45 def _TestSamplesLocales(self, sample_path, failures): | 32 def setUp(self): |
| 46 # Use US English, Spanish, and Arabic. | 33 self._renderer = LocalRenderer(_BASE_PATH) |
| 47 for lang in ['en-US', 'es', 'ar']: | 34 |
| 48 request = _MockRequest(sample_path) | 35 def testCronAndPublicFiles(self): |
| 49 request.headers['Accept-Language'] = lang + ';q=0.8' | 36 '''Runs cron then requests every public file. Cron needs to be run first |
| 50 response = _MockResponse() | 37 because the public file requests are offline. |
| 38 ''' |
| 39 if _EXPLICIT_TEST_FILES is not None: |
| 40 return |
| 41 |
| 42 print('Running cron...') |
| 43 start_time = time.time() |
| 44 try: |
| 45 render_content, render_status, _ = self._renderer.Render('/cron/stable') |
| 46 self.assertEqual(200, render_status) |
| 47 self.assertEqual('Success', render_content) |
| 48 finally: |
| 49 print('Took %s seconds' % (time.time() - start_time)) |
| 50 |
| 51 public_files = _GetPublicFiles() |
| 52 |
| 53 print('Rendering %s public files...' % len(public_files.keys())) |
| 54 start_time = time.time() |
| 55 try: |
| 56 for path, content in _GetPublicFiles().iteritems(): |
| 57 render_content, render_status, _ = self._renderer.Render(path) |
| 58 self.assertEqual(200, render_status) |
| 59 # This is reaaaaaly rough since usually these will be tiny templates |
| 60 # that render large files. At least it'll catch zero-length responses. |
| 61 self.assertTrue(len(render_content) >= len(content)) |
| 62 finally: |
| 63 print('Took %s seconds' % (time.time() - start_time)) |
| 64 |
| 65 def testExplicitFiles(self): |
| 66 '''Tests just the files in _EXPLICIT_TEST_FILES. |
| 67 ''' |
| 68 if _EXPLICIT_TEST_FILES is None: |
| 69 return |
| 70 print('Rendering %s explicit files...' % len(_EXPLICIT_TEST_FILES)) |
| 71 for filename in _EXPLICIT_TEST_FILES: |
| 72 print('Rendering %s...' % filename) |
| 73 start_time = time.time() |
| 51 try: | 74 try: |
| 52 Handler(request, response).get() | 75 render_content, render_status, _ = self._renderer.Render( |
| 53 if 200 != response.status: | 76 filename, always_online=True) |
| 54 failures.append( | 77 self.assertEqual(200, render_status) |
| 55 'Samples page with language %s does not have 200 status.' | 78 self.assertTrue(render_content != '') |
| 56 ' Status was %d.' % (lang, response.status)) | 79 finally: |
| 57 if not response.out.getvalue(): | 80 print('Took %s seconds' % (time.time() - start_time)) |
| 58 failures.append( | |
| 59 'Rendering samples page with language %s produced no output.' % | |
| 60 lang) | |
| 61 except Exception as e: | |
| 62 failures.append('Error rendering samples page with language %s: %s' % | |
| 63 (lang, e)) | |
| 64 | 81 |
| 65 def _RunPublicTemplatesTest(self): | 82 def testFileNotFound(self): |
| 66 base_path = os.path.join(BASE_PATH, 'docs', 'templates', 'public') | 83 render_content, render_status, _ = self._renderer.Render( |
| 67 if EXPLICIT_TEST_FILES is None: | 84 '/extensions/notfound.html') |
| 68 test_files = [] | 85 self.assertEqual(404, render_status) |
| 69 for path, dirs, files in os.walk(base_path): | |
| 70 for dir_ in dirs: | |
| 71 if dir_.startswith('.'): | |
| 72 dirs.remove(dir_) | |
| 73 for name in files: | |
| 74 if name.startswith('.') or name == '404.html': | |
| 75 continue | |
| 76 test_files.append(os.path.join(path, name)[len(base_path + os.sep):]) | |
| 77 else: | |
| 78 test_files = EXPLICIT_TEST_FILES | |
| 79 test_files = [f.replace(os.sep, '/') for f in test_files] | |
| 80 failures = [] | |
| 81 for filename in test_files: | |
| 82 request = _MockRequest(filename) | |
| 83 response = _MockResponse() | |
| 84 try: | |
| 85 Handler(request, response).get() | |
| 86 if 200 != response.status: | |
| 87 failures.append('%s does not have 200 status. Status was %d.' % | |
| 88 (filename, response.status)) | |
| 89 if not response.out.getvalue(): | |
| 90 failures.append('Rendering %s produced no output.' % filename) | |
| 91 if filename.endswith('samples.html'): | |
| 92 self._TestSamplesLocales(filename, failures) | |
| 93 except Exception as e: | |
| 94 failures.append('Error rendering %s: %s' % (filename, e)) | |
| 95 if failures: | |
| 96 self.fail('\n'.join(failures)) | |
| 97 | |
| 98 def testAllPublicTemplates(self): | |
| 99 logging.getLogger().setLevel(logging.ERROR) | |
| 100 logging_error = logging.error | |
| 101 try: | |
| 102 logging.error = self.fail | |
| 103 self._RunPublicTemplatesTest() | |
| 104 finally: | |
| 105 logging.error = logging_error | |
| 106 | |
| 107 def testNonexistentFile(self): | |
| 108 logging.getLogger().setLevel(logging.CRITICAL) | |
| 109 request = _MockRequest('extensions/junk.html') | |
| 110 bad_response = _MockResponse() | |
| 111 Handler(request, bad_response).get() | |
| 112 self.assertEqual(404, bad_response.status) | |
| 113 request_404 = _MockRequest('404.html') | |
| 114 response_404 = _MockResponse() | |
| 115 Handler(request_404, response_404).get() | |
| 116 self.assertEqual(200, response_404.status) | |
| 117 self.assertEqual(response_404.out.getvalue(), bad_response.out.getvalue()) | |
| 118 | |
| 119 def testCron(self): | |
| 120 if EXPLICIT_TEST_FILES is not None: | |
| 121 return | |
| 122 logging_error = logging.error | |
| 123 try: | |
| 124 logging.error = self.fail | |
| 125 request = _MockRequest('/cron/trunk') | |
| 126 response = _MockResponse() | |
| 127 Handler(request, response).get() | |
| 128 self.assertEqual(200, response.status) | |
| 129 self.assertEqual('Success', response.out.getvalue()) | |
| 130 finally: | |
| 131 logging.error = logging_error | |
| 132 | 86 |
| 133 if __name__ == '__main__': | 87 if __name__ == '__main__': |
| 134 parser = optparse.OptionParser() | 88 parser = optparse.OptionParser() |
| 135 parser.add_option('-p', | 89 parser.add_option('-p', '--path', default=None) |
| 136 '--path', | 90 parser.add_option('-a', '--all', action='store_true', default=False) |
| 137 default=os.path.join( | |
| 138 os.path.abspath(os.path.dirname(__file__)), | |
| 139 os.pardir, | |
| 140 os.pardir)) | |
| 141 parser.add_option('-a', | |
| 142 '--all', | |
| 143 action='store_true', | |
| 144 default=False) | |
| 145 (opts, args) = parser.parse_args() | 91 (opts, args) = parser.parse_args() |
| 146 | |
| 147 if not opts.all: | 92 if not opts.all: |
| 148 EXPLICIT_TEST_FILES = args | 93 _EXPLICIT_TEST_FILES = args |
| 149 BASE_PATH = opts.path | 94 if opts.path is not None: |
| 150 suite = unittest.TestSuite(tests=[ | 95 _BASE_PATH = opts.path |
| 151 IntegrationTest('testNonexistentFile'), | 96 # Kill sys.argv because we have our own flags. |
| 152 IntegrationTest('testCron'), | 97 sys.argv = [sys.argv[0]] |
| 153 IntegrationTest('testAllPublicTemplates') | 98 unittest.main() |
| 154 ]) | |
| 155 result = unittest.TestResult() | |
| 156 suite.run(result) | |
| 157 if result.failures: | |
| 158 print('*----------------------------------*') | |
| 159 print('| integration_test.py has failures |') | |
| 160 print('*----------------------------------*') | |
| 161 for test, failure in result.failures: | |
| 162 print(test) | |
| 163 print(failure) | |
| 164 exit(1) | |
| 165 exit(0) | |
| OLD | NEW |