| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2013 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 # Run build_server so that files needed by tests are copied to the local | 6 # Run build_server so that files needed by tests are copied to the local |
| 7 # third_party directory. | 7 # third_party directory. |
| 8 import build_server | 8 import build_server |
| 9 build_server.main() | 9 build_server.main() |
| 10 | 10 |
| 11 import logging | 11 from itertools import groupby |
| 12 from operator import itemgetter |
| 12 import optparse | 13 import optparse |
| 13 import os | 14 import os |
| 14 import sys | 15 import sys |
| 15 import time | 16 import time |
| 16 import unittest | 17 import unittest |
| 17 | 18 |
| 19 from link_error_detector import LinkErrorDetector |
| 20 from local_file_system import LocalFileSystem |
| 18 from local_renderer import LocalRenderer | 21 from local_renderer import LocalRenderer |
| 19 from fake_fetchers import ConfigureFakeFetchers | 22 from fake_fetchers import ConfigureFakeFetchers |
| 20 from handler import Handler | 23 from handler import Handler |
| 21 from servlet import Request | 24 from servlet import Request |
| 22 from test_util import EnableLogging, DisableLogging | 25 from test_util import EnableLogging, DisableLogging |
| 23 | 26 |
| 24 # Arguments set up if __main__ specifies them. | 27 # Arguments set up if __main__ specifies them. |
| 25 _EXPLICIT_TEST_FILES = None | 28 _EXPLICIT_TEST_FILES = None |
| 26 | 29 |
| 27 def _ToPosixPath(os_path): | 30 def _ToPosixPath(os_path): |
| 28 return os_path.replace(os.sep, '/') | 31 return os_path.replace(os.sep, '/') |
| 29 | 32 |
| 30 def _GetPublicFiles(): | 33 def _GetPublicFiles(): |
| 31 '''Gets all public files mapped to their contents. | 34 '''Gets all public files mapped to their contents. |
| 32 ''' | 35 ''' |
| 33 public_path = os.path.join(sys.path[0], os.pardir, 'templates', 'public') | 36 public_path = os.path.join(sys.path[0], os.pardir, 'templates', 'public') |
| 34 public_files = {} | 37 public_files = {} |
| 35 for path, dirs, files in os.walk(public_path, topdown=True): | 38 for path, dirs, files in os.walk(public_path, topdown=True): |
| 36 dirs[:] = [d for d in dirs if d != '.svn'] | 39 dirs[:] = [d for d in dirs if d != '.svn'] |
| 37 relative_posix_path = _ToPosixPath(path[len(public_path):]) | 40 relative_posix_path = _ToPosixPath(path[len(public_path):]) |
| 38 for filename in files: | 41 for filename in files: |
| 39 with open(os.path.join(path, filename), 'r') as f: | 42 with open(os.path.join(path, filename), 'r') as f: |
| 40 public_files['/'.join((relative_posix_path, filename))] = f.read() | 43 public_files['/'.join((relative_posix_path, filename))] = f.read() |
| 41 return public_files | 44 return public_files |
| 42 | 45 |
| 46 def _PrintBrokenLinks(broken_links): |
| 47 '''Prints out broken links in a more readable format. |
| 48 ''' |
| 49 col_width = max(len(link[0]) for link in broken_links) |
| 50 getter = itemgetter(1) |
| 51 |
| 52 def pretty_print(prefix, message): |
| 53 print("%s%s -> %s" % (prefix, (col_width - len(prefix)) * ' ', message)) |
| 54 |
| 55 for target, links in groupby(sorted(broken_links, key=getter), getter): |
| 56 links = [l[0] for l in links] |
| 57 if len(links) > 50: |
| 58 out = "%s and %d others" % (links[0], len(links) - 1) |
| 59 pretty_print(out, target) |
| 60 else: |
| 61 for link in links: |
| 62 pretty_print(link, target) |
| 63 |
| 43 class IntegrationTest(unittest.TestCase): | 64 class IntegrationTest(unittest.TestCase): |
| 44 def setUp(self): | 65 def setUp(self): |
| 45 ConfigureFakeFetchers() | 66 ConfigureFakeFetchers() |
| 46 | 67 |
| 47 @EnableLogging('info') | 68 @EnableLogging('info') |
| 48 def testCronAndPublicFiles(self): | 69 def testCronAndPublicFiles(self): |
| 49 '''Runs cron then requests every public file. Cron needs to be run first | 70 '''Runs cron then requests every public file. Cron needs to be run first |
| 50 because the public file requests are offline. | 71 because the public file requests are offline. |
| 51 ''' | 72 ''' |
| 52 if _EXPLICIT_TEST_FILES is not None: | 73 if _EXPLICIT_TEST_FILES is not None: |
| 53 return | 74 return |
| 54 | 75 |
| 55 print('Running cron...') | 76 print('Running cron...') |
| 56 start_time = time.time() | 77 start_time = time.time() |
| 57 try: | 78 try: |
| 58 response = Handler(Request.ForTest('/_cron/stable')).Get() | 79 response = Handler(Request.ForTest('/_cron/stable')).Get() |
| 59 self.assertEqual(200, response.status) | 80 self.assertEqual(200, response.status) |
| 60 self.assertEqual('Success', response.content.ToString()) | 81 self.assertEqual('Success', response.content.ToString()) |
| 61 finally: | 82 finally: |
| 62 print('Took %s seconds' % (time.time() - start_time)) | 83 print('Took %s seconds' % (time.time() - start_time)) |
| 63 | 84 |
| 85 print("Checking for broken links...") |
| 86 start_time = time.time() |
| 87 link_error_detector = LinkErrorDetector( |
| 88 LocalFileSystem(os.path.join(sys.path[0], os.pardir, os.pardir)), |
| 89 lambda path: Handler(Request.ForTest(path)).Get(), |
| 90 'templates/public', |
| 91 ('extensions/index.html', 'apps/about_apps.html')) |
| 92 |
| 93 broken_links, broken_anchors = link_error_detector.GetBrokenLinks() |
| 94 if broken_links or broken_anchors: |
| 95 # TODO(jshumway): Test should fail when broken links are detected. |
| 96 print('Warning: Found %d broken links:' % ( |
| 97 len(broken_links + broken_anchors))) |
| 98 _PrintBrokenLinks(broken_links + broken_anchors) |
| 99 |
| 100 print('Took %s seconds.' % (time.time() - start_time)) |
| 101 |
| 102 print('Searching for orphaned pages...') |
| 103 start_time = time.time() |
| 104 orphaned_pages = link_error_detector.GetOrphanedPages() |
| 105 if orphaned_pages: |
| 106 # TODO(jshumway): Test should fail when orphaned pages are detected. |
| 107 print('Warning: Found %d orphaned pages:' % len(orphaned_pages)) |
| 108 for page in orphaned_pages: |
| 109 print(page) |
| 110 print('Took %s seconds.' % (time.time() - start_time)) |
| 111 |
| 64 public_files = _GetPublicFiles() | 112 public_files = _GetPublicFiles() |
| 65 | 113 |
| 66 print('Rendering %s public files...' % len(public_files.keys())) | 114 print('Rendering %s public files...' % len(public_files.keys())) |
| 67 start_time = time.time() | 115 start_time = time.time() |
| 68 try: | 116 try: |
| 69 for path, content in public_files.iteritems(): | 117 for path, content in public_files.iteritems(): |
| 70 if path.endswith('redirects.json'): | 118 if path.endswith('redirects.json'): |
| 71 continue | 119 continue |
| 72 def check_result(response): | 120 def check_result(response): |
| 73 self.assertEqual(200, response.status, | 121 self.assertEqual(200, response.status, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 96 for filename in _EXPLICIT_TEST_FILES: | 144 for filename in _EXPLICIT_TEST_FILES: |
| 97 print('Rendering %s...' % filename) | 145 print('Rendering %s...' % filename) |
| 98 start_time = time.time() | 146 start_time = time.time() |
| 99 try: | 147 try: |
| 100 response = LocalRenderer.Render(_ToPosixPath(filename)) | 148 response = LocalRenderer.Render(_ToPosixPath(filename)) |
| 101 self.assertEqual(200, response.status) | 149 self.assertEqual(200, response.status) |
| 102 self.assertTrue(response.content != '') | 150 self.assertTrue(response.content != '') |
| 103 finally: | 151 finally: |
| 104 print('Took %s seconds' % (time.time() - start_time)) | 152 print('Took %s seconds' % (time.time() - start_time)) |
| 105 | 153 |
| 154 # TODO(jshumway): Check page for broken links (currently prohibited by the |
| 155 # time it takes to render the pages). |
| 156 |
| 106 @DisableLogging('warning') | 157 @DisableLogging('warning') |
| 107 def testFileNotFound(self): | 158 def testFileNotFound(self): |
| 108 response = Handler(Request.ForTest('/extensions/notfound.html')).Get() | 159 response = Handler(Request.ForTest('/extensions/notfound.html')).Get() |
| 109 self.assertEqual(404, response.status) | 160 self.assertEqual(404, response.status) |
| 110 | 161 |
| 111 if __name__ == '__main__': | 162 if __name__ == '__main__': |
| 112 parser = optparse.OptionParser() | 163 parser = optparse.OptionParser() |
| 113 parser.add_option('-a', '--all', action='store_true', default=False) | 164 parser.add_option('-a', '--all', action='store_true', default=False) |
| 114 (opts, args) = parser.parse_args() | 165 (opts, args) = parser.parse_args() |
| 115 if not opts.all: | 166 if not opts.all: |
| 116 _EXPLICIT_TEST_FILES = args | 167 _EXPLICIT_TEST_FILES = args |
| 117 # Kill sys.argv because we have our own flags. | 168 # Kill sys.argv because we have our own flags. |
| 118 sys.argv = [sys.argv[0]] | 169 sys.argv = [sys.argv[0]] |
| 119 unittest.main() | 170 unittest.main() |
| OLD | NEW |