Enable Enterprise enrollment on desktop builds.
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / integration_test.py
blobcfc3f37bbaacbb711ec7a3840126efda6776d382
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.
6 # Run build_server so that files needed by tests are copied to the local
7 # third_party directory.
8 import build_server
9 build_server.main()
11 import json
12 import optparse
13 import os
14 import posixpath
15 import sys
16 import time
17 import unittest
19 from branch_utility import BranchUtility
20 from chroot_file_system import ChrootFileSystem
21 from extensions_paths import (
22 CONTENT_PROVIDERS, CHROME_EXTENSIONS, PUBLIC_TEMPLATES)
23 from fake_fetchers import ConfigureFakeFetchers
24 from special_paths import SITE_VERIFICATION_FILE
25 from handler import Handler
26 from link_error_detector import LinkErrorDetector, StringifyBrokenLinks
27 from local_file_system import LocalFileSystem
28 from local_renderer import LocalRenderer
29 from path_util import AssertIsValid
30 from servlet import Request
31 from third_party.json_schema_compiler import json_parse
32 from test_util import (
33 ChromiumPath, DisableLogging, EnableLogging, ReadFile, Server2Path)
36 # Arguments set up if __main__ specifies them.
37 _EXPLICIT_TEST_FILES = None
38 _REBASE = False
39 _VERBOSE = False
42 def _ToPosixPath(os_path):
43 return os_path.replace(os.sep, '/')
46 def _FilterHidden(paths):
47 '''Returns a list of the non-hidden paths from |paths|.
48 '''
49 # Hidden files start with a '.' but paths like './foo' and '../foo' are not
50 # hidden.
51 return [path for path in paths if (not path.startswith('.')) or
52 path.startswith('./') or
53 path.startswith('../')]
56 def _GetPublicFiles():
57 '''Gets all public file paths mapped to their contents.
58 '''
59 def walk(path, prefix=''):
60 path = ChromiumPath(path)
61 public_files = {}
62 for root, dirs, files in os.walk(path, topdown=True):
63 relative_root = root[len(path):].lstrip(os.path.sep)
64 dirs[:] = _FilterHidden(dirs)
65 for filename in _FilterHidden(files):
66 with open(os.path.join(root, filename), 'r') as f:
67 request_path = posixpath.join(prefix, relative_root, filename)
68 public_files[request_path] = f.read()
69 return public_files
71 # Public file locations are defined in content_providers.json, sort of. Epic
72 # hack to pull them out; list all the files from the directories that
73 # Chromium content providers ask for.
74 public_files = {}
75 content_providers = json_parse.Parse(ReadFile(CONTENT_PROVIDERS))
76 for content_provider in content_providers.itervalues():
77 if 'chromium' in content_provider:
78 public_files.update(walk(content_provider['chromium']['dir'],
79 prefix=content_provider['serveFrom']))
80 return public_files
83 class IntegrationTest(unittest.TestCase):
84 def setUp(self):
85 ConfigureFakeFetchers()
87 @EnableLogging('info')
88 def testCronAndPublicFiles(self):
89 '''Runs cron then requests every public file. Cron needs to be run first
90 because the public file requests are offline.
91 '''
92 if _EXPLICIT_TEST_FILES is not None:
93 return
95 print('Running cron...')
96 start_time = time.time()
97 try:
98 response = Handler(Request.ForTest('/_cron')).Get()
99 if response:
100 self.assertEqual(200, response.status)
101 self.assertEqual('Success', response.content.ToString())
102 else:
103 self.fail('No response for _cron')
104 finally:
105 print('Took %s seconds' % (time.time() - start_time))
107 # TODO(kalman): Re-enable this, but it takes about an hour at the moment,
108 # presumably because every page now has a lot of links on it from the
109 # topnav.
111 #print("Checking for broken links...")
112 #start_time = time.time()
113 #link_error_detector = LinkErrorDetector(
114 # # TODO(kalman): Use of ChrootFileSystem here indicates a hack. Fix.
115 # ChrootFileSystem(LocalFileSystem.Create(), CHROME_EXTENSIONS),
116 # lambda path: Handler(Request.ForTest(path)).Get(),
117 # 'templates/public',
118 # ('extensions/index.html', 'apps/about_apps.html'))
120 #broken_links = link_error_detector.GetBrokenLinks()
121 #if broken_links:
122 # print('Found %d broken links.' % (
123 # len(broken_links)))
124 # if _VERBOSE:
125 # print(StringifyBrokenLinks(broken_links))
127 #broken_links_set = set(broken_links)
129 #known_broken_links_path = os.path.join(
130 # Server2Path('known_broken_links.json'))
131 #try:
132 # with open(known_broken_links_path, 'r') as f:
133 # # The JSON file converts tuples and sets into lists, and for this
134 # # set union/difference logic they need to be converted back.
135 # known_broken_links = set(tuple(item) for item in json.load(f))
136 #except IOError:
137 # known_broken_links = set()
139 #newly_broken_links = broken_links_set - known_broken_links
140 #fixed_links = known_broken_links - broken_links_set
142 #print('Took %s seconds.' % (time.time() - start_time))
144 #print('Searching for orphaned pages...')
145 #start_time = time.time()
146 #orphaned_pages = link_error_detector.GetOrphanedPages()
147 #if orphaned_pages:
148 # # TODO(jshumway): Test should fail when orphaned pages are detected.
149 # print('Found %d orphaned pages:' % len(orphaned_pages))
150 # for page in orphaned_pages:
151 # print(page)
152 #print('Took %s seconds.' % (time.time() - start_time))
154 public_files = _GetPublicFiles()
156 print('Rendering %s public files...' % len(public_files.keys()))
157 start_time = time.time()
158 try:
159 for path, content in public_files.iteritems():
160 AssertIsValid(path)
161 if path.endswith('redirects.json'):
162 continue
164 # The non-example html and md files are served without their file
165 # extensions.
166 path_without_ext, ext = posixpath.splitext(path)
167 if (ext in ('.html', '.md') and
168 '/examples/' not in path and
169 path != SITE_VERIFICATION_FILE):
170 path = path_without_ext
172 def check_result(response):
173 self.assertEqual(200, response.status,
174 'Got %s when rendering %s' % (response.status, path))
176 # This is reaaaaally rough since usually these will be tiny templates
177 # that render large files. At least it'll catch zero-length responses.
178 self.assertTrue(len(response.content) >= len(content),
179 'Rendered content length was %s vs template content length %s '
180 'when rendering %s' % (len(response.content), len(content), path))
182 check_result(Handler(Request.ForTest(path)).Get())
184 if path.startswith(('apps/', 'extensions/')):
185 # Make sure that adding the .html will temporarily redirect to
186 # the path without the .html for APIs and articles.
187 if '/examples/' not in path:
188 redirect_response = Handler(Request.ForTest(path + '.html')).Get()
189 self.assertEqual(
190 ('/' + path, False), redirect_response.GetRedirect(),
191 '%s.html did not (temporarily) redirect to %s (status %s)' %
192 (path, path, redirect_response.status))
194 # Make sure including a channel will permanently redirect to the same
195 # path without a channel.
196 for channel in BranchUtility.GetAllChannelNames():
197 redirect_response = Handler(
198 Request.ForTest(posixpath.join(channel, path))).Get()
199 self.assertEqual(
200 ('/' + path, True),
201 redirect_response.GetRedirect(),
202 '%s/%s did not (permanently) redirect to %s (status %s)' %
203 (channel, path, path, redirect_response.status))
205 # Samples are internationalized, test some locales.
206 if path.endswith('/samples'):
207 for lang in ('en-US', 'es', 'ar'):
208 check_result(Handler(Request.ForTest(
209 path,
210 headers={'Accept-Language': '%s;q=0.8' % lang})).Get())
211 finally:
212 print('Took %s seconds' % (time.time() - start_time))
214 #if _REBASE:
215 # print('Rebasing broken links with %s newly broken and %s fixed links.' %
216 # (len(newly_broken_links), len(fixed_links)))
217 # with open(known_broken_links_path, 'w') as f:
218 # json.dump(broken_links, f,
219 # indent=2, separators=(',', ': '), sort_keys=True)
220 #else:
221 # if fixed_links or newly_broken_links:
222 # print('**********************************************\n'
223 # 'CHANGE DETECTED IN BROKEN LINKS WITHOUT REBASE\n'
224 # '**********************************************')
225 # print('Found %s broken links, and some have changed. '
226 # 'If this is acceptable or expected then run %s with the --rebase '
227 # 'option.' % (len(broken_links), os.path.split(__file__)[-1]))
228 # elif broken_links:
229 # print('%s existing broken links' % len(broken_links))
230 # if fixed_links:
231 # print('%s broken links have been fixed:' % len(fixed_links))
232 # print(StringifyBrokenLinks(fixed_links))
233 # if newly_broken_links:
234 # print('There are %s new broken links:' % len(newly_broken_links))
235 # print(StringifyBrokenLinks(newly_broken_links))
236 # self.fail('See logging for details.')
238 # TODO(kalman): Move this test elsewhere, it's not an integration test.
239 # Perhaps like "presubmit_tests" or something.
240 def testExplicitFiles(self):
241 '''Tests just the files in _EXPLICIT_TEST_FILES.
243 if _EXPLICIT_TEST_FILES is None:
244 return
245 for filename in _EXPLICIT_TEST_FILES:
246 print('Rendering %s...' % filename)
247 start_time = time.time()
248 try:
249 response = LocalRenderer.Render(_ToPosixPath(filename))
250 self.assertEqual(200, response.status)
251 self.assertTrue(response.content != '')
252 finally:
253 print('Took %s seconds' % (time.time() - start_time))
255 # TODO(jshumway): Check page for broken links (currently prohibited by the
256 # time it takes to render the pages).
258 @DisableLogging('warning')
259 def testFileNotFound(self):
260 response = LocalRenderer.Render('/extensions/notfound')
261 self.assertEqual(404, response.status)
263 def testSiteVerificationFile(self):
264 response = LocalRenderer.Render('/' + SITE_VERIFICATION_FILE)
265 self.assertEqual(200, response.status)
267 if __name__ == '__main__':
268 parser = optparse.OptionParser()
269 parser.add_option('-a', '--all', action='store_true', default=False,
270 help='Render all pages, not just the one specified')
271 parser.add_option('-r', '--rebase', action='store_true', default=False,
272 help='Rewrites the known_broken_links.json file with '
273 'the current set of broken links')
274 parser.add_option('-v', '--verbose', action='store_true', default=False,
275 help='Show verbose output like currently broken links')
276 (opts, args) = parser.parse_args()
277 if not opts.all:
278 _EXPLICIT_TEST_FILES = args
279 _REBASE = opts.rebase
280 _VERBOSE = opts.verbose
281 # Kill sys.argv because we have our own flags.
282 sys.argv = [sys.argv[0]]
283 unittest.main()