integration_test.py revision bb1529ce867d8845a77ec7cdf3e3003ef1771a40
1#!/usr/bin/env python 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 4# found in the LICENSE file. 5 6# Run build_server so that files needed by tests are copied to the local 7# third_party directory. 8import build_server 9build_server.main() 10 11import optparse 12import os 13import posixpath 14import sys 15import time 16import unittest 17 18from branch_utility import BranchUtility 19from link_error_detector import LinkErrorDetector, StringifyBrokenLinks 20from local_file_system import LocalFileSystem 21from local_renderer import LocalRenderer 22from fake_fetchers import ConfigureFakeFetchers 23from handler import Handler 24from servlet import Request 25from test_util import EnableLogging, DisableLogging 26 27# Arguments set up if __main__ specifies them. 28_EXPLICIT_TEST_FILES = None 29 30def _ToPosixPath(os_path): 31 return os_path.replace(os.sep, '/') 32 33def _GetPublicFiles(): 34 '''Gets all public files mapped to their contents. 35 ''' 36 public_path = os.path.join(sys.path[0], os.pardir, 'templates', 'public') 37 public_files = {} 38 for path, dirs, files in os.walk(public_path, topdown=True): 39 dirs[:] = [d for d in dirs if d != '.svn'] 40 relative_posix_path = _ToPosixPath(path[len(public_path):]) 41 for filename in files: 42 with open(os.path.join(path, filename), 'r') as f: 43 public_files['/'.join((relative_posix_path, filename))] = f.read() 44 return public_files 45 46class IntegrationTest(unittest.TestCase): 47 def setUp(self): 48 ConfigureFakeFetchers() 49 50 @EnableLogging('info') 51 def testCronAndPublicFiles(self): 52 '''Runs cron then requests every public file. Cron needs to be run first 53 because the public file requests are offline. 54 ''' 55 if _EXPLICIT_TEST_FILES is not None: 56 return 57 58 print('Running cron...') 59 start_time = time.time() 60 try: 61 response = Handler(Request.ForTest('/_cron/stable')).Get() 62 self.assertEqual(200, response.status) 63 self.assertEqual('Success', response.content.ToString()) 64 finally: 65 print('Took %s seconds' % (time.time() - start_time)) 66 67 print("Checking for broken links...") 68 start_time = time.time() 69 link_error_detector = LinkErrorDetector( 70 LocalFileSystem(os.path.join(sys.path[0], os.pardir, os.pardir)), 71 lambda path: Handler(Request.ForTest(path)).Get(), 72 'templates/public', 73 ('extensions/index.html', 'apps/about_apps.html')) 74 75 broken_links = link_error_detector.GetBrokenLinks() 76 if broken_links: 77 # TODO(jshumway): Test should fail when broken links are detected. 78 print('Warning: Found %d broken links:' % ( 79 len(broken_links))) 80 print(StringifyBrokenLinks(broken_links)) 81 82 print('Took %s seconds.' % (time.time() - start_time)) 83 84 print('Searching for orphaned pages...') 85 start_time = time.time() 86 orphaned_pages = link_error_detector.GetOrphanedPages() 87 if orphaned_pages: 88 # TODO(jshumway): Test should fail when orphaned pages are detected. 89 print('Warning: Found %d orphaned pages:' % len(orphaned_pages)) 90 for page in orphaned_pages: 91 print(page) 92 print('Took %s seconds.' % (time.time() - start_time)) 93 94 public_files = _GetPublicFiles() 95 96 print('Rendering %s public files...' % len(public_files.keys())) 97 start_time = time.time() 98 try: 99 for path, content in public_files.iteritems(): 100 if path.endswith('redirects.json'): 101 continue 102 def check_result(response): 103 self.assertEqual(200, response.status, 104 'Got %s when rendering %s' % (response.status, path)) 105 # This is reaaaaally rough since usually these will be tiny templates 106 # that render large files. At least it'll catch zero-length responses. 107 self.assertTrue(len(response.content) >= len(content), 108 'Content was "%s" when rendering %s' % (response.content, path)) 109 110 check_result(Handler(Request.ForTest(path)).Get()) 111 112 # Make sure that leaving out the .html will temporarily redirect to the 113 # path with the .html. 114 if path != '/404.html': 115 redirect_result = Handler( 116 Request.ForTest(posixpath.splitext(path)[0])).Get() 117 self.assertEqual((path, False), redirect_result.GetRedirect()) 118 119 # Make sure including a channel will permanently redirect to the same 120 # path without a channel. 121 for channel in BranchUtility.GetAllChannelNames(): 122 redirect_result = Handler( 123 Request.ForTest('%s/%s' % (channel, path))).Get() 124 self.assertEqual((path, True), redirect_result.GetRedirect()) 125 126 # Samples are internationalized, test some locales. 127 if path.endswith('/samples.html'): 128 for lang in ['en-US', 'es', 'ar']: 129 check_result(Handler(Request.ForTest( 130 path, 131 headers={'Accept-Language': '%s;q=0.8' % lang})).Get()) 132 finally: 133 print('Took %s seconds' % (time.time() - start_time)) 134 135 # TODO(kalman): Move this test elsewhere, it's not an integration test. 136 # Perhaps like "presubmit_tests" or something. 137 def testExplicitFiles(self): 138 '''Tests just the files in _EXPLICIT_TEST_FILES. 139 ''' 140 if _EXPLICIT_TEST_FILES is None: 141 return 142 for filename in _EXPLICIT_TEST_FILES: 143 print('Rendering %s...' % filename) 144 start_time = time.time() 145 try: 146 response = LocalRenderer.Render(_ToPosixPath(filename)) 147 self.assertEqual(200, response.status) 148 self.assertTrue(response.content != '') 149 finally: 150 print('Took %s seconds' % (time.time() - start_time)) 151 152 # TODO(jshumway): Check page for broken links (currently prohibited by the 153 # time it takes to render the pages). 154 155 @DisableLogging('warning') 156 def testFileNotFound(self): 157 response = Handler(Request.ForTest('/extensions/notfound.html')).Get() 158 self.assertEqual(404, response.status) 159 160if __name__ == '__main__': 161 parser = optparse.OptionParser() 162 parser.add_option('-a', '--all', action='store_true', default=False) 163 (opts, args) = parser.parse_args() 164 if not opts.all: 165 _EXPLICIT_TEST_FILES = args 166 # Kill sys.argv because we have our own flags. 167 sys.argv = [sys.argv[0]] 168 unittest.main() 169